質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4349閲覧

Python geojson形式のPolygonデータを作成したい

okiron9619

総合スコア5

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/10/23 15:02

編集2020/10/24 03:13

前提・実現したいこと

Djangoを用いて、マップ上にポリゴンを描画しようとしています。
Postgresql上にあるポリゴンデータをpythonでgeojson形式に格納して、Leafletを用いて、描画するという流れです。

発生している問題・エラーメッセージ

Pointであれば、latlng.xやlatlng.yのようにアクセスできたのですが、
Polygonの場合、どのように記述すべきか調べてみたのですが、わかりませんでした。

該当のソースコード

該当のpython部分を載せています
データベースには、meesh_id,latlngのカラムでデータがあります。(latlngには、geometry型,Polygon,srid = 4326)
mesh_listには、データベースにあるPolygonの全オブジェクトが格納されます

python

1views.py 2class MeshView(View): 3 4 def get(self, request, *args, **kwargs): 5 """ 6 メッシュリストの取得 7 """ 8 mesh_list = Mesh.objects.all() 9 10 # レスポンスの生成 11 features = [MeshMapper(mesh).as_dict() for mesh in mesh_list] 12 response = { 13 'type': 'FeatureCollection', 14 'crs': { 15 'type': 'name', 16 'properties': { 17 'name': 'EPSG:4326', 18 }, 19 }, 20 'features': features, 21 } 22 response_json = json.dumps(response) 23 24 # レスポンスの返却 25 return HttpResponse(response_json, content_type='application/json')

python

1views_models.py 2class MeshMapper: 3 """Meshマッパー""" 4 5 def __init__(self, obj): 6 self.obj = obj 7 8 def as_dict(self): 9 mesh = self.obj 10 return { 11 'type': 'Feature', 12 'properties': { 13 'mesh': { 14 'id': mesh.mesh_id, 15 }, 16 }, 17 'geometry': { 18 'type': 'Polygon', 19 'coordinates': #この部分の記述方法を教えていただきたいです 20 }, 21 }

python

1models.py 2from django.contrib.gis.db import models 3class Mesh(models.Model): 4 """メッシュモデル""" 5 mesh_id = models.IntegerField(primary_key=True, default=0, editable=False) 6 latlng = models.PolygonField(srid=4326) 7 8 class Meta: 9 db_table = 'meshes' 10 verbose_name = 'メッシュ' 11 verbose_name_plural = 'メッシュ一覧' 12 13 def __str__(self): 14 return str(self.mesh_id) 15
テーブルの構造 テーブル "public.meshes" 列 | 型 | 照合順序 | Null 値を許容 | デフォルト ---------+------------------------+----------+---------------+------------ mesh_id | integer | | not null | latlng | geometry(Polygon,4326) | | not null | インデックス: "meshes_pkey" PRIMARY KEY, btree (mesh_id) "meshes_latlng_id" gist (latlng) テーブル内のデータの一部 mesh_id | latlng ---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 | 0103000020E6100000010000000500000006AC107262F56040161E38A66B824140C220A48A66F56040161E38A66B824140C220A48A66F56040244BEA435B82414006AC107262F56040244BEA435B82414006AC107262F56040161E38A66B824140 2 | 0103000020E6100000010000000500000006AC107262F56040244BEA435B824140C220A48A66F56040244BEA435B824140C220A48A66F5604032789CE14A82414006AC107262F5604032789CE14A82414006AC107262F56040244BEA435B824140

試したこと

Polygonの場合、コンストラクタの引数を二つ指定しないといけないようなのですが、指定方法まではわかりませんでした。

補足情報(FW/ツールのバージョンなど)

Django3.0.8
python3.8
必要な情報が抜けている可能性があります。お手数ですが、教えていただけましたら幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

下記のようにした場合どうでしょうか。

def as_dict(self): mesh = self.obj return { 'type': 'Feature', 'properties': { 'mesh': { 'id': mesh.mesh_id } }, 'geometry': { 'type': 'Polygon', 'coordinates': [[point.x, point.y] for point in mesh.latlng]] } }

投稿2020/10/23 22:02

編集2020/10/24 07:40
sfdust

総合スコア1135

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

okiron9619

2020/10/24 02:46

回答ありがとうございます。 すみません、質問の仕方がわるかったかもしれません。 回答していただいたような、記述方法とPolygonオブジェクトの各座標のアクセス方法について教えていただきたいというものでした。 Pointであれば、'coordinates':[mesh.latlng.x,mesh.latlng.y]のように、各座標にアクセスできるのですが、Polygonの場合がわからないというものです、、、
sfdust

2020/10/24 03:05 編集

>Pointであれば、'coordinates':[mesh.latlng.x,mesh.latlng.y]のように、各座標にアクセスできるのですが、Polygonの場合がわからないというものです それについては、Meshデータベースのデータ構造が示されていない限り回答しようがありません。 「データベースには、mesh_id, latlngのカラムでデータがあります。」とあり、 「latlngには、geometry型, Polygon, srid = 4326」とのことなので、 latlngカラムの中に、何らかの形式でPolygonのデータが含まれているということでしょうが、 latlngカラムの中に実際にどのようにPolygonのデータが記録されているかは、データベースにMeshデータを記録するプログラムによると思われるので、現状示されている情報だけでは、Polygonの取り出し方は分かるはずもありません。 それとも何か公式にcsvなどで落とせるデータなのでしょうか?
okiron9619

2020/10/24 03:15

申し訳ありません。 質問を編集致しました。 データベースの概要について、記載いたしましたが、まだ、必要な情報が欠けているかもしれません。
sfdust

2020/10/24 04:47

手探りですが、修正しました。エラーになるかもしれませんが。試してみてください。
okiron9619

2020/10/24 14:46

ありがとうございます。 回答していただいたコードで試してみたのですが、 TypeError: Object of type ndarray is not JSON serializable というエラーが出ました。 回答していただいたコードのように、上手く1行にまとめることはできませんでしたが、 以下のようにすると、(見栄えはよくないですが)geojson形式に格納することはできました。 [[ [mesh.latlng[0][0][0], mesh.latlng[0][0][1]], [mesh.latlng[0][1][0], mesh.latlng[0][1][1]], [mesh.latlng[0][2][0], mesh.latlng[0][2][1]], [mesh.latlng[0][3][0], mesh.latlng[0][3][1]], [mesh.latlng[0][4][0], mesh.latlng[0][4][1]] ]]
sfdust

2020/10/25 01:49

それでしたら 'coordinates': [[ [point[0], point[1]] for point in mesh.latlng[0] ]] とすると多少短くできるかもしれません。
okiron9619

2020/10/25 06:02

そちらのコードでもエラーが出てしまいます、、、 'coordinates': [[ [point.x, point.y] for point in mesh.latlng[0] ]]のようにしても同様でした。 2重ループにしないと厳しい模様でしょうか、、、
sfdust

2020/10/25 11:04

二十ループでうまくいくならそれでいいかもしれません。 たとえば、 'coordinates': のところは正常にできている状態で mesh = self.obj の直後に下記の8つを書いて実行したとき、 print(mesh.latlng) print(mesh.latlng[0]) print(mesh.latlng[0][0]) print(mesh.latlng[0][0][0]) print(type(mesh.latlng)) print(type(mesh.latlng[0])) print(type(mesh.latlng[0][0])) print(type(mesh.latlng[0][0][0])) それぞれどのような出力がされるでしょうか。
okiron9619

2020/10/27 10:47

返信遅れ申し訳ありません。 そちらのコードを実行した結果の1例を示します。 SRID=4326;LINEARRING (135.674267281115 35.0124101957332, 135.674767281115 35.0124101957332, 135.674767281115 35.01191019573319, 135.674267281115 35.01191019573319, 135.674267281115 35.0124101957332) (135.674267281115, 35.012410195733196) 135.674267281115 <class 'django.contrib.gis.geos.polygon.Polygon'> <class 'django.contrib.gis.geos.linestring.LinearRing'> <class 'tuple'> <class 'float'>
sfdust

2020/10/27 13:11 編集

'django.contrib.gis.geos.polygon.Polygon django.contrib.gis.geos.linestring.LinearRing それぞれのソースを見ましたが、それぞれ__iter__メソッドを持っているので 二重forループの内包表記で print([[ring[0], ring[1]] for poly in mesh.latlng for ring in poly]) としてみた場合はどう表示されるでしょうか。(エラーが途中で出るかもしれませんが)
okiron9619

2020/10/28 02:02

ありがとうございます。 最終行部分の抜粋です。以下のような出力でした。 [[135.67826728111498, 35.016910195733196], [135.67876728111497, 35.016910195733196], [135.67876728111497, 35.016410195733194], [135.67826728111498, 35.016410195733194], [135.67826728111498, 35.016910195733196]] 以下のように記述することで、geojson形式に格納することができました。 'coordinates':[[[ring[0], ring[1]] for poly in mesh.mesh.latlng for ring in poly]]
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問