Apskaičiuokite didžiojo apskritimo atstumą tarp platumos ir ilgumos taškų arba pateikite užklausą naudodami Haversino formulę (PHP, JavaScript, Java, Python, MySQL, MSSQL pavyzdžiai)

Šį mėnesį aš programavau PHP bei MySQL forumas GIS. Tyrinėjant temą man buvo sunku rasti geografiniai skaičiavimai Norėdami sužinoti atstumą tarp dviejų vietų, norėjau jais pasidalinti čia.
Paprastas atstumo tarp dviejų taškų apskaičiavimo būdas - naudojant Pitagoro formulę - apskaičiuoti trikampio hipotenuzą (A² + B² = C²). Tai vadinama Euklido atstumas.
1 Artėjant prie pusiaujo, platumos linijos tolsta viena nuo kitos. Jei naudosite paprastą trianguliacijos lygtį, ji gali tiksliai išmatuoti atstumą vienoje vietoje ir neteisingai kitoje dėl Žemės kreivumo.

Didelis rato atstumas
Maršrutai, kuriais nukeliaujama dideliais atstumais aplink Žemę, vadinami Didžiuoju apskritimo atstumu. Tai reiškia, kad trumpiausias atstumas tarp dviejų taškų sferoje skiriasi nuo atstumo plokščiame žemėlapyje. Pridėkite prie to faktą, kad platumos ir ilgumos linijos nėra vienodu atstumu viena nuo kitos... ir gausite sudėtingą skaičiavimą.
Štai fantastiškas vaizdo įrašo paaiškinimas, kaip veikia „Didieji ratai“.
Haversine formulė
Atstumas naudojant Žemės kreivumą įtrauktas į Haversino formulę, kuri naudoja trigonometriją, kad būtų galima nustatyti Žemės kreivumą. Tiesi linija yra lankas, kai randate atstumą tarp 2 vietų Žemėje (tiesa kryptimi).
Tai taikoma kelionėms lėktuvu. Ar kada nors žiūrėjote į tikrąjį skrydžių žemėlapį ir pastebėjote, kad jie yra išlenkti? Taip yra todėl, kad skrydis arka tarp dviejų taškų yra trumpesnis nei skrydis tiesiai į vietą.
PHP: Apskaičiuokite atstumą tarp 2 platumos ir ilgumos taškų
Štai PHP formulė, skirta apskaičiuoti atstumą tarp dviejų taškų (kartu su mylios ir kilometro konvertavimu), suapvalinta iki dviejų skaičių po kablelio.
function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch($unit) {
case 'miles':
break;
case 'kilometers' :
$distance = $distance * 1.609344;
}
return (round($distance,2));
} Kintamieji yra:
- $platuma1 – jūsų pirmosios vietos platumos kintamasis.
- $ilguma1 – pirmosios vietos ilgumos kintamasis
- $platuma2 – antrosios vietos platumos kintamasis.
- $ilguma2 – antrosios vietos ilgumos kintamasis.
- $ vienetas – numatytoji būtybė mylių. Tai gali būti atnaujinta arba perduodama kaip kilometrų.
Java: Apskaičiuokite atstumą tarp 2 platumos ir ilgumos taškų
public static double getDistanceBetweenPointsNew(double latitude1, double longitude1, double latitude2, double longitude2, String unit) {
double theta = longitude1 - longitude2;
double distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit.equals("miles")) {
return Math.round(distance, 2);
} else if (unit.equals("kilometers")) {
return Math.round(distance * 1.609344, 2);
} else {
return 0;
}
} Kintamieji yra:
- platuma1 – jūsų pirmosios vietos platumos kintamasis.
- ilguma1 – pirmosios vietos ilgumos kintamasis
- platuma2 – antrosios vietos platumos kintamasis.
- ilguma2 – antrosios vietos ilgumos kintamasis.
- vienetas – numatytoji būtybė mylių. Tai gali būti atnaujinta arba perduodama kaip kilometrų.
JavaScript: apskaičiuokite atstumą tarp 2 platumos ir ilgumos taškų
function getDistanceBetweenPoints(latitude1, longitude1, latitude2, longitude2, unit = 'miles') {
let theta = longitude1 - longitude2;
let distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit == 'miles') {
return Math.round(distance, 2);
} else if (unit == 'kilometers') {
return Math.round(distance * 1.609344, 2);
}
} Kintamieji yra:
- platuma1 – jūsų pirmosios vietos platumos kintamasis.
- ilguma1 – pirmosios vietos ilgumos kintamasis
- platuma2 – antrosios vietos platumos kintamasis.
- ilguma2 – antrosios vietos ilgumos kintamasis.
- vienetas – numatytoji būtybė mylių. Tai gali būti atnaujinta arba perduodama kaip kilometrų.
Python: apskaičiuokite atstumą tarp 2 platumos ir ilgumos taškų
Štai Python formulė, skirta apskaičiuoti atstumą tarp dviejų taškų (kartu su mylios ir kilometro konvertavimu), suapvalinta iki dviejų skaičių po kablelio. Nuopelnas mano sūnui Billui Karrui, duomenų mokslininkui OpenINSIGHTS, už kodą.
from numpy import sin, cos, arccos, pi, round
def rad2deg(radians):
degrees = radians * 180 / pi
return degrees
def deg2rad(degrees):
radians = degrees * pi / 180
return radians
def getDistanceBetweenPointsNew(latitude1, longitude1, latitude2, longitude2, unit = 'miles'):
theta = longitude1 - longitude2
distance = 60 * 1.1515 * rad2deg(
arccos(
(sin(deg2rad(latitude1)) * sin(deg2rad(latitude2))) +
(cos(deg2rad(latitude1)) * cos(deg2rad(latitude2)) * cos(deg2rad(theta)))
)
)
if unit == 'miles':
return round(distance, 2)
if unit == 'kilometers':
return round(distance * 1.609344, 2) Kintamieji yra:
- platuma1 – jūsų pirmosios vietos kintamasis platuma.
- ilguma1 – jūsų pirmosios vietos kintamasis ilguma
- platuma2 – jūsų antrosios vietos kintamasis platuma.
- ilguma2 – jūsų antrosios vietos kintamasis ilguma.
- vienetas – numatytoji būtybė mylių. Tai gali būti atnaujinta arba perduodama kaip kilometrų.
MySQL: visų įrašų gavimas diapazone skaičiuojant atstumą myliomis naudojant platumą ir ilgumą
Erdvinių duomenų tipų naudojimas MySQL yra efektyvesnis ir patogesnis būdas dirbti su geografiniais duomenimis, įskaitant atstumų tarp taškų skaičiavimą. MySQL palaiko erdvinių duomenų tipus, tokius kaip POINT, LINESTRINGir POLYGON, kartu su erdvinėmis funkcijomis, pvz ST_Distance.
Kai naudojate ST_Distance funkcija MySQL su geografiniais duomenimis vaizduojama kaip POINT koordinates, atsižvelgiama į Žemės paviršiaus kreivumą. ST_Distance naudojamas sferinis modelis naudoja Haversine formulę. Šis apytikslis skaičiavimas tinka daugeliui praktinių tikslų, tačiau važiuojant dideliais atstumais gali atsirasti nedidelių netikslumų.
Štai kaip galite apskaičiuoti atstumus tarp dviejų taškų naudodami erdvinių duomenų tipus:
- Sukurkite lentelę su erdvinių duomenų tipu: Pirmiausia sukurkite lentelę su a
POINTstulpelį geografiniams taškams saugoti. Pavyzdžiui:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
coordinates POINT
); Į šią lentelę įrašykite savo geografinius taškus naudodami POINT konstruktorius:
INSERT INTO locations (name, coordinates)
VALUES
('Point A', POINT(40.7128, -74.0060)), -- New York City
('Point B', POINT(34.0522, -118.2437)); -- Los Angeles - Apskaičiuokite atstumą naudodami ST_Distance: Galite apskaičiuoti atstumą tarp dviejų taškų naudodami
ST_Distancefunkcija. Štai užklausos pavyzdys, skirtas apskaičiuoti atstumą tarp dviejų taškų:
SELECT
id1,
id2,
(ST_Distance(coordinates1, coordinates2) / 1609.344) AS distance_in_miles
FROM (
SELECT
l1.id AS id1,
l2.id AS id2,
l1.coordinates AS coordinates1,
l2.coordinates AS coordinates2
FROM
locations l1,
locations l2
WHERE
l1.id = 1 AND l2.id = 2
) AS distances; pakeisti 1 bei 2 su dviejų taškų, tarp kurių norite apskaičiuoti atstumą, ID.
- Pasekmė: užklausa pateiks atstumą tarp dviejų taškų myliomis.
Naudojant erdvinių duomenų tipus ir ST_Distance funkcija suteikia efektyvesnį ir tikslesnį būdą dirbti su geografiniais duomenimis MySQL. Tai taip pat supaprastina atstumų tarp taškų skaičiavimą, todėl lengviau valdyti duomenis ir pateikti užklausas.
MySQL: visų įrašų gavimas diapazone skaičiuojant atstumą kilometrais naudojant platumą ir ilgumą
Pagal nutylėjimą ST_Distance grąžina atstumą metrais, todėl jums tereikia atnaujinti užklausą dėl kilometrų:
SELECT
id1,
id2,
(ST_Distance(coordinates1, coordinates2) / 1000) AS distance_in_kilometers
FROM (
SELECT
l1.id AS id1,
l2.id AS id2,
l1.coordinates AS coordinates1,
l2.coordinates AS coordinates2
FROM
locations l1,
locations l2
WHERE
l1.id = 1 AND l2.id = 2
) AS distances; „Microsoft SQL Server“ geografinis atstumas: STDistance
Jei naudojate „Microsoft SQL Server“, jie siūlo funkciją, vadinamą STDistumas atstumui tarp dviejų taškų apskaičiuoti naudojant duomenų tipą Geografija.
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h); Skrybėlės patarimas Manashui Sahoo, įmonės įkūrėjui ir vyresniajam architektui Jonas trys.



