YAMAPの登山計画書閲覧ページからルート情報をgeojsonで取得するscript
2023-10-07 14:23:41 使えなくなっていた
__NUXT__にルートデータが含まれなくなった
しかもこの中には時刻情報が含まれない。コードを解析してどのように時刻を再現しているか探らないといけない
使い方
下記のscriptを登山計画書ページから開発コンソールに貼り付けて実行する
geojsonのdownload windowが表示されるので、それを保存する
備考
propertiesは地理院地図の規格に準拠している ラベルの位置は手動で調整すること
からくり
Nuxt.jsは、どうやら内部で使っているデータをwindow.__NUXT__に露出しているらしい
この中に表示している登山計画書のデータが含まれているので、そこからルート座標を取り出してgeojsonを作ればいい
同じ原理で、KMLなどももちろん作成できる
実装したいこと
も表示する?
バグ
計算が難しい
修正済み
2022-10-15 20:56:58 まだずれてるかも
そのうち確認する
2022-10-15
20:38:07 「分岐」という名前のラベルを除外した
2022-08-09
12:45:17
各地点の到着時刻も表示する
座標が地点名と重なっているので、適宜手動で動かすこと
自動でずらすのは難しいtakker.icon
縮尺によって緯度の移動量が変化するため
ファイル名に計画書のタイトルを使う
スタイルは適宜調整すること
code:js
{
const plan = __NUXT__.data0.plan; const rootName = plan.title; // 適宜変更する
const root = plan.coords;
const startAt = new Date(plan.start_at * 1000);
// 前のポイントからの移動時間を計算するのに必要な変数
let cursor = new Date(startAt);
let prev = 0;
/** @type {{ coord: number[]; name: string; arrived: Date; stayTime: number; }[]}
*
* stayTimeの単位は秒
*/
const checkpoints = plan.checkpoints.flatMap((point) => {
const coord = point.landmark.coord;
const name = point.landmark.name;
/** その日の最初のポイントかどうか */
const isStart = point.cumulative_down === 0 && point.cumulative_up === 0;
const now = point.arrival_time_in_seconds;
const arrived = !isStart ?
new Date(cursor.getTime() + Math.round((now - prev) * 1000 * plan.time_multiplier)) :
new Date(startAt.getTime() + now * 1000);
arrived.setDate(arrived.getDate() + point.arrival_day_number - 1);
prev = now + point.stay_time;
cursor = new Date(arrived.getTime() + point.stay_time * 1000);
return { coord, name, arrived, stayTime: point.stay_time };
});
const zero = (n) => ${n}.padStart(2, "0");
const toHHMM = (date) => ${zero(date.getHours())}:${zero(date.getMinutes())};
const geoJson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: {
name: rootName,
_color: "#56a066",
_opacity: 1,
_weight: 3,
},
geometry: {
type: "LineString",
coordinates: root,
},
},
// 通過点の図形情報
...checkpoints.flatMap(({
coord, name, arrived,
}) => {
const geometries = [
{
type: "Feature",
properties: {
_markerType: "Icon",
// よくある逆しずく形のアイコン
// そのままだと大きいので、1/2に縮小する
// 逆しずくの脚部分をアンカーにする
},
geometry: {
type: "Point",
coordinates: coord,
},
},
{
type: "Feature",
properties: {
_markerType: "DivIcon",
_html: <div style=\"font-size:12pt;font-weight:bold;\">${toHHMM(arrived)}</div>,
},
geometry: {
type: "Point",
coordinates: coord,
},
},
];
if (name !== "分岐")geometries.push(
{
type: "Feature",
properties: {
_markerType: "DivIcon",
_html: <div style=\"font-size:18pt;font-weight:bold;\">${name}</div>,
},
geometry: {
type: "Point",
coordinates: coord,
},
}
);
return geometries;
}),
],
};
const url = URL.createObjectURL(new Blob(
{ type: "application/json" },
));
const a = document.createElement("a");
a.href = url;
a.download = ${rootName}.geojson;
a.style.display = "none";
document.body.append(a);
a.click();
a.remove();
}