Analiz ve TestCRM ve Veri PlatformlarıPazarlama Araçları

Haversine Formülünü Kullanarak Enlem ve Boylam Noktaları Arasındaki Büyük Çember Mesafesini Hesaplayın veya Sorgulayın (PHP, JavaScript, Java, Python, MySQL, MSSQL Örnekleri)

Bu ay GIS için PHP ve MySQL ile programlama yapıyorum. Konuyu araştırırken bulmakta zorlandım coğrafi hesaplamalar iki lokasyon arasındaki mesafeyi bulmak için burada paylaşmak istedim.

Büyük Daire Mesafeli Avrupa Uçuş Haritası

İki nokta arasındaki mesafeyi hesaplamanın basit yolu, bir üçgenin hipotenüsünü hesaplamak için Pisagor formülünü kullanmaktır (A² + B² = C²). Bu, Öklid mesafesi.

Bu ilginç bir başlangıç, ancak enlem ve boylam çizgileri arasındaki mesafe eşit olduğundan coğrafya için geçerli değil. eşit mesafelerde değil. Ekvatora yaklaştıkça enlem çizgileri birbirinden uzaklaşır. Basit bir üçgenleme denklemi kullanırsanız, Dünya'nın eğriliği nedeniyle mesafeyi bir konumda doğru, diğerinde yanlış ölçebilir.

Büyük Daire Mesafesi

Dünya çevresinde uzun mesafeler kat edilen rotalar, Büyük Çember Mesafesi olarak bilinir. Yani… bir küre üzerindeki iki nokta arasındaki en kısa mesafe, düz bir haritadaki noktalardan farklıdır. Bunu enlem ve boylam çizgilerinin eşit uzaklıkta olmadığı gerçeğiyle birleştirin… ve zor bir hesaplamanız var.

İşte Harika Çevreler'in nasıl çalıştığına dair harika bir video açıklaması.

Haversine Formülü

Dünyanın eğriliğini kullanan mesafe, Dünyanın eğriliğine izin vermek için trigonometri kullanan Haversine formülüne dahil edilmiştir. Dünya üzerindeki 2 yer arasındaki mesafeyi bulduğunuzda (kuş uçuşu), düz bir çizgi aslında bir yaydır.

Bu hava uçuşu için geçerlidir - hiç gerçek uçuş haritasına baktınız ve kemerli olduklarını fark ettiniz mi? Bunun nedeni, iki nokta arasında bir yay şeklinde uçmanın, doğrudan konuma gitmekten daha kısa olmasıdır.

PHP: 2 Enlem ve Boylam Noktası Arasındaki Mesafeyi Hesaplayın

İşte iki nokta arasındaki mesafeyi hesaplamak için kullanılan PHP formülü (Mil ve Kilometre dönüşümü ile birlikte) iki ondalık basamağa yuvarlanmıştır.

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

Değişkenler şunlardır:

  • $Enlem1 – ilk konumunuzun enlemi için bir değişken.
  • $Boylam1 – ilk konumunuzun boylamı için bir değişken
  • $Enlem2 – ikinci konumunuzun enlemi için bir değişken.
  • $Boylam2 – ikinci konumunuzun boylamı için bir değişken.
  • $birim - varsayılan varlık mil. Bu güncellenebilir veya şu şekilde iletilebilir: kilometre.

Java: 2 Enlem ve Boylam Noktası Arasındaki Mesafeyi Hesaplayın

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

Değişkenler şunlardır:

  • enlem1 – ilk konumunuzun enlemi için bir değişken.
  • boylam1 – ilk konumunuzun boylamı için bir değişken
  • enlem2 – ikinci konumunuzun enlemi için bir değişken.
  • boylam2 – ikinci konumunuzun boylamı için bir değişken.
  • birim - varsayılan varlık mil. Bu güncellenebilir veya şu şekilde iletilebilir: kilometre.

JavaScript: 2 Enlem ve Boylam Noktası Arasındaki Mesafeyi Hesaplayın

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

Değişkenler şunlardır:

  • enlem1 – ilk konumunuzun enlemi için bir değişken.
  • boylam1 – ilk konumunuzun boylamı için bir değişken
  • enlem2 – ikinci konumunuzun enlemi için bir değişken.
  • boylam2 – ikinci konumunuzun boylamı için bir değişken.
  • birim - varsayılan varlık mil. Bu güncellenebilir veya şu şekilde iletilebilir: kilometre.

Python: 2 Enlem ve Boylam Noktası Arasındaki Mesafeyi Hesaplayın

İki nokta arasındaki mesafeyi (Mil ve Kilometre dönüşümüyle birlikte) iki ondalık basamağa yuvarlanmış olarak hesaplamak için Python formülünü burada bulabilirsiniz. Veri Bilimcisi oğlum Bill Karr'a teşekkür ederim. AÇIK İÇGÖRÜLER, kod için.

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)

Değişkenler şunlardır:

  • enlem1 – ilk konumunuz için bir değişken enlem.
  • boylam1 – ilk konumunuz için bir değişken boylam
  • enlem2 – ikinci konumunuz için bir değişken enlem.
  • boylam2 – ikinci konumunuz için bir değişken boylam.
  • birim - varsayılan varlık mil. Bu güncellenebilir veya şu şekilde iletilebilir: kilometre.

MySQL: Enlem ve Boylam Kullanarak Mil Olarak Mesafeyi Hesaplayarak Bir Aralık İçindeki Tüm Kayıtları Alma

MySQL'de Uzamsal Veri Türlerini kullanmak, noktalar arasındaki mesafeleri hesaplamak da dahil olmak üzere coğrafi verilerle çalışmanın daha verimli ve kullanışlı bir yoludur. MySQL, aşağıdakiler gibi Uzamsal Veri Türlerini destekler: POINT, LINESTRING, ve POLYGONgibi mekansal işlevlerle birlikte ST_Distance.

Kullandığınızda ST_Distance MySQL'de coğrafi verilerin şu şekilde temsil edildiği işlev POINT koordinatlar, Dünya yüzeyinin eğriliğini hesaba katar. Kullandığı küresel model ST_Distance Haversine formülünü kullanır. Bu yaklaşım çoğu pratik amaç için uygundur ancak çok uzun mesafeler için hafif yanlışlıklara neden olabilir.

Uzamsal Veri Türlerini kullanarak iki nokta arasındaki mesafeleri şu şekilde hesaplayabilirsiniz:

  1. Uzamsal Veri Türüne Sahip Bir Tablo Oluşturma: Öncelikle bir tablo oluşturun. POINT Coğrafi noktaları depolamak için sütun. Örneğin:
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    coordinates POINT
);

kullanarak coğrafi noktalarınızı bu tabloya ekleyin. POINT yapıcı:

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. ST_Distance Kullanarak Mesafeyi Hesaplayın: İki nokta arasındaki mesafeyi kullanarak hesaplayabilirsiniz. ST_Distance işlev. İki nokta arasındaki mesafeyi hesaplamak için örnek bir sorguyu burada bulabilirsiniz:
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;

değiştirmek 1 ve 2 Arasındaki mesafeyi hesaplamak istediğiniz iki noktanın kimlikleri ile.

  1. Sonuç: Sorgu iki nokta arasındaki mesafeyi mil cinsinden döndürecektir.

Uzamsal Veri Türlerini Kullanmak ve ST_Distance işlevi, MySQL'deki coğrafi verilerle çalışmanın daha verimli ve doğru bir yolunu sağlar. Ayrıca noktalar arasındaki mesafelerin hesaplanmasını basitleştirerek verilerinizi yönetmeyi ve sorgulamayı kolaylaştırır.

MySQL: Enlem ve Boylam Kullanarak Kilometre Olarak Mesafeyi Hesaplayarak Bir Aralık İçindeki Tüm Kayıtları Alma

Varsayılan olarak ST_Distance mesafeyi metre cinsinden döndürür, bu nedenle sorguyu kilometre cinsinden güncellemeniz yeterlidir:

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 Coğrafi Mesafesi: STDistance

Microsoft SQL Server kullanıyorsanız, kendi işlevlerini sunarlar, STMesafe Coğrafya veri türünü kullanarak iki nokta arasındaki mesafeyi hesaplamak için.

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

Kurucu ve kıdemli mimar Manash Sahoo'ya şapka ipucu İyon Üç.

Douglas Karr

Douglas Karr CMO'su AÇIK İÇGÖRÜLER ve kurucusu Martech Zone. Douglas düzinelerce başarılı MarTech startup'ına yardımcı oldu, Martech satın almaları ve yatırımlarında 5 milyar doların üzerindeki durum tespitine yardımcı oldu ve şirketlere satış ve pazarlama stratejilerini uygulama ve otomatikleştirme konusunda yardımcı olmaya devam ediyor. Douglas, uluslararası alanda tanınan bir dijital dönüşüm ve MarTech uzmanı ve konuşmacısıdır. Douglas aynı zamanda Dummie's Guide ve iş liderliği kitabının yayınlanmış yazarıdır.

İlgili Makaleler

Başa dön düğmeye
Kapanış

Adblock Algılandı

Martech Zone sitemizden reklam geliri, bağlı kuruluş bağlantıları ve sponsorluklar yoluyla para kazandığımız için size bu içeriği ücretsiz olarak sağlayabilir. Sitemizi gezerken reklam engelleyicinizi kaldırırsanız seviniriz.