【问题标题】:Creating a OSM map tiles server in Django在 Django 中创建 OSM 地图瓦片服务器
【发布时间】:2025-12-10 18:40:02
【问题描述】:

我按照switch2osm 的教程创建了一个切片服务器,但本教程仅适用于 apache 服务器。

我有一个 Django 服务器,想为它创建一个自定义地图。我已经安装了 Mapnik、PostGIS 并将 OSM 数据加载到我的 PostGIS 数据库中。

我创建了一个 python 脚本,它使用 Mapnik 创建一个简单的地图,代码如下:

#!/usr/bin/env python
import mapnik

stylesheet = 'database.xml'
image = 'database.png'
m = mapnik.Map(900, 450)
mapnik.load_map(m, stylesheet)
m.zoom_all() 
mapnik.render_to_file(m, image)
print "rendered image to '%s'" % image

还有xml文件:

<Map background-color="steelblue" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">

  <Style name="My Style">
    <Rule>
      <PolygonSymbolizer fill="#f2eff9" />
      <LineSymbolizer stroke="rgb(50%,50%,50%)" stroke-width="0.1" />
    </Rule>
  </Style>

  <Layer name="countries" status="on" srs="+proj=latlong +datum=WGS84">
    <StyleName>My Style</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="host">localhost</Parameter>
      <Parameter name="dbname">db</Parameter>
      <Parameter name="user">user</Parameter>      
      <Parameter name="password"></Parameter>
      <Parameter name="table">(SELECT * from planet_osm_line where highway is not null) as foo</Parameter>
      <!-- <Parameter name="extent">-180,-90,180,89.99</Parameter> -->
      <!-- <Parameter name="extent">-20037508.34,-20037508.34,20037508.34,20037508.34</Parameter> -->
    </Datasource>
  </Layer>

</Map>

这会生成以下图像(我只加载了这个 OSM 数据,而不是整个星球):

我正在考虑创建一个类似的东西来创建一个 Django 视图,该视图将提供我的地图图块,但处理时间太长(3 分钟)。

如何使用 Mapnik 通过 Django 创建图块服务器?是否有任何 Django 库可以使这更容易?

【问题讨论】:

  • 您需要 django 来生成切片(=> 从 celery 运行 mapnik)还是只需要 django 来提供文件(=> 将它们放入 django 的媒体目录并完成)?
  • 我只需要 Django 来提供磁贴,但我认为这些磁贴是动态生成的,因此它们不会占用太多磁盘空间。
  • 切片是在切片服务器上动态生成的,但是存在两个瓶颈:切片生成时间和磁盘空间。通过修剪较少使用的切片来节省磁盘空间,并通过缓存处理生成时间。这也是为什么你可能会在地球上不那么经常访问的位置获得空的瓷砖,因为瓷砖生成是异步触发的。当然取决于实施。
  • 但是是否有任何 Django 应用程序/库来帮助生成/缓存/服务这些图块?如果没有,这样做的最佳方法是什么?或者是保持我的 Django 服务器和 apache 服务这些图块的唯一简单方法?

标签: python django openstreetmap mapnik


【解决方案1】:

我猜你混合了两个完全独立的东西:

Django 服务

这是你的部分,你可以在你的专用用例上创建各种逻辑、模型、视图等。例如,您编写一个平台来标记地图上有趣的地方,您可以在其中使用djangos geoapp (fka.geodjango) 嵌入地理空间魔法等。

平铺地图服务

这就是(独立!)创建可以被任何其他应用程序(桌面 gis...JS webmap 小部件)使用的地图图块。通常人们使用existing tile-providers 来获取地图,无需任何自己的工作,而且是免费的。仅当您需要创建自己的自定义地图样式时,您才需要托管自己的图块渲染堆栈,如 www.switch2osm.org 中所述。无论如何,强烈建议您遵循本指南并依靠现有工具(mapnik、postgis、...)来避免很多麻烦。在您开始自己的服务之前,请记住硬件和服务要求(磁贴覆盖范围、可靠性、更新频率……)!

这个瓷砖如何在您的 django 前端代码中链接为 Leaflet/OpenLayers/... 层。仅此而已:)

【讨论】:

  • 我可以向这个现有的 tile-providers 添加额外的数据吗?例如,如果我的 PostGIS 数据库中有人行道状况信息,我是否可以在使用此信息显示更完整的地图时使用此图块提供程序(例如用不同颜色为某些人行道着色)?
  • 当然!您只需向您的 JS 小部件添加一个新图层(可能是通过 WMS 的栅格或矢量,例如 geoJSON)。如果你愿意,这个源可以是你的 Django 服务(参见Django REST framework GIS),只需几行代码。
  • 我已经在使用 Django REST 框架 GIS 来提供我的 JSON 信息 使用GeoFeatureModelSerializer 是否比使用GeoModelSerializer 更容易进入地图中的新图层?您知道在使用 Android 的 OSMdroid(或在 Android 中使用 OSM 地图图块的另一个库)时添加新图层是否容易?感谢您的帮助!
  • 完全取决于您的需求。在大多数情况下,ModelSerializer 可以 1:1 发布您的模型,包括引用等。但是如果您想调整模型的 API 表示,则可能会切换到不同的(更手动的)序列化程序。我对 OSMdroid 没有任何经验,但您似乎需要 bonuspack 来添加叠加功能等...(请提出一个单独的问题,因为这与原始主题无关)