Geo django: как загрузить файл .shp и преобразовать его в geo json с помощью правильной CRS? - PullRequest
4 голосов
/ 19 июня 2020

У меня есть несколько шейп-файлов (.shp) с их вспомогательными файлами, которые я хочу отобразить на карте Leaflet. В шейп-файлах используются разные системы координат (CRS), и мне трудно найти самый простой и надежный способ показать объекты на карте. В учебнике geo django DataSource используется для загрузки шейп-файла и последующего управления им. Однако в своих примерах они извлекают только геометрию отдельных элементов, а не всего шейп-файла. Я использовал PyShp , и я могу показать карту, используя что-то вроде:

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

Однако это не удается, когда CRS не WGS84, все не работает, и я не Не вижу, как это преобразовать.

Читаю еще немного, этот пост жалуется на поддержку CRS и pyshp и предлагает использовать ogr2ogr.

Итак, после попытки понять параметры, которые я вижу с использованием Datasource, pyshp и ogr2ogr в качестве возможных вариантов, но я не знаю, какой вариант действительно имеет наибольший смысл. 1023 * в строку geo json, которая использует WGS84, чтобы я мог включить его на страницу HTML, которая использует Leaflet.

Может ли кто-нибудь с большим опытом предложить конкретный маршрут?

1 Ответ

3 голосов
/ 25 июня 2020

Нет прямого способа прочитать любой шейп-файл, используя Django s DataSource, а затем преобразовать его в 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 считывает шейп-файл в объект. Информация хранится в объектах Layers (представляющих многослойный шейп-файл), которые знают свои srs как SpatialReference. Это важно, потому что мы преобразуем геометрию позже в WGS84, чтобы ее можно было отобразить на карте.

  3. Из каждого слоя каждого шейп-файла мы будем используйте метод get_geoms() для извлечения списка OGRGeometry srs объектов с поддержкой.

  4. Каждая такая геометрия имеет json метод, который:

    Возвращает строковое представление этой геометрии в формате JSON:

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

    То есть очень полезно, потому что это половина решения для создания FeatureCollection типа geo json, который будет отображаться на карте.

  5. A FeatureCollection geo json имеет очень специфический формат c, поэтому мы создадим основу и процедурно заполним ее:

    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 dict wil l содержать извлеченный набор функций, преобразованный в epsg:4326, и вы можете создать из него json (например, 1077

...