After making my previous post on how to simply store comments in a jSon file (and the comment from Brian) I decided to write an additional HOWTO create dynamic markers and store them in a jSon file.
It also includes an automatic geo data lockup via Google GeoCoder and generates a detail html file for-each marker created, which then will be loaded dynamic when the marker is clicked.
Check out the working example or download the code on GitHub.
// data file with markers (could also be a PHP file for dynamic markers) var newDate = new Date; var markerFile = 'markers.json?time=' + newDate.getTime(); // set default map properties var defaultLatlng = new google.maps.LatLng(49.00,10.00); // zoom level of the map var defaultZoom = 2; // variable for map var map; // variable for marker info window var infowindow // List with all marker to check if exist var markerList = {}; // set error handler for jQuery AJAX requests $.ajaxSetup({"error":function(XMLHttpRequest,textStatus, errorThrown) alert(textStatus); alert(errorThrown); alert(XMLHttpRequest.responseText); }}); // option for google map object var myOptions = { zoom: defaultZoom, center: defaultLatlng, mapTypeId: google.maps.MapTypeId.HYBRID }
/** * Load Map */ function loadMap(){ // create new map make sure a DIV with id myMap exist on page map = new google.maps.Map(document.getElementById("myMap"), myOptions); // create new info window for marker detail pop-up infowindow = new google.maps.InfoWindow(); // load markers loadMarkers(); }
/** * Load markers via ajax request from server */ function loadMarkers(){ // load marker jSon data $.getJSON(markerFile, function(data) { // loop all the markers $.each(data.markers, function(i,item){ // add marker to map loadMarker(item); }); }); }
/** * Load marker to map */ function loadMarker(markerData){ // create new marker location var myLatlng = new google.maps.LatLng(markerData['lat'],markerData['long']); // create new marker var marker = new google.maps.Marker({ id: markerData['id'], map: map, title: markerData['name'] , position: myLatlng }); // add marker to list used later to get content and additional marker information markerList[marker.id] = marker; // add event listener when marker is clicked // currently the marker data contain a dataurl field this can of course be done different google.maps.event.addListener(marker, 'click', function() { // show marker when clicked showMarker(marker.id); }); // add event when marker window is closed to reset map location google.maps.event.addListener(infowindow,'closeclick', function() { map.setCenter(defaultLatlng); map.setZoom(defaultZoom); }); }
/** * Show marker info window */ function showMarker(markerId){ // get marker information from marker list var marker = markerList[markerId]; // check if marker was found if( marker ){ // get marker detail information from server $.get( 'data/' + marker.id + '.html' , function(data) // show marker window infowindow.setContent(data); infowindow.open(map,marker); }); }else{ alert('Error marker not found: ' + markerId); } }
/** * Adds new marker to list */ function newMarker(){ // get new city name var markerAddress = $('#newMarker').val(); // create new geocoder for dynamic map lookup var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': markerAddress}, function(results, status) { // check response status if (status == google.maps.GeocoderStatus.OK) { // Fire Google Goal _gaq.push(['_trackPageview', '/tracking/marker-submit']); // set new maker id via timestamp var newDate = new Date; var markerId = newDate.getTime(); // get name of creator var markerCreator = prompt("Please enter your name",""); // create new marker data object var markerData = { 'id': markerId, 'lat': results[0].geometry.location.lat(), 'long': results[0].geometry.location.lng(), 'creator': markerCreator, 'name': markerAddress, }; // save new marker request to server $.ajax({ type: 'POST', url: "data.php", data: { marker: markerData }, dataType: 'json', async: false, success: function(result){ // add marker to map loadMarker(result); // show marker detail showMarker(result['id']); } }); }else if( status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT){ alert("Marker not found:" + status); } }); }
/* get markes from file */ $dataPath = '/var/www/gmap/data/'; $markerDataFile = 'markers.json'; $markerText = file_get_contents($markerDataFile); /* create array list from markers */ $markerList = json_decode($markerText,true); /* check if new marker is posted */ if( !empty($_POST['marker']) ){ /* get new marker data */ $markerData = $_POST['marker']; /* add additional marker information */ $markerData['ip'] = $_SERVER['REMOTE_ADDR']; $markerData['created'] = time(); /* create detail marker content file */ $markerContent = $markerData['creator'] . "-> " . $markerData['name']; $markerContent .= date("D M j G:i:s T Y"); /* save marker file to server */ $markerFile = $dataPath . $markerData['id'] . ".html"; file_put_contents($markerFile , $markerContent); /* add new marker to existing list */ $markerList['markers'][] = $markerData; /* convert comments to string */ $markerText = json_encode($markerList); /* save comment to file */ file_put_contents($markerDataFile, $markerText); /* return newly created marker */ echo json_encode($markerData); }else{ echo "Invalid request"; }
This should give a good start on how to dynamically add and display markers via Google map.
Check out the working example or download the code on GitHub.
Bravo on your great work on this. Here is more specific detail about what I am trying to do.
I use a mobile app called Instamapper http://instamapper.com that can run on any mobile device and upload gps data to their server at specified intervals. In my case I am doing this for long bike rides but it would be good for any type of travel where there was wireless data service available. I had aleady been generating google maps of my routes using service from http://GPSVisualizer.com and generating tracks and or markers from the automatically uploaded tracking information from the data feed from instamapper. An example of this can be viewed at http://theregoesbrian.com . What I would like to add to this is the ability to create additional markers on the map that I create from the browser of my phone while moving along my trip bu having a php form that would have text fields that I could enter a label and comment for a marker and then when the script wrote the data to the text file it would also add data from the instamapper feed such as longitude and latitude to finish off the row of data to create the markers from since that location data would be accurate at the most recent time of sync with the server. So essentially doing what you have done only adding this other source of data. Once this is setup one of the form fields can be an image link that I can create from a photo uploaded from my phone to my dropbox account since it’s easy to do it that way. Example map is using a google docs spreadsheet as the data source for the markers since I could do that manually to create the example.
In this case, i would keep using http://instamapper.com (it’s a great application i use it as well), to show the route and the full path of the trip.
If you want to add custom markers i would use twitter. There you can add your current location, images and a description of what’s happening (or any other mobile app which allows you to post you current location).
To then generate the map you combine the two data files:
1. instamapper data for the route
2. twitter api data for custom marker
Great idea, would be interesting to build an example on how to combine instamapper and twitter into one custom map.
Hope you got my point and will look into it once i have a bit more time.
Twitter sounds like an interesting approach to integrate photo, location and message if i could setup a feed with the data i wanted. searching for that I haven’t found anything that is within my capabilities. Do you know of any tutorials on that? The data that I need is right there by accessing http://www.instamapper.com/api?action=getPositions&key=4964919593082806954&num=1&format=json
and your other post: http://blog.sofasurfer.ch/2011/03/04/php-simple-comments-readwrite-json-data-to-text-file/
looks like it could use that date to include in the text file it creates.