I have some JSON data which i want to appear on google map. But the thing is its showing nothing. The JSON data will load from a server where the index file is also located. when i try to debug the problems i got some errors that i didn't understood. So, here is my data:
var map, infowindow; ////
var json = $.getJSON( "file.json", function( json ) {
function initialize() {
var mapOptions = {
////
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var bounds = new google.maps.LatLngBounds();
var responses = json.ResponseData;
for(var i = 0; i <= responses.length; i++) {
// Adding a new marker for the object
var position =
new google.maps.LatLng( responses.CoordinateY, responses.CoordinateX ); ////
bounds.extend( position ); ////
var marker = new google.maps.Marker({
position: position, ////
map: map,
draggable: true,
animation: google.maps.Animation.DROP,
title: responses.BuildingName
});
// Adding a new info window for the object
var clicker = addClicker(marker, responses.BuildingName); ////
} map.fitBounds( bounds ); ////
// Adding a new click event listener for the object
function addClicker(marker, content) {
google.maps.event.addListener(marker, 'click', function() {
if (infowindow) {infowindow.close();}
infowindow = new google.maps.InfoWindow({content: content});
infowindow.open(map, marker);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
});
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB6U22yg_ty9a4LFvJi6E0rYCyGwYt04Xk&callback=json">
</script>
<script src="https:////cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="map-canvas"></div>
the json data file link is JSON DATA
and here is the link of the html file HTML
The thing is i want to show the markers on google map. The json file will be updating all time.
Thanks
The callback in your API load is incorrect. json is not a function.
Related
I'm using google maps API with multiple equipment locations fed from a Mysql database. I can successfully show the markers on the map and make them draggable. If I drag any marker to a new location, it prompts to ask if you want to update the database and if yes, supposedly sends the updated lat/lng to the database. This isn't working correctly, and instead always only updates the last item in the markers array.
Note that I have done this successfully with a single marker, and am able to update it anywhere I drag the new marker. But for multiple markers, I just don't seem to be able to get the current dragged marker's id and new lat/lon data to send back to the ajax call to update the database for that particular marker. I'm thinking it's because I'm not accessing the current marker's data, but I'm struggling with how to get that.
Any ideas what I'm doing wrong? I know it's got to be something simple I'm overlooking.
Here's a Fiddle to demonstrate my issue: JSFiddle
<!-- php stuff would be up here to get the database and feed the google API. Instead here I've just created the const markers to show the markers. -->
<html>
<head>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
</head>
<body>
<div id="mapCanvas"></div>
</body>
</html>
<style>#mapCanvas {
width: 100%;
height: 850px;
}
</style>
<script>
function initMap() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'hybrid'
};
// Display a map on the web page
map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
map.setTilt(100);
// Multiple markers location, latitude, and longitude
const mapIcon = "https://maps.google.com/mapfiles/marker_grey.png";
const markers = [
['Pike-1', 35.42526738862006, -81.172076628969, mapIcon, 10819],
['Pike-2', 35.425311504805924, -81.17216095766817, mapIcon, 10820],
['Pike-3', 35.425171475622824, -81.17188553479076, mapIcon, 10821],
['Pike-4', 35.42530668524588, -81.17134696588283, mapIcon, 10822],
['Pike-5', 35.42559347700399, -81.17218140606506, mapIcon, 10823],
['Pike-5', 35.426094498781885, -81.17195101338058, mapIcon, 26455],
['Pike-6', 35.42532308059036, -81.17215505637606, mapIcon, 26456]
];
// Place each marker on the map
for (i = 0; i < markers.length; i++) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
var eid = markers[i][4];
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
draggable: true,
animation: google.maps.Animation.DROP,
icon: markers[i][3],
equipid: markers[i][4],
title: markers[i][0]
});
//Add listener if marker is moved, then ask to update and call function if yes.
google.maps.event.addListener(marker, 'dragend', function() {
var mytitle = marker.equipid;
var latLng = marker.latLng;
let updateDB = confirm('Update location to database?');
if (updateDB) {
update_marker(latLng, mytitle);
console.log(latLng, mytitle);
}
});
// Center the map to fit all markers on the screen
map.fitBounds(bounds);
function update_marker(Marker, mytitle)
//This is the function that sends the update to the ajax call. Currently not working.
//with multiple markers, I can't get the selected marker equipment ID and new lat/lng.
{
//Update saved marker from DB and map using jQuery Ajax
var mLatLang = marker.getPosition().toUrlValue(); //get marker position - this does not get the marker position, but the last row of the result set from mysql
var mytitle = marker.equipid; //get marker equipment id - this currently gets the last row[id] of the mysql result set.
var myData = {
update: 'true',
name: mytitle,
latlang: mLatLang
};
$.ajax({
type: "POST",
url: "equipment-ajaxupdate-gps.php",
data: myData,
success: function(data) {
alert(data);
console.log(mytitle, mLatLang);
},
error: function(xhr, ajaxOptions, thrownError) {
alert("Error! Update Failed!")
console.log(mytitle, mLatLang);
}
});
}
} //end of for( i = 0)
// Set zoom level
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(19);
google.maps.event.removeListener(boundsListener);
});
} //End of function(initmap)
// Load initialize function
google.maps.event.addDomListener(window, 'load', initMap);
</script>
I made a few changes to your code - this seems to work OK as it sends the correct details via the ajax call so updating the db should be trivial from that point forth.
With the script tag that loads the Google Maps api you specify the callback function so there is no need to then manually call initMap function as you are with google.maps.event.addDomListener(window, 'load', initMap);
The update_marker function can be simplified to use a single argument that is the reference to the marker itself. This greatly simplifies accessing properties of the marker itself as you can see below where self is used within the function ( could be any name - it is a reference to the marker )
Rather than the clunky for (i = 0; i < markers.length; i++) { loop to iterate through the array elements a simpler forEach loop means you no longer need to use the name[i][2] type syntax - though if the actual data is coming from your db you'll likely be using JSON anyway which would necessitate a different loop strategy.
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' && isset(
$_POST['update'],
$_POST['name'],
$_POST['latlang']
)){
$_POST['date']=date( DATE_RSS );
$payload=json_encode( $_POST );
exit( $payload );
}
?>
<html>
<head>
<style>
#mapCanvas {
width: 100%;
height: 850px;
}
</style>
<script src='//code.jquery.com/jquery-latest.js'></script>
</head>
<body>
<div id="mapCanvas"></div>
<script>
function initMap() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId:'hybrid'
};
map = new google.maps.Map( document.getElementById("mapCanvas"), mapOptions );
map.setTilt(100);
const mapIcon = "https://maps.google.com/mapfiles/marker_grey.png";
const markers = [
['Pike-1', 35.42526738862006, -81.172076628969, mapIcon, 10819],
['Pike-2', 35.425311504805924, -81.17216095766817, mapIcon, 10820],
['Pike-3', 35.425171475622824, -81.17188553479076, mapIcon, 10821],
['Pike-4', 35.42530668524588, -81.17134696588283, mapIcon, 10822],
['Pike-5', 35.42559347700399, -81.17218140606506, mapIcon, 10823],
['Pike-6', 35.426094498781885, -81.17195101338058, mapIcon, 26455],
['Pike-7', 35.42532308059036, -81.17215505637606, mapIcon, 26456]
];
// Place each marker on the map.
// A forEach loop is, IMO, cleaner than the for(i=0;i<n;i++) {} etc
markers.forEach(a=>{
let title=a[0];
let latlng=new google.maps.LatLng( a[1], a[2] );
let icon=a[3];
let eid=a[4];
let marker=new google.maps.Marker({
position: latlng,
map: map,
draggable: true,
animation: google.maps.Animation.DROP,
icon:icon,
/* custom properties */
equipid:eid,
title:title
});
bounds.extend( latlng );
google.maps.event.addListener( marker, 'dragend', function(e) {
if( confirm('Update location to database?') ) {
/*
Within the context of this function `this` refers
to the marker itself that invoked the event handler.
Passing `this` as the function parameter to `update_marker`
allows us to access all properties of the marker from
within that function.
As the marker has been assigned custom properties when it was
added to the map we can access those easily within `update_marker`
*/
update_marker( this );
console.log('Update - Position:%s, Title:%s', this.getPosition().toUrlValue(), this.title );
}
});
function update_marker( self ){
/*
self is the marker reference
*/
$.ajax({
type:"POST",
url:location.href, //"equipment-ajaxupdate-gps.php"
data: {
update:'true',
name:self.title,
latlang:self.getPosition().toUrlValue()
},
success: function( response ) {
console.log( 'Ajax response: %o',response );
bounds.extend( latlng );
map.fitBounds( bounds );
},
error: function( error ) {
alert( "Error! Update Failed!\n"+error )
}
});
};
});//end forEach loop
map.fitBounds( bounds );
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap"></script>
</body>
</html>
I have this event from myGroup Template:
'click #details': function(e){
// Prevent default actions
e.preventDefault();
// Get groupid
var groupId = e.target.name
group = Groups.findOne(groupId)
lat = group.destination.location.lat
lon = group.destination.location.lon
Session.set('lat', lat);
Session.set('lon', lon);
Router.go('/group/'+groupId);
}
This event, as you can see, create two session variables and then redirect to another Template called groupMap.
I have this code to run when groupMap is rendered:
Template.groupMembers.rendered = function(){
var map;
var infowindow;
var lat = Session.get("lat");
var lon = Session.get("lon");
console.log(lat,lon)
function initialize() {
var location = new google.maps.LatLng(lat, lon);
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: location,
zoom: 15
});
var request = {
location: location,
radius: 500,
types: ['store']
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
google.maps.event.addDomListener(window, 'load', initialize)
};
It is a simple code that take the previous two variables and then render a map centered in lat and lon, and display some google places markers.
NOTE1: I load the googlemap api on the header
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true&libraries=places"></script>
My problem is: When I click on #details the event work well(create the variables and redirect), after redirect I can see the two variables displayed at the console but the map never render. If I reload the page de map render in blank because the variables disappear and if I change something in the code to trigger the Meteor hot-reload the map will render well.
What can I do to fix this ? (I need to render the map on the 1st load)
The source of your problem lies within the last line of your code:
google.maps.event.addDomListener(window, 'load', initialize)
With this line, you are basically telling your app to initialize the map when the window is loaded. (duh, right?) It's good, when you expect the page to still be loading when calling that statement. But in Meteor, this "windows is loaded" event occurs very few times during your app's runtime: when loading a page of your app "for the first time" on your browser (or pressing F5), and on hot-code reloads.
From that moment on, your app will no longer trigger any more load event on your window (as opposed to multi-pages apps, which "reload" each page as you navigate through them), unless of course you programmatically trigger one in your code.
This is why your map only shows on hot-code reloads. Only then are both your listener active and the window's loaded event being triggered, hence triggering your initialize function.
What you want in your case is to trigger the map every time the template is rendered. To achieve that, what you just need is to call your initialize() function within your rendered hook. Here's an example based on what you have (using the new correct onRendered function):
Template.groupMembers.onRendered(function(){
var map;
var infowindow;
var lat = Session.get("lat");
var lon = Session.get("lon");
console.log(lat,lon)
function initialize() {
var location = new google.maps.LatLng(lat, lon);
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: location,
zoom: 15
});
var request = {
location: location,
radius: 500,
types: ['store']
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
initialize();
});
I am getting latitude & longitude from database table and trying to display markers on ajax success. I am getting latitude & longitude on json format but when tried with loop, markers are not displaying.
My JSON Data:
[
{"latitude":"23.046100780353495","longitude":"72.56860542227514"},
{"latitude":"23.088427701737665","longitude":"72.49273109366186"},
{"latitude":"23.061264193197644","longitude":"72.68224525381811"},
{"latitude":"22.977212139977677","longitude":"72.52191352774389"},
{"latitude":"23.002180435752084","longitude":"72.47590827872045"},
{"latitude":"23.108638843843046","longitude":"72.49444770743139"}
]
Google map with Ajax Code:
<script type="text/javascript">
// Check DOM Ready
$(document).ready(function() {
// Execute
(function() {
// Map options
var options = {
zoom: 6,
center: new google.maps.LatLng(23.039567700000000000, 72.566004499999960000), // Centered
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControl: false
};
// Init map
var map = new google.maps.Map(document.getElementById('map_canvas'), options);
$.ajax({
url: 'get-locations.php',
success:function(data){
var obj = JSON.parse(data);
var totalLocations = obj.length;
for (var i = 0; i < totalLocations; i++) {
// Init markers
var marker = new google.maps.Marker({
position: new google.maps.LatLng(obj[i].latitude + ',' + obj[i].longitude),
map: map,
title: 'Click Me ' + i
});
// Process multiple info windows
(function(marker, i) {
// add click event
google.maps.event.addListener(marker, 'click', function() {
infowindow = new google.maps.InfoWindow({
content: 'Hello, World!!'
});
infowindow.open(map, marker);
});
})(marker, i);
}
}
});
})();
});
</script>
When I tried to pass static latitude & longitude inside the loop marker is displayed:
position: new google.maps.LatLng(23.046100780353495,72.56860542227514),
but not working with dynamic with loop.
Any idea why markers are not displaying?
Thanks.
You're passing the coordinates incorrectly to the google.maps.LatLng constructor. There should be two parameters separated by a comma but you're concatenating them as a string.
The code should look like this:
position: new google.maps.LatLng(obj[i].latitude, obj[i].longitude)
Im working on a google maps plugin (there's always room for another right?) and I'm drawing a preview of the map my users will be inserting into their content. Im able to draw everything I set out to, custom content in the info window, setting the location (through places.Autocomplete) etc. The one thing that is escaping me is custom map icon isn't being drawn.
My goal is to have the default icon drawn on first load, and then update it when it changes
Im not getting any 404 or errors in the console, and I've checked my event handlers and they are all working. Can anyone tell me where I've going astray?
Here is what I have so far:
//Initilize the map
google.maps.event.addDomListener(window, 'load', initialize);
function initialize(infowindow) {
var init_center = new google.maps.LatLng(43.703793, -72.326187);
mapOptions = {
center: init_center,
zoom: parseFloat(mapZoomReturn),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
};
var input = document.getElementById('mapAddress');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
//var marker = new google.maps.Marker({
// position: init_center,
// map: map,
// icon: mapMarkerImageReturn
//});
// Draw the map
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
// marker needs to be set after the map
var marker = new google.maps.Marker({
position: init_center,
map: map,
icon: mapMarkerImageReturn
});
// Set up event listeners
// Info window DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapInfoWindow'),
'change', function() {
mapInfoWindowReturn = escape(jQuery('#mapInfoWindow').val());
// get the extra content from feild, by this time the place_changed even will have fired at least once, so we have these values
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn); // returns formatted markup for info bubble
infowindow.setContent(infowindowPlace);
});
// Marker dropdown selection DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarker'), 'change', update_maker);
// Custom marker text field DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarkerImage'), 'change', update_maker );
function update_maker(){
//update the marker imge - (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
}
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.close();
if (mapMarkerImageReturn !=='' || mapMarkerImageReturn !== false) marker.setVisible(false);
input.className = '';
locPlace = autocomplete.getPlace();
if (!locPlace.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
// If the place has a geometry, then present it on a map.
if (locPlace.geometry.viewport) {
map.fitBounds(locPlace.geometry.viewport);
mapCurrCenter = map.getCenter();
} else {
map.setCenter(locPlace.geometry.location);
map.setZoom(parseFloat(mapZoomReturn));
mapCurrCenter = map.getCenter();
}
// Set the marker image (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
// get the location values for the info bubble
if (locPlace.address_components) {
//console.log(locPlace.address_components);
// Populate values for info bubble
locName = locPlace.name;
locIcon = locPlace.icon;
locAddress = locPlace.formatted_address;
locPhone = locPlace.formatted_phone_number;
locWeb = locPlace.website;
}
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.setContent(infowindowPlace);
infowindow.open(map, marker);
});
}
I have GoogleMaps integrated into my site. I'm having a problem pulling my info from my JSON file into the Info Window when the markers are clicked.
Below is my current code:
/*********** Custom GoogleMaps functions ***********/
if (document.getElementById("events-map")) {
// set json path
var markerFile = '/scripts/json/find-events.json';
// set default map properties
var defaultLatlng = new google.maps.LatLng(41.4925, -99.9018);
// zoom level of the map
var defaultZoom = 4;
// variable for map
var map;
// variable for marker info window
var infowindow;
// List with all marker to check if exist
var markerList = {};
// option for google map object
var myOptions = {
zoom: defaultZoom,
center: defaultLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
/**
* Load Map
*/
function loadMap() {
// create new map make sure a DIV with id myMap exist on page
map = new google.maps.Map(document.getElementById("events-map"), 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, function(i, item) {
// add marker to map
loadMarker(item);
});
});
}
/**
* Load marker to map
*/
function loadMarker(makerData) {
// create new marker location
var myLatlng = new google.maps.LatLng(markerData['xCoordinate'], markerData['yCoordinate']);
// create new marker
var marker = new google.maps.Marker({
id: markerData['id'],
map: map,
title: markerData['propertyName'] ,
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
$.getJSON(markerFile, function(data) {
// show marker window
infowindow.setContent(data);
infowindow.open(map, marker);
});
} else {
alert('Error marker not found: ' + markerId);
}
}
google.maps.event.addDomListener(window, 'load', loadMap);
}
And here is the info that is contained in my JSON file:
{
"markers":[
{
"id":"1",
"xCoordinate" : 34.048928,
"yCoordinate" : -111.093731,
"propertyName" : "Arizona",
"propertyState" : "AZ",
"propertyPhone" : "777.777.7777",
"propertyEmail" : "test#example.com"
},
{
"id":"2",
"xCoordinate" : 38.582526,
"yCoordinate" : -92.510376,
"propertyName" : "Missouri",
"propertyState" : "MO",
"propertyPhone" : "777.777.7777",
"propertyEmail" : "test#example.com"
}
]
}
In
var marker = ...
$.getJSON(markerFile, function(data) {...marker...}
the function(data) is the callback that is called asynchronously when the result of the respective AJAX call is returned. At that moment the local variable marker is no longer in scope. You should apply a closure over the marker:
$.getJSON(markerFile, function(mapMarker) {
var m = mapMarker; // save the current marker in the closure
return function(data) { // return the required callback ...
// show marker window
infowindow.setContent(data);
infowindow.open(map, m);
} (marker) // ... applied to marker
});
There is a typo in your loadMarker function:
makerData should be markerData