如何解决从Leaflet.js映射手动写入世界文件jgw
我需要从客户端的Leaflet.js导出地理参考图像。从Leaflet导出图像不是问题,因为有很多现有的插件,但是我想在导出中包含一个world file,以便可以将生成的图像读入GIS软件。我有一个工作脚本要塞他,但我似乎无法为我的世界文件确定正确的参数,以使生成的地理参考图像定位正确。
这是我当前的脚本
// map is a Leaflet map object
let bounds = map.getBounds(); // Leaflet LatLngBounds
let topLeft = bounds.getNorthWest();
let bottomRight = bounds.getSouthEast();
let width_deg = bottomRight.lng - topLeft.lng;
let height_deg = topLeft.lat - bottomRight.lat;
let width_px = $(map._container).width() // Width of the map in px
let height_px = $(map._container).height() // Height of the map in px
let scaleX = width_deg / width_px;
let scaleY = height_deg / height_px;
let jgwText = `${scaleX}
0
0
-${scaleY}
${topLeft.lng}
${topLeft.lat}`
这似乎在大比例下效果很好(即放大到城市级别左右),但是在小比例下,y轴上会出现一些失真。我注意到的一件事是,我可以找到的所有世界文件示例(以及从QGIS或ArcMap生成的世界文件示例)都具有完全相同的x比例和y比例参数(带正负号)。在我的计算中,除非您正坐在赤道上,否则这些术语是不同的。
从QGIS生成的示例世界文件
0.08984380916303301 // x-scale (size of px in x direction) 0 // rotation parameter 1 0 // rotation parameter 2 -0.08984380916303301 // y-scale (size of px in y direction) -130.8723208723141056 // x-coord of top left px 51.73651369984968085 // y-coord of top left px
根据我的计算产生的示例世界文件
0.021972656250000017 0 0 -0.015362443783773333 -130.91308593750003 51.781435604431195
使用我的计算并覆盖正确的状态边界生成的图像示例:
有人知道我在做什么错吗?
解决方法
问题使用世界文件使用EPSG:3857解决,并确保在此坐标系中也测量了地图边界的宽度和高度。我曾尝试将EPSG:3857用于世界文件,但使用Leaflet的L.map.distance()函数测量了地图边界的宽度和高度。为了解决该问题,我改用L.CRS.EPSG3857.project()将地图边界的角点投影到EPSG:3857,只需减去X,Y值即可。
下面显示了正确的代码,其中map是Leaflet地图对象(L.map)
// Get map bounds and corner points in 4326
let bounds = map.getBounds();
let topLeft = bounds.getNorthWest();
let bottomRight = bounds.getSouthEast();
let topRight = bounds.getNorthEast();
// get width and height in px of the map container
let width_px = $(map._container).width()
let height_px = $(map._container).height()
// project corner points to 3857
let topLeft_3857 = L.CRS.EPSG3857.project(topLeft)
let topRight_3857 = L.CRS.EPSG3857.project(topRight)
let bottomRight_3857 = L.CRS.EPSG3857.project(bottomRight)
// calculate width and height in meters using epsg:3857
let width_m = topRight_3857.x - topLeft_3857.x
let height_m = topRight_3857.y - bottomRight_3857.y
// calculate the scale in x and y directions in meters (this is the width and height of a single pixel in the output image)
let scaleX_m = width_m / width_px
let scaleY_m = height_m / height_px
// worldfiles need the CENTRE of the top left px,what we currently have is the TOPLEFT point of the px.
// Adjust by subtracting half a pixel width and height from the x,y
let topLeftCenterPxX = topLeft_3857.x - (scaleX / 2)
let topLeftCenterPxY = topLeft_3857.y - (scaleY / 2)
// format the text of the worldfile
let jgwText = `
${scaleX_m}
0
0
-${scaleY_m}
${topLeftCenterPxX}
${topLeftCenterPxY}
`
对于任何其他有此问题的人,只要您的scale-x和scale-y值完全相等(但符号相反),您就会知道事情是正确的!
感谢@IvanSanchez指出正确的方向:)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。