简短版本:如何将SVG路径添加到Leaflet Map ,以便在 Map 坐标更改时路径将更新(例如,在缩放更改或幻灯片上)?
长版:你好,我有一个包含建筑轮廓的地形image . 在对图像进行地理校正后,我使用Photoshop将栅格数据转换为SVG . 我知道描述SVG边界的边界框的地理坐标,并知道SVG路径元素的内部坐标 . 我想知道现在将SVG的路径元素中描述的建筑物添加到Leaflet Map 的最佳方法 .
这是一个小提琴,显示红色的SVG图像的边界框和蓝色的建筑物:http://jsfiddle.net/duhaime/4vL925Lj/正如您所看到的,建筑物相对于边界框尚未正确定向 .
我最初计划对齐建筑物是使用一次性脚本将路径元素从SVG坐标系转换为lat,long坐标,然后使用我用于绘制边界框的折线函数在 Map 上绘制建筑物:
var polyline = L.polyline(
[upperLeft, upperRight, lowerRight, lowerLeft, upperLeft],
{color: 'red', className: 'bounding-box', weight: 2}
).addTo(map);
这种方法的问题在于Leaflet折线无法绘制Bezier曲线,这些曲线存在于上面的SVG路径元素中 . 作为一种解决方法,我认为我可以对贝塞尔曲线使用线性近似,尽管这可能会成为一个相当大的工作量 .
最后我意识到上面小提琴中的边界框的SVG使用贝塞尔曲线,这让我想到我可能会使用矩阵变换将构建SVG的坐标空间转换到Leaflet坐标空间 . 上面的小提琴使用样本矩阵变换css规则来变换建筑物层 .
在深入了解这个兔子洞之前,我想问一下:其他人认为最好的方法是将上述SVG中的建筑物的路径添加到小提琴中的Leaflet Map 中?我将非常感谢其他人可以就此问题提供的任何建议!
PROGRESS: 我决定简化这个问题并弄清楚如何使用矩阵变换将一个div("A")转换为另一个div的纵横比("B") . 在这样做时,我做了一个小的Python script,它将输入div A 's pixel coordinates and the desired output div B'的像素坐标作为输入 . 该脚本生成变换矩阵X,使得AX = B.该脚本在内部记录并附带fiddle .
我还创建了一个gist,它导出变换矩阵,将SVG空间中的点投射到适当的lat,lng coords中 . 最糟糕的情况是,我可以对SVG路径元素进行分区,使用变换矩阵获取每个点的点积,并使用传单绘制折线以绘制建筑物 . 那将失去Bezier曲线......
3 回答
这需要相当多的思考,但我找到了解决方案 .
在阅读之后,我意识到可以通过识别变换矩阵,然后通过乘以输入空间中的每个点,将点从一个坐标空间(例如SVG坐标空间)转换到另一个(例如,纬度/长坐标空间)( SVG)通过该变换矩阵 . 此操作会将给定点转置到 Map 中的适当位置 .
我写了this script来计算所需的变换矩阵 . 该脚本将SVG的边界框坐标和从中提取SVG元素的地理定位地理坐标的边界框坐标作为参数 . 该脚本生成变换矩阵,并显示如何将SVG空间中的点乘以矩阵以找到其适当的纬度/经度坐标 .
在SVG中有's a catch--one needs to have the points in the SVG represented without any kind of CSS transformation. To get a straightforward representation of a SVG point'的位置,我使用this tool将SVG中的路径元素转换为多边形元素,source可以公开使用 .
如果其他人需要完成类似的任务,这里是我使用的完整工作流程:
找到感兴趣的栅格 Map (jpg / tiff) .
使用QGIS,ArcGIS或MapWarper对 Map 进行地理定位 . 这产生了一个地理位置 .
下载并安装GDAL,一个带有Python绑定的强大地理空间库 .
在Adobe Illustrator中的Geotiff(例如建筑物)中感兴趣的要素上运行图像跟踪 . 这产生了一个矢量层;将矢量图层保存为SVG文件 .
如果保存的SVG中有任何
<rect>
或其他几何形状,请将它们转换为路径并重新保存 .确定SVG和Geotiff的边界框坐标作为Illustrator的输入 . 后者的边界框可以通过运行
gdalinfo {your-geotiff-file.tif}
从GDAL获得在上面引用的脚本中内联那些边界框坐标 . 然后将SVG分割为
<polygon>
元素数组,并为每个元素将多边形拆分为一个点数组 . 将每个点乘以变换矩阵以找到该点的纬度/长度位置 .将每个形状的每个点保存为适当的geojson格式,以便将数据加载到客户端 .
对于's worth, the script I' m用于生成矩阵变换以及将
<polygon>
元素点转换为纬度/长度空间的内容是here . 请注意,脚本中的某些路径需要根据您的情况进行更新 - 例如 . 该脚本将输出geojson推送到我实验室管理的S3存储桶:)我希望这可以帮助那些发现自己面临这项任务的人!坦白地说,我花了很多精力,我很确定必须有更优雅的工作流程......
我将此功能添加到我之前在Leaflet Maps上完成的工作中 . 这可能适用于您的申请 . 见:www.svgdiscovery.com/K/K04A.htm
这使用了Leaflet Map和导入的SVG路径共有的两个关键点 .
以下示例使用折线值来演示在Leaflet贴图的缩放/平移期间应用于svg路径和其他形状的方法 . 基本上创建SVG层并且在其中添加所有svg元素 .