チーム「shpファイル」のメンバーが足りません



:::note info
これは [MIERUNE AdventCalendar 2023](https://qiita.com/advent-calendar/2022/mierune)…6日目の記事です。
昨日は @KEI_YAMA さんによる [テスト駆動開発でブログアプリのバックエンドを実装してみる](https://qiita.com/KEI_YAMA/items/fa942ff57ea77fefe296) でした。
:::

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/ee1f3010-28d5-11b3-15d1-7ea772576a3b.png" width=500 />

はい出オチです（DALL-E２画伯による[生成画像](https://www.bing.com/images/create/e688a6e99a8ae789b9e692aee38392e383bce383ade383bc6e4babae3818ce38081e99b86e7b590e38197e381a6e38184e3828b1960e5b9b4e4bba3e789b9e692aesfe698a0e794bbe381aee382b9e38381e383bce383abe58699e79c9fe38082e381aae3818ae38081e59084e383a1e383b3e38390e383bce381aee38386e383bce3839e/1-6558766bf80a44e195a4615aafb81643?id=pzSymIESuyc%2b31BRkAbtcw%3d%3d&view=detailv2&idpp=genimg&FORM=GCRIDP&ajaxhist=0&ajaxserp=0)をベースにしていますので適宜利用可能かと）


## はじめに

GISでデファクトスタンダードと呼ばれはや数十年…であるSHP（しぇいぷ）ファイルというファイル形式あります。
呼び名としては、SHPファイルのほかにShapeファイル・シェープファイル・シェイプファイル・例のアレ等いろいろです。

最近では、生まれたときからSHPファイルがすでにあったという**SHPファイルネイティブ世代**も世間を賑わせております（知らんけど)


そんなSHPファイルネイティブ世代やGIS初学者が、この記事で紹介する事案について、幼少時に焚き火を触ってから火の怖さを知る等とされる「ネイティブアメリカンの教え」の如く最初にやらかしがちなことがらですが、あまりに些末すぎてこのような情報や検証が世間にはあまりみあたらないのでこちらにおいておきます。


結論を先に書くと

:::note warn
拡張子shpのファイルだけ相手に送っても何も見れないよ！
:::

です。


いわばこんな感じ
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Hello there!<br>General <a href="https://twitter.com/shapefiIe?ref_src=twsrc%5Etfw">@shapefiIe</a>! <a href="https://twitter.com/hashtag/mappymeme?src=hash&amp;ref_src=twsrc%5Etfw">#mappymeme</a> <a href="https://t.co/ZeLviu3nqP">pic.twitter.com/ZeLviu3nqP</a></p>&mdash; 🥔🗺️ ᴘᴏᴋᴀᴛᴇᴏ ᴍᴀᴘs (@pokateo_maps) <a href="https://twitter.com/pokateo_maps/status/1405190483572367360?ref_src=twsrc%5Etfw">June 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


まあでも、初学者の方にとってこんなルールは理解に苦しむでしょう、無理もありません。
私だっていきなり電話かかってきて「今すぐ北京ダック一式送って！」と恫喝されたらどうしたらいいかわかりませんもの。

## なんで？

仕様です。すみません。

> An ESRI shapefile consists of a main file, an index file, and a dBASE table

https://www.esri.com/content/dam/esrisites/sitecore-archive/Files/Pdfs/library/whitepapers/pdfs/shapefile.pdf


> The term "shapefile" is quite common, but the format consists of a collection of files with a common filename prefix, stored in the same directory. The three mandatory files have filename extensions .shp, .shx, and .dbf

https://en.wikipedia.org/wiki/Shapefile



つまり上記のネタツイートにあるように

`hoge.shp`
`hoge.shx`
`hoge.dbf`

の３つが必須とされています。

最近はほかにもいろいろな`hoge.xxx`といった拡張子が最初存在したり、GISソフトによってはあとから関連ファイルが生成されたりくっついてきます。そのため、他のユーザーから「shpファイルくださーい」と言われた場合は、今後の信頼性と世界の平穏を確保するために、同じ名前で拡張子が異なるファイルも一緒に念のため送ってあげましょう。

また、今回試しで使ってみる国土数値情報では、SHPファイルグループとは別の形式である、GeoJSONやXMLなども同梱されててなかなかややこしいです…ですので、GeoJSONとか数メガのXMLが入っている場合は送らなくても良い場合があります。

なお、上記[wikipedia先生](https://en.wikipedia.org/wiki/Shapefile)によるとshpファイルに関わる拡張子がいろいろ列挙されております。

必須とされる
`hoge.shp`　`hoge.shx`　`hoge.dbf`
以外ですと、独断と偏見ですがこのあたりの拡張子は高頻度で遭遇します

- hoge.prj
- hoge.sbn
- hoge.sbx
- hoge.qpj

また、こちらもたまに見ます

- hoge.fbn
- hoge.fbx
- hoge.ain
- hoge.aih
- hoge.cpg
- hoge.qix

これらはほとんど見たこと無い気がする…松茸レベルかな…

- hoge.ixs
- hoge.mxs

あとQGIS/ArcGISつかう方とやり取りしているとこのへんのファイルもくっついてくることがあります

- hoge.qml
- hoge.lyr


## 揃ってないとどうなるか

それでは、任意の拡張子だけの場合や、何かがヌケている場合どのような挙動をするのか確かめてみます。

環境はmacOS12.6.3 QGIS 3.28.8-Firenzeです。
さすがにこういう検証を意図的にやったことがないので、感電とか落盤しないか心配です。

今回は皆さんよく使う国土数値情報における[行政区域の令和５年・東京都データ](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03-v3_1.html)をサンプルとして用います。
DLしてくるとこのような中身になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/982a426a-8e73-d3ea-d80e-a42ef80c6a90.png)

*.shpをQGISで開くとこうなります、属性もこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/44381e93-47e3-3265-5a37-371d034bcc13.png)


なお、
- N03-23_13_230101.geojson
- N03-23_13_230101.xml
- KS-META-N03-23_13_230101.xml

は、前述のとおり今回検証に扱う一連のshpファイル群とは異なり、同梱されているGeoJSON形式やメタデータですので今回の検証から除外します(その理由は[こちら](https://nlftp.mlit.go.jp/first.html)にあるんですが、xmlの説明がないけどええまあはい)

 
 ### *.shpのみしかない場合
 では、*.shpのみ送られてきた場合はどうのような挙動になるでしょうか？
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/a44161a6-e05f-eac6-8e28-be9eed4f39fe.png)

 QGISでデータを追加するデータソースマネージャーでN03-23_13_230101.shpを単一で指定し「追加」を押すと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/b1672dcf-f13f-3119-e5f4-5d9025847cb8.png)


>無効なデータソース: /hogehoge/hoge/N03-20230101_13_GML/N03-23_13_230101.shp は有効または認識されたデータソースではありません

と叱られます。ドラッグ＆ドロップでも同じです。

### *.dbfがない場合

では、*.dbfがない場合はどうでしょう、こんな構成に変えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/4de058ff-1caf-68fc-2121-b765e28be8e9.png)

こちらもQGISのデータソースマネージャーではN03-23_13_230101.shpをむやり指定し、「追加」を押すと

あら、マップキャンバスに東京都の行政区域が表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/258a0a9c-95d3-b56d-c482-02859ac4374b.png)



でも、*.dbf…つまり属性のデータがないので属性テーブルをQGISで開いてみると空っぽです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/b11ec2fb-1d7c-2b28-af2a-dd664a72e2f0.png)

もちろん、ドラッグ＆ドロップでも同じ現象になります。

無理やり開くと、てっきりエラーが出ると思ったんですが、形状は読み込んでくれてしまうので、送られたデータを確認するときには形状だけでなく属性テーブルも上記のように中身を確認することをおすすめします(私みたいなジオジサンになると数々の事案に遭遇しているので癖になっている…)


### *.shxがない場合

では、*.shxを削ってみましょう。この組み合わせになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/d739171e-6324-0011-d337-9c40524471c3.png)

とすると、やはり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/b1672dcf-f13f-3119-e5f4-5d9025847cb8.png)


>無効なデータソース: /hogehoge/hoge/N03-20230101_13_GML/N03-23_13_230101.shp は有効または認識されたデータソースではありません

と叱られます。こちらもドラッグ＆ドロップでも同じです。

### そもそもフィルタリングすると読めない

上記のように、shpファイルに必須といわれる、*.shp *.shx *.dbfが揃っていな場合はデータソースマネージャーでデータ形式を`ESRI Shapefiles`にフィルタリングした途端、ターゲットのファイルが全てグレーアウトしてしまい、選択することができなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/32a4e26e-5c74-20ea-e116-930a121e5b6b.png)



### 補足…*.prjがない場合

*.prjファイルは、必須ではないものの、各データの座標系の定義が書き込まれています。中身はこんな感じです

>GEOGCS["GCS_JGD_2011",DATUM["D_JGD_2011",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]


では*.prjがない場合はどうなるのでしょうか？

読めることは読めます、属性も読めている…あれ、背景のOpenStreetMapなどがなんか変だ…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/dd18a3b7-0908-1f10-308b-ea264f9c731d.png)

つまり、座標系の定義がないためOpenStreetMapなどEPSG:3857の地図タイル背景で確認すると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/b9306ff6-29c8-164b-444b-47d398f03393.png)

アフリカ大陸の東にある座標[0,0]周辺…いわゆる[null島](https://ja.wikipedia.org/wiki/%E3%83%8C%E3%83%AB%E5%B3%B6)付近に飛ばされてしまいます。


なお、最近のQGISでは*.prjがない…つまり座標系定義がない場合「？」マークがレイヤの右横に出るしくみになっています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/5c3962ef-f996-8eb0-889c-77b72e8cfc2d.png)

もし出てしまったらコチラの「？」マークを押すと、正しい座標系・投影法を選択するウインドウが開きます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/43f5eb5e-87b6-a473-d49d-37c4c48ea558.png" width=400 />

ここで本来の座標系を定義してあげると、ちゃんとした位置にデータが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/29cd2b72-dd46-e7b5-d9de-dc99401f1273.png)

ただし、この処理ではQGISのプロジェクト上で「強制的に座標系を定義」しているだけですので、今後このデータを用いる際は新規ファイルとしてエクスポートすることをおすすめします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/8264fab6-8dc2-5abf-0a7a-471c950e441b.png)

:::note
前述のようにshpファイルが策定された際、とくに*.prjは必須ではなかったのですが、この記事を書きながらArcViewからArcGISにバージョンアップされた1999年頃などにオンザフライ投影機能が実装され、当該shpがそもそもどの座標系で作成されたか認識するためにprjが付与された瞬間に立ち会ったことを思い出しました
オンザフライ投影や*.prjの実装当時、なんだこれ、すげー！別々の投影法で作成してもちゃんと重なる！便利だ！と感動したのですが、それまではメタデータもメモもないまま送りつけられてきたshpが一体なんの座標系で作られたかを推定するのにトライ＆エラーで半日以上かかるなどということもありました(略)、ということで*prj大事です。
:::

## まとめ

shpファイル関連でなにかのファイルが欠けていると、感電も落盤もしませんでしたがさまざまな処理上の不整合が起きます。

なので、これらを送るときはまとめてZipファイルなどで圧縮して送りましょう！

…という毎回毎回ZIPする手間やヌケモレを先方に確認するコストをジオジサンとして20年くらいやってると疲れてきたので、これからはfgbとかgdbとかGeoJSONなどSHPを凌駕するフォーマットの出現が待たれますね（でもけっきょくshpはなかなか減らないし使ってしまう…）

なお、このへんの議論は[Switch from Shapefile](http://switchfromshapefile.org/)とか、Iguchi先生による[シェープファイルの真の後継規格 FlatGeobufの普及啓蒙活動](https://www.slideshare.net/KanahiroIguchi/foss4g-japan-2021-flatgeobuf)などを御覧ください。


:::note info
明日は@moritoruさんによる[地図のレンダリングを実現するまでの流れはどうなっているのか？](https://qiita.com/moritoru/items/d1b3c3efcd0474cd98ce#_reference-6be71ae98e4657f34868)です！　お楽しみにー
:::



<br><br><br><br><br><br>
<br><br><br><br><br><br>



----

※DALL-E画伯にはこういうのも作っていただいたのだが、後ろのロボがなんかすごく悪い感じだったり、6人っていってるのに5人だったり、赤が被りすぎたのでこれはボツに…

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100567/97b48a5c-43a8-6ddd-d56a-67f0c3475c27.png" width=300 />