12
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

シェープファイルをGeoJSON形式に変換する

Posted at

前提

zip圧縮されたシェープファイル群(.shp, .shx, .dbf)を、GeoJson形式で出力する関数です。
当然、シェープファイル群のファイル名が共通している必要があります。
また、.geojsonファイルを出力するのではなく、メモリ上で処理します。
事前にpyshp(shapefile)が必要になります。

コード

import shapefile, io, zipfile

# zipファイルからshpファイルを探してファイル名を取得
def find_shpfile_inzip(zipped_shp):
	zip_infolist = zipped_shp.infolist()
	for info in zip_infolist:
		if not info.filename.startswith('__MACOSX/'): #Mac-ZIP対応
			if info.filename.endswith('.shp'):
				return info.filename

まずこのように、zip圧縮されたshapefileのファイル名を取得する関数を定義します。
この関数を用いて

# ZIP保存されたSHP群をGEOJSON形式で返す
def zipped_shp_to_geojson(zipped_shp):
	zipped_files = zipfile.ZipFile(zipped_shp)

	#zipファイルからshpファイルを探してファイル名を取得
	shp_name = find_shpfile_inzip(zipped_files)[:-4]

	#shapefile読み込みと適合判定
	try:
		shp_file_bytes = zipped_files.read(shp_name + '.shp')
		shx_file_bytes = zipped_files.read(shp_name + '.shx')
		dbf_file_bytes = zipped_files.read(shp_name + '.dbf')
	except:
		print("Imported file was not apropriate Shape-Zip-File.")
		return None

	geojson = dict(type="FeatureCollection", features=[])
	#pyshpはライブラリ内部でデコードするので、正しいエンコーディングでデコード出来るまでループ
	for codec in CODECS:
		try:
			reader = shapefile.Reader(shp=io.BytesIO(shp_file_bytes),
					                    shx=io.BytesIO(shx_file_bytes),
					                    dbf=io.BytesIO(dbf_file_bytes),encoding=codec)

			fields = reader.fields[1:]
			field_names = [field[0] for field in fields]
			for sr in reader.shapeRecords():
				atr = dict(zip(field_names, sr.record))
				geom = sr.shape.__geo_interface__
				geojson['features'].append(dict(type="Feature", \
				 geometry=geom, properties=atr))
			print(codec + 'encoding is correct.' )
			break
		except UnicodeDecodeError:
			print(codec + 'is not suitable for this file.')
			continue
	return geojson

これでgeojsonに変換されます。
エンコーディングについてはコメントのとおりです。pyshpではデフォルトだとUTF-8でデコードされますが、オープンデータで提供されるシェープファイルは、大半がcp932(Windows環境のShift-JIS)です。エンコーディングの指定が間違っているとUnicode errorが発生します。それならcp932を指定してデコードすれば良いのでは、と考えますが、当然ながらUTF-8等にも対応しておきたいところです。したがって、メジャーなエンコーディングのなかから適合するまでデコードし続けるようになっています(このモジュールの冒頭で、CODECS定数を定義してある)。

12
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?