What are the distance units in com.vividsolutions.jts.geom.Geometry class? - java

Our VB.NET project is using a Java library from Vivid Solutoins (com.vividsolutions.jts.geom.Geometry) to do Geometry calculations. The help is here: http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/geom/Geometry.html
What I can't figure out are the units specifically for the Buffer property, or any other distance for that matter. My program is dealing with Nautical Miles, and the documentation gives no indication if the units are degrees, miles, Nautical Miles, Kilometers, inches, etc.
Has anyone used this library who knows the answer? Thanks in advance.

First of all, I don't know this API, I've just browsed the link you've given.
Judging by the Javadocs for Coordinate, it says:
[Coordinate is a] lightweight class used to store coordinates on the 2-dimensional Cartesian plane. It is distinct from Point, which is a subclass of Geometry. Unlike objects of type Point (which contain additional information such as an envelope, a precision model, and spatial reference system information)
So it would seem that Geometry has no units as such, but Point, its subclass, does, and you can specify them.
I wouldn't be surprised if the Geometry class doesn't have any units as such, and just represents the concept of a point in space in any particular coordinate system.

This is an old post, but here is the answer for anyone else who is looking, since incredibly the java docs do not state the units returned by the method. The distance returned is in central angle degrees. You can then use any number of formulas to convert to your required unit of measure. The simplest is to convert to radians. 1 radian = 180 degrees divided by pi (rad=180deg/pi). From there, you can multiply radians by the average radius of the earth in your choice of units (6371 km for instance) to get distance between two points. More accurate methods are also available, but you can look them up on the net.

I confirmed with one of the author's of the library, and by testing it myself using geospatial files with different projections, that the distance units depend on the source file's CRS. This is covered in their FAQ here: https://locationtech.github.io/jts/jts-faq.html#B5
A quick way to find this is to look up the EPSG code at http://epsg.io/ and find the units. For example, EPSG 3347 has units of metres.

As I recently worked on this library (http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/geom/Geometry.html) and after investigation I found that the unit distance returned when call some of the methods distance calculation with this api will be in degree unit. To convert it to kilometer, assumes that value returned is d then you need to convert it to radian and multiply with earth radius 6371km. The formula would be d / 180 * PI * 6371.

Related

calculate actual distance travelled by mobile [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I want to calculate actual distance traveled by mobile (iOS and Android). I know through google map API, we can find optimum route distance between 2 coordinates. But I want to calculate distance, actual path mobile(in vehicle) has covered.
One Algo I came to know is saving coordinates after x seconds, lets say after 5 or 10 seconds, and then calculate distance between consecutive coordinates, and there sum will give total distance.
I want to discuss better approach of its solution , Is there any better solution?
Edit : How Apps like Nike running app and Uber works?
------------------UPDATE----------------------
There is two major point in your question.
1) get the phone coordinates (which has been treated in the first part of this response)
2) Calculate the real distance between this two coordinates
IMHO, calculus could be done by a web service: calculation based only
on the distance between two coordinates can lead to really wrong result.
Here is an exemple of such a web service
https://graphhopper.com/#directions-api
The demo app: https://graphhopper.com/api/1/examples/
It's based on traffic flow (as many of this tools)
So you have to be careful with the order of the coordinates
because it can bring wrong result.
For exemple with two point in the right order:
This gives a good result
But if you give wrong order (with the same coordinates)
For the same coordinates, it can lead to an extremely different result.
So for coordinates ABCD (in chrnological order)
you need to do:
A->B B->C C->D
Graphhopper seems able to do offline distance calculus
Here are the lib on iOS and Android
https://github.com/graphhopper/graphhopper-ios/
https://github.com/graphhopper/graphhopper/tree/master/android
---------------------------------------------------
You have to define how your app work. Foreground or background?
As said in other responses, you'll have to get the user position every X seconds. Then calculate the distance.
For iOS:
You can use information on this website: http://mobileoop.com/
It talks about tracking user location on iOS when the app is in background.
Here is the github: https://github.com/voyage11/Location
Then you have to convert the point thanks to
CLLocationDistance distance = [aCLLocationA distanceFromLocation:aCLLocationB];
You can also check this (from apple doc) https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html:
Make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES. When this property is set to YES, Core Location pauses location updates (and powers down the location hardware) whenever it makes sense to do so, such as when the user is unlikely to be moving anyway. (Core Location also pauses updates when it can’t obtain a location fix.)
Assign an appropriate value to the location manager’s activityType property. The value in this property helps the location manager determine when it is safe to pause location updates. For an app that provides turn-by-turn automobile navigation, setting the property to CLActivityTypeAutomotiveNavigation causes the location manager to pause events only when the user does not move a significant distance over a period of time.
CLActivityTypeAutomotiveNavigation insure you to get a position which is on a road.
For Android:
You can use this project:
https://github.com/quentin7b/android-location-tracker
That can easily helps you to get the user's position thru time
Thanks to the TrackerSettings object
TrackerSettings settings =
new TrackerSettings()
.setUseGPS(true)
.setUseNetwork(true)
.setUsePassive(true)
.setTimeBetweenUpdates(30 * 60 * 1000)
.setMetersBetweenUpdates(100);
To find the distance between two point on Android, you can check this:
Get the distance between two geo points
Both OS
Based on a position picked up every X second you have to reduce time between picking location data to improve accuracy.
As you want to calculate distance on a road context, setup the Location manager in navigation mode, this mode gives you coordinates that are on road.
Finally
If you want to improve the accuracy of your distance calculus,
you can use a google API:
https://developers.google.com/maps/documentation/distance-matrix/intro
By setting the right mode parameter:
Optional parameters
mode (defaults to driving) — Specifies the mode of transport to use when calculating distance. Valid values and other request details are specified in the Travel Modes section of this document.
I'm working on something similar on Andoriod, but the principals are the same for iOS either:
For each GPS sample, check its accuracy. If it's over some threshold (say 20 meters) - ignore it.
Remember that even if the mobile device is static, different GPS samples will give you different locations, depending on the accuracy. A car standing still for a long time in a traffic light, will show that you've advanced few dozens of meters, so add a method that detects if the mobile is static or not. I've implemented this by reading the accelerometer - if the delta between two readings if bigger than some threshold - the device is moving. If it's too small - ignore the GPS.
If you intend to use it in a car, you can read the GPS whenever it has a new reading (in Android use the onLocationChanged method). If you use it for running/walking, take into account that your speed is slow - two consecutive readings will be relativly close, but due to the GPS's accuracy, you can get quite a large distance betwwen them. It can be fixed by increasing the time between two consecutive readings, or by ignoring some of them (i.e. take into account only each 10th reading).
Use the Haversine formula to calculate the distance between two consecutive readings. In Android it can be done with the Location.distanceTo() method.
You'll have to test it against the odometer in your car and adjust the thresholds for the accelerometer.
4 years ago, I just made an app called Landsurvayor that calculates the actual distance of two geo-graphical points drawn on Google Map. I don't know that might help you or not but there is a formula called Haversine formula that calculates the actual distance between two geo-graphical points. You might give it a try and see whether it is useful for you or not. Below is the sample code of Haversine formula:
public double CalculationByDistance(double initialLat, double initialLong,
double finalLat, double finalLong){
int R = 6371; // km
double dLat = toRadians(finalLat-initialLat);
double dLon = toRadians(finalLong-initialLong);
lat1 = toRadians(lat1);
lat2 = toRadians(lat2);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
public double toRadians(deg) {
return deg * (Math.PI/180)
}
More about Haversine formula:
https://en.wikipedia.org/wiki/Haversine_formula
There is another simple Android SDK built-in approach to calculate distance between two lat, lng:
Location locationA = new Location("point A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("point B");
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB) ;
I hope it might help you.
You can achieve more accuracy with a combination of the following strategies.
As mentioned in other Answers, you can store the position of the mobile
every X seconds(say 10 seconds) using GPS and measure the
consecutive time between the points.
Also when the user makes quick turns, make sure to read that by
using Magnetic Sensor values too, so in such event, decrease the
"timing between position storing" to say 1-2 seconds(Will be needed for accuracy)
As a final step, use Map data(such as Google Maps etc.) to make sure
you are being tracked properly(if on road).
And then sum up all the values to get the accurate distance.
P.S. I gave information about the strategies alone since I'm not sure about its implementation in Android(or iOS).
Hope this helps :)
One problem with using GPS coordinates is that they (obviously) are not accurate. If you are travelling in a straight line, the GPS coordinates might show you travelling on a zig-zag path, hence returning a greater distance travelled than the true distance. Even with good GPS accuracy this error can be significant. Using less coordinates could result in a more accurate calculation, or not.
What you need is a way to smooth the GPS path plotted, with due consideration to your required accuracy (again a trade-off).
My first thought is to break the points into groups, and fit line segments to each group (look up "linear regression"). Then find where each consecutive line-pair overlap to define each line segment. Then simply sum the line segment lengths.
You could curve-fit segments, but that's much more intense mathematically, and might not yield a better result (and which curve formula to use?). There may be better mathematical ways I'm not aware of.
Hope this helps.
If you are looking for exact (or nearly exact) distance information, you need to track the path followed, which means checking coordinates every few seconds (depending upon expected speed traveled). You can save space by discarding the old coordinates after calculating each segment and just storing current distance traveled.
Android :: how to calculate distance while walking in android?
There are different ways to do this:
1.GPS: Keep adding GPS distance between 2 points every X seconds (say 10 sec). Check Android Location.distanceTo or distanceBetween. Check
My Tracks app, it is open source. GPS is not available indoors and
would have error if user is changing direction very frequently (read
every 1-2 second)
2.Accelerometer: Look for code/library for step detection using accelerometer. Distance comes from double integration of acceleration,
errors can add up very quickly here.
3.Step detector: Built-in in Nexus 5. Google must have taken care of accelerometer errors to extent possible. This is hardware-based
computation, consumes less battery but not available in most of
handsets as of date.
The 2nd option seem very similar to what you suggested and I do think its the best way to achieve it since iOS and Android defer in code and in functionality therefor the best method to achieve it is saving currentLocation and previousLocation in a while loop that will .sleep() and just sum the entire loop as the distance traveled.
the bigger question is this supposedly app is a distance summerizing app? does it just a small function inside of it? how do you decide when to stop calculating the distance?
If accuracy is critical, you can use data from accelerometer and gyroscope. You can find very simple formula for solving simple cinematic task so you get acc in global axis. Than you just have to use integral twice (first to get velocity, than to get position).
Just to show another perspective.
Use GPS to get lat lon of both places and after getting both pass it below method.Its will return distance in km
public static double getDistanceFromLatLonInKm(double lat1, double lon1,
double lat2, double lon2) {
double R = 6371; // Radius of the earth in km
double dLat = deg2rad(lat2 - lat1); // deg2rad below
double dLon = deg2rad(lon2 - lon1);
double 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);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = R * c; // Distance in km
return d;
}
public static double deg2rad(double deg) {
return deg * (Math.PI / 180);
}
}
Log points every x seconds (maybe 2-3?) and use distance formula below for every point logged.
Distance = sqrt((x2−x1)^2+(y2−y1)^2)
Sum them all up and you get distance

How to calculate percentage format prediction confidence of face recognition using opencv?

I am doing a two-faces comparison work using OpenCV FaceRecognizer of LBP type. My question is how to calculate the percentage format prediction confidence? Giving the following code(javacv):
int n[] = new int[1];
double p[] = new double[1];
personRecognizer.predict(mat, n, p);
int confidence = p[0];
but the confidence is a double value, how should I convert it into a percentage % value of probability?
Is there an existing formula?
Sorry if I didn't state my question in a clear way. Ok, here is the scenario:
I want to compare two face images and get out the likeliness of the two face, for example input John's pic and his classmate Tom's pic, and let's say the likeliness is 30%; and then input John's pic and his brother Jack's pic, comes the likeliness is 80%.
These two likeliness factor shows that Jack is more like his brother John than Tom does... so the likeliness factor in percentage format is what i want, more the value means more likeliness of the two input face.
Currently I did this by computing the confidence value of the input using opencv function FaceRecognizer.predict, but the confidence value actually stands for the distance between the inputs in their feature vectors space, so how can I scale the distance(confidence) into the likeliness percentage format?
You are digging too deep by your question. Well, according to the OpenCV documentation:
predict()
Predicts a label and associated confidence (e.g. distance) for a given
input image
I am not sure what are you looking for here but the question is not really easy to be answered. Intra-person face variants (variation of the same person) are vast and inter-person face variation (faces from different persons) can be more compact (e.g. when both face front while the intra-person second facial image is profile) so this is a whole topic that expect an answer.
Probably you should have a ground truth (i.e. some faces with labels already known) and deduct form this set the percentage you want associating the distances with the labels. Though this is also often inaccurate as distance would not coincide with your perception of similarity (as mentioned before inter-person faces can vary a lot).
Edit:
First of all, there is no universal human perception of face similarity. On the other half, most people would recognize a face that belongs to the same person in various poses and postures. Most word here is important. As you pressure the limits the human perception will start to diverge, e.g. when asked to recognize a face over the years and the time span becomes quite large (child vs adolescence vs old person).
You are asking to compute the similarity of noses/eyes etc? If so, I think the best way is to find a set of noses/eyes belonging to the same persons and train over this and then check your performance on a different set from different persons.
The usual approach as I know is to train and test using pairs of images comprising positive and negative samples. A positive sample is a pair of images belonging to the same person while a negative one is an image pair belong to two different ones.
I am not sure what you are asking exactly so maybe you can check out this link.
Hope it helped.
Edit 2:
Well, since you want to convert the distance that you are getting to a similarity expressed as percentage you can somehow invert the distance to get the similarity. There are some problems arising here though:
There is a value for absolute match, that is dis = 0; or equivalently similarity is sim = 100% but there is no value explicit for total mismatch: dis = infinite so sim = 0%. On the other hand the inverse progress has explicit boundaries 0% - 100%.
Since extreme values include 0 and infinite there must be a smarter conversion than simple inversion.
You can easily assign 1.0 (or 100% to similarity) corresponding to the absolute match but what you are going to take as total mismatch is not clear. You can consider an arbitrary high value as 0.0 (since you there is no big difference e.g. in using distance 10000 to 11000 I guess) and all values higher than this (distance values that is) to be considered 0.0.
To find which value that should be I would suggest to compare two quite distinct images and use the distance between them as 0.0.
Let's suppose that this value is disMax = 250.0; and simMax = 100.0;
then a simple approach could be:
double sim = simMax - simMax/disMax*dis;
which gives a 100.0 similarity for 0 distance and 0.0 for 250 distance. Values larger than 250 would give negative similarity values which should be considered 0.0.

What are the conventions regarding angles and directions in 2D games?

I am making a simple Asteroids-like game using Java that involves angles, but I'm not sure how I should format the angles and directions of the various objects.
I have three main questions:
Where should 0 radians be? (Should it be pointing upwards, should it point to the right, etc.)
Should turning clockwise increase or decrease the value?
Should the range of the value be from 0 to (2 * pi) or from -pi to pi?
In general, you should always follow the same conventions concerning angles in ANY language, as angles are really more mathematical than computer-related concepts and math is universal (e.g. the angle-related math functions in any reasonable language should, and in my experience do behave the same way).
Therefore, these conventions are not so much unique to java as they are a good set of rules to follow whenever you're dealing with angles:
0 radians is to the right.
increasing the angle means moving counterclockwise, so pi/2 radians is up, pi is left, ect.
The last one is a bit trickier. Mathematically speaking, the range of angles around the unit circle is [0, 2pi], and this how I prefer to use angles. In general, this makes things easier, but some java functions seem to utilize the other approach. The main trigonometric functions sin, cos, and tan can accept any number as a input (for instance sin(pi) == sin(3pi)), just as the domain of these functions in mathematics is All Real Numbers. The range of these functions does not relate to pi. However, the inverse trigonometric functions (asin, acos, and atan, but NOT atan2) have limited ranges that are defined in the javadoc:
the returned angle is in the range -pi/2 through pi/2.
Which is also consistent with mathematics. Therefore:
Most of time, you should use [0, 2pi]. It's easier to read and easier to operate on.
When dealing with the inverse trigonometric functions, keep in mind that their range is [pi/2, -pi/2] and make conversions as necessary.

How to find lat/long that is X (k)meters from a given lat/long?

How do I get the lat/long of point X which is 1KM north to lat/long point Y (such as 39.777012,-105.068951)?
In Java CODE please! No external links (I don't read math). Thanks..
Use the answer you posted in your code, UnitConstants.DegreesToRadians is defined as follow:
double DegreesToRadians = Math.PI / 180.0;
You could also use Math.toRadians to do the conversion (Thanks to #Hovercraft Full Of Eels for pointing this out)
Calculating such a distance is done using some mathematical formulas that use radians not degrees and that's why all angles need to be transformed to radian by applying the UnitConstants.DegreesToRadians factor, more info here
Call the method defined in the previous link I have provided like this:
LatLonAlt dest= CalculateDerivedPosition(source, 1000, 0);
source being the source point, 1000 is 1KM to the destination point and 0 degrees (or radians) as the destination point is on the north compared to the source point.
Not to repeat the information, have a look at this SO answer. Have a look at this article as well, it will definitely help you out.

Euclidean distance to calculate if something is near something

currently i have using a framework and it has a function called distance2D, and it has this description:
Calculate the Euclidean distance
between two points (considering a
point as a vector object). Disregards
the Z component of the vectors and is
thus a little faster.
and this is how i use it
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) > 1)
System.out.println("Near");
i have totally no idea what a Euclidean distance is, i am thinking that it can be used to calculate how far 2 points are? because i am trying to compare distance between 2 objects and if they are near within a certain range i want to do something. how would i be able to use this?
Euclidean distance is the distance between 2 points as if you were using a ruler. I don't know what are the dimensions of your Euclidean space, but be careful because the function you are using just takes in consideration the first two dimensions (x,y). Thus if you have a space with 3 dimensions(x,y,z) it will only use the first two(x,y of x,y,z) to calculate the distance. This may give a wrong result.
For what I understood, if you want to trigger some action when two points are within some range you should make:
<!-- language: lang-java -->
if(g.getCenterPointGlobal().distance2D(target.getCenterPointGlobal()) < RANGE)
System.out.println("Near");
The Euclidean distance is calculated tracing a straight line between two points and measuring as the hypotenuse of a imaginary isosceles triangle between the two lines and a complementary point. This measure is scalar, so it's a good metric for your calculations.
Euclidean geometry is a coordinate system in which space is flat, not curved. You don't need to care about non-Euclidean geometry unless for example you're dealing with coordinates mapped onto a sphere, such as calculating the shortest travel distance between two places on Earth.
I imagine this function will basically use Pythagoras' theorem to calculate the distance between the two objects. However, as the description says, it disregards the Z component. In otherwords, it will only give a correct answer if both points have the same Z value (aka "depth").
If you wish to compare distances and save time, use not the distance itself, but its square: (x1-x2)^2 + (y1-y2)^2. Don't take sqrt. So, your distances will work exactly as euclidian ones, but quickly.

Categories

Resources