Как извлечь геометрию из PostGIS, используя вид, а затем добавить ее на карту листовки в шаблоне, используя Django - PullRequest
0 голосов
/ 08 января 2020

Я хочу извлечь данные геометрии многоугольника из базы данных PostGIS, используя python в представлении, и добавить их в мою карту листовки в шаблоне. Казалось, что проще всего было извлечь данные и преобразовать их в Geo JSON, используя функцию postgis ST_AsGeo JSON в моем представлении Django, а затем отобразить их в шаблоне как контекст в L.geo JSON ( GEO JSON). Функция addTo (map).

Не работает. При запросе страницы карты карта теперь пуста и, как кажется, Geo JSON не распознается. Мне удалось передать жестко заданный многоугольник из вида и добавить его на карту, но данные геометрии в моей базе данных 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>

Вот листовка с добавленным полигоном

Теперь, когда я пытаюсь получить pass Geo JSON из моей базы данных postgis, используя мой новый вид, он не работает:

import psycopg2
from django.shortcuts import render

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

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

    geo_json={
        "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "properties": {},
              "geometry": varpoly
            }
          ]
        }

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

Я замечаю, что формат Geo JSON немного отличается когда я вывожу это: -

IS FINE

{'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'properties': {}, 'geometry': {'type': 'Polygon', 'координаты' и т. д. и т. д.

- это проблема

{'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'properties': {}, 'geometry': [('{"type": "MultiPolygon", "координаты" и т. д. и т. п.

проблематично c Geo JSON имеет дополнительные скобки и кавычка, предшествующая второй «типовой» клавише

Итак, мой вопрос: -

1 / Возможно ли переформатировать проблематику c Geo JSON? У меня были трудности с удалением ненужных символов, которые обертывают список

2 / Или я могу извлечь только координаты и передать их соответствующей части geo_ json?

3 / Или любым другим способом: я могу извлечь данные многоугольника из postgis и добавить их на карту листовки

кстати, вы можете спросить, почему я использую курсор, а не Django объект модели, который имеет метод Geo JSON. Этот подход дал мне ошибку GDAL из-за того, что библиотеки не были настроены должным образом и является проблемой для другого дня!

Большое спасибо за ваше внимание к этому.

Phil #anoobintrouble

1 Ответ

0 голосов
/ 09 января 2020

Мне ответили "cabesuon", как вы увидите в комментариях выше. Но я объединю все, чтобы надеяться помочь будущим пользователям. Вот способ извлечения данных геометрии (многоугольника) из базы данных PostGIS, а затем их рендеринга в шаблон и добавления их в карту листовок с помощью веб-платформы Django.

Представление ниже извлекает данные , преобразует его в Geo JSON и затем возвращает его на карту. html template: -

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 и добавляет его на карту листовки. , нанесение геометрии полигона (которая в данном случае является парламентским округом Великобритании «Олдершот»): -

<!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>

вот геометрия, нанесенная на карту

Пара замечаний: -

1 / Я использовал чистый python для доступа к базе данных. Я действительно должен использовать Geo Django, вызывая геометрию следующим образом: -

from boris.models import constituency
obj=constituency.objects.get(id=1)
geo_json=obj.shape.geojson

, но получил GDAL_ERROR 1: b'PROJ: proj_create_from_database: не удается найти proj.db '

Я считаю, что библиотека GDAL не настроена должным образом - я могу попытаться исправить это

2 / Теперь я намереваюсь сделать это приложение интерактивным, позволяя пользователю выбирать избирательные округа, регионы или находить их постоянные в зависимости от их местоположения и возвращать как можно больше интересной информации.

Не стесняйтесь комментировать, исправлять и добавлять что-либо полезное.

Фил #anoobinneed

...