GoogleMap系の周辺技術の整理メモ
随時追記予定
map_jsレベルの対応
staticMap
Googleで地名検索をした場合に、表示される簡易mapの画像表示で使われている技術
画像がそのまま返却されるので、そのままPicasso等で表示するとかにも使えますね。
一応keyが必要ということになっているけど、
request数の大幅な制限があることを除けば指定なしても表示は実は可能
制限的な箇所は
複数のマーカを指定した場合
- zoom値を指定すると、距離がある場合に画面内に表示されない
- scale=2 とか指定してしまうと、劇的に生成時間が増える
- 2秒 =>4秒程度
- 二点間の距離が1kmを超えると劇的に生成時間が増える
- 2秒 =>4秒程度
play-ground
streetviewのサムネイルが欲しい時
Street View Image API を使う
属性 | 説明 |
---|---|
location | 緯度経度(緯度,経度) |
size | 表示する画像のサイズ(縦x横) |
heading | カメラの方位(0 〜 360) 0=北 |
pitch | カメラのアングル(90 〜 -90) 90=上 -90=下 |
fov | カメラの水平視野(0 〜 120) 0=狭い 120=広い |
zoom | カメラのズーム(0〜5) 0=遠い 5=近い |
https://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,-73.988354 &fov=90&heading=235&pitch=10
Twitter等に挿入する時
Twitterだと下記の形にしないと embedサムネイルが出ない(画像添付されていない時)
しかも日本語サムネイルは www.google.co.jp の時のみ!
https://www.google.co.jp/maps/@35.682326,139.761850,15z
String sUrl; if(isJapanese()){ sUrl += "https://www.google.co.jp"; } else{ sUrl += "https://www.google.com"; } sUrl += "/maps/@" + target.latitude + "," + target.longitude +"," + (int) zoom +"z";
関連の話は下記を参照
https://www.ipentec.com/document/document.aspx?page=google-map-link&culture=ja-jp
intentによるMapアプリの呼び出し
指定位置の表示
geo:35.684331,139.735232
geo:35.684331,139.735232?z=19 //(z:ズーム値)
指定をしたときに、左下に近場のstreetview サムネイル*1が表示されるようになってる
geo:35.684331,139.735232?q=35.684331,139.735232
と指定した場合は、
geo:目的地座標?q=目的地座標
みたいな感じで、目的地に マーカーピン を立てる
geo:目的地座標?q=<<検索ワード(要URLエンコード)>>
だと、Mapアプリの上の方に検索された状態で表示される
最新版のGoogleMapアプリで拡張されている処(2016年版)
geo:目的地座標?q=目的地座標
で マーカーピンを表示た場合「名前のない場所」
geo:目的地座標?q=目的地座標(ラベル<<要URLエンコード>>)
と設定すると
URLエンコードされたラベルが
「名前のない場所」=>「指定ラベル」
となります。
GoogleMapアプリが片手落ちな処
これ ユーザーのアカウントに紐付いて
- GoogleMapにカスタムプレイスを保存する機能
の利用を促進するためのやつなんですが、
- この設定したラベルが保存するときに引き継がれない
- 一から新規で入れる・・しかも別画面・・・見ながらも入力不可・・・
- コピー機能はなぜか住所をコピーする*2
経路情報
経路情報に関しては、APIとしては未だ提供されていないのが現状だったり。。
特に公式ドキュメントに記載はないが
http://maps.google.co.jp/maps?saddr=現在地&daddr=目的地&dirflg=w //d:車/t:電車(デフォルト)/w:徒歩
を setPackage でcom.google.android.apps.mapsを指定すれば
mapアプリ内で表示はされる
Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setClassName("com.google.android.apps.maps","com.google.android.maps.MapsActivity"); intent.setData(Uri.parse("http://maps.google.com/maps?saddr=35.684331,139.735232&daddr=35.684331,139.735232")); startActivity(intent);
みたいな感じ。
自前で遣る場合は、Google Directions API を使いましょうって話で
が出てくるくらいかと。
後はラップしたライブラリを作っている方もいますね
navigation intent
google.navigation:q=35.684331,139.735232
google.navigation:q=35.684331,139.735232&mode=w //(d:車/w:歩き/b:自転車)
な指定の感じだけど、こっちだとなんか感じが違う感じがする
streetviewのintentに関して
google.streetview:cbll=35.684331,139.735232
で呼び出し
- 現在はstreetviewアプリをinstallしていても呼び出されず、現在はGoogleMapアプリが呼び出される
streetviewを確実に表示するには
SupportStreetViewPanoramaFragment 等で自前で出しましょうという話
下記は 東京タワーを表示する記述例
StreetViewPanoramaView を使う場合
public class StreetViewActivity extends Activity { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); StreetViewPanoramaView sv; final StreetViewPanoramaOptions options = new StreetViewPanoramaOptions(); latitude = 35.657797; longitude = 139.745625; final LatLng TOKYO_TOWER = new LatLng(latitude, longitude); options.position(TOKYO_TOWER); // 場所の指定 sv = new StreetViewPanoramaView(this, options); addContentView(sv, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); sv.onCreate(savedInstanceState); } }
SupportStreetViewPanoramaFragment を使う場合
StreetViewPanoramaCamera で更に下記の指定も指定することが可能
項目 | 設定内容 |
---|---|
zoom | ズーム倍率 |
tilt | カメラの水平角度を指定 |
bearing | 真北を0とした方角を指定 |
<fragment android:name="com.google.android.gms.maps.SupportStreetViewPanoramaFragment" android:id="@+id/streetviewpanorama" android:layout_width="match_parent" android:layout_height="match_parent"/>
setContentView(R.layout.activity_streetview); final SupportStreetViewPanoramaFragment fm = (SupportStreetViewPanoramaFragment) getSupportFragmentManager().findFragmentById(R.id.map_streetview); fm.getStreetViewPanoramaAsync(new OnStreetViewPanoramaReadyCallback(){ @Override public void onStreetViewPanoramaReady(StreetViewPanorama map) { // 座標の設定(★) Double latitude = 35.657797; // 緯度 Double longitude = 139.745625; // 経度 LatLng TOKYO_TOWER = new LatLng(latitude, longitude); map.setPosition(TOKYO_TOWER); //セットしたポジションからpanolamaIdを取得する◎ StreetViewPanoramaLocation location = map.getLocation(); if (location != null && location.links != null) { map.setPosition(location.links[0].panoId); } // カメラコントロールの設定 float zoom = 0.0f; // ズーム倍率 float tilt = 37.462147f; // カメラの水平角度 float bearing = 347.0586f; // 真北を0とした方角 final StreetViewPanoramaCamera camera = new StreetViewPanoramaCamera(zoom, tilt, bearing); // カメラをその位置へ3秒かけて移動する map.animateTo(camera, 3000); } });
ちなみに◎は必須。
- 理由は
- ビルの中等の座標を指定した場合、
- 勿論G様でもPanorama撮影していないから、
- 近辺(近くの道路画像とか)のPanoramaIdを検索する必要があるらしい
使い勝手を考えるなら、★はIntent等で渡す作りにしたほうが良いかもしれませんね
住所から位置情報を取得する(Geocoder)
基本上記のコードでよくて、 v1/v2の違いで
- 1E6をかけてint型に変換する必要がない(double型でそのまま扱えばOK)
ぐらいの差分でしょうか。。ググると未だ古い記述のものが多くて混乱しますね(汗
今風で使うとすると
AppCompat + SearchView 辺りでの利用でしょうか。。
因みに、
<item android:id="@+id/action_search" android:title="@string/action_search" android:icon="@drawable/ic_action_search" app:showAsAction="always|collapseActionView" android:actionViewClass="android.support.v7.widget.SearchView" />
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu, menu); SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));//★ searchView.setOnQueryTextListener(this); return super.onCreateOptionsMenu(menu); }
な記述をかくと思いますが、
support-library-24.2.X になるまで、Android 5.0以上で
MenuItemCompat.getActionView でnullを返すというバグが有りました・・。