準備 (※Android Studio利用の場合)
- APIキーからAPIキーを取得する
- ダウンロードからjarをダウンロードしプロジェクトのlibsフォルダに入れる
- プロジェクトの app/build.gradle ファイルの dependencies ブロック内に下記を追記する
compile `com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2`
- AndroidManifest.xmlに<uses-permission android:name="android.permission.INTERNET" />を追記する
地図を表示する
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
// MapView mapView = new MapView(this, "APIキー", new MapionMap3D()); // 3D風地図を表示したい場合
// mapView.setLoadingBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.loading)); // loading画像を指定する場合
mapView.setZoom(17.f);
// mapView.animateZoom(17.f); // アニメーションさせる場合
// mapView.animateZoom(17.f, MapView.DEFAULT_ANIMATE_ZOOM_INTERVAL - 3, MapView.DEFAULT_ANIMATE_ZOOM_STEPS + 0.07f); // アニメーションのスピードを調整する場合。これは速くする例
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
// mapView.animateCenter(new GeoPoint(35.301667, 139.283333)); // アニメーションさせる場合
// mapView.animateCenter(new GeoPoint(35.301667, 139.283333), MapView.DEFAULT_ANIMATE_ZOOM_INTERVAL - 2); // アニメーションのスピードを速くする場合
// mapView.setMap(new MapionMap3D()); // 地図を切り替えたい場合
setContentView(mapView);
}
リスナー
MoveendListener
MoveendListener moveendListener = new MoveendListener() {
@Override
public void moveend(MapView mapView) {
// moveendの処理を書く
}
};
mapView.getMoveendListeners().add(moveendListener);
ZoomendListener
ZoomendListener zoomendListener = new ZoomendListener() {
@Override
public void zoomend(MapView mapView) {
// zoomendの処理を書く
}
};
mapView.getZoomendListeners().add(zoomendListener);
縮尺変更ボタンを表示する
import jp.co.mapion.android.maps.MapView;
import jp.co.mapion.android.maps.Overlay;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.view.MotionEvent;
public class ZoomUpOverlay extends Overlay {
private Context context;
private Bitmap currentButton;
private Bitmap normal;
private Bitmap disabled;
private Bitmap pressed;
private Point before = new Point();
public ZoomUpOverlay(Context context) {
this.context = context;
normal = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_up_normal);
disabled = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_up_disabled);
pressed = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_up_pressed);
currentButton = normal;
}
@Override
public void draw(Canvas canvas, MapView mapView) {
int viewWidth = mapView.getWidth();
int viewHeight = mapView.getHeight();
int bitmapWidth = currentButton.getWidth();
int bitmapHeight = currentButton.getHeight();
int marginright = 5;
int marginbottom = 0;
canvas.restore();
Bitmap button = mapView.getZoom() ==
mapView.getMaxZoom() ?
disabled : currentButton;
int x = viewWidth - bitmapWidth - marginright;
int y = viewHeight - bitmapHeight - marginbottom;
canvas.drawBitmap(button, x, y, null);
canvas.save();
}
@Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
Point p = new Point((int) e.getX(), (int) e.getY());
if (inside(p, mapView)) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
before = p;
currentButton = pressed;
return false;
case MotionEvent.ACTION_UP:
currentButton = normal;
if (distance(p) < 20) {
zoom(mapView);
}
return true;
case MotionEvent.ACTION_MOVE:
return false;
case MotionEvent.ACTION_CANCEL:
return false;
}
} else {
switch (e.getAction()) {
case MotionEvent.ACTION_UP:
currentButton = normal;
break;
}
}
return false;
}
private boolean inside(Point p, MapView mapView) {
Bitmap btnZoomUp = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_up_normal);
if (btnZoomUp == null) {
return false;
}
int viewWidth = mapView.getWidth();
int viewHeight = mapView.getHeight();
int bitmapWidth = btnZoomUp.getWidth();
int bitmapHeight = btnZoomUp.getHeight();
int minx = viewWidth - bitmapWidth;
int maxx = viewWidth;
int miny = viewHeight - bitmapHeight;
int maxy = viewHeight;
if (p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy) {
return true;
}
return false;
}
private int distance(Point after) {
int x = Math.abs(before.x - after.x);
int y = Math.abs(before.y - after.y);
return x + y;
}
private void zoom(MapView mapView) {
mapView.animateZoom(mapView.getZoom() + 1);
}
@Override
public String toString() {
return getClass().getName();
}
}
import jp.co.mapion.android.maps.MapView;
import jp.co.mapion.android.maps.Overlay;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.view.MotionEvent;
public class ZoomDownOverlay extends Overlay {
private Context context;
private Bitmap currentButton;
private Bitmap normal;
private Bitmap disabled;
private Bitmap pressed;
private Point before = new Point();
public ZoomDownOverlay(Context context) {
this.context = context;
normal = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_down_normal);
disabled = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_down_disabled);
pressed = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_down_pressed);
currentButton = normal;
}
@Override
public void draw(Canvas canvas, MapView mapView) {
int viewWidth = mapView.getWidth();
int viewHeight = mapView.getHeight();
int bitmapWidth = currentButton.getWidth();
int bitmapHeight = currentButton.getHeight();
int marginright = 5;
int marginbottom = 0;
canvas.restore();
Bitmap button = mapView.getZoom() == mapView.getMinZoom() ?
disabled : currentButton;
int x = viewWidth - bitmapWidth * 2 - marginright;
int y = viewHeight - bitmapHeight - marginbottom;
canvas.drawBitmap(button, x, y, null);
canvas.save();
}
@Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
Point p = new Point((int) e.getX(), (int) e.getY());
if (inside(p, mapView)) {
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
before = p;
currentButton = pressed;
return false;
case MotionEvent.ACTION_UP:
currentButton = normal;
if (distance(p) < 20) {
zoom(mapView);
}
return true;
case MotionEvent.ACTION_MOVE:
return false;
case MotionEvent.ACTION_CANCEL:
return false;
}
} else {
switch (e.getAction()) {
case MotionEvent.ACTION_UP:
currentButton = normal;
break;
}
}
return false;
}
private boolean inside(Point p, MapView mapView) {
Bitmap btnZoomDown = BitmapFactory.decodeResource(
context.getResources(), R.drawable.btn_zoom_down_normal);
if (btnZoomDown == null) {
return false;
}
int viewWidth = mapView.getWidth();
int viewHeight = mapView.getHeight();
int bitmapWidth = btnZoomDown.getWidth();
int bitmapHeight = btnZoomDown.getHeight();
int minx = viewWidth - bitmapWidth * 2;
int maxx = viewWidth - bitmapWidth;
int miny = viewHeight - bitmapHeight;
int maxy = viewHeight;
if (p.x >= minx && p.x <= maxx && p.y >= miny && p.y <= maxy) {
return true;
}
return false;
}
private int distance(Point after) {
int x = Math.abs(before.x - after.x);
int y = Math.abs(before.y - after.y);
return x + y;
}
private void zoom(MapView mapView) {
mapView.animateZoom(mapView.getZoom() - 1);
}
@Override
public String toString() {
return getClass().getName();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
mapView.getOverlays().add(new ZoomUpOverlay(this));
mapView.getOverlays().add(new ZoomDownOverlay(this));
setContentView(mapView);
}
画像を描画する
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
Overlay kokodeneOverlay = new Overlay() {
private Bitmap kokodene = BitmapFactory.decodeResource(getResources(), R.drawable.kokodene);
@Override
public void draw(Canvas canvas, MapView mapView) {
Point pixel = mapView.geoToPixel(MapView.LONGBEACH);
canvas.drawBitmap(kokodene, pixel.x, pixel.y - 13, null);
}
};
mapView.getOverlays().add(kokodeneOverlay);
setContentView(mapView);
}
多数の画像を描画したい場合
描画のたびに緯度経度をピクセルに変換するのは重いので以下のようにピクセルを行列で変換するやり方があります
public class ClusterOverlay extends Overlay {
Bitmap mIcon;
float[] mPoints;
float[] mDstPoints;
GeoPoint baseGeoPoint;
float baseZoom;
Matrix matrix = new Matrix();
public ClusterOverlay(MapView mapView, ArrayList<GeoPoint> geoPoints, Bitmap icon) {
mPoints = new float[geoPoints.size() * 2];
mDstPoints = new float[mPoints.length];
for (int i = 0, offset = 0, size = geoPoints.size(); i < size; i++) {
Point point = mapView.geoToPixel(geoPoints.get(i));
mPoints[offset++] = point.x;
mPoints[offset++] = point.y;
}
mIcon = icon;
Point centerPoint = mapView.geoToPixel(mapView.getCenter());
centerPoint.x -= mapView.getWidth() / 2;
centerPoint.y -= mapView.getHeight() / 2;
baseGeoPoint = mapView.pixelToGeo(centerPoint);
baseZoom = mapView.getZoom();
}
@Override
public void draw(Canvas canvas, MapView mapView) {
float zoom = mapView.getZoom();
float nextZoom = zoom - baseZoom;
float scale = (float) Math.pow(2, nextZoom);
Point point = mapView.geoToPixel(baseGeoPoint);
matrix.reset();
matrix.preScale(scale, scale, point.x, point.y);
matrix.preTranslate(point.x, point.y);
matrix.mapPoints(mDstPoints, mPoints);
for (int i = 0; i < mPoints.length; i++) {
if (i % 2 == 1) {
float x = mDstPoints[i-1] - mIcon.getWidth() / 2;
float y = mDstPoints[i] - mIcon.getHeight() / 2;
boolean inside = x >= 0 - mIcon.getWidth() &&
y >= 0 - mIcon.getHeight() &&
x <= mapView.getWidth() &&
y <= mapView.getHeight();
if (inside) {
canvas.drawBitmap(mIcon, x, y, null);
}
}
}
}
}
ArrayList geoPoints = new ArrayList();
geoPoints.add(MapView.LONGBEACH);
geoPoints.add(new GeoPoint(35.303667, 139.285333));
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.cancel_circle);
ClusterOverlay cluster = new ClusterOverlay(mapView, geoPoints, icon);
mapView.getOverlays().add(cluster);
サークルを描画する
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
Overlay circle = new Overlay() {
@Override
public void draw(Canvas canvas, MapView mapView) {
float pixel = mapView.metersToEquatorPixels(100);
Point pos = mapView.geoToPixel(MapView.LONGBEACH);
Paint fillPaint = new Paint();
fillPaint.setColor(Color.argb(30, 0, 0, 255));
fillPaint.setAntiAlias(true);
fillPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(pos.x, pos.y, pixel, fillPaint);
Paint strokePaint = new Paint();
strokePaint.setColor(Color.argb(100, 0, 0, 255));
strokePaint.setAntiAlias(true);
strokePaint.setStrokeWidth(3);
strokePaint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(pos.x, pos.y, pixel, strokePaint);
}
};
mapView.getOverlays().add(circle);
setContentView(mapView);
}
ラインを描画する
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapview mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
Overlay line = new Overlay() {
private GeoPoint one = new GeoPoint(35.301667, 139.283333);
private GeoPoint two = new GeoPoint(35.304667, 139.286333);
private GeoPoint three = new GeoPoint(35.305667, 139.281333);
@Override
public void draw(Canvas canvas, MapView mapView) {
Point onePoint = mapView.geoToPixel(one);
Point twoPoint = mapView.geoToPixel(two);
Point threePoint = mapView.geoToPixel(three);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(8);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.argb(150, 255, 0, 255));
canvas.drawLines(new float[]{onePoint.x, onePoint.y, twoPoint.x, twoPoint.y, twoPoint.x, twoPoint.y, threePoint.x, threePoint.y}, paint);
}
};
mapView.getOverlays().add(line);
setContentView(mapView);
}
ルートを描画したい場合
ポイントの多いルートは毎回全てのポイントの位置を計算する処理は重いため以下のように工夫する必要があります
public class RouteOverlay extends Overlay {
private float lineWidth;
private GeoPoint baseGeoPoint;
private float baseZoom;
private Paint paint = new Paint();
private Path path = new Path();
public RouteOverlay(MapView mapView, ArrayList<GeoPoint> coordinates, float lineWidth) {
this.lineWidth = lineWidth;
Point centerPoint = mapView.geoToPixel(mapView.getCenter());
centerPoint.x -= mapView.getWidth() / 2;
centerPoint.y -= mapView.getHeight() / 2;
baseGeoPoint = mapView.pixelToGeo(centerPoint);
baseZoom = mapView.getZoom();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
for (int i = 0, size = coordinates.size(); i < size; i++) {
Point point = mapView.geoToPixel(coordinates.get(i));
if (i == 0) {
path.moveTo(point.x, point.y);
} else {
path.lineTo(point.x, point.y);
}
}
}
@Override
public void draw(Canvas canvas, MapView mapView) {
float zoom = mapView.getZoom();
float nextZoom = zoom - baseZoom;
float scale = (float) Math.pow(2, nextZoom);
paint.setStrokeWidth(lineWidth / scale);
Point point = mapView.geoToPixel(baseGeoPoint);
canvas.scale(scale, scale, point.x, point.y);
canvas.translate(point.x, point.y);
canvas.drawPath(path, paint);
}
}
ArrayList<GeoPoint> coordinates = new ArrayList<GeoPoint>();
coordinates.add(new GeoPoint(35.301533,139.27926));
coordinates.add(new GeoPoint(35.301664,139.279389));
coordinates.add(new GeoPoint(35.301822,139.279925));
coordinates.add(new GeoPoint(35.302343,139.279914));
coordinates.add(new GeoPoint(35.302912,139.279893));
coordinates.add(new GeoPoint(35.302662,139.278182));
coordinates.add(new GeoPoint(35.303152,139.278117));
coordinates.add(new GeoPoint(35.303419,139.279861));
coordinates.add(new GeoPoint(35.303914,139.279866));
coordinates.add(new GeoPoint(35.303831,139.27911));
coordinates.add(new GeoPoint(35.304444,139.279088));
coordinates.add(new GeoPoint(35.304409,139.277447));
coordinates.add(new GeoPoint(35.305556,139.277398));
coordinates.add(new GeoPoint(35.306694,139.277484));
coordinates.add(new GeoPoint(35.306987,139.277516));
coordinates.add(new GeoPoint(35.306983,139.276921));
coordinates.add(new GeoPoint(35.307066,139.276336));
coordinates.add(new GeoPoint(35.307701,139.27639));
coordinates.add(new GeoPoint(35.308143,139.276476));
coordinates.add(new GeoPoint(35.308568,139.276658));
coordinates.add(new GeoPoint(35.308502,139.276926));
coordinates.add(new GeoPoint(35.308432,139.277597));
coordinates.add(new GeoPoint(35.309019,139.277565));
coordinates.add(new GeoPoint(35.309929,139.277441));
coordinates.add(new GeoPoint(35.310494,139.277575));
coordinates.add(new GeoPoint(35.31056,139.277034));
coordinates.add(new GeoPoint(35.310568,139.276384));
coordinates.add(new GeoPoint(35.311383,139.276427));
coordinates.add(new GeoPoint(35.311369,139.276663));
coordinates.add(new GeoPoint(35.312044,139.276894));
coordinates.add(new GeoPoint(35.31203,139.278037));
coordinates.add(new GeoPoint(35.312687,139.278042));
coordinates.add(new GeoPoint(35.314635,139.277747));
coordinates.add(new GeoPoint(35.314871,139.280338));
coordinates.add(new GeoPoint(35.314547,139.280853));
coordinates.add(new GeoPoint(35.313908,139.281025));
coordinates.add(new GeoPoint(35.311746,139.281143));
coordinates.add(new GeoPoint(35.31161,139.28117));
coordinates.add(new GeoPoint(35.311277,139.281347));
coordinates.add(new GeoPoint(35.3108,139.281438));
coordinates.add(new GeoPoint(35.310564,139.281422));
coordinates.add(new GeoPoint(35.309688,139.281111));
coordinates.add(new GeoPoint(35.308283,139.280628));
coordinates.add(new GeoPoint(35.307097,139.280279));
coordinates.add(new GeoPoint(35.306585,139.280874));
coordinates.add(new GeoPoint(35.306331,139.281245));
coordinates.add(new GeoPoint(35.306068,139.2811));
coordinates.add(new GeoPoint(35.306024,139.281003));
coordinates.add(new GeoPoint(35.305963,139.280478));
coordinates.add(new GeoPoint(35.30588,139.2797));
RouteOverlay route = new RouteOverlay(mapView, coordinates, 8.f);
mapView.getOverlays().add(route);
ポリゴンを描画する
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
Overlay polygon = new Overlay() {
private GeoPoint one = new GeoPoint(35.301667, 139.283333);
private GeoPoint two = new GeoPoint(35.304667, 139.286333);
private GeoPoint three = new GeoPoint(35.305667, 139.281333);
@Override
public void draw(Canvas canvas, MapView mapView) {
Point onePoint = mapView.geoToPixel(one);
Point twoPoint = mapView.geoToPixel(two);
Point threePoint = mapView.geoToPixel(three);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.argb(120, 0, 0, 255));
paint.setStyle(Paint.Style.FILL_AND_STROKE);
Path path = new Path();
path.moveTo(onePoint.x, onePoint.y);
path.lineTo(twoPoint.x, twoPoint.y);
path.lineTo(threePoint.x, threePoint.y);
path.lineTo(onePoint.x, onePoint.y);
canvas.drawPath(path, paint);
}
};
mapView.getOverlays().add(polygon);
setContentView(mapView);
}
複雑なポリゴンを描画したい場合
頂点の多いポリゴンは毎回全ての頂点の位置を計算する処理は重いためルート描画と同様以下のように工夫する必要があります
public class PolygonOverlay extends Overlay {
private GeoPoint baseGeoPoint;
private float baseZoom;
private Paint paint = new Paint();
private Path path = new Path();
public PolygonOverlay(MapView mapView, ArrayList<GeoPoint> coordinates) {
Point centerPoint = mapView.geoToPixel(mapView.getCenter());
centerPoint.x -= mapView.getWidth() / 2;
centerPoint.y -= mapView.getHeight() / 2;
baseGeoPoint = mapView.pixelToGeo(centerPoint);
baseZoom = mapView.getZoom();
paint.setAntiAlias(true);
paint.setColor(Color.argb(120, 255, 0, 0));
paint.setStyle(Paint.Style.FILL_AND_STROKE);
for (int i = 0, size = coordinates.size(); i < size; i++) {
Point point = mapView.geoToPixel(coordinates.get(i));
if (i == 0) {
path.moveTo(point.x, point.y);
} else {
path.lineTo(point.x, point.y);
}
}
}
@Override
public void draw(Canvas canvas, MapView mapView) {
float zoom = mapView.getZoom();
float nextZoom = zoom - baseZoom;
float scale = (float) Math.pow(2, nextZoom);
Point point = mapView.geoToPixel(baseGeoPoint);
canvas.scale(scale, scale, point.x, point.y);
canvas.translate(point.x, point.y);
canvas.drawPath(path, paint);
}
}
ArrayList<GeoPoint> coordinates = new ArrayList<GeoPoint>();
coordinates.add(new GeoPoint(35.301533,139.27926));
coordinates.add(new GeoPoint(35.301664,139.279389));
coordinates.add(new GeoPoint(35.301822,139.279925));
coordinates.add(new GeoPoint(35.302343,139.279914));
coordinates.add(new GeoPoint(35.302912,139.279893));
coordinates.add(new GeoPoint(35.302662,139.278182));
PolygonOverlay polygonOverlay = new PolygonOverlay(mapView, coordinates);
mapView.getOverlays().add(polygonOverlay);
地図タイルの大きさ(tile range)を変える
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー", new NewMap());
// タイルのサイズの変化幅を調整する係数
// 0 〜 1まで設定できる
// このように明示的に設定しない場合、端末の画面情報を見て自動で決まる
// 1 だと 256〜512
// 0.5 だと 180〜360
// 0 だと 128〜256
mapView.setTileCoe(0.5f);
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
setContentView(mapView);
}
OpenStreetMapを表示する
import android.graphics.Bitmap;
import jp.co.mapion.android.maps.EPSG3857Map;
import jp.co.mapion.android.maps.Tile;
public class OpenStreetMap extends EPSG3857Map {
@Override
public Bitmap bitmapForTile(Tile tile) {
// Webからタイルを取得する場合はここでnullを返してurlForTileでURLを返す
// 逆にローカルのタイルを使用する場合はurlForTileでnullを返してここでBitmapを返す
return null;
}
@Override
public float getMinZoom() {
return 0.f;
}
@Override
public float getMaxZoom() {
return 18.f;
}
@Override
public String getName() {
return "OSM";
}
@Override
public String getCopyright() {
return "Map data © OpenStreetMap contributors, CC BY-SA";
}
@Override
public String urlForTile(Tile tile) {
String ret = "http://tile.openstreetmap.org/" + tile.z + "/" + tile.x + "/" + tile.y + ".png";
return ret;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapview mapView = new MapView(this, "APIキー", new OpenStreetMap());
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
setContentView(mapView);
}
import jp.co.mapion.android.maps.EPSG3857Map;
import jp.co.mapion.android.maps.Tile;
import android.graphics.Bitmap;
public class GSIMap extends EPSG3857Map {
@Override
public Bitmap bitmapForTile(Tile tile) {
return null;
}
@Override
public float getMinZoom() {
return 6.f;
}
@Override
public float getMaxZoom() {
return 18.f;
}
@Override
public String getName() {
return "GSI";
}
@Override
public String getCopyright() {
return "国土地理院";
}
@Override
public String urlForTile(Tile tile) {
String did;
switch (tile.z) {
case 6:
case 7:
case 8:
did = "JAIS";
break;
case 9:
case 10:
case 11:
did = "BAFD1000K";
break;
case 12:
case 13:
case 14:
did = "BAFD200K";
break;
case 15:
case 16:
case 17:
did = "DJBMM";
break;
case 18:
did = "FGD";
break;
default:
did = "";
break;
}
String xstr = String.format("%1$07d", tile.x);
String ystr = String.format("%1$07d", tile.y);
String path = getPath(xstr, ystr);
String ret = "http://cyberjapandata.gsi.go.jp/sqras/all/" + did + "/latest/" + tile.z + path + "/" + xstr + ystr + ".png";
return ret;
}
private String getPath(String x, String y) {
StringBuilder dir = new StringBuilder();
for (int i = 0; i < 6; i++) {
String xi = x.substring(i, i + 1);
String yi = y.substring(i, i + 1);
dir.append('/').append(xi).append(yi);
}
return dir.toString();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapview mapView = new MapView(this, "APIキー", new GSIMap());
mapView.setZoom(14.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
setContentView(mapView);
}
独自画像を表示する
ローカルやWEBにある独自画像を表示することが可能です。独自画像にピンを立てたりラインを引くことも可能です。例として以下の画像(mapiontown.jpeg)をタイル化してAPIで表示させる場合を示します。
タイル化手順
-
GMap Image Cutterをダウンロード&インストール
-
GMap Image Cutterを起動する
-
mapiontown.pngを開く
-
Createを押す
-
mapiontown-tilesとmapiontown.htmlが出来上がる(必要なのはmapiontown-tiles内のタイルです)
-
drawable-nodpiにタイルをコピーする
MapionTownMapクラス作成
import jp.co.mapion.android.maps.GeoPoint;
import jp.co.mapion.android.maps.Map;
import jp.co.mapion.android.maps.ProjectedPoint;
import jp.co.mapion.android.maps.ProjectedRect;
import jp.co.mapion.android.maps.Tile;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class MapionTown implements Map {
private Context mContext;
public MapionTown(Context context) {
mContext = context;
}
@Override
public Bitmap bitmapForTile(Tile tile) {
String fileName = tileToFileName(tile);
int resourceId = getResourceId(fileName);
Bitmap ret = BitmapFactory.decodeResource(mContext.getResources(), resourceId);
return ret;
}
@Override
public GeoPoint projectedPointToGeo(ProjectedPoint projectedPoint) {
return new GeoPoint(projectedPoint.y, projectedPoint.x);
}
@Override
public ProjectedPoint geoToProjectedPoint(GeoPoint geo) {
return new ProjectedPoint(geo.lng, geo.lat);
}
@Override
public float getMinZoom() {
return 0;
}
@Override
public float getMaxZoom() {
return 3;
}
@Override
public int getTileLength() {
return 256;
}
@Override
public ProjectedRect getProjectedRect() {
return new ProjectedRect(-256, -256, 256 * 2, 256 * 2);
}
@Override
public String getName() {
return "MapionTown";
}
@Override
public String getCopyright() {
return "© Mapion";
}
@Override
public String urlForTile(Tile tile) {
return null;
}
// タイルのサイズの変化幅を調整する
// 0 だと 256〜512
// 0.5 だと 180〜360
// 1 だと 128〜256
@Override
public double getTileCoe() {
return 0;
}
private String tileToFileName(Tile tile) {
double p = Math.pow(2.0, tile.z);
int x = tile.x;
int y = tile.y;
StringBuilder sb = new StringBuilder();
sb.append('t');
for (int i = 0; i < tile.z; i++) {
p = p / 2;
if (y < p) {
if (x < p) {
sb.append('q');
} else {
sb.append('r');
x -= p;
}
} else {
if (x < p) {
sb.append('t');
y -= p;
} else {
sb.append('s');
x -= p;
y -= p;
}
}
}
return sb.toString();
}
private int getResourceId(String name) {
return mContext.getResources().getIdentifier(name, "drawable", getClass().getPackage().getName());
}
}
使い方
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, ("APIキー"), new MapionTown(this));
mapView.setZoom(1);
mapView.setCenter(new GeoPoint(0, 0));
setContentView(mapView);
}
回転する
法人向けのみの機能です
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17.f);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
mapView.setDegrees(45.f);
setContentView(mapView);
}
タッチイベントを設定する
import jp.co.mapion.android.maps.MapView;
import jp.co.mapion.android.maps.Overlay;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Canvas;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
public class TouchEventOverlay extends Overlay {
private Context mContext;
private GestureDetectorCompat mGestureDetector;
private MapView mMapView;
public TouchEventOverlay(Context context) {
mContext = context;
mGestureDetector = new GestureDetectorCompat(context, mGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent e, MapView mapView) {
mMapView = mapView;
return mGestureDetector.onTouchEvent(e);
}
@Override
public void draw(Canvas canvas, MapView mapView) {
}
private final GestureDetector.SimpleOnGestureListener mGestureListener
= new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
if (mMapView.oneFingerZooming()) return;
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle("長押ししました。");
dialog.setNegativeButton("閉じる", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
dialog.show();
}
};
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.setZoom(17);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
mapView.getOverlays().add(new TouchEventOverlay(this));
setContentView(mapView);
}
レイヤを追加する
import android.graphics.Bitmap;
import jp.co.mapion.android.maps.EPSG3857Map;
import jp.co.mapion.android.maps.Tile;
public class OpenWeatherMap extends EPSG3857Map {
@Override
public Bitmap bitmapForTile(Tile tile) {
return null;
}
@Override
public float getMinZoom() {
return 5.f;
}
@Override
public float getMaxZoom() {
return 18.f;
}
@Override
public String getName() {
// 10分毎にキャッシュをクリアするためにsuffixを付ける
Calendar now = Calendar.getInstance();
int minute = now.get(Calendar.MINUTE);
int floorMinute = (int) Math.floor(minute * 0.1);
return "OpenWeatherMap" + floorMinute;
}
@Override
public String getCopyright() {
return "Open Weather Map";
}
@Override
public String urlForTile(Tile tile) {
String ret = "http://tile.openweathermap.org/map/precipitation/" + tile.z + "/" + tile.x + "/" + tile.y + ".png";
return ret;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapView mapView = new MapView(this, "APIキー");
mapView.addMap(new OpenWeatherMap());
mapView.setZoom(6);
mapView.setCenter(new GeoPoint(35.301667, 139.283333));
setContentView(mapView);
}
メモリーキャッシュの上限を設定する
mapView.setMemoryCacheCapacity(256); // デフォルトは128
ディスクキャッシュの上限を設定する
これを設定するとスクロールが重くなります
mapView.setDiskCacheCapacity(100); // デフォルトは0
キャッシュをクリアする
mapView.cacheClear();