如何使用视图从PostGIS提取几何图形,然后使用Django将其添加到模板中的传单地图
我想在视图中使用python从PostGIS数据库提取多边形几何体数据,并将其添加到模板中的传单地图中。 最简单的方法似乎是提取数据并在我的Django视图中使用postgis函数ST_AsGeoJSON将其转换为GeoJSON,然后将其作为L.geoJSONGEOJSON.addTomap函数中的上下文呈现给模板 这是行不通的。在请求地图页面时,地图现在为空,并且似乎无法识别GeoJSON。我已经能够从视图中传递硬编码多边形并将其添加到地图中,但我的postgis数据库中的几何数据根本无效 以下是一个带有硬编码多边形的视图,该多边形已成功打印在地图上:如何使用视图从PostGIS提取几何图形,然后使用Django将其添加到模板中的传单地图,django,geometry,leaflet,postgis,geojson,Django,Geometry,Leaflet,Postgis,Geojson,我想在视图中使用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">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© 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">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© 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>