ジオコーディングが簡単にできるライブラリの話は先日書いた。
千葉県警が犯罪発生情報をオープンデータとして配布している。まあオープンデータにするなら、文字コードはUTF-8に改行コードはLFにしておいてほしいが、配布されているファイルはSJIS + CRLFなので、適当なツールでUTF-8 + LFにしてから以下の適当なPythonに通せば、Googleマップにレイヤーとして載せられる。row[2]は抜き出したい警察署の名前をいれてください。
#!/usr/bin/python3
import csv
import json
import jageocoder
jageocoder.init()
with open(f'crimes.csv', 'w') as output_file:
writer = csv.writer(output_file, quoting=csv.QUOTE_ALL)
writer.writerow(['WKT','名前','説明'])
for file in ['オートバイ盗', 'ひったくり', '自転車盗', '自動車盗', '自動販売機ねらい', '車上ねらい', '部品ねらい']:
with open(f'{file}.csv') as input_file:
reader = csv.reader(input_file)
death = []
injury = []
for row in reader:
if row[2] == '市川':
results = jageocoder.search(row[5] + row[6] + row[7])
lon, lat = results['candidates'][0]['x'], results['candidates'][0]['y']
writer.writerow([f'POINT ({lon} {lat})',f'{file}'])
一方で、警察庁は交通事故統計をオープンデータとして配布している。こちらは「本票」となっているファイルに交通事故の詳細データが入っているので、以下のようなPythonで抜き出して、こちらもGoogleマップに載せられる。row[1]で都道府県コード、row[2]で警察署コードを指定できるので、同じページで配布されている各種コード表を参照して、抜き出したい都道府県・警察署を指定してくだされ。
#!/usr/bin/python3
import csv
import math
from decimal import Decimal, ROUND_HALF_UP
year=2021
def dms2deg(dms):
# 度分秒から度への変換
print(dms)
h = int(dms[0])
m = int(dms[1])
s = float(dms[2])
deg = Decimal(str(h + (m / 60) + (s / 3600))).quantize(Decimal('0.0001'), rounding=ROUND_HALF_UP)
return deg
def deg2dms(deg):
# 度から度分秒への変換
h = math.modf(deg)[1]
m = math.modf(math.modf(deg)[0] * 60)[1]
s = math.modf(math.modf(deg)[0] * 60)[0]*60
if Decimal(str(s)).quantize(Decimal('0'), rounding=ROUND_HALF_UP) == 60:
s = 0
m = m + 1
if Decimal(str(m)).quantize(Decimal('0'), rounding=ROUND_HALF_UP) == 60:
m = 0
h = h + 1
dms_tap = (int(Decimal(h).quantize(Decimal('0'), rounding=ROUND_HALF_UP)),
int(Decimal(m).quantize(Decimal('0'), rounding=ROUND_HALF_UP)),
int(Decimal(s).quantize(Decimal('0'), rounding=ROUND_HALF_UP)))
return dms_tap
with open(f'honhyo_{year}.csv') as f:
reader = csv.reader(f)
death = []
injury = []
for row in reader:
if row[1] == '44': #千葉県
if row[2] == '105': #市川警察署
lat = dms2deg([row[54][0:2], row[54][2:4], row[54][4:6] + '.' + row[54][6:]])
lon = dms2deg([row[55][0:3], row[55][3:5], row[55][5:7] + '.' + row[55][7:]])
if int(row[5]) >= 1: #死亡事故
death.append([lat, lon])
else: #負傷事故
injury.append([lat, lon])
with open(f'death_{year}.csv', 'w') as f:
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
writer.writerow(['WKT','名前','説明'])
for lat,lon in death:
writer.writerow(['POINT ({} {})'.format(lon,lat),f'死亡事故({year}年)'])
with open(f'injury_{year}.csv', 'w') as f:
writer = csv.writer(f, quoting=csv.QUOTE_ALL)
writer.writerow(['WKT','名前','説明'])
for lat,lon in injury:
writer.writerow(['POINT ({} {})'.format(lon,lat),f'負傷事故({year}年)'])
こんな感じに見ることが可能。