javascript - Leaflet - 使用平铺层时如何保持原始坐标系有效?
问题描述
在我的 Leaflet 应用程序中,我曾经使用 ImageOverlay 显示背景层。但是由于图像太大并且会减慢 Leaflet 处理速度,我改用平铺方法。我使用gdal2tiles-leaflet来生成我的图块。它工作得很好。
但是现在我的笛卡尔坐标系在其中投影了我的背景层(我使用 Leaflet CRS Simple),不再有效。
这是我的图像规格:
- 宽度:21002 像素
- 高度:14694 像素
- 分辨率:0.02(1 米 = 50 像素)
有谁知道发生了什么?
解决方案
正如@TomazicM 所建议的,我研究了与gdal2tiles-leaflet互补的leaflet-rastercoords插件。基于它,我实现了一个 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);
推荐阅读
- ionic4 - Ionic4 cordova-plugin-mobile-ocr 如何设置静态文件的正确路径
- react-native - 如何删除到达导航 5.x 警告
- mysql - 我可以在 mysql 查询中获取聚合字段的唯一值,该查询将 group by 用于另一个字段
- selenium - 如何通过 C# 使用 Selenium 解决“OpenQA.Selenium.WebDriverException:目标框架分离”
- vue.js - Vue/Nuxt JS 没有重复的属性
- node.js - 如何使用 node.js 在 Firebase Cloud Firestore 中添加 sendgrid webhook 事件 Json 响应
- python - 如何将包含“$ -”、“字符”的 Panda 字符串转换为浮点数
- python - 如何从重复的观察中创建新列并在 Pandas DataFrame 中使用 Python 转置相关数据?
- scala - 案例类方法与 Spark 和 Scala 中伴随对象的效率
- javascript - Internet Explorer 兼容性?每个函数的 Javascript