著者:飯尾 淳
前回は、政府統計の総合窓口「e-Stat1」から入手できるデータをダウンロードして、八王子市の町・丁目を示す境界データを地図上に可視化する準備をしました。今回は、実際に地図データを活用できるように、データをきれいに整理する作業を実施します。データをきれいにする作業、それを「クレンジング」と呼びます。
記事本文掲載のシェルスクリプトマガジンvol.54は以下のリンク先でご購入できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
#!/usr/bin/env python from math import sqrt # 近傍にあるかどうかの判定 def near(a, b, e): (c_ax, c_ay, c_az) = a.split(",") (c_bx, c_by, c_bz) = b.split(",") dx = float(c_ax) - float(c_bx) dy = float(c_ay) - float(c_by) d = sqrt(dx*dx + dy*dy) return (d < e) def splitBorderParts(c0, c1): # 境界面を形作る地点の集合を作成 s0 = [a for a in c0 for b in c1 if near(a, b, 0.00001)] s1 = [b for b in c1 for a in c0 if near(a, b, 0.00001)] # 交差部分がないとき if len(s0) == 0: raise NameError("No intersections!") # 始点が境界面の端に来るように回す if c0[0] not in s0: # 始点が境界面の外にあるとき while c0[0] not in s0: c0.append(c0.pop(0)) else: # 始点が境界面の中にあるとき while c0[-1] in s0: c0.insert(0, c0.pop()) if c1[0] not in s1: while c1[0] not in s1: c1.append(c1.pop(0)) else: while c1[-1] in s1: c1.insert(0, c1.pop()) # 境界面部分を取り出す(元データの境界面には'0,0,0'でマークしておく) i = 0; s0_ = [] for c in c0: if c in s0: s0_.append(c0[i]); c0[i] = '0,0,0' i += 1 i = 0; s1_ = [] for c in c1: if c in s1: s1_.append(c1[i]); c1[i] = '0,0,0' i += 1 return (c0,s0_,c1,s1_) from bs4 import BeautifulSoup import re import sys xml = open("./sample4.kml") bsObj = BeautifulSoup(xml.read(), "lxml") targets = bsObj.findAll("coordinates") coords = [] for coord in targets: val = re.sub(" +", "", coord.get_text()).split("\n") while val.count(""): val.remove("") # 先頭と末尾が重複しているので,とりあえず先頭を削除 val.pop(0) coords.append(val) try: # 第1引数で与える配列の非境界面(c0), 境界面(s0), # 第2引数で与える配列の非境界面(c1), 境界面(s0) を求める (c0,s0,c1,s1) = splitBorderParts(coords[0], coords[1]) # c0とc1から'0.0.0'を取り除く while c0[0] == '0,0,0': c0.pop(0) while c1[0] == '0,0,0': c1.pop(0) # c0,c1の頭にs0,s1の末尾(境界面の端点)を追加 c0.insert(0, s0[-1]) c1.insert(0, s1[-1]) # c0とc1を繋いで出力(最後に先頭を出力して閉領域完成) print (“<coordinates>”) for f in c0: print (“ ”, f) for f in c1: print (“ ”, f) print (“ ”, c0[0]) print (“</coordinates>”) except NameError: sys.exit() |