功能令人惊讶地改变了传单地图中的多边形坐标
function surprisingly changes polygon coords in leaflet map
我正在尝试为传单地图创建一些功能,我为每个创建的标记添加具有特定旋转的三角形。
这是创建标记和添加三角形的函数(这很好用):
function add_items_to_map( to_map, longitude, latitude, path, polygon_color, rotation_of_polygon, fov )
{
var newMarker = L.marker([latitude, longitude]).addTo( to_map );
markerGroup.addLayer( newMarker );
var b = ( 2 * Math.sin( (fov*Math.PI/180.0)/2 ) ) / 2;
var h = Math.sqrt( 1 - b*b );
// stuff to rotate triangle
var angleRad = -rotation_of_polygon * Math.PI / 180.0;
var y_ = parseFloat(latitude) + h;
var x_1 = parseFloat(longitude) - b;
var x_2 = parseFloat(longitude) + b;
var origin_point = new Array();
var pnt = new Array();
origin_point[0] = parseFloat(longitude);
origin_point[1] = parseFloat(latitude);
// rotation
pnt[0] = Math.cos(angleRad) * (origin_point[0] - origin_point[0]) - Math.sin(angleRad) * (origin_point[1] - origin_point[1]) + origin_point[0];
pnt[1] = Math.sin(angleRad) * (origin_point[0] - origin_point[0]) + Math.cos(angleRad) * (origin_point[1] - origin_point[1]) + origin_point[1];
pnt[2] = Math.cos(angleRad) * (x_1 - origin_point[0]) - Math.sin(angleRad) * (y_ - origin_point[1]) + origin_point[0];
pnt[3] = Math.sin(angleRad) * (x_1 - origin_point[0]) + Math.cos(angleRad) * (y_ - origin_point[1]) + origin_point[1];
pnt[4] = Math.cos(angleRad) * (x_2 - origin_point[0]) - Math.sin(angleRad) * (y_ - origin_point[1]) + origin_point[0];
pnt[5] = Math.sin(angleRad) * (x_2 - origin_point[0]) + Math.cos(angleRad) * (y_ - origin_point[1]) + origin_point[1];
var polygon = L.polygon(
[ [pnt[1], pnt[0]],
[pnt[3], pnt[2]],
[pnt[5], pnt[4]]
],
{
color: polygon_color
}).addTo(to_map);
polygonLayer.push( polygon );
// this function makes me trouble
// var rot_polygon = rotate_polygon( polygon.getLatLngs(), rotation_of_polygon );
}
当我这样调用函数时:add_items_to_map( map, 0, 0, path[0], 'green', 270, 90 );
一切正常,三角形旋转如下图所示:
问题出在我函数的最后一行 - var rot_polygon = rotate_polygon( polygon.getLatLngs(), rotation_of_polygon );
被调用时。
这个函数看起来像这样:
function rotate_polygon( points, angle )
{
var angleRad = angle * Math.PI / 180.0;
var origin_point = new Array();
origin_point[0] = points[0]['lng'];
origin_point[1] = points[0]['lat'];
points[0]['lat'] = Math.cos(angleRad) * (points[0]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[0]['lng'] - origin_point[1]) + origin_point[0];
points[0]['lng'] = Math.sin(angleRad) * (points[0]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[0]['lng'] - origin_point[1]) + origin_point[1];
points[1]['lat'] = Math.cos(angleRad) * (points[1]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[1]['lng'] - origin_point[1]) + origin_point[0];
points[1]['lng'] = Math.sin(angleRad) * (points[1]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[1]['lng'] - origin_point[1]) + origin_point[1];
points[2]['lat'] = Math.cos(angleRad) * (points[2]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[2]['lng'] - origin_point[1]) + origin_point[0];
points[2]['lng'] = Math.sin(angleRad) * (points[2]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[2]['lng'] - origin_point[1]) + origin_point[1];
return points;
}
这就是我调用它时发生的情况:
它修改创建的多边形中的坐标。你知道为什么吗?
如果不调试您的方法,我会说旋转经纬度点比您在这里尝试的要多。您需要旋转点而不是 latlng,并考虑地图的投影。看看这个取自 L.GeometryUtil
:
的方法
/**
Returns LatLng of rotated point around specified LatLng center.
@param {L.LatLng} latlngPoint: point to rotate
@param {double} angleDeg: angle to rotate in degrees
@param {L.LatLng} latlngCenter: center of rotation
@returns {L.LatLng} rotated point
*/
rotatePoint: function(map, latlngPoint, angleDeg, latlngCenter) {
var maxzoom = map.getMaxZoom();
if (maxzoom === Infinity)
maxzoom = map.getZoom();
var angleRad = angleDeg*Math.PI/180,
pPoint = map.project(latlngPoint, maxzoom),
pCenter = map.project(latlngCenter, maxzoom),
x2 = Math.cos(angleRad)*(pPoint.x-pCenter.x) - Math.sin(angleRad)*(pPoint.y-pCenter.y) + pCenter.x,
y2 = Math.sin(angleRad)*(pPoint.x-pCenter.x) + Math.cos(angleRad)*(pPoint.y-pCenter.y) + pCenter.y;
return map.unproject(new L.Point(x2,y2), maxzoom);
}
https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/dist/leaflet.geometryutil.js#L483
多边形用法示例:
var polygon = new L.Polygon([[[-45,-45],[-45,45],[45,45],[45,-45]]]).addTo(map),
latLngs = polygon.getLatLngs(),
bounds = polygon.getBounds(),
center = bounds.getCenter(),
newLatLngs = [],
angle = 45;
latLngs.forEach(function (latLng) {
newLatLngs.push(L.GeometryUtil.rotatePoint(map, latLng, angle, center));
});
polygon.setLatLngs(newLatLngs);
Plunker 上的工作示例:http://plnkr.co/edit/5j7jFgJcNcTP9IjUo9ou?p=preview
如果您考虑到这一点并将您的方法重写为 separate/create 旋转单个经纬度的方法,您将不会遇到当前遇到的问题。希望有所帮助。祝你好运!
我正在尝试为传单地图创建一些功能,我为每个创建的标记添加具有特定旋转的三角形。
这是创建标记和添加三角形的函数(这很好用):
function add_items_to_map( to_map, longitude, latitude, path, polygon_color, rotation_of_polygon, fov )
{
var newMarker = L.marker([latitude, longitude]).addTo( to_map );
markerGroup.addLayer( newMarker );
var b = ( 2 * Math.sin( (fov*Math.PI/180.0)/2 ) ) / 2;
var h = Math.sqrt( 1 - b*b );
// stuff to rotate triangle
var angleRad = -rotation_of_polygon * Math.PI / 180.0;
var y_ = parseFloat(latitude) + h;
var x_1 = parseFloat(longitude) - b;
var x_2 = parseFloat(longitude) + b;
var origin_point = new Array();
var pnt = new Array();
origin_point[0] = parseFloat(longitude);
origin_point[1] = parseFloat(latitude);
// rotation
pnt[0] = Math.cos(angleRad) * (origin_point[0] - origin_point[0]) - Math.sin(angleRad) * (origin_point[1] - origin_point[1]) + origin_point[0];
pnt[1] = Math.sin(angleRad) * (origin_point[0] - origin_point[0]) + Math.cos(angleRad) * (origin_point[1] - origin_point[1]) + origin_point[1];
pnt[2] = Math.cos(angleRad) * (x_1 - origin_point[0]) - Math.sin(angleRad) * (y_ - origin_point[1]) + origin_point[0];
pnt[3] = Math.sin(angleRad) * (x_1 - origin_point[0]) + Math.cos(angleRad) * (y_ - origin_point[1]) + origin_point[1];
pnt[4] = Math.cos(angleRad) * (x_2 - origin_point[0]) - Math.sin(angleRad) * (y_ - origin_point[1]) + origin_point[0];
pnt[5] = Math.sin(angleRad) * (x_2 - origin_point[0]) + Math.cos(angleRad) * (y_ - origin_point[1]) + origin_point[1];
var polygon = L.polygon(
[ [pnt[1], pnt[0]],
[pnt[3], pnt[2]],
[pnt[5], pnt[4]]
],
{
color: polygon_color
}).addTo(to_map);
polygonLayer.push( polygon );
// this function makes me trouble
// var rot_polygon = rotate_polygon( polygon.getLatLngs(), rotation_of_polygon );
}
当我这样调用函数时:add_items_to_map( map, 0, 0, path[0], 'green', 270, 90 );
一切正常,三角形旋转如下图所示:
问题出在我函数的最后一行 - var rot_polygon = rotate_polygon( polygon.getLatLngs(), rotation_of_polygon );
被调用时。
这个函数看起来像这样:
function rotate_polygon( points, angle )
{
var angleRad = angle * Math.PI / 180.0;
var origin_point = new Array();
origin_point[0] = points[0]['lng'];
origin_point[1] = points[0]['lat'];
points[0]['lat'] = Math.cos(angleRad) * (points[0]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[0]['lng'] - origin_point[1]) + origin_point[0];
points[0]['lng'] = Math.sin(angleRad) * (points[0]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[0]['lng'] - origin_point[1]) + origin_point[1];
points[1]['lat'] = Math.cos(angleRad) * (points[1]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[1]['lng'] - origin_point[1]) + origin_point[0];
points[1]['lng'] = Math.sin(angleRad) * (points[1]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[1]['lng'] - origin_point[1]) + origin_point[1];
points[2]['lat'] = Math.cos(angleRad) * (points[2]['lat'] - origin_point[0]) - Math.sin(angleRad) * (points[2]['lng'] - origin_point[1]) + origin_point[0];
points[2]['lng'] = Math.sin(angleRad) * (points[2]['lat'] - origin_point[0]) + Math.cos(angleRad) * (points[2]['lng'] - origin_point[1]) + origin_point[1];
return points;
}
这就是我调用它时发生的情况:
它修改创建的多边形中的坐标。你知道为什么吗?
如果不调试您的方法,我会说旋转经纬度点比您在这里尝试的要多。您需要旋转点而不是 latlng,并考虑地图的投影。看看这个取自 L.GeometryUtil
:
/**
Returns LatLng of rotated point around specified LatLng center.
@param {L.LatLng} latlngPoint: point to rotate
@param {double} angleDeg: angle to rotate in degrees
@param {L.LatLng} latlngCenter: center of rotation
@returns {L.LatLng} rotated point
*/
rotatePoint: function(map, latlngPoint, angleDeg, latlngCenter) {
var maxzoom = map.getMaxZoom();
if (maxzoom === Infinity)
maxzoom = map.getZoom();
var angleRad = angleDeg*Math.PI/180,
pPoint = map.project(latlngPoint, maxzoom),
pCenter = map.project(latlngCenter, maxzoom),
x2 = Math.cos(angleRad)*(pPoint.x-pCenter.x) - Math.sin(angleRad)*(pPoint.y-pCenter.y) + pCenter.x,
y2 = Math.sin(angleRad)*(pPoint.x-pCenter.x) + Math.cos(angleRad)*(pPoint.y-pCenter.y) + pCenter.y;
return map.unproject(new L.Point(x2,y2), maxzoom);
}
https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/dist/leaflet.geometryutil.js#L483
多边形用法示例:
var polygon = new L.Polygon([[[-45,-45],[-45,45],[45,45],[45,-45]]]).addTo(map),
latLngs = polygon.getLatLngs(),
bounds = polygon.getBounds(),
center = bounds.getCenter(),
newLatLngs = [],
angle = 45;
latLngs.forEach(function (latLng) {
newLatLngs.push(L.GeometryUtil.rotatePoint(map, latLng, angle, center));
});
polygon.setLatLngs(newLatLngs);
Plunker 上的工作示例:http://plnkr.co/edit/5j7jFgJcNcTP9IjUo9ou?p=preview
如果您考虑到这一点并将您的方法重写为 separate/create 旋转单个经纬度的方法,您将不会遇到当前遇到的问题。希望有所帮助。祝你好运!