#!/usr/bin/env ruby require 'csv' require 'json' require 'open-uri' require 'cgi' # require 'pstore' require 'yaml/store' # [yuzaaed.csv] # 施設名,設置場所,屋内外,住所,24h,,地図 yolp = 'https://map.yahooapis.jp/geocode/V1/geoCoder?' yolocal = "https://map.yahooapis.jp/search/local/V1/localSearch?" # cache = PStore.new("geoconv.pstore") cache = YAML::Store.new("geoconv.yaml") appid = IO.read(".appid").chomp YOLP_baseurl = yolp + "appid=#{appid}&output=json&query=" YOLOCAL_baseurl = yolocal + "appid=#{appid}&output=json&query=" GSI_base = 'https://msearch.gsi.go.jp/address-search/AddressSearch?q=' SLEEP = ($ENV["SLEEP_SECS"] || 5) aed = CSV.read(ARGV[0], headers:true) puts (aed.headers+["lon", "lat", "description"]).to_csv.sub("施設名", "name") def outerr(addr) STDERR.puts "#{addr}は変換不能" STDERR.puts "-"*50 end def geocode_gsi(addr) return $geo[addr] if $geo[addr] request = GSI_base+CGI.escape(addr) begin json = URI.open(request){|u| u.read} STDERR.puts "---DONE---" if $DEBUG ### puts JSON.pretty_generate(JSON.parse(json)) # こんなふう # [{"geometry":{"coordinates":[139.917679,38.992184],"type":"Point"},"type":"Feature","properties":{"addressCode":"","title":"山形県遊佐町豊岡"}}] answer = JSON.parse(json)[0] # 配列で来るようだ rescue return nil end # "Coordinates": "139.92680911,38.99745103", $geo[addr] = answer["geometry"]["coordinates"] end def geocode_yolp(addr, base=YOLP_baseurl) # https://qiita.com/takataka5845/items/4469fcc7226c8ef332b9 return $geo[addr] if $geo[addr] request = base+CGI.escape(addr) STDERR.puts "q=#{addr}" if $DEBUG begin json = URI.open(request){|u| u.read} # こんなふう from YOLP # "Geometry": { # "Type": "point", # "Coordinates": "139.92680911,38.99745103", # "BoundingBox": "139.9256460,38.9963590 139.9300200,38.9986830" # }, answer = JSON.parse(json)["Feature"][0] STDERR.puts "ANS=#{answer}" if $DEBUG rescue STDERR.puts "#{addr}ではだめだった!!" STDERR.puts json return nil end $geo[addr] = answer["Geometry"]["Coordinates"].split(",") end # https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/localsearch.html def geocode_yolp_local(spot) geocode_yolp(spot, YOLOCAL_baseurl) end cache.transaction do cache["geodata"] ||= Hash.new $geo = cache["geodata"] aed.each do |row| name = row["施設名"] addr = row["住所"].sub(/番地の?/, "-") if /(.*[市町村郡])/ =~ addr name = $1 + " " + name end #coord = geocode_yolp_local(name)||geocode_yolp(addr)||geocode_gsi(addr) coord = geocode_yolp(addr)||geocode_yolp_local(name)||geocode_gsi(addr) unless coord outerr(addr) next end sleep SLEEP_SECS # 速度控えめに desc = %w(設置場所 使用可能時間帯等 屋内外 住所).collect do |k| k + ": " + row[k].to_s end.join("\n") print (row.to_h.values+coord+[desc]).to_csv end end