Put markers from JSON data for Google MAPS API v3

I have a MySQL database that I created a PHP script to pull this data into JSON format. I know that I need to take this JSON output and create markers on a Google map. It seems simple, but I only need tokens to show if one of the values โ€‹โ€‹from the JSON output returns true. I'll tell you how markers should be displayed.

Json output

gpsStatus": "true", = Show streamOffline.png icon/marker If gpsStatus & "streamStatus": "true", Then show the streamOnine.png icon/marker If gpsStatus": "false" the show or remove from map the streamOffline.png icon/marker 

Thus, basically the only time the icon / creator should be displayed is if gpsStatus ":" true ", but depending on the state of the streamStatus determines whether it displays streamOffline.png icon / marker or streamOnline.png icon /marker.gpsStatus ":" false "removes or does not show the marker regardless of the value of streamStatus.

Another twist - I'm trying to update / update markers without reloading the map based on this data from lat / lng values โ€‹โ€‹from JSON output. If I also try to pull other values โ€‹โ€‹from JSON output so that I can put data in infowidows, etc.

I searched for months on how to do this on both Stack, Google, and YouTube, and tried different things (too many things to list and publish here), but most of the examples on the air don't apply to me or are out of date, and I canโ€™t work for my needs. I am terrible when it comes to JavaScript and Google Maps.

So, is there anyone who could give me an example based on my situation, how to take JSON data and skip it to map dynamic markers based on the / s value of some objects and update / update when lat / lng values are changed and then the marker is deleted when "gpsStatus" shows false, and also knows which keys to use in other areas?

Here is my JSON output.

http://stream.dfwstormforce.com/test/api.php

Here is my test card with a static marker and how it should look with the filled data that I am trying to execute.

http://stream.dfwstormforce.com/test/test.html

+5
source share
3 answers

I tried to change the code to what I understood from the description above, now you can extend it.

  var customIcons = { offline: { icon: 'http://stream.dfwstormforce.com/images/icons/gpsOffline.png' }, online: { icon: 'http://stream.dfwstormforce.com/images/icons/gpsOnline.png' } }; var getCustomIcons= function (streamdata){ var iconUrl=customIcons.online; if(streamdata.gpsStatus=='false') { iconUrl=customIcons.offline.icon; }else { iconUrl=customIcons.online.icon; } return iconUrl; } $.getJSON('http://stream.dfwstormforce.com/inc/api.php', function(responsedata) { $.each( responsedata.streamers, function(i, value) { if(value.lat!="" && value.lng!="" ) { var marker = new google.maps.Marker({ position: {lat: parseFloat(value.lat), lng: parseFloat(value.lng)}, animation: google.maps.Animation.DROP, title: value.DisplayName+','+ value.ChaserLocation, icon: getCustomIcons(value), map: map }); marker.addListener('click', function() { infowindow.open(map, marker); }); } }); }); 
+3
source

The problem is that you draw your latitude and longitude as a marker, after receiving a response from $.getJSON you convert them using only parseFloat, but lat / lng contain the characters N, E, W and S, so the parseFloat method does not work .

i.e. you lat / lng look like this

  "lat": "N32.95421", "lng": "W96.38196", 

Therefore, when you use parseFloat in this part of the code, the result is NaN

 $.each(responsedata.streamers, function(i, value) { if (value.lat != "" && value.lng != "") { var myLat = parseFloat(value.lat); // HERE on this line check in your CONSOLE the result is NaN console.log(myLat); var marker = new google.maps.Marker({ position: { lat: value.lat, lng: value.lng }, animation: google.maps.Animation.DROP, title: value.DisplayName + ',' + value.ChaserLocation, map: map }); } }); 

So, you first need to convert the latitude and longitude format to decimal:

 $.each(responsedata.streamers, function(i, value) { if (value.lat != "" && value.lng != "") { var myLat = ConvertPoint(value.lat); //parseFloat(value.lat); var myLng = ConvertPoint(value.lng); var marker = new google.maps.Marker({ position: { lat: myLat, lng: myLng }, animation: google.maps.Animation.DROP, title: value.DisplayName + ',' + value.ChaserLocation, //icon: getcustomicons(value), map: map }); //marker.addlistener('click', function() { // infowindow.open(map, marker); // }); } }); 

Add this function to your JS code

  function ConvertPoint(stringVal) { // This function will convert you lat, lng - instead of using parseFloat var direction = stringVal.substring(0, 1); var withOutChar = stringVal.substring(1); var point = parseFloat(withOutChar); if (direction == "S" || direction == "W") { point = point * -1; } // Don't do anything for N or E return point; } 

Try it, let me know if the markers are built correctly.

It is connected with several markers and information windows, and then updates them, if they change, you will need to do another job - but first get a marker for building - try without a special icon at the moment. keep it simple, then go to the next step.

+1
source

Here is a complete working example of your page. In this simplified version, your JSON API http://stream.dfwstormforce.com/test/api.php will be loaded periodically every 10 seconds and qualified data will be displayed on the map ( gpsStatus = true ).

The marker icon displayed will depend on the value of streamStatus .

 <!doctype html> <html> <head> <title>Google Map Test Page</title> <style> html, body, .map { width: 100%; height: 100%; background-color: #eee; } </style> </head> <body> <div id="map" class="map"></div> <script> var map = null; var markers = []; // Reload interval in milliseconds. var reloadInterval = 10000; var intervalId = window.setInterval(loadData, reloadInterval); function initMap() { var northTexasPosition = { lat: 32.836, lng: -96.995 }; map = new google.maps.Map(document.getElementById('map'), { center: northTexasPosition, zoom: 7, mapTypeControl: true, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, position: google.maps.ControlPosition.TOP_RIGHT }, }); loadData(); } // Load the markers data from API and display them on the map. function loadData() { $.getJSON('http://stream.dfwstormforce.com/test/api.php', function(responsedata) { clearMarkers(); $.each(responsedata.streamers, function (key, item) { item.lat = parseCoordinateNumber(item.lat); item.lng = parseCoordinateNumber(item.lng); item.gpsStatus = parseBoolean(item.gpsStatus); item.streamStatus = parseBoolean(item.streamStatus); if (shouldAddToMap(item)) { addToMap(item); } }); }); } // Clear all markers from the map. function clearMarkers() { $.each(markers, function (key, marker) { marker.setMap(null); }); markers = []; } // Add marker to the map. function addToMap(item) { var marker = new google.maps.Marker({ position: { lat: item.lat, lng: item.lng }, title: item.DisplayName + ', ' + item.ChaserLocation, icon: getIcon(item.streamStatus), map: map }); markers.push(marker); } // Get the appropiate image url for marker icon. function getIcon(streamStatus) { if (! streamStatus) { return 'http://stream.dfwstormforce.com/images/icons/streamOffline.png'; } return 'http://stream.dfwstormforce.com/images/icons/streamOnline.png'; } // Should we add the marker to the map? function shouldAddToMap(item) { if ($.type(item.lat) === 'null' || $.type(item.lng) === 'null') { return false; } return item.gpsStatus === true; } // Parse coordinate number like 'W96.38188' to appropiate decimal value: -96.38188 // return null if it invalid. function parseCoordinateNumber(val) { if ($.type(val) === 'number') { return parseFloat(val); } if ($.type('val') !== 'string') { return null; } val = val.trim(); if (val.length === 0) { return null; } var directionPart = val.substr(0, 1).toUpperCase(); var valuePart = parseFloat(val.substring(1)); if ($.inArray(directionPart, ['N', 'E']) >= 0) { return isNaN(valuePart) ? null : valuePart; } if ($.inArray(directionPart, ['S', 'W']) >= 0) { return isNaN(valuePart) ? null : -valuePart; } val = parseFloat(val); return isNaN(val) ? null : val; } // Parse boolean value. function parseBoolean(val) { if ($.type(val) === 'boolean') { return val; } if (val === 1) { return true; } if (val === 0) { return false; } if ($.type('val') !== 'string') { return null; } val = val.trim().toUpperCase(); if (val === 'TRUE') { return true; } if (val === 'FALSE') { return false; } return null; } </script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async="defer"></script> </body> </html> 

As @Dawood Awan pointed out, the main problem is that your lat and lng data use the degree direction (N, S, E, W). You must analyze this data in the appropriate coordinate value in decimal format. Here is the part of my code above that will parse lat and lng :

 function parseCoordinateNumber(val) { if ($.type(val) === 'number') { return parseFloat(val); } if ($.type('val') !== 'string') { return null; } val = val.trim(); if (val.length === 0) { return null; } var directionPart = val.substr(0, 1).toUpperCase(); var valuePart = parseFloat(val.substring(1)); if ($.inArray(directionPart, ['N', 'E']) >= 0) { return isNaN(valuePart) ? null : valuePart; } if ($.inArray(directionPart, ['S', 'W']) >= 0) { return isNaN(valuePart) ? null : -valuePart; } val = parseFloat(val); return isNaN(val) ? null : val; } 

This will allow the coordinate value in a number or line with a direction (N, S, E or W). I have not dealt with the correct range of latitude or longitude, but you can also add this. The function will return null if this coordinate is not valid.

Also, be sure to replace the Google Maps API with yours:

 <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async="defer"></script> 

Hope this helps you!

+1
source

Source: https://habr.com/ru/post/1259246/


All Articles