概要
osmdroidのMapViewでは真上からの表示にしか対応してません。
そこで、MapViewを改造して鳥瞰図表示に対応しました。(マリオカートのような疑似3Dです)
また地図の回転にも対応しています。
あくまで個人の備忘録としてまとめているので至らない点があったらすみません。
注意
計算負荷や各種リソースなどは考慮してないのでそこは注意!
完成イメージ
真上からの表示
鳥瞰図としての表示
コード
BirdEyeMapView.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import org.osmdroid.api.IMapView;
import org.osmdroid.config.Configuration;
import org.osmdroid.tileprovider.MapTileProviderBase;
import org.osmdroid.views.MapView;
public class BirdEyeMapView extends MapView {
private boolean birdView = true;
public BirdEyeMapView(Context context, MapTileProviderBase tileProvider, Handler tileRequestCompleteHandler, AttributeSet attrs) {
super(context, tileProvider, tileRequestCompleteHandler, attrs);
}
public BirdEyeMapView(Context context, MapTileProviderBase tileProvider, Handler tileRequestCompleteHandler, AttributeSet attrs, boolean hardwareAccelerated) {
super(context, tileProvider, tileRequestCompleteHandler, attrs, hardwareAccelerated);
}
public BirdEyeMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BirdEyeMapView(Context context) {
super(context);
}
public BirdEyeMapView(Context context, MapTileProviderBase aTileProvider) {
super(context, aTileProvider);
}
public BirdEyeMapView(Context context, MapTileProviderBase aTileProvider, Handler tileRequestCompleteHandler) {
super(context, aTileProvider, tileRequestCompleteHandler);
}
public void setBirdView(boolean birdView) {
this.birdView = birdView;
}
@Override
protected void dispatchDraw(Canvas c) {
final long startMs = System.currentTimeMillis();
this.setProjection(null);
if (birdView) {
Matrix perspectiveMatrix = new Matrix();
perspectiveMatrix.setPolyToPoly(new float[]{
0, 0, // Top-left
getWidth(), 0, // Top-right
getWidth() * 0.7f, getHeight()*1.1f, // Bottom-right
getWidth() * 0.3f, getHeight()*1.1f}, // Bottom-left
0, new float[]{
0, 0, // Top-left
getWidth(), 0, // Top-right
getWidth(), getHeight(), // Bottom-right
0, getHeight()}, // Bottom-left
0, 4);
c.concat(perspectiveMatrix);
}
/* Draw background */
try {
/* Draw all Overlays. */
this.getOverlayManager().onDraw(c, this);
if (this.getZoomController() != null) {
this.getZoomController().draw(c);
}
super.dispatchDraw(c);
} catch (Exception ex) {
//for edit mode
Log.e(IMapView.LOGTAG, "error dispatchDraw, probably in edit mode", ex);
}
if (Configuration.getInstance().isDebugMapView()) {
final long endMs = System.currentTimeMillis();
Log.d(IMapView.LOGTAG, "Rendering overall: " + (endMs - startMs) + "ms");
}
}
}
解説
dispatchDrawメソッドにてMatrixを使い台形に変換しています。
Matrix perspectiveMatrix = new Matrix();
perspectiveMatrix.setPolyToPoly(new float[]{
0, 0, // Top-left
getWidth(), 0, // Top-right
getWidth() * 0.7f, getHeight()*1.1f, // Bottom-right
getWidth() * 0.3f, getHeight()*1.1f}, // Bottom-left
0, new float[]{
0, 0, // Top-left
getWidth(), 0, // Top-right
getWidth(), getHeight(), // Bottom-right
0, getHeight()}, // Bottom-left
0, 4);
c.concat(perspectiveMatrix);
この部分になります。
地図の回転にも対応しています。
mapView.setMapOrientation(mLastDriveDirection, true);