Last Updated on 11 years by Mas Herdi
Google Maps Android API v2 menawarkan berbagai macam kemudahan, salah satunya kita bisa mengganti default tile yang berupa Google Maps tile menjadi tile apapun asalkan menggunakan maps projection yang digunakan juga oleh Google Maps, yaitu Mercator projection. Karena itu, pada kesempatan kali ini saya akan berbagi tutorial tentang cara mengganti default map pada Android Maps API menjadi OpenStreetMap.
Untuk mengganti default tile dan menampilkan peta dari OpenStreetMap, Google Maps Android API SDK mempunyai satu buah kelas bernama TileProvider, kelas inilah yang nantinya akan meng-handle dan me-replace semua tile default dengan OpenStreetMap.
Pre-Requisites :
Seperti biasa, sebelum memulai tutorial ini paling tidak kalian sudah belajar tentang bagaimana cara 😀 :
- Menampilkan Maps Menggunakan Android Maps API v2
- Tutorial lain yang berguna tentang Android Maps API v2
Disarankan juga kalian sudah mempelajari tutorial sebelumnya sampai ke tahap menampilkan marker pada Android Maps API v2.
Let’s Begin
Pertama-tama, kita perlu mengakses tile kepunyaan OpenStreetMap. Untuk aksesnya, OpenStreetMap sendiri sudah menyediakan URL tile provider yang berformat seperti berikut.
http://a.tile.openstreetmap.org/{z}/{x}/{y}.png
Dimana {z} adalah zoom level, {x} dan {y} adalah koordinat x dan y pada Mercator Projection.
Apabila kalian memasukkan sebuah value z, x, y seperti contoh berikut :
http://a.tile.openstreetmap.org/15/5241/12663.png
Maka kalian akan mendapatkan tile yang berupa gambar png berukuran 256×256 piksel seperti ini :
Membuat Custom TileProvider
Langkah selanjutnya adalah membuat custom TileProvider. Karena tile yang akan kita dapatkan nantinya berasal dari URL, maka kita akan extends class tersebut dari class UrlTileProvider. Buatlah satu file .java bernama MapsTileProvider dan isikan kode berikut :
import java.net.MalformedURLException; import java.net.URL; import com.google.android.gms.maps.model.UrlTileProvider; public class MapsTileProvider extends UrlTileProvider{ private String baseURL; public MapsTileProvider(int width, int height, String url) { super(width, height); this.baseURL = url; } @Override public URL getTileUrl(int x, int y, int zoom) { try { return new URL(baseURL.replace("{z}", ""+zoom).replace("{x}",""+x).replace("{y}",""+y)); } catch (MalformedURLException e) { e.printStackTrace(); } return null; } }
Setelah itu pada MainActivity kita tambahkan dua variabel seperti berikut :
private String osmURL = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"; private MapsTileProvider mTileProvider = new MapsTileProvider(256, 256, osmURL);
Untuk menampilkan tile overlay menggunakan provider lain, kalian hanya perlu menggunakan satu baris kode berikut :
map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider));
Namun kode tersebut hanya akan mengganti tile pada area yang terlihat saja. Masalahnya, bagaimana kalau peta nya digeser? Tile tersebut akan hilang. Karena itu kita perlu membuat sebuah listener yang berfungsi untuk mendeteksi ketika pengguna menggeser-geser peta. Listener tersebut bernama OnCameraChangeListener, dan kita akan meletakkan kode tersebut di dalam onCameraChangeListener :
map.setOnCameraChangeListener(new OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition campos) { map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider)); } });
Sehingga apabila peta digeser, tile yang baru akan otomatis ter-replace dengan tile dari OpenStreetMap.
Kelas MainActivity kalian yang baru sekarang akan terlihat seperti berikut :
package id.web.twoh.www.mapsv2; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.TileOverlayOptions; import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MapsMainNew extends FragmentActivity { private GoogleMap map; private LatLng latLngBiru = new LatLng(35.6829733, 139.7321275); private LatLng latLngKuning = new LatLng(35.6847009,139.7314891); private LatLng latLngMerah = new LatLng(35.6839537, 139.7308615); private String osmURL = "http://a.tile.openstreetmap.org/{z}/{x}/{y}.png"; private MainActivity mTileProvider = new MainActivity(256, 256, osmURL); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps_main); SupportMapFragment mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mapFrag.getMap(); map.setMyLocationEnabled(true); map.addMarker(new MarkerOptions() .position(latLngBiru) .icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_BLUE)) .title("tempat rahasia").snippet("rahasia lho")); map.addMarker(new MarkerOptions() .position(latLngKuning) .icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)) .title("bangunan kampus").snippet("bangunan utama")); map.addMarker(new MarkerOptions() .position(latLngMerah) .icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_RED)) .title("kantin kampus").snippet("makan makan")); map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLngBiru, 17)); map.setOnCameraChangeListener(new OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition campos) { map.addTileOverlay(new TileOverlayOptions().tileProvider(mTileProvider)); } }); } }
Running Application :
Setelah di-running, maka beginilah tampilan OpenStreetMap saat ditampilkan pada Android Maps API :
Dan beginilah tampilan menggunakan Google Maps default.
Malam mas,
saya mau nanya, kebetulan saya sedang mencari tutorial untuk membuat webgis dengan menggunakan openstreetmap untuk tugas akhir saya.
apakah untuk web codingnya sama dengan untuk android?
terima kasih atas perhatiannya 🙂
berbeda… kalo nggak salah untuk web-nya menggunakan Javascript