I am trying to build something similar to this example.
The example's workflow is the following:
add 2 markers to map.
click "get route"
keep clicking forward until you get from point A to point B
If a user inserts a third marker -> click get route etc, original route gets redrawn.
What I want to achieve is the following. I have a fixed destination, and user inserts one marker, clicks get_route, then forward until route gets drawn, one step at a time. So far so good.
I have made it possible for the user to add a second marker, click get route, and see the route drawn to the destination.
The problem I am facing is the following. On the second marker, the first time the user clicks forward, he gets two steps at once drawn, after that another two, etc. The third marker, 3steps per click. 4th marker, 4 steps per click, etc.
Here is the code:
$(document).ready(function(){
$('#forward').attr('disabled', 'disabled');
$('#back').attr('disabled', 'disabled');
$('#get_route').click(function(e){
e.preventDefault();
count = 0;
map.getRoutes({
origin: [map.markers[map.markers.length-1].getPosition().lat(), map.markers[map.markers.length-1].getPosition().lng()],
destination: [meetinglat, meetinglng],
travelMode : google.maps.TravelMode.WALKING,
callback: function(e){
route = new GMaps.Route({
map: map,
route: e[e.length-1], // e[0] initially
strokeColor: '#336699',
strokeOpacity: 0.5,
strokeWeight: 10,
destination: [meetinglat, meetinglng]
});
$('#forward').removeAttr('disabled');
$('#back').removeAttr('disabled');
}
});
$('#forward').click(function(e){
e.preventDefault();
route.forward();
if(route.step_count <= route.steps_length && count < route.steps_length){
count++;
$('#steps').append('<li>'+route.step_count+' '+route.steps[route.step_count-1].instructions+'</li>');
$("#container").scrollTop($("#container")[0].scrollHeight);
}
});
$('#back').click(function(e){
e.preventDefault();
route.back();
if(route.step_count >= 0){
$('#steps').find('li').last().remove();
count--;
}
});
});
map = new GMaps({
el: '#map',
lat: meetinglat,
lng: meetinglng,
zoom: 17,
height: '500px',
click: function(e){
map.addMarker({
lat: e.latLng.lat(),
lng: e.latLng.lng()
});
}
});
Can you tell if I am missing something here? When a new route gets created, I am passing the correct one obviously, as it is the one that gets drawn.
The problem is on the first time the user clicks "forward" after inserting the second marker, because the 2 steps run at once. The third time, 3 steps, 4th time 4 steps, etc.
Thanks very much
Edit: jsBin
Managed to resolve the issue.
It seems that "forward" and "back" click events were bubbling-propagation, so that was the reason for the behaviour it had. (1 step per click 1st marker, 2 step per click 2nd marker, 3 step per click 3rd marker etc).
I added:
e.stopImmediatePropagation();
at the end of both forward and back click event handlers. Working as expected now
Related
I have a project to finish, and I have 1 month to finish it, I am very late…
I have tried to do what I want to have, but it never worked, I am a beginner in Javascript…
Here is what I would like to have in order to continue my project. Sorry in advance for my English…
I would like that, when I click on a country, markers appears (It works), but I would also like that when I click on a marker, this one disappear and zoom on a specified location (the river, to be precise).
And I also wanted that marker’s popup are shown on mouseover but I didn’t succeed.
I don’t know all the possibilities of javascript. But is it possible to see these things if I zoom out ? (for example : I see the river, I zoom out to the country level and markers appears)
A help would considerably help me in my project and hopefully allow me to finish in time.
Thank you for your attention,
Here is the link of my full code that works till before my last changes :
https://jsfiddle.net/Gio687351/cj9bvrg7/1/
Here is one of the codes that I have tested :
function toggleLayerVisibility(map, selectedLayer) {
if (selectedLayerId && selectedLayerId !== selectedLayer._leaflet_id) {
map.eachLayer(layer => {
if (layer._leaflet_id === selectedLayerId) geojson.resetStyle(layer);
});
}
selectedLayer.setStyle({
opacity: 0,
fillOpacity: 0.0
});
selectedLayerId = selectedLayer._leaflet_id; //save identifier of a selected layer
map.on('zoomend', function() {
if (map.getZoom() < 8 && map.getZoom() > 6){
map.removemarker;
}
else {
map.on('zoomend', {
marker.on('mouseover', function(e) {
L.marker([52.7472, -8.5087]).bindPopup('Limerick, Shannon River').addTo(map);
L.marker([53.34565, -6.32105]).bindPopup('Dublin, River Liffey').addTo(map);
L.marker([47.88363, 7.22444]).bindPopup('Soultz-Haut-Rhin, Le Rimbach').addTo(map); }
}); }
});
I found the solution :
enter image description here
I have polygons, multi polygons,and polygons with holes in them. All them working fine. We are currently putting a pin (Marker) and then moving the marker when someone selects a different polygon.
[Edit: There are hundreds of polygons, so manually re-setting them like in the answer below is not practical]
What we want is to replace the marker with a fillColor. When someone clicks on a polygon I can easily change the fillColor - that's not an issue. The problem I am having is trying to clear that fillColor, when someone clicks a different polygon.
This is a large project with many files... But the relevant portion is here:
//building is the polygon
building.addListener('click', function() {
// We've been using markers, can we can easily move them.
setMarker(map, this.center, true);
// Want to use this instead. This works fine to color the polygon but...
this.setOptions({
fillColor: 'orange'
});
// I need some function, likely to be called here that clears any other polygon that has been change to 'orange'.
// I was looking at map.data.revertStyle(); but this doesn't work at this level.
});
Just to make it clear, there are plenty of examples of how to reset the polygon if someone clicks on it again. That is easy to do. I want to reset when a different polygon is clicked, just like how the move marker functionality works.
thank you
You can make your map listen to a custom resetColor event, and trigger this event on the click function of your polygons like this:
var map;
function initMap() {
//initialize map...
// Define the LatLng coordinates for the polygons paths.
// Construct the polygon.
//add polygons to map
//attach the map to our custom -resetColor- event
google.maps.event.addListener(map, "resetColor", function(){
resetColor.call(bermudaTriangle, null); //invoke resetColor making sure 'this' is the bermuda triangle
resetColor.call(secondTriangle, null); // 'this' is the second triangle
resetColor.call(someOtherTriangle, null); // ditto
});
bermudaTriangle.addListener("click", selectedColor); //polygon1
secondTriangle.addListener("click", selectedColor); //polygon2
someOtherTriangle.addListener("click", selectedColor); //polygon3
}
google.maps.event.addDomListener(window, "load", initMap);
function resetColor() {
console.log("in trigger function");
this.setOptions({
fillColor: "black"
});
}
function selectedColor() {
//function executed on polygon click
google.maps.event.trigger(map, "resetColor"); //trigger our custom event on the map
this.setOptions({
fillColor: "yellow" //make the clicked polygon 'selected'
});
}
see this pen to see it working.
This code above is open for improvement and any idea is welcomed.
This is how we ended up approaching this. If someone has a better solution, feel free to pass it along. This might help some people though...
I am creating a separate polygon, which will only hold the last polygon clicked. It gets reset on click on any other polygon. The pros is that it works nicely and exactly as needed. The part I don't love is that I am creating a separate layer, and it would be nice to just change the fillColor if possible.
var new_polygon = '';
// Checks for an "active" polygon, clears it if it exists, or sets a new one if it does not.
function active_polygon(center, polygon_latlng) {
if (new_polygon) {
new_polygon.setMap(null);
new_polygon = '';
}
new_polygon = new google.maps.Polygon({
map: map,
paths: polygon_latlng,
fillColor: "#DC4405",
center: center,
strokeWeight: 0,
fillOpacity: 1,
clickable: true,
zIndex: 400,
});
return new_polygon.setMap(map);
}
// this was my original listener above for polygons
// This is located in the polygon loop in a later part of the code.
building.addListener('click', function() {
// Generates the new polygon active later
active_polygon(this.center, this.getPaths());
});
The marker.setMap(null) call doesn't remove the marker from the map.
I have confirmed the map and marker vars point to the right place but the setMap(null) call simply leaves the marker visible on the map. The setVisible(false) also has no effect.
if(sch_ovr_google_markers.length > 0){//remove from map
for(var i=0;i < sch_ovr_google_markers.length;i++){
sch_ovr_google_markers[i].setMap(null);//no effect
}
}
The markers are created here:
var latlon = new google.maps.LatLng(o.lat, o.lon);
var marker = new google.maps.Marker(
{
map:sch_google_map,
position: latlon,
title: gpn[4],
icon: pinImage,
shadow: pinShadow,
animation: google.maps.Animation.DROP,
zIndex:10000,
index: c
});
sch_ovr_google_markers[lidx] = marker;
sch_ovr_google_iws[lidx] = new google.maps.InfoWindow({ content:h, position:latlon });
sch_ovr_google_cbs[lidx] = sch_ovr_google_marker_init(marker,lidx);
The whole map works great except for this one problem. The surrounding code tests good and too involved to list completely.
I am wondering if there is some hidden preconditions for it to work. I have tried deleting other references to it before setMap(null), but still no luck.
The documentation makes it sound like the method will simply remove it, but obviously, to met at least, there is something more required. Any ideas?
Hopefully the original poster still isn't needing this late answer, but I had similar symptoms and couldn't find any help in the Internets.
For me, there was a problem in populating the data which caused duplicate markers to appear. Therefore, calling setMap(null) didn't seem to do anything, though it still actually did work ok, but of course it only worked on the other marker, leaving the other still on the map which looked like the setMap(null) isn't working.
So, if you're sure that your marker's map is set to null (you can check from javascript console/debugger) but the marker is still visible, try setting draggable: true parameter for the marker and move it around to see if another marker is lurking behind it.
I am drawing markers that represent shops on a map.
There is a single global infoWindow which appears for each marker that is clicked, right after it closes for the previous clicked marker.
In some cases a few shops may have the same address so the markers appear on top of each other and one can only see the top marker.
To solve this I added pagination to the infoWindow.
The problem is that the top marker is the last one on the list, and so the infoWindow shows the latest shop's info and the pagination shows the "back" button, instead of showing the first shop first and the "next" button.
I tried reversing the order of the "for" loop like this for (i=limit; i>0; i--) but it doesn't work. The map gets stuck as if running some ajax request.
Here's the code:
function drawShopsMarkers(){
var marker;
markersArray = [];
var i;
var limit = globalShopsArr.length;
for (i=0; i<limit; i++){
marker = new google.maps.Marker({
position: new google.maps.LatLng(globalShopsArr[i].shopLat, globalShopsArr[i].shopLng),
map: map,
title: globalShopsArr[i].shopTitle
});
markersArray.push(marker);
marker.setMap(map);
google.maps.event.addListener(markersArray[i], 'click', makeListener(i));
}
function makeListener(index) {
return function() {
globalInfowindow.disableAutoPan=true;
globalInfowindow.open(map,markersArray[index]);
CreateInfoWindowString(index);
globalInfowindow.setOptions({
content: globalContentString
});
}
}
}
The CreateInfoWindowString() function simply populates the globalContentString including the pagination.
Can you say what's causing the problem?
Try
for (i=limit-1;i>=0;i--)
like suggested in the comment. You need to change the line when you attach the function to the marker, too. When you push the marker to the array it's accumulate but you attach function to a non-existent element. Use another variable and increment it in the loop: c++
This line google.maps.event.addListener(markersArray[i],.. ... ...
When you change the loop to decrement i and try markersArray[i] it must give an error because element i isn't in the array yet. So create a c variable and use it instead like I wrote and change the line to use c instead of i.
I need some help with JavaScript and Google Maps API.
I have a Google Maps map on my website which shows markers, which in turn show a custom InfoBox when clicked on.
When a marker is clicked, a new object is created for this InfoBox:
google.maps.event.addListener(marker, 'click', function() {
infoBox = new InfoBox({id: id, content: description, latlng: marker.getPosition(), map: map});
});
When a visitor clicks two markers consecutively, he is faced with two InfoBoxs. I run two lines of code that hide the InfoBoxs when a users clicks away in the map or when they click the cross in the upper right corner:
google.maps.event.addDomListener(closeImg, 'click', removeInfoBox(this));
google.maps.event.addDomListener(map, 'click', removeInfoBox(this));
What I would like to happen is that when a user clicks on a marker, all previous markers will get hidden (so after each click on a marker, there would only be one previous InfoBox to be hidden).
I'm struggling to get this done. If I create a DomListener on all markers with the 'click' event, I never get an InfoBox to pop up. If I put removeInfoBox(this); before creating a new object of InfoBox I also never get shown an InfoBox.
Where and how would be the proper way to prevent more than one InfoBox from showing up?
I found a post on how to remove markers and keep track of them which I could adept to my script.
First I declare the array for storing opened infoBox'es and the function to remove them (clearOverlays()):
// Declare global array for hiding infowindows
var infowindowsArray = [];
function clearOverlays(){
if(infowindowsArray){
for (i in infowindowsArray){
infowindowsArray[i].setMap(null);
}
}
}
Then when I create a listener for the marker's click event, it will add the new infoBox to that marker. First I use the clearOverlays() function to clear all other infoBox'es. Then I create the new infoBox and push it into the array:
google.maps.event.addListener(marker, 'click', function() {
clearOverlays();
infoBox = new InfoBox({id: id, content: description, latlng: marker.getPosition(), map: map});
infowindowsArray.push(infoBox);
});
This solved my problem with the custom created infoBox'es.