Is it possible in Mapbox GL to set a zoom level after the user selects one search result? My goal is to show at least a few markers on the map around the user. Or is there another way to achieve the same result, like zoom to geocoder marker + nearest marker?
You can set the zoom level that the Mapbox geocoder goes to when there's a result like this:
new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
zoom: 12
})
After the user selects a geocoder result, its possible to give him some options to fit specific zoom level, by using the flyTo options
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
flyTo: {
padding: 15, // If you want some minimum space around your result
easing: function(t) {
return t;
},
maxZoom: 6, // If you want your result not to go further than a specific zoom
}
})
More options for the flyTo property here : https://docs.mapbox.com/mapbox-gl-js/api/map/#map#flyto
You want to use the zoom variable from flyTo
map.addControl(
new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
flyTo: {
bearing: 0,
speed: 0.8,
curve: 1,
zoom: 6,
easing: function (t) {
return t;
}
},
mapboxgl: mapboxgl,
})
);
Related
in Leaflet.Editable I need to draw several polygons, be able to edit them and at the end save them as GeoJSON or delete them all together by external button. I can do it with one polygon:
map = new L.Map('mapa', {
maxBounds: extent,
minZoom: 12,
zoomControl:false,
touchZoom: true,
tap: false,
editable:true,
attributionControl:true,
zoomControl: true
});
$('body').on('click','#start_drawing',function(e){
newPolygon=map.editTools.startPolygon('',{color:'#d7191c', opacity:0.8, weight: 5,fillColor:'#d7191c', fillOpacity:0.2});
});
$('body').on('click','#delete_drawing',function(e){
map.removeLayer(newPolygon);
});
$('body').on('click','#save_drawing',function(e){
newPolygon.toGeoJSON();
});
I tried to set featureLayer for LeafletEditable, but it created empty LayerGroup.
Thanks for help,
Dan
Grouping the new polygons is the way to go, but you need to set up a group to hold them outside the callbacks for the controls. Add an empty group to the map first, then add the new polygons to that as you create them. Something along these lines should work:
map = new L.Map('mapa', {
maxBounds: extent,
minZoom: 12,
zoomControl:false,
touchZoom: true,
tap: false,
editable:true,
attributionControl:true,
zoomControl: true
});
const fg = L.featureGroup().addTo(map);
$('body').on('click','#start_drawing',function(e){
const newPolygon=map.editTools.startPolygon('',{color:'#d7191c', opacity:0.8, weight: 5, fillColor:'#d7191c', fillOpacity:0.2});
fg.addLayer(newPolygon);
});
$('body').on('click','#delete_drawing',function(e){
fg.clearLayers();
});
$('body').on('click','#save_drawing',function(e){
let geoJSON = fg.toGeoJSON();
// Do something with geoJSON...
});
Leaflet has a nice heatmap layer, but which I am finding difficulties to handle when zooming into the map.
I can set the data to have a radius of 0.1 and they look very nice when I have a zoom level of 8.
If a user zooms in to a level of, say 10, the map becomes entirely covered by the heatmap.
Also, if the user zooms out to level 6 the heatmap becomes invisible.
Can anyone, please, let me know how to scale the radius of data points of the heatmap, so as to obtain a similar effect to that of Google Maps Heatmap?
Thank you!
EDITED:
I used the heatmap from Patrick Wield heatmap.js
The code I used is as follows:
<script>
window.onload = function() {
var myData = {
max: 1000,
data: [
{lat: 50.32638, lng: 9.81727, count: 1},
{lat: 50.31009, lng: 9.57019, count: 1},
{lat: 50.31257, lng: 9.44102, count: 1},
]
};
var baseLayer = L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © CloudMade',
maxZoom: 18,
minZoom: 7
}
);
var cfg = {
"radius": .1,
"maxOpacity": 1,
"scaleRadius": true,
"useLocalExtrema": true,
latField: 'lat',
lngField: 'lng',
valueField: 'count'
};
var heatmapLayer = new HeatmapOverlay(cfg);
var map = new L.Map('map', {
center: new L.LatLng(50.339247, 9.902947),
zoom: 8,
layers: [baseLayer, heatmapLayer]
});
heatmapLayer.setData(myData);
layer = heatmapLayer;
};
</script>
In the following code in Ionic Project, sometimes map doesn't fit correctly an center
code:
initMap() {
this.mapInitialised = true;
this.bounds = new google.maps.LatLngBounds();
this.Geolocation.getCurrentPosition().then((position) => {
this.location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
let mapOptions = {
center: this.location,
zoom: 15,
draggable: true,
backgroundColor: 'white',
fullscreenControl: false,
mapTypeControl: false,
zoomControl: true,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
this.map.fitBounds(this.bounds); //# auto - zoom
this.map.panToBounds(this.bounds);
console.log(this.location);
this.PostMarker(this.Postlatlng);
this.CurrentMarker(this.location);
});
}
CurrentMarker(location){
console.log(location.lat, location.lng);
let image = 'https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi_hdpi.png';
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: location,
icon: image
});
this.bounds.extend(new google.maps.LatLng(location.lat(), location.lng()));
}
PostMarker(location) {
console.log(location.lat,location.lng);
let image = 'https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi_hdpi.png';
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: location,
icon: image
});
this.bounds.extend(new google.maps.LatLng(location.lat, location.lng));
}
output:
after zooming out:
update
As you can see in the output map of the screen is pacific ocean while test data point is a place in Tibet and the second point is my current location in Iran. instead of fitting this two point in screen it shows wrong location/area.
This problem mostly happens when two point is so far from each other. In near location Isaw this problem one or two times.
Set the minZoom map option. Otherwise, the screenshot you have posted it how the API (correctly) behaves when you zoom out to 0.
For example:
new google.maps.Map(element,{minZoom:3});
I'm working on a map with a few circleMarkers. When a user is clickin on one of this circleMarker, I would like to center the map on this circleMarker and to zoom in. It works when I try this on multipolygon layers, but I didn't succeed on circleMarkers. Does anyone can help me?
Here is the code for my circleMarkers:
<script>
var map = L.map('map', {
center: [41.8, 12.5],
zoom: 5,
zoomControl:true, maxZoom:15, minZoom:4,
});
var feature_group = new L.featureGroup([]);
var raster_group = new L.LayerGroup([]);
var basemap = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Source: Esri',
});
basemap.addTo(map);
function style1(feature) {
return {
weight: 2,
radius: 10,
opacity: 1,
color: 'black',
weight: 1,
fillOpacity: 1,
fillColor: 'red'
};
}
L.geoJson(villes, {
style: style1,
pointToLayer: function (feature, latlng)
{
return L.circleMarker(latlng).bindLabel( feature.properties.Name, {className: "ville", noHide: true });
}
}
)
.addTo(map)
.showLabel;
</script>.
Here is a link to the complete map.
Thank you.
This can be achieved really simply.
Let's assume marker points to your leaflet marker and map to your leaflet map.
Quick way (recommended)
marker.on("click", function(event) {
map.setView(marker.getLatLng(), 16);
}, marker);
Here, I don't even compute the needed zoom level, because I assume leaflet will have to zoom to its max level anyway.
I could also have added my marker to a L.LayerGroup, even if the main point of a LayerGroup is to group multiple markers.
Anyhow, the more precise way
marker.on("click", function(event) {
map.setView(marker.getLatLng(), map.getBoundsZoom(layerGroup.getBounds());
}, marker);
Note that the quick way will do it nicely too. The second solution might seem more precise but it also slower, and implies a use of LayerGroup which is not the way it has been designed to work (create a new layergroup for each marker).
Don't forget to take yout time reading the docs, it's well-designed and pretty easy to understand.
I find the solution:
function onClick(e) {map.setView(this.getLatLng(),15);}
L.geoJson(villes, {
style: style1,
pointToLayer: function (feature, latlng)
{
return L.circleMarker(latlng).bindLabel( feature.properties.Name, {className: "ville", noHide: true }).on('click', onClick);
}
}
)
.addTo(zoom1)
.showLabel;
Thanks Stranded Kid for your help.
On this Leaflet application I show all available bus stops in Denmark.
http://drivetime.mapicture.dk/stops
The strange thing is, that if you zoom down to one of the last 4 zoom levels, the layer with these bus stops simply disappears. They reappear when you zoom out again.
The bus stops are made as a single layer retrieved through a WMS request to our Geoserver. The entire javascript code is actually pretty simple, so I have trouble finding out, what causes this behavior.
function CurrentStopsMap(mapNode, zoomSettings) {
var self = this;
self.mapNode = mapNode;
self.zoomSettings = zoomSettings;
self.mapquest = new L.TileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: "©<a href='http://openstreetmap.org/' target='_blank'>OpenStreetMap</a> contributors, Tiles Courtesy of <a href='http://open.mapquest.com' target='_blank'>MapQuest</a>",
subdomains: ['1', '2', '3', '4']
});
self.regions = new L.TileLayer.WMS("http://backend.mapicture.dk:8080/geoserver/mapicture/wms", {
layers: 'mapicture:region',
format: 'image/png',
styles: 'regions',
transparent: false
});
self.stops = new L.TileLayer.WMS("http://backend.mapicture.dk:8080/geoserver/mapicture/wms", {
layers: 'mapicture:stops',
format: 'image/png',
transparent: true
});
self.map = new L.Map(mapNode, {
center: new L.LatLng(zoomSettings.lat, zoomSettings.lon),
zoom: zoomSettings.level,
layers: [self.mapquest, self.stops],
zoomControl: true
});
L.control.layers({
"Kort": self.mapquest,
"Områder": self.regions
}, {
"Stoppesteder": self.stops
}).addTo(self.map);
}
var zoom = {
lat: 56.24,
lon: 10.68,
level: 7
};
var map = new CurrentStopsMap('map', zoom)
This was actually a problem with the Geoserver daemon.