I have a google map which was working well until a few weeks ago.
My problem is that now, all the label markers appears in the right place but only the last image appears.
I see in the generated html code that all images are here but all of them have the same position (that's why i can just see the last one).
I say again : it was working before, i'm sure! Maybe google has changed something (i'm calling the script : https://maps.googleapis.com/maps/api/js?sensor=false).
Here is my code :
jQuery(function() {
var stops = [];
var nbPoints = $('#nbPoints').val();
for (var i = 1; i <= nbPoints; i++) {
if($('#latitude'+i).val() && $('#longitude'+i).val())
stops.push({"Geometry":{"Latitude":$('#latitude'+i).val(),"Longitude":$('#longitude'+i).val()}});
}
var map = new window.google.maps.Map(document.getElementById("map_canvas"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer({suppressMarkers: true});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);
else $("#message").html("Erreur : Aucune coordonnée renseignée!");
});
function Tour_startUp(stops) {
if (!window.tour) window.tour = {
updateStops: function (newStops) {
stops = newStops;
},
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom: 13,
center: new window.google.maps.LatLng($('#latitudeInit').val(),$('#longitudeInit').val()),
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (directionsService, directionsDisplay) {
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
//var directionsResultsReturned = 0;
var directionsResultsReturned = new Array();
directionsResultsReturned[0]=0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: window.google.maps.TravelMode.DRIVING
};
creerRoute(k,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay);
}
}
};
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var icons = new Array();
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
function getMarkerImage(numero, type, anomalie) {
var url_img = "../img/";
var type = new String(type);
if(anomalie) url_img+="anomalie.png";
else{
switch(type.toUpperCase()){
case "LAVAGE" : url_img+="shower.png"; break;
case "EAU" : url_img+="waterdrop.png"; break;
default : url_img+="stop.png"; break;
}
}
icons[numero] = new google.maps.MarkerImage(url_img,
new google.maps.Size(34, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
return icons[numero];
}
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var iconImage = new google.maps.MarkerImage('mapIcons/marker_red.png',
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(34, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var iconShape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};
function createMarker(map, latlng, label, html, numero, type, anomalie) {
var contentString = '<b>'+label+'</b><br>'+html;
var marker = new MarkerWithLabel({
position: latlng,
map: map,
draggable: false,
raiseOnDrag: true,
icon : getMarkerImage(numero,type,anomalie),
labelContent: numero,
labelAnchor: new google.maps.Point(0, 0),
labelClass: "labels",
labelInBackground: false
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
return marker;
}
function creerRoute(kk,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
directionsResultsReturned[0]++;
if (directionsResultsReturned[0] == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
for (var i=0; i < legs.length;i++){
var j = i + 1;
var markerletter = $('#ordre'+j).val();
var anomalie=false;
var html = $('#infospoint'+j).val();
if($('#infoschocspoint'+j).length){
anomalie = true;
html+="<br/>"+$('#infoschocspoint'+j).val();
}
createMarker(directionsDisplay.getMap(),legs[i].start_location,$('#titrepoint'+j).val(),html,markerletter,$('#type'+j).val(),anomalie);
}
var i=legs.length + 1;
var markerletter = $('#ordre'+i).val();
var anomalie=false;
var html = $('#infospoint'+i).val();
if($('#infoschocspoint'+i).length){
anomalie = true;
html+="<br/>"+$('#infoschocspoint'+i).val();
}
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,$('#titrepoint'+i).val(),html,markerletter,$('#type'+i).val(),anomalie);
}
}else {
if (status == window.google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
setTimeout( function(){
creerRoute(kk,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay);
}, 200);
}else{
$("#message").html("Erreur : Code "+status);
}
}
});
}
Has anyone the same problem?
Thanks for your help!
You can use new one
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3.3"></script>
I am using google maps api v3.
The Below code i am trying to run , It is working on all Browsers except IE.
Can u please suggest any changes needed to work in IE.
Fiddle Link
My Code is :
var map;
var mapOptions = { center: new google.maps.LatLng(0.0, 0.0), zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP };
var markers = [];
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
from1 = new google.maps.LatLng(0,0);
to1 = new google.maps.LatLng(30,12);
from2 = new google.maps.LatLng(-30,15);
to2 = new google.maps.LatLng(10,-100);
from3 = new google.maps.LatLng(0,-50);
to3 = new google.maps.LatLng(0,50);
addMarker(from1,to1);
addMarker(from2,to2);
addMarker(from3,to3);
}
function addMarker(pos, dest) {
var marker = new google.maps.Marker({
map: map,
position: pos,
destination: dest
});
google.maps.event.addListener(marker, 'click', function(event) {
fromLat = this.position.lat();
fromLng = this.position.lng();
toLat = this.destination.lat();
toLng = this.destination.lng();
// store a LatLng for each step of the animation
frames = [];
for (var percent = 0; percent < 1; percent += 0.01) {
curLat = fromLat + percent * (toLat - fromLat);
curLng = fromLng + percent * (toLng - fromLng);
frames.push(new google.maps.LatLng(curLat, curLng));
}
move = function(marker, latlngs, index, wait, newDestination) {
marker.setPosition(latlngs[index]);
if(index != latlngs.length-1) {
// call the next "frame" of the animation
setTimeout(function() {
move(marker, latlngs, index+1, wait, newDestination);
}, wait);
}
else {
// assign new route
marker.position = marker.destination;
marker.destination = newDestination;
}
}
// begin animation, send back to origin after completion
move(marker, frames, 0, 20, marker.position);
});
markers.push(marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
After some fiddling it looks like a typing issue. Because you haven't implicitly declared the variable frames as a var ie is unsure that it is an array, thus the error "Object does not support method push".
You simply need to change:
frames = [];
to:
var frames = [];
Tested in ie 8- 10.
Using the Google Maps API v3 I've been able to update multiple positions of markers via an AJAX call. However, it lacks any transition. Code below:
if ( !latlong.equals( point.latlong ) ) {
point.latlong = latlong;
point.marker.setPosition(latlong);
}
The drawback is that setPosition has no native animation method. Does anyone know any methods for extending setPosition so the marker can fluently "move" from it's old to new position? Or any methods available? I have not been able to find any documentation. Thanks!
I did not find any native way to create this animation. You can create your own animation by stepping the position from the current point to the final point using the setPosition. Here is a code snippet to give you an idea:
var map = undefined;
var marker = undefined;
var position = [43, -89];
function initialize() {
var latlng = new google.maps.LatLng(position[0], position[1]);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
marker = new google.maps.Marker({
position: latlng,
map: map,
title: "Your current location!"
});
google.maps.event.addListener(map, 'click', function(me) {
var result = [me.latLng.lat(), me.latLng.lng()];
transition(result);
});
}
var numDeltas = 100;
var delay = 10; //milliseconds
var i = 0;
var deltaLat;
var deltaLng;
function transition(result){
i = 0;
deltaLat = (result[0] - position[0])/numDeltas;
deltaLng = (result[1] - position[1])/numDeltas;
moveMarker();
}
function moveMarker(){
position[0] += deltaLat;
position[1] += deltaLng;
var latlng = new google.maps.LatLng(position[0], position[1]);
marker.setPosition(latlng);
if(i!=numDeltas){
i++;
setTimeout(moveMarker, delay);
}
}
This can probably be cleaned up a bit, but will give you a good start. I am using JavaScript's setTimeout method to create the animation. The initial call to 'transition' gets the animation started. The parameter to 'transition' is a two element array [lat, lng]. The 'transition' function calculates the step sizes for lat and lng based upon a couple of animation parametes (numDeltas, delay). It then calls 'moveMarker'. The function 'moveMarker' keeps a simple counter to indicate when the marker has reached the final destination. If not there, it calls itself again.
Here is a jsFiddle of the code working: https://jsfiddle.net/rcravens/RFHKd/2363/
Hope this helps.
Bob
In case you want smooth animations (with easing), these libraries should help:
https://github.com/terikon/marker-animate-unobtrusive
http://terikon.github.io/marker-animate-unobtrusive/demo/unobtrusive/markermove-sliding.html
I know its late but it might help the future SO wanderers.
Problem Statement: write a function(and not a library due to specific use-case) to animate a google maps marker to a new location.
Solution is based on this awesome library marker-animate-unobtrusive
function animateMarkerTo(marker, newPosition) {
var options = {
duration: 1000,
easing: function (x, t, b, c, d) { // jquery animation: swing (easeOutQuad)
return -c *(t/=d)*(t-2) + b;
}
};
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
// save current position. prefixed to avoid name collisions. separate for lat/lng to avoid calling lat()/lng() in every frame
marker.AT_startPosition_lat = marker.getPosition().lat();
marker.AT_startPosition_lng = marker.getPosition().lng();
var newPosition_lat = newPosition.lat();
var newPosition_lng = newPosition.lng();
// crossing the 180° meridian and going the long way around the earth?
if (Math.abs(newPosition_lng - marker.AT_startPosition_lng) > 180) {
if (newPosition_lng > marker.AT_startPosition_lng) {
newPosition_lng -= 360;
} else {
newPosition_lng += 360;
}
}
var animateStep = function(marker, startTime) {
var ellapsedTime = (new Date()).getTime() - startTime;
var durationRatio = ellapsedTime / options.duration; // 0 - 1
var easingDurationRatio = options.easing(durationRatio, ellapsedTime, 0, 1, options.duration);
if (durationRatio < 1) {
marker.setPosition({
lat: (
marker.AT_startPosition_lat +
(newPosition_lat - marker.AT_startPosition_lat)*easingDurationRatio
),
lng: (
marker.AT_startPosition_lng +
(newPosition_lng - marker.AT_startPosition_lng)*easingDurationRatio
)
});
// use requestAnimationFrame if it exists on this browser. If not, use setTimeout with ~60 fps
if (window.requestAnimationFrame) {
marker.AT_animationHandler = window.requestAnimationFrame(function() {animateStep(marker, startTime)});
} else {
marker.AT_animationHandler = setTimeout(function() {animateStep(marker, startTime)}, 17);
}
} else {
marker.setPosition(newPosition);
}
}
// stop possibly running animation
if (window.cancelAnimationFrame) {
window.cancelAnimationFrame(marker.AT_animationHandler);
} else {
clearTimeout(marker.AT_animationHandler);
}
animateStep(marker, (new Date()).getTime());
}