Mapbox geocode with Jumpto instead of Flyto? - mapbox

Mapbox has a default geocoding feature called flyto. It zooms out of your current location pans across the map and zooms in on another location. This looks cool but it seems to run slow with a large data set. Is it possible to change the default geocoding feature to Jumpto instead of Flyto? I've noticed jumpto tends to load faster in other examples with large data.

See the API documentation https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md there is a flyTo option you can set to false.

Disabling the flyTo will result in the map not moving at all. There is currently no way to make use of a jumpTo animation with the Geocoder Control but what you can do change the animation properties.
As per the documentation, the flyTo parameter accepts an AnimationOptions object as a parameter, where you can set the duration to 0.
const geocoder = new MapboxGeocoder({
accessToken: MAPBOX_ACCESS_TOKEN,
mapboxgl: mapboxgl,
flyTo: { duration: 0 }
});
This will make the animation instantaneous.

Related

Is there any way to retrieve coordinates from searched location in mapbox?

I am using mapbox geocoder to search for a location in one of my mapbox project. I am able to implement the search functionality successfully but I am having hard time in extracting the selected address by the user from the list of searched/suggested addresses.
Is there any way to get the coordinates of the searched place?
I went through mapbox docs but only found an event 'moveend' which is fired when we fly to some location. So I am listening for that event and once fired, I am calling getBounds() function on the map. It somehow works but it doesn't give me the exact coordinates since getBounds() gives the South West and North East coordinates of the box. Can we get the exact coordinates of the selected place?
Below is the code I am using to search for a place.
initMapSearch() {
var _this = this;
var geocoder = new MapboxGeocoder({ accessToken: environment.mapbox.accessToken, mapboxgl: mapboxgl });
this.locationObj = geocoder.onAdd(_this.map)
document.getElementById('geocoder').appendChild(this.locationObj);
}
And this is my moveend event.
this.map.on('moveend', function() {
_this.lat = _this.map.getBounds()["_ne"]["lng"];
_this.long = _this.map.getBounds()["_ne"]["lat"];
});
Thanks in advance to the community.
You should listen to geocoder.on('result') which is passed the feature (and its location).

Marker position being updated only for a short period of time in Mapbox GL JS

I have a loop where I am constantly updating the position of a marker:
function loop(timestamp) {
marker._lngLat.lng = clientState.markers[room.sessionId].lng;
marker._lngLat.lat = clientState.markers[room.sessionId].lat;
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(loop);
Strangely, the position is updated only for ~ one second and then stops updating. If the camera position is updated, the position of the marker updates once again for ~ one second and then once again stops updating.
What might be the problem? Thank you in advance for your insight.
_lngLat is a private property which has no guarantees, you should use the public method to set location, see the API docs I think it's called setLngLat

Get Mapbox point for queryRenderedFeatures based on longitude and latitude

I found an address with the Mapbox Geocoding API. Then I want to highlight that building on the map.
It works in native, but does not in web. I want to have the point in the mapBox view for the renderedFeatures.
Something like this
pointInView = await map.getPointInView(foundAddress.center)
foundBuildings = await map.queryRenderedFeaturesAtPoint(pointInView)
How can I convert long,lat to the a point in mapbox-gl-js
Update
Found something helpful
How can I query the feature that's closest to the geocode result in Mapbox?
Found it, it's called project(LngLat)
pointInView = await map.project(foundAddress.center)
See: https://docs.mapbox.com/mapbox-gl-js/api/#map#project

leaflet routing machine when waypoints are the same

I am using this plugin : https://github.com/perliedman/leaflet-routing-machine.
My code looks like this:
for(let i=0; i<markers.length; i++){
points.push(L.latLng(markers[i].latitude, markers[i].longitude))
}
this.routingControl = L.Routing.control({
waypoints: points
}).addTo(this.map);
When I pass points filled with different latitude/longitude, it draws the route fine. But let's imagine the following scenario. let's say that points array contains 3 items. each item contains latitude/longitude and let's say that those latitude/longitude are the same. So something like this:
34.72581233927868 -80.71105957031251
34.72581233927868 -80.71105957031251
34.72581233927868 -80.71105957031251
Now what Routing control does is as it can't draw the route, it automatically zooms in in the maximum way and in the console, it shows the errors. {"message":"Zoom level must be between 0-20."}
Workaround 1: after drawing routes, i decided to use settimeout after 1 second and there I zoom at 11 by myseslf. this way it zooms out, but in the console, errors still stay. How do I fix this?
If you know your input can be invalid, then the cleanest way would be to filter it on the way in to remove duplicates. If that's not possible for some reason and you want to let LRM determine if there's an error, then you can catch the error event with:
L.Routing.control({
...
})
.addTo(this.map)
.on('routingerror', function(e) {
// do your error action here - e.g. zoom out
})
For more information on handling errors in LRM, see https://www.liedman.net/leaflet-routing-machine/api/#eventobjects

When does mapquest route finish rendering?

I am using MapQuest map with leaflet. The routes are being injected dynamically. When we add routes to the map, it takes time to finish the rendering.
I want to block the screen while the map is being rendered.
Is there any way(mapquest API or leaflet event) to know the map is ready or finished rendering so that I can stop the blocking of the screen.
I'm using Leaflet to add the routes. Something like this:
function (locations) {
const dir = MQ.routing.directions();
dir.route({ locations: locations });
comp.mqroute = MQ.routing.routeLayer({
directions: dir,
fitBounds: true,
draggable: false,
});
comp.map.addLayer(comp.mqroute);
}
This is a case of RTFM.
The fact that you're using MQ.routing.directions in your code tells me that you're using the Mapquest routing plugin for Leaflet, which has complete API documentation.
By reading that API documentation, one can notice a success event, I quote:
success
Fired when route data has been retrieved from the server and shapePoints have been decompressed. [...]
I have a heavy suspicion that you don't need to know when the route is rendered (meaning: when the lines have been displayed on the screen) but rather when then network requests for the route are finished (which is what takes most time). The time to actually render lines on the screen is usually negligible unless one is working with thousands of segments (after the automatic douglas-peucker simplification).
I also have a heavy suspicion that this is a XY problem, and that the root problem you're trying to solve is race conditions when the user is (re-)requesting routes too fast, to which the solution is just throttling the requests rather than blocking the UI.
How to use this success event is illustrated in MapQuest's Route Narrative example:
dir = MQ.routing.directions();
dir.on('success', function(data) {
// ...
// the code here will run once the route is ready
// ...
}