Analytiikka ja testausCRM ja tietoalustatMarkkinointityökalut

Laske tai kysy suurympyrän etäisyys leveys- ja pituusastepisteiden välillä Haversine-kaavan avulla (esimerkkejä PHP, JavaScript, Java, Python, MySQL, MSSQL)

Tässä kuussa olen ohjelmoinut PHP:llä ja MySQL:llä GIS:lle. Aihetta tutkiessani minulla oli vaikeuksia löytää maantieteelliset laskelmat kahden sijainnin välisen etäisyyden selvittämiseksi, joten halusin jakaa ne täällä.

Euroopan lentokartta, jolla on suuri ympyräetäisyys

Yksinkertainen tapa laskea kahden pisteen välinen etäisyys on Pythagorean kaavan avulla laskettaessa kolmion hypotenuus (A² + B² = C²). Tätä kutsutaan Euklidinen etäisyys.

Tämä on mielenkiintoinen alku, mutta se ei koske maantiedettä, koska leveys- ja pituuspiirien välinen etäisyys on eivät ole yhtä kaukana toisistaan. Kun tulet lähemmäksi päiväntasaajaa, leveyspiirit etääntyvät toisistaan. Jos käytät yksinkertaista kolmioyhtälöä, se voi mitata etäisyyden tarkasti yhdessä paikassa ja väärin toisessa Maan kaarevuuden vuoksi.

Suuri ympyräetäisyys

Reittejä, jotka kulkivat pitkiä matkoja Maan ympäri, tunnetaan nimellä Great Circle Distance. Eli… lyhin etäisyys kahden pallon pisteen välillä eroaa tasaisen kartan pisteistä. Yhdistä se siihen, että leveys- ja pituuspiirit eivät ole yhtä kaukana toisistaan… ja sinulla on vaikea laskelma.

Tässä on upea videoesitys siitä, kuinka suuret piirit toimivat.

Haversinen kaava

Maan kaarevuutta käyttävä etäisyys sisältyy Haversinen kaavaan, joka käyttää trigonometriaa maan kaarevuuden sallimiseksi. Kun etsit etäisyyttä maan kahden paikan välillä (lintulento), suora on itse asiassa kaari.

Tämä pätee lentolennolle – oletko koskaan katsonut lentojen todellista karttaa ja huomannut, että ne ovat kaarevia? Tämä johtuu siitä, että kaaressa lentäminen kahden pisteen välillä on lyhyempää kuin suoraan kohteeseen.

PHP: Laske etäisyys kahden leveys- ja pituusasteen välillä

Tässä on PHP-kaava kahden pisteen välisen etäisyyden laskemiseen (sekä Mailia vs. Kilometrit -muunnos) pyöristettynä kahteen desimaaliin.

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

Muuttujat ovat:

  • $Latitude1 – ensimmäisen sijaintisi leveysasteen muuttuja.
  • $Pituusaste1 – ensimmäisen sijaintisi pituusasteen muuttuja
  • $Latitude2 – toisen sijaintisi leveysasteen muuttuja.
  • $Pituusaste2 – toisen sijaintisi pituusasteen muuttuja.
  • $yksikkö – oletusarvo mailia. Tämä voidaan päivittää tai antaa eteenpäin kilometriä.

Java: Laske etäisyys 2 leveys- ja pituusasteen välillä

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

Muuttujat ovat:

  • leveysaste1 – ensimmäisen sijaintisi leveysasteen muuttuja.
  • pituusaste1 – ensimmäisen sijaintisi pituusasteen muuttuja
  • leveysaste2 – toisen sijaintisi leveysasteen muuttuja.
  • pituusaste2 – toisen sijaintisi pituusasteen muuttuja.
  • yksikkö – oletusarvo mailia. Tämä voidaan päivittää tai antaa eteenpäin kilometriä.

JavaScript: Laske etäisyys 2 leveys- ja pituusasteen välillä

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

Muuttujat ovat:

  • leveysaste1 – ensimmäisen sijaintisi leveysasteen muuttuja.
  • pituusaste1 – ensimmäisen sijaintisi pituusasteen muuttuja
  • leveysaste2 – toisen sijaintisi leveysasteen muuttuja.
  • pituusaste2 – toisen sijaintisi pituusasteen muuttuja.
  • yksikkö – oletusarvo mailia. Tämä voidaan päivittää tai antaa eteenpäin kilometriä.

Python: Laske etäisyys 2 leveys- ja pituusasteen välillä

Tässä on Python-kaava kahden pisteen välisen etäisyyden laskemiseksi (yhdessä maili vs. kilometri -muunnoksen kanssa) pyöristettynä kahteen desimaaliin. Kiitos pojalleni Bill Karrille, joka on tietotutkija OpenINSIGHTS, koodia varten.

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)

Muuttujat ovat:

  • leveysaste1 – ensimmäisen sijaintisi muuttuja leveysaste.
  • pituusaste1 – ensimmäisen sijaintisi muuttuja pituusaste
  • leveysaste2 – toisen sijaintisi muuttuja leveysaste.
  • pituusaste2 – toisen sijaintisi muuttuja pituusaste.
  • yksikkö – oletusarvo mailia. Tämä voidaan päivittää tai antaa eteenpäin kilometriä.

MySQL: Hae kaikki tietueet tietyn alueen sisällä laskemalla etäisyys maileina käyttämällä leveys- ja pituusasteita

Paikkatietotyyppien käyttäminen MySQL:ssä on tehokkaampi ja kätevämpi tapa käsitellä maantieteellisiä tietoja, mukaan lukien pisteiden välisten etäisyyksien laskeminen. MySQL tukee paikkatietotyyppejä, kuten POINT, LINESTRINGja POLYGON, sekä tilafunktiot, kuten ST_Distance.

Kun käytät ST_Distance toiminto MySQL:ssä ja maantieteelliset tiedot esitetään muodossa POINT koordinaatit, se ottaa huomioon maan pinnan kaarevuuden. Pallomainen malli, jota käytti ST_Distance käyttää Haversine-kaavaa. Tämä likiarvo sopii useimpiin käytännön tarkoituksiin, mutta se voi aiheuttaa pieniä epätarkkuuksia erittäin pitkillä etäisyyksillä.

Näin voit laskea kahden pisteen väliset etäisyydet paikkatietotyyppien avulla:

  1. Luo taulukko paikkatietotyypillä: Luo ensin taulukko a POINT sarake tallentaa maantieteellisiä pisteitä. Esimerkiksi:
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    coordinates POINT
);

Lisää maantieteelliset pisteet tähän taulukkoon käyttämällä POINT rakentaja:

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. Laske etäisyys käyttämällä ST_Distance: Voit laskea kahden pisteen välisen etäisyyden käyttämällä ST_Distance toiminto. Tässä on esimerkkikysely kahden pisteen välisen etäisyyden laskemiseksi:
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;

korvata 1 ja 2 niiden kahden pisteen tunnuksilla, joiden välillä haluat laskea etäisyyden.

  1. Tulos: Kysely palauttaa kahden pisteen välisen etäisyyden maileina.

Paikkatietotyyppien ja ST_Distance -toiminto tarjoaa tehokkaamman ja tarkemman tavan käsitellä maantieteellisiä tietoja MySQL:ssä. Se myös yksinkertaistaa pisteiden välisten etäisyyksien laskemista, mikä helpottaa tietojen hallintaa ja kyselyitä.

MySQL: Hae kaikki tietueet tietyllä alueella laskemalla etäisyys kilometreinä käyttämällä leveys- ja pituusasteita

Oletuksena ST_Distance palauttaa etäisyyden metreinä, joten sinun tarvitsee vain päivittää kilometrikysely:

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 Maantieteellinen etäisyys: STDistance

Jos käytät Microsoft SQL Serveriä, ne tarjoavat oman toimintonsa, STDistance kahden pisteen välisen etäisyyden laskemiseen maantiede-tietotyypin avulla.

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

Hattuvinkki Manash Sahoolle, yrityksen perustajalle ja vanhemmalle arkkitehdille Ioni kolme.

Douglas Karr

Douglas Karr on CMO of OpenINSIGHTS ja perustaja Martech Zone. Douglas on auttanut kymmeniä menestyneitä MarTech-startuppeja, auttanut yli 5 miljardin dollarin due diligence -tarkastuksessa Martechin hankinnoissa ja investoinneissa ja avustaa edelleen yrityksiä niiden myynti- ja markkinointistrategioiden toteuttamisessa ja automatisoinnissa. Douglas on kansainvälisesti tunnustettu digitaalisen transformaation ja MarTechin asiantuntija ja puhuja. Douglas on myös julkaissut Dummie's-oppaan ja yritysjohtajuuskirjan.

Aiheeseen liittyvät artikkelit

Takaisin alkuun -painiketta
lähellä

Adblock havaittu

Martech Zone pystyy tarjoamaan sinulle tämän sisällön veloituksetta, koska ansaitsemme sivustomme mainostulojen, kumppanilinkkien ja sponsoroinnin kautta. Olisimme kiitollisia, jos poistaisit mainosten esto-ohjelman, kun katselet sivustoamme.