質問編集履歴

1

前回質問から一部解決できたので、解決できない部分に絞った質問に変えました。

2021/02/08 12:40

投稿

tatsu3
tatsu3

スコア11

test CHANGED
@@ -1 +1 @@
1
- GoogleMapsのDirectionsService、DirectionsRendererでト上のより細かい座標取得できなか?
1
+ GoogleMapsAPIで取得した詳細な座標配列(legs/step/path)から一定距離の地点にマカー立てた
test CHANGED
@@ -8,254 +8,134 @@
8
8
 
9
9
  ##これまでできたこと
10
10
 
11
- あちこちサンプドなども参考にながらGoogle API使って以下通りコ書いました。
11
+ 起点から終点までのルートを取得し、下記のarrでそのルート上の座標配列取得。隣り合た座標の距離を次々足しいき、指定した距離に最近接座標にマカーることができました。
12
12
 
13
13
 
14
14
 
15
+ ```javascript
16
+
17
+ var arr = response.routes[0].overview_path;
18
+
15
- 起点と終点、34カ所の経由地を含む地図を取得して左半分に表示。起点からの歩いた距離分の地点を取得し、そのストリートビュー画像を右半分に表示する仕組みです。歩いた距離は、最終的にはFitBitから取得を目指しますが、とりあえずHTMLの入力欄<input id="mark">から入力する形にしてあります。
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
- ```JavaScript
65
+ より誤差を小さくするため、ルート上のより多くの座標を取得できないか調べたところ、routesの下の、overview_pathプロパティ以外に、legs > steps > pathと辿って行ったところに、より詳細な座標が格納されていることが分かりました。これをfor文で回して取得し、全てをまとめてwhole_pathという座標配列にして見ました。座標の数(length)をみると、overview_pathの座標の数と比べて7倍くらい多く、精度が高いことが確認できました。
66
+
67
+ これをもとに、同じように隣り合った座標間の距離を次々足していき、指定した距離に最近接の座標にマーカーを立てようと以下のようなコードにしてみましたが、うまくいきませんでした。
24
68
 
25
69
 
26
70
 
27
- <script>
71
+ ```javascript
28
72
 
29
- function initMap() {
73
+ var whole_path = [];
30
74
 
31
- var gMaps = google.maps;
75
+ var legs = response.routes[0].legs;
32
76
 
33
- var ds = new gMaps.DirectionsService;
77
+ for (i = 0; i < legs.length; i++) {
34
78
 
35
- var map = new gMaps.Map(document.getElementById('map_canvas'));
79
+ var steps = legs[i].steps;
36
80
 
37
- var stations = [
81
+ for (j = 0; j < steps.length; j++) {
38
82
 
39
- { lat: 43.16787133305725, lng: -1.2377224338793966, name: 'Saint-Jean-Pied-de-Port(サン・ジャン・ピエ・ド・ポー)' },
83
+ var nextSegment = steps[j].path;
40
84
 
41
- ***中略。34カ所の経由地点が書かれています***
85
+ for (k = 0; k < nextSegment.length; k++) {
42
86
 
43
- { lat: 42.88081810734543, lng: -8.544630899970322, name: 'Santiago de Compostela(サンティアゴ・デ・コンポステーラ)' },
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
- for (var i = 0; i < stations.length; i++) {
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
+ どうしたら良いのか(そもそも、この考え方で良いのかどうか)ご教示頂けると、とてもとてもありがたく思います。どうぞよろしくお願いいたします。