Analytics un testēšanaCRM un datu platformasmārketinga rīki

Aprēķiniet vai vaicājiet lielā apļa attālumu starp platuma un garuma punktiem, izmantojot Haversine formulu (PHP, JavaScript, Java, Python, MySQL, MSSQL piemēri)

Šomēnes es programmēju PHP un MySQL GIS. Pētot tēmu, man bija grūtības atrast ģeogrāfiskie aprēķini lai atrastu attālumu starp divām atrašanās vietām, tāpēc vēlējos ar tiem dalīties šeit.

Lidojuma karte Eiropā ar lielu apļa attālumu

Vienkāršs veids, kā aprēķināt attālumu starp diviem punktiem, ir Pitagora formulas izmantošana, lai aprēķinātu trijstūra hipotenūzu (A² + B² = C²). Tas ir pazīstams kā Eiklīda attālums.

Tas ir interesants sākums, taču tas neattiecas uz ģeogrāfiju, jo attālums starp platuma un garuma līnijām ir nav vienādi attālumi viens no otra. Tuvojoties ekvatoram, platuma līnijas attālinās viena no otras. Ja izmantojat vienkāršu triangulācijas vienādojumu, tas var precīzi izmērīt attālumu vienā vietā, bet otrā - nepareizi Zemes izliekuma dēļ.

Liels apļa attālums

Maršruti, kas veikti lielos attālumos ap Zemi, ir pazīstami kā Lielā apļa attālums. Tas ir… īsākais attālums starp diviem punktiem uz sfēras atšķiras no punktiem plakanā kartē. Apvienojiet to ar faktu, ka platuma un garuma līnijas nav vienādā attālumā… un jums ir sarežģīts aprēķins.

Šeit ir fantastisks video skaidrojums par to, kā darbojas lieliski loki.

Haversines formula

Attālums, izmantojot Zemes izliekumu, ir iekļauts Haversine formulā, kas izmanto trigonometriju, lai ņemtu vērā Zemes izliekumu. Kad atrodat attālumu starp 2 vietām uz Zemes (lidojot), taisna līnija patiesībā ir loks.

Tas ir piemērojams gaisa lidojumos — vai esat kādreiz skatījies faktiskajā lidojumu kartē un pamanījis, ka tās ir izliektas? Tas ir tāpēc, ka lidojums arkā starp diviem punktiem ir īsāks nekā tieši uz atrašanās vietu.

PHP: Aprēķiniet attālumu starp 2 platuma un garuma punktiem

Šeit ir PHP formula attāluma starp diviem punktiem aprēķināšanai (kopā ar jūdžu un kilometru pārrēķinu), kas noapaļota līdz divām zīmēm aiz komata.

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)); 
}

Mainīgie lielumi ir:

  • $Latitude1 – mainīgais jūsu pirmās atrašanās vietas platuma grādam.
  • $ garums1 – jūsu pirmās atrašanās vietas garuma mainīgais
  • $Latitude2 – mainīgais jūsu otrās atrašanās vietas platuma grādam.
  • $ garums2 – jūsu otrās atrašanās vietas garuma mainīgais.
  • $vienība – noklusējuma būtne jūdzes. To var atjaunināt vai nodot kā kilometri.

Java: Aprēķiniet attālumu starp 2 platuma un garuma punktiem

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;
    }
}

Mainīgie lielumi ir:

  • platums1 – mainīgais jūsu pirmās atrašanās vietas platuma grādam.
  • garums1 – jūsu pirmās atrašanās vietas garuma mainīgais
  • platums2 – mainīgais jūsu otrās atrašanās vietas platuma grādam.
  • garums2 – jūsu otrās atrašanās vietas garuma mainīgais.
  • vienība – noklusējuma būtne jūdzes. To var atjaunināt vai nodot kā kilometri.

JavaScript: Aprēķiniet attālumu starp 2 platuma un garuma punktiem

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);
    }
}

Mainīgie lielumi ir:

  • platums1 – mainīgais jūsu pirmās atrašanās vietas platuma grādam.
  • garums1 – jūsu pirmās atrašanās vietas garuma mainīgais
  • platums2 – mainīgais jūsu otrās atrašanās vietas platuma grādam.
  • garums2 – jūsu otrās atrašanās vietas garuma mainīgais.
  • vienība – noklusējuma būtne jūdzes. To var atjaunināt vai nodot kā kilometri.

Python: Aprēķiniet attālumu starp 2 platuma un garuma punktiem

Šeit ir Python formula attāluma starp diviem punktiem aprēķināšanai (kopā ar jūdžu un kilometru pārrēķinu), kas noapaļota līdz divām zīmēm aiz komata. Pateicība manam dēlam Bilam Karam, datu zinātniekam par OpenINSIGHTS, par kodu.

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)

Mainīgie lielumi ir:

  • platums1 – mainīgais jūsu pirmajai atrašanās vietai platums.
  • garums1 – mainīgais jūsu pirmajai atrašanās vietai garums
  • platums2 – mainīgais jūsu otrajai atrašanās vietai platums.
  • garums2 – mainīgais jūsu otrajai atrašanās vietai garums.
  • vienība – noklusējuma būtne jūdzes. To var atjaunināt vai nodot kā kilometri.

MySQL: visu ierakstu izgūšana diapazonā, aprēķinot attālumu jūdzēs, izmantojot platuma un garuma grādus

Telpisko datu tipu izmantošana MySQL ir efektīvāks un ērtāks veids, kā strādāt ar ģeogrāfiskajiem datiem, tostarp aprēķināt attālumus starp punktiem. MySQL atbalsta telpisko datu tipus, piemēram POINT, LINESTRING, un POLYGON, kā arī telpiskās funkcijas, piemēram, ST_Distance.

Kad lietojat ST_Distance funkcija MySQL ar ģeogrāfiskajiem datiem, kas attēloti kā POINT koordinātas, tas ņem vērā Zemes virsmas izliekumu. Sfēriskais modelis, ko izmantoja ST_Distance izmanto Haversine formulu. Šis tuvinājums ir piemērots lielākajai daļai praktisku mērķu, bet var radīt nelielas neprecizitātes ļoti lielos attālumos.

Lūk, kā varat aprēķināt attālumus starp diviem punktiem, izmantojot telpisko datu tipus.

  1. Izveidojiet tabulu ar telpisko datu tipu: Vispirms izveidojiet tabulu ar a POINT kolonnu, lai saglabātu ģeogrāfiskos punktus. Piemēram:
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    coordinates POINT
);

Ievadiet savus ģeogrāfiskos punktus šajā tabulā, izmantojot POINT konstruktors:

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
  1. Aprēķiniet attālumu, izmantojot ST_Distance: Varat aprēķināt attālumu starp diviem punktiem, izmantojot ST_Distance funkciju. Šis ir vaicājuma piemērs, lai aprēķinātu attālumu starp diviem punktiem:
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;

aizstāt 1 un 2 ar divu punktu ID, starp kuriem vēlaties aprēķināt attālumu.

  1. Rezultāts: vaicājums atgriezīs attālumu starp diviem punktiem jūdzēs.

Izmantojot telpisko datu tipus un ST_Distance funkcija nodrošina efektīvāku un precīzāku veidu, kā strādāt ar ģeogrāfiskajiem datiem MySQL. Tas arī vienkāršo attāluma aprēķināšanu starp punktiem, atvieglojot datu pārvaldību un vaicājumu veikšanu.

MySQL: visu ierakstu izgūšana diapazonā, aprēķinot attālumu kilometros, izmantojot platuma un garuma grādus

Pēc noklusējuma ST_Distance atgriež attālumu metros, tāpēc jums vienkārši jāatjaunina vaicājums par kilometriem:

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 ģeogrāfiskais attālums: STDistance

Ja izmantojat Microsoft SQL Server, tie piedāvā savu funkciju, STDistance lai aprēķinātu attālumu starp diviem punktiem, izmantojot datu tipu Ģeogrāfija.

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);  

Cepures padoms Manash Sahoo, uzņēmuma dibinātājs un vecākais arhitekts Jons Trīs.

Douglas Karr

Douglas Karr ir TKO no OpenINSIGHTS un dibinātājs Martech Zone. Duglass ir palīdzējis desmitiem veiksmīgu MarTech jaunuzņēmumu, ir palīdzējis veikt vairāk nekā 5 miljardu dolāru Martech iegādes un ieguldījumu uzticamības pārbaudi, kā arī turpina palīdzēt uzņēmumiem ieviest un automatizēt to pārdošanas un mārketinga stratēģijas. Douglas ir starptautiski atzīts digitālās transformācijas un MarTech eksperts un runātājs. Duglass ir arī publicēts Dummie rokasgrāmatas un biznesa vadības grāmatas autors.

Saistītie raksti

Atpakaļ uz augšu pogu
aizvērt

Reklāmu bloķēšana konstatēta

Martech Zone var nodrošināt jums šo saturu bez maksas, jo mēs gūstam peļņu no savas vietnes, izmantojot ieņēmumus no reklāmām, saistīto uzņēmumu saites un sponsorēšanu. Būsim pateicīgi, ja, apskatot mūsu vietni, noņemtu savu reklāmu bloķētāju.