How to use Pagination in Google Maps and Ajax - javascript

I have an api where is pagination because of a lot of data. Now I am trying to do Google Maps where I use API to get lat and lng from database. I still get just first page of API Data. What's wrong with my code ? What should I change. Please help. I will be glad to you.
Hi. I have an api where is pagination because of a lot of data. Now I am trying to do Google Maps where I use API to get lat and lng from database. I still get just first page of API Data. What's wrong with my code ? What should I change. Please help. I will be glad to you.
<script>
function initMap(map) {
var start_point = new google.maps.LatLng(27.772321, 1.803125);
// Creating a new map
var map = new google.maps.Map(document.getElementById("companies-map"), {
center: start_point,
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
function setMarkerPoints(map) {
var bounds = new google.maps.LatLngBounds();
var mc = [];
var infoWindow = new google.maps.InfoWindow();
url = '/api/companies/map/',
$.ajax({
type: "GET",
url: url,
dataType: "json",
success: function(data, pagination) {
$.each(data.results, function(marker, data) {
var latLng = new google.maps.LatLng(data.point.latitude, data.point.longitude);
bounds.extend(latLng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
animation: google.maps.Animation.DROP,
map: map,
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent('' + data.name + '<br>' + data.name);
infoWindow.open(map, marker);
});
mc.push(marker);
});
if (pagination.hasNextPage) {
pagination.nextPage();
};
new MarkerClusterer(map, mc, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
},
error: function(data) {
console.log('Please refresh the page and try again');
}
});
//END MARKER DATA
// end loop through json
}
setMarkerPoints(map);
}
google.maps.event.addDomListener(window, 'load', renderGoogleMap);
renderGoogleMap();
</script>
THANK YOU SO MUCH

You need to create a PlaceSearchPagination object in order to access additional pages. The object is created via a callback function.
https://developers.google.com/maps/documentation/javascript/places#place_search_responses
Take a look at the Accessing Additional Results section, specifically under the comments "// Create the places service" and "// Perform a nearby search.".

Related

Google maps v3 API only loading after refresh / Authentication goes very slow

Using Google maps v3 API. When i visit the page with the map i sometimes get following error : "custom.js:46 Uncaught ReferenceError: google is not defined".
API's enabled on the key:
Google Maps Directions API
Google Maps Distance Matrix API
Google Maps Elevation API
Google Maps Geocoding API
Google Maps JavaScript API
When i reload the page, everything is working fine. This doesn't work 100% of the time. Multiple reloads are needed on some occasions.
I did notice that when the map isn't loading correctly this script is running in my head tags:
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps/api/js/AuthenticationService.Authenticate?1shttp%3A%2F%2Fmayan-co.com%2Fen%2Foutlets&MYKEY&callback=_xdc_._h7cv8d&token=60166"></script>
After 10-20 seconds this script goes away and when i refresh the page after this script goes away, my map is working correctly.
Things i tried without results:
Putting the script to load the API in the footer.
Not using async or defer.
Adding specific url's to my api key.
Not using a api key
Loading the api script in the Head of my page:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY" async defer></script>
My script to render the map and place markers on the map (loaded in the footer)
jQuery(document).ready(function($) {
$('#animation').addClass('animate');
$('.heart img').popover({
placement: 'top',
html: true,
container: '#animation',
content: function () {
return $(this).attr('alt');
}
});
$('body').on('click', function(e) {
$('.heart img').each(function() {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.heart img').has(e.target).length === 0) {
$(this).popover('hide');
} else {
$(this).popover('toggle');
}
});
});
function render_map($el) {
var $markers = $(document).find('#locations .data-source li');
var args = {
zoom: 16,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP]
}
};
var map = new google.maps.Map($el[0], args);
map.markers = [];
index = 0;
$markers.each(function() {
add_marker($(this), map, index);
index++;
});
center_map(map);
}
function add_marker($marker, map, index) {
var latlng = new google.maps.LatLng($marker.attr('data-lat'), $marker.attr('data-lng'));
var image = '../../img/maps-leaf.png';
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
map.markers.push(marker);
if ($marker.html()) {
$('#locations .data-display').append('<li class="linkage" id="p'+index+'">'+$marker.html()+'</li>');
$(document).on('click', '#p' + index, function() {
infowindow.open(map, marker);
setTimeout(function() { infowindow.close(); }, 5000);
});
var infowindow = new google.maps.InfoWindow({
content: $marker.html(),
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
function center_map(map) {
var bounds = new google.maps.LatLngBounds();
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
if( map.markers.length == 1 ) {
map.setCenter( bounds.getCenter() );
map.setZoom( 16 );
} else {
map.fitBounds( bounds );
}
}
$(document).ready(function(){
$('#map').each(function(){
render_map( $(this) );
});
});
});
What you describe looks like you try to instantiate the map before the Google Maps API JavaScript is loaded (you're using async attribute there). That's why it sometimes throws google is not defined error.
In other words, document.ready is called before https://maps.googleapis.com/maps/api/js?key=MYKEY is loaded.
Google Maps API allows you to use callback parameter in the URL with a name of a function that's called after the API is fully loaded. See https://developers.google.com/maps/documentation/javascript/tutorial.
So in your case you'll use URL like:
https://maps.googleapis.com/maps/api/js?key=MYKEY&callback=initMap
And then initialize the map:
initMap() {
var map = new google.maps.Map($el[0], args);
}

Google Maps info windows only displays info from the first click

I have a script that:
pulls results from a database in the form of an XML file
parses those results
creates a marker for each result and places it on a map (a single map for all markers)
at the same times, builds a clickable HTML list (sidebar) containing all those results.
When the user clicks on a place name in the sidebar, the info window from the corresponding marker on the map is automatically displayed. Of course the user can also click directly on a marker on the map, and the same info window is also displayed.
This code has been working fine for several years, but last week I noticed that its behavior was now bugged. When viewing some given results, the first click (either on the map or in the sidebar) works fine (the info window opens and displays the correct information), but the following clicks all show the same information from the first click, all in their respective info window. (To be clear: the information shown is the one from the very first click, not from the previous click.)
I've been trying to debug that for hours but I don't understand why it doesn't work anymore. As you can see in my code below, I tried adding a console.log in the google.maps.event.addListener function, to see what data is being worked with when the marker is clicked, but even there, I don't see anything wrong.
Here is my code (simplified to be more readable):
var side_bar_html = '\n';
var gmarkers = []; // array for created markers
var infoWindow;
var center_lat = <?php echo $position_lat; ?>;
var center_lng = <?php echo $position_lng; ?>;
function createMarker(point, name, html, place_id, map) {
var marker, markerOptions;
markerOptions = {
map: map,
position: point,
dataId: place_id,
icon : 'theme/marker.png',
shadow: 'theme/marker_shadow.png'
};
marker = new google.maps.Marker(markerOptions);
infoWindow = new google.maps.InfoWindow({content: html});
google.maps.event.addListener(marker, 'click', function() {
console.log(this, marker, html);
infoWindow.content = html;
infoWindow.open(map, this);
});
gmarkers.push(marker);
side_bar_html += '\n<li>' + name + '</li>';
return marker;
}
function showPlace(i) {
google.maps.event.trigger(gmarkers[i], 'click');
}
function loadEarth(opt, zoom) {
var map, point, mapCenter, mapOptions;
if (zoom === null) {zoom = 7;}
mapCenter = new google.maps.LatLng(center_lat, center_lng);
mapOptions = {
zoom: zoom,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
point = new google.maps.LatLng(parseFloat(center_lat), parseFloat(center_lng));
if (opt != 0) {
map.setMap(new google.maps.Marker(point));
}
}
// receiving results via XML
function go() {
var map, bounds;
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
bounds = new google.maps.LatLngBounds();
$.ajax({
url : 'url/to/data.xml',
type : 'GET',
dataType : 'xml',
success : function(xml) {
var markers, lat, lng, place_id, point, label, html, marker;
markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// extract data for each marker
lat = parseFloat(markers[i].getAttribute("lat"));
lng = parseFloat(markers[i].getAttribute("lng"));
place_id = parseFloat(markers[i].getAttribute("place_id"));
point = new google.maps.LatLng(lat,lng);
label = $(markers[i]).find('label').eq(0).text();
html = $(markers[i]).find('infowindow').eq(0).text();
// marker creation
marker = createMarker(point, label, html, place_id, map);
// extend visible zone to newly added marker
bounds.extend(point);
}
map.setCenter(new google.maps.LatLng(center_lat, center_lng), 7);
bounds.extend(point);
if (markers.length>0) {
document.getElementById("side_results").innerHTML = side_bar_html;
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
} else {
loadEarth();
}
} // end AJAX success
}); // end AJAX
} // end go()
if ($('#places_page').is('.empty')) {
loadEarth(0,8);
} else go();
Any help would be greatly appreciated.
Edit:
As requested, here's a sample of the XML received. In this case, the PHP variables at the start of the script would receive the following values:
$position_lat: 46.9479222
$position_lng: 7.4446085
<?xml version="1.0" encoding="UTF-8"?><markers>
<marker place_id="955" lat="46.950218" lng="7.442429">
<label><![CDATA[<em>Place 955</em><strong>3011 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 955</em><br />Speichergasse 35<br />3011 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
<marker place_id="985" lat="46.942032" lng="7.389993">
<label><![CDATA[<em>Place 985</em><strong>3018 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 985</em><br />BrĂ¼nnenstrasse 106A<br />3018 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
</markers>
The Google Maps API is included via this line:
<script src="http://maps.google.com/maps/api/js?v=3&sensor=true&language=fr&key=..."></script>
Edit 2:
Changing the API call to force it to use version 3.18 does fix the problem:
<script src="http://maps.google.com/maps/api/js?v=3.18&sensor=true&language=fr&key=..."></script>
Obviously this is a temporary fix, since v. 3.18 won't always be available. Now I need to understand what change in the 3.19 version made this bug appear. Any suggestion is still appreciated. :)
This undocumented usage:
infoWindow.content = html;
May be the issue. Should be:
infoWindow.setContent(html);
The .content property went away or is no longer supported issue

Google Map API3 Map.fitBounds is not working on IE

I am using webservice to load markers from sql server. and a cluster-er to group those markers, then I re-size the map to fit the bounds using map.fitBounds(bounds).. it works fine on chrome and firefox,, BUT not working on IE,, it gives me an error of Out of stack space in one of google map api 3 files (main.js)
you can check this demo for the issue : http://aprilit.com/gmap/default.aspx
here is a part of my code.
function LoadMap(arrMarkers) {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
}
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var markers = [];
var tempCount = 0;
var bounds = new google.maps.LatLngBounds();
for (var XMLCount = 0; XMLCount < arrMarkers.length; XMLCount++) {
var Points = $.parseXML(arrMarkers[XMLCount]);
$Markers = $(Points).find("Marker");
for (var i = 0; i < $Markers.length; i++) {
var tempID = $Markers.find('mid')[i].innerHTML;
var tempCID = $Markers.find('cid')[i].innerHTML;
var myLatLng =
new google.maps.LatLng($Markers.find('lt')[i].innerHTML,
$Markers.find('lg')[i].innerHTML);
markers.push(new google.maps.Marker({
position: myLatLng,
map: map,
animation: google.maps.Animation.DROP,
markerid: $Markers.find('mid')[i].innerHTML,
catid: $Markers.find('cid')[i].innerHTML,
icon: LoadIcon($Markers.find('cimg')[i].innerHTML)
}));
infowindow = new google.maps.InfoWindow({
content: "loading..."
});
google.maps.event.addListener(markers[tempCount], 'click', function () {
infowindow.setContent('<div ><img src="img/assets/loader.gif"/>
Loading../div>');
infowindow.open(map, this);
$.ajax(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Markers.asmx/GetMarker",
data: JSON.stringify({ MarkerID: this['markerid'],
CategoryID: this['catid'] }),
dataType: "json",
success: function (msg) {
infowindow.setContent(formatInfoDivHTML(msg.d));
}
});
map.panTo(this.getPosition());
infowindow.open(map, this);
});
bounds.extend(myLatLng);
tempCount++;
}
}
//////////////////////////Here is the problem
map.fitBounds(bounds);
var mcOptions = { gridSize: 50, maxZoom: 12 };
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
google.maps.event.trigger(map, 'resize');
}
thanks and ill appreciate your help
also note that I am using fitbounds in other places and it is working just fine.
Just for the reference,, when I checked with an older version of google chrome (Version 31.0.1650.57 m) it gave me the same error..but when I updated chrome the issue has gone
Your SplitXML function is appending an extra null element to the array of markers. Most versions of IE don't like that.
I solved this issue,,
It appears that IE doesn't support the innerHTML property I used here:
$Markers.find('mid')[i].innerHTML
or any where else where I am retrieving the data from my xml fields.
so it had to be replaced with the the textContent property as this:
$Markers.find('mid')[i].textContent;
and that solves the whole issue.!!
thanks for your help guys

Google Maps V3 - json marker loading issue (using Rails 3.1 for data)

We're building a google map app in rails that initially loads some makers using a javascript json marker generating function (using the rails .to_json method on the data object).
Then we have a listener on the zoom action that hoovers the new json file directly and feeds it into the same marker function above.
On initial load the markers turn up fine, but on zoom no new ones seem to be showing up. Checking in the rails logs, the json file is being called, so the problem is either to do with how that json data is processed, or how the markers are delivered.
Can any of you see what the problem is?
var map;
function initialize() {
var myOptions = {
zoom: <%= #zoom %>,
center: new google.maps.LatLng(<%= #centre %>),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
stream_json = (<%= raw(#stream.to_json) %>);
parse_json(stream_json);
google.maps.event.addListener(map, 'zoom_changed', function() {
json_url = "/test?bounds="+map.getBounds()+"&zoom="+map.getZoom();
stream_json = $.getJSON(json_url);
parse_json(stream_json);
});
function parse_json(json) {
if (json.length > 0) {
var markers = [];
for (i=0; i<json.length; i++) {
var place = json[i];
alert(place.longitude +','+place.latitude);
// addLocation(place);
markers[i] = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(place.latitude, place.longitude)
});
}
}
};
}
google.maps.event.addDomListener(window, 'load', initialize);
Many thanks in advance for any pointers you can send our way!
You're not using getJSON correctly. It's an asynchronous call, so you need to supply a callback:
google.maps.event.addListener(map, 'zoom_changed', function() {
json_url = "/test?bounds="+map.getBounds()+"&zoom="+map.getZoom();
$.getJSON(json_url, function(data) {
parse_json(data);
});
});

Google Maps v3: Markerclusterer not being fired?

I have a bit of a puzzle on my hands. I'm Using Google Maps v3 and MarkerClusterer v3. When I load my page, the map appears, the points are all there, but nothing is clustered.
If I go to the firebug console and do:
markerCluster = new MarkerClusterer(map, markers);
Suddenly clustering works.
Weirdly, If I put an alert between the map instantiation and the markerclusterer instantiation, again clustering suddenly works.
Here is the end of my $(document).ready function:
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
markerCluster = new MarkerClusterer(map, markers);
and all it takes to make the clustering work is:
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
alert("test");
markerCluster = new MarkerClusterer(map, markers);
What am I missing here? Do I need to refresh the map somehow? Is that what is happening with the alert box?
If you need more code drop me a comment.
Your problem comes from the fact that $.ajax(), $.getJSON() are asynchronous methods. Once executed, your code is not blocked (otherwise the browser would be blocked as well). Therefore, var markerCluster = new MarkerClusterer(map, markers); is called before the end of the AJAX response processing.
To solve this issue, you have to use a callback, such as complete(), which is fired once the processing is done.
For example:
$.getJSON('/your_data.json', function(data) {
for (var i=0;i<data.length;i++){
// code to display markers
}
}).complete(function() {
var marker_cluster = new MarkerClusterer(map, gmarkers);
});
Hope this helps.
Here is a lightly edited version of what I ended up using. I'm giving most of script here so people can get an idea of the context each function is happening in as well as the scope of everything. Hopefully this will save someone some head scratching.
var initialize = function(){
var markers = [];
var infowindow = new google.maps.InfoWindow();
function load_content(marker, id){
$.ajax({
url: 'eventos/' + id,
success: function(data){
infowindow.setContent(data);
infowindow.open(map, marker);
}
});
}
var opt = { ...options...}
var map = new google.maps.Map(document.getElementById('map_canvas'), opt);
map.setCenter(new google.maps.LatLng(-44.4419, 170.1419));
map.setZoom(9);
$.ajax({
url: 'eventos/',
method: 'GET',
dataType: 'json',
success: function(data){
$.each(data, function(i, a){
var latlng = new google.maps.LatLng(a.evento.lat, a.evento.lng);
var marker = new google.maps.Marker({
position : latlng,
title: a.evento.title
});
google.maps.event.addListener(marker, 'closeclick', function() {
infowindow.setContent("");
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.close();
infowindow.setContent("<img src='loading.gif'>");
load_content(marker, a.evento.id);
});
markers.push(marker);
});
var markerCluster = new MarkerClusterer(map, markers);
}
});
};
I had the exact same issue and symptoms. My solution in the end was to load the map with google loader instead, which for some reason worked fine.
This does not work with mapclusterer:
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
...
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
While this works:
<script src="http://www.google.com/jsapi"></script>
...
google.load('maps', '3', { other_params: 'sensor=false' });
google.setOnLoadCallback(initialize);
function initalize() {
var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
}
This workaround might not be possible for everyone, but hopefully someone can benefit from it.
Have you checked out this thread on MarkerClusterer v3? It's got a few links to some handy resources, namely code examples and reference docs.
Check the examples and make sure they're working OK in your testing browser (you never know, could be an issue with MC).

Categories