知っておけば安心!DjangoのGeoJSON操作: 関数、シリアライザー、カスタムコード徹底解説


django.contrib.gis.db.models.functions.AsGeoJSON は、Django の GeoDjango モジュールで提供される関数の一つで、ジオメトリオブジェクトを GeoJSON 形式に変換するものです。GeoJSON は、地理空間データを表現するためのオープンな標準フォーマットであり、JavaScript や Leaflet などの WebGIS ライブラリで広く利用されています。

機能

AsGeoJSON 関数は、以下の機能を提供します。

  • ジオメトリオブジェクトの境界ボックスを含める
  • ジオメトリオブジェクトの座標系を指定する
  • ジオメトリオブジェクトの座標精度を指定する
  • ジオメトリオブジェクトを GeoJSON 形式に変換する

使い方

AsGeoJSON 関数は、以下の構文で使用できます。

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

geojson = AsGeoJSON(geometry_field, **options)
  • options: 変換オプションを指定する辞書型オブジェクト
  • geometry_field: GeoJSON 形式に変換するジオメトリオブジェクトを表すフィールド

オプション

以下のオプションを options 辞書型オブジェクトで指定できます。

  • bbox: 境界ボックスを含めるかどうかを指定. デフォルトは False です。
  • crs: 座標系の指定. デフォルトは、ジオメトリオブジェクトの座標系です。
  • precision: 座標精度の指定. デフォルトは 8 です。

以下の例は、City モデルの location フィールドのジオメトリオブジェクトを GeoJSON 形式に変換し、座標精度を 6 桁に設定し、境界ボックスを含めるようにしています。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location, precision=6, bbox=True)

print(geojson)
{
  "type": "Point",
  "coordinates": [139.769, 35.689],
  "bbox": [139.75, 35.67, 139.78, 35.7]
}


ジオメトリオブジェクトを GeoJSON 形式に変換する

この例では、City モデルの location フィールドのジオメトリオブジェクトを GeoJSON 形式に変換します。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location)

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689]
}

座標精度を指定する

この例では、座標精度を 6 桁に設定して GeoJSON 形式に変換します。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location, precision=6)

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769000, 35.689000]
}

座標系を指定する

この例では、ジオメトリオブジェクトの座標系を WGS84 に設定して GeoJSON 形式に変換します。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location, crs='EPSG:4326')

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689],
  "crs": {
    "type": "EPSG",
    "properties": {
      "code": 4326
    }
  }
}

境界ボックスを含める

この例では、境界ボックスを含めて GeoJSON 形式に変換します。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location, bbox=True)

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689],
  "bbox": [139.75, 35.67, 139.78, 35.7]
}

フィールド名を指定する

この例では、出力される GeoJSON オブジェクトのフィールド名を my_geojson_field に指定します。

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

from .models import City

city = City.objects.get(name='東京')
geojson = AsGeoJSON(city.location, field_name='my_geojson_field')

print(geojson)

出力

{
  "my_geojson_field": {
    "type": "Point",
    "coordinates": [139.769, 35.689]
  }
}

GeoJSON レイヤーを作成する

この例では、AsGeoJSON 関数を使用して GeoJSON レイヤーを作成し、Leaflet マップに表示します。

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

from .models import City

cities = City.objects.all()
geojson_layer = GeoJSONLayer(cities, field='location')

map = folium.Map(zoom_start=7, location=[35.689, 139.769])
map.add_layer(geojson_layer)

map


GeoJSONSerializer を使用する

GeoJSONSerializer は、Django REST framework で提供されるシリアライザーで、モデルインスタンスを GeoJSON 形式に変換することができます。AsGeoJSON 関数よりも柔軟性が高く、多くのオプションを提供しています。

利点

  • Django REST framework とシームレスに連携できる
  • 複雑な GeoJSON オブジェクトを生成しやすい
  • 多くのオプションを提供している

欠点

  • Django REST framework を使用していない場合は利用できない
  • AsGeoJSON 関数よりも複雑

from rest_framework import serializers
from .models import City

class CitySerializer(serializers.ModelSerializer):
    geojson = serializers.GeoJSONField(source='location')

    class Meta:
        model = City
        fields = ('id', 'name', 'location', 'geojson')

city = City.objects.get(name='東京')
serializer = CitySerializer(city)
geojson = serializer.data['geojson']

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689]
}

GeoJSON フィールドを使用する

GeoJSON フィールドは、Django 3.2 以降で導入された新しいフィールドタイプで、モデルインスタンスを GeoJSON 形式で直接保存することができます。AsGeoJSON 関数を使用する必要がなくなり、コードが簡潔になります。

利点

  • AsGeoJSON 関数を使用する必要がない
  • コードが簡潔になる

欠点

  • AsGeoJSON 関数よりもオプションが少ない
  • Django 3.2 以降でのみ利用可能

from django.contrib.gis.db import models

class City(models.Model):
    name = models.CharField(max_length=255)
    location = models.PointField()
    geojson = models.GeoJSONField()

city = City.objects.create(name='東京', location=Point(139.769, 35.689))

print(city.geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689]
}

カスタムシリアライザーを使用する

カスタムシリアライザーを作成して、モデルインスタンスを GeoJSON 形式に変換することができます。これは、複雑な GeoJSON オブジェクトを生成したり、独自のオプションを追加したりする場合に役立ちます。

利点

  • 独自のオプションを追加できる
  • 複雑な GeoJSON オブジェクトを生成できる

欠点

  • AsGeoJSON 関数や GeoJSONSerializer よりも複雑

from django.contrib.gis.db.models.functions import GeoJSON
from rest_framework import serializers

from .models import City

class CityGeoJSONSerializer(serializers.Serializer):
    geojson = serializers.CharField(source='*')

    def to_representation(self, instance):
        geojson = GeoJSON(instance.location)
        return {'geojson': geojson}

city = City.objects.get(name='東京')
serializer = CityGeoJSONSerializer(city)
geojson = serializer.data['geojson']

print(geojson)

出力

{
  "type": "Point",
  "coordinates": [139.769, 35.689]
}

外部ライブラリを使用する

GeoJSON を生成するための外部ライブラリをいくつか利用することができます。これらのライブラリは、Django に依存していないため、より汎用性が高く、他のプロジェクトでも利用することができます。

利点

  • 他のプロジェクトでも利用できる
  • より汎用性が高い
  • Django に依存していない

欠点

  • Django との統合が難しい場合がある
import geojson

from .models import City

city = City.objects.get