Is there any way to remove the markers that the directions put on the map? I have 4 locations that show on the map. A green arrow where the user is and 3 locations marked A, B, C. If I click on one it routes between the user's location and the marker. The problem is that google adds a new A & B marker to the map as the start and end of the directions. Now I have a couple A and B markers on the map and it's pretty confusing.
Thanks
In the DirectionsRendererOptions set suppressMarkers to true
This is an old post, but I ran on the same issue. I have map with my own markers, I would select few of them and starting point, then I would show directions with markers A, B, C... The problem was how to remove directions and show my markers again.
Here is what worked for me to remove direction paths with markers (A, B, C, etc..).
directionsDisplay.setMap(null);
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
RefreshMarkers(); //your function to draw your markers
directionDisplay is declared globally. It's API v3.
Not sure if this is helpful or not. When you create a new GDirection and supply it with a map object, it will automatically draw the polyline to the map as soon as the direction is loaded. This also automatically adds the markers at the start and end of the journey.
I've noticed, however, that if you don't supply the map object initially and instead use the the 'load' event listener to manually add the polyline to the map, you get the line but not the markers.
//Don't supply a map to GDirections()
var direction = new GDirections();
//Make sure {getPolyline:true} is given to the load function
direction.load("here to there", {getPolyline:true});
GEvent.addListener(direction,
"load",
function(){ map.addOverlay(direction.getPolyline()); }
);
This might be easier than finding and removing the markers, especially if you're using the 'load' event listener anyway.
For each marker you want to remove, do
marker.setMap(null);
http://code.google.com/apis/maps/documentation/v3/overlays.html#Markers
Hit menu then layers and on the lower left press clear map. That should clear out everything on the map.
Normally you'd be able to simply do marker.setMap(null), but because the Directions call automatically places the A & B markers on the map, you do not have direct access to them and therefore cannot remove them in this way.
Related
I created a prototype for a project I'm working on, in which the user should create various markers in a map, be able to remove them, calculate a route with the markers, and go back to manage the markers.
I used some code found here in geocodezip.com to calculate the route, and wrote some for the markers, etc.
My problem is that once the user calculates the route, no matter how he edits the markers, when clicking the button to calculate the route, the map only returns the route with the markers that were there on the first time he clicked the button. And the strangest thing is that I checked the coordinates that are being passed to the script that generates the route and the function is sending the markers as it should, but no matter the coordinates sent, it only works correctly on the first time.
Js Fiddle: https://jsfiddle.net/1kmg2u65/2/
The code is really really long so it's all in the Fiddle, but this is what it does:
1. User clicks on map, generate marker, marker goes to an array
2. If user deletes marker, it becomes null in array, to maintain the indexes
3. 'Clean' markers array receives all the markers in order, without the items that are null
4. A function is called with all the markers, this function creates the route
5. To manage the markers, a function reload the map just like it was in the start, but render all the markers that already are in the markers array
it works fine if you remove the conditional if (!window.tour) in Tour_startUp function definition.
So here is what I believe is going on.
In the function markMap() you are instantiating new markers that belong to the google map object.
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
}
}
This if fine, but you are not storing that constructed object anywhere. You need to be able to reference that marker to UN-associate it from the map.
At the end of the this for loop you need to add THAT mark to a global array so you can manage it later in the script.
EXAMPLE
// defined at the top of the script
var markerGlobal = [];
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
// push marker onto global array
markerGlobal.push(marker);
}
}
Now we can loop through the array and setMap to null
// un-reference marker from map
markerGlobal[2].setMap(null);
I see you tried to do this with the removeMarker() function, but it doesn't have the handles to the markers already added to the map.
Some Suggestions
If I was you, I would think about refactoring the code to have one multi dimensional object that holds all the markers, their row info, variables etc.
You could take it one step further and create a constructor function that handles the map and its associated markers. It would be most efficient.
Good luck.
Let's say I have the following objects:
var map = new google.maps.Map(...)
var marker = new google.maps.Marker(...);
I can add marker to map with:
marker.setMap(map);
If the marker already exists on the map, and I call marker.setMap(map) again, does the API actually redraw the marker? Or does it know the marker already exists on the map, so it doesn't take any further actions?
I am listening for events and need to either add or remove markers from the map when those events occur. I'm wondering if I can simply keep calling setMap(map) even if the marker already exists without performance suffering significantly, or do I need to be smarter and not call setMap in the first place if the marker is already on the map.
If you don't know the answer, do you have any idea how I could figure this out?
If the marker already exists on the map, and I call marker.setMap(map)
again, does the API actually redraw the marker? Or does it know the
marker already exists on the map, so it doesn't take any further
actions?
The setMap function work on the visibility of the marker... assing to the marker in which map object this marker must be place/visibile..
If you set marker.setMap(null) you don't destroy the marker simply is not more showed in the "map".
when you manage event on marker you can use setMap(null) for make the marker invisible.. if you have previuosly stored the marker object in some var..eg
var store_marker = marker;
you can simply turn it on again doing
store_marke.setMap(map);
You can use array for manage collection of markers
I have a mapbox.js map but the parameter zoom doesn't seem to be doing anything
and I can't figure it out in the documentation. whatever I set zoom to the zoom level always defaults to my project zoom level Here is the code:
<script src='https://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.css' rel='stylesheet' />
$(document).ready(function() {
var map = L.mapbox.map('map', 'nhaines.hek4pklk', {
zoom: 1
});
// disable drag and zoom handlers
map.dragging.disable();
map.touchZoom.disable();
map.doubleClickZoom.disable();
map.scrollWheelZoom.disable();
// disable tap handler, if present.
if (map.tap) map.tap.disable();
});
It took me a lot of digging around but I figured this out on my own. The dev's didn't respond yet. We were going about this all wrong. Here's what to do:
First, create the MapBox object, but set zoomAnimation to false. This question helped me realize that trying to setZoom while a CSS3 animation was in progress wouldn't ever work because it's tough to break out of. At least that's what I think is going on. Setting zoomAnimation to true allows the map to animate in and bypasses any custom zoom levels, so clearly this is very important.
var map = L.mapbox.map('map', 'username.map_id', {
zoomAnimation: false
});
Next, create a polygon layer and add to map from map's geojson. You find this within your MapBox projects > info tab. (In my case this geojson happens to contain the lat/lng coords of a polygon but your case may be different. featureLayer() should still add the geojson either way.)
var polygonLayer = L.mapbox.featureLayer().loadURL('http://your/maps/geojson').addTo(map);
After polygon layer (or whatever your lat/lng coords are of) has been added to map
polygonLayer.on('ready', function() {
// featureLayer.getBounds() returns the corners of the furthest-out markers,
// and map.fitBounds() makes sure that the map contains these.
map.fitBounds(polygonLayer.getBounds());
map.setView(map.getCenter(), 10);
}
Apparently fitBounds satisfies the map requirements to allow setView to be called on it, since now you can just call the map object directly to get the center lat/lng.
I haven't tested this in simple cases - I adapted this code from mine which checks if an address's lat/lng coords fall within a polygon while iterating over a series of MapBox maps. It should get you going though. Hope it helps!
I have a leaflet.js map that has points and linestrings on it that come from an external JSON file.
If I add:
map.setView(new L.LatLng(0,0), 10);
It will centre the map on the latitude and longitude 0,0. How can I set it so the map centre and zoom fit all of the points from the JSON on it?
You could add all of your layers to a FeatureGroup which has a getBounds method. So you should be able to just say myMap.fitBounds(myFeatureGroup.getBounds());
The getBounds method for L.FeatureGroup is only available in the master branch (not the latest version, 0.3.1), for now at least.
Similar case with me. I drawn all the markers from GeoJson data. So I written the function, which gets called repeatedly on button click. Just try if it suits your requirements.
function bestFitZoom()
{
// declaring the group variable
var group = new L.featureGroup;
// map._layers gives all the layers of the map including main container
// so looping in all those layers filtering those having feature
$.each(map._layers, function(ml){
// here we can be more specific to feature for point, line etc.
if(map._layers[].feature)
{
group.addLayer(this)
}
})
map.fitBounds(group.getBounds());
}
The best use of writing this function is that even state of map/markers changed, it will get latest/current state of markers/layers. Whenever this method gets called all the layers will be visible to modest zoom level.
I needed to do this when showing a user directions from his origin to a destination. I store my list of directions in an array of L.LatLng called directionLatLngs then you can simply call
map.fitBounds(directionLatLngs);
This works because map.fitBounds takes a L.LatLngBounds object which is just an array of L.LatLng
http://leafletjs.com/reference.html#latlngbounds
I discovered that is possible to add only eight waypoints in google api directions, you know how to bypass this limitation? I've tried to display direction api, but gave up this idea. Now my solution is based on own polyline, each click adds marker that should stick to that line, next together with it should move as you drag and here occurred is that if there are more than 8 points polyline with markers is no longer compatible. Maybe my approach is completly bad? How to fix this?
Current code: jsfiddle
Markers are not on the polyline:
One way to avoid markers being placed in the middle of the block is to place one at the end of the generated polyline, for example, inside one of your loops, instead of where the click was.
for (k = 0; k < next.length; k++) {
polyline.getPath().push(next[k]);
if (z == steps.length-1 && k == next.length-1) {
var roadMarker = new google.maps.Marker( {
map: map,
position: next[k],
icon: "http://labs.google.com/ridefinder/images/mm_20_green.png"
});
}
}
You will have to also change the first marker to be placed at the start of the polyline
This applies the code above http://jsfiddle.net/T79as/3/
So, my solution is to create render DirectionRenderner between each important waypoint (with marker?):
http://jsfiddle.net/9T7Vg/
draggable markers that look exactly like original ones
draggable polyline with immediately calculation
custom markers with letters (A, B, etc.) - this was difficult
route computation in long distance is much faster
route can have more than 8 waypoints (you can improve script to automate split the route when user want to place 9th waypoint between markers)
So this solution is in fact better than original in Google Maps, especially with long routes.