Analýza a testováníCRM a datové platformymarketingové nástroje

Vypočítejte nebo dotazujte vzdálenost velkého kruhu mezi body zeměpisné šířky a délky pomocí vzorce Haversine (příklady PHP, JavaScript, Java, Python, MySQL, MSSQL)

Tento měsíc jsem programoval v PHP a MySQL pro GIS. Při zkoumání tématu jsem měl problém najít geografické výpočty najít vzdálenost mezi dvěma místy, tak jsem je chtěl sdílet zde.

Letová mapa Evropy s velkou vzdáleností od kruhu

Jednoduchý způsob výpočtu vzdálenosti mezi dvěma body je pomocí Pythagorovy vzorce pro výpočet přepony trojúhelníku (A² + B² = C²). Toto je známé jako Euklidovská vzdálenost.

To je zajímavý začátek, ale neplatí to pro geografii, protože vzdálenost mezi čarami zeměpisné šířky a délky je nejsou od sebe ve stejné vzdálenosti. Jak se přibližujete k rovníku, čáry zeměpisné šířky se vzdalují. Pokud použijete jednoduchou triangulační rovnici, může změřit vzdálenost přesně v jednom místě a špatně ve druhém kvůli zakřivení Země.

Velká vzdálenost kruhu

Trasy ujeté na dlouhé vzdálenosti kolem Země jsou známé jako Velká kruhová vzdálenost. To znamená... nejkratší vzdálenost mezi dvěma body na kouli se liší od bodů na ploché mapě. Zkombinujte to se skutečností, že čáry zeměpisné šířky a délky nejsou stejně vzdálené... a máte obtížný výpočet.

Zde je fantastické video vysvětlení toho, jak Great Circles fungují.

Vzorec Haversine

Vzdálenost využívající zakřivení Země je začleněna do Haversinova vzorce, který využívá trigonometrii k zohlednění zakřivení Země. Když zjišťujete vzdálenost mezi 2 místy na Zemi (vzdušnou čarou), přímka je ve skutečnosti oblouk.

To platí v leteckém letu – už jste se někdy podívali na skutečnou mapu letů a všimli jste si, že jsou klenuté? Je to proto, že let v oblouku mezi dvěma body je kratší než přímo na místo.

PHP: Vypočítejte vzdálenost mezi 2 body zeměpisné šířky a délky

Zde je vzorec PHP pro výpočet vzdálenosti mezi dvěma body (spolu s převodem Míle vs. Kilometr) zaokrouhlený na dvě desetinná místa.

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

Proměnné jsou:

  • $Latitude1 – proměnná pro zeměpisnou šířku vašeho prvního místa.
  • $Longitude1 – proměnná pro zeměpisnou délku vašeho prvního místa
  • $Latitude2 – proměnná pro zeměpisnou šířku vašeho druhého místa.
  • $Longitude2 – proměnná pro zeměpisnou délku vašeho druhého místa.
  • $jednotka – výchozí bytost míle. To lze aktualizovat nebo předat jako kilometrů.

Java: Vypočítejte vzdálenost mezi 2 body zeměpisné šířky a délky

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

Proměnné jsou:

  • zeměpisná šířka 1 – proměnná pro zeměpisnou šířku vašeho prvního místa.
  • zeměpisná délka 1 – proměnná pro zeměpisnou délku vašeho prvního místa
  • zeměpisná šířka 2 – proměnná pro zeměpisnou šířku vašeho druhého místa.
  • zeměpisná délka 2 – proměnná pro zeměpisnou délku vašeho druhého místa.
  • jednotka – výchozí bytost míle. To lze aktualizovat nebo předat jako kilometrů.

JavaScript: Vypočítejte vzdálenost mezi 2 body zeměpisné šířky a délky

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

Proměnné jsou:

  • zeměpisná šířka 1 – proměnná pro zeměpisnou šířku vašeho prvního místa.
  • zeměpisná délka 1 – proměnná pro zeměpisnou délku vašeho prvního místa
  • zeměpisná šířka 2 – proměnná pro zeměpisnou šířku vašeho druhého místa.
  • zeměpisná délka 2 – proměnná pro zeměpisnou délku vašeho druhého místa.
  • jednotka – výchozí bytost míle. To lze aktualizovat nebo předat jako kilometrů.

Python: Vypočítejte vzdálenost mezi 2 body zeměpisné šířky a délky

Zde je pythonovský vzorec pro výpočet vzdálenosti mezi dvěma body (spolu s převodem Míle vs. Kilometr) zaokrouhlený na dvě desetinná místa. Poděkování patří mému synovi, Billu Karrovi, datovému vědci za OpenINSIGHTS, pro kód.

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)

Proměnné jsou:

  • zeměpisná šířka 1 – proměnná pro vaše první umístění zeměpisná šířka.
  • zeměpisná délka 1 – proměnná pro vaše první umístění zeměpisná délka
  • zeměpisná šířka 2 – proměnná pro vaše druhé umístění zeměpisná šířka.
  • zeměpisná délka 2 – proměnná pro vaše druhé umístění zeměpisná délka.
  • jednotka – výchozí bytost míle. To lze aktualizovat nebo předat jako kilometrů.

MySQL: Získávání všech záznamů v rámci rozsahu výpočtem vzdálenosti v mílích pomocí zeměpisné šířky a délky

Použití typů prostorových dat v MySQL je efektivnější a pohodlnější způsob práce s geografickými daty, včetně výpočtu vzdáleností mezi body. MySQL podporuje typy prostorových dat jako např POINT, LINESTRING, a POLYGON, spolu s prostorovými funkcemi jako ST_Distance.

Když používáte ST_Distance funkce v MySQL s geografickými daty reprezentovanými jako POINT souřadnice, zohledňuje zakřivení zemského povrchu. Sférický model, který používá ST_Distance využívá Haversinův vzorec. Tato aproximace je vhodná pro většinu praktických účelů, ale může způsobit mírné nepřesnosti na velmi dlouhé vzdálenosti.

Zde je návod, jak vypočítat vzdálenosti mezi dvěma body pomocí typů prostorových dat:

  1. Vytvořte tabulku s typem prostorových dat: Nejprve vytvořte tabulku s a POINT sloupec pro uložení geografických bodů. Například:
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    coordinates POINT
);

Vložte své geografické body do této tabulky pomocí POINT konstruktér:

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. Vypočítejte vzdálenost pomocí ST_Distance: Vzdálenost mezi dvěma body můžete vypočítat pomocí ST_Distance funkce. Zde je příklad dotazu pro výpočet vzdálenosti mezi dvěma body:
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;

Nahradit 1 a 2 s ID dvou bodů, mezi kterými chcete vypočítat vzdálenost.

  1. Výsledek: Dotaz vrátí vzdálenost mezi dvěma body v mílích.

Použití typů prostorových dat a ST_Distance poskytuje efektivnější a přesnější způsob práce s geografickými daty v MySQL. Zjednodušuje také výpočet vzdáleností mezi body, což usnadňuje správu a dotazování vašich dat.

MySQL: Získávání všech záznamů v rámci rozsahu výpočtem vzdálenosti v kilometrech pomocí zeměpisné šířky a délky

Ve výchozím nastavení ST_Distance vrací vzdálenost v metrech, takže stačí aktualizovat dotaz na kilometry:

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;

Geografická vzdálenost Microsoft SQL Server: STDistance

Pokud používáte Microsoft SQL Server, nabízejí své vlastní funkce, STDvzdálenost pro výpočet vzdálenosti mezi dvěma body pomocí datového typu Geografie.

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

Klobouk pro Manash Sahoo, zakladatele a hlavního architekta ve společnosti Ion tři.

Douglas Karr

Douglas Karr je CMO OpenINSIGHTS a zakladatelem Martech Zone. Douglas pomohl desítkám úspěšných MarTech startupů, pomohl s due diligence v hodnotě více než 5 miliard dolarů v akvizicích a investicích Martech a nadále pomáhá společnostem při implementaci a automatizaci jejich prodejních a marketingových strategií. Douglas je mezinárodně uznávaný odborník na digitální transformaci a MarTech a řečník. Douglas je také publikovaným autorem průvodce pro figuríny a knihy o obchodním vedení.

Související články

Tlačítko Nahoru
zavřít

Byl detekován Adblock

Martech Zone je schopna vám poskytnout tento obsah zdarma, protože naše stránky zpeněžujeme prostřednictvím příjmů z reklam, přidružených odkazů a sponzorství. Ocenili bychom, kdybyste při prohlížení našich stránek odstranili svůj blokovač reklam.