Wie lautet die Formel zur Berechnung der Entfernung zwischen 2 Geocodes? Ich habe einige der Antworten auf dieser Seite gesehen, aber sie sagen im Grunde, dass sie sich auf die Funktionen von SQL Server 08 verlassen, ich bin noch nicht auf 08. Jede Hilfe wäre willkommen.Entfernung zwischen 2 Geocodes
Antwort
Verwenden Sie eine Approximation der Erde und die Haversine Formel. Sie können auf folgende URL ein Javascript-Version erhalten, die Sie in der Sprache Ihrer Wahl übersetzen kann:
http://www.movable-type.co.uk/scripts/latlong.html
ist hier eine andere Art und Weise: http://escience.anu.edu.au/project/04S2/SE/3DVOT/3DVOT/pHatTrack_Application/Source_code/pHatTrack/Converter.java
der Satz des Pythagoras?
einen Blick hier für eine SQL Server 2000-Version Nehmen SQL Server Zipcode Latitude/Longitude proximity distance search
Sie suchen nach der Länge des Great Circle Path zwischen zwei Punkten auf einer Kugel. Versuchen Sie, bei Google nach "Großkreis-Pfad" oder "Großkreis-Entfernung" zu suchen.
Sorry, ich weiß nicht, in welchem Land Sie gerade sind. Sprechen wir über Easting und Northings (UK, Ordance Survey System) oder Lat/Long oder ein anderes System? Wenn wir Eastern und Northing sprechen, dann können Sie sqr ((x1-x2)^2 + (y1-y2)^2)
Dies erlaubt nicht für die Tatsache, dass die Erde eine Kugel ist, aber für kurze Wege werden Sie nicht bemerken. Wir verwenden es bei der Arbeit für Entfernungen zwischen Punkten innerhalb der Grafschaft.
Seien Sie vorsichtig, wie lange die Gitterreferenz verwendet wird. Ich denke, eine 8-stellige Referenz gibt Ihnen eine Distanz in Metern. Ich werde in der nächsten Woche eine definitive Antwort auf die Arbeit bekommen, wenn niemand anders es geliefert hat.
Das Pythagoras Theorem, wie es hier von anderen angeboten wird, funktioniert nicht so gut.
Die beste, einfache Antwort ist, die Erde als eine Kugel anzunähern (es ist eigentlich eine leicht abgeflachte Kugel, aber das ist sehr nahe). In Haskell, zum Beispiel könnten Sie die folgende verwenden, aber die Mathematik kann in so ziemlich alles transkribiert werden:
distRadians (lat1,lon1) (lat2,lon2) =
radius_of_earth *
acos (cos lat1 * cos lon1 * cos lat2 * cos lon2 +
cos lat1 * sin lon1 * cos lat2 * sin lon2 +
sin lat1 * sin lat2) where
radius_of_earth = 6378 -- kilometers
distDegrees a b = distRadians (coord2rad a) (coord2rad b) where
deg2rad d = d * pi/180
coord2rad (lat,lon) = (deg2rad lat, deg2rad lon)
distRadians
erfordert Ihre Winkel in Radiant angegeben werden.
distDegrees
ist eine Hilfsfunktion, die Breitengrade und Längengrade in Grad annehmen kann.
Weitere Informationen zur Ableitung dieser Formel finden Sie unter this series of posts.
Wenn Sie wirklich die zusätzliche Präzision durch die Annahme, die Erde gewährt müssen elliptisch finden Sie in diesem FAQ: http://www.movable-type.co.uk/scripts/gis-faq-5.1.html
Dieses es für Sie in C# tun.
Im Namespace setzen diese:
public enum DistanceType { Miles, Kilometers };
public struct Position
{
public double Latitude;
public double Longitude;
}
class Haversine
{
public double Distance(Position pos1, Position pos2, DistanceType type)
{
double preDlat = pos2.Latitude - pos1.Latitude;
double preDlon = pos2.Longitude - pos1.Longitude;
double R = (type == DistanceType.Miles) ? 3960 : 6371;
double dLat = this.toRadian(preDlat);
double dLon = this.toRadian(preDlon);
double a = Math.Sin(dLat/2) * Math.Sin(dLat/2) +
Math.Cos(this.toRadian(pos1.Latitude)) * Math.Cos(this.toRadian(pos2.Latitude)) *
Math.Sin(dLon/2) * Math.Sin(dLon/2);
double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
double d = R * c;
return d;
}
private double toRadian(double val)
{
return (Math.PI/180) * val;
}
Dann werden diese in den Hauptcode zu verwenden:
Position pos1 = new Position();
pos1.Latitude = Convert.ToDouble(hotelx.latitude);
pos1.Longitude = Convert.ToDouble(hotelx.longitude);
Position pos2 = new Position();
pos2.Latitude = Convert.ToDouble(lat);
pos2.Longitude = Convert.ToDouble(lng);
Haversine calc = new Haversine();
double result = calc.Distance(pos1, pos2, DistanceType.Miles);
Wenn
- Sie wissen, dass die zwei Punkte sind „nicht zu weit voneinander entfernt "
- und Sie tolerieren eine "einigermaßen kleine" Fehler.
Dann betrachten, daß die Erde zwischen den Punkten 2 flach ist:
- Der Entfernungsunterschied in der Breitenrichtung ist
EarthRadius * latitude difference
- Der Entfernungsunterschied in der Längenrichtung
EarthRadius * longitude difference * cos(latitude)
ist. Wir multiplizieren mitcos(lat)
, weil die Längengrade nicht den gleichen km Abstand machen, wenn sich der Breitengrad ändert. Als P1 und P2 nahe sind, cos (latP1) liegt in der Nähe von cos (latP2) - Dann Pythagore
In JavaScript:
function ClosePointsDistance(latP1, lngP1, latP2, lngP2) {
var d2r = Math.PI/180,
R=6371; // Earth Radius in km
latP1 *= d2r; lngP1 *= d2r; latP2 *= d2r; lngP2 *= d2r; // convert to radians
dlat = latP2 - latP1,
dlng = (lngP2 - lngP1) * Math.cos(latP1);
return R * Math.sqrt(dlat*dlat + dlng*dlng);
}
ich es zwischen Paris getestet und Orleans (Frankreich): die Formel findet 110,9 km, während die (exakte) Haversine Formel 111,0 km findet.
!!! Hüten Sie sich vor Situationen um den Meridian 0 (Sie können es verschieben): Wenn P1 bei Lng 359 und P2 bei Lng 0 ist, wird die Funktion sie als ungewöhnlich weit betrachten !!!
Hier ist eine Möglichkeit, es zu tun, wenn Sie SQL Server verwenden.
CREATE function dist (@Lat1 varchar(50), @Lng1 varchar(50),@Lat2 varchar(50), @Lng2 varchar(50))
returns float
as
begin
declare @p1 geography
declare @p2 geography
set @p1 = geography::STGeomFromText('POINT('+ @Lng1+' '+ @Lat1 +')', 4326)
set @p2 = geography::STGeomFromText('POINT('+ @Lng2+' '+ @Lat2 +')', 4326)
return @p1.STDistance(@p2)
end
Leider ist die Erde nicht flach. –
Es hängt von der Projektion ab, die Sie verwenden. Es gibt eine Projektion der Zustandsebene, die über relativ kurze Entfernungen sehr genau ist. Mit einer Projektion der Zustandsebene ist das Pythagoras-Theorem in Ordnung. Wenn Sie Breiten-/Längenkoordinaten verwenden, die bereits in Winkeln ausgedrückt sind (keine Abstände), können Sie das Pythogoräische Theorem nicht verwenden. –