地図上にピンを載せる方法についてのメモ
Skobblerではピンのことをアノテーション「SKAnnotation」と呼びます。
SKAnnotationを地図上に表示するにはSKMapSurfaceView#addAnnotationを使います。
第一引数はSKAnnotationで第二引数はSKAnimationSettingsを渡します。
まずは、SKAnnotationを作ります。
private SKAnnotation createSKAnnotation(int uniqueID, int type, int minimum, SKScreenPoint location, View pinView) {
//SKAnnotationインスタンスを作成、引数はID
SKAnnotation skAnnotation = new SKAnnotation(uniqueID);
//IDの変更
skAnnotation.setAnnotationType(uniqueID);
//SKAnnotationの位置指定は緯度経度が必要です。
//しかし、SKScreenPointは画面上の位置なので緯度経度に変換する必要があります。
//SKMapSurfaceView#pointToCoordinateを使うことで変換ができます。
SKCoordinate skCoordinate = mapView.pointToCoordinate(location);
//SKAnnotationの位置を指定する。
skAnnotation.setLocation(skCoordinate);
//ピンの見た目はデフォルトで用意されているアイコン
//または独自Viewのどちらかをセットできます。
//どちらもセットされないと何も表示されません。
//SKAnnotation.SK_ANNOTATION_TYPE_BLUE
//SKAnnotation.SK_ANNOTATION_TYPE_DESTINATION_FLAG
//SKAnnotation.SK_ANNOTATION_TYPE_GREEN
//SKAnnotation.SK_ANNOTATION_TYPE_MARKER
//SKAnnotation.SK_ANNOTATION_TYPE_PURPLE
//SKAnnotation.SK_ANNOTATION_TYPE_RED
//デフォルトのピンをセットする。
if(pinView == null){
skAnnotation.setAnnotationType(type);
} else {
//独自Viewを配置する場合はSKAnnotationViewを使う。
SKAnnotationView skAnnotationView = new SKAnnotationView();
//Viewをセットする。
skAnnotationView.setView(pinView);
//SKAnnotationViewをセットする。
skAnnotation.setAnnotationView(skAnnotationView);
}
//ピンが表示される最小ズームレベルを指定する。
//いろいろな値を指定しても変わらない。動かない?
//第一メソッド名がminimumではないのは何故
skAnnotation.setMininumZoomLevel(minimum);
//何のオフセットしているのかわからない
SKScreenPoint skScreenPoint = new SKScreenPoint();
skScreenPoint.setX(5);
skScreenPoint.setY(5);
skAnnotation.setOffset(skScreenPoint);
return skAnnotation;
}
続いてSKAnimationSettingsを作ります。
第一引数はアニメーションタイプを引数を渡します。
ANIMATION_NONE | アニメーションなし |
ANIMATION_PIN_DROP | 画面上部から落ちてくるアニメーション |
ANIMATION_POP_OUT | ピンの位置から膨らんで出てくるアニメーション |
ANIMATION_PULSE_CCP | わからない |
第二引数はアニメーションエの加速/減速タイプを引数を渡します。
EASE_IN_CUBIC | 0からt(時間)の3乗の式に沿って加速していく。 |
EASE_IN_EXPO | 0から2のt(時間)乗の式に沿って加速していく。 |
EASE_IN_OUT_CUBIC | 0から半分まではt(時間)の3乗の式に沿って加速し、半分からはt(時間)の3乗の式に沿って減速する。 |
EASE_IN_OUT_EXPO | 0から半分までは2のt(時間)乗の式に沿って加速し、半分からは2のt(時間)乗の式に沿って減速する。 |
EASE_IN_OUT_QUAD | 0から半分まではt(時間)の2乗の式に沿って加速し、半分からはt(時間)の2乗の式に沿って減速する。 |
EASE_IN_OUT_QUART | 0から半分まではt(時間)の4乗の式に沿って加速し、半分からはt(時間)の4乗の式に沿って減速する。 |
EASE_IN_OUT_QUINT | 0から半分まではt(時間)の5乗の式に沿って加速し、半分からはt(時間)の5乗の式に沿って減速する。 |
EASE_IN_OUT_SINE | 0から半分まではsin(t)の式に沿って加速し、半分からはsin(t)の式に沿って減速する。 |
EASE_IN_QUAD | 0からt(時間)の2乗の式に沿って加速していく。 |
EASE_IN_QUART | 0からt(時間)の4乗の式に沿って加速していく。 |
EASE_IN_QUINT | 0からt(時間)の5乗の式に沿って加速していく。 |
EASE_IN_SINE | 0からsin(t)の式に沿って加速していく。 |
EASE_LINEAR | 加速しない |
EASE_OUT_CUBIC | 最大加速度からt(時間)の3乗の式に沿って減速していく。 |
EASE_OUT_EXPO | 最大加速度から2のt(時間)乗の式に沿って減速していく。 |
EASE_OUT_QUAD | 最大加速度からt(時間)の2乗の式に沿って減速していく。 |
EASE_OUT_QUART | 最大加速度からt(時間)の4乗の式に沿って減速していく。 |
EASE_OUT_QUINT | 最大加速度からt(時間)の5乗の式に沿って減速していく。 |
EASE_OUT_SINE | 最大加速度からsin(t)の式に沿って減速していく。 |
このようにして「SKAnnotation」と「SKAnimationSettings」を渡すことでアニメーションを付けてアノテーションを地図上に表示することができます。
今回はシングルタップでデフォルトの見た目のアノテーションを追加し、ダブルタップで独自Viewのアノテーションを地図上に配置するコードです。
public class MainActivity extends AppCompatActivity implements SKPrepareMapTextureListener, SKMapSurfaceListener {
private SKCoordinate tokyo = new SKCoordinate(139.766084, 35.681382);
private SKMapSurfaceView mapView;
private SKMapViewHolder mapHolder;
String mapResourcesDirPath;
/**
* アノテーションを作成する。
* @param uniqueID ID
* @param type 見た目
* @param minimum ????
* @param location 画面座標位置
* @param pinView 独自VIew
* @return
*/
private SKAnnotation createSKAnnotation(int uniqueID, int type, int minimum, SKScreenPoint location, View pinView) {
//SKAnnotationインスタンスを作成、引数はID
SKAnnotation skAnnotation = new SKAnnotation(uniqueID);
//IDの変更
skAnnotation.setAnnotationType(uniqueID);
//SKAnnotationの位置指定は緯度経度が必要です。
//しかし、SKScreenPointは画面上の位置なので緯度経度に変換する必要があります。
//SKMapSurfaceView#pointToCoordinateを使うことで変換ができます。
SKCoordinate skCoordinate = mapView.pointToCoordinate(location);
//SKAnnotationの位置を指定する。
skAnnotation.setLocation(skCoordinate);
//ピンの見た目はデフォルトで用意されているアイコン
//または独自Viewのどちらかをセットできます。
//どちらもセットされないと何も表示されません。
//SKAnnotation.SK_ANNOTATION_TYPE_BLUE
//SKAnnotation.SK_ANNOTATION_TYPE_DESTINATION_FLAG
//SKAnnotation.SK_ANNOTATION_TYPE_GREEN
//SKAnnotation.SK_ANNOTATION_TYPE_MARKER
//SKAnnotation.SK_ANNOTATION_TYPE_PURPLE
//SKAnnotation.SK_ANNOTATION_TYPE_RED
//デフォルトのピンをセットする。
if(pinView == null){
skAnnotation.setAnnotationType(type);
} else {
//独自Viewを配置する場合はSKAnnotationViewを使う。
SKAnnotationView skAnnotationView = new SKAnnotationView();
//Viewをセットする。
skAnnotationView.setView(pinView);
//SKAnnotationViewをセットする。
skAnnotation.setAnnotationView(skAnnotationView);
}
//ピンが表示される最小ズームレベルを指定する。
//いろいろな値を指定しても変わらない。動かない?
//第一メソッド名がminimumではないのは何故
skAnnotation.setMininumZoomLevel(minimum);
//何のオフセットしているのかわからない
SKScreenPoint skScreenPoint = new SKScreenPoint();
skScreenPoint.setX(5);
skScreenPoint.setY(5);
skAnnotation.setOffset(skScreenPoint);
return skAnnotation;
}
@Override
public void onSingleTap(SKScreenPoint skScreenPoint) {
//タップ(ActionDown-ActionUp)したときに呼ばれる。
Log.d("SKMapSurfaceListener", "onSingleTap");
Log.d("SKMapSurfaceListener", "onSingleTap[x:" + skScreenPoint.getX() + "/y:" + skScreenPoint.getY() + "]");
SKAnnotation skAnnotation = createSKAnnotation(
mapView.getAllAnnotations().size(),
SKAnnotation.SK_ANNOTATION_TYPE_MARKER ,
0,
skScreenPoint, null);
SKAnimationSettings skAnimationSettings = new SKAnimationSettings(
SKAnimationSettings.SKAnimationType.PULSE_CCP,
SKAnimationSettings.SKEasingType.EASE_IN_EXPO ,
1000
);
mapView.addAnnotation(skAnnotation, skAnimationSettings);
}
@Override
public void onDoubleTap(SKScreenPoint skScreenPoint) {
//ダブルタップ(ActionDown-ActionUp-ActionDown-ActionUp)したときに呼ばれる。
Log.d("SKMapSurfaceListener", "onDoubleTap");
Log.d("SKMapSurfaceListener", "onDoubleTap[x:" + skScreenPoint.getX() + "/y:" + skScreenPoint.getY() + "]");
ImageView imageView = new ImageView(getApplicationContext());
imageView.setImageResource(R.mipmap.ic_launcher);
SKAnnotation skAnnotation = createSKAnnotation(
mapView.getAllAnnotations().size(),
SKAnnotation.SK_ANNOTATION_TYPE_MARKER ,
0,
skScreenPoint, imageView);
SKAnimationSettings skAnimationSettings = new SKAnimationSettings(
SKAnimationSettings.SKAnimationType.PIN_DROP,
SKAnimationSettings.SKEasingType.EASE_IN_EXPO ,
1000
);
mapView.addAnnotation(skAnnotation, skAnimationSettings);
}
@Override
public void onSurfaceCreated(SKMapViewHolder skMapViewHolder) {
mapHolder = skMapViewHolder;
mapView = skMapViewHolder.getMapSurfaceView();
mapView.centerMapOnPosition(new SKCoordinate(139.766084, 35.681382));
//initMapSettings();
//settingScaleView();
}
@Override
public void onLongPress(SKScreenPoint skScreenPoint) {
//長押ししたときに呼ばれる。
Log.d("SKMapSurfaceListener", "onLongPress");
Log.d("SKMapSurfaceListener", "onLongPress[x:" + skScreenPoint.getX() + "/y:" + skScreenPoint.getY() + "]");
}
@Override
public void onActionPan() {
//移動したときに呼ばれる。
Log.d("SKMapSurfaceListener", "onActionPan");
}
@Override
public void onActionZoom() {
//ズームしたときに呼ばれる。
Log.d("SKMapSurfaceListener", "onActionZoom");
}
@Override
public void onRotateMap() {
//回転したときに呼ばれる。
Log.d("SKMapSurfaceListener", "onRotateMap");
}
@Override
public void onMapActionDown(SKScreenPoint skScreenPoint) {
//マップに指が触れたときに呼ばれる。
Log.d("SKMapSurfaceListener", "onMapActionDown");
Log.d("SKMapSurfaceListener", "onMapActionDown[x:" + skScreenPoint.getX() + "/y:" + skScreenPoint.getY() + "]");
}
@Override
public void onMapActionUp(SKScreenPoint skScreenPoint) {
//マップから指から離れたときに呼ばれる。
Log.d("SKMapSurfaceListener", "onMapActionUp");
Log.d("SKMapSurfaceListener", "onMapActionUp[x:" + skScreenPoint.getX() + "/y:" + skScreenPoint.getY() + "]");
}
@Override
public void onAnnotationSelected(SKAnnotation skAnnotation) {
}
@Override
public void onMapRegionChanged(SKCoordinateRegion skCoordinateRegion) {
}
@Override
public void onMapRegionChangeStarted(SKCoordinateRegion skCoordinateRegion) {
}
@Override
public void onMapRegionChangeEnded(SKCoordinateRegion skCoordinateRegion) {
}
@Override
public void onInternetConnectionNeeded() {
}
@Override
public void onPOIClusterSelected(SKPOICluster skpoiCluster) {
}
@Override
public void onMapPOISelected(SKMapPOI skMapPOI) {
}
@Override
public void onCustomPOISelected(SKMapCustomPOI skMapCustomPOI) {
}
@Override
public void onCompassSelected() {
}
@Override
public void onCurrentPositionSelected() {
}
@Override
public void onObjectSelected(int i) {
}
@Override
public void onInternationalisationCalled(int i) {
}
@Override
public void onBoundingBoxImageRendered(int i) {
}
@Override
public void onGLInitializationError(String s) {
}
@Override
public void onScreenshotReady(Bitmap bitmap) {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapResourcesDirPath = getFilesDir().getPath() + "/" + "SKMaps/";
if (!new File(mapResourcesDirPath).exists()) {
new SKPrepareMapTextureThread(this, mapResourcesDirPath, "SKMaps.zip", this).start();
} else {
initMapSetting();
}
}
@Override
public void onMapTexturesPrepared(boolean b) {
if (b) {
initMapSetting();
}
}
private void initMapSetting() {
SKMapsInitSettings initMapSettings = new SKMapsInitSettings();
initMapSettings.setMapResourcesPaths(mapResourcesDirPath,
new SKMapViewStyle(mapResourcesDirPath + "daystyle/", "daystyle.json"));
final SKAdvisorSettings advisorSettings = initMapSettings.getAdvisorSettings();
advisorSettings.setAdvisorConfigPath(mapResourcesDirPath + "Advisor");
advisorSettings.setResourcePath(mapResourcesDirPath + "Advisor/Languages");
advisorSettings.setLanguage(SKAdvisorSettings.SKAdvisorLanguage.LANGUAGE_EN);
advisorSettings.setAdvisorVoice("en");
initMapSettings.setAdvisorSettings(advisorSettings);
SKMaps.getInstance().initializeSKMaps(this, initMapSettings);
SKMapFragment mapFragment = new SKMapFragment();
mapFragment.setMapSurfaceListener(this);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, mapFragment).commit();
}
@Override
protected void onPause() {
super.onPause();
if (mapHolder != null) {
mapHolder.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mapHolder != null) {
mapHolder.onResume();
}
}
private void initMapSettings() {
//地図描画フレームレートの最大値を設定する。ただし、ユーザー操作は含まれない。
mapView.getMapSettings().setFrameRate(60);
//地図の表示領域が何を追尾モードを指定する。
//例えば下記のようにするとユーザーの位置が地図の中心に来るように追尾します。
mapView.getMapSettings().setFollowerMode(SKMapSettings.SKMapFollowerMode.NONE);
//地図の言語設定に使用する。
SKMapInternationalizationSettings skMapInternationalizationSettings = new SKMapInternationalizationSettings();
skMapInternationalizationSettings.setPrimaryLanguage(SKMaps.SKLanguage.LANGUAGE_RU);
mapView.getMapSettings().setMapInternationalizationSettings(skMapInternationalizationSettings);
settingsUserAction();
settingsMapObject();
settingsPoi();
settingsStyle();
settings3D();
//以下は使い方がわからない調査中メソッド
//mapView.getMapSettings().setDrawingOrder();
//mapView.getMapSettings().setTerrainEnabled(false);
//mapView.getMapSettings().setTerrainDisabledIfNoElevation(false);
//mapView.getMapSettings().setOrientationIndicatorType();
//mapView.getMapSettings().setGeneratedPoisShown(false);
//mapView.getMapSettings().setImportantPoisShown(true);
}
private void settings3D() {
//地図を3D表示したときのカメラを設定する。
SK3DCameraSettings sk3DCameraSettings = new SK3DCameraSettings();
sk3DCameraSettings.setTilt(60);
sk3DCameraSettings.setCenter(0.9f);
sk3DCameraSettings.setDistance(10);
mapView.getMapSettings().setCameraSettings(sk3DCameraSettings);
//地図を拡大した表示を2Dと3Dのどちらかを指定することができます。
mapView.getMapSettings().setMapDisplayMode(SKMapSettings.SKMapDisplayMode.MODE_3D);
//通りの名前をポップアップ風に表示する。true:ポップアップ表示/false:地図上に書き込み
mapView.getMapSettings().setStreetNamePopupsShown(false);
}
private void settingsStyle() {
// 地図を描画する時に使うスタイルファイルを設定する。
//SKMaps.zip内にはデフォルトで下記の4styleが存在します。
String daystyle = "daystyle";
String grayscalestyle = "grayscalestyle";
String nightstyle = "nightstyle";
String outdoorstyle = "outdoorstyle";
String style = nightstyle;
//コンストラクタの引数はstyleファイルが存在するフォルダとstyleファイルの名前です。
SKMapViewStyle skMapViewStyle = new SKMapViewStyle(mapResourcesDirPath + style + "/", style + ".json");
mapView.getMapSettings().setMapStyle(skMapViewStyle);
}
private void settingsPoi() {
//POIはランドマークのことです。
//POIの表示非表示を設定する true:表示/false:非表示
mapView.getMapSettings().setMapPoiIconsShown(true);
//地図上の都市情報の表示非表示を設定する true:表示/false:非表示
//country:国名/state:州名/city:都市名/town:街名/village:村名などなど
mapView.getMapSettings().setCityPoisShown(true);
}
private void settingsMapObject() {
//自転車専用レーンの表示非表示を設定する true:表示/false:非表示
mapView.getMapSettings().setShowBicycleLanes(true);
//一方通行の表示非表示を設定する true:表示/false:非表示
mapView.getMapSettings().setOneWayArrows(true);
//同一建物内の店舗数の表示非表示を設定する true:表示/false:非表示
mapView.getMapSettings().setHouseNumbersShown(true);
//自分の位置の表示非表示を設定する。true:表示/false:非表示
//初期表示位置はなぜか北極点
mapView.getMapSettings().setCurrentPositionShown(false);
//コンパスの表示-true:表示/false:非表示
mapView.getMapSettings().setCompassShown(true);
//コンパスの位置を指定する。右上を原点とする。
mapView.getMapSettings().setCompassPosition(new SKScreenPoint(10, 10));
}
private void settingsUserAction() {
//地図の移動の有効無効を設定する。true:有効/false:無効
mapView.getMapSettings().setMapPanningEnabled(false);
//地図の回転の有効無効を設定する true:有効/false:無効
mapView.getMapSettings().setMapRotationEnabled(false);
//Zoomの有効無効を設定する。true:有効/false:無効
mapView.getMapSettings().setMapZoomingEnabled(true);
//地図の移動に慣性力を付加する。 true:有効/false:無効
mapView.getMapSettings().setInertiaPanningEnabled(false);
//地図の回転に慣性力を付加する。 true:有効/false:無効
mapView.getMapSettings().setInertiaRotatingEnabled(false);
//地図のズームに慣性力を付加する。 true:有効/false:無効
mapView.getMapSettings().setInertiaZoomingEnabled(false);
//アンカーポイントを中心にZoomをするかを設定する。
// true:アンカー(地図中心)にZoomする。/false:ピンチしている指の間を中心にZoomする。
mapView.getMapSettings().setZoomWithAnchorEnabled(false);
//Zoomの上下限を設定するメソッド
//しかし、どんな値を設定しても特に変化がない。
mapView.getMapSettings().setZoomLimits(5f, 19f);
//リファレンスに説明が無く、値を変更しても反応しない。
//動作しないメソッドなのか?
mapView.getMapSettings().setMinimumZoomForTapping(0);
}
private void settingScaleView() {
//縮尺の表示を有効にする。
mapHolder.setScaleViewEnabled(true);
//縮尺を右下に配置する。
mapHolder.setScaleViewPosition(0, 80, RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.ALIGN_PARENT_BOTTOM);
//SKMapScaleViewのインスタンスを取得する。
SKMapScaleView scaleView = mapHolder.getScaleView();
//枠線の色を指定する。
scaleView.setBorderColor(Color.RED);
//SKMapScaleViewのバーは明るい色と黒い色の二色で塗り分けられます。
//暗い色を指定します。
scaleView.setDarkerColor(Color.BLUE);
//明るい色を指定します。
scaleView.setLighterColor(Color.GREEN);
//テキストの色を指定します。
scaleView.setTextColor(Color.CYAN);
//縮尺の単位を指定します。キロメーター、マイルフィート、マイルヤードから選択できます。
scaleView.setDistanceUnit(SKMaps.SKDistanceUnitType.DISTANCE_UNIT_KILOMETER_METERS);
//各単位のラベルを指定する。
scaleView.setDistanceUnitLabels("kmのラベル", "mのラベル", "miのラベル", "ftのラベル", "ydのラベル");
//SKMapScaleViewの自動フェイドアウトアニメーションの有効無効を設定する。true:フェイドアウトする/false:フェイドアウトしない
scaleView.setFadeOutEnabled(false);
}
}