座標を取得します
良いニュースは、Googleが座標間のルートを計算するサービスのAPIを提供することです。 したがって、今後の作業の一般的な構造はほぼ次のとおりです。
- パラメータを使用してリクエストを作成します
- リクエストを送信し、レスポンスを取得します
- パーシムアンサー
- 地図にオーバーレイを描く
リクエスト形成
リクエストの詳細については、 Google開発者向けの公式ドキュメントをご覧ください。 ここでは、主な側面を検討します。 一般に、リクエストは次のようになります。
http://maps.googleapis.com/maps/api/directions/output?parameters
出力が2つの値を取る場合:
- json-出力をJavaScript Object Notation(JSON)形式で設定します。
- xml-出力をXML形式で設定します。
Google自体はJSONを使用することを推奨しています。
parametersはさまざまな必須のパラメーターであり、要件に応じて指定できるパラメーターではありません。 オプションのパラメーターについては説明しません。必ず指定しなければならない主なパラメーターは3つあります。
- origin-ルートの始点の緯度と経度の住所またはテキスト値。
- destination-ルートの最終目的地の緯度と経度の住所またはテキスト値。
- sensor-ルートリクエストが位置センサー付きのデバイスから送信されているかどうかを示します。 有効な値はtrueまたはfalseです。
最終的に、JSON応答を含む最も単純な要求(VoronezhからMoscowへ)は次のようになります。
http://maps.googleapis.com/maps/api/directions/json?origin= Voronezh&destination = Moscow&sensor = false
必要なコード行を作成するのは非常に簡単なので、この部分にはコードを持ち込みません。
リクエストを送信して結果を受信する
それで、リクエストが形成され、送信する時が来ました。 おそらく、サービスリクエストを処理する方法に関する多くのメソッドがありますが、私の人生を最大2行まで簡単にするために、 Spring Framework for androidを使用します。 まあ、あなた自身が知っているように。 私はそれをダウンロードし、プロジェクトに入れました。リクエストは次のようになります。
RestTemplate rTemplate = new RestTemplate(); String jsonResponse = rTemplate.getForObject(query, String.class));
回答の解析
ルートに関するさまざまな情報を含むjson形式で回答を得ましたが、オーバーレイを描画する座標のみが必要なので、他のすべての結果は省略します。Google開発者でも同じように読むことができます。
JSONを解析してみましょう。コードは次のようになります。
public ArrayList<Section> parse(JSONObject jsonObject) throws AuthenticationException { ArrayList<Section> list = new ArrayList<Section>(); Location startGeo; Location endGeo; JSONArray results = jsonObject.optJSONArray("routes"); JSONObject route = results.optJSONObject(0); JSONArray legs = route.optJSONArray("legs"); JSONObject leg = legs.optJSONObject(0); JSONArray steps = leg.optJSONArray("steps"); for (int i=0; i < steps.length(); ++i) { JSONObject step = steps.optJSONObject(i); JSONObject startP = step.optJSONObject("start_location"); JSONObject endP = step.optJSONObject("end_location"); JSONObject polyline = step.optJSONObject("polyline"); String encodedPoints = polyline.optString("points"); startGeo = new Location(""); endGeo = new Location(""); startGeo.setLatitude(startP.optDouble("lat")); startGeo.setLongitude(startP.optDouble("lng")); endGeo.setLatitude(endP.optDouble("lat")); endGeo.setLongitude(endP.optDouble("lng")); list.add(new Section(startGeo.getLatitude(), startGeo.getLongitude(), endGeo.getLatitude(), endGeo.getLongitude() , encodedPoints)); } return list; }
興味のある主な情報はステップ配列にあり、その構造は次のようになります。
"steps": [ { "travel_mode": "DRIVING", "start_location": { "lat": 41.8507300, "lng": -87.6512600 }, "end_location": { "lat": 41.8525800, "lng": -87.6514100 }, "polyline": { "points": "a~l~Fjk~uOwHJy@P", "levels": "B?B" }, "duration": { "value": 19, "text": "1 min" }, "html_instructions": "Head \u003cb\u003enorth\u003c/b\u003e on \u003cb\u003eS Morgan St\u003c/b\u003e toward \u003cb\u003eW Cermak Rd\u003c/b\u003e", "distance": { "value": 207, "text": "0.1 mi" } }, ...
steps配列の各要素には、start_locationフィールドとend_locationフィールドが含まれます。これらは、交差点など、ルートの重要な参照ポイントの座標です。 モスクワからヴォロネジへのリクエストを実行すると、このようなポイントは約20個になりますが、もちろん、20ポイントで描画することはできません。 実際、ポリラインフィールドに注意を払う必要があります。 さらに2つのフィールド「ポイント」と「レベル」が含まれています。 「ポイント」の内容は不気味に見えますが、実際にはこれらは私たちの座標であり、 このようにエンコードされています。 あなたは恐れてはいけません、私たちはすべてを考え出しました、私たちはそれを利用します。 そのため、道路を描くための膨大な量の座標を取得します。 行「ポリライン」が「ステップ」の各要素に含まれていることを忘れないでください。
オーバーレイを描く
現時点では、リクエストがどのように見えるか、どのように送信できるか、回答を受信して解析する方法を把握しました。 これらすべてから、パスを描く必要がある座標の束があります。 コードは次のようになります。
private class Road extends Overlay { private ArrayList<GeoPoint> list; private Paint paint; public Road(ArrayList<GeoPoint> list) { this.list = new ArrayList<GeoPoint>(); this.list.addAll(list); paint = new Paint(); paint.setColor(Color.MAGENTA); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(4); } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { drawPath(mapView, canvas); } private void drawPath(MapView mv, Canvas canvas) { int x1 = -1; int y1 = -1; int x2 = -1; int y2 = -1; Point point = new Point(); for (int i=0; i < list.size(); i++) { mv.getProjection().toPixels(list.get(i), point); x2 = point.x; y2 = point.y; if (i > 0) { canvas.drawLine(x1, y1, x2, y2, paint); } x1 = x2; y1 = y2; } }
それがすべての作業です。 その結果、任意の2点間のルートを簡単に取得して、マップに表示できます。 この記事がお役に立てば幸いです。 がんばって。
もう一度、ひとまとめにしてすべてのリンクを複製します。
Google Direction API-このサービスに関する完全な情報。
Springフレームワーク -Googleサービスへの残りのリクエストのフレームワーク 代替手段として。
ポリライン暗号化形式
破線をデコードする方法は?