Can anyone tell me why the map does not load centered the first time it loads? It works fine when I do a second search, but never loads up correctly the first time.
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"
var directionsDisplay;
var directionsService;
var geocoder;
var currentAddress = 'placeholder';
var tabCount = 0;
var altRouteCount = 0;
var savedRoutes;
$(document).ready(function(){
$('#message-container').hide (0);
document.getElementById('sidebar').className = 'sidebar-hidden';
// Keeps form pointAB from refreshing the page.
$('#pointAB').on('submit', function (e) {
e.preventDefault();
});
$('#tabs').tab();
$('#tabs a').click( function (e) {
e.preventDefault();
$(this).tab('show');
});
$('#sidebar #togglebtn').click(toggleSidebar);
$('#deletes').click(deleteTabs);
$('#routeChange').click(function () {
var index = $('#routeChange').data('route');
index = (index+1)%altRouteCount;
deleteTabs();
printRoute (savedRoutes, index);
$('#routeChange').data('route', index);
});
// Call Google Direction
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
// Google Autocomplete
var start_input = document.getElementById('start');
var end_input = document.getElementById('end');
var bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.532980, -74.118551),
new google.maps.LatLng(40.895218, -73.735403)
);
// Bounds right now only restrict country
var start_autocomplete = new google.maps.places.Autocomplete((start_input),{
// bounds: {sw:new google.maps.LatLng(40.895218, -73.735403), ne:new google.maps.LatLng(40.532980, -74.118551)},
componentRestrictions: {country: 'us'}
}
);
var end_autocomplete = new google.maps.places.Autocomplete((end_input),{
// bounds: {sw:new google.maps.LatLng(40.895218, -73.735403), ne:new google.maps.LatLng(40.532980, -74.118551)},
componentRestrictions: {country: 'us'}
}
);
start_autocomplete.setBounds(bounds);
end_autocomplete.setBounds(bounds);
// Initial map
function initialize() {
var map;
var pos;
// Default pos for map will be center of Manhattan
if(!pos){
pos = new google.maps.LatLng(40.784148400000000000, -73.966140699999980000);
}
var mapOptions = {
zoom: 13
};
getAddress();
// Draw Map
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
map.setCenter(pos);
// Google Direction text route
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions-panel'));
//Needed to resize maps
google.maps.event.addDomListener (map, 'idle', function(){
google.maps.event.trigger (map, 'resize');
});
}
// Load Map
google.maps.event.addDomListener(window, 'load', initialize);
});
/************************************************
Site Navigational Elements
************************************************/
function toggleSidebar() {
var state = $('#sidebar').data('toggle');
if (state == 'hidden') {
document.getElementById('sidebar').className = "sidebar-appear";
$('#sidebar').data('toggle', 'shown');
}
else if (state == 'shown') {
document.getElementById('sidebar').className = "sidebar-hidden";
$('#sidebar').data('toggle', 'hidden');
}
};
function nextSlide() {
$('#navCarousel').carousel('next');
};
function prevSlide(){
$('#navCarousel').carousel('prev');
};
/************************************************
UI Messages
************************************************/
function hideMessage(){
$('#init-message').hide(1000);
};
function pushMessage (messageType, message) {
$('#message-container').hide (0);
if (messageType == 'error') {
document.getElementById('message-container').className = "alert alert-danger";
document.getElementById('icon').className = "glyphicon glyphicon-remove-sign";
}
else if (messageType == 'success') {
document.getElementById('message-container').className = "alert alert-success";
document.getElementById('icon').className = "glyphicon glyphicon-ok-sign";
}
else if (messageType == 'warn') {
document.getElementById('message-container').className = "alert alert-warning";
document.getElementById('icon').className = "glyphicon glyphicon-exclaimation-sign";
}
else {
//Congrats. Senpai has noticed your ability to break shit. Rejoice.
console.error ("Please check your messageType.")
}
$('#message').text(message);
$('#message-container').show (1000);
};
/************************************************
Information Retrieval
************************************************/
// Get current location button function
function getAddress(callback){
geocoder = new google.maps.Geocoder();
// If geolocation available, get position
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {timeout:60000,maximumAge:60000});
}
//Else, browser doesn't support geolocaiton
else {
pushMessage ('error', 'Your browser doesn\'t support geolocation.');
console.log("Browser doesn't support geolocaiton");
}
// Optional callback
if (callback){
callback();
}
};
function successCallback(position){
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
//Reverse geocoding for current location
geocoder.geocode({'latLng': pos}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results.length != 0) {
currentAddress = results[0].formatted_address;
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
};
function errorCallback(){
};
fillAddress = function() {
if (currentAddress != 'placeholder') {
$('#start').val (currentAddress);
pushMessage ('success', "Got your current location!");
}
else {
pushMessage ('warn', 'Please share your location to use this feature.');
}
};
// Set route and request direction result
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
if (start == '' && end == '') {
pushMessage ('error', "Please fill in your current location and destination.");
start='';
end='';
return;
}
else if (start == '') {
pushMessage ('error', "Please fill in your current location.");
start='';
end='';
return;
}
else if (end == '') {
pushMessage ('error', "Please fill in your destination.");
start='';
end='';
return;
}
else {
start += ' new york city';
end += ' new york city';
}
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
travelMode: google.maps.TravelMode.TRANSIT
};
deleteTabs();
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
altRouteCount = response.routes.length;
savedRoutes = response;
printRoute (savedRoutes, 0);
//Move to next slide when directions have been retrieved.
$('#navCarousel').carousel('next');
//Disable loading icon pseudocode.
//$('#loadingIcon').hide(300);
savedRoutes = response;
}
else {
//If DirectionsStatus.NOT_FOUND
//or DirectionsStatus.ZERO_RESULTS
pushMessage ('error', 'No directions found.');
}
});
};
function printRoute (routeObj, routeNo) {
// Get route object
var thisRoute = routeObj.routes[routeNo].legs[0];
for (var i = 0; i < thisRoute.steps.length; i++) {
// Find all possible transit
if (typeof thisRoute.steps[i].transit != 'undefined'
&& thisRoute.steps[i].transit.line.vehicle.type == "SUBWAY") {
trainTab (thisRoute.steps[i]);
}
}
}
//Get details from Maps API json object
function getTransitDetail(obj, tabNo){
var parent='';
if (tabNo) {
parent='div#tab'+tabNo+' ';
}
$(parent+'#train').text(obj.transit.line.short_name + " Train");
$(parent+'#train-stop-depart').text(obj.transit.departure_stop.name);
$(parent+'#train-stop-end').text(obj.transit.arrival_stop.name);
$(parent+'#num-stop').text(obj.transit.num_stops + " Stops");
$(parent+'#arrival_time').text(obj.transit.arrival_time.text);
$(parent+'#departure_time').text(obj.transit.departure_time.text);
$(parent+'#distance').text(obj.distance.text);
$(parent+'#duration').text(obj.duration.text);
};
// Get current time from device
function getTime(){
var currentdate = new Date();
var datetime = currentdate.getDate() + "/"
+ (currentdate.getMonth()+1) + "/"
+ currentdate.getFullYear() + " # "
+ currentdate.getHours() + ":"
+ currentdate.getMinutes() + ":"
+ currentdate.getSeconds();
return datetime;
};
function makeNewTab() {
var prevTab = 'tab' + tabCount;
tabCount++;
var newTab = 'tab' + tabCount;
console.log ('New Tab.');
//Adds tab to nav bar
$('#routeChange').before('<li>TAG LABEL</li>');
//Adds contents of tab
$('div.tab-content #'+prevTab).after('<div id="'+newTab+'"></div>');
$('#'+newTab).addClass("tab-pane");
};
function deleteTabs() {
var thisTab;
while (tabCount >= 1) {
thisTab = 'tab' + tabCount;
//Remove tab from nav bar
$('ul#tabs li a[href="#'+thisTab+'"]').remove();
//Remove contents of tab
$('#'+thisTab).remove();
tabCount--;
}
tabCount = 1;
$('#tabs a:first').tab('show');
};
function trainTab (obj) {
makeNewTab();
$('ul#tabs li a[href="#tab'+tabCount+'"]').text(obj.transit.line.short_name);
$('#tab'+tabCount).append (
'<div id="station-info" class="col-xs-11 col-xs-height col-sm-12 col-sm-height">\
<p>Station Info:</p>\
<p id="train"></p>\
<p id="train-stop-depart"></p>\
<p id="train-stop-end"></p>\
<p id="num-stop"></p>\
<p id="arrival_time"></p>\
<p id="departure_time"></p>\
<p id="distance"></p>\
<p id="duration"></p>\
<!-- <%= link_to "an article", #station%> -->\
</div>');
getTransitDetail (obj, tabCount);
};
Is it because of the order of my code? I tried playing around with the order and could not find a solution. Any help would be appreciated. Thanks in advance!
Related
Hi I have a button which when it gets clicked triggers a function. The function does some stuff (reverse geocodes a latitude/longitude) and then fills a hidden form input with a value.
I need the input to have the correct value before the rest of the code I need gets executed, is there a way to do this? At the moment I have
$('.addButton').click(function() {
//first run the reverse geocode to update the hidden location input with the readable address
reversegeocode();
var location = $("#location").val();//the value I need
$.post("<?php echo $this->webroot;?>locations/add", {location:location})
.done(function (data) {
$("#locationsHolder").html(data);
});
});
So basically I don't want to get the value from the input and post it via AJAX until I know that the reversegeocode() function has finished
Can anyone please explain how I can go about this. I've read some stuff about deferment but I'm absolutely useless at figuring out Javascript and I'm really struggling.
Thanks
EDIT:
Here's my reversegeocode funciton
function reversegeocode(){
var lat = $('#lattitude').val();
var lng = $('#longitude').val();
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {//http://stackoverflow.com/questions/8082405/parsing-address-components-in-google-maps-upon-autocomplete-select
var address_components = results[0].address_components;
var components={};
jQuery.each(address_components, function(k,v1) {jQuery.each(v1.types, function(k2, v2){components[v2]=v1.long_name});})
var output = '';
var needAcomma = false;
if(components.route != undefined) {
output += components.route;
needAcomma = true;
}
if(components.locality != undefined) {
if(needAcomma) {
output += ', ';
}
output += components.locality;
needAcomma = true;
}
if(components.administrative_area_level_1 != undefined) {
if(needAcomma) {
output += ', ';
}
output += components.administrative_area_level_1;
needAcomma = true;
}else if(components.administrative_area_level_2 != undefined) {
if(needAcomma) {
output += ', ';
}
output += components.administrative_area_level_2;
needAcomma = true;
}else if(components.administrative_area_level_3 != undefined) {
if(needAcomma) {
output += ', ';
}
output += components.administrative_area_level_3;
needAcomma = true;
}
$("#location").val(output);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
}
Since reversegeocode is a asynchronous method, you need to use a callback based solution. reversegeocode should receive a callback method as a argument and then invoke the callback once the geocoding is completed.
$('.addButton').click(function () {
//pass a callback to reversegeocode which will get called once the geocoding is completed
reversegeocode(function (location) {
//the callback receives the location as a parameter
$.post("<?php echo $this->webroot;?>locations/add", {
location: location
})
.done(function (data) {
$("#locationsHolder").html(data);
});
});
});
function reversegeocode(callback) {
var lat = $('#lattitude').val();
var lng = $('#longitude').val();
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({
'latLng': latlng
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) { //http://stackoverflow.com/questions/8082405/parsing-address-components-in-google-maps-upon-autocomplete-select
var address_components = results[0].address_components;
var components = {};
jQuery.each(address_components, function (k, v1) {
jQuery.each(v1.types, function (k2, v2) {
components[v2] = v1.long_name
});
})
var output = '';
var needAcomma = false;
if (components.route != undefined) {
output += components.route;
needAcomma = true;
}
if (components.locality != undefined) {
if (needAcomma) {
output += ', ';
}
output += components.locality;
needAcomma = true;
}
if (components.administrative_area_level_1 != undefined) {
if (needAcomma) {
output += ', ';
}
output += components.administrative_area_level_1;
needAcomma = true;
} else if (components.administrative_area_level_2 != undefined) {
if (needAcomma) {
output += ', ';
}
output += components.administrative_area_level_2;
needAcomma = true;
} else if (components.administrative_area_level_3 != undefined) {
if (needAcomma) {
output += ', ';
}
output += components.administrative_area_level_3;
needAcomma = true;
}
$("#location").val(output);
//call the callback
callback(output);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
}
Change reversegeocode to take a callback parameter (also known as a continuation).
Encapsulate all the stuff that needs to wait for reversegeocode to finish, putting it into an in-place, nameless function.
(Note the similarity to what you're already doing for the click handler.)
With this approach you are also free to add parameters to the callback, which you can use to pass data directly through.
$('.addButton').click(function() {
reversegeocode(function(some_data) {
var location = $("#location").val();//the value I need
//...stuff...
});
});
function reversegeocode(callback){
//...stuff...
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//...stuff...
} else {
alert('Geocoder failed due to: ' + status);
}
callback(some_data);
});
}
You need to use a callback function in the reversegeocode function.
The same exact way as you do ajax :)
$('.addButton').click(function() {
reversegeocode().done(function(location) {
$.post("<?php echo $this->webroot;?>locations/add", {location:location})
.done(function (data) {
$("#locationsHolder").html(data);
});
});
})
To do this you will have reversegeocode return a jquery deferred promise
function reversegeocode() {
return $.Deferred(function(d) {
//do stuff and when it succeeds
d.resolve(location);
//or if it fails
d.reject("something went wrong");
}).promise();
}
I've been using the following code for a while now and noticed it has stopped working and throwing an error. The alert says null. Has the maps API changed? I've loaded up
https://maps.googleapis.com/maps/api/js?sensor=false
and
https://maps.gstatic.com/intl/en_us/mapfiles/api-3/15/5/main.js
function geo(){
if(navigator.geolocation) {
var fallback = setTimeout(function() { fail('10 seconds expired'); }, 10000);
navigator.geolocation.getCurrentPosition(
function (pos) {
clearTimeout(fallback);
console.log('pos', pos);
var point = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
new google.maps.Geocoder().geocode({'latLng': point}, function (res, status) {
if(status == google.maps.GeocoderStatus.OK && typeof res[0] !== 'undefined') {
var zip = res[0].formatted_address.match(/,\s\w{2}\s(\d{5})/);
alert(zip);
var homecity;
var homezip;
if((zip[1]>21201)&&(zip[1]<21298)) {
//document.getElementById('geo').innerHTML = "Baltimore "+zip[1];
homecity = "Baltimore";
homezip = zip[1];
//$("._res").html(homecity+" "+homezip);
window.location.href = "?city="+homecity+"&zip="+homezip;
}
if((zip[1]>20001)&&(zip[1]<20886)) {
//document.getElementById('geo').innerHTML = "Baltimore "+zip[1];
homecity = "D.C.";
homezip = zip[1];
//$("._res").html(homecity+" "+homezip);
window.location.href = "?city="+homecity+"&zip="+homezip;
}
if((zip[1]>19019)&&(zip[1]<19255)) {
//document.getElementById('geo').innerHTML = "Baltimore "+zip[1];
homecity = "Philadephia";
homezip = zip[1];
//$("._res").html(homecity+" "+homezip);
window.location.href = "?city="+homecity+"&zip="+homezip;
}
}
});
}, function(err) {
fail(err.message+" WTF");
}
);
}
Simple fix, just change the 0 in the res to 1:
var zip = res[1].formatted_address.match(/,\s\w{2}\s(\d{5})/);
I am not a programmer or a developer. I am facing a problem that the google map infobox not display when they are in exact same location, (geocodezip) have a very good solution, however I don't know how to modify my code.
This is my code
(function ($) {
var settings;
var element;
var map;
var markers = new Array();
var markerCluster;
var clustersOnMap = new Array();
var clusterListener;
var methods = {
init: function (options) {
element = $(this);
var defaults = $.extend({
enableGeolocation: false,
pixelOffsetX : -145,
pixelOffsetY : -200
});
settings = $.extend({}, defaults, options);
google.maps.Map.prototype.setCenterWithOffset = function (latlng, offsetX, offsetY) {
var map = this;
var ov = new google.maps.OverlayView();
ov.onAdd = function () {
var proj = this.getProjection();
var aPoint = proj.fromLatLngToContainerPixel(latlng);
aPoint.x = aPoint.x + offsetX;
aPoint.y = aPoint.y + offsetY;
map.setCenter(proj.fromContainerPixelToLatLng(aPoint));
}
ov.draw = function () {
};
ov.setMap(this);
};
google.maps.visualRefresh = true;
google.maps.event.addDomListener(window, 'load', loadMap);
if (settings.filterForm && $(settings.filterForm).length !== 0) {
$(settings.filterForm).submit(function (e) {
var form = $(this);
var action = $(this).attr('action');
$.ajax({
type : 'GET',
url : action,
data : form.serialize(),
success: function (data) {
element.aviators_map('removeMarkers');
element.aviators_map('addMarkers', {
locations: eval(data.locations),
types : eval(data.types),
contents : eval(data.contents)
});
}
});
e.preventDefault();
});
}
if (options.callback) {
options.callback();
}
return $(this);
},
removeMarkers: function () {
for (i = 0; i < markers.length; i++) {
markers[i].infobox.close();
markers[i].marker.close();
markers[i].setMap(null);
}
markerCluster.clearMarkers();
$.each(clustersOnMap, function (index, cluster) {
cluster.cluster.close();
});
clusterListener.remove();
},
addMarkers: function (options) {
markers = new Array();
settings.locations = options.locations;
settings.contents = options.contents;
settings.types = options.types;
renderElements();
}
}
$.fn.aviators_map = function (method) {
// Method calling logic
if (methods[method]) {
return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on Aviators Map');
}
};
function loadMap() {
var mapOptions = {
zoom : settings.zoom,
mapTypeId : google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
draggable : true,
mapTypeControl : false,
panControl : false,
zoomControl : true,
zoomControlOptions: {
style : google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.LEFT_BOTTOM
}
};
if (settings.enableGeolocation) {
if (navigator.geolocation) {
browserSupportFlag = true;
navigator.geolocation.getCurrentPosition(function (position) {
initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(initialLocation);
}, function () {
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
});
} else {
browserSupportFlag = false;
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
}
} else {
mapOptions.center = new google.maps.LatLng(settings.center.latitude, settings.center.longitude);
}
map = new google.maps.Map($(element)[0], mapOptions);
var dragFlag = false;
var start = 0, end = 0;
function thisTouchStart(e) {
dragFlag = true;
start = e.touches[0].pageY;
}
function thisTouchEnd() {
dragFlag = false;
}
function thisTouchMove(e) {
if (!dragFlag) {
return
}
end = e.touches[0].pageY;
window.scrollBy(0, ( start - end ));
}
var el = $('#map')[0];
if (el.addEventListener) {
el.addEventListener('touchstart', thisTouchStart, true);
el.addEventListener('touchend', thisTouchEnd, true);
el.addEventListener('touchmove', thisTouchMove, true);
} else if (el.attachEvent){
el.attachEvent('touchstart', thisTouchStart);
el.attachEvent('touchend', thisTouchEnd);
el.attachEvent('touchmove', thisTouchMove);
}
google.maps.event.addListener(map, 'zoom_changed', function () {
$.each(markers, function (index, marker) {
marker.infobox.close();
marker.infobox.isOpen = false;
});
});
renderElements();
$('.infobox .close').live('click', function () {
$.each(markers, function (index, marker) {
marker.infobox.close();
marker.infobox.isOpen = false;
});
});
}
function isClusterOnMap(clustersOnMap, cluster) {
if (cluster === undefined) {
return false;
}
if (clustersOnMap.length == 0) {
return false;
}
var val = false;
$.each(clustersOnMap, function (index, cluster_on_map) {
if (cluster_on_map.getCenter() == cluster.getCenter()) {
val = cluster_on_map;
}
});
return val;
}
function addClusterOnMap(cluster) {
// Hide all cluster's markers
$.each(cluster.getMarkers(), (function () {
if (this.marker.isHidden == false) {
this.marker.isHidden = true;
this.marker.close();
}
}));
var newCluster = new InfoBox({
markers : cluster.getMarkers(),
draggable : true,
content : '<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>',
disableAutoPan : true,
pixelOffset : new google.maps.Size(-21, -21),
position : cluster.getCenter(),
closeBoxURL : "",
isHidden : false,
enableEventPropagation: true,
pane : "mapPane"
});
cluster.cluster = newCluster;
cluster.markers = cluster.getMarkers();
cluster.cluster.open(map, cluster.marker);
clustersOnMap.push(cluster);
}
function renderElements() {
$.each(settings.locations, function (index, location) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(location[0], location[1]),
map : map,
icon : settings.transparentMarkerImage
});
marker.infobox = new InfoBox({
content : settings.contents[index],
disableAutoPan : false,
maxWidth : 0,
pixelOffset : new google.maps.Size(settings.pixelOffsetX, settings.pixelOffsetY),
zIndex : null,
closeBoxURL : "",
infoBoxClearance : new google.maps.Size(1, 1),
position : new google.maps.LatLng(location[0], location[1]),
isHidden : false,
pane : "floatPane",
enableEventPropagation: false
});
marker.infobox.isOpen = false;
marker.marker = new InfoBox({
draggable : true,
content : '<div class="marker ' + settings.types[index] + '"><div class="marker-inner"></div></div>',
disableAutoPan : true,
pixelOffset : new google.maps.Size(-21, -58),
position : new google.maps.LatLng(location[0], location[1]),
closeBoxURL : "",
isHidden : false,
pane : "floatPane",
enableEventPropagation: true
});
marker.marker.isHidden = false;
marker.marker.open(map, marker);
markers.push(marker);
google.maps.event.addListener(marker, 'click', function (e) {
var curMarker = this;
$.each(markers, function (index, marker) {
// if marker is not the clicked marker, close the marker
if (marker !== curMarker) {
marker.infobox.close();
marker.infobox.isOpen = false;
}
});
if (curMarker.infobox.isOpen === false) {
curMarker.infobox.open(map, this);
curMarker.infobox.isOpen = true;
map.setCenterWithOffset(curMarker.getPosition(), 100, -120);
} else {
curMarker.infobox.close();
curMarker.infobox.isOpen = false;
}
});
});
markerCluster = new MarkerClusterer(map, markers, {
gridSize: 40,
styles: [
{
height : 42,
url : settings.transparentClusterImage,
width : 42,
textColor: 'transparent'
}
]
});
clustersOnMap = new Array();
clusterListener = google.maps.event.addListener(markerCluster, 'clusteringend', function (clusterer) {
var availableClusters = clusterer.getClusters();
var activeClusters = new Array();
$.each(availableClusters, function (index, cluster) {
if (cluster.getMarkers().length > 1) {
activeClusters.push(cluster);
}
});
$.each(availableClusters, function (index, cluster) {
if (cluster.getMarkers().length > 1) {
var val = isClusterOnMap(clustersOnMap, cluster);
if (val !== false) {
val.cluster.setContent('<div class="clusterer"><div class="clusterer-inner">' + cluster.getMarkers().length + '</div></div>');
val.markers = cluster.getMarkers();
$.each(cluster.getMarkers(), (function (index, marker) {
if (marker.marker.isHidden == false) {
marker.marker.isHidden = true;
marker.marker.close();
}
}));
} else {
addClusterOnMap(cluster);
}
} else {
// Show all markers without the cluster
$.each(cluster.getMarkers(), function (index, marker) {
if (marker.marker.isHidden == true) {
marker.marker.open(map, this);
marker.marker.isHidden = false;
}
});
// Remove old cluster
$.each(clustersOnMap, function (index, cluster_on_map) {
if (cluster !== undefined && cluster_on_map !== undefined) {
if (cluster_on_map.getCenter() == cluster.getCenter()) {
// Show all cluster's markers/
cluster_on_map.cluster.close();
clustersOnMap.splice(index, 1);
}
}
});
}
});
var newClustersOnMap = new Array();
$.each(clustersOnMap, function (index, clusterOnMap) {
var remove = true;
$.each(availableClusters, function (index2, availableCluster) {
if (availableCluster.getCenter() == clusterOnMap.getCenter()) {
remove = false;
}
});
if (!remove) {
newClustersOnMap.push(clusterOnMap);
} else {
clusterOnMap.cluster.close();
}
});
clustersOnMap = newClustersOnMap;
});
}
})(jQuery);
and This is geocodezip code
Google Maps Multiple markers with the exact same location Not working
Many Many Thanks
That solution is great, but I'd take a look at using the Overlapping Marker Spiderfier library to handle markers in the same location. You can use this in conjunction with the marker clusterer library, without any issues. This way you also don't lose the ability to see how many markers are actually in that same location - and it gives you a great UI in my opinion.
To use Overlapping Marker Spiderfier, include the script file before your main js file in your html. Then in your js, create an instance of the OverlappingMarkerSpiderfier object:
var oms = new OverlappingMarkerSpiderfier(map);
/*in your case I'd do this after you initialize the `map` object,
*and declare the `oms` globally, like you do with your other global objects
*/
Then when the markers are created, you want to add the marker to the oms object via the addMarker() method. So, in your case add the following line to the renderElements() function after the click event listener you declare for the marker:
oms.addMarker(marker);
Lastly, make sure to also clear the markers from the oms object when the removeMarkers() function in your code is called by adding the following to that function:
oms.clearMarkers();
I have some issue with the callback inside geocoder.geocode.
var tri = new Array();
for (var j = 1; j < taille; j++) {
where = getBoutique[j].adresse + ", " + getBoutique[j].ville;
boutiqueProche(lat, lon, where, function (distanceO) {
//window.localStorage.setItem("distance", distance);
console.log(distanceO);
tri.push(distanceO);
//return distance;
//console.log("Nous somme dans "+localStorage.getItem("distance"));
});
console.log("Inside " + tri);
}
function boutiqueProche(cLat, cLong, where, callback) {
var geocoder = new google.maps.Geocoder();
var currentPosition = new google.maps.LatLng(cLat, cLong); // On récupère nos info
var recup = getBoutique.length;
var distance;
geocoder.geocode({
'address': where
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var laBoutique = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
distance = google.maps.geometry.spherical.computeDistanceBetween(currentPosition, laBoutique);
recup = distance / 1000;
callback(recup);
} else {
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(function () {
boutiqueProche(cLat, cLong, where, callback); // rappel fonction avec meme param
}, 200);
} else { /*Faire quelque chose */ }
}
});
}
I want to fill the array tri with the data from recup variable. But when I fill tri, nothing happens. It is empty.
What is the problem?
I'm writing some code with the Google Maps API, it works fine in all browsers (FF, IE9, Chrome) but IE8 or below, I have assigned the map to a global variable called Map, which gets populated but when the addMarker function gets called the Map global is null in IE8, but the addMarker function does work when I call it from the locator function, I have included all these functions below.
var GoogleMaps = {};
var Map = null;
var init = (function () {
"use strict";
var MapType = null;
var ZoomLevel = null;
var ControlPos = null;
var ControlSize = null;
var myLatLong = null;
var Geocoder;
var result = null;
GoogleMaps.setup = function (options) {
myLatLong = new google.maps.LatLng(24.886436490787712, -70.26855468754);
if (google.loader.ClientLocation) {
myLatLong = new google.maps.LatLng(
google.loader.ClientLocation.latitude,
google.loader.ClientLocation.longitude);
} else if (options.Lat !== null && options.Long !== null) {
options.Location = new google.maps.LatLng(options.Lat, options.Long);
} else {
// Else centre to UK
options.Location = new google.maps.LatLng(52.961875, -1.419433);
}
if (options.MapType.toUpperCase() === 'ROADMAP') {
MapType = google.maps.MapTypeId.ROADMAP;
} else if (options.MapType.toUpperCase() === 'TERRAIN') {
MapType = google.maps.MapTypeId.TERRAIN;
} else if (options.MapType.toUpperCase() === 'HYBRID') {
MapType = google.maps.MapTypeId.HYBRID;
} else {
MapType = google.maps.MapTypeId.SATELLITE;
}
// Check zoom level, if not set then set to zoom level 8.
if (options.ZoomLevel) {
ZoomLevel = options.ZoomLevel;
} else {
ZoomLevel = 8;
}
var mapOptions = {
center: myLatLong,
zoom: ZoomLevel,
mapTypeId: MapType
};
var mapDiv = document.getElementById('canvas');
// Map gets initiated here
window.Map = new google.maps.Map(mapDiv, mapOptions);
delete options.MapType;
delete options.Lat;
delete options.Long;
delete options.ZoomLevel;
};
GoogleMaps.addMarker = function (options) {
var Location = null;
var Animation = null;
var Title = null;
var Draggable = null;
var Content = null;
var InfoWindow = null;
var Flat = null;
var Clickable = null;
if (options.lat !== null && options.long !== null) {
Location = new google.maps.LatLng(options.lat, options.long);
;
} else {
Location = myLatLong;
}
if (typeof(options.position) !== "undefined") {
Location = options.position;
}
if (options.animation.toUpperCase() === 'BOUNCE') {
Animation = google.maps.Animation.BOUNCE;
} else if (options.animation.toUpperCase() === 'DROP') {
Animation = google.maps.Animation.DROP;
} else {
Animation = google.maps.Animation.NONE;
}
if (options.draggable !== null && options.draggable === 'true') {
Draggable = true;
} else {
Draggable = false;
}
if (options.title !== null) {
Title = options.title;
} else {
Title = null;
}
if (options.content !== null) {
Content = options.content;
InfoWindow = new google.maps.InfoWindow({
content: Content
});
}
if (options.flat !== null && options.flat === 'true') {
Flat = true;
} else {
Flat = false;
}
if (options.clickable !== null && options.clickable === 'true') {
Clickable = true;
} else {
Clickable = false;
}
// Gets used in this section
var Marker = new google.maps.Marker({
position: Location,
map: window.Map,
animation: Animation,
draggable: Draggable,
title: Title,
flat: Flat,
clickable: Clickable,
zIndex: 1
});
// and sets map here
Marker.setMap(window.Map);
if (options.content !== null) {
google.maps.event.addListener(Marker, 'click', function (e) {
InfoWindow.open(window.Map, this);
google.maps.event.addListener(window.Map, 'click', function (e) {
InfoWindow.close(window.Map, window.Marker);
});
});
}
google.maps.event.addListener(Marker, 'dragend', function (e) {
});
delete options.lat;
delete options.long;
delete options.animation;
delete options.title;
delete options.content;
delete options.flat;
delete options.draggable;
delete options.clickable;
};
GoogleMaps.Locator = function (result) {
var address = null;
Geocoder = new google.maps.Geocoder();
address = result;
Geocoder.geocode({ 'address': address }, function (response, status) {
if (status === google.maps.GeocoderStatus.OK) {
window.Map.setCenter(response[0].geometry.location);
var Location = new google.maps.LatLng(response[0].geometry.location.Xa, response[0].geometry.location.Ya);
var markerOptions = {
animation: "drop",
draggable: "true",
content: 'Hello World!',
title: "Hello",
position: Location
};
GoogleMaps.addMarker(markerOptions);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
};
Below is how I am calling the functions:
var markerOptions = {
lat: 52.48278,
long: -0.892089,
animation: "drop",
draggable: "true",
content: 'Hello World!',
title: "Click Me"
};
google.maps.event.addDomListener(window, 'load', function () { GoogleMaps.setMarker(markerOptions) });
google.maps.event.addDomListener(window, 'load', function () { GoogleMaps.Locator('London') });
Thanks for any help.
I resolved the problem like this.
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7; IE=EmulateIE9″/>
Try changing this line in your setup
window.Map = new google.maps.Map(mapDiv, mapOptions);
to just
Map = new google.maps.Map(mapDiv, mapOptions);
This way you accessing the global variable declared.
when is GoogleMaps.setup called? Right now it looks like depending on the browser it can be called after functions attached by
google.maps.event.addDomListener(window, 'load', function () { ... });
and that's why map is not set when you call addMarker, but is already initialized when you receive callback from
Geocoder.geocode(...)
To fix this make sure that GoogleMaps.setup is called before addMarker.
IE8 has always meant trouble. :-) Try adding the following meta tag at the beginning of your <head> section:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
Description here:
http://blogs.msdn.com/b/ie/archive/2008/06/10/introducing-ie-emulateie7.aspx