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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

4205閲覧

geopandasを用いたシェープファイルの出力で、UnicodeDecodeError(utf-8)またはSchemaError(shift-jis)が発生してしまいます

tohon

総合スコア10

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2020/07/07 03:05

国土数値情報から土地利用細分メッシュ(リンク内容)をダウンロードし、その中にある区分コードに応じた土地利用種別(リンク内容)をexcelにコピーした表を使い新規フィールドとして追加したシェープファイルを作ろうとしています。フィールドに種別を追加した後で新しいシェープファイルとして出力するという操作を最後に行いたいのですが、そこでエラーが発生してしまいファイルの出力ができず、対策方法が分からず困っております。
(一連の作業はjupyter notebook上で行っております。)

元の土地利用細分メッシュの文字コードはshift-jisで、出力はshift-jisとutf-8のどちらも試しました。

shift-jisで出力しようとしたときはSchemaErrorが出て、別のコードならいけるかもしれないと思いutf-8で出力しようとしたときはUnicodeDecodeErrorが出てしまいどちらでも不可能でした。

エラーコードを見るに元のシェープファイルのフィールド名'メッシュ'に何か問題があるようなのですが、それが何なのかわかっておりません。

以下に作成したコード、shift-jisで出力を試みた時のエラーコード、utf-8で出力を試みた時のエラーコードを記載いたします。

作成したコード

python

1import pandas as pd 2import geopandas as gpd 3import openpyxl 4 5df1 = gpd.read_file('C:\Users\ユーザー名\土地細分メッシュ\L03-b-16_5339-tky.shp', encoding='shift-jis') 6df1['土地利用種'] = df1['土地利用種'].apply(int) 7df1['メッシュ'] = df1['メッシュ'].apply(int) 8 9kubun = pd.read_excel('C:\Users\ユーザー名\土地細分メッシュ\区分.xlsx') 10kubun['コード'] = kubun['コード'].apply(int) 11 12df1_code = list(df1['土地利用種']) 13 14kubun_code = list(kubun['コード']) 15kubun_name = list(kubun['種別']) 16 17add_kubun = [] 18for i in df1_code: 19 add_kubun.append(kubun_code.index(i)) 20 21input_kubun = [] 22for s in add_kubun: 23 input_kubun.append(kubun_name[s]) 24 25df1.insert(2, '種別', input_kubun) 26 27df1.to_file('土地利用区分追加.shp', driver='ESRI Shapefile', encoding='shift-jis')

shift-jisで出力しようとしたときのエラーコード

python

1 2--------------------------------------------------------------------------- 3CPLE_AppDefinedError Traceback (most recent call last) 4fiona/ogrext.pyx in fiona.ogrext.WritingSession.start() 5 6fiona/_err.pyx in fiona._err.exc_wrap_int() 7 8CPLE_AppDefinedError: Failed to create field name 'メッシュ': cannot convert to shift-jis 9 10During handling of the above exception, another exception occurred: 11 12SchemaError Traceback (most recent call last) 13<ipython-input-4-79f9a8b84e47> in <module> 14 26 df1.insert(2, '種別', input_kubun) 15 27 16---> 28 df1.to_file('土地利用区分追加.shp', driver='ESRI Shapefile', encoding='shift-jis') 17 18C:\ProgramData\Anaconda3\lib\site-packages\geopandas\geodataframe.py in to_file(self, filename, driver, schema, **kwargs) 19 502 from geopandas.io.file import to_file 20 503 21--> 504 to_file(self, filename, driver, schema, **kwargs) 22 505 23 506 def to_crs(self, crs=None, epsg=None, inplace=False): 24 25C:\ProgramData\Anaconda3\lib\site-packages\geopandas\io\file.py in to_file(df, filename, driver, schema, **kwargs) 26 126 with fiona_env(): 27 127 with fiona.open( 28--> 128 filename, "w", driver=driver, crs=df.crs, schema=schema, **kwargs 29 129 ) as colxn: 30 130 colxn.writerecords(df.iterfeatures()) 31 32C:\ProgramData\Anaconda3\lib\site-packages\fiona\env.py in wrapper(*args, **kwargs) 33 394 def wrapper(*args, **kwargs): 34 395 if local._env: 35--> 396 return f(*args, **kwargs) 36 397 else: 37 398 if isinstance(args[0], str): 38 39C:\ProgramData\Anaconda3\lib\site-packages\fiona\__init__.py in open(fp, mode, driver, schema, crs, encoding, layer, vfs, enabled_drivers, crs_wkt, **kwargs) 40 261 c = Collection(path, mode, crs=crs, driver=driver, schema=this_schema, 41 262 encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, crs_wkt=crs_wkt, 42--> 263 **kwargs) 43 264 else: 44 265 raise ValueError( 45 46C:\ProgramData\Anaconda3\lib\site-packages\fiona\collection.py in __init__(self, path, mode, driver, schema, crs, encoding, layer, vsi, archive, enabled_drivers, crs_wkt, ignore_fields, ignore_geometry, **kwargs) 47 160 elif self.mode in ('a', 'w'): 48 161 self.session = WritingSession() 49--> 162 self.session.start(self, **kwargs) 50 163 except IOError: 51 164 self.session = None 52 53fiona/ogrext.pyx in fiona.ogrext.WritingSession.start() 54 55SchemaError: Failed to create field name 'メッシュ': cannot convert to shift-jis 56

utf-8で出力しようとしたときのエラーコード

python

1 2--------------------------------------------------------------------------- 3UnicodeDecodeError Traceback (most recent call last) 4UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 61: invalid continuation byte 5 6Exception ignored in: 'fiona._env.log_error' 7UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 61: invalid continuation byte 8--------------------------------------------------------------------------- 9UnicodeDecodeError Traceback (most recent call last) 10UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7 in position 64: invalid continuation byte 11 12Exception ignored in: 'fiona._env.log_error' 13UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe7 in position 64: invalid continuation byte 14--------------------------------------------------------------------------- 15UnicodeDecodeError Traceback (most recent call last) 16UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe6 in position 64: invalid continuation byte 17 18Exception ignored in: 'fiona._env.log_error' 19UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe6 in position 64: invalid continuation byte 20--------------------------------------------------------------------------- 21UnicodeDecodeError Traceback (most recent call last) 22<ipython-input-3-c48df3a82a00> in <module> 23 26 df1.insert(2, '種別', input_kubun) 24 27 25---> 28 df1.to_file('土地利用区分追加.shp', driver='ESRI Shapefile', encoding='utf-8') 26 27C:\ProgramData\Anaconda3\lib\site-packages\geopandas\geodataframe.py in to_file(self, filename, driver, schema, **kwargs) 28 502 from geopandas.io.file import to_file 29 503 30--> 504 to_file(self, filename, driver, schema, **kwargs) 31 505 32 506 def to_crs(self, crs=None, epsg=None, inplace=False): 33 34C:\ProgramData\Anaconda3\lib\site-packages\geopandas\io\file.py in to_file(df, filename, driver, schema, **kwargs) 35 126 with fiona_env(): 36 127 with fiona.open( 37--> 128 filename, "w", driver=driver, crs=df.crs, schema=schema, **kwargs 38 129 ) as colxn: 39 130 colxn.writerecords(df.iterfeatures()) 40 41C:\ProgramData\Anaconda3\lib\site-packages\fiona\env.py in wrapper(*args, **kwargs) 42 394 def wrapper(*args, **kwargs): 43 395 if local._env: 44--> 396 return f(*args, **kwargs) 45 397 else: 46 398 if isinstance(args[0], str): 47 48C:\ProgramData\Anaconda3\lib\site-packages\fiona\__init__.py in open(fp, mode, driver, schema, crs, encoding, layer, vfs, enabled_drivers, crs_wkt, **kwargs) 49 261 c = Collection(path, mode, crs=crs, driver=driver, schema=this_schema, 50 262 encoding=encoding, layer=layer, enabled_drivers=enabled_drivers, crs_wkt=crs_wkt, 51--> 263 **kwargs) 52 264 else: 53 265 raise ValueError( 54 55C:\ProgramData\Anaconda3\lib\site-packages\fiona\collection.py in __init__(self, path, mode, driver, schema, crs, encoding, layer, vsi, archive, enabled_drivers, crs_wkt, ignore_fields, ignore_geometry, **kwargs) 56 160 elif self.mode in ('a', 'w'): 57 161 self.session = WritingSession() 58--> 162 self.session.start(self, **kwargs) 59 163 except IOError: 60 164 self.session = None 61 62fiona/ogrext.pyx in fiona.ogrext.WritingSession.start() 63 64fiona/ogrext.pyx in fiona.ogrext.Session.get_schema() 65 66UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 9: unexpected end of data 67

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーコードを見るに元のシェープファイルのフィールド名'メッシュ'に何か問題があるようなのですが、それが何なのかわかっておりません。

内部で使用しているGDALのAPIに問題があるようです。調べた結果、メッシュの最後の文字がNGです。最後の行のdf1.to_file()の前に以下のコードを入れてメッシュを「メッシ」にすると動くと思います。

python

1columns = df1.columns.tolist() 2columns[columns.index('メッシュ')] = 'メッシ' 3df1.columns = columns

[追記]
Windowsでは上記の対策ではNGでしたので、シェープファイルを作るだけであれば下記の対応で可能です(根本的な解決ではないです)。上記の代わりにフィールド名を全て英語名に変換します。

python

1df1.columns = ["mesh", "utilization", "type", "datetime", "geometry"]

その上で書き出す際にutf-8を指定して下さい。

python

1df1.to_file("土地利用区分追加.shp", driver="ESRI Shapefile", encoding="utf-8")

参考情報

C++から直接GDALのAPIを呼び出しても同じようにがデコードされません。下記のソースコードはシェープファイルにフィールド名メッシュをUTF-8指定で作成し、読み出すだけのプログラムです。

c++

1#include <iostream> 2#include <iomanip> 3#include <string> 4#include "gdal.h" 5#include "ogr_api.h" 6#include "ogr_p.h" 7 8void dump_utf8(const std::string &s) 9{ 10 std::cout << s << ":"; 11 for (std::string::size_type i = 0; i < s.length(); ++i) 12 { 13 int val = (int)(s[i]) & 0xFF; 14 std::cout << " 0x"; 15 std::cout << std::hex << std::setfill('0') << std::setw(2); 16 std::cout << val; 17 } 18 std::cout << std::endl; 19} 20 21int main() 22{ 23 std::string s = u8"メッシュ"; 24 dump_utf8(s); 25 26 // initialize 27 OGRRegisterAll(); 28 OGRSFDriverH drv = OGRGetDriverByName("ESRI Shapefile"); 29 OGRDataSourceH ds = OGR_Dr_CreateDataSource(drv, "test.shp", nullptr); 30 31 // options 32 char **options = nullptr; 33 options = CSLSetNameValue(options, "ENCODING", "UTF-8"); 34 35 // layer 36 OGRSpatialReferenceH srs = OSRNewSpatialReference(nullptr); 37 OGRwkbGeometryType geom_type = static_cast<OGRwkbGeometryType>(1); 38 OGRLayerH layer = GDALDatasetCreateLayer(ds, "test", srs, geom_type, options); 39 40 // field 41 OGRFieldDefnH field = OGR_Fld_Create(s.c_str(), OFTString); 42 OGRErr err = OGR_L_CreateField(layer, field, true); 43 44 // check 45 OGRFeatureDefnH feature = OGR_L_GetLayerDefn(layer); 46 OGRFieldDefnH field_out = OGR_FD_GetFieldDefn(feature, 0); 47 std::string s_out = OGR_Fld_GetNameRef(field_out); 48 dump_utf8(s_out); 49 50 // release 51 OGR_Fld_Destroy(field); 52 CSLDestroy(options); 53 OSRDestroySpatialReference(srs); 54 OGRReleaseDataSource(ds); 55 56 return 0; 57}

結果

terminal

1$ g++ --std=c++11 -o test_gdal test_gdal.cc -I /Users/guest/miniconda3/envs/geo/include -L /Users/guest/miniconda3/envs/geo/lib -lgdal 2$ DYLD_LIBRARY_PATH=/Users/guest/miniconda3/envs/geo/lib ./test_gdal 3メッシュ: 0xe3 0x83 0xa1 0xe3 0x83 0x83 0xe3 0x82 0xb7 0xe3 0x83 0xa5 4Warning 6: Normalized/laundered field name: 'メッシュ' to 'メッシ�' 5メッシ�: 0xe3 0x83 0xa1 0xe3 0x83 0x83 0xe3 0x82 0xb7 0xe3

バグの発生箇所

UTF-8を指定した際のバグの発生箇所を特定しました。
https://github.com/OSGeo/gdal/blob/master/gdal/ogr/ogrsf_frmts/shape/shapefil.h
の515行目で下記の定義がされています。

c

1#define XBASE_FLDNAME_LEN_WRITE 10

これはフィールド名に使えるのは10バイトであることを意味しています。「メッシュ」はUTF-8では12バイト(1文字3バイト)、SJISでは8バイト(1文字2バイト)になります。したがってUTF-8を指定した場合、10文字制限で最後の2バイトが切り取られ、文字列として不完全になりエラーとなっていました。

投稿2020/07/07 17:09

編集2020/07/08 11:01
yymmt

総合スコア1615

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

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

tohon

2020/07/08 03:24

詳細のご回答、誠にありがとうございます。 ュに問題があったということで、ご提案いただいた'メッシュ'を'メッシ'に変更するための文をdf1.to_fileの前に挿入して書き出しを行おうとしましたが、TypeError: Index does not support mutable operations が発生してしまい、今度はカラムの書き換えができないようです。 「ュ」を消去したい場合、カラム全体を何か別の配列に入れ替える必要があるでしょうか?
yymmt

2020/07/08 03:57

すいません、カラムの型がタプルだったので、tolist()でリストにして下さい。本文を修正します。
tohon

2020/07/08 04:55

早速ありがとうございます! 変更後の方法、 columns = df1.columns.tolist() columns[columns.index('メッシュ')] = 'メッシ' df1.columns = columns で試してみますと、今度は書き換えた「メッシ」で最初と同じエラーが発生しています。 SchemaError: Failed to create field name 'メッシ': cannot convert to shift-jis ここは他に様々な語(「1」、「mesh」等)で置き換えを試しましたが結果は同様でした。 df1.to_fileでファイルを出力する前にprint(df1.head())でカラム名を調べると、ちゃんと名前は置き換わっているようです。シェープファイルへの書き出しの段階でおっしゃっていただいている「GDALに異常がある」ということの影響を受けているのでしょうか。
yymmt

2020/07/08 09:10

macOSとLinuxで上記の対応で動作しましたが、確かにWindowsで行ったところ同エラーが発生しました。OSによる差もあるようです。対策はさらに追記します。
tohon

2020/07/09 01:57 編集

バグの発生個所と原因を特定いただきまして、誠にありがとうございます。何が原因で起きているのかまったくわからずの状態でありましたので、突き止めていただけて深く感謝いたします。 申し遅れてしまい恐縮ですが、作業は全てwindowsで行っていましたのでおっしゃる通りこのエラーがずっと発生している状態になっていました。 また、英語名で置き換える方法で目的のファイルを作成することができ、安心いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問