dockerは、どのOS環境でも動くを唄っていますが、基本的に、わたしは、どんなパッケージであろうとも、「これ」を信じていません。
とくに時系列方向については、全く信用していません。
ともあれ、ノートPCにtomioka_dbをdocker-compose.ymlで再構築した時、以下の部分の変更が必要でしたので、逐次メモしていきます。
江端智一のホームページ
dockerは、どのOS環境でも動くを唄っていますが、基本的に、わたしは、どんなパッケージであろうとも、「これ」を信じていません。
とくに時系列方向については、全く信用していません。
ともあれ、ノートPCにtomioka_dbをdocker-compose.ymlで再構築した時、以下の部分の変更が必要でしたので、逐次メモしていきます。
私は今でも、Meadow3を使っています。
I still use Meadow3.
Meadow3とは、Windowsに特化したemacsのことです。
Meadow3 is a Windows-specific emacs.
WindowsNT 4.0より前から使っていますが、今も使い続けています。
I have been using it since before Windows NT 4.0 and continue to use it.
なぜか ―― 動くからです。
Why -- because it works.
現在、Windows11上でも動き続けています。
Currently, it continues to run on Windows 11.
-----
動き続けている限り、使わない理由はありません。
There is no reason not to use it as long as it keeps moving.
.emacsをメンテナンスする気力もありませんので、キーバインドも、当時から固定のままです。
I don't have the energy to maintain .emacs, so key bindings have remained fixed since that time.
もはやMeadow3は、私の体の一部といっても過言ではありません。
It is no exaggeration to say that Meadow3 is now a part of my body.
-----
Meadowが、バージョンアップしたWindowsOSで動かなくなった時に、私の中でも何かが終わるような気がしています。
I feel that something will end for me when Meadow stops working with the upgraded Windows OS.
―― と言いながら、次女のPCにMeadow3をインストールして、今、それで、この文章を書いています。
-- but I installed Meadow3 on my second daughter's PC and am now writing this text with it.
あと、次女のノートPCに大量に貼ってあるステッカーが、ちょっとアバンギャルドで、このPCを学会会場に持ち込む勇気が出ませんでした。
Also, the large number of stickers on my second daughter's laptop was a bit avant-garde, and I could not find the courage to bring this computer to the conference venue.
という訳で、こんなの購入して、ノートPCに貼りつけていました。
So I bought one like this and stuck it on my laptop.
返却時に、元に戻して返すつもりですが。
I intend to return it to its original state when I return it.
エクスプローラで、ファイルをコピーする場合、同じファイル名の場合には時刻が新しい場合のみ上書きしたいですがどうすれば良いですか
ChatGPT
ChatGPT
Windowsエクスプローラでファイルをコピーする際、同じファイル名の場合は時刻が新しい場合のみ上書きするという機能は標準では提供されていません。しかし、以下の方法でこの操作を実現できます。
方法1: コマンドプロンプトでrobocopyを使用
Windowsにはrobocopyという強力なコマンドラインツールがあり、これを使用してファイルのコピーを行うと、指定した条件に基づいてファイルを上書きできます。
以下の手順で行います。
コマンドプロンプトを管理者権限で開く
以下のrobocopyコマンドを実行
cmd
コードをコピーする
robocopy "コピー元フォルダのパス" "コピー先フォルダのパス" /XO
ここで、/XOオプションは古いファイルを除外します。これにより、コピー元フォルダのファイルがコピー先フォルダのファイルより新しい場合にのみ上書きされます。
例
コピー元フォルダがC:\source、コピー先フォルダがD:\destinationの場合、次のように入力します。
cmd
コードをコピーする
robocopy "C:\source" "D:\destination" /XO
cmd.exeを管理者モードで立ち上げ
C:\WINDOWS\system32>robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z
C:\WINDOWS\system32>robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z
======
robocopy "f:\しゅらばしゅう" "\\192.168.0.23\ynu-share\しゅらばしゅう_フルバックアップ" /XO /E /Z
robocopy "\\192.168.0.10\usb_mount" "\\192.168.0.23\ynu-share\usb_mount_フルバックアップ" /XO /E /Z
robocopy "g:home\ebata\tomioka3B\src" "\\192.168.0.9\share\tomioka3B\src" /XO /E /Z
robocopy "g:home\ebata\hakata" "\\192.168.0.9\share\hakata" /XO /E /Z
echo
======
gnuplotで
0.98, 0.40, 0.30
0.98, 0.41, 0.30
0.97, 0.42, 0.30
0.96, 0.42, 0.30
0.98, 0.42, 0.31
0.98, 0.41, 0.31
のようにx,y,z座標で記載された、cluster1.csvの内容を、Gnuplotで表示するコマンドを教えて下さい。
ChatGPT
ChatGPT
以下は、cluster1.csv の内容を Gnuplot で表示するためのコマンドです。まず、CSVファイルの内容を正しく読み込むためのスクリプトを作成し、その後に3Dプロットを行います。
cluster1.csv の内容が次のようになっていると仮定します:
コードをコピーする
0.98, 0.40, 0.30
0.98, 0.41, 0.30
0.97, 0.42, 0.30
0.96, 0.42, 0.30
0.98, 0.42, 0.31
0.98, 0.41, 0.31
Gnuplot を使用してこのデータをプロットするためのスクリプトを作成します。以下はそのスクリプトです:
gnuplot
コードをコピーする
set datafile separator ","
set title "Cluster 1 Data"
set xlabel "X-axis"
set ylabel "Y-axis"
set zlabel "Z-axis"
set xrange [0:1]
set yrange [0:1]
set zrange [0:1]
set ticslevel 0
splot 'cluster1.csv' using 1:2:3 with points pt 7 ps 1 lc rgb "blue" title 'Cluster 1'
複数個出すのであれば、こんな感じ
splot 'cluster1.csv' using 1:2:3 with points pt 7 ps 1 lc rgb "blue" title 'Cluster 1', 'cluster2.csv' using 1:2:3 with points pt 7 ps 1 lc rgb "red" title 'Cluster 2', 'cluster3.csv' using 1:2:3 with points pt 7 ps 1 lc rgb "yellow" title 'Cluster 3'
splot 'cluster1.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "blue" title 'Cluster 1', 'cluster2.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "red" title 'Cluster 2', 'cluster3.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "yellow" title 'Cluster 3', 'cluster4.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "green" title 'Cluster 4', 'cluster5.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "cyan" title 'Cluster 5', 'cluster6.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "magenta" title 'Cluster 6', 'cluster7.csv' using 1:2:3 with points pt 7 ps 2 lc rgb "orange" title 'Cluster 7'
このスクリプトを Gnuplot に読み込むことで、3Dプロットが作成されます。具体的な手順は以下の通りです。
Gnuplot を起動します。
上記のスクリプトをコマンドラインに入力するか、ファイルに保存して load コマンドで読み込みます。
例えば、スクリプトを plot_cluster1.gnuplot というファイルに保存した場合:
sh
コードをコピーする
gnuplot> load 'plot_cluster1.gnuplot'
これで、cluster1.csv の内容が3Dプロットとして表示されます。プロットのポイントの形状や色、サイズは必要に応じて調整できます。
/*
こちらは、length_m as cost を使っている
query := `
SELECT seq, source, target, x1, y1, x2, y2, agg_cost
FROM pgr_dijkstra(
'SELECT gid as id, source, target, length_m as cost FROM ways',
$1::bigint,
$2::bigint,
directed:=false
) a
INNER JOIN ways b ON (a.edge = b.gid)
ORDER BY seq
`
*/
// こちらは、cost, reverse_cost を使っている
query := `
SELECT seq, source, target, x1, y1, x2, y2, agg_cost
FROM pgr_dijkstra(
'SELECT gid as id, source, target, cost, reverse_cost FROM ways',
$1::bigint,
$2::bigint,
directed:=false
) a
INNER JOIN ways b ON (a.edge = b.gid)
ORDER BY seq
`
こちらは、"length_m as cost" を使っては駄目だった。
cost, reverse_cost を使わなければならなかった。
もう、これで完成だ、と思っても次々問題が出てきて、本当に疲れる・・・
pgr_dijkstra()で、ダイクストラの順番を壊さずにルートの座標を得る方法(getDijkstraPath())
を改造する必要が出てきました。
特定領域内で、乱数的な緯度・経度の作成を行うコードをChatGPTに考えて貰いました。
package main
import (
"fmt"
"math"
"math/rand"
)
// Polygon represents a polygon defined by its vertices
type Polygon [][]float64
// Point represents a point with x and y coordinates
type Point struct {
X float64
Y float64
}
// isInPolygon checks if a point is inside a polygon using the ray casting algorithm
func (p Polygon) isInPolygon(point Point) bool {
intersections := 0
for i := 0; i < len(p); i++ {
p1 := p[i]
p2 := p[(i+1)%len(p)]
if point.Y > math.Min(p1[1], p2[1]) && point.Y <= math.Max(p1[1], p2[1]) &&
point.X <= math.Max(p1[0], p2[0]) && p1[1] != p2[1] {
xIntersection := (point.Y-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1]) + p1[0]
if p1[0] == p2[0] || point.X <= xIntersection {
intersections++
}
}
}
return intersections%2 != 0
}
// generateRandomPointInPolygon generates a random point inside the given polygon
func generateRandomPointInPolygon(p Polygon) Point {
var minX, minY, maxX, maxY float64
minX = math.MaxFloat64
minY = math.MaxFloat64
maxX = -math.MaxFloat64
maxY = -math.MaxFloat64
// Find bounding box of the polygon
for _, vertex := range p {
if vertex[0] < minX {
minX = vertex[0]
}
if vertex[1] < minY {
minY = vertex[1]
}
if vertex[0] > maxX {
maxX = vertex[0]
}
if vertex[1] > maxY {
maxY = vertex[1]
}
}
// Generate random points until a point inside the polygon is found
var randomPoint Point
for {
randomPoint.X = rand.Float64()*(maxX-minX) + minX
randomPoint.Y = rand.Float64()*(maxY-minY) + minY
if p.isInPolygon(randomPoint) {
break
}
}
return randomPoint
}
func main() {
// Define the polygon
polygon := Polygon{
{35.36394967, 139.61846500},
{35.36216810, 139.61890850},
{35.36170465505306, 139.6220415552594},
{35.36163108058289, 139.62334070015595},
{35.363117271878345, 139.62314221968566},
{35.36335187635167, 139.62481739887647},
{35.36310056060587, 139.62485183402688},
{35.36376860001917, 139.6288186562702},
{35.36420166714637, 139.6297897196359},
{35.36754482323006, 139.6296024603071},
{35.37126945661188, 139.62886244945108},
{35.37375189636854, 139.62615207124352},
{35.37464657021711, 139.623189740366},
{35.37574882601201, 139.6213765671167},
{35.37527643251494, 139.6210117866997},
{35.37306314467156, 139.6217413475337},
{35.37268696718477, 139.62013202216457},
{35.37018828750506, 139.61840497406456},
{35.370782160278, 139.61705458898427},
{35.36947068533102, 139.61641732865053},
{35.370596575495014, 139.61476348635583},
{35.37078029225879, 139.61403393574466},
{35.36864433631068, 139.61438212951467},
{35.36653571408147, 139.61453772192408},
{35.36394967, 139.61846500},
}
// Generate a random point inside the polygon
randomPoint := generateRandomPointInPolygon(polygon)
fmt.Println("Random point inside polygon:", randomPoint)
}
なるほど、と思いながらコードを読んでいたのですが、『あれ? これって、領域に入った緯度・経度の乱数を採用するだけだから、発生頻度が均一にならないんじゃないかな?』と思い、ChatGPTにたずねてみたら『Yes』と言われました。
で、発生頻度を均一になるコードを再度要求したのですが ―― コードを一目見て、『このコードは間違っているな』と分かるようなものが出てきました。
で、昔のコードを探していたら、PostGISを使うものが出てきました。
// C:\Users\ebata\tomioka3B\src\others\main35.go
/*
実験用の座標を作る
修正後 (富岡西5丁目を削除し、富岡6丁目の下1/4を削除)
このプログラムは、Go言語を使用してPostgreSQLデータベースから空間データを取得し、指定された多角形内に均等に配置された乱数の座標を生成します。以下はプログラムの概要です:
パッケージのインポート: 必要なパッケージをインポートします。database/sql はデータベースの操作に使用され、fmt と log は出力とログのために使用されます。また、PostgreSQLデータベースへの接続に使用するドライバもインポートされます。
main() 関数: プログラムのエントリーポイントです。まず、PostgreSQLデータベースに接続します。接続情報は、ユーザー名、パスワード、ホスト、ポート、およびデータベース名で構成されます。
SQLクエリの実行: query 変数にSQLクエリが格納されています。このクエリは、指定された多角形の領域内に均等に配置された15000個の点を生成するものです。db.Query() を使用してクエリを実行し、結果を rows に格納します。
結果の処理: rows.Next() を使用して、結果セットの各行を処理します。各行は msg として取得されます。次に、regexp パッケージを使用して、取得した座標データを処理します。
座標データの分解: 取得した座標データは、MULTIPOINT 形式の文字列として提供されます。この文字列をバラバラに分解し、各点の緯度と経度を取得します。regexp.MustCompile("[() ,]").Split(msg, -1) を使用して、文字列を分割します。
座標の表示: 緯度と経度のペアを取得し、それぞれを浮動小数点数に変換して表示します。
このプログラムは、指定された多角形内に均等に分布する乱数の座標を生成し、それを取得して表示します。
*/
package main
import (
"database/sql"
"fmt"
"log"
"regexp"
"strconv"
_ "github.com/lib/pq"
)
func main() {
// 取り扱うDBによってノード番号が代わるので注意すること
// 例えばtomioka_db_c とtomioka_dbは全く異なる
db, err := sql.Open("postgres",
"user=postgres password=password host=192.168.0.23 port=15432 dbname=tomioka_db_f sslmode=disable")
if err != nil {
log.Fatal("OpenError: ", err)
}
defer db.Close()
// 修正後のターゲットの富岡地区 (富岡西5丁目を削除し、富岡6丁目の下1/4を削除)
query := `
SELECT st_asText(
ST_GeneratePoints(
ST_GeomFromText(
'POLYGON((
35.36394967 139.61846500,
35.36216810 139.61890850,
35.36170465505306 139.6220415552594,
35.36163108058289 139.62334070015595,
35.363117271878345 139.62314221968566,
35.36335187635167 139.62481739887647,
35.36310056060587 139.62485183402688,
35.36376860001917 139.6288186562702,
35.36420166714637 139.6297897196359,
35.36754482323006 139.6296024603071,
35.37126945661188 139.62886244945108,
35.37375189636854 139.62615207124352,
35.37464657021711 139.623189740366,
35.37574882601201 139.6213765671167,
35.37527643251494 139.6210117866997,
35.37306314467156 139.6217413475337,
35.37268696718477 139.62013202216457,
35.37018828750506 139.61840497406456,
35.370782160278 139.61705458898427,
35.36947068533102 139.61641732865053,
35.370596575495014 139.61476348635583,
35.37078029225879 139.61403393574466,
35.36864433631068 139.61438212951467,
35.36653571408147 139.61453772192408,
35.36394967 139.61846500
))'
),
15000)
)
`
rows, err := db.Query(query) // この25が生成する乱数座標
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var msg string
for rows.Next() {
if err := rows.Scan(&msg); err != nil {
fmt.Println(err)
}
// まずはMULTIPOINTをバラバラに分解する
arr1 := regexp.MustCompile("[() ,]").Split(msg, -1) // '('か、')'か、' 'か、","で分割する → "[中身]" という構造でまぎらわしい
// 2つの値を一度に取得する (最初の値" MULTIPOIN"をスキップする為に、i:=1から始める)
for i := 1; i < len(arr1); i += 2 {
// arr1[i]とarr1[i+1]は2つの値を表します
if i+1 < len(arr1) {
value1, _ := strconv.ParseFloat(arr1[i], 64) // 乱数の緯度
value2, _ := strconv.ParseFloat(arr1[i+1], 64) // 乱数の経度
fmt.Println(i, value1, value2)
}
}
}
}
ポイントは、指定された多角形内に均等に分布する乱数の座標を生成 という点です。
どういう仕組みか分かりませんし、ChatGPTが真実を言っているのかも不明ですが、『postGISなら、その程度の仕組みは入れてくるだろう』と期待して、今回は、こちらを使うことにしました。
以上
なんでもかんでも、ニューラルネットワークに突っ込む必要はないと思うんですよね。
/*
c:\users\ebata\tomioka3b\src\others\main41.go
このプログラムは、与えられた地点の緯度経度情報と京急富岡駅からの電車による移動時間を元に、スプライン補間を行い、特定の座標における移動時間を補間することを目的としています。
Point 構造体は、地点の名前 (Name)、緯度 (Latitude)、経度 (Longitude)、移動時間 (min2Tomioka) の情報を保持します。
convertToDataSet 関数は、Point 構造体の配列を受け取り、それを緯度、経度、標高の情報を含む二次元配列データセットに変換します。
splineInterpolation 関数は、スプライン補間を行うための関数を返します。この関数は、与えられたデータセットを元に、スプライン補間に必要な計算を行います。
main 関数では、与えられた地点の情報を元に Point 構造体のスライスが定義され、それを convertToDataSet 関数で二次元配列データセットに変換します。
さらに、splineInterpolation 関数を使用してスプライン補間関数を生成し、特定の座標における移動時間を補間します。
最後に、補間された値が出力されます。
このプログラムは、地理空間データの補間処理に利用できる汎用的なスプライン補間関数を提供します。
*/
package main
import (
"fmt"
"sort"
)
type Point struct {
Name string
Latitude float64
Longitude float64
min2Tomioka float64
}
// スプライン補間用の関数
func splineInterpolation(dataSet [][]float64) func(float64, float64) float64 {
n := len(dataSet)
// xの値を昇順にソートする
sort.Slice(dataSet, func(i, j int) bool {
return dataSet[i][0] < dataSet[j][0]
})
// トリディアゴナル行列を作成
h := make([]float64, n-1)
for i := 0; i < n-1; i++ {
h[i] = dataSet[i+1][0] - dataSet[i][0]
}
// 2階微分の値を計算
delta := make([]float64, n)
for i := 1; i < n-1; i++ {
delta[i] = (dataSet[i+1][1]-dataSet[i][1])/h[i] - (dataSet[i][1]-dataSet[i-1][1])/h[i-1]
}
// トリディアゴナル行列を解く
m := make([]float64, n)
l := make([]float64, n)
zArray := make([]float64, n)
l[0] = 1
for i := 1; i < n-1; i++ {
l[i] = 2*(dataSet[i+1][0]-dataSet[i-1][0]) - h[i-1]*m[i-1]
m[i] = h[i] / l[i]
zArray[i] = (delta[i] - h[i-1]*zArray[i-1]) / l[i]
}
l[n-1] = 1
zArray[n-1] = 0
c := make([]float64, n)
b := make([]float64, n)
d := make([]float64, n)
for j := n - 2; j >= 0; j-- {
c[j] = zArray[j] - m[j]*c[j+1]
b[j] = (dataSet[j+1][1]-dataSet[j][1])/h[j] - h[j]*(c[j+1]+2*c[j])/3
d[j] = (c[j+1] - c[j]) / (3 * h[j])
}
// 補間関数を返す
return func(xVal, yVal float64) float64 {
// xの範囲を確認
if xVal < dataSet[0][0] || xVal > dataSet[n-1][0] {
panic("x value is out of range")
}
// 対応するiを探す
i := 0
for i < n-1 && dataSet[i+1][0] <= xVal {
i++
}
// スプライン補間を計算
dx := xVal - dataSet[i][0]
return dataSet[i][2] + b[i]*dx + c[i]*dx*dx + d[i]*dx*dx*dx
}
}
func convertToDataSet(points []Point) [][]float64 {
var dataSet [][]float64
for _, point := range points {
data := []float64{point.Latitude, point.Longitude, point.min2Tomioka}
dataSet = append(dataSet, data)
}
return dataSet
}
func main() {
points := []Point{
{"日暮里", 35.72810551475649, 139.77065214505967, 73}, // 日暮里
{"鶯谷", 35.72147285483459, 139.77803484630024, 63}, // 鶯谷
{"上野", 35.71419330617392, 139.7774413019538, 57}, // 上野
{"御徒町", 35.70752513412557, 139.7748544863164, 67}, // 御徒町
{"秋葉原", 35.6983999333567, 139.77290571388025, 65}, // 秋葉原
{"お茶の水", 35.69977763102643, 139.76447338219248, 61}, // お茶の水
{"水道橋", 35.7020483726974, 139.75337286940393, 66}, // 水道橋
{"神田", 35.691843953947895, 139.77075286750426, 63}, // 神田
{"東京", 35.68127103173912, 139.76691023873528, 57}, // 東京
{"有楽町", 35.67504451109795, 139.7629009441794, 59}, // 有楽町
{"新橋", 35.6663876890884, 139.7580715945385, 55}, // 新橋
{"浜松町", 35.65538959029243, 139.75707527127187, 54}, // 浜松町
{"田町", 35.64573607270807, 139.7475731442898, 54}, // 田町
{"品川", 35.628479993237924, 139.73869534241823, 43}, // 品川
{"北品川", 35.62204337901307, 139.73929378869565, 50}, // 北品川
{"青物横丁", 35.616530476669595, 139.74147241132803, 49}, // 新馬場
{"青物横丁", 35.6089113073848, 139.74314516357873, 45}, // 青物横丁
{"鮫洲", 35.60505014227371, 139.74226998316405, 50}, // 鮫洲
{"立会川", 35.598565208786674, 139.73893538884946, 50}, // 立会川
{"大森海岸", 35.58770513004266, 139.73546417819148, 51}, // 大森海岸
{"平和島", 35.578786612348516, 139.7348957122944, 40}, // 平和島
{"大森町", 35.572470928220454, 139.73209389290315, 53}, // 大森町
{"梅屋敷", 35.56680589146817, 139.7282405712228, 53}, // 梅屋敷
{"京急蒲田", 35.561346378009084, 139.72413782845052, 33}, // 京急蒲田
{"雑色", 35.549501628543595, 139.71492252305998, 38}, // 雑色
{"六郷土手", 35.540534565682265, 139.70758227692838, 34}, // 六郷土手
{"糀谷", 35.55475500818507, 139.72947450479222, 40}, // 糀谷
{"大鳥居", 35.55230710920823, 139.74016209480337, 45}, // 大鳥居
{"穴守稲荷", 35.550433498630504, 139.7467475129522, 46}, // 穴守稲荷
{"天空橋", 35.549323611239814, 139.75367380680967, 46}, // 天空橋
{"京急川崎", 35.5330130222155, 139.70085261643172, 30}, // 京急川崎
{"小島新田", 35.53497952289224, 139.74753015189842, 42}, // 小島新田
{"八丁畷", 35.523294588264044, 139.69182471487903, 41}, // 八丁畷
{"鶴見市場", 35.51795110131048, 139.68654897642313, 40}, // 鶴見市場
{"京急鶴見", 35.507313116366205, 139.67793452856546, 34}, // 京急鶴見
{"花月総持寺", 35.50045335293103, 139.67299835084395, 31}, // 花月総持寺
{"生麦", 35.49532037586162, 139.66697084291033, 30}, // 生麦
{"京急新子安", 35.48709301222138, 139.6554644900453, 29}, // 京急新子安
{"子安", 35.484595747125226, 139.64499414507037, 32}, // 子安
{"神奈川新町", 35.48089584236831, 139.63961808116608, 26}, // 神奈川新町
{"京急東神奈川", 35.47728484644749, 139.63437152522133, 30}, // 京急東神奈川
{"神奈川", 35.471042823081326, 139.62708525622278, 32}, // 神奈川
{"京急横浜", 35.465974566273886, 139.6218737093478, 20}, // 京急横浜
{"戸部", 35.45669353999209, 139.61954391949988, 27}, // 戸部
{"日ノ出町", 35.445535830399635, 139.62677764713118, 25}, // 日ノ出町
{"黄金町", 35.4398051861557, 139.6228192707623, 24}, // 黄金町
{"南太田", 35.43704871593425, 139.61413963595152, 18}, // 南太田
{"井土ヶ谷", 35.434049908914936, 139.6013697675809, 16}, // 井土ヶ谷
{"弘明寺", 35.424392517088215, 139.59679056178064, 17}, // 弘明寺
{"上大岡", 35.409119230795824, 139.59658257505384, 14}, // 上大岡
{"屏風浦", 35.394628914972444, 139.61025512796533, 10}, // 屏風浦
{"杉田", 35.38359625400674, 139.6158614781421, 3}, // 杉田
{"京急富岡", 35.36713079862617, 139.6298755067998, 0}, // 京急富岡
{"能見台", 35.36088096572114, 139.62943901110575, 1}, // 能見台
{"京急金沢文庫", 35.34283976967888, 139.62161382892742, 3}, // 京急金沢文庫
{"金沢八景", 35.33143644664979, 139.62019186432977, 6}, // 金沢八景
{"野島公園", 35.33057520638215, 139.63154448609114, 17}, // 野島公園
{"海の公園南口", 35.337221851530074, 139.63203843792144, 18}, // 海の公園南口
{"海の公園芝口", 35.34207978297347, 139.6357948657779, 18}, // 海の公園芝口
{"八景島", 35.34081263381398, 139.64082413734104, 20}, // 八景島
{"六浦", 35.32276335943298, 139.61123194142903, 13}, // 六浦
{"神武寺", 35.306362422782364, 139.59316695868543, 19}, // 神武寺
{"逗子・葉山", 35.29593435944306, 139.5811992373588, 31}, // 逗子・葉山
{"追浜", 35.3158514243523, 139.62481670534095, 15}, // 追浜
{"京急田浦", 35.30091271311823, 139.62553483073157, 16}, // 京急田浦
{"安針塚", 35.28681218160922, 139.64296751736376, 17}, // 安針塚
{"逸見", 35.28064334099864, 139.6528184088048, 21}, // 逸見
{"汐入", 35.280307747849356, 139.6624959442711, 19}, // 汐入
{"横須賀中央", 35.27868971431925, 139.6700294865965, 20}, // 横須賀中央
{"県立大学", 35.27046934794596, 139.6765472421848, 26}, // 県立大学
{"堀ノ内", 35.263578813428, 139.68674190193195, 23}, // 堀ノ内
{"新大津", 35.25692239324099, 139.69014415109714, 23}, // 新大津
{"北久里浜", 35.2497686048071, 139.68628696286345, 25}, // 北久里浜
{"浦賀", 35.250938172839675, 139.71498764424754, 30}, // 浦賀
{"京急久里浜", 35.231585086558596, 139.7022284815838, 29}, // 京急久里浜
{"YRP野比", 35.21207247285571, 139.68500815775707, 33}, // YRP野比
{"京急長沢", 35.20555570645748, 139.67414472893097, 44}, // 京急長沢
{"津久井浜", 35.19868000571067, 139.66570472891374, 37}, // 津久井浜
{"三浦海岸", 35.188117336673066, 139.65328211521543, 39}, // 三浦海岸
{"三崎口", 35.17752001890131, 139.633171976671, 42}, // 三崎口
}
dataSet := convertToDataSet(points)
// スプライン補間関数を作成
interpolatedFunction := splineInterpolation(dataSet)
// 特定の座標で補間された値を計算
xValue := 35.4688634
yValue := 139.6268306
xValue, yValue = 35.7214573, 139.7754384
interpolatedValue := interpolatedFunction(xValue, yValue)
// 結果の出力
fmt.Printf("補間された値: %.2f\n", interpolatedValue)
}
// c:\users\ebata\tomioka3b\src\others\main45.go
/*
このプログラムは、与えられた複数の地点の中からランダムに1つを選択し、その地点を中心として半径500メートルの円内にランダムな地点を生成します。
Point 構造体: 緯度と経度を表す構造体です。
main 関数:
与えられた複数の地点のリストを作成します。
ランダムに1つの地点を選択します。
選択された地点を中心として、generateRandomPointInCircle 関数を使用して半径500メートルの円内にランダムな地点を生成します。
生成されたランダムな地点の緯度と経度を出力します。
generateRandomPointInCircle 関数:
中心となる地点と半径を受け取ります。
ランダムな角度と距離を生成し、それらを使用して円内のランダムな地点の緯度と経度を計算します。
計算された緯度と経度を持つ地点を返します。
degToRad 関数:
度をラジアンに変換するためのユーティリティ関数です。
このプログラムは、与えられた地点の中からランダムに1つを選択し、その地点を中心として半径500メートルの円内にランダムな地点を生成することで、地理空間データを扱うための基本的な方法を示しています。
*/
package main
import (
"fmt"
"math"
"math/rand"
"time"
)
type Point struct {
Name string
Latitude float64
Longitude float64
min2Tomioka float64
}
func main() {
// 与えられた複数の点(駅の座標)
points := []Point{
{"日暮里", 35.72810551475649, 139.77065214505967, 73}, // 日暮里
{"鶯谷", 35.72147285483459, 139.77803484630024, 63}, // 鶯谷
{"上野", 35.71419330617392, 139.7774413019538, 57}, // 上野
{"御徒町", 35.70752513412557, 139.7748544863164, 67}, // 御徒町
{"秋葉原", 35.6983999333567, 139.77290571388025, 65}, // 秋葉原
{"お茶の水", 35.69977763102643, 139.76447338219248, 61}, // お茶の水
{"水道橋", 35.7020483726974, 139.75337286940393, 66}, // 水道橋
{"神田", 35.691843953947895, 139.77075286750426, 63}, // 神田
{"東京", 35.68127103173912, 139.76691023873528, 57}, // 東京
{"有楽町", 35.67504451109795, 139.7629009441794, 59}, // 有楽町
{"新橋", 35.6663876890884, 139.7580715945385, 55}, // 新橋
{"浜松町", 35.65538959029243, 139.75707527127187, 54}, // 浜松町
{"田町", 35.64573607270807, 139.7475731442898, 54}, // 田町
{"品川", 35.628479993237924, 139.73869534241823, 43}, // 品川
{"北品川", 35.62204337901307, 139.73929378869565, 50}, // 北品川
{"青物横丁", 35.616530476669595, 139.74147241132803, 49}, // 新馬場
{"青物横丁", 35.6089113073848, 139.74314516357873, 45}, // 青物横丁
{"鮫洲", 35.60505014227371, 139.74226998316405, 50}, // 鮫洲
{"立会川", 35.598565208786674, 139.73893538884946, 50}, // 立会川
{"大森海岸", 35.58770513004266, 139.73546417819148, 51}, // 大森海岸
{"平和島", 35.578786612348516, 139.7348957122944, 40}, // 平和島
{"大森町", 35.572470928220454, 139.73209389290315, 53}, // 大森町
{"梅屋敷", 35.56680589146817, 139.7282405712228, 53}, // 梅屋敷
{"京急蒲田", 35.561346378009084, 139.72413782845052, 33}, // 京急蒲田
{"雑色", 35.549501628543595, 139.71492252305998, 38}, // 雑色
{"六郷土手", 35.540534565682265, 139.70758227692838, 34}, // 六郷土手
{"糀谷", 35.55475500818507, 139.72947450479222, 40}, // 糀谷
{"大鳥居", 35.55230710920823, 139.74016209480337, 45}, // 大鳥居
{"穴守稲荷", 35.550433498630504, 139.7467475129522, 46}, // 穴守稲荷
{"天空橋", 35.549323611239814, 139.75367380680967, 46}, // 天空橋
{"京急川崎", 35.5330130222155, 139.70085261643172, 30}, // 京急川崎
{"小島新田", 35.53497952289224, 139.74753015189842, 42}, // 小島新田
{"八丁畷", 35.523294588264044, 139.69182471487903, 41}, // 八丁畷
{"鶴見市場", 35.51795110131048, 139.68654897642313, 40}, // 鶴見市場
{"京急鶴見", 35.507313116366205, 139.67793452856546, 34}, // 京急鶴見
{"花月総持寺", 35.50045335293103, 139.67299835084395, 31}, // 花月総持寺
{"生麦", 35.49532037586162, 139.66697084291033, 30}, // 生麦
{"京急新子安", 35.48709301222138, 139.6554644900453, 29}, // 京急新子安
{"子安", 35.484595747125226, 139.64499414507037, 32}, // 子安
{"神奈川新町", 35.48089584236831, 139.63961808116608, 26}, // 神奈川新町
{"京急東神奈川", 35.47728484644749, 139.63437152522133, 30}, // 京急東神奈川
{"神奈川", 35.471042823081326, 139.62708525622278, 32}, // 神奈川
{"京急横浜", 35.465974566273886, 139.6218737093478, 20}, // 京急横浜
{"戸部", 35.45669353999209, 139.61954391949988, 27}, // 戸部
{"日ノ出町", 35.445535830399635, 139.62677764713118, 25}, // 日ノ出町
{"黄金町", 35.4398051861557, 139.6228192707623, 24}, // 黄金町
{"南太田", 35.43704871593425, 139.61413963595152, 18}, // 南太田
{"井土ヶ谷", 35.434049908914936, 139.6013697675809, 16}, // 井土ヶ谷
{"弘明寺", 35.424392517088215, 139.59679056178064, 17}, // 弘明寺
{"上大岡", 35.409119230795824, 139.59658257505384, 14}, // 上大岡
{"屏風浦", 35.394628914972444, 139.61025512796533, 10}, // 屏風浦
{"杉田", 35.38359625400674, 139.6158614781421, 3}, // 杉田
{"京急富岡", 35.36713079862617, 139.6298755067998, 0}, // 京急富岡
{"能見台", 35.36088096572114, 139.62943901110575, 1}, // 能見台
{"京急金沢文庫", 35.34283976967888, 139.62161382892742, 3}, // 京急金沢文庫
{"金沢八景", 35.33143644664979, 139.62019186432977, 6}, // 金沢八景
{"野島公園", 35.33057520638215, 139.63154448609114, 17}, // 野島公園
{"海の公園南口", 35.337221851530074, 139.63203843792144, 18}, // 海の公園南口
{"海の公園芝口", 35.34207978297347, 139.6357948657779, 18}, // 海の公園芝口
{"八景島", 35.34081263381398, 139.64082413734104, 20}, // 八景島
{"六浦", 35.32276335943298, 139.61123194142903, 13}, // 六浦
{"神武寺", 35.306362422782364, 139.59316695868543, 19}, // 神武寺
{"逗子・葉山", 35.29593435944306, 139.5811992373588, 31}, // 逗子・葉山
{"追浜", 35.3158514243523, 139.62481670534095, 15}, // 追浜
{"京急田浦", 35.30091271311823, 139.62553483073157, 16}, // 京急田浦
{"安針塚", 35.28681218160922, 139.64296751736376, 17}, // 安針塚
{"逸見", 35.28064334099864, 139.6528184088048, 21}, // 逸見
{"汐入", 35.280307747849356, 139.6624959442711, 19}, // 汐入
{"横須賀中央", 35.27868971431925, 139.6700294865965, 20}, // 横須賀中央
{"県立大学", 35.27046934794596, 139.6765472421848, 26}, // 県立大学
{"堀ノ内", 35.263578813428, 139.68674190193195, 23}, // 堀ノ内
{"新大津", 35.25692239324099, 139.69014415109714, 23}, // 新大津
{"北久里浜", 35.2497686048071, 139.68628696286345, 25}, // 北久里浜
{"浦賀", 35.250938172839675, 139.71498764424754, 30}, // 浦賀
{"京急久里浜", 35.231585086558596, 139.7022284815838, 29}, // 京急久里浜
{"YRP野比", 35.21207247285571, 139.68500815775707, 33}, // YRP野比
{"京急長沢", 35.20555570645748, 139.67414472893097, 44}, // 京急長沢
{"津久井浜", 35.19868000571067, 139.66570472891374, 37}, // 津久井浜
{"三浦海岸", 35.188117336673066, 139.65328211521543, 39}, // 三浦海岸
{"三崎口", 35.17752001890131, 139.633171976671, 42}, // 三崎口
}
// ランダムな点を選択
rand.Seed(time.Now().UnixNano())
for i := 0; i < 1000; i++ {
randomIndex := rand.Intn(len(points))
center := points[randomIndex]
// 中心点から半径500メートルの円内にランダムな点を生成
randomPoint := generateRandomPointInCircle(center, 500)
//fmt.Printf("Random Point in Circle: Latitude=%f, Longitude=%f\n", randomPoint.Latitude, randomPoint.Longitude)
fmt.Printf("%f, %f\n", randomPoint.Latitude, randomPoint.Longitude)
}
}
func generateRandomPointInCircle(center Point, radius float64) Point {
// ランダムな角度を生成
randAngle := rand.Float64() * 2 * math.Pi
//fmt.Printf("randAngle=%f\n", randAngle)
// ランダムな距離を生成
randDistance := math.Sqrt(rand.Float64()) * radius
//fmt.Printf("randDistance=%f\n", randDistance)
// ランダムな点の座標を計算
randLat := center.Latitude + (randDistance/6371000.0)*(180/math.Pi)*(math.Cos(randAngle))
randLon := center.Longitude + (randDistance/6371000.0)*(180/math.Pi)*(math.Sin(randAngle))/(math.Cos(degToRad(center.Latitude)))
return Point{Latitude: randLat, Longitude: randLon}
}
func degToRad(deg float64) float64 {
return deg * (math.Pi / 180)
}