Calculate leaflet map view port - leaflet

I have view port bounding coordinates (NE(7.48855,80.3641) and SW (7.46907, 80.30747)). Also I have view port height(867px) and width(1866). I calculated zoom and center point to get complete view of above bounds. I used https://leafletjs.com/examples/zoom-levels/ to make logic. With my calculation i got zoom 14 for height and 15 for width.
const getNumberOfSeconds = (decimal) =>{
const degrees = Math.floor(decimal);
const minutes = Math.floor(60 * (decimal - degrees));
const seconds = 3600 * (decimal - degrees) - 60 * minutes;
return (degrees * 3600 + minutes *60+ seconds)
}
export const getViewPort = (bound, height,width) =>{
const tileWidth = 256.;
const latDiff = Math.abs(bound.maxLat - bound.minLat)
const latDiffSeconds = getNumberOfSeconds(latDiff);
const zoom1_2n = (180 * 3600 * height) / (tileWidth * latDiffSeconds);
const zoom1 = Math.floor(Math.log10(zoom1_2n) / Math.log10(2));
const lonDiff = Math.abs(bound.maxLng - bound.minLng)
const lonDiffSeconds = getNumberOfSeconds(lonDiff);
const zoom2_2n = (360 * 3600 * width) / (tileWidth * lonDiffSeconds);
const zoom2 = Math.floor(Math.log10(zoom2_2n) / Math.log10(2));
const center = [0.5 * (bound.maxLat + bound.minLat), 0.5 * (bound.maxLng + bound.minLng)]
const zoom = Math.min(zoom1, zoom2)
const newViewPort = { center, zoom }
return newViewPort;
}
Then I get the minimum zoom level which is 14.
My question is with zoom level 15, map can show above bound. I think I have done mistake at calculation. Please help me to find that, or let me help to calculate zoom value.

Related

How can we calculate bound from a point?

I have a coordinate. How can we calculate the bounds that the point is centered in map?
Call that point O and its bound has size 5x5m
.
Do any of you have a solution? I don't have a solution yet.
Solution:
* Returns the Point resulting from moving a distance from an origin in the
* specified heading (expressed in degrees clockwise from north).
*
* #param from The Point from which to start.
* #param distance The distance to travel.
* #param heading The heading in degrees clockwise from north.
*/
public static Point computeOffset(Point from, double distance, double heading)
{
distance /= MathUtil.EARTH_RADIUS;
heading = MathUtil.convertToRadians(heading);
// http://williams.best.vwh.net/avform.htm#LL
double fromLat = MathUtil.convertToRadians(from.Lat);
double fromLng = MathUtil.convertToRadians(from.Lng);
double cosDistance = Math.Cos(distance);
double sinDistance = Math.Sin(distance);
double sinFromLat = Math.Sin(fromLat);
double cosFromLat = Math.Cos(fromLat);
double sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * Math.Cos(heading);
double dLng = Math.Atan2(sinDistance * cosFromLat * Math.Sin(heading), cosDistance - sinFromLat * sinLat);
return new Point(MathUtil.toDegreesFromRadians(Math.Asin(sinLat)), MathUtil.toDegreesFromRadians(fromLng + dLng));
}

Check if 2 coordinates are in the same city

Basically, I have 2 LatLong values 1 for the user that keeps updating according to his current location and 1 stored on the database. How can I check if these 2 coordinates are in the same city or state.
Note: I used the google maps API https://maps.googleapis.com/maps/api/geocode/json?latlng=33.26944346171845,%2035.20463784635442&sensor=true&key=KEY for both coordinates and compared strings(administrative_area_level_2) to check if the user is in the same city or not. Is there a better way to do it in Flutter?
Thanks in advance!
I think your method is quite reasonable. If you don't want to use API, you can calculate the distance between two coordinates with the below method. Using this, you can assume that those below a certain distance are in the same city or state.
const convertToRadian = x => x * Math.PI / 180;
function getDistanceBetween(lat1, lat2, lng1, lng2) {
const R = 6378137; // Earth’s mean radius in meter
const dLat = convertToRadian(lat2 - lat1);
const dLong = convertToRadian(lng2 - lng1);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(convertToRadian(lat1)) * Math.cos(convertToRadian(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c; // returns the distance in meter
}

How to add a buffer with fixed size in pixels using leaflet and turf

I'm trying to create a buffer with fixed size using leaflet and turf, the buffer should be created when the mapClick event is emitted, so basically a buffer is created when I click the map
when creating a buffer or a circle you need to pass a radius property which is pretty much the "size" of the buffer, which can be in Kilometers, Meters, Miles and so on
The problem is: I need the buffer to always be the same size in pixels regardless of the mapZoom or Scale, for instance, using circle:
const center = [LatlongFromMouseEvent];
const radius = 5;
const options = {steps: 10, units: 'kilometers', properties: {foo: 'bar'}};
const circle = turf.circle(center, radius, options);
OR using buffer
const point = turf.point([LatlongFromMouseEvent]);
const buffered = turf.buffer(point, 5, {units: 'kilometers'});
OR using native Leaflet "Circle" constructor
const lCircle = new Circle([event.latlng.lat, event.latlng.lng], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500
})
lCircle.addTo(mapInstance)
All of those "buffers" will change it's size depending on the level of zoom of the map
AND "circleMarker" from leaflet automatically changes size when you change the zoom
Found a solution by using the metersPerPixel formula
const zoom = map.getZoom()
const lat = map.getCenter().lat
const metersPerPixel = 156543.03392 * Math.cos(lat * Math.PI / 180) / Math.pow(2, zoom)
const radius = metersPerPixel * sizeInPixels
More info about the formula in:
https://gis.stackexchange.com/questions/7430/what-ratio-scales-do-google-maps-zoom-levels-correspond-to

Dividing long and lat coordinates into sub-coordinates(smaller squares)?

I have 2 long, lat points of a rectangle(bottom left and top right) and I want to divide this rectangle into smaller ones based on a base area (long and lat) I already have. I already know that I can't deal with long and lat as distance measured with meters and kilometres but degrees on an approximation of Earth's surface shape.
The points taken is extracted by leaflet with a 4326 SRID and so are the original points. I need the centre of the "smaller squares" or the long and lat coordinates.
For example, this is my base rectangle 24.639567,46.782406 24.641452,46.785413 and for the rectangle, I want to divide 24.584749,46.612782 24.603323,46.653809.
First, let's turn your two points into a leaflet bounds object:
const bounds - L.latLngBounds(point1, point2)
Now let's pick a sample interval, meaning how many sub-rectangles across the width and height of your bounds. For example, a sampling size of 10 would give 100 sub-rectangles (10 x 10), though if your sub-rectangles don't need the same aspect-ratio as your main bounds, you could choose two separate sampling intervals (one for x and one for y)
const samplingInterval = 10 // easy to change
To properly interpolate through your main bounds, we'll grab the corners of it, as well as the width in longitude degrees, and height in latitude degrees, called dLat and dLng (for delta):
const sw = bounds.getSouthWest();
const nw = bounds.getNorthWest();
const ne = bounds.getNorthEast();
const dLat = ne.lat - sw.lat;
const dLng = ne.lng - nw.lng;
Now we can build an array of new bounds extrapolated from the original:
let subBounds = [];
for (let i = 0; i < samplingInterval - 1; i++){
for (let j = 1; j < samplingInterval; j++){
const corner1 = [
sw.lat + (dLat * i) / samplingInterval,
sw.lng + (dLng * j) / samplingInterval
];
const corner2 = [
sw.lat + (dLat * (i + 1)) / samplingInterval,
sw.lng + (dLng * (j + 1)) / samplingInterval
];
subBounds.push(L.latLngBounds(corner1, corner2));
}
}
Now to get the centers of these bounds, you can call .getCenter() on them:
const centerPoints = subBounds.map(bounds => bounds.getCenter());
Working codesandbox

What is the size limit of the gameobjects?

I am building an AR application with unity and Mapbox. I have a point to represents a building. I can geolocate the point through Mapbox. I want to see this object everywhere. So, I change the size of objects according to distance.
Firstly, the code is working. But, I could not see the point really far away, 5 km away.
// Update is called once per frame
void Update()
{
// Get user location
// Latitude
x = getLocation.x1.ToString();
user_lat = Convert.ToDouble(x);
user_lat_rad = Math.PI * user_lat / 180.0; // Radian
// Longitude
y = getLocation.y1.ToString();
user_lon = Convert.ToDouble(y);
user_lon_rad = Math.PI * user_lon / 180.0; // Radian
// Change POIs sizes
distances = distance(user_lat_rad, user_lon_rad);
double s = 0.3; // size of the poi
double d = 50f; // specific distance to point (reference distance)
double size = (distances * s) / d;
float size2 = Convert.ToSingle(size);
temp = transform.localScale;
temp.x = size2;
temp.y = size2;
temp.z = size2;
transform.localScale = temp;
}
public double distance(double lat2, double lon2)
{
// Haversine Formula
// Lat2,Lon2 = User Location
// Lat1,Lon1 = POI Location
double dist1 = Sqrt((Pow(Sin((lat2 - lat1) / 2), 2)) + Cos(lat2) * Cos(lat2) * (Pow(Sin((lon2 - lon1) / 2), 2)));
double distance = 2 * r * Asin(dist1);
return distance;
}
Why I couldn't see the point far away even though object size is change? Is there any limitation for this?
As said in the comments the issue most probably is a too small value for the Camera's farClipPlane.
The furthest point relative to the camera that drawing will occur.
Any object/triangle that is further away from the Camera will not be rendered.
In the Inspector it is configured on the Camera component &rightarrow; Clipping Planes &rightarrow; Far
or using code
cameraReference.farClipPlane = XYZ;