GIS奮闘記

現役GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

Pythonで位置参照情報ダウンロードサービスの Web API を使ってみよう

本日はみんな大好きな位置参照情報ダウンロードサービスについて書いてみようと思います。

位置参照情報ダウンロードサービスとは

以下エントリーでも紹介していますが、日本全国の大字町丁目または街区単位の座標を CSV形式でダウンロードできるWEBサイトです。

www.gis-py.com

位置参照情報ダウンロードサービス WEB APIとは?

このAPIを利用することで、位置参照情報を組み込んだ Webサイトやアプリケーションの開発を行うことが可能になります。また、データをダウンロードするには以下のような画面で一つ一つデータを手動でダウンロードする必要がありますが、APIを使うことでデータを一括でダウンロードしたりすることもできます。

f:id:sanvarie:20190706230310p:plain

API 仕様

API 仕様はここに公開されています。http://nlftp.mlit.go.jp/isj/specification_api_isj.pdf

以下のような形でリクエストを投げるとXML形式で結果が返ってきます。
f:id:sanvarie:20190706231349p:plain

例えば、このようなリクエストを投げると
http://nlftp.mlit.go.jp/isj/api/1.0b/index.php/app/getISJURL.xml?appId=isjapibeta1&areaCode=13000&fiscalyear=%27%E5%B9%B3%E6%88%9025%E5%B9%B4%27&posLevel=0

このような結果が返ってきます。
f:id:sanvarie:20190706231554p:plain

パラメータ

リクエストするURLに入れるパラメータはこのようになっています。必須は以下の二つのみですね。

  1. appId
  2. areaCode

f:id:sanvarie:20190706232101p:plain

areaCode コードですが、http://www.tt.rim.or.jp/~ishato/tiri/code/kanto.htmのようなサイトで一覧を手に入れることができます。

実行環境

Windows(64bit)
Python3.6.5

インストールが必要なライブラリ

lxml を使っていますので、pip install lxml でインストールしてください。

サンプルコード

今回は以下のデータをダウンロード、解凍する処理を書いてみました。

  1. 横須賀市のデータを使用
  2. 街区レベルのデータを使用
  3. すべての年度のデータをダウンロード
  4. 各年度毎にフォルダを作ってそこにデータ(zip)を格納して解凍
# -*- coding: utf-8 -*-
import zipfile
import os.path
import requests
from lxml import etree

class WebAPI(object):

    def __init__(self):
        self.appId = "isjapibeta1" #固定
        self.areaCode = "14201"    #固定
        self.posLevel = "0"        #街区レベル
        self.directory = "D:\data" #フォルダ作成先
        self.new_directory = ""    #ダウンロードしたデータの解凍先

    def get_url(self):
        """
        位置参照情報のWEBAPIを使用して各情報をXMLで取得します。
        """
        url = "http://nlftp.mlit.go.jp/isj/api/1.0b/index.php/app/getISJURL.xml" \
              "?appId=%s&areaCode=%s&posLevel=%s" %(self.appId, self.areaCode, self.posLevel)

        resp = requests.get(url, timeout=10)
        tree = etree.fromstring(resp.content)
        tree = tree.xpath('/ISJ_URL_INF/ISJ_URL/item/child::node()')

        for t in tree:
            if t.tag == "fiscalyear":
                self.make_directory(t.text)

            if t.tag == "zipFileUrl":
                self.download_zip(t.text)

    def make_directory(self,fiscalyear):
        """
        新しいフォルダを作ります
        """
        self.new_directory = os.path.join(self.directory, fiscalyear)
        if os.path.exists(self.new_directory) == 0: #なかったら作る
            os.makedirs(self.new_directory)

    def download_zip(self,text):
        """
        指定したURLからZIPをダウンロードします。
        """

        filename = text.split('/')[-1]
        r = requests.get(text, stream=True)
        with open(filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=1024):
                if chunk:
                    f.write(chunk)
                    f.flush()

            self.uncompress_zip(filename)

    def uncompress_zip(self,filename):
        """
        ZIP ファイルを指定したディレクトリに展開します。
        """
        zfile = zipfile.ZipFile(filename)
        zfile.extractall(self.new_directory)

if __name__ == '__main__':
    w = WebAPI()
    w.get_url()

このようにファイルがダウンロードされました。
f:id:sanvarie:20190707111150p:plain

各フォルダの中身を確認するとデータが解凍されていることが確認できました
f:id:sanvarie:20190707111246p:plain

大字・町丁目レベルでデータをダウンロードするには

上記プログラムの self.posLevel = "0" をself.posLevel = "1" に変更すればダウンロード可能です。

都道府県ごとのデータをダウンロードするには

self.areaCode = "14201" の部分を各都道府県ごとのコードに変更すればダウンロードできます。APIの使用を見る限りhttp://www.tt.rim.or.jp/~ishato/tiri/code/kanto.htmの中の市区町村コードの上二桁+000 が各都道府県コードになっているかと思います。

感想

けっこうあっさりとデータのダウンロードができました。位置参照情報をよく使うという方はぜひこのAPIを使ってみてください。