Geometry.getarea() and Polygon.getarea() what are the units? - java

So I am working with a set of images where the the corners are the lat long on the map. I am creating Polygons to check if there is overlap of the given images. I need to know the units associated with the .getarea() methods for both Polygon and geometry. I'm using the following objects to create my polygons and geometry
http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/geom/Geometry.html#getArea()
http://www.vividsolutions.com/jts/javadoc/com/vividsolutions/jts/geom/Polygon.html
When using both of the above objects I get a number back however I have found no indication on what the units associated with the number are. So are we talking meters, kilometers, miles?
a sample of cordinates i'm using are
+30.658739 -086.345670, +30.659997 -086.34002, +30.664041 -086.345082, +30.662783 -086.342750 I'm looking for the area between these 4 points.
the value i get back from the .getArea() is 1.31039680000139E-5 The points are realitively close so i'm thinking its in meters which would be 1310.4 meters

This is difficult to tell without knowing what the underlying coordinate system is. After taking a quick glance at the Javadoc API you linked to, I suspect that your geometry package is probably dealing in raw cartesian coordinates and is agnostic about the units of measurement being used. If this is the case, you are on a very slippery slope. Here's the problem:
Not All Degrees Are Created Equal
Degrees in latitude all have the same spatial resolution. Each degree of latitude corresponds to roughly 111km of distance. This is not the case for degrees of longitude. At the equator, degrees of longitude correspond to 111km of distance, but at the poles, 1 degree of longitude has ZERO km of distance. In other words, if you have a Lat/Lon box with the upper left at 10:0 and lower-right at 0:10, it will have more surface area than a Lat/Lon box with upper left at 20:0 and lower-right at 10:10, even though the sides of those boxes are all 10 degrees long.
A second issue is the curvature of the earth. Because of the earth's curvature, a 100km by 100km square on the earth's surface will have more surface area than 10000 km^2, because the shortest distance from one point on the earth's surface to another is not actually straight line, but an arc.
A third and often-overlooked but less-important issue is that the Earth is not actually a sphere, but an ellipsoid. It tends to bulge near the equator, which breaks our assumption that a degree of latitude anywhere on earth is the same distance as another degree of latitude anywhere else. However, this issue does not introduce as much error into our surface area estimates as the first two.
In other words, spherical (or in reality, ellipsoidal) surface area isn't an easy problem to solve, at least not as easy as mapping to cartesian coordinates and using them to find euclidean measurements of surface area. You can get away with it if the surface area you are dealing with spans a very small angular distance, but the larger your lat/lon box is, the more distortion you get.
Possible Solution
This only works if your images are rectangular and top/bottom of the image have constant latitude from left-to right. This still introduces more error with wider ranges of latitude because it still ignores the curvature of the earth, but does a better job than assuming all degrees are created equal in a cartesian coordinate system. If this is the case, then the intersection of your image will be bounded by the following coordinates:
topLat:*leftLon*, bottomLat:*rightLon*
Calculate the average latitude, then use it to find distance per degree of longitude at that average latitude, kmPerLon. We now have the following equation:
area = ((topLat - bottomLat) * 111km) * (rightLon - leftLon) * kmPerLon)
The area you get from this will be measured in square kilometers, but again, I'd like to reiterate that this only works reasonably well if your images are rectangularly aligned to parallel latitudes and do not span much angular distance.

CodeBlind is correct that the library is unit-agnostic. The units aren't in the Javadoc because JTS has no opinion on the subject. You can use whatever units you want. If your units are inches, area will be in square inches. If you're using feet, area will be in square feet... and so on. If your numbers are in degrees, then your area is in degrees squared.

What are the distance units in com.vividsolutions.jts.geom.Geometry class?
From that post Distance is in radian (and I have proven it). Then I wonder if the area is also in radian. So I tried it with this:
Math.toRadians(polygon1.getArea()) * 6371000 * 100 => this one become square kilometers.
I don't know if this is accurate or not. But it came pretty close

Related

Calculate meter offset based on decimal degree position

I have a position given in decimal degrees (x.xxxxxxxx and y.yyyyyyyy). I need to draw a rectangle around it. The center of the rectangle matches the position. The dimensions of the rectangle is given in meters and it has a rotation ranging from 0-360 degrees.
Question
How can I calculate the four corners of the rectangle and return the result as four decimal degree values? Like arrayOf<LatLon> getRectangle(LatLon position, int rectWidthCm, int rectLengthCm, double rectRotation).
Example
I have a position given in LatLon format with two two values: latitude and longitude. We will assume this location is precise.
The main task is to draw a rectangle based on this position in a Google Maps chart. The rectangle can have any dimentions but let's use these in this example: Width = 0.9 meter and Length = 1.2 meters. Any heading may also be given so lets use this heading: 45. 0 Is north and going clockwise round (east = 90, south = 180 and west = 270). When the rectangle is pointing north it has the length in the north/south direction. Finally, the rectangle center should be equal to the given position.
Note: The project setup is an Android application with Kotlin support and a google maps chart. I am interested in a modern approach to this problem. Regarding precision loss it should at most be within centimeters.
I understand that you are looking for a function geo_rect(x,y,w,h,a) with the following parameters
x is the longitude according to WGS84
y is the latitude
w is the width of the rectangle in meters
h is the height of the rectangle in meters
a is the angle to which the rectangle is turned from w being horizontal (meaning pointing exactly West to East). I suggest to allow values ranging within the open interval (-90°,90°) as this makes the math either to understand.
Your function getRectangle(LatLon position, int rectWidthCm, int rectLengthCm, double rectRotation) deliver all the required information, you need a small wrapper function which determines w, h, and a from rectWidthCm, rectLengthCm and rectRotation, with the latter being within [0°,360°).
The function geo_rect() will return an arrayOf<LatLon> of length four, namely the coordinates of all four corners, starting on the top left and then going clockwise. We will refer to the points as P_NE,P_NW,P_SE, and P_SW respectively.
Assumptions
In order to keep things mathematically feasible, we make some assumptions
We assume that we can use as approximation that the rectangle is a plane, which is okay if w ~ h << r with r = 6378 km being the radius of the Earth.
We further assume that the Earth is a ideal sphere rather than an ellipsoid or even more bumpy. For an accessible article on that issue, see e.g. Zachary C. Eilon's blog
Basic structure of the algorithm
The algorithm could be structured as follows:
Determine the distance d from (x,y) to all four end points. Because of our first assumption we can use simple Euclidian geometry rather than intricate Spherical geometry. Pythagoras holds: d^2 = (w/2)^2 + (h/2)^2.
We also need the four bearings, e.g. b_NW for the angle between the vector pointing to the North Pole and the vector pointing from (x,y) to point P_NW.
Given the information (x,y,d,b_NW, b_NE, b_SW, b_SE) from the previous steps, we can now follow Get lat/long given current point, distance and bearing to calculate the position of all four points. This is the mathematically hard part where I suggest to use a well-established and tested library for.
Last but not least, let us double-check whether the calculation went well by evaluating Great circle distances between some or all pairs of points. For instance d(P_NE,P_NW) should approximately be w, d(P_NW,P_SW) should approximately be h. Don't be surprised if there is actually a difference - this errors are due the assumptions we made. Normal GPS under usual conditions will anyhow not allow you to determine your position up to the centimeter, you will need DPGS for that.
Further reading
At https://www.movable-type.co.uk/scripts/latlong-vectors.html you can experiment online to determine a destination point along a great-circle given the distance and bearing from a start point (in our case: the center of the rectangle).
Old, but amazingly documented and well tested tool kit for geo-applications in general are the https://www.generic-mapping-tools.org/ - you might want to look at the command gmtvector.
If you are looking for java implementations, I found e.g.
https://introcs.cs.princeton.edu/java/12types/GreatCircle.java.html on of many implementations for calculating great circle distances
Need a standalone Java library for performing spatial calculations on lat/lon data
Calculate point based on distance and direction

How do I get the distance from an object to another object with a camera?

My FRC (robotics) team is having issues with image processing, and tomorrow is our last testing day before competition.
The camera is facing downward and tilted in the x direction. We are trying to calculate the distance that an object is to a fixed point on the same surface. We only need to calculate the x distance (in inches).
Here's a diagram.
The object could be anywhere on the line with the fixed point.
Here is the view from the camera
The tape measure represents the line in the diagram.
I know it's low res and not the best picture, I took it just before I left today. The tape measure is where the object could be. And we only care about it's x position.
Other info if needed:
Camera: Pixy
Focal length: 28mm (1.1024")
Sensor size: 0.25"
Height of camera from surface (the ground in our case): 8"
We always know the x position (in pixels) of the object, we just need to calculate the distance (in inches) that the object is from the fixed point.
If you have any other questions please ask. Thanks.
You are on the right track with your image of the tape measure. All you need to do is manually (from that image), determine the inches (from zero) for each x-position (pixel). Create a lookup table that you can use in the code.
When you determine the x-position of the object and the x-position of the fixed point, look up the inches for each of these x-positions and subtract to get the distance between the object and the fixed point.
This approach is super simple, but also depends on proper calibration of the system. In particular, the operational setup (height, angle, camera optics, etc.) has to exactly match the setup when the test image was taken that was used to create the lookup table.
A standard technique is to calibrate the system by taking and processing a calibration image whenever the operational setup might have changed. For example, you could place a grid patter (e.g., with one inch squares) in the field of view. The idea is that you code a calibration analysis that will determine the proper lookup table values based on the standard image.

Calculating Haversine distance of two coordinates taking into consideration the altitude

Today in class wev'e been introduced to the haversine function. the describtion of the function goes like this : "This uses the ‘haversine’ formula to calculate the great-circle distance between two points – that is, the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points (ignoring any hills they fly over, of course!)."
The goal is to load a csv file that inclued lat,lon and alt of a point and calculate the distance of 2 coordinates on earth.
My question is: how do I integrate the haversine function with the altitude factor?

How to approximate OCTANT of a circle using QUADRATIC Bezier curve?

In a vector graphics program I am writing using Java, ideally any shape would be represented by a modified form of the Path2D class, which uses quadratic Bezier curves. Ideally ellipses would be represented as Path2D objects as well. There is heavy documentation on the internet for approximating quadrants of a circle using cubic Bezier curves, but using the Path2D class, cubic Bezier curves are not possible. I have been using Desmos to try to find an approximation of the octant of a circle, and the middle point (between the two control points) for a circle of radius 1 centered at (0, 0) is approximately (0.993, 0.412). Surely there is some irrational number that can more precisely be expressed as a formula using square roots or trigonometric functions.
I have attempted using the formula 4*tan(pi/(2*n))/3. Either that formula does not apply to octants or it was poorly explained where I found it.
t would help if you said where you found it - the formulae for arbitrary angles (which obviously includes octants, just plug in PI/4 as your angle) are rather different from what you show. Find the real formulae, and explanation, over on https://pomax.github.io/bezierinfo/#circles.
Quadratic curves are dead simple in the sense that the control point is a linear intersection of the end point tangents. So, given start point (1,0) with vertical tangent (because it's a circle, that's how circles work) and end point (cos(phi), sin(phi)) for some angle phi, with tangent (sin(phi), -cos(phi)), we can determine the control point for this curve as:
Cx = cos(phi) - b * sin(phi)
Cy = sin(phi) + b * cos(phi)
where:
cos(phi) - 1
b = ------------
sin(phi)
(The actual maths here is explained in the link above).
Plugging in PI/4 to compute the first octant means we get:
Cx = 1 (obviously; it's a vertical tangent, so the x coordinate is fixed)
Cy = sqrt(2) - 1
And you're done: you don't need to derive any other values, because all the other octants are just reflections of these values that you literally just write out on some paper by drawing a circle, draw lines to show octants, mark the first octant with its coordinate values, and then go "oh, obviously the other coordinates are: ..." -- also the above formulae are for circles with radius 1, but you know how to multiply so you know how to scale the values so that they match your desired circle.
I would be curious why you want quadratic curves, though, because they're objectively pretty terrible compared to cubics. For example: you need 16 points to model a circle with quadratic octants, whereas you only need 12 points for cubic quarters, which have higher precision.
Also, even if you're dead set only ever using quadratics, users of your software might move to other software. They expect cubics to be available to the point where they will petition you for them if the rest of your software is worth using. Plan for that, or ideally just support quadratic and cubic from the start. After all, SVG etc. already do.

Convert Latitude and Longitude values to a custom sized grid

I am making a java program that classifies a set of lat/lng coordinates to a specific rectangle of a custom size, so in effect, map the surface of the earth into a custom grid and be able to identify what rectangle/ polygon a point lies in.
The way to do this I am looking into is by using a map projection (possibly Mercator).
For example, assuming I want to classify a long/lat into 'squares' of 100m x 100m,
44.727549, 10.419704 and 44.727572, 10.420460 would classify to area X
and
44.732496, 10.528092 and 44.732999, 10.529465 would classify to area Y as they are within 100m apart.
(this assumes they lie within the same boundary of course)
Im not too worried about distortion as I will not need to display the map, but I do need to be able to tell what polygon a set of coordinates belong to.
Is this possible? Any suggestions welcome. Thanks.
Edit
Omitting projection of the poles is also an acceptable loss
Here is my final solution (in PHP), creates a bin for every square 100m :
function get_static_pointer_table_id($lat, $lng)
{
$earth_circumference = 40000; // km
$lat_bin = round($lat / 0.0009);
$lng_length = $earth_circumference * cos(deg2rad($lat));
$number_of_bins_on_lng = $lng_length * 10;
$lng_bin = round($number_of_bins_on_lng * $lng / 360);
//the 'bin' unique identifier
return $lat_bin . "_" . $lng_bin;
}
If I understand correctly, you are looking for
a way to divide the surface of the earth into approximately 100m x 100m squares
a way to find the square in which a point lies
Question 1 is mission impossible with squares but much less so with polygons. A very simple way to create the polygons would to use the coordinates themselves. If each polygon is 0.0009° in latitude and longitude, you will have approximately square 100m x 100m grid on the equator, put the slices will become very thin close to the poles.
Question 2 depends on the approximation used to solve the challenge outlined above. If you use the very simple method above, then placing each coordinate into a bin is just a division by 0.0009 (and rounding down to the closest integer).
So, first you will have to decide what you can compromise. Is it important to have equal area in the polygons, equal longitudinal distance, equal latitude distance, etc.? Is it important to have four corners in the polygon? Is it important to have similar or almost similar polygons close to the poles and close to the equator? Once you know the limitations set by your application, choosing the projection becomes easier.
What you are trying to do here is a projection onto a flat surface of an ellipsoid. So as long as your points are close together, and, well, you don't mind getting the answer slightly wrong you can assume that your projection plane intersects in the centre of your collection of points, and, each degree of lat and lon are a constant number of metres. Then the problem is a simple planar calculation.
This is wrong, of course. I would actually recommend that you look into map projections, pick one that makes sense, and go for that. Remember that you can move the centre of the projection to the centre to your set of points which will reduce distortion.
I suspect that PROJ.4 might help you in terms of libraries. There also must be a good Java one but that is not my speciality.
Finally you can could assume that the earth is a sphere and do your calculations on the sphere. Or, if you really want to get it right you can pick a standard earth ellipsoid and do the calculations on that.

Categories