【问题标题】:PostGis Polygon into leaflet map using django使用 django 将 PostGis Polygon 转换为传单地图
【发布时间】:2026-01-24 08:45:01
【问题描述】:

我的问题是我不知道如何使用 django 将存储在 PostGIS 中的多边形可视化为传单地图。

在模板中,我使用它来绘制点:

  <script type="text/javascript">

      function map_init(map, options) {
        {% for each_model in loca %}

          var lon =   {{each_model.location.x}}
          var lat =   {{each_model.location.y}}


          map.setView([lat, lon], 2);

          L.marker([lat, lon]).bindPopup("{{each_model.name}}").addTo(map)

          {% endfor %}
          // get point lat and lon

          // zoom to point & add it to map
        ;
      }

  </script>

模型.py

from __future__ import unicode_literals

from django.contrib.gis.db import models
from django.contrib.gis.geos import Point


class Shop(models.Model):
    name = models.CharField(max_length=100)
    location = models.PointField()
    address = models.CharField(max_length=100)
    city = models.PolygonField()

如果我打印 {{loca.city}},它将打印出 GEOS 对象,如下所示:

SRID=4326;POLYGON ((2.988282590688516 6............))

知道如何在绘制点时绘制多边形吗?

更新二:

打印出模型在使用 Shop.object.all() 时产生的内容

<QuerySet [<Shop: Shop object (1)>, <Shop: Shop object (2)>, <Shop: Shop object (3)>, <Shop: Shop object (4)>]>

数据库表看起来像这样存储多边形和点 (x,y)

我考虑过手动(在视图中)使用查询,但它不起作用(cursor.execute("SELECT ST_AsText(city) FROM trial2_shop;)

使用此代码:

{% for each_model in loca %}

{{each_model.name}} <br>

{% endfor %}

输出是这样的:

HELLO 
PARIS 
France 
abc 

然后使用这个:

{% for each_model in loca %}

{{each_model.city}} <br>

{% endfor %}

输出是这样的:

SRID=4326;POLYGON ((2.988282590688516 6.287501448673132, -2.724608033516236 4.362344411133384, -5.624998658112493 4.800392361058798, -9.316404907598319 4.62520548641869, -7.29492053288002 -2.927082610924476, 8.701173214893267 -0.8189537900473602, 9.667970089758358 3.573231060257538, 5.537110715333732 4.362344411133384, 2.988282590688516 6.287501448673132)) 
SRID=4326;POLYGON ((2.379232127237539 48.99532183070828, 1.835408885125764 48.778601581576, 2.489095408472194 48.61544474629894, 2.780233103744227 48.87985458449839, 2.379232127237539 48.99532183070828)) 
SRID=4326;POLYGON ((4.921880363732911 48.86996904931716, 13.00781786260736 44.28238994198036, -8.08593213445636 32.47943349940858, -25.31249463205829 49.55890707900826, 5.364418038408538e-06 58.4058966101036, -8.789057134358529 49.10068218084409, 4.921880363732911 48.86996904931716)) 
SRID=4326;POLYGON ((10.10742321469805 59.8969527006269, 16.34765758882955 60.31310053764656, 15.02929821401315 57.87662999493084, 12.39257946438035 57.92333496310473, 10.10742321469805 59.8969527006269))

所以我确定存储的是多边形,但是在检索时将其绘制在地图模板中是问题...

【问题讨论】:

    标签: python leaflet postgis geodjango geos


    【解决方案1】:

    您基本上需要在模板中使用leaflet polygon documentation
    你需要做两件事:

    1. Polygon's coordinates的列表:

      lst_coords = [[point.x, point.y] for point in shop_object.city]
      

      这将产生一个列表/坐标对的列表。

    2. 将坐标列表插入到传单多边形中:

      L.polygon(lst_coords, {color: 'red'}).addTo(map);
      

    现在让我们将上述内容应用到您的示例中:

    1. 在模型中添加property 以返回坐标列表(仅为方便起见):

      class Shop(models.Model):
          name = models.CharField(max_length=100)
          location = models.PointField()
          address = models.CharField(max_length=100)
          city = models.PolygonField()
      
          @property
          def city_coords_list(self):
               return [[point.x, point.y] for point in self.city]
      
    2. 将以上内容集成到模板中:

      <script type="text/javascript">
      
        function map_init(map, options) {
          {% for each_model in loca %}
      
            L.polygon(
              {{ each_model.city_coords_list }}, {color: 'red'}
            ).bindPopup({{ each_model.name }}).addTo(map)
      
        {% endfor %}
        // Find a way to fit the map accordignly (search the docs)
        ;
      }
      

    【讨论】:

    • 感谢@John 的清晰解释,问题仍然存在 lst_coords = list(shop_object.city.coords) 这实际上返回:[((2.9882825906885158, 6.287501448673132), (-2.7246080335162364, 4.36234)441 -5.624998658112493, 4.8003923610587975))] 其中它不是列表列表,我尝试了这些步骤,但实际上并没有可视化任何内容,在传单文档中它显示:var latlngs = [ [45.51, -122.68], [37.77, -122.43],[34.04,-118.2]];这是一个列表列表,我想如果我们解决了问题,你怎么看?
    • 例如运行这个:{% for each_model in loca %} var coords_list = {{each_model.city_coords_list}};警报(coords_list); L.polygon(coords_list, {color: 'red'}).addTo(map); {% endfor %} 警报只会显示这个:6.287501448673132 这是管中第一个点的 Y 轴,仅此而已
    • @kiwis 我已经测试了要列出的坐标元组,它按我的预期工作,但是由于你有问题,我编辑了我的答案以遍历列表。看看,让我知道:)
    • 介意分享你的views.py吗?它仍然对我不起作用 def dd(request): spost = Shop.objects.all() context = { 'loca' : spost, } return render(request,'def2.html',context)
    • @kiwis 你能解释一下“不起作用”是什么意思吗?你得到一个空列表还是别的什么?