функция неожиданно меняет координаты полигона на карте буклета

Я пытаюсь создать некоторую функциональность для карты листовок, к каждому созданному маркеру я добавляю треугольник с определенным поворотом.
Это функция для создания маркера и добавления треугольника (это работает хорошо):

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 ); все работает хорошо, треугольник поворачивается, как на этом рисунке:

‹a href=http://oi63.tinypic.com/29maskz.jpg›Здесь‹/a›

Проблема в том, когда вызывается эта последняя строка - 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;
}  

Вот что происходит, когда я это называю: ‹a href=http://oi63.tinypic.com/29maskz.jpg›Здесь‹/a›

Изменяет координаты в созданном полигоне. У вас есть идеи, почему?


person Petr Bečka    schedule 12.02.2016    source источник


Ответы (1)


Без отладки вашего метода я бы сказал, что вращение точки широты - это нечто большее, чем то, что вы здесь пытаетесь. Вам нужно будет повернуть точку вместо широты и принять во внимание проекцию карты. Взгляните на этот метод, взятый из 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

Если вы примете это во внимание и перепишете свой метод, чтобы отделить/создать метод для вращения отдельных latlngs, у вас не будет проблемы, с которой вы сейчас сталкиваетесь. Надеюсь, это поможет. Удачи!

person iH8    schedule 13.02.2016
comment
Спасибо за ответ, круто!! - person Petr Bečka; 13.02.2016