Is GeoPy a wrapper of another implementation? Where can I find a Scala or Java equivalent solution to measure distances between two coordinates? Geotools does not work the way I want. For example, I have spotted a couple of cases in which the coordinates do not converge and return an error.
The GeographicLib-Java package (I wrote this) will do what you want.
It does all sorts of geodesic calculations on an ellipsoid. The solution
for the distance between two points always converges.
have also a look at Geocalc. I wrote it for one of my website
//Kew, London
Coordinate lat = new DegreeCoordinate(51.4843774);
Coordinate lng = new DegreeCoordinate(-0.2912044);
Point kew = new Point(lat, lng);
//Richmond, London
lat = new DegreeCoordinate(51.4613418);
lng = new DegreeCoordinate(-0.3035466);
Point richmond = new Point(lat, lng);
double distance = EarthCalc.getDistance(richmond, kew); //in meters
double distance = EarthCalc.getHarvesineDistance(richmond, kew); //in meters
double distance = EarthCalc.getVincentyDistance(richmond, kew); //in meters
In the past I've worked with JTS, it's a very rich library for processing georeferenced data. If you want to use it in Scala it's not very idiomatic but I know there's a binding library that may fit your needs.
Related
I cannot find exactly what I'm looking for or reading google documentation I missed it, I just need a function or whatever to submit 2 point, start and end, and get X waypoint in between.
Is there some api like "www.somesite.com/api.php?start=43.12,12.23&end=44.12,12.23&number_of_waypoints=5" that return some json?
thank you!
First of all, this will require working with geodesics, which are the shortest lines passing through two points around the Earth, assuming the Earth is an ellipsoid. WGS84 is the standard coordinate system you will see most widely used for "latitude + longitude" coordinates, and this assumes the Earth is an ellipsoid.
To solve this problem, you first need to find the azimuth (bearing angle from north) and distance between two coordinates. The way to calculate this is by solving the inverse geodesic problem.
Once we have this distance (let's say in metres), we can divide it by n, where n - 1 is the number of waypoints we want in between the line. This gives us the distance d metres between each waypoint.
Now, we need to plot points at intervals of d metres along this line. To do this, we can solve the direct geodesic problem. This gives us a new set of coordinates after moving a given distance from a given point with a given azimuth. We can do this repeatedly to get new points moving d metres from the previous point each time. One thing to note with this is that the resultant azimuth to the end of the line from different points within the line will vary, so the destination azimuth must be obtained after each stage and used for calculating the next point.
Solving the direct and inverse geodesic problems requires mathematical formulas, of which multiple are available. However, for your PHP application, you are probably best not trying to implement these yourself, but instead use a library which can do this for you. One popular library for PHP which does this is called phpgeo.
Here's an example of how this might be implemented with phpgeo:
<?php
use Location\Coordinate;
use Location\Distance\Vincenty;
use Location\Bearing\BearingEllipsoidal;
$numPoints = 5;
$coordsA = new Coordinate(50.0, 0.0);
$coordsB = new Coordinate(51.0, 1.0);
$bearingCalculator = new BearingEllipsoidal();
$distanceCalculator = new Vincenty();
// Inverse geodesic problem
// Calculate total length of line between coords
$totalDistance = $distanceCalculator->getDistance($coordsA, $coordsB);
$intervalDistance = $totalDistance / ($numPoints + 1);
// Inverse geodesic problem
// Calculate angle to destination
$currentBearing = $bearingCalculator->calculateBearing($coordsA, $coordsB);
$currentCoords = $coordsA;
$points = [];
for ($i = 0; $i < $numPoints; $i++) {
// Direct geodesic problem
// Calculate new point along line
$currentCoords =
$bearingCalculator->calculateDestination($currentCoords,
$currentBearing,
$intervalDistance);
// Add these new coordinates to the list
array_push($points, $currentCoords);
// Inverse geodesic problem
// Recalculate angle to destination
$currentBearing =
$bearingCalculator->calculateBearing($currentCoords,
$coordsB);
}
// Print out the list of points
foreach ($points as $point) {
echo "{$point->getLat()}, {$point->getLng()}\n";
}
Hey people this is going to be my first question so dont hit me too hard !
Before I have already added polygons but the intersection is a bit complicating.
with pre-defined i mean for example intersection coordinates of two other polygons. I'm calculating the area of the polygon intersection but i also want to highlight the area. Thanks
You would need two steps:
calculate intersection: polygon from 2 polygons. I would use JTS for it, you would need to provide data in JTS objects.
highlight the intersection on mapview (nutiteq for example). You can just add the resulting polygon as one geometry element into geometry layer, just as any other polygon. Use special styling to make it look different. You would need to convert JTS polygon to Nutiteq Polygon object to show it on map
ArrayList<MapPos> keslist = new ArrayList<MapPos>();
for (int i = 0; i < sonuc.getNumPoints(); i++) {
double lon = sonuc.getX(i);
double lat = sonuc.getY(i);
MapPos mPos = new MapPos(lon, lat);
keslist.add(mPos);
}
PolygonStyle polygonStyle = PolygonStyle.builder().setColor(Color.GREEN).build();
StyleSet<PolygonStyle> polygonStyleSet = new StyleSet<PolygonStyle>(null);
polygonStyleSet.setZoomStyle(10, polygonStyle);
Polygon KesisimPol = new Polygon(keslist, new DefaultLabel("Kesişim"), polygonStyleSet, null);
GeometryLayer geomLayer = new GeometryLayer(mapView.getLayers().getBaseLayer().getProjection());
mapView.getLayers().addLayer(geomLayer);
geomLayer.add(KesisimPol);
}
Here is my solution. I've tried it works. Right now I'm trying to add this new polygon to editable objects layer. Because I can't use the result polygon in another intersection process.
I hope this will help the others.
When using the embedded interactivity embedded interactivity function on the iOS SDK I can click a map tile and get the data coords in LAT LON but I would like to have the result in EPSG 3857 WGS 84...is this possible? If so what is the transform command?
Looks like I am going to answer my own question. I could not find a transform function. So I passed the LAT LONG coordinate pair to the webservice and did the transformation on the server.
You can do this with Leaflet/Mapbox.
Here's an example
var latlng = L.latLng(45, -120);
var sphericalMercator = L.Projection.SphericalMercator.project(latlng);
sperhicalMercator.x => -2.0943951023931953
sphericalMercator.y => 0.8813735870195429
You'll still need to multiply these coordinates by 6378137 (earth's radius in meters) (why Leaflet doesn't do this, I don't know...), and you get the spherical mercator equivalent to the original lat/long (45, -120):
(-13358338.8952, 5621521.48619)
Say I have a square which consists of four CLLocationCoordinate2D points, which are in lat, lon, and I want to find the area of the square in meters. I convert the CLLocationCoordinate2D points into MKMapPoints, and I find the area in X-Y space. However, the area I find is in the units of MKMapPoint, which don't directly translate to meters. How can I translate this area in MKMapPoint-space back into meters?
The MapKit function MKMetersBetweenMapPoints makes this easier.
For example, if you wanted to get the area of the currently displayed region:
MKMapPoint mpTopLeft = mapView.visibleMapRect.origin;
MKMapPoint mpTopRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y);
MKMapPoint mpBottomRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y + mapView.visibleMapRect.size.height);
CLLocationDistance hDist = MKMetersBetweenMapPoints(mpTopLeft, mpTopRight);
CLLocationDistance vDist = MKMetersBetweenMapPoints(mpTopRight, mpBottomRight);
double vmrArea = hDist * vDist;
The documentation states that the function takes "into account the curvature of the Earth."
You can use the Haversine formula to calculate it, assuming that the earth is a perfect sphere.
To understand how lat/lon vs meters works in the context of the earth, you may find it interesting to read about Nautical miles.
You can find some more resources and some sample code by googling objective-c Haversine formula.
Enjoy!
as title how to? i have tried the code from google earth, but seem like the result is different with the google map calculation result. below provided the code i did
-(double)GetDistance:(double)lat1 long1:(double)lng1 la2:(double)lat2 long2:(double)lng2 {
//NSLog(#"latitude 1:%.7f,longitude1:%.7f,latitude2:%.7f,longtitude2:%.7f",lat1,lng1,lat2,lng2);
double radLat1 = [self rad:lat1];
double radLat2 = [self rad:lat2];
double a = radLat1 - radLat2;
double b = [self rad:lng1] -[self rad:lng2];
double s = 2 * asin(sqrt(pow(sin(a/2),2) + cos(radLat1)*cos(radLat2)*pow(sin(b/2),2)));
s = s * EARTH_RADIUS;
s = round(s * 10000) / 10000;
return s;
}
-(double)rad:(double)d
{
return d *3.14159265 / 180.0;
}
the EARTH_RADIUS value is 6378.138
by using this function by provided two coordinates the result come out is 4.5kM
but when i use google map get direction between two same coordinates, it show me the distance is about 8km
can anyone help to point out the problem of my code?
Since this is tagged iPhone, why not use the built-in distance function rather than rolling your own? location1 and location2 are CLLocation objects.
CLLocationDistance distance = [location1 getDistanceFrom:location2];
Here is a simple code (supposing you just have latitude and longitude of the two points)
CLLocation *startLocation = [[CLLocation alloc] initWithLatitude:startLatitude longitude:startLongitude];
CLLocation *endLocation = [[CLLocation alloc] initWithLatitude:endLatitude longitude:endLongitude];
CLLocationDistance distance = [startLocation distanceFromLocation:endLocation]; // aka double
Don't forget to add MapKit Framework to your project, and import MapKit in your file :
#import <MapKit/MapKit.h>
Google Maps is likely to be giving you the driving distance, whereas the great circle equation you have listed is going to be the straight line surface distance. If there was a straight line surface road directly from point A to point B, Google Maps would likely give you the same distance as the equation you have there.
Since
getDistanceFrom:
isDeprecated
Try use the
[newLocation distanceFromLocation:oldLocation
You should be able to use the google API directly to calculate either great circle distance or driving distance depending on your application needs.
See GLatLong::distanceFrom and GDirections::getDistance.