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

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

ただいまの
回答率

90.23%

Google MAPS APIのDirections APIをサーバー側からrequestを投げてresponseを受け取った後に、既存の地図にresponseの内容を反映させる方法について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 650

k.t.est

score 37

ajaxで下記PHPにてDirections APIに問い合わせを行い、受け取ったresponseを利用して、
既に作成されている地図上に道路に沿った線を引きたいのですが、
受け取るresponseの中の、下記PHPコード内でいうと$route["route_data"]["routes"]["legs"]["steps"]["travel_mode"]が設定されておらず、エラーが表示されます。

どのようにすればtravel_modeが設定されますでしょうか?
ご教示戴ければ幸甚で御座います。

$data["start"] = スタート地点の緯度,経度
$data["end"] = 目的地の緯度,経度

//Directions APIに問い合わせ
$ch = curl_init('https://maps.googleapis.com/maps/api/directions/json?origin='.$data["start"].'&destination='.$data["end"].'&avoid=highways&mode=walking&units=metric&key=key' );
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
$res = curl_exec($ch);
$route_data = json_decode($res,true );

//ここから追加
    $request_data = array(
        "request" => array(
            "origin" => array(
                "lat" => explode(",",$data["start"])[0],
                "lng" => explode(",",$data["start"])[1],
            ),
            "destination" => array(
                "lat" => explode(",",$data["end"])[0],
                "lng" => explode(",",$data["end"])[1],
            ),
            "travelMode" => "DRIVING",
        )
    );
    $route_data = array_merge($route_data, $request_data);
//ここまで
//さらに追加
    $replace_array = array(
        "bounds" => array(
            "north" => 北端,
            "east" => 東端,
            "south" => 南端,
            "west" => 西橋,
        ),
    );

    //元の配列のboundsと入れ替え
    $route_data["routes"]["0"] = array_replace($route_data["routes"]["0"],$replace_array);
//ここまで

$route[] = array(
    "start" => explode(",",$data["start"]),
    "end" => explode(",",$data["end"]),
    "route_data" => $route_data,
  );

echo json_encode($route);//この内容をjavascriptに渡す
//既存の地図の呼び出し
var home = 地図の中心地の緯度,経度
var latlng = new google.maps.LatLng(home.lat,home.lng);
var opts = {
              zoom: 12,
              center: latlng,
              mapTypeId: google.maps.MapTypeId.ROADMAP,
            };

var map = new google.maps.Map(document.getElementById("map_canvas"), opts);

//PHPから受け取ったデータ($route["route_data"])をjavascriptに渡す
var response = JSON.parse(result)[0].route_data;

//地図に書き入れる                    
var rendererOptions = {
            map: map, // 描画先の地図
            draggable: false, // ドラッグ不可
            //preserveViewport: true // centerの座標、ズームレベルで表示
            suppressMarkers: true, // デフォルトのマーカーを削除
            preserveViewport: true, // true を指定するとビューの移動(ルート全体を表示する)を行いません。
            polylineOptions: {
                strokeColor: '#ff0000',
                strokeOpacity: 0.8,
                strokeWeight: 10
            }
        };
directionsDisplay = new google.maps.DirectionsRenderer( rendererOptions );
directionsDisplay.setDirections( response );
directionsDisplay.setMap(map);

});

エラー内容①

//エラー内容
Uncaught (in promise) TypeError: Cannot read property 'travelMode' of undefined
at directions.js:131
    at _.ww.f.(anonymous function) [as getEnabled] (https://maps.google.com/maps-api-v3/api/js/35/4/intl/ja_ALL/util.js:31:236)
    at PM._.S.get (js?key=key&libraries=geometry&quotaUser=quotaUser:175)
    at PM._.n.enabled_changed (directions.js:118)
    at Fd (js?key=key&libraries=geometry&quotaUser=quotaUser:77)
    at PM._.S.bindTo (js?key=key&libraries=geometry&quotaUser=quotaUser:176)
    at Object.wk (directions.js:131)
    at js?key=key&libraries=geometry&quotaUser=quotaUser:205

エラー内容②

Uncaught Jc {message: "not a LatLngBounds or LatLngBoundsLiteral: unknown property northeast", name: "InvalidValueError", stack: "Error↵    at new Jc (https://maps.google.com/maps/…taUser=quotaUser:205:5489)"}message: "not a LatLngBounds or LatLngBoundsLiteral: unknown property northeast"name: "InvalidValueError"stack: "Error↵    at new Jc 

message: "not a LatLngBounds or LatLngBoundsLiteral: unknown property northeast"
name: "InvalidValueError"
stack: "Error↵

Directions APIから得たresponse(PHP内の$route["route_data"])

//JSON
[{
 "start":["35.705825","139.845428"],
 "end":["35.704571","139.846222"],
 "route_data":{
  "geocoded_waypoints":[
   {
    "geocoder_status":"OK",
    "place_id":"ChIJe1mQ26SIGGAR0elQ7U7lOEk",
    "types":[
      "bus_station",
      "establishment",
      "point_of_interest",
      "transit_station"]
   },
   {
    "geocoder_status":"OK",
    "place_id":"ChIJWf8dg6SIGGARBHv-iXil1Eo",
    "types":["premise"]
   }
  ],
  "routes":[{
    "bounds":{
      "northeast":{
          "lat":35.70582900000000137197275762446224689483642578125,
          "lng":139.846198100000009389987098984420299530029296875
      },
      "southwest":{
          "lat":35.7045624000000003661625669337809085845947265625,
          "lng":139.845427900000004228786565363407135009765625
       }
     },
    "copyrights":"Map data \u00a92018 Google, ZENRIN",
    "legs":[
             {
               "distance":{"text":"0.2 km","value":159},
               "duration":{"text":"1 min","value":38},
               "end_address":"Japan, \u3012132-0035 T\u014dky\u014d-to, Edogawa-ku, Hirai, 4 Chome\u22124, \u30b8\u30e7\u30a4\u30d7\u30e9\u30b6\u5e73\u4e95",
               "end_location":{
                 "lat":35.7045624000000003661625669337809085845947265625,
                 "lng":139.846198100000009389987098984420299530029296875},
               "start_address":"Hirai 4 Chome, 4 Chome-9 Hirai, Edogawa-ku, T\u014dky\u014d-to 132-0035, Japan",
               "start_location":{
                 "lat":35.70582619999999707260940340347588062286376953125,
                 "lng":139.845427900000004228786565363407135009765625},
               "steps":[
                 {
                   "distance":{"text":"4 m","value":4},
                   "duration":{"text":"1 min","value":1},
                "end_location":{
                 "lat":35.70582900000000137197275762446224689483642578125,
                 "lng":139.845475499999992052835295908153057098388671875
                 },
                "html_instructions":"Head <b>east<\/b> toward <b>\u3086\u308a\u306e\u304d\u6a4b\u901a\u308a<\/b>\/<b>\u90fd\u9053449\u53f7\u7dda<\/b>",
                "polyline":{"points":"mx|xE}pptY?I"},
                "start_location":{
                 "lat":35.70582619999999707260940340347588062286376953125,
                 "lng":139.845427900000004228786565363407135009765625
                },
                "travel_mode":"DRIVING"
             },
            {
              "distance":{"text":"0.2 km","value":155},
              "duration":{"text":"1 min","value":37},
              "end_location":{
                "lat":35.7045624000000003661625669337809085845947265625,
                "lng":139.846198100000009389987098984420299530029296875
              },
              "html_instructions":"Turn <b>right<\/b> onto <b>\u3086\u308a\u306e\u304d\u6a4b\u901a\u308a<\/b>\/<b>\u90fd\u9053449\u53f7\u7dda<\/b><div style=\"font-size:0.9em\">Destination will be on the left<\/div>",
              "maneuver":"turn-right",
              "polyline":{
                  "points":"mx|xEgqptYJCn@_@PG|@c@tAo@ZO"
               },
              "start_location":{
                 "lat":35.70582900000000137197275762446224689483642578125,
                 "lng":139.845475499999992052835295908153057098388671875
               },
               "travel_mode":"DRIVING"
             }
    ],
    "traffic_speed_entry":[],
    "via_waypoint":[]
   }],
   "overview_polyline":{
         "points":"mx|xE}pptY?IJC`Ag@nDcB"
   },
  "summary":"\u3086\u308a\u306e\u304d\u6a4b\u901a\u308a\/\u90fd\u9053449\u53f7\u7dda",
   "warnings":[],
   "waypoint_order":[]
  }],
  "status":"OK"
 }
}]

試したこと

PHPからDirections APIに問い合わせる方法が悪いと思い、modeをwalkingからdriving、また設定しないという方法を試してみましたが、状況は変わらずでした。

API_KEYについて

既存のMAPの呼び出し用のAPI_KEY(jsから問い合わせ)と、サーバーサイドからのDirections APIへの問い合わせ用API_KEY(phpから問い合わせ)は異なります。
これによって不具合は出ないかと思いますが、念の為です。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Lhankor_Mhy

    2018/12/10 17:46 編集

    API のデモを見てみましたが、どうやら、(new google.maps.DirectionsService).route は単純にレスポンスをレンダラに渡すだけのメソッドではなさそうです。request というプロパティが追加されていました。

    キャンセル

  • k.t.est

    2018/12/10 18:01

    requestの内容は、PHPで既にGoogle側に投げているので、問題ないと思った次第ですが、そうではないということでしょうか?

    キャンセル

  • Lhankor_Mhy

    2018/12/10 18:07

    うーん、ただ、APIの仕様書を読む限りだと、setDirections メソッドの引数は DirectionsResult となっていて、仕様書の動作と違うんですよねえ……? 一応、回答欄にまとめてみます。

    キャンセル

回答 1

checkベストアンサー

+1

解決にはならないと思うのですが、調べたことをまとめます。解決方法は他の回答者諸兄にゆだねます。

Directions Service  |  Maps JavaScript API  |  Google Developers
↑の動作を見てみると、directionsService.routeがコールバックに渡す値が、DirectionsResultとは異なっていました。

{
  "geocoded_waypoints": [
    {
      "geocoder_status": "OK",
      "place_id": "ChIJ7cv00DwsDogRAMDACa2m4K8",
      "types": [
        "locality",
        "political"
      ]
    },
    {
      "geocoder_status": "OK",
      "place_id": "ChIJ-Y7t-qm02IcRW-C7IsrqOb4",
      "types": [
        "locality",
        "political"
      ]
    }
  ],
  "routes": [
//  (略)
  ],
  "status": "OK",
  "request": {
    "origin": {
      "query": "chicago, il"
    },
    "destination": {
      "query": "st louis, mo"
    },
    "travelMode": "DRIVING"  // ←これ
  }
}


一方で、サーバからのレスポンスはDirectionsResult的なものに見えます。
なので、DirectionsService.routeがサーバからのレスポンスをよきにはからってコールバック関数に渡しているのではないか、と思いました。
 
ところが、APIのレファレンスによると、

setDirections(directions)
Parameters: 
directions:  DirectionsResult
DirectionsRenderer class | Directions  |  Maps JavaScript API  |  Google Developers

となっており、
DirectionsResult interface | Directions  |  Maps JavaScript API  |  Google Developers
にはrequestというプロパティがないのです。
仕様書と実装が違うような気がします。

ただ、

Note that though this result is "JSON-like," it is not strictly JSON, as it indirectly includes LatLng objects.
DirectionsResult interface | Directions  |  Maps JavaScript API  |  Google Developers

とあり、字面からはDirectionsResultはレスポンスJSONをパースしただけのものとは違うもの、であるように読めますので、素直にDirectionsService.routeを使った方がいいのかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/11 15:18

    大変恐縮ですが、「APIを使ってPolyLineを引く」方法につき、具体的にご教示いただくことは可能でしょうか?宜しくお願い申し上げます。

    キャンセル

  • 2018/12/11 16:24

    こちらのドキュメントのとおりです。
    https://developers.google.com/maps/documentation/javascript/shapes#polylines
    たとえば、このページなどはわかりやすいかもしれません。
    http://phpjavascriptroom.com/?t=ajax&p=googlemapsapiv3_polyline

    キャンセル

  • 2018/12/11 17:30

    有難う御座いました!
    PHPで取得できたstepsを利用して、無事polylineをoverlayすることができました。当初想定していた方法とは異なりましたが、目的を達成することが出来ました。

    キャンセル

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

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • JavaScriptに関する質問
  • Google MAPS APIのDirections APIをサーバー側からrequestを投げてresponseを受け取った後に、既存の地図にresponseの内容を反映させる方法について