0
0

osmdroid(OpenStreetMapのAndroid向けライブラリ)のMapViewを鳥瞰図に対応させる

Posted at

概要

osmdroidのMapViewでは真上からの表示にしか対応してません。
そこで、MapViewを改造して鳥瞰図表示に対応しました。(マリオカートのような疑似3Dです)
また地図の回転にも対応しています。
あくまで個人の備忘録としてまとめているので至らない点があったらすみません。

注意

計算負荷や各種リソースなどは考慮してないのでそこは注意!

完成イメージ

真上からの表示

Screenshot_20240427-181419.png

鳥瞰図としての表示

Screenshot_20240427-181425.png

コード

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);
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0