Calculate distance travelled using PostgreSQL query - postgresql

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

Related

How get distance in degrees to calculate buffers in athena?

Athena only allows to calculate the distance of the buffer in decimal degrees but this value varies with respect to the latitude in the globe, tate to obtain a distance according to the following formula but it is not consistent in Mexico.
Athena function like this : ST_Buffer(geometry, double)
Athena geospatial functions
So, is posible obtain the corresponding distance in decimal degrees over a custom point in map , ex : get the decimal degree for point x, y like that distance in meters is 300 mts
Currently I use the following formula to approximate the decimal degrees but some buffers are quite horrible although it meets the minimum required
SELECT
ST_Buffer(ST_GeometryFromText( shape_wkt) ,
abs(5000.0 * 360.0 / (2.0 * pi() * cos( latitud )* 6400000.0) ) ) AS
dinamic_buffer_5000
5000 is buffer in meters
6400000.0 earth radius in meters
Some useffull questions :
gps-coordinates-in-degrees-to-calculate-distances
Calculate distance in meters using results in degrees
calculating-latitude-longitude-x-miles-from-point
A possible alternative is the following
To obtain the decimal degrees relative to a point one could:
Generate a second point at a distance d for this you would have to implement this formula, where the bearing does not matter
With this second point calculate the distance in Athena that will return the distance in decimal degrees, as input for the buffer function.
As an approximate is good alternative
Now how implement the second point ?....Here is the formula
I will try to convert to SQL code if can :
After a test I realize that even with the difference of distance it is not possible to obtain the buffer in an optimal way.
In this case the distance to the lower point was 300 meters, after obtaining the distance in decimal degrees with Athena an oblate shape is obtained, it changes the degree of inclination of the point by 90 degrees but it only generates a slightly larger shape.
Destination point given distance and bearing from start point
Source code (zory im edit for test my sql ):
destinationPoint(distance, bearing, radius=6371e3) {
// sinφ2 = sinφ1⋅cosδ + cosφ1⋅sinδ⋅cosθ
// tanΔλ = sinθ⋅sinδ⋅cosφ1 / cosδ−sinφ1⋅sinφ2
// see mathforum.org/library/drmath/view/52049.html for derivation
const dist_ang = distance / radius; // angular distance in radians
const angulo = Number(bearing).toRadians();
const rad_lat = this.lat.toRadians();
const rad_lon = this.lon.toRadians();
console.log("distance", distance);
console.log("radius", radius);
console.log("angular distance in radians", dist_ang);
console.log("bearing", Number(bearing));
console.log("bearing angulo ", angulo );
console.log("lat.toRadians", rad_lat);
console.log("lon.toRadians", rad_lon);
console.log("lon",this.lon);
console.log("lat",this.lat);
const sinφ2 = Math.sin(rad_lat) * Math.cos(dist_ang) + Math.cos(rad_lat) * Math.sin(dist_ang) * Math.cos(angulo);
const φ2 = Math.asin(sinφ2); //lat
console.log("φ2",φ2); //lat
console.log("sinφ2",sinφ2);
const y = Math.sin(angulo) * Math.sin(dist_ang) * Math.cos(rad_lat);
const x = Math.cos(dist_ang) - Math.sin(rad_lat) * sinφ2;
console.log("y",y);
console.log("x",x);
const λ2 = rad_lon + Math.atan2(y, x); //lon
console.log("λ2",λ2);
const lat = φ2.toDegrees();//lat
const lon = λ2.toDegrees();//lon
console.log("lon2",lon);
console.log("lat2",lat);
return new LatLonSpherical(lat, lon);
}

Is there a way to convert meters to kilometers in dart?

i am using geolocator: ^7.3.1 package They mentioned a function that calculates the distance between two geographical points , But the result comes in meters by default
How could this be done in Km
getDistance(){
double distanceInMeters = Geolocator.distanceBetween(52.2165157, 6.9437819, 52.3546274, 4.8285838);
print(distanceInMeters); // result comes in meters by default which is 144851.67191816124 meters
}
How can I get the result in kilometers, and in short number not like that long number in their example?
Conversion
double distanceInMeters = 144851.67191816124;
double distanceInKiloMeters = distanceInMeters / 1000;
double roundDistanceInKM =
double.parse((distanceInKiloMeters).toStringAsFixed(2));
print(distanceInMeters);
print(distanceInKiloMeters);
print(roundDistanceInKM);
Output
144851.67191816124
144.85167191816123
144.85
Is this helpful?

is there any formula to get travel time between two locations or from distance in flutter without using google maps

I have two locations and I have the formula to get the distance between them but I want to calculate the travel time between them without using google maps or any API calling. Is there any formula to do that in flutter?
I think the real travel time depends on a lot of factors, for example the road you take or the speed limit.
Whitout some complex elaboration, which are usually perfomed by a backend, I don't think it is possible to calculate it.
Anyway, since you have got the distance, you could simply estimate it by giving a supposed speed and then using basic physics formulas.
time = distance / speed.
You cannot find the travel distance between two locations without using the Google API.
However you can get the air distance in meters using this formula in flutter.
double calculateDistance(
double lat1, double lon1, double lat2, double lon2) {
var p = 0.017453292519943295;
var c = cos;
var a = 0.5 -
c((lat2 - lat1) * p) / 2 +
c(lat1 * p) * c(lat2 * p) * (1 - c((lon2 - lon1) * p)) / 2;
var temp = 12742 * asin(sqrt(a));
return (temp * 1000);
}

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:

Wrong distance calculation with MongoDB

I am executing the following raw query with MongoDB:
qry = {"position" : SON([("$near", [52.497309,13.39385]), ("$maxDistance", distance/111.12 )])}
locations = Locations.objects(__raw__=qry)
The position in the database is set to [52.473266, 13.45494].
I get a result once I set the distance to 7.3 or higher, so it seems the two locations must at least be 7.3 kilometer away from each other.
When I calculate the distance of those two geo locations with Google Maps (for example going by car) it's telling me it's only 5.2 kilometer away from each other.
I tested it with loads of different locations and there is always a big difference in the distance calculation of google and Mongodb
Am i missing anything or can somebody explain please where this difference is coming from?
I already checked this answer but it's not working for me...
MongoDB assumes that coordinates are in (long, lat) format. If you compute distances by hand using Great-circle distance you'll see what is going on:
> from math import acos, sin, cos, radians
>
> long_x, lat_x = [radians(y) for y in [52.473266, 13.45494]]
> long_y, lat_y = [radians(y) for y in [52.497309, 13.39385]]
>
> acos(sin(lat_x) * sin(lat_y) + cos(lat_x) * cos(lat_y) * cos(long_x - long_y)) * 6371.0
7.27362435031
Google takes coordinates in (lat, long) format so if you provide the same input Google interpretation will be like below:
> acos(sin(long_x) * sin(long_y) + cos(long_x) * cos(long_y) * cos(lat_x - lat_y)) * 6371.0
4.92535867182