create every day - 福野泰介の一日一創

続く福井の大雪警報、オープンデータ消火栓探しと警報取得Python3プログラム with SPARQL API

2018/02/06 23:55:00
#SPARQL #python #opendata 

消火栓がすっぽり埋まってしまうほどの大雪に見舞われた福井県。
大雪警報は継続中です。
大雪に伴う市民生活情報 – めがねのまちさばえ 鯖江市


左:完全に埋まった消火栓、右:消火栓救出成功!

火事から守る命綱、消火栓も合わせて除雪しておきましょう。

消火栓を探す - findhydrant
金沢では金属探知機で消火栓を探していたそうですが、緯度経度データ付きの消火栓オープンデータで市民の力で防災対策が可能です。 odp / オープンデータプラットフォームの消火栓テンプレートで登録すれば、すぐにこのアプリに反映されます!
金属探知機で消火栓探し除雪 金沢市消防局 | NHKニュース

警報チェックにオープンデータを活用します。
気象庁による配信されているオープンデータが、AITCによってSPARQL APIで取得できるようになっていました。
先端IT活用推進コンソーシアム - 公開API

福井県の警報・注意報のデータがあるURLを取得するSPARQLクエリーがこちら

select * { <urn:uuid:f57b5866-0c8c-3c92-9aff-10a715cdf48b> atom:entry ?o. ?o atom:updated ?updated. ?o atom:content ?content. ?o atom:link ?link. ?o atom:title ?title. FILTER(REGEX(?content, "福井")) FILTER(REGEX(?title, "気象特別警報・警報・注意報")) } order by desc(?updated) limit 1

これを使って、市町村毎の警報、注意報を取得するPython3のプログラムを作ってみました。

import urllib.request import urllib.parse import xml.etree.ElementTree as ET import dateutil.parser import sys if len(sys.argv) == 1: print("getalerm.py [pref] [city]") print("ex) python3 getalerm.py 福井 鯖江市") print() pref="福井" city="鯖江市" else: pref=sys.argv[1] city=sys.argv[2] query = ( 'PREFIX atom: <http://www.w3.org/2005/Atom#>\n' 'select * {\n' ' <urn:uuid:f57b5866-0c8c-3c92-9aff-10a715cdf48b> atom:entry ?o.\n' ' ?o atom:updated ?updated.\n' ' ?o atom:content ?content.\n' ' ?o atom:link ?link.\n' ' ?o atom:title ?title.\n' ' FILTER(REGEX(?content, "' + pref + '"))\n' ' FILTER(REGEX(?title, "気象特別警報・警報・注意報"))\n' '} order by desc(?updated) limit 1\n' ) print(query) url = "http://api.aitc.jp/ds/sparql?query=" + urllib.parse.quote(query) + "&output=xml" #print(url) resfn, headers = urllib.request.urlretrieve(url) #resfn = "/var/folders/0p/8n831_gn5j97jrlqmh5ddggc2s2n0c/T/tmpaqzg7_ib" print("sparql result file: " + resfn) tree = ET.parse(resfn) root = tree.getroot() xmlurl = tree.find(".//{http://www.w3.org/2005/sparql-results#}binding[@name='link']")[0].text updated = tree.find(".//{http://www.w3.org/2005/sparql-results#}binding[@name='updated']")[0].text supdated = dateutil.parser.parse(updated).astimezone().strftime("%Y/%m/%d %H:%M:%S") # xmlfn = "4848abcd-56a2-3170-8468-4fef8be3d405.xml" xmlfn, headers = urllib.request.urlretrieve(xmlurl) print("xml file: " + xmlfn) print("updated: " + supdated) tree = ET.parse(xmlfn) root = tree.getroot() warn = root.find(".//{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Warning[@type='気象警報・注意報(市町村等)']") for item in warn: area = item.find(".//{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Area") name = area.find(".//{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Name").text # print(name) if name == city: for kind in item: if kind.tag == "{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Kind": alert = kind.find(".//{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Name").text print(alert)

SPARQLクエリーの渡し方、ネームスペース付きXMLのパース、日付の日本時間変更などやってます

備えあれば憂い無し。災害は忘れた頃にやってくる。
痛い目に遭った今こそ、次に向けた手を創っておきましょう!

links
- 気象庁防災情報XMLフォーマット | 技術資料
- 大雪に伴う市民生活情報 – めがねのまちさばえ 鯖江市
- odp / オープンデータプラットフォーム

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / high-res profile image