2015-10-15 96 views

回答

0

你可以通過你所有的邊圈和計算這樣兩個點之間的距離:我希望這對你的作品,這是「簡單的」矢量數學

function double calculateDistance(
    double edgeLat1, double edgeLng1, 
    double edgeLat2, double edgeLng2, 
    double pointLat, double pointLng) { 

    //calculate straight/edge 
    double mS = (edgeLng2 - edgeLng1)/(edgeLat2- edgeLat2); 
    double tS = edgeLng1 - edgeLng1 * mS; 

    //calculate helper straight 
    double mH = -mS; 
    double tH = pointLng - mH * pointLat; 

    //calcuate straight intersection 
    xI = (tH - tS)/(mS - mH); 
    yI = mH * xI - tH; 

    //calculate distance 
    /* in degree 
    double dInDegree = Math.sqrt((pointLat - xI) * (pointLat - xI) 
          + (pointLng - yI) * (pointLng - yI)); 

    return dInDegree; 
    */ 
    //in meter 
    double R = 6371000; // m 
    double dLat = (pointLat-xI).toRad(); 
    double dLon = (pointLng-yI).toRad(); 
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
    Math.cos(x1.toRad()) * Math.cos(pointLat.toRad()) * 
    Math.sin(dLon/2) * Math.sin(dLon/2); 
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    double distanceInMeter = R * c; 
    return distanceInMeter; 
} 

+0

這找到最近的角落,而不是最近的邊緣。如果提問者關心固定單位的距離(例如公里/英里)而不是緯度/經度,這也可能是錯誤的。 – Sbodd

+0

對不起,花了這麼長時間,但我沒有能夠做到這一點。在我的第一個答案之前,我無法閱讀;)現在它應該適合你! –

0

檢查單個單獨緯度/長度,查找列表中存在的最近座標。

然後收集連接到該座標的兩個點(離您的單點最近的那個點)所以現在您有4個點。

singlePoint,closestPointToSinglePoint,neighbor1,neighbor2。我假設你在這一點上有一些基本的觸發經驗(沒有雙關意圖)。你應該從這裏做什麼是可視化2個三角形。 (singlePoint,closestPointToSinglePoint,neighbor1)和(singlePoint,closestPointToSinglePoint,neighbor2)。

此時,計算單點的三角形高度作爲參考。你現在有2個距離到2個最近的邊緣。比較,並享受您的結果。

+0

爲了便於說明,請使用Edge(Neighbor#和closestPointToSinglePoint之間的邊)作爲計算的基礎。 Area = 1/2 Base *高度。所以對於高度= h = 2 * A/b – Lencalot

1

我建議下面的解決方案,它也適用於圍繞北極的多邊形,其中經度和緯度差異的計算沒有意義。

該解決方案通過使用World Geodetic System 84將地球上各點的經緯度轉換爲三維座標。使用這些三維點,您可以計算三維空間中由另外兩個點定義的線上一點的投影。

這是執行計算的代碼。它使用類javafx.geometry.Point3D,提供的Java 8

/** Semi-major axis of earth in meter */ 
public static final double WGS84_A = 6378137.0; 

/** Semi-minor axis of earth in meter */ 
public static final double WGS84_B = 6356752.314245; 

/** Eccentricity of earth */ 
public static final double WGS84_E = 
     Math.sqrt((WGS84_A * WGS84_A)/(WGS84_B * WGS84_B) - 1); 

public static final double DEGREES_TO_RADIANS = Math.PI/180; 

/** 
* Calculates a three-dimensional point in the 
* World Geodetic System (WGS84) from latitude and longitude. 
*/ 
public static Point3D latLonToPoint3D(double lat, double lon) { 
    double clat = Math.cos(lat * DEGREES_TO_RADIANS); 
    double slat = Math.sin(lat * DEGREES_TO_RADIANS); 
    double clon = Math.cos(lon * DEGREES_TO_RADIANS); 
    double slon = Math.sin(lon * DEGREES_TO_RADIANS); 

    double N = WGS84_A/Math.sqrt(1.0 - WGS84_E * WGS84_E * slat * slat); 

    double x = N * clat * clon; 
    double y = N * clat * slon; 
    double z = N * (1.0 - WGS84_E * WGS84_E) * slat; 
    return new Point3D(x, y, z); 
} 

/** 
* Calculates distance of projection p of vector a on vector b. 
* 
* Use formula for projection, with p being the projection point: 
* <p> 
* p = a X b/|b|^2 * b 
* </p> 
* X being the dot product, * being multiplication of vector and constant 
*/ 
public static Point3D calculateProjection(Point3D a, Point3D b) { 
    return b.multiply(a.dotProduct(b)/(b.dotProduct(b))); 
} 

/** 
* Calculates shortest distance of vector x and the line defined by 
* the vectors a and b. 
*/ 
public static double calculateDistanceToLine(Point3D x, Point3D a, Point3D b) { 
    Point3D projectionOntoLine = 
      calculateProjection(x.subtract(a), b.subtract(a)).add(a); 
    return projectionOntoLine.distance(x); 
} 

通過調用calculateDistanceToLine用點和多邊形細分點,你能夠找到的邊緣點定義和擴展到無窮遠最近的線路。如果是凹多邊形,這可能不是你想要的,就像你在圖片中看到的那樣。

A concave polygon where the next edge (orange) is not the line with the nearest projection point.

考慮到多邊形邊緣的距離必須至少只要到最近的邊緣點的距離,你可以得到的距離邊緣爲:

Math.max(calculateDistanceToLine(x, edgePoint1, edgePoint2), 
    Math.min(x.distance(edgePoint1), x.distance(edgePoint2))); 

注意,這個計算結果也不是地球表面的距離,而是直接穿過地球的距離。無論如何,它應該足以選擇最短的距離。

函數latLonToPoint3D是我找到的函數的修改版本here