有没有办法确定纬度/经度是否在 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
答案 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)
答案 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