检查lat / long是否在Nokia HERE Map多边形内

时间:2014-01-15 13:31:32

标签: javascript here-api

有没有办法确定纬度/经度是否在 nokia.maps.map.Polygon 中?

我可以使用 nokiaMap.getObjectsAt 方法来检查给定地图像素位置下是否有多边形,但这对纬度和经度没有帮助。

有一种方法 nokiaMap.geoToPixel ,我想用它来获取像素位置,然后调用 nokiaMap.getObjectsAt ,但文档说明“结果可见地图区域之外的值可能非常不可靠“我已经看到了这种情况,所以不能使用这种方法。

nokiaMap.geoToPixel文档 http://developer.here.com/docs/maps_js/topics_api_pub/nokia.maps.map.Display.html#topic-apiref__Display-geoToPixel-method

2 个答案:

答案 0 :(得分:2)

这需要从计算几何中实现point in polygon算法。下面是一个例子:

nokia.maps.map.Polygon.prototype.containsCoordinate = function(arg) {
    var latitude, longitude;

    if (arg instanceof  nokia.maps.geo.Coordinate){
      latitude = arg.latitude;
      longitude = arg.longitude;
    } else if (arg instanceof Array && arg.length === 2 && !isNaN(arg[0]) && !isNaN(arg[1])){
      latitude = arg[0];
      longitude = arg[1];
    }

    // Fail fast if not in the bounding box - don't bother with Ray Cast method
    if (!poly.getBoundingBox().contains(
      nokia.maps.geo.BoundingBox.coverAll(
        [new nokia.maps.geo.Coordinate(latitude, longitude)]))){
      return false;
    }

    var inPoly = false,
      path = this.path,
      numPoints = path.getLength(),
      j = numPoints-1;

      for(var i=0; i < numPoints; i++) {
      var vertex1 = path.getLatLng(i),
        vertex2 = path.getLatLng(j);

        if (vertex1[1] < longitude && vertex2[1] >= longitude ||
          vertex2[1] < longitude && vertex1[1] >= longitude) {
          if (vertex1[0] + (longitude - vertex1[1]) / (vertex2[1] - vertex1[1]) 
             * (vertex2[0] - vertex1[0]) < latitude) {
            inPoly = !inPoly;
          }
        }
        j = i;
      }
    return inPoly;
  };

您可以使用Coordinate或一对数字来呼叫它。 e.g:

poly.containsCoordinate(coordinate)

Working Example

答案 1 :(得分:1)

我编写了一个PL / SQL程序,它使用Ray cast算法来计算该点是否为多边形。多边形的顶点数量没有限制。在这里,顶点的经度和纬度以及要检查的点以十进制分钟格式提交并且是管道分离的。

create or replace function PIP(verLong in varchar2,
                               verLat  in varchar2,
                               xLong   in number,
                               yLat    in number) return boolean

 is

  i number := 0;

  j number := 0;

  c boolean := false;

  tempLong number;

  tempLat number;

  latDegree number;

  minLength number;

  pi NUMBER := 3.1415926;

  x number := xLong;

  y number := yLat;

  TYPE coodArray IS TABLE OF VARCHAR2(1000) INDEX BY BINARY_INTEGER;

  longArray coodArray;

  latArray coodArray;

begin

  --Convert reference point in meters

  --Round number to 4 places

  x := round(x, 4);

  y := round(y, 4);

  --convert latitude to degrees

  latDegree := y / 60;

  --convert latitude from degrees to radians

  latDegree := (latDegree * pi) / 180;

  --compute minute or arc in meters given the latitude value

  minLength := 1852.3 - (9.4 * Cos(2 * latDegree));

  --Multiply the latitude and longitude pair with the length factor to get co-ordinates in meters

  x := x * minLength;

  y := y * minLength;

  loop

    --Retrieve the longitudes and latitudes from the string of latitudes or longitudes

    tempLong := to_number(get_token(verLong, i + 1, '|'));

    tempLat := to_number(get_token(verLat, i + 1, '|'));

    i := i + 1;

    if (tempLong is null) then

      exit;

    end if;

    --Round the numbers upto four decimals

    tempLong := round(tempLong, 4);

    tempLat := round(tempLat, 4);

    --convert latitude to degrees

    latDegree := tempLat / 60;

    --convert latitude from degrees to radians

    latDegree := (latDegree * pi) / 180;

    --compute the minute of an arc in meters given the latitude value

    minLength := 1852.3 - (9.4 * Cos(2 * latDegree));

    --Multiply the latitude and longitude pair with the length factor to get co-ordinates in meters

    tempLong := tempLong * minLength;

    tempLat := tempLat * minLength;

    longArray(i) := tempLong;

    latArray(i) := tempLat;

  end Loop;

  j := latArray.COUNT;

  --Check whether the point lies inside the polygon formed by the vertices (Ray casting algorithm)

  for i in 1 .. j loop

    if (((latArray(i) > y) != (latArray(j) > y)) and
       (x < (Longarray(j) - Longarray(i)) * (y - Latarray(i)) /
       (latarray(j) - Latarray(i)) + longarray(i))) then

      c := not c;

    end if;

    j := i;

  end loop;

  return c;

end PIP;

谢谢, Noorul