質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Google マップ

Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

Q&A

解決済

1回答

1117閲覧

GASのaddPathに最短距離のルートを追加したい。

Lynsay

総合スコア1

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Google マップ

Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

0グッド

0クリップ

投稿2023/02/21 06:57

実現したいこと

最短距離を抽出し、最短距離のものを画像に変換したい

前提

本サイトの
「GASでGoogleMAPの提示するルートの距離・時間をすべて表示させたい」
という質疑やその他の参考サイト等をもとに作成しましたが、
エラーの原因がわからず、先に進むことができません。
誰でも修正できるようにコメント等をたくさん入れているため分かりにくくなっています。

該当のソースコード

function createMap_変数チェック(){ // 拠点リストのシートを取得する挙動を宣言 let sheetDB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("リスト") // 地図を表示させるシートを取得する挙動を宣言 let sheetMap = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("地図") // jikanで出発時刻を確定し宣言。平日月曜かつ深夜0時で固定する。 let jikan = new Date(2022,12,5) // ループ処理前に前回の地図データを削除する sheetMap.clear() // ループ処理開始 // 拠点リストにおいて最終行まで次の処理を繰り返す for (let m = 1 ; m <= sheetDB.getLastRow() ; m++){ // 拠点リストにおいて1行あたりの地点数を確認し、変数宣言 // 1行あたりの件数を確認し結果を変数宣言。ただし、様式に従い最大8地点まで。関数を9列目に差し込む sheetDB.getRange(m,9).setFormula("=counta(RC[-8]:RC[-1])") // 関数結果をpoCount変数に格納 let poCount = sheetDB.getRange(m,9).getValue() // point変数に地点をすべて格納。point[0][0]が始点、point[0][1]が2地点目…となる。 let point = sheetDB.getRange(m,1,1,8).getValues() // 拠点のデータをもって地図シートに移動し、地図シートで片道ずつの最短経由を追加する // poCountに格納された地点数-1が片道ずつの経路数。poCount-1回まで繰り返す for (let po = 1 ; po <= poCount - 1 ; po++) { // 始点はpoint[0][po-1]、終点はpoint[0][po]で表現可能となる var start = Maps.newGeocoder().geocode(point[0][po-1])['results'][0]['geometry']['location']['lat']+","+Maps.newGeocoder().geocode(point[0][po-1])['results'][0]['geometry']['location']['lng'] var end = Maps.newGeocoder().geocode(point[0][po])['results'][0]['geometry']['location']['lat']+","+Maps.newGeocoder().geocode(point[0][po])['results'][0]['geometry']['location']['lng'] // 地図作成のコードをまとめて変数宣言 var directionFinder = Maps .newDirectionFinder() .setAlternatives(true) // ベストパスだけではなく、代替経路も出力する .setLanguage('ja') // 日本語設定 .setOrigin(start) // start変数を始点に設定 .setDestination(end) // end変数を終点に設定 .setMode(Maps.DirectionFinder.Mode.DRIVING) // 自動車利用に設定。他、DRIVINGをWALKINGに変更で徒歩になる。 .setDepart(jikan) // jikan変数を出発時刻に設定 .getDirections().routes; // 地図作成後、最短距離のものを変数宣言する // xx変数で地図作成のコードを利用してルート検索を実行する // var xx = directionFinder.getDirections() // ルート検索の中で最短距離にソートで並び替えを実行。nearestRoute.legs[0]で最短のものが表示される。 // nearestRoute.legs[0].コード名で最短のもので画像作成などを実行可能となる。 const nearestRoute = directionFinder.sort((a,b)=> a.legs[0].distance.value - b.legs[0].distance.value)[0] let map = new Maps.newStaticMap() map.setSize(400 , 300) .setLanguage('ja') .setPathStyle(3, Maps.StaticMap.Color.Blue , null) // 幅、線の色、塗りつぶしの色 .addPath(Maps.decodePolyline(nearestRoute.routes[0].legs[0].steps[0].polyline.points)) 以降画像貼り付け等のコードのため省略。

試したこと

最後のコードの
.addPath(Maps.decodePolyline(nearestRoute.routes[0].legs[0].steps[0].polyline.points))
の部分に問題があることはデバッグで分かりました。
しかし、routes~の部分をlegsのみにする等をしましたが、処理が同じように止まってしまいます。
エラーの原因を調べようにも、同じような処理を目指すサイトが見つからないため、どのように修正すべきかわからなくなってしまいました。
これが初めてのGAS作成で、1~2か月かけて色々調べていますが、完全にお手上げ状態です。
お手数をおかけしますが、問題点が複数にわたる場合は、再度調べますので、参考できるサイトをご存知でしたらご教授いただけませんでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2023/02/21 07:03

エラーが出たなら、エラーメッセージを提示しましょう エラーメッセージは、よけいな省略翻訳しないで出たそのママをコピペで提示してください
Lynsay

2023/02/21 13:22

閲覧いただきありがとうございます。 実行で表示されるエラー内容は次の通りです。 エラー TypeError: Cannot read properties of undefined (reading 'routes') createMap_変数チェック @ テスト.gs:53 gs:53は本文にて示した問題部分となっています。 また、デバッグの場合は コールスタックが createMap_変数チェック @テスト:53 と表示されています。 以上となります。 よろしくお願いいたします。
YAmaGNZ

2023/02/21 13:30

routesってプロパティがないって言われています。 ご自身のコードのコメントに // ルート検索の中で最短距離にソートで並び替えを実行。nearestRoute.legs[0]で最短のものが表示される。 // nearestRoute.legs[0].コード名で最短のもので画像作成などを実行可能となる。 と書いていて nearestRoute.routes[0].legs[0] とアクセスしているのは正常なのですか?
Lynsay

2023/02/22 04:50

閲覧いただきありがとうございます。 nearestRoutesの変数宣言に誤りがあるということでしょうか。 本サイトでの「GASでGoogleMAPの提示するルートの距離・時間をすべて表示させたい」の質疑を参考にした部分となります。 その質疑ではroute変数とnearestRoutes変数を用いておりますが、nearestRoutes変数にまとめられると考えましたので、まとめました。 その結果、nearestRoute変数に最短経路のものが格納されるとなるはずなので、routeの情報を書き出すMaps.newStaticMapで対応しましたが、この部分が問題なのでしょうか。 また、コメントアウトしている部分については、様々なサイトを参考にし、追記したものとなります。 参考サイトではlegs[0]で最終的に最短距離を求めていましたので、そのように記載し、当初はlegs[0]のみで実行しましたが、同様のエラー(末尾のroutesがlegsの違いのみ)でした。そのため、routes、legs、stepsの組み合わせで試したものとなります。 以上となります。 よろしくお願いいたします。
guest

回答1

0

ベストアンサー

nearestRouteは配列なのではないでしょうか?

GAS

1.addPath(Maps.decodePolyline(nearestRoute[0].legs[0].steps[0].polyline.points))

こういうことだったりしませんか?

すみません。勘違いです。

GAS

1.addPath(Maps.decodePolyline(nearestRoute.legs[0].steps[0].polyline.points))

これでダメなんですかね?

GAS

1function myFunction() { 2 let jikan = new Date(2023,1,23); 3 let startpoint = '東京駅'; 4 let endpoint = '東京タワー'; 5 6 var start = Maps.newGeocoder().geocode(startpoint)['results'][0]['geometry']['location']['lat']+","+Maps.newGeocoder().geocode(startpoint)['results'][0]['geometry']['location']['lng'] 7 var end = Maps.newGeocoder().geocode(endpoint)['results'][0]['geometry']['location']['lat']+","+Maps.newGeocoder().geocode(endpoint)['results'][0]['geometry']['location']['lng'] 8 9 var directionFinder = Maps 10 .newDirectionFinder() 11 .setAlternatives(true) // ベストパスだけではなく、代替経路も出力する 12 .setLanguage('ja') // 日本語設定 13 .setOrigin(start) // start変数を始点に設定 14 .setDestination(end) // end変数を終点に設定 15 .setMode(Maps.DirectionFinder.Mode.DRIVING) // 自動車利用に設定。他、DRIVINGをWALKINGに変更で徒歩になる。 16 .setDepart(jikan) // jikan変数を出発時刻に設定 17 .getDirections().routes; 18 19 const nearestRoute = directionFinder.sort((a,b)=> a.legs[0].distance.value - b.legs[0].distance.value)[0] 20 21 let map = new Maps.newStaticMap() 22 map.setSize(400 , 300) 23 .setLanguage('ja') 24 .setPathStyle(3, Maps.StaticMap.Color.Blue , null) // 幅、線の色、塗りつぶしの色 25 .addPath(Maps.decodePolyline(nearestRoute.legs[0].steps[0].polyline.points)) 26 27} 28

上記コードで試しましたが、jikanが古いとルートが取得できずにdirectionFinderが空っぽでした。
現在から1か月以内であればルートが取得できるようです。

提示コードですと去年の12月固定になっているのでルートが取得できずにエラーが出たのではないでしょうか?
とりあえずjikan = new Date()と本日でやってみてはどうでしょうか。

投稿2023/02/22 05:29

編集2023/02/22 06:34
YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lynsay

2023/02/22 06:18

ご回答いただきありがとうございます。 試しましたところ、 TypeError: Cannot read properties of undefined (reading 'legs') というエラーが出てしまいました。 nearestRouteの宣言が間違っているということになるのでしょうか。
YAmaGNZ

2023/02/22 06:40

出発時間に問題があるようです。 追記しておきました。
Lynsay

2023/02/22 06:42

Googleマップだと去年の12月でも検索できたため、jikan変数の誤りとは思いつかなかったです。 試しましたところ、正常に動作ができました、本当にありがとうございます。
YAmaGNZ

2023/02/22 07:54

そもそも出発時間を設定する必要がないのであれば var directionFinder = Maps .newDirectionFinder() .setAlternatives(true) .setLanguage('ja') .setOrigin(start) .setDestination(end) .setMode(Maps.DirectionFinder.Mode.DRIVING) .getDirections().routes; と設定しないようにすればデフォルトで現在となるはずです。
Lynsay

2023/02/23 13:30

ご連絡いただきありがとうございます。 当初は、渋滞を考慮された検索を除外するために時間を指定しておりました。 その後の処理において、全経路での最短を抽出するものに変更したため、よく考えれば時間を指定するメリットがないことに気づきました。そのため、jikan変数は不要なものでした。 ご指摘により気づくことができましたので、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問