(1)スタート地点 139.91804656152837 36.57246810341353, (2)ゴール地点 139.93515104919825 36.55883778950532 (3)とした時、この2点に最も近いノードを探し出して、 (4)その2点をダイクストラ法で、最短距離探索をするプログラム

// go get github.com/lib/pq を忘れずに
// go run main6.go

/*
	前提は、https://ebata-books.booth.pm/items/3351408 の環境

	(1)スタート地点  139.91804656152837 36.57246810341353,
	(2)ゴール地点 139.93515104919825 36.55883778950532
	(3)とした時、この2点に最も近いノードを探し出して、
	(4)その2点をダイクストラ法で、最短距離探索をするプログラム

	分かったこと
	上記(3)のノードが、孤立ノードになっている場合があり、この場合(4)が実施できないので、
	ダイクストラに失敗する場合は、別のノードでトライアルする必要あり 
	(このコードでは展開しないけど)
*/

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/lib/pq"
)

var source int
var longitude float64
var latitude float64
var dist float64

func main() {
	db, err := sql.Open("postgres",
		"user=postgres password=password host=localhost port=15432 dbname=utsu_db sslmode=disable")
	if err != nil {
		log.Fatal("OpenError: ", err)
	}
	defer db.Close()

	// スタート地点  139.91804656152837 36.57246810341353
	rows, err := db.Query("SELECT source, x1 as longitude, y1 as latitude, ST_Distance('SRID=4326;POINT(139.91804656152837 36.57246810341353)'::GEOGRAPHY, the_geom) as dist FROM ways WHERE ST_DWithin(the_geom, ST_GeographyFromText('SRID=4326;POINT(139.91804656152837 36.57246810341353)'), 300.0) ORDER BY dist LIMIT 1")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {

		if err := rows.Scan(&source, &longitude, &latitude, &dist); err != nil {
			fmt.Println(err)
		}
		fmt.Println(source, longitude, latitude, dist)
	}

	o_source := source

	// ゴール地点 139.93515104919825 36.55883778950532
	rows, err = db.Query("SELECT source, x1 as longitude, y1 as latitude, ST_Distance('SRID=4326;POINT(139.93515104919825 36.55883778950532)'::GEOGRAPHY, the_geom) as dist FROM ways WHERE ST_DWithin(the_geom, ST_GeographyFromText('SRID=4326;POINT(139.93515104919825 36.55883778950532)'), 300.0) ORDER BY dist LIMIT 1")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {

		if err := rows.Scan(&source, &longitude, &latitude, &dist); err != nil {
			fmt.Println(err)
		}
		fmt.Println(source, longitude, latitude, dist)
	}

	d_source := source

	fmt.Println(o_source, d_source)

	// これが基本形
	// rows, err = db.Query("SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id, source, target,length as cost FROM ways',8889, 22848, false)")

	// この bigint なるものは、https://wp.kobore.net/%E6%B1%9F%E7%AB%AF%E3%81%95%E3%82%93%E3%81%AE%E6%8A%80%E8%A1%93%E3%83%A1%E3%83%A2/error-function-pgr_dijkstraunknown-start_vid-bigint-end_vid-bigint-directed-boolean-does-not-exist-line-7-pgr_dijkstra-hint-no-function-matches-the-given-name/ に記載がある
	rows, err = db.Query("SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id, source, target,length as cost FROM ways', $1::bigint , $2::bigint , false)", o_source, d_source)

	// こっちも稼動します
	// str := "SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id, source, target,length as cost FROM ways'," + strconv.Itoa(o_source) + "," + strconv.Itoa(d_source) + ", false)"
	// fmt.Println(str)
	// rows, err = db.Query(str)

	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {
		var seq int
		var node int
		var edge int
		var cost float64

		if err := rows.Scan(&seq, &node, &edge, &cost); err != nil {
			fmt.Println(err)
		}
		fmt.Println(seq, node, edge, cost)
	}

	if err := db.Ping(); err != nil {
		log.Fatal("PingError: ", err)
	}
}

2022/05,江端さんの技術メモ

Posted by ebata