osmdroidのMapViewでは真上からの表示にしか対応していない。
そこで、MapViewを改造して鳥瞰図表示に改造しました。
計算負荷などは考慮してないのでそこは注意!
package dev.booyah.carmeterdisplay.view;
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を使い台形に変換しています。