Topics & News
マピオンラボリニューアルしました。

Mapion マピオンラボ モバイル 独自画像をAndroid Maps APIで表示する方法(GMap Image Cutter編)

独自画像をAndroid Maps APIで表示する方法(GMap Image Cutter編)



Mapion Android Maps APIで独自画像を表示する方法を紹介します。
デモアプリの「独自地図画像を指定する」の実現方法です。

※独自画像を実装するためにはmaps API 2.5以上が推奨です(それ以前のVerはスクロール遅いなど問題あり)

以下の画像(sa.png 1280x800)をタイル化してMaps APIで表示します。
sa.png

手順

1.タイルを作成する

画像を分割するのは手間なので、GMap Image Cutterというツールを使います

GMap Image Cutterを起動する
my01.png


sa.pngを開く
redokuji2_1.png


Createを押す(以下は縮尺3つ分)
redokuji2_2.png


sa-tilesとsa.htmlが出来上がる(必要なのはsa-tiles内のタイルです)
redokuji2_3.png


2.res/drawable-nodpiにタイルをコピーする

my05.png


3.Mapのサブクラスを作る

今回は縮尺3つなのでinitメソッドでratiosに3つ追加(縮尺が増えればさらに8,16,32...と縮尺分追加していく)
package jp.co.mapion.android.mymap;

import java.lang.reflect.Field;
import java.util.HashMap;

import jp.co.mapion.android.maps.GeoPoint;
import jp.co.mapion.android.maps.Map;
import jp.co.mapion.android.maps.Tile;
import android.graphics.Point;

public class MyMap extends Map {

	protected int tileWidth = 256;
	protected int tileHeight = 256;

	protected HashMap<Integer, Float> ratios = new HashMap<Integer, Float>();

	private HashMap<String, Integer> tileNameMap = new HashMap<String, Integer>();

	private String key;

	private int noimage;

	public MapionTownMap2(String key, int noimage) {
		this.key = key;
		this.noimage = noimage;
		init();
	}

	protected void init() {
		ratios.put(1, 4.0f);
		ratios.put(2, 2.0f);
		ratios.put(3, 1.0f);
	}

	@Override
	protected int getMaxZoomLevel() {
		return ratios.size();
	}

	@Override
	protected void setup() {
		setCenter(new GeoPoint(0, 0));
		setZoom(1);
	}

	@Override
	protected int getTileWidth() {
		return tileWidth;
	}

	@Override
	protected int getTileHeight() {
		return tileHeight;
	}

	@Override
	protected Point geoToPixel(GeoPoint geo) {
		int x = (int) (geo.getLongitudeE6() / getRatio());
		int y = (int) (geo.getLatitudeE6() / getRatio());
		return new Point(x, y);
	}

	@Override
	protected GeoPoint pixelToGeo(Point pixel) {
		int lat = (int) (pixel.y * getRatio());
		int lon = (int) (pixel.x * getRatio());
		return new GeoPoint(lat, lon);
	}

	@Override
	protected GeoPoint getOrigin() {
		double originRatio = ratios.get(1);
		int lat = (int) ((tileHeight / 2) * originRatio);
		int lon = (int) (-(tileWidth / 2) * originRatio);
		return new GeoPoint(lat, lon);
	}

	@Override
	protected String getURL(Tile tile) {
		int x = (int) tile.getX();
		int y = (int) tile.getY();
		if (x < 0 || y < 0) {
			return noMap();
		}
		if (isOut(tile)) {
			return noMap();
		}
		int gzoom = getZoom() - 1;
		double pow = Math.pow(2, gzoom);
		StringBuilder tileName = new StringBuilder();
		tileName.append("t");
		for (int i = 0; i < gzoom; i++) {
			pow = pow / 2;
			if (y < pow) {
				if (x < pow) {
					tileName.append("q");
				} else {
					tileName.append("r");
					x -= pow;
				}
			} else {
				if (x < pow) {
					tileName.append("t");
					y -= pow;
				} else {
					tileName.append("s");
					x -= pow;
					y -= pow;
				}
			}
		}
		return String.valueOf(getResourceInt(tileName.toString()));
	}

	@Override
	protected String getKey() {
		return key;
	}

	private double getRatio() {
		return ratios.get(getZoom());
	}

	private int getResourceInt(String name) {
		if (tileNameMap.containsKey(name)) {
			return tileNameMap.get(name);
		}
		try {
			Field field = R.drawable.class.getDeclaredField(name);
			int tileId = field.getInt(R.drawable.class);
			tileNameMap.put(name, tileId);
			return tileId;
		} catch (Exception e) {
		}
		return -1;
	}

	private String noMap() {
		return String.valueOf(noimage);
	}

	private boolean isOut(Tile tile) {
		int max = 1 << (getZoom() - 1);
		if (tile.getX() >= max || tile.getY() >= max) {
			return true;
		}
		return false;
	}
}


4. Activityを作る

package jp.co.mapion.android.mymap;

import jp.co.mapion.android.maps.Map;
import jp.co.mapion.android.maps.MapActivity;
import jp.co.mapion.android.maps.MapView;
import android.os.Bundle;
import android.view.Window;

public class MapionTownActivity extends MapActivity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		MapView mapView = new MapView(this, new MapionTownMap("APIキー", R.drawable.nashi));
		mapView.setClickable(true);
		mapView.setBuiltInZoomControls(true);
		setContentView(mapView);
	}
}

これで完成です。
APIの機能が全て使えるのでアイコンやテキストなどをOverlayしたり、回転させたりできます。
例ではローカルに画像を置いていますが、サーバに置くことも可能です。
comment
ニックネーム 
trackback

この記事のトラックバックURLhttp://labs.mapion.co.jp/mtos/mt-tb.cgi/94

Mashup Awards 7 (#MA7)
ユーザーアーカイブ