Leaflet - 如何在使用图块层时保持原始坐标系统有效?

问题描述 投票:0回答:1

在我的Leaflet应用程序中,我曾经使用ImageOverlay显示背景图层。但由于图像太大而且传单处理速度变慢,我转而采用平铺方法。我使用gdal2tiles-leaflet来生成我的瓷砖。它工作正常。

但现在我的笛卡尔坐标系统(我使用Leaflet CRS Simple)投影我的背景图层并不是更有效。

这是我的图像规格:

  • 宽度:21002像素
  • 身高:14694像素
  • 分辨率:0.02(1米= 50像素)

以下是使用ImageOverlay时的图像界限:enter image description here

这是我使用TileLayer时的图像界限:enter image description here

这就是我将它们展示在一起时的样子:enter image description here

有谁知道发生了什么?

javascript leaflet gdal tiling cartesian-coordinates
1个回答
0
投票

正如@TomazicM所建议的,我调查了leaflet-rastercoords插件,它与gdal2tiles-leaflet互补。基于此,我实现了一个API,允许以栅格或笛卡尔方式转换坐标。

为此,我首先将leaflet-rastercoords代码用于单个方法:

export let loadLeafletRastercoordsPlugin = (L: any) => {
    // rastercoords.js source code
}

然后我写了一个类来处理坐标转换:

import * as L from 'leaflet';
import { loadLeafletRastercoordsPlugin } from './leaflet-rastercoords';

export class RasterCoords {

    public rc: any;
    public map: L.Map;
    public rasterWidth: number;
    public rasterHeight: number;
    public resolution: number;

    constructor(map: L.Map, rasterWidth: number, rasterHeight: number, resolution: number) {
        loadLeafletRastercoordsPlugin(L);
        this.rc = new L['RasterCoords'](map, [rasterWidth, rasterHeight]);
        this.map = map;
        this.rasterWidth = rasterWidth;
        this.rasterHeight = rasterHeight;
        this.resolution = resolution;
    }

}

使用一种方法将栅格坐标投影到我的图像的原始正交平面,基于其宽度,高度和分辨率,并通过自下而上的方式放置Y轴:

public project(coordinates: L.LatLngTuple): L.LatLngTuple {
    coordinates = this.applyResolution(coordinates);
    const projectedCoordinates = this.rc.project(
        coordinates
    );

    return this.applyCartesianProjection([projectedCoordinates.y, projectedCoordinates.x] as L.LatLngTuple);
}

private applyResolution(coordinates: L.LatLngTuple): L.LatLngTuple {
    return coordinates.map((v: number) => v * this.resolution) as L.LatLngTuple;
}

private applyCartesianProjection(coordinates: L.LatLngTuple): L.LatLngTuple {
    return [(this.rasterHeight * this.resolution) - coordinates[0], coordinates[1]];
}

并且有一种方法可以“取消项目”笛卡尔坐标(即逐点地重新处理项目方法):

public unproject(coordinates: L.LatLngTuple): L.LatLngTuple {
    coordinates = this.unapplyResolution(this.unapplyCartesianProjection(coordinates));

    return this.rc.unproject([coordinates[1], coordinates[0]]);
}

private unapplyResolution(coordinates: L.LatLngTuple): L.LatLngTuple {
    return coordinates.map((v: number) => v / this.resolution) as L.LatLngTuple;
}

private unapplyCartesianProjection(coordinates: L.LatLngTuple): L.LatLngTuple {
    return [Math.abs(coordinates[0] - (this.rasterHeight * this.resolution)), coordinates[1]];
}

然后API帮助我根据笛卡尔坐标有效地将对象添加到我的地图:

const imageWidth = 21002;
const imageHeight = 14694;
const imageResolution = 0.02;
const map = L.map('map');
const rc = new RasterCoords(map, imageWidth, imageHeight, imageResolution);
map.setView(rc.unproject([imageWidth, imageHeight]), 2);
L.tileLayer('./image/{z}/{x}/{y}.png', {
    noWrap: true
}).addTo(map);
new L.CircleMarker(this.rc.unproject([293, 420])).addTo(map);
© www.soinside.com 2019 - 2024. All rights reserved.