I have a local .json file with lat/long coordinates for each feature, and a column Distance that is empty (randomly putting 999).
The overall goal is to display markers in a leaflet map and filter it based on geolcoation using a button.
I am trying to create one button that is able to:
Get my current location
Calculate distance for each feature in my json file (for loop)
[Blocking point] Update the column Distance / or create a new column
filter json file based on distance (for ex. show me markers where distance is under 100 km)
I got inspiration from this example
but had suffered with the "callback hell" issue.
I am right now in the 3rd step : I managed to calculate distance. but not working outside the function.
Here the code I'm using, The blockage is in the For loop: the distance column is not being updated
var allmarkers = L.markerClusterGroup();
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
}
})
console.log(data.features[0].properties.distance); //check BUG : showing initial distance [999]
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
Do you have any recommendations on how to structure my code to access the data with the updated Distance column
Thank you
I got a solution !
I had only to put the var distance100 right after the For loop
With these functions : On button click, you are able to filter markers in a Leaflet map based on your current location (by updating distance in your json file)
Many cases are tackled here : read/access and update a Geojson local file, filter Leaflet markers onclick, use geolocation coordinates in another function, calculate distance ...
the updated code is below (loading the map and the controls is not covered):
var allmarkers = L.markerClusterGroup(); //markercluster plugin using leaflet
var markersdist100 = L.markerClusterGroup();
// Load json file
var promise = $.getJSON("./data/FILE.geojson");
promise.then(function(data) {
// Update distance in json data
// Geolocation part to get current position
var userPositionPromise = new Promise(function(resolve, reject) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(data1) {
resolve(data1);
}, function(error) {
reject(error);
});
} else {
reject({
error: 'browser doesn\'t support geolocation'
});
};
});
userPositionPromise.then(function(dataa) {
lat = dataa.coords.latitude;
lng = dataa.coords.longitude;
console.log(lng); // check ok : lng of current location
console.log(data.features.length); //check ok : json length for iteration
// For loop to calculate the new distance
for (var i = 0; i < data.features.length; i++) {
data.features[i].properties.distance = getDistanceFromLatLonInKm(lat, lng, data.features[i].geometry.coordinates[0], data.features[i].geometry.coordinates[1]);
console.log(data.features[i].properties.distance); //check ok : showing the right distance
};
// data filtered by distance, see the function [filter_distance]
var distance100 = L.geoJson(data, {
pointToLayer: style_markers,
filter: filter_distance
});
// Filter distance on button click
$("#distance100").click(function() {
markersdist100.addLayer(distance100);
allmarkers.addLayer(all);
map.addLayer(markersdist100);
map.removeLayer(allmarkers);
});
});
//all data
var all = L.geoJson(data, {
pointToLayer: style_markers,
});
});
// FUNCTIONS
function filter_distance(feature, other) {
return feature.properties.distance < 100;
};
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
};
function deg2rad(deg) {
return deg * (Math.PI / 180)
};
A screenshot of my map
Hope this can help others in their use cases
Feel free to optimize the code and share it with us
Related
I'm facing issues getting value of a variable from another function. I'm trying to get the distance of the place from current position in google maps, but using Haversine Formula of calculating distance.
My HTML:
<p>
<script>
lat = "<?php echo $atm_row_data->latitude;?>";
lng = "<?php echo $atm_row_data->longitude;?>";
dist = getDistance(lat, lng);
document.write(dist);
</script>
</p>
My JavaScript:
var curPosition;
var lat, lng;
/**** get current position ****/
function getPosition() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showCurrentPosition);
} else {
alert('Geolocation is not supported by this browser.');
}
}
function showCurrentPosition(position) {
lat = position.coords.latitude;
lng = position.coords.longitude;
curPosition = new google.maps.LatLng(lat, lng);
console.log('curPosition: '+curPosition); <--- this works
}
/******** Haversine Formula of Getting Distance ********/
var rad = function(x) {
return x * Math.PI / 180;
};
function getDistance(lt, lg) {
console.log(curPosition); <--- this shows undefined
var p1 = curPosition;
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(lt - p1.lat());
var dLong = rad(lg - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(lt)) *
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
if (d >= 1000)
return Math.round( (d / 1000) * 100) / 100 + "Km";
else
return Math.round( (d * 100) / 100) + "m";
};
/******** END Haversine Formula of Getting Distance ********/
Where am I going wrong?
Any help is appreciated...
Knowing the google api, , navigator.geolocation has a callback, so showcurrentPostion is the callback function, but the thing is u never call
getPosition() <--
function getDistance(lt, lg) {
console.log(curPosition); <--- this shows undefined <---- so this will always be undefined
var p1 = curPosition;
var R = 6378137; // Earth’s mean radius in meter
var dLat = rad(lt - p1.lat());
var dLong = rad(lg - p1.lng());
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(rad(p1.lat())) * Math.cos(rad(lt)) * <--- see comment
Math.sin(dLong / 2) * Math.sin(dLong / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
if (d >= 1000)
return Math.round( (d / 1000) * 100) / 100 + "Km";
else
return Math.round( (d * 100) / 100) + "m";
};
comment: <------ p1 curposition gets an google maps object with lat and long where i know that lat() is not a function so this will fail
so even when u get the current position the function above (getDistance()) will fail
Call getPosition first() <--- u need to get the position
edit: i see that u can call console.log and you say it works, so i think its a scoping issue,
I made an example for you -> http://codepen.io/anon/pen/qOBMPj
i'm not able to render the googlemap within the pen, but u can look at the source, on how its done. hope this helps you.
so in order to do this calculation u dont really need google maps u just need the first/ and second coords, but its fun to do something with on on the google map:)
In your script tags, your only call getDistance(lat,lng), but showCurrentPosition(position) is never called! So the variable curPosition is undefined, because it is not defined yet!
You need to call showCurrentPosition(position) for the variable curPosition to hold a value.
Perhaps calling getPosition() at the beginning of your getDistance() function could solve the problem, as it seems to call showCurrentPosition.
Alternative to show the position in HTML (this is just a quick snippet, you can adapt it to whatever you like):
function getPositionHTML() {
navigator.geolocation.getCurrentPosition(function(pos) {
curPosition = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
});
return curPosition;
}
It basically does the same thing as your other function, but it relies on the Single Reponsibility Principle, so once you called this function you can manipulate curPosition however you want.
I'd like to help the user to input an orientation for a segment with OpenLayers.
I have that form where user can input the bearing for a point, but I would like to help him by :
start drawing the first vertice of a segment on the map when the user clicks on a button, (that first vertice being a known point)
then the user just has to click for the second vertice, and bearing is computed automatically.
See the fiddle here or SO snippet below.
I'm almost done : I can compute the bearing when a segment is drawn. But there's an exception at the very end of the script : I can't get OL to draw automatically the first point of my segment.
Thank you to anyone who can help.
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<body>
<div id="map" style="height: 500px"></div>
</body>
<script>
var CONSTANTS = {
MAP_FROM_PROJECTION: new OpenLayers.Projection("EPSG:4326"), // Transform from WGS 1984
MAP_TO_PROJECTION: new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
};
function radians(n) {
return n * (Math.PI / 180);
}
function degrees(n) {
return n * (180 / Math.PI);
}
function computeBearing(startLat, startLong, endLat, endLong) {
startLat = radians(startLat);
startLong = radians(startLong);
endLat = radians(endLat);
endLong = radians(endLong);
var dLong = endLong - startLong;
var dPhi = Math.log(Math.tan(endLat / 2.0 + Math.PI / 4.0) / Math.tan(startLat / 2.0 + Math.PI / 4.0));
if (Math.abs(dLong) > Math.PI) {
if (dLong > 0.0) dLong = -(2.0 * Math.PI - dLong);
else dLong = (2.0 * Math.PI + dLong);
}
return (degrees(Math.atan2(dLong, dPhi)) + 360.0) % 360.0;
}
map = new OpenLayers.Map("map");
map.addLayer(new OpenLayers.Layer.OSM());
map.setCenter(new OpenLayers.LonLat(3, 47).transform(CONSTANTS.MAP_FROM_PROJECTION, CONSTANTS.MAP_TO_PROJECTION), 6);
var lineLayer = new OpenLayers.Layer.Vector("Line Layer");
map.addLayers([lineLayer]);
var lineControl = new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path, {
handlerOptions: {
maxVertices: 2,
freehandMode: function(evt) {
return false;
}
},
featureAdded: function(feature) {
var drawnLinePoints = feature.geometry.getVertices();
var lonlat1 = drawnLinePoints[0].transform(CONSTANTS.MAP_TO_PROJECTION, CONSTANTS.MAP_FROM_PROJECTION);
var lonlat2 = drawnLinePoints[1].transform(CONSTANTS.MAP_TO_PROJECTION, CONSTANTS.MAP_FROM_PROJECTION);
var bearingValue = computeBearing(lonlat1.y, lonlat1.x, lonlat2.y, lonlat2.x);
console.log(bearingValue);
}
});
map.addControl(lineControl);
lineControl.activate();
var handler;
for (var i = 0; i < map.controls.length; i++) {
var control = map.controls[i];
if (control.displayClass === "olControlDrawFeature") {
handler = control.handler;
break;
}
}
// Here I have an exception in the console : I would like
// OL to draw hat point automatically.
handler.addPoint(new OpenLayers.Pixel(50, 50));
</script>
OpenLayers.Handler.Path.addPoint works on OpenLayers.Pixel, not OpenLayers.LonLat:
/**
* Method: addPoint
* Add point to geometry. Send the point index to override
* the behavior of LinearRing that disregards adding duplicate points.
*
* Parameters:
* pixel - {<OpenLayers.Pixel>} The pixel location for the new point.
*/
addPoint: function(pixel) {
this.layer.removeFeatures([this.point]);
var lonlat = this.layer.getLonLatFromViewPortPx(pixel);
this.point = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
);
this.line.geometry.addComponent(
this.point.geometry, this.line.geometry.components.length
);
this.layer.addFeatures([this.point]);
this.callback("point", [this.point.geometry, this.getGeometry()]);
this.callback("modify", [this.point.geometry, this.getSketch()]);
this.drawFeature();
delete this.redoStack;
}
I actually see no good way of achieving this other than adding an addPointByLonLat method:
OpenLayers.Handler.Path.prototype.addPointByLonLat = function(lonLat) {
this.layer.removeFeatures([this.point]);
this.point = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)
);
this.line.geometry.addComponent(
this.point.geometry, this.line.geometry.components.length
);
this.layer.addFeatures([this.point]);
this.callback("point", [this.point.geometry, this.getGeometry()]);
this.callback("modify", [this.point.geometry, this.getSketch()]);
this.drawFeature();
delete this.redoStack;
};
Or subclass as your own handler class (propbably cleaner).
Notes:
addPoint is not an API method (so addPointByLonLat is also not). This may result in problem on version changes.
Don't use the compressed/minified JS in development and check docs on methods you use.
Next time consider asking on https://gis.stackexchange.com/.
Consider asking for a code review on your JS.
You can also use insertXY(x,y) function in order to insert a point with geographic coordinates
http://dev.openlayers.org/docs/files/OpenLayers/Handler/Path-js.html#OpenLayers.Handler.Path.insertXY
lonlat = new OpenLayers.LonLat(1,45);
lonlat.transform(CONSTANTS.MAP_FROM_PROJECTION,CONSTANTS.MAP_TO_PROJECTION);
handler.createFeature(new OpenLayers.Pixel(100, 100));
handler.insertXY(lonlat.lon,lonlat.lat);
handler.drawFeature();
You can check it here with a fork of your original jsfiddle : http://jsfiddle.net/mefnpbn2/
See this fiddle for the solution.
tldr :
// draw the first point as I needed, as if a user has clicked on the map
handler.modifyFeature(new OpenLayers.Pixel(50, 50), true);
// draw a first point on the map (not clicked).
// This will be the initial point where the "cursor" is on the map, as long as
// the user hasn't hovered onto the map with its mouse. This make the blue
// line showing current segment to appear, without this segment is drawn but
// no feedback is given to the user as long as he hasn't clicked.
handler.addPoint(new OpenLayers.Pixel(50, 50)); //
So i want to calculate distance between my start point and multiple points, than display the shortest route to this point,but it show me always the last point. this is my distanceCal function it works fine :
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI / 180)
}
and this is my points latt/long :
var dist = [
[35.733972, -5.881999],
[ 35.734077, -5.881033],
[ 35.736898, -5.877771],
[35.738396, -5.875154]
];
then my script to display directions :
function calcRoute() {
var start = new google.maps.LatLng(35.728329, -5.882750);
for (var i = 0; i < dist.length; i++)
{
var dis = dist[i];
//here i need something to choose the shortest route
var min = Math.min(getDistanceFromLatLonInKm(35.728329, -5.882750, dis[0], dis[1]));
var end = new google.maps.LatLng(dis[0], dis[1]);
}
var request = {
origin: start,
destination: end,
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
google.maps.event.addDomListener(window, 'load', getMap);
so please if someone have any idea or solution i will be very appreciate.
The following code uses Googles geometry library to calculate distances between points.The distances are stored in an array and then parsed to find minimum distance .
I have changed the array from dist[] to coords[] as we need an array to hold distances dist[].
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false"></script>
<script type="text/javascript">
var coords = [
[35.733972, -5.881999],
[35.734077, -5.881033],
[35.736898, -5.877771],
[35.738396, -5.875154]
];
var dist = [];//Array to hold distances
function calcRoute() { {
var start = new google.maps.LatLng(35.728329, -5.882750);
for (var i = 0; i < coords.length; i++){
var point = new google.maps.LatLng(coords[i][0],coords[i][1]);
var distance = google.maps.geometry.spherical.computeDistanceBetween(start, point);
dist.push(distance);
}
var test = dist[0];
var index = 0;
for (var i = 1; i < dist.length; i++){
if(dist[i] < test){
test = dist[i];
index = i;
}
}
var end = new google.maps.LatLng(coords[index][0],coords[index][1]);
// Apply the rest of your code here
It sounds like you want to use optimizeWaypoints:true in your DirectionsServiceRequest:
optimizeWaypoints | boolean | If set to true, the DirectionService will attempt to re-order the supplied intermediate waypoints to minimize overall cost of the route. If waypoints are optimized, inspect DirectionsRoute.waypoint_order in the response to determine the new ordering.
The DirectionsResult
Each leg of each route returned includes distance and duration information.
Right now I have an array of locations and one of those locations will be a marker.
The second marker will be based on the location a user searches.
Right now the code is this:
function find_closest_marker( lat1, lon1 ) {
var pi = Math.PI;
var R = 6371; //equatorial radius
var distances = [];
var closest = -1;
var markers = allMyLocations;
for( i=0;i<markers.length; i++ ) {
var lat2 = markers[i][1];
var lon2 = markers[i][2];
var chLat = lat2-lat1;
var chLon = lon2-lon1;
var dLat = chLat*(pi/180);
var dLon = chLon*(pi/180);
var rLat1 = lat1*(pi/180);
var rLat2 = lat2*(pi/180);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(rLat1) * Math.cos(rLat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
distances[i] = d;
if ( closest == -1 || d < distances[closest] ) {
closest = i;
}
var closestMarker = markers[closest];
var newLat = markers[closest][1]
var newLon = markers[closest][2]
var b = new google.maps.LatLng(newLat, newLon);
map.setCenter(b);
map.setZoom(10);
google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
ShowHideMenu();
if($('#newPos').length==0){
$('div.gmnoprint').last().parent().wrap('<div id="newPos" />');
}
//showInfoWindow(map, closest);
});
}
}
Right now this code gets the closest location from where a user searches and centers that on the page. What I'm trying to do is make it zoom so that the the location searched is centered and the location in the array is within the area of the maps. The map isn't a normal size, it is 790px by 400px.
Can someone please help me with the logic of zoom and how I could make this possible?
Have you tried the LatLngBounds function This function will construct a viewable are based upon the soutwest and north east corners. As a result the pins will be centered in the map. You can use zoom if you want but you could omit it to see if it gives you the desired result.
A sample of the code would be:
make your declaration
var mybounds = new google.maps.LatLngBounds();
then within your event listener where you create the markers add
mybounds.extend(b);
then finally outside of the event listener
map.fitBounds(mybounds)
I am using bing maps ajax v7 and for simplicity's sake let's say I have 10 PinPoints placed around the world. I'm trying to have the map zoom to the lowest level so that the closest PinPoint is still visible to the current location of the user. If someone could point me in the right direction I would greatly appreciate it.
$(document).ready(function () {
var windowHeight = $(window).height();
var windowWidth = $(window).width();
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"), {
credentials: "myCredentials",
backgroundColor: "#A4C4ED",
zoom: 3,
height: windowHeight,
width: windowWidth
});
Microsoft.Maps.Events.addHandler(map, 'viewchange', hideInfoBox);
Microsoft.Maps.Events.addHandler(map, 'click', hideInfoBox);
//get users location and set view bound
var geoLocationProvider = new Microsoft.Maps.GeoLocationProvider(map);
var viewRectangle = Microsoft.Maps.LocationRect(geoLocationProvider.getCurrentPosition());
map.setView({ bounds: viewRectangle });
dataLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(dataLayer);
var infoboxLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayer);
//create initial infobox
infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), {
visible: false,
offset: new Microsoft.Maps.Point(0, 20)
});
infoboxLayer.push(infobox);
Microsoft.Maps.loadModule('Microsoft.Maps.Search', { callback: searchModuleLoaded });
});
I assume that you is one pin point and you have another 10 pin points located somewere on the map.
First you need to find the pinpoint that is closest to you.
You can use this function that expect two location objects that contains latitude and longitude.
oLocation1 = {latitude:0,longitude:0};
oLocation2 = {latitude:19,longitude:23};
function calcDistHaversine (oLocation1, oLocation2) {
var dLat = (oLocation2.latitude * Math.PI / 180 - oLocation1.latitude * Math.PI / 180);//*Math.PI*180;
var dLon = (oLocation2.longitude * Math.PI / 180 - oLocation1.longitude * Math.PI / 180);//*Math.PI*180;
var lat1 = oLocation1.latitude * Math.PI / 180;//*Math.PI*180;
var lat2 = oLocation2.latitude * Math.PI / 180;//*Math.PI*180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var distance = 6371 * c;
return distance;
};
As a result you will get the distance between those two location with respect yo earth curvature.
Now you have your location and closest pinpoint location.
Lets name them as your,their.
Next you need to create array that contains those two location converted to microsoft location objects.
var yourLocation= new Microsoft.Maps.Location(your.latitude, your.longitude);
var theirLocation= new Microsoft.Maps.Location(their.latitude, their.longitude);
var arr = [];
arr.push(yourLocation);
arr.push(theirLocation);
Now you use bing maps feature that gives you best zoom and pointing according to given locations.
var bestView = Microsoft.Maps.LocationRect.fromLocations(arrLocations);
Then you set the map view according to the best view that we found.
setTimeout((function () {
map.setView({ bounds: bestView });
}).bind(this), 1000);