質問編集履歴
1
前回質問から一部解決できたので、解決できない部分に絞った質問に変えました。
title
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
GoogleMapsAPIで取得した詳細な座標配列(legs/step/path)から、一定距離の地点にマーカーを立てたい
|
body
CHANGED
@@ -3,129 +3,69 @@
|
|
3
3
|
歩いた距離は、活動量トラッカーFitbitのAPIを使ってタイムリーに取得します。
|
4
4
|
|
5
5
|
##これまでできたこと
|
6
|
-
|
6
|
+
起点から終点までのルートを取得し、下記のarrでそのルート上の座標配列を取得。隣り合った座標の距離を次々足していき、指定した距離に最近接の座標にマーカーを立てることができました。
|
7
7
|
|
8
|
+
```javascript
|
9
|
+
var arr = response.routes[0].overview_path;
|
8
|
-
|
10
|
+
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
11
|
+
var difference = Infinity;
|
12
|
+
var total = 0;
|
13
|
+
for (var i = 0, l = arr.length - 1; i < l; i++) {
|
14
|
+
var current = arr[i];
|
15
|
+
var distance = between(current, arr[i + 1]);
|
16
|
+
var dif = Math.abs(mark - (total + distance));
|
17
|
+
if (difference > dif) {
|
18
|
+
difference = dif;
|
19
|
+
total += distance;
|
20
|
+
}
|
21
|
+
else {
|
22
|
+
new gMaps.Marker({
|
23
|
+
position: current,
|
24
|
+
map: map,
|
25
|
+
title: total + 'm'
|
26
|
+
});
|
27
|
+
break;
|
28
|
+
}
|
9
29
|
|
30
|
+
```
|
10
31
|
|
32
|
+
##改善したこと、試みたこと
|
33
|
+
より誤差を小さくするため、ルート上のより多くの座標を取得できないか調べたところ、routesの下の、overview_pathプロパティ以外に、legs > steps > pathと辿って行ったところに、より詳細な座標が格納されていることが分かりました。これをfor文で回して取得し、全てをまとめてwhole_pathという座標配列にして見ました。座標の数(length)をみると、overview_pathの座標の数と比べて7倍くらい多く、精度が高いことが確認できました。
|
34
|
+
これをもとに、同じように隣り合った座標間の距離を次々足していき、指定した距離に最近接の座標にマーカーを立てようと以下のようなコードにしてみましたが、うまくいきませんでした。
|
11
35
|
|
12
|
-
```
|
36
|
+
```javascript
|
13
|
-
|
14
|
-
<script>
|
15
|
-
function initMap() {
|
16
|
-
var gMaps = google.maps;
|
17
|
-
var ds = new gMaps.DirectionsService;
|
18
|
-
var map = new gMaps.Map(document.getElementById('map_canvas'));
|
19
|
-
|
37
|
+
var whole_path = [];
|
20
|
-
{ lat: 43.16787133305725, lng: -1.2377224338793966, name: 'Saint-Jean-Pied-de-Port(サン・ジャン・ピエ・ド・ポー)' },
|
21
|
-
***中略。34カ所の経由地点が書かれています***
|
22
|
-
{ lat: 42.88081810734543, lng: -8.544630899970322, name: 'Santiago de Compostela(サンティアゴ・デ・コンポステーラ)' },
|
23
|
-
];
|
24
|
-
|
25
|
-
|
38
|
+
var legs = response.routes[0].legs;
|
26
|
-
var lats = stations.map(function (station) { return station.lat; });
|
27
|
-
map.fitBounds({
|
28
|
-
west: Math.min.apply(null, lngs),
|
29
|
-
east: Math.max.apply(null, lngs),
|
30
|
-
north: Math.min.apply(null, lats),
|
31
|
-
south: Math.max.apply(null, lats),
|
32
|
-
});
|
33
|
-
|
34
|
-
|
39
|
+
for (i = 0; i < legs.length; i++) {
|
35
|
-
new google.maps.Marker({
|
36
|
-
position: stations[i],
|
37
|
-
map: map,
|
38
|
-
|
40
|
+
var steps = legs[i].steps;
|
41
|
+
for (j = 0; j < steps.length; j++) {
|
42
|
+
var nextSegment = steps[j].path;
|
43
|
+
for (k = 0; k < nextSegment.length; k++) {
|
39
|
-
|
44
|
+
whole_path.push(nextSegment[k]);
|
40
45
|
}
|
41
|
-
|
46
|
+
}
|
47
|
+
}
|
42
|
-
|
48
|
+
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
49
|
+
var difference = Infinity;
|
50
|
+
var total = 0;
|
43
|
-
|
51
|
+
for (var i = 0, l = whole_path.length - 1; i < l; i++) {
|
52
|
+
var current = whole_path[i];
|
44
|
-
|
53
|
+
var distance = between(current, whole_path[i + 1]);
|
45
|
-
|
46
|
-
|
54
|
+
var dif = Math.abs(mark - (total + distance));
|
47
|
-
var mark = document.getElementById("mark").value;
|
48
|
-
|
55
|
+
if (difference > dif) {
|
49
|
-
console.log('Directions request failed due to ' + status);
|
50
|
-
|
56
|
+
difference = dif;
|
57
|
+
total += distance;
|
51
58
|
}
|
59
|
+
else {
|
60
|
+
new gMaps.Marker({
|
61
|
+
position: current,
|
62
|
+
map: map,
|
63
|
+
title: total + 'm'
|
64
|
+
});
|
65
|
+
break;
|
66
|
+
}
|
52
67
|
|
53
|
-
|
68
|
+
```
|
54
|
-
//for (var h = 0; h < response.routes[0].legs.length; h++) {
|
55
|
-
// m += response.routes[0].legs[h].distance.value;
|
56
|
-
//} // ルートの距離(m)を取得できたが、ふたつに分割されている
|
57
69
|
|
58
|
-
var disp = new gMaps.DirectionsRenderer;
|
59
|
-
disp.setMap(map);
|
60
|
-
disp.setOptions({
|
61
|
-
suppressMarkers: true,
|
62
|
-
preserveViewport: true,
|
63
|
-
suppressInfoWindows: false,
|
64
|
-
polylineOptions: {
|
65
|
-
strokeColor: '#ff0000',
|
66
|
-
strokeOpacity: 0.5,
|
67
|
-
strokeWeight: 3
|
68
|
-
}
|
69
|
-
});
|
70
|
-
|
71
|
-
var arr = response.routes[0].overview_path; //legs.step.path; ??//
|
72
|
-
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
73
|
-
var difference = Infinity;
|
74
|
-
var total = 0;
|
75
|
-
for (var m = 0, l = arr.length - 1; m < l; m++) {
|
76
|
-
var current = arr[m];
|
77
|
-
var distance = between(current, arr[m + 1]);
|
78
|
-
var dif = Math.abs(mark - (total + distance));
|
79
|
-
if (difference > dif) {
|
80
|
-
difference = dif; // 距離差を更新
|
81
|
-
total += distance; // 合計距離を更新
|
82
|
-
} else {
|
83
|
-
var panorama = new google.maps.StreetViewPanorama(
|
84
|
-
document.getElementById("pano"),
|
85
|
-
{position: current,
|
86
|
-
pov: {heading: 270,
|
87
|
-
pitch: 0,
|
88
|
-
},
|
89
|
-
});
|
90
|
-
map.setStreetView(panorama);
|
91
|
-
break;
|
92
|
-
}}
|
93
|
-
disp.setDirections(response);
|
94
|
-
};
|
95
|
-
for (var i = 0; i < parts.length; i++) {
|
96
|
-
var waypoints = [];
|
97
|
-
for (var j = 1; j < parts[i].length - 1; j++)
|
98
|
-
waypoints.push({ location: parts[i][j], stopover: false });
|
99
|
-
var request = {
|
100
|
-
origin: parts[i][0],
|
101
|
-
destination: parts[i][parts[i].length - 1],
|
102
|
-
waypoints: waypoints,
|
103
|
-
travelMode: 'WALKING'
|
104
|
-
};
|
105
|
-
ds.route(request, service_callback);
|
106
|
-
}
|
107
|
-
}
|
108
|
-
</script>
|
109
|
-
<script async defer
|
110
|
-
src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxx&callback=initMap"></script>
|
111
|
-
|
112
|
-
```##改善したいこと
|
113
|
-
前段として、数10kmのルート上で試している時は誤差が数10mくらいで、あまり気にならなかったのですが、このルートは全長800kmあるので(当たり前かもしれませんが)誤差が非常に大きくなります。
|
114
|
-
|
115
|
-
中盤の「var arr = response.routes[0].overview_path;」で得られる座標配列をコンソール画面で調べたところ、全長のうち計400カ所超のようです。必然的に数kmの誤差が出る計算です。
|
116
|
-
|
117
|
-
前段の数10kmのルート上で調べた時も得られた座標配列のlengthは200超だったので、取得できる座標の数は長さに比例して多くなるのではなく、一定程度に決められているのでしょうか??
|
118
|
-
|
119
|
-
|
70
|
+
途中までは、上と同じようにうまく行っているようなのですが、最後にcurrentの座標を調べてみると、起点と同じ位置から動いていません。
|
120
|
-
|
121
|
-
##試してみたこと
|
122
|
-
取得できたオブジェクトを見ると、「routes.overview_path」のほか、「routes.legs.step.path」というところにより細かい座標が入っているようだったので、「var arr = response.routes[0].legs.step.path;」と変えてみましたが、うまく行かず、おまけにレンダリングされたルートの線も消えてしまいました。
|
123
|
-
|
124
|
-
##さらにもう1点、お知恵を拝借したいこと
|
125
|
-
Googlemapsには経由地(WayPoints)の数の制限があり、APIを取得していた場合でも起点・終点を含めて25カ所が上限と理解しています。巡礼路は、重要な巡礼地を経由してこそのルートなので、なんとかこれを回避する方法を模索しました。ネットのサンプルコードを参考に、詳しく仕組みは理解していませんが、ルートをDivideしてつなぎ合わせる形にしたのが上のコードです。
|
126
|
-
|
127
|
-
起点がふたつあるような形になっていて、「歩いた距離」の地点にマーカーを立つようにすると2カ所に立ちます。上のルート上の座標も約200カ所ずつに分かれて出力されます。総距離mも500数十kmと200数十kmのふたつに分かれて出ます。
|
128
|
-
|
129
|
-
これをうまくつなぎ、全行程で本来の起点(サン・ジャン・ピエ・ド・ポー=フランス)から歩いた距離の地点をCurrentとして取得できる仕組みをつくりたいと考えています。いろいろ調べたり、考えたりしましたが、今のところ足がかりさえ見えなません。
|
130
|
-
|
131
|
-
方
|
71
|
+
どうしたら良いのか(そもそも、この考え方で良いのかどうか)ご教示頂けると、とてもとてもありがたく思います。どうぞよろしくお願いいたします。
|