I'm starting to learn Google Map. It's strange that when statically declared, markers are working and being displayed, but when they come from DB, they aren't being drawn on map.
// var markers = [[15.054419, 120.664785, 'Device1'], [15.048203, 120.692186, 'Device 2'], [15.033303, 120.694611, 'Device 3']];
var markers = [];
I have the entire code here, maybe I am missing something? I even used console log and I successfully pass all data from ajax to markers variable.
I think I got this code somewhere here in SO and modified it to fit in for my DB calls for records. I hope you can help me out on this one. Thank you!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize"></script>
<script type="text/javascript">
var map;
var global_markers = [];
// var markers = [[15.054419, 120.664785, 'Device1'], [15.048203, 120.692186, 'Device 2'], [15.033303, 120.694611, 'Device 3']];
var markers = [];
var infowindow = new google.maps.InfoWindow({});
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(15.058607, 120.660884);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$.ajax({
type: 'GET',
url: 'control_panel/get_device_list_ajax',
success:
function (data) {
data = JSON.parse(data);
if (data['success']){
var device = data['device_list'];
device.forEach(function (dev) {
markers.push([dev['dev_geolat'], dev['dev_geolng'], dev['dev_name']]);
//console.log(markers);
});
addMarker();
} else {
}
}
});
}
function addMarker() {
console.log(markers);
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i][0]);
var lng = parseFloat(markers[i][1]);
var trailhead_name = markers[i][2];
var myLatlng = new google.maps.LatLng(lat, lng);
var contentString = "<html><body><div><p><h2>" + trailhead_name + "</h2></p></div></body></html>";
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "Coordinates: " + lat + " , " + lng + " | Trailhead name: " + trailhead_name
});
marker['infowindow'] = contentString;
global_markers[i] = marker;
google.maps.event.addListener(global_markers[i], 'click', function() {
infowindow.setContent(this['infowindow']);
infowindow.open(map, this);
});
}
}
window.onload = initialize;
</script>
EDIT
Here is the jsfiddle I used to work with this one http://jsfiddle.net/kjy112/ZLuTg/ (thank you to the one that lead me to this)
Could be related to the way you accessing to json rendered by ajax
markers.push([dev.dev_geolat, dev.dev_geolng, dev.dev_name]);
or the json content
I don't know how to close this question as I overlooked some problems on my DB but I'll be posting my answer if someone may come with the same problem (well, I am not sure about that hehe)
I get the same response from AJAX of the values in DB and I am not able to draw markers on MAP, I found that db->table->fields LAT LNG are referenced with a data type of DECIMAL (7,5) and changed it to FLOAT (10, 6) as to what is found in this GOOGLE MAP Tutorial - Using PHP/MySQL with Google Maps.
The issue at the field before was that higher values tend to be saved as 99.999999 instead of the actual value (e.g. 120.XXXXX) .
Related
I will start by saying that I am relatively new to JS, so please forgive my ignorance if this is obvious.
I am trying to add markers to a google map. I have created an array coordList, then used the geocoding api to get the lag and long from the addresses and pushed them into coordList.
I am now trying to use the coordList array to plot markers on the map, however I cannot seem to get the values from the coordList array. When I run console.log(typeof coordList) - it tells me it's an object, but when i look at the array with console.log(coordList) it just looks like a normal array?
var coordList = [];
var address = [];
address.push('52+Kalynda+pde,+bohle+plains,+QLD')
address.push('51+Frank+St,+Kirwan+QLD+4817');
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: new google.maps.LatLng(-19.259854,146.8001348),
mapTypeId: 'roadmap'
});
}
function getLatLong(address){
var index;
for (index = 0; index < address.length; ++index) {
var request = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + address[index] + '&key=[MY_key]';
$.getJSON( request, function( data ) {
var lat = data.results[0].geometry.location.lat;
var lng = data.results[0].geometry.location.lng;
var coords = [];
coords.push(lat);
coords.push(lng);
//push coords into coordList
coordList.push(coords);
});
}
}
// Loop through the results array and place a marker for each
// set of coordinates.
function addMarkers(coordList) {
for (var i = 0; i < coordList.length; i++) {
var coords = coordList[i];
var latLng = new google.maps.LatLng(coords[0],coords[1]);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
}
}
getLatLong(address);
addMarkers(coordList);
Your problem is that $.getJSON() is an asynchronous request and your code executes addMarkers() before than $.getJSON() finishes, so coordList is empty.
You can add the markers inside $.getJSON() callback. For example:
var address = [];
address.push('52+Kalynda+pde,+bohle+plains,+QLD')
address.push('51+Frank+St,+Kirwan+QLD+4817');
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: new google.maps.LatLng(-19.259854,146.8001348),
mapTypeId: 'roadmap'
});
}
function getLatLongAndAddMarkers(address){
var index;
for (index = 0; index < address.length; ++index) {
var request = 'https://maps.googleapis.com/maps/api/geocode/json?dress=' + address[index] + '&key=[MY_key]';
$.getJSON( request, function( data ) {
var latLong = new google.maps.LatLng(data.results[0].geometry.location);
//add markers here
var marker = new google.maps.Marker({
position: latLong,
map: map
});
});
}
}
getLatLongAndAddMarkers(address);
I am trying to render Google map with Latitude and Longitude from my MVC Model by using different examples. Google Map is displaying fine but it is not displaying the markers. I am very new to the Google Maps and feeling completely clueless about it. Can please anyone tell me how I can get the markers?
My MVC view is as follow
if (Model.WidgetType == "Map")
{
<div class="experienceRestrictedText">
<script src="//maps.google.com/maps/api/js?sensor=false&callback=initialize" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
var London = new google.maps.LatLng(#Html.Raw(Json.Encode(Model.UserLatitude)), #Html.Raw(Json.Encode(Model.UserLongitude)));
// These are options that set initial zoom level, where the map is centered globally to start, and the type of map to show
var mapOptions = {
zoom: 14,
center: London,
mapTypeId: google.maps.MapTypeId['ROADMAP']
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
$.get("/Home/GetMapLocations", function(data){
$.each(data, function(i, item){
var marker = new google.maps.Marker({
'position' : new google.maps.LatLng(item.Latitude, item.Longitude),
'map' : map,
'title': item.EngineerName
});
});
});
#*var data = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.lstMapLocations));
$.each(data, function (i, item){
var marker = new google.maps.Marker({
'position' : new google.maps.LatLng(item.Latitude, item.Longitude),
'map' : map,
'title': item.EngineerName
});
});*#
}
</script>
<div class="map" id="map" style="width:690px; height:400px;"></div>
</div>
}
MVC Controller is as follow
public ActionResult GetMapLocations()
{
var lstMapLocations = new List<MapLocation>();
var mapLocationModel1 = new MapLocation
{
EngineerName = "Engineer1",
SiteName = "Site1",
Latitude = 51.507351,
Longitude = -0.127758,
LstDouble = new List<double>()
};
var mapLocationModel2 = new MapLocation
{
EngineerName = "Engineer2",
SiteName = "Site2",
Latitude = 51.481728,
Longitude = -0.613576,
LstDouble = new List<double>()
};
var mapLocationModel3 = new MapLocation
{
EngineerName = "Engineer3",
SiteName = "Site3",
Latitude = 51.628611,
Longitude = -0.748229,
LstDouble = new List<double>()
};
var mapLocationModel4 = new MapLocation
{
EngineerName = "Engineer4",
SiteName = "Site4",
Latitude = 51.26654,
Longitude = -1.092396,
LstDouble = new List<double>()
};
lstMapLocations.Add(mapLocationModel1);
lstMapLocations.Add(mapLocationModel2);
lstMapLocations.Add(mapLocationModel3);
lstMapLocations.Add(mapLocationModel4);
foreach(var item in lstMapLocations)
{
item.LstDouble.Add(item.Latitude);
item.LstDouble.Add(item.Longitude);
item.LatLong = item.LstDouble.ToArray();
}
return Json(lstMapLocations);
}
I have found a work around to my problem and thought to share it for those who may stumble upon a similar issue. Courtesy stack overflow post particularly the answer posted by Atish Dipongkor. There may well be a better alternative to this problem but this approach has resolve my problem. I have made little change in that answer as Atish has used apostrophes while retrieving data from model which can break the functionality if any of the model field has string data with apostrophe in it. My appended solution with the above dummy data (in my question) is as follow
<div class="experienceRestrictedText">
<script src="//maps.google.com/maps/api/js?sensor=false&callback=initialize" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
var London = new google.maps.LatLng(#Html.Raw(Json.Encode(Model.UserLatitude)), #Html.Raw(Json.Encode(Model.UserLongitude)));
// These are options that set initial zoom level, where the map is centered globally to start, and the type of map to show
var mapOptions = {
zoom: 8,
center: London,
mapTypeId: google.maps.MapTypeId['ROADMAP']
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
#foreach (var item in Model.lstMapLocations)
{
<text>
var markerLatLong = new google.maps.LatLng(#(item.Latitude), #(item.Longitude));
var markerTitle = #Html.Raw(Json.Encode(item.EngineerName));
var markerContentString = #Html.Raw(Json.Encode(item.EngineerName)) + " At " + #Html.Raw(Json.Encode(item.SiteName));
var infowindow = new google.maps.InfoWindow({
content: markerContentString
});
var marker = new google.maps.Marker({
position: markerLatLong,
title: markerTitle,
map: map,
content: markerContentString
});
google.maps.event.addListener(marker, 'click', (function (marker) {
return function () {
infowindow.setContent(marker.content);
infowindow.open(map, marker);
}
})(marker));
</text>
}
}
</script>
<div class="map" id="map" style="width:690px; height:400px;"></div>
</div>
I have implemented Google Maps JavaScript API v3 to contrive a custom store locator for my company's website. Let me start by saying that the code I have works for the two stores, but it would not be efficient or feasible if I added any more stores because of the "hacky" code used to make it work.
I am using the Google Maps Places Library to send "place details" requests to Google using the getDetails() method. On the callback, I am receiving the InfoWindow information (name, address, location) for each of my store locations.
I create a marker for each place, then use google.maps.event.addListener to coordinate the Place, Marker, and InfoWindow objects. This is where I encounter problems. The place details requests are not always received in the same order they are sent which throws off the indexing of my buttons that have a data-marker attribute set to 0 and 1, respectively, to correlate to the map markers.
Is there anyway to delay the second request until the first is finished? or write the script in a way that maintains ordinal integrity?
The first snippet of code below is my event handler to bind the click listener to each button using the .place.placeId property of the marker rather than the preferred technique of using the index of the markers array (the markers array holds the place details for the two stores).
None of the demos or examples in the Google Maps API documentation (Places Library) delineate the procedure for multiple places. Any tips, resources, or suggestions will be much appreciated
Website: http://m.alliancepointe.com/locate.html
Event Handler
$(".loc-btn").on('click', function () {
var me = $(this).data('marker');
var place1 = markers[0].place.placeId;
var myIndex = me == place1 ? 0 : 1;
google.maps.event.trigger(markers[myIndex], 'click');
});
Full JS
var markers = [];
var map;
var infowindow;
var service;
function initialize() {
var index;
var daddr;
var idVA = 'ChIJKezXgqmxt4kRXrAnqIwIutA';
var geoVA = '38.80407,-77.062881/Alliance+Pointe,+LLC';
var idDC = 'ChIJDQlqOLG3t4kRqDU3uNoy4hs';
var geoDC = '38.90188,-77.049161/Alliance+Pointe,+LLC';
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
center: {lat: 38.90188, lng: -77.049161},
zoom: 10,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
};
map = new google.maps.Map(document.getElementById('map'),
mapOptions);
var request = [
{placeId: idVA, location: {lat: 38.80407, lng: -77.062881}},
{placeId: idDC, location: {lat: 38.90188, lng: -77.049161}}
];
var office = [
"Main Office",
"Principal Office"
];
infowindow = new google.maps.InfoWindow();
service = new google.maps.places.PlacesService(map);
for (var i = 0; i < request.length; i++) {
service.getDetails(request[i], function (placeResult, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var id = placeResult.place_id;
var location = placeResult.geometry.location;
var trimAddr = placeResult.formatted_address.split(", ");
var image = {
url: 'images/icons/AP-marker_large.png',
scaledSize: new google.maps.Size(32, 54)
};
var marker = new google.maps.Marker({
map: map,
place: {
placeId: id,
location: location
},
icon: image,
title: "Get directions"
});
google.maps.event.addListener(marker, 'click', function () {
if (id == idVA) {
index = 0;
daddr = geoVA;
trimAddr[0] = "1940 Duke St #200";
} else {
index = 1;
daddr = geoDC;
trimAddr[0] = "2200 Pennsylvannia Ave NW";
}
infowindow.setContent('<div class="info-window title">' + placeResult.name + "</div><div class='info-window sub-title'>" + office[index] + '</div><div class="info-window">' + trimAddr[0] + '<br>' + trimAddr[1] + ", " + trimAddr[2] + '</div><div class="info-window direction-div"><div class="direction-icon"></div><a class="google-link save-button-link" target="_blank" href="https://www.google.com/maps/dir/Current+Location/' + daddr + '">Get Directions</a></div>');
infowindow.open(map, marker);
});
markers.push(marker);
//bounds.extend(location);
}
});
}
if (!bounds.isEmpty()) {
map.fitBounds(bounds);
}
$(".loc-btn").on('click', function () {
var me = $(this).data('marker');
var place1 = markers[0].place.placeId;
var myIndex = me == place1 ? 0 : 1;
google.maps.event.trigger(markers[myIndex], 'click');
//console.log("PlaceId = " + me);
//console.log("Adj index = " + myIndex);
//console.log("0:VA array index = " + markers[0].place.placeId);
//console.log("1:DC array index = " + markers[1].place.placeId);
});
google.maps.event.addListenerOnce(map, 'idle', function () {
$.mobile.loading("hide");
$(".loc-btn").prop("disabled",false);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
HTML: Map & Buttons
<div data-role="content" class="full-width">
<figure id="map"></figure>
<div class="loc-btn-set">
<button disabled data-role="none" data-theme="a" data-marker="ChIJKezXgqmxt4kRXrAnqIwIutA" class="loc-btn nightly-button">VA <span>- Alexandria</span></button>
<button disabled data-role="none" data-theme="b" data-marker="ChIJDQlqOLG3t4kRqDU3uNoy4hs" class="loc-btn nightly-button">DC <span>- Washington</span></button>
</div>
</div>
The simpliest approach based on the given code would be to add the click-handler for the buttons inside the getDetails-callback.
Add this after the creation of the marker:
$('.loc-btn[data-marker="'+id+'"]').click(function(){
google.maps.event.trigger(marker,'click');
});
My Google Map is showing correctly, also centering the map is working like a charm. But when I want to add some marker (just the marker, don't want to reload the whole map) nothing happens (there are no visible markers on the map).
My script looks like this:
function g_maps(){
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(48.2136522, 16.386172),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
}
function g_maps_marker(coordinates){
var locations = [ coordinates ];
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
visible: true
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
The (important) part of my ajax request looks like that:
...
success:function(data){
$('#pagination_content table').empty();
data = $.parseJSON(data);
i = 1;
coordinates = "";
for(var i in data.results) {
$('#content_table').append("blablabla");
coordinates += "['" + data.results[i].title + "', " + data.results[i].lat + ", " + data.results[i].lat + ", " + i++ + "], ";
};
coordinates = coordinates.slice(0, -2)
g_maps_marker(coordinates);
},
...
The output of coordinates is this:
['abc', 48.1857442, 48.1857442, 0], ['xyz', 48.2136522, 48.2136522, 1]
The function g_maps is called at the document.ready() event.
I'm using the API v3.
You are slicing coordinates = coordinates.slice(0, -2); and then again making an array out of coordinates like this var locations = [ coordinates ];.
I' am confused a bit. slice already gives you an array so why making an array again? Are you sure that your loop gets executed?
Maybe you should remove var locations = [ coordinates ]; from g_maps_marker and then try again. I hope it will work.
** Edit **
After analyzing code a bit further I found that you are trying to use string which looks like an array and then trying to loop around it. This will not work.
For example
a = "[1, 2, 3]";
b = [a];
b[0][0]; // => will result in [ and not in your desired element
You should use following code in-order to make array objects for coordinates.
i = 1;
coordinates = [];
for(var i in data.results)
{
$('#content_table').append("blablabla");
var coordinate = [];
coordinate.push(data.results[i].title);
coordinate.push(data.results[i].lat);
coordinate.push(data.results[i].lon);
coordinates.push(coordinate);
};
Also it seems that you forgot to use longitude while creating coordinates array and used latitude two times. I have fixed this in my code.
I am sending the google.geocoder several addresses, but the values in the results[0].geometry.location are all the same. I believe I have accounted for the asynchronous nature of the call using a call back. When I add alerts to see the values returned, the addresses passed in the geocoder.geocode( { 'address': addr }... are all correct, the status returned is "ok", but the lat/long are the same for every call. I am not very well versed in JavaScript, and am new to the .net environment, so any help would be greatly appreciated.
This code worked perfectly from 4/1/2012 until some time near December or early 2013. Has something changed with the Google API? I have looked at google's website but cannot find anything.
Here is my initial call:
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
var directionsDisplay;
var directionsRenderer;
var startPoint;
var endPoint;
function initialize()
{
geocoder = new google.maps.Geocoder();
codeAddress();
var myOptions =
{
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
setMarkers(map);
google.maps.event.addListener(map, 'click', function(event) {
dirMarker(event.latLng);
startPoint = event.latLng;
});
}
function codeAddress()
{
var address = document.getElementById("<%=hCVT.ClientID%>").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert("Status: " + status + "res from CODE ADDRESS -- " + results[0].geometry.location); //TO REMOVE
map.setCenter(results[0].geometry.location);
} else {
alert("Geocode of CVT was not successful for the following reason: " + status);
}
});
}
The function to set the markers and info window information (I have removed some of the code that seemed irrelevant to the question)
function setMarkers(map)
{
// Add markers to the map
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
var places = new Array([,,,,]);
var xx = String;
xx = document.getElementById("<%=addys.ClientID%>").value;
var placeholder = xx.split(",");
var latlng;
var i = 0;
for(var y = 0; y < (placeholder.length / 5 - 1); i=i+5)
{
places[y, 0] = placeholder[i];
places[y, 1] = placeholder[i+1]; //Unit Status
places[y, 2] = placeholder[i+2]; // Long - not used
places[y, 3] = placeholder[i+3]; // Zindex
places[y, 4] = placeholder[i+4]; // HTML for information window
addr = places[y,0];
ustat = places[y,1];
zind = places[y,3];
iwdata = places[y,4];
getLatLong(addr, iwdata, ustat, zind, function(latlng, addr, iwdata, ustat, zind) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
html: iwdata,
icon: pinImage,
shadow: pinShadow,
shape: shape,
title: addr,
zIndex: parseInt(places[y,3])
});
var infowindow = new google.maps.InfoWindow({
content: iwdata});
});
y = y + 1;
}
}
The function where I believe the problem lies follows. Since there were several addresses being sent to google, I added a built in timeout so as to not exceed the limitations. Again, this all worked for about 8 months and has suddenly stopped. Where several markers used to show on the map, now there is one marker which is seeming over written because the lat/lng return is the same as the initial call in the codeAddress() function. In an effort to find a solution I have been adding alerts to show me the return values. I was getting confused with the bugzilla values as they would take me over to the google javascript which was completely over my head.
function getLatLong(addr, iwdata, ustat, zind, callback){
geocoder.geocode( { 'address': addr}, function(results, status){
if (status == google.maps.GeocoderStatus.OK){
callback(results[0].geometry.location, addr, iwdata, ustat, zind);
} else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
window.setTimeout(function() {self.getLatLong(addr, iwdata, ustat, zind, callback);
},500);
} else {
alert("Address Geocode failure: " + addr + " ==== " + status + "Y value: " + zind + " res ---" + res);
}
});
}
Can anyone help me with this?
Well, after some long hours of staring at this code trying to figure it out, I finally stumbled on something using smartly placed alerts. Apparently the addr variable contained "'" and the geocoder was not able to provide lat/lng data as a result. Adjusted this line:
addr = places[y,0].replace(/'/g, "");
All works now.