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
Related
I have a google map that has some markers.I have the coordinates or each marker and I have a drawing tool that allows me to draw polygons.
I'm trying to detect if the markers inside a drawn polygon are shared with one or more others polygons so here is my logic and code :
Logic : when I draw a polygon, I put it in an array called "polygons" then I remove the last drawn polygon from that array and I extract the locations of each marker inside it then for each marker extracted I check if it is inside an other polygon or not.
Here is my code:
The issue I have is that the variable shared_markers returns always true even if no markers are shared with 2 or more polygons. Any help please?
Thanks
The line of code that is causing the problem is where you're getting all the polygons except the last one:
function checkIfSharedMarkers(polygons, gmarkers){
...
var all_drawn_polygons_except_last_one = polygons.splice(-1,1);
...
}
The Array splice() method modifies the original array. I compared the length of the array before and after that line was called and it was the same - therefore all_drawn_polygons_except_last_one still contains the last drawn polygon. I replaced that line with:
var all_drawn_polygons_except_last_one = polygons.slice(0, polygons.length-1)
which uses Array slice() instead of splice() (this ensures the original polygons array is preserved). This returns the chosen elements in a new array so all_drawn_polygons_except_last_one now has the last element removed.
Please see this Plunkr for a demo.
I use great Leaflet plugins for geocoding such as https://github.com/smeijer/L.GeoSearch
While these are perfect for showing address locations on the map when found, I would also like to be able to use the coordinates from the result to other functions that I have included in my map (e.g. I've written one which finds nearby points from a data layer based on the locationfound event fired from Leaflet's inbuilt locate function).
I know the answer (probably) lies in accessing the events from the geosearch plugin, but that's a bit beyond my skills at the moment. Any help would be very welcome.
The L.GeoSearch plugin fires it's events on your map instance. You'll need to listen for the geosearch_foundlocations event. The object that's returned when the event is fired holds a Locations property which contains an array with L.GeoSearch.Result objects. Each object has four properties; Label, X, Y and bounds
Example in code:
map.on('geosearch/showlocation', function (e) {
e.Locations.forEach(function (Location) {
// Location.Label = full address
// Location.X = longitude
// Location.Y = latitude
// Location.bounds = boundaries
});
});
I just want to clarify whether my way of understanding is correct. In my Google Maps app I would like to show to my users markers from particular continents.
Question: Am I right that a bound in Google Map API is an area made from NOT MORE AND NOT LESS than two points (markers)?
From math lessons, to draw 2D area I just need two points. Right? So to show to my users all markers from Europe should I just find two coordinates, one from Iceland (top, left) and second from let's say south-east Turkey? (For USA I would pick Seattle and Miami).
So, below JS code works perfectly. My question is - could you confirm that my way of understanding and the approach I've chosen is correct? Does it make any sense?
var bounds = new google.maps.LatLngBounds();
bounds.extend(new google.maps.LatLng('66.057878', '-22.579047')); // Iceland
bounds.extend(new google.maps.LatLng('37.961952', '43.878878')); // Turkey
this.map.fitBounds(bounds);
Yes, you are mostly correct. Except a 'bound' in Google maps case can include multiple points, for example if you had a point to the far right in the middle of the square in your image above and another at the bottom of the square in the middle you would still get an area the same as you have drawn above but with 3 points as in the edited map.
Obligatory link to the docs :)
https://developers.google.com/maps/documentation/javascript/reference?hl=en
You should not think about "top-left" and "bottom-right" but as south-west and north-east (so bottom-left and top-right if you like), as these are the coordinates used to create and/or retrieve the bounds object.
See the documentation and the getNorthEast and getSouthWest methods.
These two points are LatLng objects, and not markers. As an example, a marker is positioned on the map using a LatLng object.
I don't know your use case and your way of storing the data, but there might be a more precise way to display "Europe" markers. You could for example save the region along with each marker so that you can just query for "EU" markers and not others...
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 markers in two marker layers,which i need to keep separate, so I can clear one or the other in the application.
What is the best way to make sure all markers are displayed. Doing it for one layer is easy with zoomToExtent. But how to do it for more then one layer?
Get the bounds from layer 1, use .extend(layer 2's bounds), and then zoomToExtent on the extended bounds.
http://dev.openlayers.org/releases/OpenLayers-2.10/doc/apidocs/files/OpenLayers/BaseTypes/Bounds-js.html#OpenLayers.Bounds.extend
is the extend method on a bounds.
sketchy and quick, sorry....
Use a new bounds object and use Bounds.extend.
var myNewBounds = Layer1.zoomToExtent.getExtent();
myNewBounds.extend(Layer2.zoomToExtent.getExtent());
Use that new bounds variable to set the bounds on your map. The syntax is wrong, but that's the direction you want to go.