如何使用视图从PostGIS提取几何图形,然后使用Django将其添加到模板中的传单地图

如何使用视图从PostGIS提取几何图形,然后使用Django将其添加到模板中的传单地图,django,geometry,leaflet,postgis,geojson,Django,Geometry,Leaflet,Postgis,Geojson,我想在视图中使用python从PostGIS数据库提取多边形几何体数据,并将其添加到模板中的传单地图中。 最简单的方法似乎是提取数据并在我的Django视图中使用postgis函数ST_AsGeoJSON将其转换为GeoJSON,然后将其作为L.geoJSONGEOJSON.addTomap函数中的上下文呈现给模板 这是行不通的。在请求地图页面时,地图现在为空,并且似乎无法识别GeoJSON。我已经能够从视图中传递硬编码多边形并将其添加到地图中,但我的postgis数据库中的几何数据根本无效 以

我想在视图中使用python从PostGIS数据库提取多边形几何体数据,并将其添加到模板中的传单地图中。 最简单的方法似乎是提取数据并在我的Django视图中使用postgis函数ST_AsGeoJSON将其转换为GeoJSON,然后将其作为L.geoJSONGEOJSON.addTomap函数中的上下文呈现给模板

这是行不通的。在请求地图页面时,地图现在为空,并且似乎无法识别GeoJSON。我已经能够从视图中传递硬编码多边形并将其添加到地图中,但我的postgis数据库中的几何数据根本无效

以下是一个带有硬编码多边形的视图,该多边形已成功打印在地图上:

from django.shortcuts import render

def map_view(request, *args, **kwargs):
    geo_json={
        "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "properties": {},
              "geometry": {
                "type": "Polygon",
                "coordinates": [
                  [
                    [
                      -0.10746002197265625,
                      51.505537109466715
                    ],
                    [
                      -0.11466979980468751,
                      51.498377681772325
                    ],
                    [
                      -0.0968170166015625,
                      51.493568479510415
                    ],
                    [
                      -0.09080886840820312,
                      51.502438390761164
                    ],
                    [
                      -0.10746002197265625,
                      51.505537109466715
                    ]
                  ]
                ]
              }
            }
          ]
        }

    return render(request ,'map.html', {'geo_json': geo_json})

地图模板如下所示:

<!DOCTYPE html>
<html>
<head>
    <title>Map Page</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
    <style>
        #map {  position: relative;
                width: 600px;
                height: 775px;
                border: 3px solid #000000;}
    </style>    
</head>
<body>
    <div id="map"></div>
    <script>
        var map = L.map('map').setView([54.8,-4.45],6);

        L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=9GKOA9jJ3jCIWFUd8k00', {attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',}).addTo(map);

        L.geoJSON({{ geo_json | safe }}).addTo(map);

    </script>

</body>
</html>
我注意到GeoJSON的格式在输出时略有不同:-

很好

{'type':'FeatureCollection','features':[{'type':'Feature','properties':{},'geometry':{'type':'Polygon','coordinates'等等

这是个问题

{'type':'FeatureCollection','features':[{'type':'Feature','properties':{},'geometry':['{type:MultiPolygon,坐标等,依此类推

有问题的GeoJSON在第二个类型键之前有额外的括号和引号

所以我的问题是:-

1/有可能重新格式化有问题的GeoJSON吗?我很难去掉包装列表的不需要的字符

2/或者我可以提取坐标并将其传递给geo_json的相关部分吗

3/或者我可以从postgis中提取多边形数据并将其添加到leaftlet地图

顺便说一句,你可能想知道为什么我使用游标而不是使用带有GeoJSON方法的Django模型对象。这种方法给了我一个GDAL错误,因为库没有正确配置,这是另一天的问题

非常感谢您的关注


Phil anoobintrouble

正如您将在上面的评论中看到的那样,卡贝索给了我答案。但我将整合一切,希望能帮助未来的用户。 以下是一种方法,您可以从PostGIS数据库提取几何多边形数据,然后将其渲染到模板,并使用Django web框架将其添加到传单地图

下面的视图提取数据,将其转换为GeoJSON,然后将其返回到map.html模板:-

from django.shortcuts import render
import json
import psycopg2

def map_view(request, *args, **kwargs):

    connection = psycopg2.connect(database="electio5_geekdata",user="electio5_blake", password="adummypassword", host='localhost')
    cursor = connection.cursor()
    cursor.execute("select name, st_AsGeoJSON(shape) from boris_constituency limit 1")

    varcons=cursor.fetchone()

    geo_json={
              "type": "Feature",
              "name": varcons[0],
              "properties": {},
              "geometry": json.loads(varcons[1])
            }

    return render(request ,'map.html', {'geo_json': geo_json})

下面的地图模板选取geo_json上下文,并将其添加到传单地图中,绘制多边形几何图形,在本例中,该几何图形为Aldershot的英国议会选区:-

<!DOCTYPE html>
<html>
<head>
    <title>Map Page</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
    <style>
        #map {  position: relative;
                width: 600px;
                height: 775px;
                border: 3px solid #000000;}
    </style>    
</head>
<body>
    <div id="map"></div>
    <script>
        var map = L.map('map').setView([54.8,-4.45],6);

        L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=9GKOA9jJ3jCIWFUd8k00', {attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',}).addTo(map);

        L.geoJSON({{ geo_json | safe }}).addTo(map);

    </script>

    {{ geo_json }}

</body>
</html>
但出现GDAL_错误1:b'PROJ:PROJ_create_from_database:not find PROJ.db'

我认为GDAL库配置不正确-我可能会尝试修复此问题

2/我现在打算让这个应用程序具有交互性,让用户选择选区、地区或根据他们的位置查找他们的选区,并返回尽可能多的有趣信息

请随意评论、更正和添加任何有用的内容

菲尔·阿诺比内德

1.模型创建

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

# Create your models here.

class Locate(models.Model):
    name=models.CharField(max_length=200)
    location =models.PointField(srid=4326)
2.在要显示的视图中创建geojson

from django.shortcuts import render
from django.views.generic import TemplateView
from django.core.serializers import serialize
from django.http import HttpResponse
from .models import Locate

# Create your views here.

class HomePageView(TemplateView):
    template_name='index.html'

# county views

def locate_datasets(request):
    locate=serialize('geojson',Locate.objects.all())
    return HttpResponse(locate,content_type='application/json')
3.在应用程序中创建url/url.py

从django.conf.url导入url 从djgeojson.views导入GeoJSONLayerView 从.views导入HomePageView,找到_数据集

#create your urls here


urlpatterns=[
    url(r'^$',HomePageView.as_view(),name='home'),
    url(r'^locate_data/$',locate_datasets,name='locate'),
]

4.模板

使用geojson ajax加载数据

<!DOCTYPE html>
<html lang="en">

{% load static %}
{% load leaflet_tags %}

<head>

    {% leaflet_js %}
    {% leaflet_css %}
</head>


<body>

<script>
 function our_layers(map,options){

 var locate = new L.GeoJSON.AJAX("{% url 'locate' %}",{}).addTo(map);

</script>

 {% leaflet_map "map" callback="window.our_layers" %}

</body>
 <script src="{% static 'leaflet.ajax.js' %}"></script>
</html>

希望这能解决您的问题

我认为问题在于fetchAll给了您一个列表,您使用它的时候就好像它只是一个元素一样。所以您需要使用varpoly[0]或者迭代varpoly,然后每个多边形都变成GeoJSON的features数组中的一个feature。谢谢。确实如此,所以我按照您的建议引用了特定元素。这去掉了为包装数组而添加的额外括号。但它仍然不起作用。现在我有了{'type':'FeatureCollection','features':[{'type':'Feature','properties':{},'geometry':'{type:MultiPolygon,coordinates:在第二个type语句前面仍然有一个引号,我认为这是造成问题的原因。它从哪里来,可以去掉吗?使用json.loads获取对象,记住它给了你一个geojson格式的字符串。非常感谢你的帮助和耐心。我应该如何以及在哪里使用'jso'n、 加载“?它是在视图中还是在模板中?这只是在某处添加一个简单赋值的情况吗?在代码中,它应该是geometry:json.loadsvarpoly[0],用于将json格式的字符串值转换为geojson对象。使用此链接确保数据转换为geojson
#create your urls here


urlpatterns=[
    url(r'^$',HomePageView.as_view(),name='home'),
    url(r'^locate_data/$',locate_datasets,name='locate'),
<!DOCTYPE html>
<html lang="en">

{% load static %}
{% load leaflet_tags %}

<head>

    {% leaflet_js %}
    {% leaflet_css %}
</head>


<body>

<script>
 function our_layers(map,options){

 var locate = new L.GeoJSON.AJAX("{% url 'locate' %}",{}).addTo(map);

</script>

 {% leaflet_map "map" callback="window.our_layers" %}

</body>
 <script src="{% static 'leaflet.ajax.js' %}"></script>
</html>