65.9K
CodeProject 正在变化。 阅读更多。
Home

创建一张带有大字体标记的地图以供打印!

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2019年8月30日

CPOL

5分钟阅读

viewsIcon

3530

每年我都需要创建一个可打印的地图,其中包含标记。这张地图是为 Sindorf trödelt 制作的,这是一个我为家乡一年一度的旧货市场建立的网站。用户可以注册他们的地址,然后我使用 Google Maps 在网站上的地图上显示它们。

每年我都需要创建一个带有标记的可打印地图。

这张地图是为 Sindorf trödelt 准备的,这是一个我为家乡一年一度的旧货市场建立的网站。

用户可以注册他们的地址,然后我使用 Google Maps 在网站上的这张地图上显示他们。

这张地图并不是全年活跃的,所以这里有一张图片

map with markers

旧货市场的组织者还需要打印带有此地图的传单和海报,但使用完全相同的 Google Map 没有意义,因为免费版的 Google Map 对您可以打印的副本数量有限制。

参与旧货市场的每个人都是在业余时间做的(包括我,我还赞助了托管费用),所以根本没有预算支付 Google Maps 许可证费用,而该许可证允许打印更多副本。


第一个解决方案

因此,我需要一种替代方法来创建一张用于打印的地图,并设法使用 OpenLayersOpenStreetMap 制作了一些可用的东西。

我的代码基于我在网上找到的一些关于带有标记的 OpenLayers 地图的示例代码(我已经没有链接了)——它工作得很好,这是一个简化的 JSFiddle(右键单击地图并另存为图片)。

但在第一批传单打印出来后,出现了一个问题:街道名称的字体大小太小,名字无法再读了。

那是两年前了。去年我没时间找到更好的解决方案,所以他们只是打印了更大的传单 :-)

今年,我终于有时间研究这个问题了。


运行我自己的瓦片服务器

听起来很厉害,不是吗?
当您搜索诸如“如何在_[随机网络地图解决方案]_中增大字体大小”之类的内容时,您很快就会发现

  • 大多数解决方案都使用第三方提供商预制好的瓦片,这些瓦片以图像形式提供
  • 要更改这些瓦片的外观,您要么需要更改提供商,要么运行自己的瓦片服务器

运行自己的瓦片服务器听起来很吓人,所以起初我没有研究它,而是专注于使用不同的工具创建整个图像。

最后,我找到了 Maperitive,它有自己的脚本语言,所以可以编写一个包含命令的文本文件并在 Maperitive 中执行,从而从头开始创建地图图像

在玩这个的过程中,我找到了示例代码,它将地图保存为瓦片(=图像文件)通过 FTP 上传它们

那是我的“啊哈”时刻:瓦片服务器并不是一个复杂的软件,而只是一个普通的 Web 服务器,通过 HTTP 提供预生成的图像文件。

所以,我只需要一些反复试验,直到瓦片看起来是我想要的为止。

以下是使用 Maperitive(我使用了 v2.4.3.0)进行操作的步骤

  1. 创建我自己的规则集

    规则集是一个包含 Maperitive 渲染规则的文件。地图的外观可以在 Maperitive 中更改(颜色、细节、文本外观),只需提供不同的规则集即可。

    我需要一些“简单的”(没有太多会弄乱视图的细节),所以我查看了所有规则集,并选择了Google Maps 规则集。这只是 Maperitive 应用程序文件夹中 `Rules` 子文件夹中的一个文件。

    我想要更大的街道字体……所以我复制了那个文件,搜索了 `font-size`,并增加了一些听起来合适的街道类型的数值(需要一些试验)。这是更改的 gist

  2. 获取 OpenStreetMap 数据为 XML

    Maperitive 的十分钟入门 ⇒ 加载地图数据的引用

    使用浏览器,访问 OSM 地图,选择一个较小的区域(比如几个街区的大小),然后点击 **导出** 标签。选择 **OpenStreetMap XML 数据** 单选按钮的值,点击 **导出** 按钮,您将从服务器收到一个名为 `map.osm` 的文件。

  3. 编写 Maperitive 脚本

    这段代码保存在一个带有 .mscript 扩展名的文本文件中

     // this is the ruleset from step 1
     use-ruleset location=sindorftiles.mrules
    
     // this is the OpenStreetMap XML file from step 2
     load-source sindorf.osm
        
     // move and zoom the map, so that the whole town is visible on the screen
     move-pos x=6.674573 y=50.904049 zoom=16
    
     // now we could export the map to a file:
     // export-bitmap file=map.png height=2000 width=1600
    
     // ...but we want to generate tiles instead:
     generate-tiles minzoom=16 maxzoom=16 subpixel=3 bounds=6.6554,50.8898,6.6924,50.9191
        
     // upload via FTP:
     ftp-upload host=tiles.sindorf-troedelt.de user=USERNAME pwd=PASSWORD remote-dir=/
    

    关于 `generate-tiles` 命令的一些说明

    • `minzoom` 和 `maxzoom` 应与 `move-pos` 命令的缩放级别匹配
    • 在这种情况下,仅生成一个缩放级别的瓦片就足够了——我们只需要打印这张地图的视图,无需再放大。缩放级别越多,生成的瓦片就越多!

    对我来说,FTP 上传并不是真正必需的,因为生成瓦片是一次性的。手动上传瓦片也可以接受……但 Maperitive 能够做到这一点仍然很不错。

  4. 打开 Maperitive 并执行脚本

    这只是一个两行代码,调用 Maperitive 并从步骤 3 传递脚本

     rd /s /q Tiles
     C:\Maperitive\Maperitive.exe "%~dp0\sindorftiles.mscript" -exitafter 
    

    我将此放入一个批处理文件中,并将前面提到的所有文件复制到与批处理文件相同的目录中。

就这样——运行它将打开 Maperitive,它将生成瓦片,将它们保存在 `\Tiles` 子文件夹中,并将它们上传到 Web 服务器。

这是一个例子——左边是原始的 OpenStreetMap 瓦片,右边是使用 Maperitive 和我的自定义规则集生成的相同瓦片

tiles before and after


使用 OpenLayers 加载我自己的瓦片

回到最初的 JSFiddle

在 `创建一张带有大字体标记的地图以供打印!- CodeProject - 代码之家

© . All rights reserved.