ruby-robotの夢

cygwin-ruby,qgisの達人を目指す奮闘記

河川距離標位置の取得

河川距離標位置とは

河川の情報のうち、縦断的な位置を示す距離標は、基本情報である。距離標において、横断測量を行い、河川の水理解析を行い、横断計画を作成する。浸水想定区域図は、距離標毎に氾濫解析して作成する。

距離標は、河口から又は合流点からの距離を示し、通常km単位であるが、縦断位置に付けた名前というべきもので、実際の距離とは異なる。例えば、蛇行河川をショートカットした場合、実距離は短くなるが、上流部の距離標位置は基本的に変更しない。

このため、1k地点と、2k地点の間隔は、0.5kmしかないという場合もある。このとき、水理計算は、距離標間の実際の距離を意味する区間距離を0.5kmとして計算する。

つまり、現在の河道データで河口から距離を計測しても、距離標の位置とは異なり。距離標位置は、そのデータを取得することが基本となる。

 

浸水ナビデータの取得

河川管理の基本となる距離標の位置は、従来から、あまり公表されていない。公表される河川整備計画の整備位置図等において示される程度(地方・河川により表示の仕方は異なる)であった。

国の管理河川では、河川基盤地図情報というデータベースが構築されているはずであるが、これらも公表されていないため、しばしば、距離標の位置整理は、個別の平面測量データに基づいて整理が必要で、面倒なことであった。

ところが、数年前から公表されている浸水ナビにおいて、国管理河川の破堤点(距離標)が表示されるようになった。

この位置情報を取得してみた。

win32oleだけで実装したかったが、連動するドロップボックスの処理ができないため、sendkeysと組み合わせた。

距離標位置緯度経度取得の手順

まずは、WIN32OLE,IE11で、距離標の表示ピクセルと、背景図の表示位置の取得を行い、その結果から、緯度経度に変換する。

いまいち、使い勝手は悪いが、参考のため掲載する。

なお、大河川の場合の表示位置の精度はあまり高くなく、IE画面を大きくしても、数十mの誤差が生じる。

距離標表示位置の取得

require "win32ole"
require "~/Lib/Ruby/ie.rb"
require "fileutils"

def sendkeys(wsh,*opts)
if opts.size==2 pat,t_keys=opts #Winscript.Shell
wsh.AppActivate(pat)
else
t_keys=opts[0]
end
t_keys.map{|t,key| sleep(t);wsh.SendKeys(key) }
end

ie=WIN32OLE.new("InternetExplorer.Application");ie.Visible=true
#print ie.ole_func_methods
top="http://suiboumap.gsi.go.jp/ShinsuiMap/Map/"
nslp=2
wsh= WIN32OLE.new("WScript.Shell")
print "DONNOT TOUCH KEYBORD"
rivers=["suikei",3,6,7,[*1..7]] #対象河川により変更する。
print "RIVERS",rivers
name,ichiho,ioffice,nriver,irs=rivers

FileUtils.makedirs(name)
nfo="#{name}/bp_dl.txt"
fo=open(nfo,"a")
irs.each{|iriver|
print "IRIVER",iriver
irep=0
while true
print "irep",irep+=1
[0,1].each do |i|
ie.Navigate(top);nsleep ie,nslp
doc=ie.Document
tabs=doc.getElementsbyClassname("glyphicon-chevron-up glyphicon").item(0)
button=doc.getElementbyId(id="btnExtend_tabRiver")
button.onchange;
button.click nil;nsleep ie,nslp*3 ;
#listarea=doc.getElementbyId(id="listArea_tabRiver") #selet drop down
#print listarea.selectedindex=9;nsleep ie,nslp
wsh.AppActivate(top);sleep 0.1
sendkeys(wsh,tk=[ [0.04,'{TAB}'] ]*22+[ [0.03,"{DOWN}"] ]*ichiho+[ [0.5,'{TAB}'] ]) sleep 0.5
sendkeys(wsh,tk=[ [0.03,"{DOWN}"] ]*ioffice+[ [0.1,'{TAB}'] ]);sleep 0.2
listflood=doc.getElementbyId("listFloodName_tabRiver")
flds=listflood.each.map{|opt| opt.innerText}

print flds[iriver]
sendkeys(wsh,tk=[ [0.03,"{DOWN}"] ]*iriver+[ [0.1,'{TAB}'] ]);sleep 0.2
sendkeys(wsh,tk=[ [0.02,' '] ]);sleep 2
end
doc=ie.Document
nsleep ie,nslp*10
tbl=doc.getElementbyID(id="tableBPList")
tds=tbl.rows.each.map{|td| td.cells.each.map{|cell| cell.innerText}[1,3]*$,}
next if tds.size==0
print "tds",tds[0],tds.size
btnserarch=doc.getElementbyId(id="btnCsvSearch")
div=doc.getElementsbyClassname("leaflet-marker-pane").item(0)
points=div.all.tags("img").each.to_a.select{|img|
img.src=="http://suiboumap.gsi.go.jp/ShinsuiMap/Scripts/leaflet/images/marker/blue.png"}

points.map!{|img|
img.style.transform.sub("translate(","").sub("px","").sub("px)","")
.split(",").map(&:to_i)}
print "points",points[0],points.size

div=doc.getElementbyId(id="map")
.getElementsbyClassname("leaflet-tile-container leaflet-zoom-animated")
.item(0)
maps=div.all.tags("img").each.to_a next if maps.size==0
maps.map!{|img| [img.src.sub(/.*pale\//,"").sub(".png",""),
img.style.transform.sub("translate(","").gsub("px","").sub(")","")
.split(",").map(&:to_i) ]}
print "maps",maps[0],maps.size

fo.print maps.map{|map| ([iriver]+map)*$,}*$\
fo.print [tds,points].transpose.map{|es| ([iriver]+es)*$,}*$\
break
end # while repeat
} #iriver

緯度経度換算

def i_zl2lat(f,zl)

nz=2**(zl)

lat=180/Math::PI*(2*Math.atan2(Math.exp ( ( 1-f* 2.0/nz)*Math::PI),1)-Math::PI/2)

end

def j_zl2lon(f,zl)

nz=2**(zl)

lon=f*1.0/nz*360-180

end

names=%w[suikei ]
names.each{|name| dls=CSV.read("#{name}/bp_dl.txt",col_sep:$,)
fo=open(nfo="#{name}/bps.txt","w")

fo.print *%w[ir ibp riv bp lr km x y zl]
rpos=dls.group_by{|fs| fs[0]}.each{|ir,ls|
print "ir",ir
bps,maps=ls.partition{|fs| fs[1][0,2]=="BP"}
jis=maps.map{|fs| fs[1].split("/").map(&:to_i)};#print jis
zl=jis[0][0];print "zl",zl
js=jis.map{|ji| ji[1]};#print "js",js #x
is=jis.map{|ji| ji[2]};#print "is",is #y
xs=maps.map{|fs| fs[2].to_i};#print "xs",xs
ys=maps.map{|fs| fs[3].to_i};#print "ys",ys
ixm=xs.index(xm=xs.min);#print "ixm",ixm
ixx=xs.index(xx=xs.max);#print "ixx",ixx
iyx=ys.index(ym=ys.min);#print "iyx",iyi #revere
iym=ys.index(yx=ys.max);#print "iym",iym #revere

isx=is[iyx];#print "isx",isx
ism=is[iym];#print "ism",ism
jsx=js[ixx];#print "jsx",jsx
jsm=js[ixm];#print "jsm",jsm
xrg=xx-xm+256;#print "xrg",xrg;
yrg=ym-yx+256;#print "yrg",yrg;
jrg=jsx-jsm;# print "jrg",jrg;
irg=ism-isx;# print "irg",irg;
print "lat0",lat0=i_zl2lat(isx,zl) #north top
print "lat_",lat_=i_zl2lat(isx-(ym/256.0),zl) #is[iyx]*scaley-90.0
print "lat1",lat1=i_zl2lat(ism-1,zl) #south bottom
print "latscale",lats=(lat1-lat0)/yrg
print "lon0",lon0=j_zl2lon(jsm,zl) #west left
print "lon_",lon_=j_zl2lon(jsm-(xm/256.0),zl) #js[ixx]*scalex-180.0
print "lon1",lon1=j_zl2lon(jsx+1,zl) #east right
print "lonscale",lons=(lon1-lon0)/xrg
bps.map!{|fs| x=fs[4].to_f;y=fs[5].to_f
lon=lon_+x*lons;lat=lat_-y*lats;
bp=fs[3]
lr=(bp.match("右岸"))?"R": ( (bp.match( "左岸"))?"L":"")
if lr==""
lr=(bp.match("R"))?"R":( ( bp.match("L"))?"L":"")
end
next if lr=="" m=bp.match(/([-0-9.km ]+)/i)
ky=m[1] #.dup
# print "bp",bp,"ky",ky
if ky.match(/[0-9]k[0-9]/i)
km=ky.sub(/k/i,".").to_f

elsif ky.match(/[0-9]km *$/i)
km=ky.sub(/km/,"").to_f
elsif ky.match(/^[0-9.]+$/)
km=ky.to_f
else
km=ky.to_f
print "KM",[ky]
end
# print km
printf "%s ",km
(fs[0,4]+[lr,km,lon,lat,zl])*$,}
fo.print bps.compact*$\
}
fo.close
print `txt2shp.rb #{nfo}`.chomp
}