2

假设我有一个非地理图像而不是通常的地图。比方说,例如 X 射线、MRI 扫描或显微镜图像,我想使用传单,这样我就可以放大、缩小并在一些预定点上放置一些标记。

我已经阅读了非地理地图中的示例,但此案例演示了使用单个图像而不是平铺。我更喜欢瓷砖,因为我的图像会相当大。请问还有其他适合我上面描述的情况的吗?我正在研究rastercoords,但我还没有明确这是否适用于任何光栅文件,仅适用于普通地图。

4

2 回答 2

10

这是我关于如何从PDF或高分辨率图像或非易滑地图等来源创建易滑地图的经验。无论如何,我想写一篇关于这个的文章,所以让这个答案成为尚未写的文章的草图。

举个例子,这里有一张带有矢量图形的欧洲内陆水道 PDF 地图,还有一张它的滑图

基本上,最合理的方法是制作一个标准的瓦片集,然后让 Leaflet 显示它。即为每个缩放级别生成大小为 256x256 的图块。
您不希望将巨大的图像作为图层,因为这对浏览器来说太重了。您也不希望在浏览器中调整大小,这将导致质量不佳。

幸运的是,使用ImageMagick创建图块非常容易。我就是这样做的。

决定你想要多少缩放级别

首先,决定你想要多少缩放级别。这取决于地图,根据我的经验,您最多需要 5-7 个缩放级别。让我们以 5 个缩放级别为例。您制作的关卡越多,您对硬件的要求就越高。下面的方法可能不适合超过 7-8 的缩放级别。

渲染或调整源图像大小

接下来,为每个缩放级别渲染或调整图像大小。您必须生成具有以下尺寸之一的图像:

  • 2560级像素
  • 5121 级像素
  • 10242 级像素
  • 20483 级像素
  • 40964级像素
  • 等等。

注意:这一步的结果是巨大的图像。第 5 级约为 10 MB,第 6 级约为 20 MB,第 7 级约为 40 MB。小心尝试在“普通”工具中打开这些图像。

调整普通高分辨率图像的大小

如果您的源是高分辨率图像,只需convert -resize使用x*256*or *256*x

convert images\source.jpg -resize   x256 images\0.jpg
convert images\source.jpg -resize   x512 images\1.jpg
convert images\source.jpg -resize  x1024 images\2.jpg
convert images\source.jpg -resize  x2048 images\3.jpg
convert images\source.jpg -resize  x4096 images\4.jpg
convert images\source.jpg -resize  x8192 images\5.jpg

如果您有多个不同缩放级别的缩放图像(我想这将是 MRI 扫描的情况),请选择最近缩放的源图像。

使用已经平铺的图像

在某些情况下,源图像已经被切割成图块。这在您想要滑动的“旧”地图客户端中很典型。这是一个例子,瓷砖被调用vk-X-Y.jpg并被切割并有一些重叠。在这种情况下,您首先必须裁剪图像:

magick data\vk-0-0.jpg  -crop 522x373+0x0 images\t-0-0.jpg
magick data\vk-1-0.jpg  -crop 522x373+0x0 images\t-1-0.jpg
magick data\vk-2-0.jpg  -crop 522x373+0x0 images\t-2-0.jpg
magick data\vk-3-0.jpg  -crop 522x373+0x0 images\t-3-0.jpg
magick data\vk-4-0.jpg  -crop 522x373+0x0 images\t-4-0.jpg
magick data\vk-5-0.jpg  -crop 650x373+0x0 images\t-5-0.jpg
...

要找出裁剪参数,将垂直和水平相邻的图块加载到图形编辑器中,尝试匹配它们并检查偏移坐标。

然后,在裁剪图块时,将它们附加到大图像中:

magick images\t-0-0.jpg images\t-1-0.jpg images\t-2-0.jpg images\t-3-0.jpg images\t-4-0.jpg images\t-5-0.jpg +append images\t-0.jpg
...
magick images\t-0.jpg images\t-1.jpg images\t-2.jpg images\t-3.jpg images\t-4.jpg images\t-5.jpg images\t-6.jpg images\t-7.jpg images\t-8.jpg images\t-9.jpg images\t-10.jpg -append images\t.jpg

这种裁剪和附加操作的结果是地图的高分辨率大图像。将其调整为上述每个级别。

调整 PDF 大小

在渲染 PDF 时,我更喜欢使用density. 计算每个缩放级别的密度(这是 Windows 命令,针对 Linux 进行相应修改):

identify -precision 16 -format "%%[fx:((256/max(w,h))*72)]\n%%[fx:((512/max(w,h))*72)]\n%%[fx:((1024/max(w,h))*72)]\n%%[fx:((2048/max(w,h))*72)]\n%%[fx:((4096/max(w,h))*72)]" source.pdf

这给了你类似的东西:

21.89073634204276
43.78147268408551
87.56294536817103
175.1258907363421
350.2517814726841

表达式的魔力(4096/max(w,h))*72很简单:(目标大小/源大小)* 标准 DPI。

有密度渲染图像:

convert -verbose -density 21.89073634204276 source.pdf        images\0.png
convert -verbose -density 43.78147268408551 source.pdf        images\1.png
convert -verbose -density 87.56294536817103 source.pdf        images\2.png
convert -verbose -density 175.1258907363421 source.pdf        images\3.png
convert -verbose -density 350.2517814726841 source.pdf        images\4.png

这在更高级别上可能需要很多时间。

切割平铺中的关卡图像

此时,您应该每层有一个图像。现在我们可以将它们切割成瓷砖:

convert -verbose images\0.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\0_%%[filename:tile].png"
convert -verbose images\1.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\1_%%[filename:tile].png"
convert -verbose images\2.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\2_%%[filename:tile].png"
convert -verbose images\3.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\3_%%[filename:tile].png"
convert -verbose images\4.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\4_%%[filename:tile].png"
convert -verbose images\5.png -crop 256x256 +adjoin -background white -extent 256x256 -set filename:tile "%%[fx:floor(page.x/256)]_%%[fx:floor(page.y/256)]" +repage "tiles\5_%%[filename:tile].png"

这会产生如下文件:

  • tiles/0_0_0.png
  • tiles/1_0_0.png
  • tiles/1_0_1.png
  • tiles/1_1_0.png
  • tiles/1_1_1.png
  • 等等

这是一组 256x256 大小的静态预渲染图块。

配置传单

现在您只需要配置 Leaflet。假设 tile 文件../tiles相对于 HTML 文件位于目录中,这很简单:

L.tileLayer('../tiles/{z}_{x}_{y}.png', {
    maxZoom: 5,
    noWrap: true,                     
    attribution: 'Some Attribution'
}).addTo(map);

如果你想设置正确的初始视点,缩放/移动到你想要的位置,在你的开发工具中打开 JavaScript 控制台并输入:

map.getCenter();
map.getZoom();

然后在初始化地图时使用打印的参数:

var map = L.map('map').setView([-26.3525, -65.0390], 3);

添加标记:

L.marker([-26.3525, -65.0390], {title: "Hi there!"}).addTo(map);

即使您平移或缩放,标记也将保持在同一位置。


以下是其中一个项目示例:

于 2018-07-15T05:26:30.767 回答
6

libvips有一个操作,可以在一个命令中为传单制作一个滑动地图瓦片集。

例如,使用这张欧洲内陆水道的 PDF 地图(谢谢@lexicore!),您可以输入:

vips dzsave European_inland_waterways_-_2012.pdf[dpi=600] xxx --layout google

它会创建一个名为xxx包含所有图块的目录,准备好上传到您的服务器。大约需要 15 秒(无论如何在这台笔记本电脑上)。

它速度很快,并且需要很少的内存。细节随文件格式而有所不同,但对于许多格式,它可以对输入进行解码,构建所有金字塔层,并写入输出图块,所有这些都是并行的,而无需将整个输入图像加载到记忆。我经常在一台普通的笔记本电脑上渲染超过 300,000 x 300,000 像素的金字塔。

它可以处理一些有用的文件类型以及通常的 tiff、PNG、JPG 等,包括 SVG、FITS、DICOM 和 OpenSlide。它也可以为 deepzoom 和 zoomify 制作金字塔。

Windows 主机的一个不错的功能是能够将切片集写入 zip 文件而不是文件系统。Windows 的文件创建速度相当慢——使用大金字塔和小图块,您可以将几乎 75% 的 CPU 时间花在文件创建上。改为写入 zip 文件,您可能会看到 3 倍的加速:

vips dzsave huge.tif xxx.zip --layout google

另外,当然 zip 更容易上传到服务器。

libvips 手册中有一章介绍了 dzsave并显示了所有选项。

于 2018-07-24T21:54:21.220 回答