簡體   English   中英

Geodjango:如何加載.shp 文件並使用正確的 CRS 轉換為 geojson?

[英]Geodjango: how to load .shp file and convert to geojson with the right CRS?

我有多個 shapefile (.shp) 及其輔助文件,我想在 Leaflet map 上顯示這些文件。 shapefile 使用不同的坐標參考系統 (CRS),我很難掌握在 map 上顯示內容的最直接、最可靠的方法。 geodjango 教程中,DataSource 用於加載 shapefile,然后對其進行操作。 然而,在他們的示例中,他們只檢索單個特征的幾何圖形,而不是整個 shapefile。 我已經使用了 PyShp ,並且可以使用以下方式顯示 map:

    sf = shapefile.Reader(filename)
    shapes = sf.shapes()
    geojson = shapes.__geo_interface__
    geojson = json.dumps(geojson)

但是,當 CRS 不是 WGS84 時,這會失敗,事情不起作用,我不知道如何轉換它。

多讀一點,這篇文章抱怨 CRS 支持和 pyshp,並建議使用 ogr2ogr。

因此,在嘗試了解這些選項之后,我看到使用 Datasource、pyshp 和 ogr2ogr 作為可能的選項,但我不知道哪個選項真正最有意義。

我想要的只是將使用 Django 的 a.shp 文件轉換為使用 WGS84 的 geojson 字符串,以便我可以將其包含在使用 Leaflet 的 HTML 頁面上。

有更多經驗的人可以建議一條特定的路線嗎?

沒有一種直接的方法可以使用 Django 的DataSource讀取任何 shapefile,然后將其轉換為EPSG:4326 (aka WGS84) ,因此我們需要一步一步地創建並解決出現的問題。

讓我們開始這個過程:

  1. 創建您需要讀取的所有.shp文件路徑的列表。應該如下所示:

     SHP_FILE_PATHS = [ 'full/path/to/shapefile_0.shp', 'full/path/to/shapefile_1.shp', ... 'full/path/to/shapefile_n.shp' ]
  2. DataSource將 shapefile 讀入 object。 信息存儲在對象的Layers (表示多層形狀文件)中,這些圖層將其srs視為SpatialReference 這很重要,因為我們稍后會將幾何轉換為WGS84 ,以便在 map 上顯示。

  3. 從每個 shapefile 的每一層,我們將利用get_geoms()方法提取OGRGeometry srs感知對象的列表。

  4. 每個這樣的幾何都有一個json方法:

    以 JSON 格式返回此幾何圖形的字符串表示形式:

     >>> OGRGeometry('POINT(1 2)').json '{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }'

    這非常有用,因為它是創建可顯示到 map 的FeatureCollection類型 geojson 的解決方案的一半。

  5. FeatureCollection geojson 具有非常特定的格式,因此我們將創建基礎並按程序填充它:

     feature_collection = { 'type': 'FeatureCollection', 'crs': { 'type': 'name', 'properties': {'name': 'EPSG:4326'} }, 'features': [] }
  6. 最后,我們需要使用提取的幾何圖形填充features列表,格式如下:

     { 'type': 'Feature', 'geometry': { 'type': Geometry_String, 'coordinates': coord_list }, 'properties': { 'name': feature_name_string } }

讓我們將以上所有內容放在一起:

for shp_i, shp_path in enumerate(SHP_FILE_PATHS):
    ds = DataSource(shp_path)
    for n in range(ds.layer_count):
        layer = ds[n]
        # Transform the coordinates to epsg:4326
        features = map(lambda geom: geom.transform(4326, clone=True), layer.get_geoms())
        for feature_i, feature in enumerate(features):
            feature_collection['features'].append(
                {
                    'type': 'Feature',
                    'geometry': json.loads(feature.json),
                    'properties': {
                        'name': f'shapefile_{shp_i}_feature_{feature_i}'
                    }
                }
            )

現在feature_collection字典將包含轉換為epsg:4326的提取特征集合,您可以從它創建一個 json (例如json.dump(feature_collection)

注意:雖然這會起作用,但它似乎有點適得其反,您可以考慮將 shapefile 永久讀取到 model 中,而不是動態加載它們。

#models.py

from __future__ import unicode_literals
from django.db import models
from django.contrib.gis.db import model
# county


class County(models.Model):
    district = models.CharField(max_length=50)
    count = models.FloatField()
    county_nam = models.CharField(max_length=50)
    code = models.BigIntegerField()
    geom = models.MultiPolygonField(srid=4326)

    def _unicode_(self):
        return self.county_nam

    class Meta:
        verbose_name_plural="County"

在視圖中

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 County

# Create your views here.

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

# county views

def county_datasets(request):
    county=serialize('geojson',County.objects.all())
    return HttpResponse(county,content_type='application/json

在 urls.py

from django.conf.urls import url
from djgeojson.views import GeoJSONLayerView
from .views import HomePageView,county_datasets

# create your urls here


urlpatterns=[
    url(r'^$',HomePageView.as_view(),name='home'),
    url(r'^county_data/$',county_datasets,name='county'),

]

運行服務器

python manage.py runserver

通過鍵入檢查您的 geojson 數據

http://localhost:8000/county_data/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM