2023,江端さんの技術メモ

OSMファイルからバスルート情報を取り出して、同じバス停留所の名前が同じの場合、位置情報の平均値を計算して算出する方法

(以下、"私だけが分かればいい"メモ)

/*

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)>go run bus_route_try_10.go

Golangで、以下のXML分の中から、<tag k="route" v="bus"/>を発見した時に、refの要素を参照にして位置情報を取り出すプログラム

そんで、同じ名前の停留所があったら、その座標の平均値として出力する

*/

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Osm struct {
	XMLName   xml.Name   `xml:"osm"`
	Nodes     []Node     `xml:"node"`
	Relations []Relation `xml:"relation"`
}

type Node struct {
	ID   int64   `xml:"id,attr"`
	Lat  float64 `xml:"lat,attr"`
	Lon  float64 `xml:"lon,attr"`
	Tags []Tag   `xml:"tag"`
}

type Relation struct {
	ID      int64    `xml:"id,attr"`
	Members []Member `xml:"member"`
	Tags    []Tag    `xml:"tag"`
}

type Member struct {
	Type string `xml:"type,attr"`
	Ref  string `xml:"ref,attr"`
	Role string `xml:"role,attr"`
}

type Tag struct {
	K string `xml:"k,attr"`
	V string `xml:"v,attr"`
}

func main() {

	// XMLファイルの読み込み
	xmlFile, err := os.Open("tsuzuki.osm") // これがベースとなるosmファイル
	if err != nil {
		log.Fatal(err)
	}
	defer xmlFile.Close()

	// XMLデータの読み込み
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		log.Fatal(err)
	}

	var osmData Osm

	// XMLデータのUnmarshal
	err = xml.Unmarshal(xmlData, &osmData)
	if err != nil {
		log.Fatal(err)
	}

	for _, relation := range osmData.Relations {

		//hasBusRouteTag := false

		for _, tag := range relation.Tags {

			if tag.K == "route" && tag.V == "bus" {

				for _, tag := range relation.Tags { // Tagの中で再度tagを回してnameを取得する(こんなことができるとは知りませんでした)
					if tag.K == "name" {
						fmt.Println("=========================")
						fmt.Printf("Route Name: %s\n", tag.V)
						break
					}
				}

				count := 0
				start_flag := 0
				//end_flag := 0
				pre_node := "ddd"
				sum_Lat := 0.0
				sum_Lon := 0.0

				for i, member := range relation.Members {

					if i == len(relation.Members)-1 { // 最後のノードを検知したら、その時点で纏めて計算して出力する
						//end_flag = 1

						fmt.Printf("Re:Bus Stop: %s\n", pre_node)
						fmt.Printf("Re:Coordinates: Lat %f, Lon %f\n\n", sum_Lat/float64(count), sum_Lon/float64(count))
					}

					if member.Type == "node" {
						node := getNodeByID(member.Ref, osmData.Nodes)
						if node != nil {

							if pre_node == getNodeName(node) || start_flag == 0  { // 停留所名が前回と同じであるなら

								count++
								sum_Lat += node.Lat
								sum_Lon += node.Lon

								start_flag = 1

							} else {

								fmt.Printf("Re:Bus Stop: %s\n", pre_node)
								fmt.Printf("Re:Coordinates: Lat %f, Lon %f\n\n", sum_Lat/float64(count), sum_Lon/float64(count))

								count = 1
								sum_Lat = node.Lat
								sum_Lon = node.Lon
							}

							pre_node = getNodeName(node)

						} 					   
					}
				}

			}
		}
	}
}

func getNodeByID(ref string, nodes []Node) *Node {
	for _, node := range nodes {
		if fmt.Sprintf("%d", node.ID) == ref {
			return &node
		}
	}
	return nil
}

func getNodeName(node *Node) string {
	for _, tag := range node.Tags {
		if tag.K == "name" {
			return tag.V
		}
	}
	return ""
}

出力はこんな感じになります。

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)>go run bus_route_try_10.go
=========================
Route Name: IKEAシャトルバス 新横浜駅前-IKEA前
Re:Bus Stop: IKEAシャトルバス IKEA前
Re:Coordinates: Lat 35.522547, Lon 139.590950

=========================
Route Name: IKEAシャトルバス IKEA前-新横浜駅前
Re:Bus Stop: IKEAシャトルバス IKEA前
Re:Coordinates: Lat 35.522547, Lon 139.590950

=========================
Route Name: すみれが丘線
Re:Bus Stop: すみれが丘
Re:Coordinates: Lat 35.564881, Lon 139.580736

Re:Bus Stop: すみれが丘公園
Re:Coordinates: Lat 35.566768, Lon 139.583192

Re:Bus Stop: 有馬変電所
Re:Coordinates: Lat 35.569075, Lon 139.584080

Re:Bus Stop: 中有馬
Re:Coordinates: Lat 35.571500, Lon 139.584235

Re:Bus Stop: 神明社前
Re:Coordinates: Lat 35.571684, Lon 139.580940

Re:Bus Stop: 地区センター前
Re:Coordinates: Lat 35.560333, Lon 139.595547

Re:Bus Stop: 北山田駅
Re:Coordinates: Lat 35.561022, Lon 139.592536

Re:Bus Stop: 山田富士
Re:Coordinates: Lat 35.561428, Lon 139.590315

Re:Bus Stop: 重代
Re:Coordinates: Lat 35.563485, Lon 139.584835

Re:Bus Stop: 北山田小学校入口
Re:Coordinates: Lat 35.563816, Lon 139.582279

Re:Bus Stop: 東山田営業所
Re:Coordinates: Lat 35.561115, Lon 139.606000

Re:Bus Stop: 東山田営業所前
Re:Coordinates: Lat 35.561358, Lon 139.604353

Re:Bus Stop: 山田小学校
Re:Coordinates: Lat 35.560874, Lon 139.602905

Re:Bus Stop: 長泉寺
Re:Coordinates: Lat 35.560052, Lon 139.597552

=========================
Route Name: 鷺沼線;有馬線
Re:Bus Stop: 神明社前

2023,江端さんの技術メモ

sharpファイルで得られたバスルートのデータを力づくでosmファイルにする

上記の方法で作成したOSMファイルでは、OSMにした時に、Nodeがバスルートの終端ににしかできないことが分かり、正直愕然としていました。これでは、バスの乗客は、バスの出発と到着地点でしか乗降できないことになるからです。

なんとかNodeを作り出せないか、色々試していたまま、いたずらに時間が過ぎていったのですが、ようやく、分かりました。

答えは、Tag情報を付与すること、でした。

作成したOMSファイルはこんな感じ

<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='200000' visible='true' version='1' lat='35.568239' lon='139.552822' />
<node id='200001' visible='true' version='1' lat='35.568164' lon='139.5528' />
<node id='200002' visible='true' version='1' lat='35.568321' lon='139.551491' />
<node id='200003' visible='true' version='1' lat='35.568338' lon='139.55136' />
<node id='200004' visible='true' version='1' lat='35.568355' lon='139.551264' />
<node id='200005' visible='true' version='1' lat='35.568406' lon='139.550885' />
<node id='200006' visible='true' version='1' lat='35.568423' lon='139.550768' />
<node id='200007' visible='true' version='1' lat='35.568445' lon='139.550568' />
<node id='200008' visible='true' version='1' lat='35.568462' lon='139.550513' />
<node id='200009' visible='true' version='1' lat='35.568507' lon='139.550154' />
<node id='200010' visible='true' version='1' lat='35.568564' lon='139.549755' />
<node id='200011' visible='true' version='1' lat='35.568603' lon='139.549438' />
<node id='200012' visible='true' version='1' lat='35.568665' lon='139.548962' />
<node id='200013' visible='true' version='1' lat='35.568671' lon='139.54888' />
<node id='200014' visible='true' version='1' lat='35.56871' lon='139.548563' />
<node id='200015' visible='true' version='1' lat='35.568817' lon='139.54744' />
<node id='200016' visible='true' version='1' lat='35.568851' lon='139.547054' />
<node id='200017' visible='true' version='1' lat='35.568879' lon='139.546737' />
<node id='200018' visible='true' version='1' lat='35.568924' lon='139.546475' />
<node id='200019' visible='true' version='1' lat='35.568986' lon='139.546241' />
<node id='200020' visible='true' version='1' lat='35.569071' lon='139.545979' />
<node id='200021' visible='true' version='1' lat='35.569094' lon='139.545918' />
<node id='200022' visible='true' version='1' lat='35.569057' lon='139.54587' />
<node id='200023' visible='true' version='1' lat='35.568969' lon='139.54582' />
<node id='200024' visible='true' version='1' lat='35.568586' lon='139.545565' />
<node id='200025' visible='true' version='1' lat='35.568372' lon='139.545373' />
<node id='200026' visible='true' version='1' lat='35.567171' lon='139.543939' />
<node id='200027' visible='true' version='1' lat='35.566558' lon='139.543161' />
<node id='200028' visible='true' version='1' lat='35.566434' lon='139.543016' />
<node id='200029' visible='true' version='1' lat='35.56622' lon='139.542644' />
<node id='200030' visible='true' version='1' lat='35.565938' lon='139.542162' />
<node id='200031' visible='true' version='1' lat='35.565519' lon='139.541454' />
<node id='200032' visible='true' version='1' lat='35.565482' lon='139.541383' />

QGISの表示はこんな感じ

Nodeが全然表われません。

今度は、これに、適当に

'/>  → '> <tag k='highway' v='bus_stop'/> 

と、適当に変換・追加してしてみました。

<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='200000' visible='true' version='1' lat='35.568239' lon='139.552822'/>
<node id='200001' visible='true' version='1' lat='35.568164' lon='139.5528'/>
<node id='200002' visible='true' version='1' lat='35.568321' lon='139.551491'/>
<node id='200003' visible='true' version='1' lat='35.568338' lon='139.55136'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200004' visible='true' version='1' lat='35.568355' lon='139.551264'/>
<node id='200005' visible='true' version='1' lat='35.568406' lon='139.550885'/>
<node id='200006' visible='true' version='1' lat='35.568423' lon='139.550768'/>
<node id='200007' visible='true' version='1' lat='35.568445' lon='139.550568'/>
<node id='200008' visible='true' version='1' lat='35.568462' lon='139.550513'/>
<node id='200009' visible='true' version='1' lat='35.568507' lon='139.550154'/>
<node id='200010' visible='true' version='1' lat='35.568564' lon='139.549755'/>
<node id='200011' visible='true' version='1' lat='35.568603' lon='139.549438'/>
<node id='200012' visible='true' version='1' lat='35.568665' lon='139.548962'/>
<node id='200013' visible='true' version='1' lat='35.568671' lon='139.54888'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200014' visible='true' version='1' lat='35.56871' lon='139.548563'/>
<node id='200015' visible='true' version='1' lat='35.568817' lon='139.54744'/>
<node id='200016' visible='true' version='1' lat='35.568851' lon='139.547054'/>
<node id='200017' visible='true' version='1' lat='35.568879' lon='139.546737'/>
<node id='200018' visible='true' version='1' lat='35.568924' lon='139.546475'/>
<node id='200019' visible='true' version='1' lat='35.568986' lon='139.546241'/>
<node id='200020' visible='true' version='1' lat='35.569071' lon='139.545979'/>
<node id='200021' visible='true' version='1' lat='35.569094' lon='139.545918'/>
<node id='200022' visible='true' version='1' lat='35.569057' lon='139.54587'/>
<node id='200023' visible='true' version='1' lat='35.568969' lon='139.54582'/>
<node id='200024' visible='true' version='1' lat='35.568586' lon='139.545565'>
<tag k='highway' v='bus_stop'/>
</node>
<node id='200025' visible='true' version='1' lat='35.568372' lon='139.545373'/>

その結果、このOSMファイル(tsuzuki_bus_trial2.osm)を、QGISで表示してみたら、こんな感じになりました。

Nodeが追加されています。

しかし、問題は、postGISでダイクストラ計算ができことが重要ですので、まずは、このosmをPostgresql にインポートしてみます。手順はいつも通りですが、ざっと記載しておきます。

C:\Users\ebata>psql -U postgres -h 192.168.0.23 -p 15432
postgres=# create database tsuzuki_bus;
CREATE DATABASE
tsuzuki_bus=# create extension postgis;
CREATE EXTENSION
tsuzuki_bus=# create extension pgrouting;
CREATE EXTENSION

で、postGISが動くDBの作成を完了しました。
で次に、

まだ試してないけど、バス停の追加は多分、これで可能となるはず

で作成した、mapconfig_for_cars_rail_busstop.xml 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <tag_name name="highway" id="1">
    <tag_value name="bus_stop"/>
    <tag_value name="motorway"          id="101" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_link"     id="102" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
    <tag_value name="trunk"             id="104" priority="1.05" maxspeed="110" />
    <tag_value name="trunk_link"        id="105" priority="1.05" maxspeed="110" />    
    <tag_value name="primary"           id="106" priority="1.15" maxspeed="90" />
    <tag_value name="primary_link"      id="107" priority="1.15" maxspeed="90" />    
    <tag_value name="secondary"         id="108" priority="1.5" maxspeed="90" />
    <tag_value name="secondary_link"    id="109" priority="1.5" maxspeed="90"/>  
    <tag_value name="tertiary"          id="110" priority="1.75" maxspeed="90" />
    <tag_value name="tertiary_link"     id="111" priority="1.75" maxspeed="90" />  
    <tag_value name="residential"       id="112" priority="2.5" maxspeed="50" />
    <tag_value name="living_street"     id="113" priority="3" maxspeed="20" />
    <tag_value name="service"           id="114" priority="2.5" maxspeed="50" />
    <tag_value name="unclassified"      id="117" priority="3" maxspeed="90"/>
    <tag_value name="road"              id="100" priority="5" maxspeed="50" />
  </tag_name> 
  <tag_name name="railway" id="1">
    <tag_value name="subway"              id="101" priority="1.0" maxspeed="40" />
    <tag_value name="rail"              id="101" priority="1.0" maxspeed="40" />
  </tag_name> 
</configuration>

重要なのは、 <tag_value name="bus_stop"/>の部分です。

このXMLファイルを使って、

F:\しゅらばしゅう\有吉先生データ\Transfer(2018)\N07-11_14_GML>osm2pgrouting -f tsuzuki_bus_trial2.osm -c mapconfig_for_cars_rail_busstop.xml -d tsuzuki_bus -U postgres -h 192.168.0.23 -p 15432 -W password

(tsuzuki_bus_trial2.osm は、変更後のOSMファイル)

を実施し、QGISでDBの内容を表示してみました。

ちゃんとNodeが追加されているようです。

しかし、ダイクストラ計算ができるかどうかは、まだ分かりませんので、QGISの地物情報でNode番号を把握して、計算を試みてみました。

 

tsuzuki_bus=# SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id,source, target,length as cost, reverse_cost FROM ways',2, 7);
seq | node | edge | cost
-----+------+------+-----------------------
1 | 2 | 25 | 0.002503402202160114
2 | 3 | 1 | 0.003623692651717509
3 | 4 | 26 | 0.0073121202899935804
4 | 5 | 27 | 0.006205490305965455
5 | 6 | 28 | 0.0048274159495506515
6 | 7 | -1 | 0
(6 rows)

ちゃんと出力されているようです。

ようやく、目処がついてきました ―― ヘナヘナと座り込みそうです。

本当にしんどくて辛い夏季休暇でした。

2023,江端さんの技術メモ

GolangでOSMファイルから、<tag k="highway" v="bus_stop"/>が入っているnode情報と、その中にあるtag k="name"の情報を出して

と、ChatGPTに頼んだら、サクッと作ってくれました。

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

type Osm struct {
	XMLName xml.Name `xml:"osm"`
	Nodes   []Node   `xml:"node"`
}

type Node struct {
	XMLName xml.Name `xml:"node"`
	Lat     string   `xml:"lat,attr"`
	Lon     string   `xml:"lon,attr"`
	Tags    []Tag    `xml:"tag"`
}

type Tag struct {
	XMLName xml.Name `xml:"tag"`
	Key     string   `xml:"k,attr"`
	Value   string   `xml:"v,attr"`
}

func main() {
	// XMLファイルの読み込み
	xmlFile, err := os.Open("tsuzuki.osm")
	if err != nil {
		log.Fatal(err)
	}
	defer xmlFile.Close()

	// XMLデータの読み込み
	xmlData, err := ioutil.ReadAll(xmlFile)
	if err != nil {
		log.Fatal(err)
	}

	var osm Osm

	// XMLデータのUnmarshal
	err = xml.Unmarshal(xmlData, &osm)
	if err != nil {
		log.Fatal(err)
	}

	// <tag k="highway" v="bus_stop"/> のノード情報を表示
	for _, node := range osm.Nodes {
		hasBusStopTag := false
		var busStopName string

		// ノード内のタグ情報を探索
		for _, tag := range node.Tags {
			if tag.Key == "highway" && tag.Value == "bus_stop" {
				hasBusStopTag = true
			}
			if tag.Key == "name" {
				busStopName = tag.Value
			}
		}

		if hasBusStopTag {
			fmt.Printf("Bus Stop Name: %s, Lat: %s, Lon: %s\n", busStopName, node.Lat, node.Lon)
			//fmt.Printf("%s, %s,%s\n", busStopName, node.Lat, node.Lon)
		}
	}
}

>go run bus_stop2.go
Bus Stop Name: 川和町, Lat: 35.5341695, Lon: 139.5461286
Bus Stop Name: 川和町, Lat: 35.5344793, Lon: 139.5458792
Bus Stop Name: 東名江田, Lat: 35.5628753, Lon: 139.5577658
Bus Stop Name: 石橋, Lat: 35.5209186, Lon: 139.5571699
Bus Stop Name: 桜通り, Lat: 35.5677990, Lon: 139.5446995
Bus Stop Name: 鶴蒔橋, Lat: 35.5496160, Lon: 139.5451910
Bus Stop Name: 鶴蒔橋, Lat: 35.5491291, Lon: 139.5461293
Bus Stop Name: 泉公園, Lat: 35.5480514, Lon: 139.5475269
Bus Stop Name: 市ヶ尾中学校前, Lat: 35.5468751, Lon: 139.5464900
Bus Stop Name: 市ヶ尾中学校前, Lat: 35.5468380, Lon: 139.5466080

2023,江端さんの技術メモ

https://josm.openstreetmap.de/wiki/Help/Action/JumpToPosition

ショートカットキー: Ctrl+J

または、ここをクリックすると、

このダイアログが出てくので、ここに名称または座標を入れる。

2023,江端さんの技術メモ

まだ試してないけど、バス停の追加は多分、これで可能となるはず

osm2pgrouting -f tsuzuki.osm -c mapconfig_for_cars_rail_busstop.xml -d tsuzuki_rail -U postgres -h 192.168.0.23 -p 15432 -W password

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <tag_name name="highway" id="1">
    <tag_value name="bus_stop"/>
    <tag_value name="motorway"          id="101" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_link"     id="102" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
    <tag_value name="trunk"             id="104" priority="1.05" maxspeed="110" />
    <tag_value name="trunk_link"        id="105" priority="1.05" maxspeed="110" />    
    <tag_value name="primary"           id="106" priority="1.15" maxspeed="90" />
    <tag_value name="primary_link"      id="107" priority="1.15" maxspeed="90" />    
    <tag_value name="secondary"         id="108" priority="1.5" maxspeed="90" />
    <tag_value name="secondary_link"    id="109" priority="1.5" maxspeed="90"/>  
    <tag_value name="tertiary"          id="110" priority="1.75" maxspeed="90" />
    <tag_value name="tertiary_link"     id="111" priority="1.75" maxspeed="90" />  
    <tag_value name="residential"       id="112" priority="2.5" maxspeed="50" />
    <tag_value name="living_street"     id="113" priority="3" maxspeed="20" />
    <tag_value name="service"           id="114" priority="2.5" maxspeed="50" />
    <tag_value name="unclassified"      id="117" priority="3" maxspeed="90"/>
    <tag_value name="road"              id="100" priority="5" maxspeed="50" />
  </tag_name> 
  <tag_name name="railway" id="1">
    <tag_value name="subway"              id="101" priority="1.0" maxspeed="40" />
    <tag_value name="rail"              id="101" priority="1.0" maxspeed="40" />
  </tag_name> 
</configuration>

明日がんばれ > 自分

2023,未分類,江端さんの技術メモ

>osm2pgrouting -f tsuzuki.osm -c mapconfig_for_cars_rail.xml -d tsuzuki_rail -U postgres -h 192.168.0.23 -p 15432 -W password

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <tag_name name="highway" id="1">
    <tag_value name="motorway"          id="101" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_link"     id="102" priority="1.0" maxspeed="130" />
    <tag_value name="motorway_junction" id="103" priority="1.0" maxspeed="130" />
    <tag_value name="trunk"             id="104" priority="1.05" maxspeed="110" />
    <tag_value name="trunk_link"        id="105" priority="1.05" maxspeed="110" />    
    <tag_value name="primary"           id="106" priority="1.15" maxspeed="90" />
    <tag_value name="primary_link"      id="107" priority="1.15" maxspeed="90" />    
    <tag_value name="secondary"         id="108" priority="1.5" maxspeed="90" />
    <tag_value name="secondary_link"    id="109" priority="1.5" maxspeed="90"/>  
    <tag_value name="tertiary"          id="110" priority="1.75" maxspeed="90" />
    <tag_value name="tertiary_link"     id="111" priority="1.75" maxspeed="90" />  
    <tag_value name="residential"       id="112" priority="2.5" maxspeed="50" />
    <tag_value name="living_street"     id="113" priority="3" maxspeed="20" />
    <tag_value name="service"           id="114" priority="2.5" maxspeed="50" />
    <tag_value name="unclassified"      id="117" priority="3" maxspeed="90"/>
    <tag_value name="road"              id="100" priority="5" maxspeed="50" />
  </tag_name> 
  <tag_name name="railway" id="1">
    <tag_value name="subway"              id="101" priority="1.0" maxspeed="40" />
    <tag_value name="rail"              id="101" priority="1.0" maxspeed="40" />
  </tag_name> 
</configuration>

とりあえず、ちゃんと、JRと市営地下鉄が加えられている。

この後は、osmファイルを手作業で加工

街の中に道路を作って、ダイクストラ計算ができるか試してみた件 ―― JOSMを使った道路追加の方法を試す

がんばれ > 自分

 

2023,江端さんの技術メモ

JOSMで地下鉄の情報だけをosm形式で取り出したい時(未完成)

JOSMでバス停が取り出せる。これを使って、バス路線を自力で作れそう。

拡大すると、こんな感じ

バス停専用の高架を作って、一般道に繋ぐイメージにすることで、バスを専用路線扱いできる。コスト値を変えて、ダイクストラを実施すれば、バスが選ばたり、逆に忌避させたりすることもできるはず。

以上

2023,江端さんの技術メモ

JOSM (Java OpenStreetMap Editor) を用いて複数 OSM ファイルのマージ

Step 1. マージするOSMを選択

Step 2.  JOSMにドラッグ

Step 3. ファイルをマージ

Step 4. 「レイヤを結合する」を選択する(この段階ではセーブされないので、どのレイヤでもいい)

Step 5. 路線を結合したい点を、同じ番号にするなどの加工を行う

以上

2023,江端さんの技術メモ

神奈川県のバスルートのsharpファイルをpostGISにインポートする

をやってから、試しに、1つのバスルートのみを、ここから取り出して、

select文の出力をローカルのテキストで保存する方法

とした後、このプログラムで、なんちゃってosmファイルを作成する。

/* 


前処理
bus_route=# \o output.txt
bus_route=# select ST_AsText(geom) from bus_route where gid = 1488;
bus_route=# \o

f:/しゅらばしゅう/有吉先生データ/Transfer(2018)/N07-11_14_GML/
sharp2osm.go

>go run sharp2osm.go ichi-61.txt 20000 > ichi-61.osm

ichi-61.txtの形式は、以下の感じ

MultiLineStringM ((139.53708861000001207 35.55222889000000208 0, 139.5370455599999957 35.55227666999999769 0, 139.53649416999999744 35.55299193999999829 0, 139.53643777999999998 35.55307056000000188 0, 139.53636917000000039 35.55315000000000225 0, 139.53559056000000282 35.55415305999999731 0, 139.53552528000000166 35.5542358300000032 0, 139.53547499999999104 35.5543083299999978 0, 139.53475943999998776 35.55520943999999872 0, 139.53468250000000239 35.55528333000000174 0, 139.53507944000000407 35.55541443999999984 0, 139.53518278000001374 35.55545389000000256 0, 139.53539638999998829 35.55552139000000267 0, 139.53575471999999991 35.55565666999999763 0, 139.5360763600000098 35.55570185999999921 0))

*/

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"strconv"
)

func main() {

	// ファイルを開く
	filePath := "output.txt" // 実際のファイルパスに置き換えてください
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println("ファイルを開けませんでした:", err)
		return
	}
	defer file.Close()


	fmt.Println("<?xml version='1.0' encoding='UTF-8'?>")
	fmt.Println("<osm version='0.6' generator='JOSM'>")

	node_id := 20000

	// ファイルを行ごとに読み込み、カンマとスペースでパースする
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line_org := scanner.Text()
		prefix := " MULTILINESTRING M ((" // 切り捨てる最初の文字列
		line := strings.TrimPrefix(line_org, prefix)

		fields := strings.FieldsFunc(line, func(r rune) bool {
			return r == ',' || r == ' ' 
		})



		var lon,lat float64


		// 取得したフィールドを表示
		for i, field := range fields {

			num, _ := strconv.ParseFloat(field, 64)
			// fmt.Println(i, i%3, num)
			
			if i % 3 == 0 {
			   lon = num
			}else if i % 3 == 1{
			   lat = num
			} else if i % 3 == 2{
			   fmt.Printf("  <node id='%d' visible='true'  version='5' lat='%f' lon='%f' />\n", node_id, lat, lon) 
			   node_id++
			   //fmt.Println(lat,",",lon)
			}	

		}
	}

	fmt.Println("  <way id='180000' visible='true' version='5'>")	

	for i:=20000; i<node_id; i++{
		fmt.Printf("    <nd ref='%d' />\n",i) 
	}
	fmt.Printf("        <tag k='highway' v='residential' />")
		
	fmt.Println("  </way>")	
	fmt.Println("</osm>")	



	if err := scanner.Err(); err != nil {
		fmt.Println("ファイル読み込みエラー:", err)
	}
}

で、以下のようなファイルができる。

<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' generator='JOSM'>
<node id='20000' visible='true' version='5' lat='35.560912' lon='139.606144' />
<node id='20001' visible='true' version='5' lat='35.561252' lon='139.606062' />
<node id='20002' visible='true' version='5' lat='35.561646' lon='139.605835' />
<node id='20003' visible='true' version='5' lat='35.561736' lon='139.60575' />
(中略)
<way id='180000' visible='true' version='5'>
<nd ref='20000' />
<nd ref='20001' />
<nd ref='20002' />
<nd ref='20003' />
(中略)
<nd ref='20189' />
<tag k='highway' v='residential' />
</way>
</osm>

JOSMでの表示

QGISでの表示

とりあえず、忘れないうちにメモを作成しました。

以上

2023,江端さんの技術メモ

bus_route=# \o output.txt
bus_route=# select * from bus_route where gid = 1488;
bus_route=# \o

psqlを立ち上げたディレクトリにできている