これは MIERUNE Advent Calendar 2025 の5日目の記事です。
昨日は @koyamagon さんによる 事務員がAI使ってChrome拡張機能を作った話 でした。
はじめに
QGISとかjupyber notebookなどでジオなデータを普段から利用されている人であれば、以下のデータは良く使っているのではないでしょうか。
国土数値情報ダウンロードサイトの「行政区域データ」です!
このデータの用途ですが、都道府県界や市町村界などを確認したいことが主な用途になるかと思います。
ただ、小縮尺の表示で良い用途の時は、用途に対して頂点が過剰に多く、地図への描画に時間がかかったり、データサイズ自体が重たかったりと使い勝手が悪かったりします(あくまで小縮尺に限定された用途での利用時の話です)。
一方、ESRIさんは「全国都道府県界データ2020(簡易版)」というデータを提供しています。
私はESRIユーザーだったので、これは便利に利用させてもらっていました。
ただ、利用規約の遵守事項として以下の記述があります。
お客様は、本データをArcGISシリーズ(アメリカ合衆国カリフォルニア州法人である Environmental Systems Research Institute, Inc.の地理情報システムに関する一連のソフトウェア製品)以外のソフトウェアで使用することはできません。
よって、QGISなどのオープンソースなソフトでは利用できませんし、他の商用GISでも利用できません。
では、なければ作ろうということで、国土数値情報ダウンロードサイトの「行政区域データ」から、「全国都道府県界データ2025(簡易版)」を作成していこうと思います。
ここで利用するのがGeoPandasです。
GeoPandas Version 1.1.0の新機能simplify_coverageによる変換
国土数値情報ダウンロードサイトから「行政区域データ」を2025年度版を全国分ダウンロートします。
まずはダウンロードしたデータをGeoPandasで読み込みます。
6.5+ MBのメモリを使っています。
import geopandas as gpd
gdf = gpd.read_file("N03-20250101_prefecture.shp", encoding="utf-8")
gdf.info()
<class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 121990 entries, 0 to 121989
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 N03_001 121990 non-null object
1 N03_002 0 non-null object
2 N03_003 0 non-null object
3 N03_004 0 non-null object
4 N03_005 0 non-null object
5 N03_007 121990 non-null object
6 geometry 121990 non-null geometry
dtypes: geometry(1), object(6)
memory usage: 6.5+ MB
地図に描画してみます。都道府県界が表示されます。
私のPC(MacBook Air M2)だと、9.1sかかりました。
それでは、Version1.1から追加された新機能simplify_coverageで都道府県界を簡易化していきます。
simplify_coverageについては、公式ドキュメントの概要を以下に示しておきます。
- simplify_coverageは、Visvalingam-Whyattアルゴリズムを用いて、有効な被覆を維持しながら辺を簡略化します
- つまり、ポリゴンの頂点を減らしつつも、隣接するポリゴンに隙間ができたり、オーバーラップすることがない
- 最も簡略化されたケースでは、多角形は三角形に縮小される
- Shapely >= 2.1 が必要
- 以下のパラメータを設定できる
-
tolerance: float
- 単純化の度合いは、削除される三角形の面積の平方根にほぼ等しくなる
- 単位はGeoSeriesの座標参照系と同じ
- 例えば、単位がメートルである投影CRSでtolerance=100を使用すると、実際の距離は100メートルになる
-
simplify_boundary: bool (default True)
- デフォルト(True)では、カバレッジの内部エッジと境界の両方が簡略化される
- Falseに設定すると、内部エッジのみが簡略化される
-
tolerance: float
実際に簡略化してみましょう。
まずはtoleranceを0.01で実行してみます。
gdf_simple = gdf.simplify_coverage(tolerance=0.01, simplify_boundary=True)
gdf_simple.info()
<class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 121990 entries, 0 to 121989
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 N03_001 121990 non-null object
1 N03_002 0 non-null object
2 N03_003 0 non-null object
3 N03_004 0 non-null object
4 N03_005 0 non-null object
5 N03_007 121990 non-null object
6 geometry 121990 non-null geometry
dtypes: geometry(1), object(6)
memory usage: 6.5+ MB
<Axes: >
<class 'geopandas.geoseries.GeoSeries'>
RangeIndex: 121990 entries, 0 to 121989
Series name: None
Non-Null Count Dtype
-------------- -----
121990 non-null geometry
dtypes: geometry(1)
memory usage: 953.2 KB
memory usageが6.5+ MBから953.2 KBに縮小されましたね。
地図にも描画してみます。
9.1sかかっていたのが、5.0sと短くなりました。
次にtoleranceを1で実行してみます。
memory usageはtoleranceが0.01の時と変わりません。
gdf_simple = gdf.simplify_coverage(tolerance=1, simplify_boundary=True)
gdf_simple.info()
<class 'geopandas.geoseries.GeoSeries'>
RangeIndex: 121990 entries, 0 to 121989
Series name: None
Non-Null Count Dtype
-------------- -----
121990 non-null geometry
dtypes: geometry(1)
memory usage: 953.2 KB
地図を表示してみます。
こちらも、ほぼ5秒と描画速度に変化はありませんでした。
ただ、北海道はだいぶ簡素化されて、原型ととどめていません。
まとめ
GeoPandasの新機能simplify_coverageにより、トポロジーを保ちつつ、ポリゴンの形状を簡素化できました。結果、データの軽量化と地図描画の速度を向上できました。
一方、ここはsimplify_coverageの仕様ではありますが、どれだけ簡素化されても地物が消失することはなく、「最も簡略化されたケースでは、多角形は三角形に縮小される」ので、地物の数は変化せず、三角形のポリゴンだけが残ります。
よって、地物数は変わらないので、データサイズや地図描画速度については、一定のところで頭打ちになるという理解をしています。
また、簡素化されてデータが消失しないことは、用途によってはマッチしないかもしれません。
小さな離島などは面積を決めてデータを削除してあげると、用途にあったデータを作成できるかもしれません。





