Leaflet.js上的自定义坐标和轴范围

时间:2018-07-21 16:03:46

标签: d3.js leaflet

我有一个尺寸(以像素为单位)为16384 x 12288的光栅图像,该图像已在传单中成功渲染。我正在使用自己的CRS,并且使用选项transformation: new L.Transformation(1 / 64, 0, -1 / 64, 256)将点(0,0)放置在图像点(16384,12288)的右下角。

但是,我图像的轴的范围是x:[6150,1370]和y:[12987,18457]

我如何告诉传单将范围用作坐标系?因此,位置(6150,12987)处的标记将对应并显示在左下角:(0,0)。我已使用以下功能手动完成此操作:

var grid = {x0: 6150, // range of plot in Matlab
            x1: 13751,
            y0: 12987,
            y1: 18457};  

var img = [16384, 
           12288];

function project(p, img, grid) {
            var x = p[0],
                y = p[1];
            xx = img[0] / (grid.x1 - grid.x0) * (x - grid.x0);
            yy = img[1] / (grid.y1 - grid.y0) * (y - grid.y0);

            return [xx, yy]
        }

但是,我想知道必须有一种更精简,更好的方法来做到这一点。我的代码是:

    var yx = L.latLng;

    var xy = function(x, y) {
        if (L.Util.isArray(x)) { // When doing xy([x, y]);
            return yx(x[1], x[0]);
        }
        return yx(y, x); // When doing xy(x, y);
    };

    var img = [
        16384, // original width of image 
        12288 // original height of image 
    ];

    L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
        transformation: new L.Transformation(1 / 64, 0, -1 / 64, 256),
    });

    var bounds = L.latLngBounds([
        xy(0, 0),
        xy(img)
    ]);

    var map = L.map('map', {
        crs: L.CRS.MySimple,
        maxBounds: bounds.pad(.5),
    }).setView([img[1] / 2, img[0] / 2], 0);


    L.tileLayer('myImage/{z}/{x}/{y}.png', {
        bounds: bounds,
        minZoom: 1,
        maxZoom: 6
    }).addTo(map);

    L.marker([0, 0]).addTo(map).bindPopup("Zero");
    L.marker([img[1] / 2, img[0] / 2]).addTo(map).bindPopup("[img[1] / 2, img[0] / 2]");
    L.marker([img[1], img[0]]).addTo(map).bindPopup("img");

1 个答案:

答案 0 :(得分:0)

我认为我取得了一些进展。如果将来有人遇到类似的情况,这是我的代码:(评论多于欢迎)

        var yx = L.latLng;

    var xy = function(x, y) {
        if (L.Util.isArray(x)) { // When doing xy([x, y]);
            return yx(x[1], x[0]);
        }
        return yx(y, x); // When doing xy(x, y);
    };

    var img = [
        16384, // original width of image
        12288 // original height of image
    ];

    var mapSW = [0, 16384],
        mapNE = [12288, 0];

    var roi = { //range of interest
        x0: 6150,
        x1: 13751,
        y0: 12987,
        y1: 18457
    };

    a = img[0] / (roi.x1 - roi.x0)
    b = -img[0] / (roi.x1 - roi.x0) * roi.x0
    c = img[1] / (roi.y1 - roi.y0)
    d = -img[1] / (roi.y1 - roi.y0) * roi.y0

    // This transformation maps a point in pixel dimensions to our user defined roi
    var t = new L.Transformation(a, b, c, d);

    // The transformation in this CRS maps the the bottom right corner to (0,0) and the topleft to (256, 256)
    L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
        transformation: new L.Transformation(1 / 64, 0, -1 / 64, 256),
    });

    var bounds = L.latLngBounds([
        xy(0, 0),
        xy(img)
    ]);

    var map = L.map('map', {
        crs: L.CRS.MySimple,
        maxBounds: bounds.pad(.5),
    }).setView([img[1] / 2, img[0] / 2], 0);


    L.tileLayer('map/{z}/{x}/{y}.png', {
        bounds: bounds,
        minZoom: 1,
        maxZoom: 6,
    }).addTo(map);

    //        map.setMaxBounds(new L.LatLngBounds(
    //            map.unproject(mapSW, map.getMaxZoom()),
    //            map.unproject(mapNE, map.getMaxZoom()),
    //        ));



    L.marker([0, 0]).addTo(map).bindPopup("Zero");
    L.marker([img[1] / 2, img[0] / 2]).addTo(map).bindPopup("[img[1] / 2, img[0] / 2]");
    L.marker([img[1], img[0]]).addTo(map).bindPopup("img");

    var marker = L.marker(xy([10000, 0]), {
        draggable: true
    }).addTo(map);
    marker.bindPopup("");

    marker.on("dragend", function(e) {
        m = marker.getLatLng();
        proj = map.project(m, map.getMaxZoom());
        marker.getPopup().setContent('Clicked ' +m.toString() + '<br />' +
                'Pixels ' + proj.toString())
            .openOn(map);
    })

    L.control.scale({
        imperial: false
    }).addTo(map);

    var popup = L.popup();

    function onMapClick(e) {
        popup
            .setLatLng(e.latlng)
            .setContent("You clicked the map at " + e.latlng.toString())
            .openOn(map);
    }

    map.on('click', onMapClick);


    var p = t.transform(L.point(roi.x1, roi.y1));
    L.circleMarker(xy([p.x, p.y])).addTo(map);

    p = t.transform(L.point(10000, 12987));
    L.circleMarker(xy([p.x, p.y])).addTo(map);

    p = t.transform(L.point(13000, 12987));
    L.circleMarker(xy([p.x, p.y])).addTo(map);

    p = t.transform(L.point(6150, 18000));
    L.circleMarker(xy([p.x, p.y])).addTo(map);