Как выровнять захват изображения на карте Leaflet с границами карты? - PullRequest
0 голосов
/ 13 июля 2020

Я работаю над проектом, в котором я делаю снимок экрана карты (используя библиотеку dom-to-image ) и отправляю его внешнему API, который возвращает некоторые координаты (x, y , w, h) после обработки отправленного изображения. Эти координаты (прямоугольники) я пытаюсь нарисовать на листовке.

Поскольку размер захваченного изображения больше, чем ширина и высота захваченной области (не знаю почему) , Мне нужно масштабировать координаты.

Теперь проблема в том, что прямоугольники Leaflet не отображают точную позицию, которую возвращает внешний API.

Однако я уверен, что внешний API возвращает правильные координаты (x, y, w, h) относительно ширины и высоты отправленного изображения.

Что-то не так, что я делаю с масштабированием координат.

Ниже приведен фрагмент кода, который я пытаюсь выполнить:

domtoimage.toPng(document.querySelector("#map"))
    .then(function (dataUrl) {
        var boundsOnly = map.getBounds(); 
        let topLeft = boundsOnly.getNorthWest();
        let topRight = boundsOnly.getNorthEast();
        let bottomLeft = boundsOnly.getSouthWest();
        let bottomRight = boundsOnly.getSouthEast();
                
        var currBBOXpoints = { x1y1: map.latLngToLayerPoint(topLeft), 
                            x2y2: map.latLngToLayerPoint(topRight),
                            x3y3: map.latLngToLayerPoint(bottomRight),
                            x4y4: map.latLngToLayerPoint(bottomLeft) };
                            
        var pW = currBBOXpoints.x2y2.x - currBBOXpoints.x1y1.x;
        var pH = currBBOXpoints.x3y3.y - currBBOXpoints.x1y1.y;
        
        currBBOXpoints.pW = pW; //calculated the width of captured area
        currBBOXpoints.pH = pH; //calculated the height of captured area
        
        var i = new Image();
        i.onload = function () { //calculating captured image's actual width, height

            $.ajax({
                type: 'post',
                url: '/externalapi',
                data: JSON.stringify(dataUrl),
                contentType: "application/json",
                dataType: "json",
                success: function (resultData) {
                    resultData["iW"] = i.width; //captured image width 
                    resultData["iH"] = i.height; //captured image height
                    resultData["currBBOXpoints"] = currBBOXpoints; //captured area bounds
                    drawRects(resultData);
                    //NOTE: Captured image's width and height are bigger than width and height of captured area (don't know why)
                }
            });
    };
    i.src = dataUrl;
});

function drawRects(rectData) {

    var scale = Math.max(rectData.currBBOXpoints.pW / rectData['iW'], rectData.currBBOXpoints.pH / rectData['iH']);
    
    var shifted_x = rectData.currBBOXpoints.pW / 2 - rectData['iW'] / 2 * scale;
    var shifted_y = rectData.currBBOXpoints.pH / 2 - rectData['iH'] / 2 * scale;

    rectData.od.forEach(rc => {
        var modifiedX = Number(rc['x']) * scale + shifted_x;
        var modifiedY = Number(rc['y']) * scale + shifted_y; 
        var modifiedW = (modifiedX + rc['w'])
        var modifiedH = (modifiedY + rc['h'])


        let point3 = map.layerPointToLatLng(L.point(modifiedX, modifiedY));
        let point4 = map.layerPointToLatLng(L.point(modifiedW, modifiedH));
        
        var rectBounds = [[point3.lat, point3.lng], [point4.lat, point4.lng]];
        var boundingBox = L.rectangle(rectBounds, { color: "yellow", weight: 1, name: "rect", fillOpacity: 0.10 });
        
        map.addLayer(boundingBox);

    });
}

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

Это проблема XY (которую вы успешно определили: размер захвата не равен размеру контейнера карты), поэтому давайте вместо этого исправим проблему root.

Похоже, что dom-to-image выравнивает верхний левый угол захвата, но также учитывает размер любых переполненных элементов (например, частично видимых фрагментов карты в юго-восточном углу) при вычислении размер захвата:

capture comparison

(This can be proven by playing a bit with the browser's инспектор модели коробки , сравнивая положение и размер самой юго-восточной плитки с размером захвата)

Поскольку захват с выравниванием по левому верхнему краю, вы можете просто обрезать захват по размеру холста карты.

Вы можете использовать параметры width и height для dom-to-image вместе с getSize метод L.Map для принудительной обрезки захваченного изображения до размеров холста карты, например:

    domtoimage.toPng(document.querySelector("#leaflet"), {
        width: map.getSize().x,
        height: map.getSize().y
    })

См. рабочую демонстрацию .

0 голосов
/ 13 июля 2020

Я не могу сказать, почему, но когда вы устанавливаете масштаб на 0,9 после определения x и y, он идеально подходит.

var scale = Math.max(currBBOXpoints.pW / imagesize.width, currBBOXpoints.pH / imagesize.height);

var x = currBBOXpoints.pW / 2 - imagesize.width / 2 * scale;
var y = currBBOXpoints.pH / 2 - imagesize.height / 2 * scale;
scale = 0.9

Также вы должны установить в скрипке css ширина и высота:

#mapWrapper{
  padding: 10px;
  margin: 10px;
  width: 1744px;
  height: 854px;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...