質問編集履歴
1
前回質問から一部解決できたので、解決できない部分に絞った質問に変えました。
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GoogleMaps
|
1
|
+
GoogleMapsAPIで取得した詳細な座標配列(legs/step/path)から、一定距離の地点にマーカーを立てたい
|
test
CHANGED
@@ -8,254 +8,134 @@
|
|
8
8
|
|
9
9
|
##これまでできたこと
|
10
10
|
|
11
|
-
|
11
|
+
起点から終点までのルートを取得し、下記のarrでそのルート上の座標配列を取得。隣り合った座標の距離を次々足していき、指定した距離に最近接の座標にマーカーを立てることができました。
|
12
12
|
|
13
13
|
|
14
14
|
|
15
|
+
```javascript
|
16
|
+
|
17
|
+
var arr = response.routes[0].overview_path;
|
18
|
+
|
15
|
-
|
19
|
+
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
20
|
+
|
21
|
+
var difference = Infinity;
|
22
|
+
|
23
|
+
var total = 0;
|
24
|
+
|
25
|
+
for (var i = 0, l = arr.length - 1; i < l; i++) {
|
26
|
+
|
27
|
+
var current = arr[i];
|
28
|
+
|
29
|
+
var distance = between(current, arr[i + 1]);
|
30
|
+
|
31
|
+
var dif = Math.abs(mark - (total + distance));
|
32
|
+
|
33
|
+
if (difference > dif) {
|
34
|
+
|
35
|
+
difference = dif;
|
36
|
+
|
37
|
+
total += distance;
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
else {
|
42
|
+
|
43
|
+
new gMaps.Marker({
|
44
|
+
|
45
|
+
position: current,
|
46
|
+
|
47
|
+
map: map,
|
48
|
+
|
49
|
+
title: total + 'm'
|
50
|
+
|
51
|
+
});
|
52
|
+
|
53
|
+
break;
|
54
|
+
|
55
|
+
}
|
16
56
|
|
17
57
|
|
18
58
|
|
59
|
+
```
|
19
60
|
|
20
61
|
|
21
62
|
|
63
|
+
##改善したこと、試みたこと
|
22
64
|
|
23
|
-
|
65
|
+
より誤差を小さくするため、ルート上のより多くの座標を取得できないか調べたところ、routesの下の、overview_pathプロパティ以外に、legs > steps > pathと辿って行ったところに、より詳細な座標が格納されていることが分かりました。これをfor文で回して取得し、全てをまとめてwhole_pathという座標配列にして見ました。座標の数(length)をみると、overview_pathの座標の数と比べて7倍くらい多く、精度が高いことが確認できました。
|
66
|
+
|
67
|
+
これをもとに、同じように隣り合った座標間の距離を次々足していき、指定した距離に最近接の座標にマーカーを立てようと以下のようなコードにしてみましたが、うまくいきませんでした。
|
24
68
|
|
25
69
|
|
26
70
|
|
27
|
-
|
71
|
+
```javascript
|
28
72
|
|
29
|
-
|
73
|
+
var whole_path = [];
|
30
74
|
|
31
|
-
|
75
|
+
var legs = response.routes[0].legs;
|
32
76
|
|
33
|
-
|
77
|
+
for (i = 0; i < legs.length; i++) {
|
34
78
|
|
35
|
-
var
|
79
|
+
var steps = legs[i].steps;
|
36
80
|
|
37
|
-
|
81
|
+
for (j = 0; j < steps.length; j++) {
|
38
82
|
|
39
|
-
|
83
|
+
var nextSegment = steps[j].path;
|
40
84
|
|
41
|
-
|
85
|
+
for (k = 0; k < nextSegment.length; k++) {
|
42
86
|
|
43
|
-
|
87
|
+
whole_path.push(nextSegment[k]);
|
44
88
|
|
89
|
+
}
|
90
|
+
|
91
|
+
}
|
92
|
+
|
93
|
+
}
|
94
|
+
|
95
|
+
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
96
|
+
|
97
|
+
var difference = Infinity;
|
98
|
+
|
99
|
+
var total = 0;
|
100
|
+
|
101
|
+
for (var i = 0, l = whole_path.length - 1; i < l; i++) {
|
102
|
+
|
103
|
+
var current = whole_path[i];
|
104
|
+
|
105
|
+
var distance = between(current, whole_path[i + 1]);
|
106
|
+
|
107
|
+
var dif = Math.abs(mark - (total + distance));
|
108
|
+
|
109
|
+
if (difference > dif) {
|
110
|
+
|
111
|
+
difference = dif;
|
112
|
+
|
113
|
+
total += distance;
|
114
|
+
|
115
|
+
}
|
116
|
+
|
117
|
+
else {
|
118
|
+
|
119
|
+
new gMaps.Marker({
|
120
|
+
|
121
|
+
position: current,
|
122
|
+
|
123
|
+
map: map,
|
124
|
+
|
125
|
+
title: total + 'm'
|
126
|
+
|
45
|
-
|
127
|
+
});
|
128
|
+
|
129
|
+
break;
|
130
|
+
|
131
|
+
}
|
46
132
|
|
47
133
|
|
48
134
|
|
49
|
-
var lngs = stations.map(function (station) { return station.lng; });
|
50
|
-
|
51
|
-
var lats = stations.map(function (station) { return station.lat; });
|
52
|
-
|
53
|
-
map.fitBounds({
|
54
|
-
|
55
|
-
west: Math.min.apply(null, lngs),
|
56
|
-
|
57
|
-
east: Math.max.apply(null, lngs),
|
58
|
-
|
59
|
-
north: Math.min.apply(null, lats),
|
60
|
-
|
61
|
-
south: Math.max.apply(null, lats),
|
62
|
-
|
63
|
-
|
135
|
+
```
|
64
136
|
|
65
137
|
|
66
138
|
|
67
|
-
|
139
|
+
途中までは、上と同じようにうまく行っているようなのですが、最後にcurrentの座標を調べてみると、起点と同じ位置から動いていません。
|
68
140
|
|
69
|
-
new google.maps.Marker({
|
70
|
-
|
71
|
-
position: stations[i],
|
72
|
-
|
73
|
-
map: map,
|
74
|
-
|
75
|
-
title: stations[i].name
|
76
|
-
|
77
|
-
});
|
78
|
-
|
79
|
-
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
// Divide route to several parts because max stations limit is 25 (23 waypoints + 1 origin + 1 destination)
|
84
|
-
|
85
|
-
for (var i = 0, parts = [], max = 25 - 1; i < stations.length; i = i + max)
|
86
|
-
|
87
|
-
parts.push(stations.slice(i, i + max + 1));
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
var service_callback = function (response, status) {
|
92
|
-
|
93
|
-
var mark = document.getElementById("mark").value;
|
94
|
-
|
95
|
-
if (status != 'OK') {
|
96
|
-
|
97
|
-
console.log('Directions request failed due to ' + status);
|
98
|
-
|
99
|
-
return;
|
100
|
-
|
101
|
-
}
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
//var m = 0;
|
106
|
-
|
107
|
-
//for (var h = 0; h < response.routes[0].legs.length; h++) {
|
108
|
-
|
109
|
-
// m += response.routes[0].legs[h].distance.value;
|
110
|
-
|
111
|
-
//} // ルートの距離(m)を取得できたが、ふたつに分割されている
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
var disp = new gMaps.DirectionsRenderer;
|
116
|
-
|
117
|
-
disp.setMap(map);
|
118
|
-
|
119
|
-
disp.setOptions({
|
120
|
-
|
121
|
-
suppressMarkers: true,
|
122
|
-
|
123
|
-
preserveViewport: true,
|
124
|
-
|
125
|
-
suppressInfoWindows: false,
|
126
|
-
|
127
|
-
polylineOptions: {
|
128
|
-
|
129
|
-
strokeColor: '#ff0000',
|
130
|
-
|
131
|
-
strokeOpacity: 0.5,
|
132
|
-
|
133
|
-
strokeWeight: 3
|
134
|
-
|
135
|
-
}
|
136
|
-
|
137
|
-
});
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
var arr = response.routes[0].overview_path; //legs.step.path; ??//
|
142
|
-
|
143
|
-
var between = gMaps.geometry.spherical.computeDistanceBetween;
|
144
|
-
|
145
|
-
var difference = Infinity;
|
146
|
-
|
147
|
-
var total = 0;
|
148
|
-
|
149
|
-
for (var m = 0, l = arr.length - 1; m < l; m++) {
|
150
|
-
|
151
|
-
var current = arr[m];
|
152
|
-
|
153
|
-
var distance = between(current, arr[m + 1]);
|
154
|
-
|
155
|
-
var dif = Math.abs(mark - (total + distance));
|
156
|
-
|
157
|
-
if (difference > dif) {
|
158
|
-
|
159
|
-
difference = dif; // 距離差を更新
|
160
|
-
|
161
|
-
total += distance; // 合計距離を更新
|
162
|
-
|
163
|
-
} else {
|
164
|
-
|
165
|
-
var panorama = new google.maps.StreetViewPanorama(
|
166
|
-
|
167
|
-
document.getElementById("pano"),
|
168
|
-
|
169
|
-
{position: current,
|
170
|
-
|
171
|
-
pov: {heading: 270,
|
172
|
-
|
173
|
-
pitch: 0,
|
174
|
-
|
175
|
-
},
|
176
|
-
|
177
|
-
});
|
178
|
-
|
179
|
-
map.setStreetView(panorama);
|
180
|
-
|
181
|
-
break;
|
182
|
-
|
183
|
-
}}
|
184
|
-
|
185
|
-
disp.setDirections(response);
|
186
|
-
|
187
|
-
};
|
188
|
-
|
189
|
-
for (var i = 0; i < parts.length; i++) {
|
190
|
-
|
191
|
-
var waypoints = [];
|
192
|
-
|
193
|
-
for (var j = 1; j < parts[i].length - 1; j++)
|
194
|
-
|
195
|
-
waypoints.push({ location: parts[i][j], stopover: false });
|
196
|
-
|
197
|
-
var request = {
|
198
|
-
|
199
|
-
origin: parts[i][0],
|
200
|
-
|
201
|
-
destination: parts[i][parts[i].length - 1],
|
202
|
-
|
203
|
-
waypoints: waypoints,
|
204
|
-
|
205
|
-
travelMode: 'WALKING'
|
206
|
-
|
207
|
-
};
|
208
|
-
|
209
|
-
ds.route(request, service_callback);
|
210
|
-
|
211
|
-
}
|
212
|
-
|
213
|
-
}
|
214
|
-
|
215
|
-
</script>
|
216
|
-
|
217
|
-
<script async defer
|
218
|
-
|
219
|
-
src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxxxxx&callback=initMap"></script>
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
```##改善したいこと
|
224
|
-
|
225
|
-
前段として、数10kmのルート上で試している時は誤差が数10mくらいで、あまり気にならなかったのですが、このルートは全長800kmあるので(当たり前かもしれませんが)誤差が非常に大きくなります。
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
中盤の「var arr = response.routes[0].overview_path;」で得られる座標配列をコンソール画面で調べたところ、全長のうち計400カ所超のようです。必然的に数kmの誤差が出る計算です。
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
前段の数10kmのルート上で調べた時も得られた座標配列のlengthは200超だったので、取得できる座標の数は長さに比例して多くなるのではなく、一定程度に決められているのでしょうか??
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
もしも、より細かい多くの座標を取得でるのであれば誤差も少なくなる…と初心者なりに考え、試行錯誤しています。
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
##試してみたこと
|
242
|
-
|
243
|
-
取得できたオブジェクトを見ると、「routes.overview_path」のほか、「routes.legs.step.path」というところにより細かい座標が入っているようだったので、「var arr = response.routes[0].legs.step.path;」と変えてみましたが、うまく行かず、おまけにレンダリングされたルートの線も消えてしまいました。
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
##さらにもう1点、お知恵を拝借したいこと
|
248
|
-
|
249
|
-
Googlemapsには経由地(WayPoints)の数の制限があり、APIを取得していた場合でも起点・終点を含めて25カ所が上限と理解しています。巡礼路は、重要な巡礼地を経由してこそのルートなので、なんとかこれを回避する方法を模索しました。ネットのサンプルコードを参考に、詳しく仕組みは理解していませんが、ルートをDivideしてつなぎ合わせる形にしたのが上のコードです。
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
起点がふたつあるような形になっていて、「歩いた距離」の地点にマーカーを立つようにすると2カ所に立ちます。上のルート上の座標も約200カ所ずつに分かれて出力されます。総距離mも500数十kmと200数十kmのふたつに分かれて出ます。
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
これをうまくつなぎ、全行程で本来の起点(サン・ジャン・ピエ・ド・ポー=フランス)から歩いた距離の地点をCurrentとして取得できる仕組みをつくりたいと考えています。いろいろ調べたり、考えたりしましたが、今のところ足がかりさえ見えなません。
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
方
|
141
|
+
どうしたら良いのか(そもそも、この考え方で良いのかどうか)ご教示頂けると、とてもとてもありがたく思います。どうぞよろしくお願いいたします。
|