ホーム » スタッフ » 斉藤徹 » 地盤データのハッカソン

2023年1月
1234567
891011121314
15161718192021
22232425262728
293031  

検索・リンク

地盤データのハッカソン

地盤データのオープンデータハッカソンが jig.jp さんで開催されたので、学生さんを何人か誘って、おまけ参加。

github.com に 福井県のボーリング情報があるけど、要望の中に緯度経度が間違ったデータがあるとの
お話だったので、XML データの緯度経度と、ボーリング箇所の町名データを比較するプログラムを書いてみた。

しかしながら、町名といっておきながら、先頭に川の名前がついていたり、複数の町をまたがっているから○○町〜○○町といった町名記載があって、ボーリングの住所から緯度経度がとれないことが多発。

ということで、ボーリングデータを登録する側で、住所の記載方法を統一化してほしいよねぇ〜という感想。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#!/usr/bin/env python3
import requests
import csv
import re
from bs4 import BeautifulSoup
import geocoder
import math
url_top = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/main/filelist.csv"
url_data = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/mai\ n/data/"
res = requests.get( url_top )
if res.ok :
for line in res.text.splitlines() :
url , type , size = line.split(',')
if re.match( '.*/DATA/BED\d\d\d\d\.XML$' , url ) :
xml_url = url_data + url
xml_res = requests.get( xml_url )
if xml_res.ok :
soup = BeautifulSoup( xml_res.text , 'xml' )
# <経度緯度情報><{緯度|経度}_{度|分|秒}>
for lat_lng in soup.find_all( '経度緯度情報' ) :
# <調査位置><調査位置住所>
lat_deg = int( lat_lng.find( '緯度_度' ).string )
lat_min = int( lat_lng.find( '緯度_分' ).string )
lat_sec = float( lat_lng.find( '緯度_秒' ).string )
lng_deg = int( lat_lng.find( '経度_度' ).string )
lng_min = int( lat_lng.find( '経度_分' ).string )
lng_sec = float( lat_lng.find( '経度_秒' ).string )
lat = lat_deg + lat_min / 60 + lat_sec / 3600
lng = lng_deg + lng_min / 60 + lng_sec / 3600
# print( lat )
addr = soup.find( '調査位置住所' ).string
addr = re.sub( '地係$' , '' , addr )
addr = re.sub( ' ' , '' , addr )
addr = re.sub( '(~|から).*$' , '' , addr )
addr = re.sub( '^.*福井県' , '' , addr )
addr = re.sub( '(.*)' , '' , addr )
addr = re.sub( '\(.*\)' , '' , addr )
addr = "福井県" + addr
#print( addr )
geo_addr = geocoder.osm( addr , timeout = 5.0 )
if geo_addr is None :
print( "None" )
elif isinstance( geo_addr.latlng , list ) :
geo_lat , geo_lng = geo_addr.latlng
err = math.sqrt( (lat - geo_lat)**2 + (lng - geo_lng)**2 )
if err > 0.001 :
print( "(%f,%f)-(%f,%f)-%s"
% ( lat , lng , geo_lat , geo_lng , addr ) )
else :
print( "(%f,%f) not [LAT LNG] -%s" % ( lat , lng , addr ) )
#!/usr/bin/env python3 import requests import csv import re from bs4 import BeautifulSoup import geocoder import math url_top = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/main/filelist.csv" url_data = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/mai\ n/data/" res = requests.get( url_top ) if res.ok : for line in res.text.splitlines() : url , type , size = line.split(',') if re.match( '.*/DATA/BED\d\d\d\d\.XML$' , url ) : xml_url = url_data + url xml_res = requests.get( xml_url ) if xml_res.ok : soup = BeautifulSoup( xml_res.text , 'xml' ) # <経度緯度情報><{緯度|経度}_{度|分|秒}> for lat_lng in soup.find_all( '経度緯度情報' ) : # <調査位置><調査位置住所> lat_deg = int( lat_lng.find( '緯度_度' ).string ) lat_min = int( lat_lng.find( '緯度_分' ).string ) lat_sec = float( lat_lng.find( '緯度_秒' ).string ) lng_deg = int( lat_lng.find( '経度_度' ).string ) lng_min = int( lat_lng.find( '経度_分' ).string ) lng_sec = float( lat_lng.find( '経度_秒' ).string ) lat = lat_deg + lat_min / 60 + lat_sec / 3600 lng = lng_deg + lng_min / 60 + lng_sec / 3600 # print( lat ) addr = soup.find( '調査位置住所' ).string addr = re.sub( '地係$' , '' , addr ) addr = re.sub( ' ' , '' , addr ) addr = re.sub( '(~|から).*$' , '' , addr ) addr = re.sub( '^.*福井県' , '' , addr ) addr = re.sub( '(.*)' , '' , addr ) addr = re.sub( '\(.*\)' , '' , addr ) addr = "福井県" + addr #print( addr ) geo_addr = geocoder.osm( addr , timeout = 5.0 ) if geo_addr is None : print( "None" ) elif isinstance( geo_addr.latlng , list ) : geo_lat , geo_lng = geo_addr.latlng err = math.sqrt( (lat - geo_lat)**2 + (lng - geo_lng)**2 ) if err > 0.001 : print( "(%f,%f)-(%f,%f)-%s" % ( lat , lng , geo_lat , geo_lng , addr ) ) else : print( "(%f,%f) not [LAT LNG] -%s" % ( lat , lng , addr ) )
#!/usr/bin/env python3

import requests
import csv
import re
from bs4 import BeautifulSoup
import geocoder
import math

url_top  = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/main/filelist.csv"
url_data = "https://raw.githubusercontent.com/GeoFUKUI/jiban-opendata/mai\ n/data/"

res = requests.get( url_top )

if res.ok :
    for line in res.text.splitlines() :
	url , type , size = line.split(',')
	if re.match( '.*/DATA/BED\d\d\d\d\.XML$' , url ) :
             xml_url = url_data + url
             xml_res = requests.get( xml_url )
             if xml_res.ok :
                 soup = BeautifulSoup( xml_res.text , 'xml' )
                 # <経度緯度情報><{緯度|経度}_{度|分|秒}>
                 for lat_lng in soup.find_all( '経度緯度情報' ) :
                     # <調査位置><調査位置住所>
                     lat_deg = int( lat_lng.find( '緯度_度' ).string )
                     lat_min = int( lat_lng.find( '緯度_分' ).string )
                     lat_sec = float( lat_lng.find( '緯度_秒' ).string )
                     lng_deg = int( lat_lng.find( '経度_度' ).string )
                     lng_min = int( lat_lng.find( '経度_分' ).string )
                     lng_sec = float( lat_lng.find( '経度_秒' ).string )
                     lat = lat_deg + lat_min / 60 + lat_sec / 3600
                     lng = lng_deg + lng_min / 60 + lng_sec / 3600
                     # print( lat )

                 addr = soup.find( '調査位置住所' ).string
                 addr = re.sub( '地係$' , '' , addr )
                 addr = re.sub( ' ' , '' , addr )
                 addr = re.sub( '(~|から).*$' , '' , addr )
                 addr = re.sub( '^.*福井県' , '' , addr )
                 addr = re.sub( '(.*)' , '' , addr )
                 addr = re.sub( '\(.*\)' , '' , addr )
                 addr = "福井県" + addr
                 #print( addr )

                 geo_addr = geocoder.osm( addr , timeout = 5.0 )
                 if geo_addr is None :
                     print( "None" )
                 elif isinstance( geo_addr.latlng , list ) :
                     geo_lat , geo_lng = geo_addr.latlng
                     err = math.sqrt( (lat - geo_lat)**2 + (lng - geo_lng)**2 )
                     if err > 0.001 :
                         print( "(%f,%f)-(%f,%f)-%s"
                                % ( lat , lng , geo_lat , geo_lng , addr ) )
                 else :
                     print( "(%f,%f) not [LAT LNG] -%s" % ( lat , lng , addr ) )

個人的なお遊びで、Webデータのスクレイピングは色々と体験あるけど、今までは Perl を使っていた。今回は、自分のチャレンジということで、Python を使ってスクレイピング。