Get the size of a map in Km generated by OpenStreetMap - openstreetmap

I exported a part of my city using OpenstreetMap, so I have a .osm file that contains at the beginning of the file:
<bounds minlat="34.8743000" minlon="-1.3494000" maxlat="34.9035000" maxlon="-1.2926000"/>
I want to know the size of my map in Km. How do I do it?

I'll put this in an answer. These are the points you have as coordinates (boundaries) for your map:
----------------- (max lat, max lon)
| |
| |
|
| y
|
| |
| |
(min lat, min lon) ------ x ------ (min lat, max lon)
The function in the answer I referenced provides the distance between 2 points. So to compute x you need the distance between point (min lat, min lon) and point (min lat, max lon). You can compute y in a similar way.For example point at bottom left is (lat1, lon1) and bottom right is (lat2, lon2) -> using the function you get x.Same thread, optimized code.Now if you just need this information once without actually programming anything, this is not so much a question for SO but you may use this link to get the numbers.

Related

Get point between two points crossing the 180 degree meridian at 180 degrees

I am plotting a line on a MapboxGL (js) world map that follows the path of orbital objects. I do this by adding a new set of decimal longitude/latitude coordinates to a line geometry array as the orbit of the object updates.
There is a known issue with Mapbox (and others) that when drawing a line that crosses the 180° meridian (longitude), we do not get a nice straight line from a to b, we get a very long line that wraps around the whole globe from a to b:
instead of: we get:
/ /
/ /___
.../..... ......... 180° meridian
/ ___
/ /
/ /
"Accepted" answers here and at Mapbox suggest shifting to a 0°/360° longitude range, but this just moves the problem from the equator to the pole. This is fine for most general proposes, but is still an issue for orbital tracking where we may be crossing the 0°/360° meridian.
My solution is to use MultiLine geometry and break up my coords into new arrays when I cross this meridian, however, this will always leave a wee gap, or, if I "180, lat" either side, we get a "kink" at the meridian:
gap: or kink:
/ /
/ /
........ .....|... 180° meridian
/
/ /
/ /
So I need to figure out what the exact latitude would be if the longitude is on the meridian, knowing the start and end points either side:
+170 | p2 /:
| / :
| / :
180 -|-----/ pX? -- 180° meridian
| /: :
(lng) | / : :
| / : :
-170 |_/___:___:___
p1 x?
(lat)
I need to solve for latitude x so I can generate pX (knowing p1 and p2 if longitude where 180). Once I have pX, I can add this to the end of the last line and to the beginning of the next, thus closing the gap (or smoothing the "kink").
I know this is basic Trig, but my old-man-brain has failed me .. again ....
The simple way to split a line in this way would be to use Turf's lineSplit function. Something like:
const meridian = turf.lineString([[180, -90], [180, 90]]);
const linePieces = turf.lineSplit(myline, meridian);
I haven't tried this, so not sure if Turf itself has any weirdness at the meridian. If it does, you might have to temporarily translate the coordinates elsewhere or something.
Better than doing your own trigonometry in any case, especially since it may introduce errors with the world not being flat.
SOLVED! With basic Trig (while writing the question - so I am posting it anyway, just incase it helps someone else):
We are basically playing with two right triangles: p1 to p2, and the smaller right triangle where the opposite side stops at the meridian, both with the same hypotenuse angle. So, we have:
+170 | p2 /|
| / |
| / |
180 -|-----/ pX? -- 180° meridian
| /: |
(lng) | / : A |
| / B: |
-170 |_/___:___|___
p1 x?
(lat)
Where A is our p1 to p2 right angle triangle and B is the triangle from p1 longitude to the meridian, whose adjacent side we need to work out.
Pythagoras basically teaches us that all we need is two points of data (other then the right angle) of a right triangle to solve any other.
We already have the opposite and adjacent lengths of A:
+170 | p2 /|
| /α|
| / |
180 -|-- / | -- 180° meridian
| / |
(lng) | / A | oppositeA
| / |
-170 |_/β______|___
p1 adjacentA
(lat)
So from here we need to calculate the hypotenuse of A to get the angle of the hypotenuse of A (α) so we can use it later:
// add 360 to a negative longitude to shift lng from -180/+180, to 0/360
p1 = { lng: p1.lng < 0 ? p1.lng + 360 : p1.lng, lat: p1.lat }
p2 = { lng: p2.lng < 0 ? p2.lng + 360 : p2.lng, lat: p2.lat }
let oppositeA = Math.abs(p2.lng - p1.lng) // get A opposite length
let adjacentA = Math.abs(p2.lat - p1.lat) // get A adjacent length
let hypotenuseA = Math.sqrt(Math.pow(oppositeA,2) + Math.pow(adjacentA,2)) // calc A hypotenuse
let angleA = Math.asin(oppositeA / hypotenuseA) // calc A hypotenuse angle
Now we need the new opposite of B (p1.lng to 180) and our calculated angle of A to work out the new hypotenuse of B so we can get the new adjacent of B:
+170 | p2 /
| /
| /
180 -|-- / -- 180° meridian
| /: B
(lng) | /α:
| / : oppositeB
-170 |_/___:___ ___
p1 adjacentB
(lat)
let oppositeB = Math.abs(180 - p1.lng) // get B opposite
let hypotenuseB = oppositeB / Math.cos(angleA) // calc B hypotenuse using A angle
let adjacentB = Math.sqrt(Math.pow(oppositeB,2) + Math.pow(hypotenuseB,2)); calc B adjacent
Now we add the new adjacent to p1 latitude, and we have x! So:
let pX = { lng: 180, lat: p1.lat + adjacentB }
End the last line array and start the next with pX, and the gap is perfectly closed!
Highschool math (well, the genius of Pythagoras) to the rescue! I knew it was rattling around in that old-man-brain somewhere .....

What is the area of geom field?

I want to check the area of geometry values.
The geometry values are POLYGON or POINT or MULTI POLYGON.
The field has the type of geometry
I check the srid of the geom field:
select st_srid(geometry)
from my_table
And I got srid=32636.
I checked here:
https://epsg.io/32636 and it seems that the units are in meters.
Now I want to get the area (in meters) of each value:
select st_area(geometry)
from my_table
And I'm getting very small values (0.0002, or 0.000097 or 0.33, ....).
I want to be sure:
Does those values means square meter (m^2) ?
So the values are less than 1 square meter ?
Since your SRS unit is metre, ST_Area will return the area in square metres. The following example calculates the area of a polygon using SRS's that have different units:
WITH j (geom) AS (
VALUES ('SRID=32636;
POLYGON((-1883435.029648588 6673769.700215263,-1883415.1158478875 6673776.142528819,-1883411.8478185558 6673765.073005969,-1883431.7724919873 6673758.967942359,-1883435.029648588 6673769.700215263))'::GEOMETRY))
SELECT
ST_Area(geom) AS sqm,
ST_Area(
ST_Transform(geom,2249)) AS sqft
FROM j;
sqm | sqft
-------------------+-------------------
237.6060612927441 | 2341.135411173445
EPSG 32636: Units are metres (Ellipsoid WGS84)
EPSG 2249: Units are feet (Ellipsoid GRS1980)
To your questions:
Does those values means square meter (m^2) ?
Yes.
So the values are less than 1 square meter ?
Yes. I'm curious about what are your geometries about. Perhaps you mixed up different SRS?
Unrelated note: Spatial operations with SRS's that have the same unit might still deliver different results, as they might also use different ellipsoids. The example below will calculate the area of the same geometry using SRS's that have metre as unit but a different ellipsoid. Note the difference in the result:
WITH j (geom) AS (
VALUES ('SRID=32636;
POLYGON((-1883435.029648588 6673769.700215263,-1883415.1158478875 6673776.142528819,-1883411.8478185558 6673765.073005969,-1883431.7724919873 6673758.967942359,-1883435.029648588 6673769.700215263))'::GEOMETRY))
SELECT
ST_Area(geom) AS sqm_32636,
ST_Area(
ST_Transform(geom,26986)) AS sqm_26986
FROM j;
sqm_32636 | sqm_26986
-------------------+--------------------
237.6060612927441 | 217.49946674261872
EPSG 32636: Units are metres (Ellipsoid WGS84)
EPSG 26986: Units are metres (Ellipsoid GRS1980)
.. but if you stick to the same ellipsoid and unit, the math makes more sense:
WITH j (geom) AS (
VALUES ('SRID=32636;
POLYGON((-1883435.029648588 6673769.700215263,-1883415.1158478875 6673776.142528819,-1883411.8478185558 6673765.073005969,-1883431.7724919873 6673758.967942359,-1883435.029648588 6673769.700215263))'::GEOMETRY))
SELECT
ST_Area(
ST_Transform(geom,2249)) AS sqft_2249,
ST_Area(
ST_Transform(geom,2249)) * 0.3048 ^ 2 AS sqm_2249, -- manually converted from sqm to sqft
ST_Area(
ST_Transform(geom,26986)) AS sqm_26986
FROM j;
sqft_2249 | sqm_2249 | sqm_26986
-------------------+--------------------+--------------------
2341.135411173445 | 217.49859674966302 | 217.49946674261872
Demo: db<>fiddle

How to get the distance between two latitude longitude points in anylogic?

I am new to Anylogic and I am trying to calculate the distance between two points with given latitude-longitude values. I want the distance in miles. I have found a method from the Anylogic website that is below
default double getDistance(double startLat,
double startLon,
double endLat,
double endLon)
Calculates distance by route between two specified points.
Returns:
the distance between two specified points, measured in meters.
(source:
https://help.anylogic.com/index.jsp?topic=%2Fcom.anylogic.help%2Fhtml%2Fjavadoc%2Fcom%2Fanylogic%2Fengine%2Fgis%2FIGISRouteProvider.html)
However, when I run this for two set of points with lat-long
Point 1:
latitude:41.40174, longitude: -72.0201
Point 2:
latitude:45.332, longitude:-73.2215
this gives me a distance of 4.1098062654025815 meters in anylogic; which is wrong.Could you please help me in giving insights what I might be doing wrong? Thanks
What is wrong
You are currently using the standard distance function from Utilities, which is using the inputs as cartesian coordinates and not as geographic latitutude and logitude:
public static final double getDistance(double x1,double y1,double x2,double y2)
Returns the distance between two given points (x1, y1) and (x2, y2)
Parameters:x1 - the x coordinate of the first pointy1 - the y coordinate of the first pointx2 - the x coordinate of the second pointy2 - the y coordinate of the second point
Returns:the distance between points
How to fix it
In order to calculate geographic distances with latitude and longitude, you will have to access the functions that come with the ShapeGISMap object:
double getDistanceByRoute(double latFrom, double lonFrom, double latTo, double lonTo)
Calculates length of route from one point to another.
double getDistance(double latFrom, double lonFrom, double latTo, double lonTo)
Returns distance, in meters, between 2 given points
You can access them by adding a GIS Map from the SpaceMarkup palette (the instance here named map), and referencing it:
map.getDistanceByRoute(41.40174,-72.0201,45.332,-73.2215);
Additional Hint
You can always check if you are really using the correct function in your context by using Java auto completion (Type the first part of the function name, then CTRL + Space Bar) and having a look in the JavaDoc that is then showing:

Store circle on earth

I want to store in table places defined by coordinate (41.67102,72.917482) and radius 100 metes. How can I convert 100 metes in same measure as coordinates because 1 latitude != 1 longitude. Or I should use postgis somehow?
In postgis, the circle would be calculated with something like:
update PLACES set the_circle = (ST_Buffer((place_geom)::geography, 100 ))::geometry) ;

Calculate distance travelled using PostgreSQL query

I am using PostgreSQL to store the location of a user send to the server by my android app. I needed to find the total distance travelled by the user for a particular time duration.
The user location is stored in the following table :
CREATE TABLE userlocation
(
latitude character varying,
longitude character varying,
geopoint point,
userid integer,
locationtime timestamp
)
I retrieved the records and calculated the distance in java using the following haversine distance method :
public double getdistance(final double lat1, final double lon1, final double lat2, final double lon2, final char unit) {
final double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
* Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
if (unit == 'K') {
dist = dist * 1.609344;
} else if (unit == 'N') {
dist = dist * 0.8684;
}
if (Double.isNaN(dist)) {
dist = 0.0;
}
return (dist);
}
However this calculation is time consuming especially while calculating the distance for multiple days as there are a lot of records. I decided to try doing the distance calculation at the database level to reduce the calculation time. I found the the following query which allows me to calculate the distance to a certain point :
SELECT latitude, longitude, geopoint <-> '19.23,72.89' AS distance FROM userlocation ORDER BY distance;
I tried to create a query that would either return the total distance traveled or atleast calculate the distance between two consecutive rows and store it in another column so that I calculate the sum in Java instead of the distance calculations.
I have tried searching for a solution but I have been unable to find one yet. Most of the questions on SO deal with distance calculation between two points.
I do not have PostGIS at the moment. Would it be possible to calculate distance in PostgreSQL or should I just continue with my current approach? In that case is there an alternative for reducing the distance calculation time.
I had the same problem last month.
I added the module Earthdistance to PostgreSQL. This plugin add functions to compute the great circle distances between two points.
Installation is simple:
CREATE EXTENSION "cube";
CREATE EXTENSION "earthdistance";
Hope that helps