
Dalam
artikel sebelumnya, saya berbicara tentang cara membuat aplikasi seluler dengan peta. Sebagai kelanjutan dari seri "on the knee" saya akan berbagi dengan Anda alat untuk mengimplementasikan denah lantai.
Pernyataan awal masalah dalam bentuk yang disederhanakan: Saya ingin dapat memvisualisasikan diagram lantai dalam aplikasi seluler Anda dan dapat menunjukkan lokasi organisasi tertentu di dalamnya. Saya juga ingin melihat lokasi pengguna, tetapi di sini masalahnya ada di bidang teknis - Anda memerlukan peralatan yang memungkinkan Anda mendapatkan koordinat perangkat di dalam ruangan. Jadi kami meninggalkan aspek ini di luar ruang lingkup artikel dan fokus pada bagian perangkat lunak.
Di bawah ini saya akan menunjukkan kepada Anda beberapa opsi yang dapat digunakan untuk mengimplementasikan persyaratan yang dijelaskan di atas. Itu semua tergantung pada data apa yang Anda miliki dan apa sebenarnya aplikasi harus dapat dilakukan. Dan kita akan mulai dengan yang paling sederhana.
Opsi pertama. API siap dengan data
Opsi pertama yang akan kami pertimbangkan adalah penggunaan widget yang sudah jadi dari 2GIS. Deskripsi API dapat dilihat di
api.2gis.ru. Ini akan cocok untuk Anda jika bangunan yang Anda minati sudah disajikan dalam 2GIS, dan lantainya sudah ditarik ke dalam gedung. Artinya, dalam hal data, semuanya sudah dilakukan. Dan yang paling penting, Anda siap online, karena opsi ini akan bekerja secara eksklusif dengan Internet.
Untuk menampilkan lantai dalam kasus ini, praktis tidak ada yang diperlukan dari Anda sama sekali. Implementasi eksekusi sebagai widget web, yang Anda hanya perlu dimasukkan ke dalam WebView.
<WebView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/am_webview" android:layout_marginTop="160dp" />
Ini adalah wadah tempat kita akan meletakkan widget kita. Kami menginisialisasi sebagai berikut:
webView = findViewById(R.id.am_webview) webView.settings.javaScriptEnabled = true webView.settings.useWideViewPort = true webView.settings.loadWithOverviewMode = true
Kami mengkonfigurasi webView itu sendiri, pastikan untuk mengaktifkan JavaScript, javaScriptEnabled = true, karena kami akan berinteraksi dengan widget yang melaluinya. Jika perlu, Anda dapat mengaktifkan scrollbar dan tombol zoom (lihat kode yang dikomentari), tetapi tidak bekerja dengan baik, jadi saya tidak merekomendasikannya.
Yang paling penting adalah memuat HTML dengan widget kami
webView.loadUrl ("file: ///android_asset/map_api.html") dan berlangganan acara, jika diperlukan. Dalam contoh di atas, setelah memuat peta, kami memanggil metode
initMap yang didefinisikan dalam map_api.html, dengan meneruskan pengidentifikasi bangunan yang ingin kami perlihatkan lantai.
HTML adalah kode yang cukup sederhana. Metode
DG.FloorsWidget.init dipanggil , ke mana objek json yang berisi data untuk diinisialisasi dilewatkan. Sebagai wadah, tentukan id yang dengannya kami telah mendeklarasikan div di markup HTML di atas. Sesuaikan lebar, tinggi. Dan di
initData kita melewati bangunan di tag
complexId , dan parameter tampilan widget tambahan, yang dapat ditemukan dalam dokumentasi API. Omong-omong, pengidentifikasi dapat dilihat sebagai respons terhadap permintaan pencarian, yang dikirim 2GIS ketika Anda mengklik bangunan yang Anda minati di
2gis.ru. Dalam contoh saya, saya menggunakan Dubai Mall. Tapi tidak ada yang mengganggu untuk mengindikasikan bangunan lain dengan lantai.
Sentuhan terakhir. Untuk pindah ke perusahaan tertentu, panggil metode showFirm, dengan lewati pengenal perusahaan
webView.loadUrl("javascript:showFirm('$firmId')")
Sederhana saja. Contoh implementasi yang sudah jadi dapat dilihat di
Github .

Kelebihan dari opsi yang dipertimbangkan:
- data siap pakai dengan denah lantai dan data perusahaan;
- implementasi ringan siap pakai di tampilan web;
- pencarian siap menurut 2GIS.
Cons:
- Dibutuhkan internet;
- diperlukan pengetahuan dasar tentang HTML dan JavaScript;
- hanya data 2GIS dan hanya bangunan yang sudah memiliki lantai.
Opsi kedua. Denah lantai sebagai gambar
Jika opsi dengan data siap dan API tidak cocok untuk Anda, Anda dapat menggunakan yang berikut ini.
Dalam hal ini, Anda akan memerlukan denah lantai dalam bentuk gambar, katakanlah, jpeg atau png. Jika interaktivitas dari jenis "menyodok ke dalam gambar - membuka kartu objek" diperlukan, maka geocoding juga akan diperlukan, yang perlu diterapkan secara independen. Jika Anda mengambil koordinat global, maka gambar harus diskalakan dengan benar dan salah satu sudut harus ditarik ke koordinat nyata sehingga Anda dapat menghitung perpindahan dari itu. Kami tidak akan membahas masalah ini secara rinci, saya harap semuanya jelas di sini.
Yang paling penting adalah menampilkan gambar ini di aplikasi. Dan untuk ini, perpustakaan
TileView sangat ideal bagi kami. Bahkan, perpustakaan ini memungkinkan, pada prinsipnya, untuk menampilkan petak peta. Tetapi ini juga cocok untuk kita, karena menyediakan kemampuan untuk bergerak dan memperbesar, memusatkan pada posisi yang ditentukan, penanda tampilan, transformasi koordinat dan kemampuan untuk berlangganan berbagai acara.
Agar perpustakaan dapat bekerja seefisien mungkin, gambar aslinya perlu disiapkan dengan memotongnya menjadi ubin. Ada
instruksi yang cukup sederhana
untuk ini . Saya merekomendasikan skrip di akhir halaman yang ditentukan yang akan membuat 4 tileset. Kami menambahkan hasil yang diperoleh ke dalam aset dan menampilkan gambar kami di aktivitas dengan kode sederhana:
tileView.setSize(floorWidth, floorHeight) tileView.setShouldRenderWhilePanning(true) tileView.addDetailLevel(1f, "tiles/floors1/1000/%d_%d.jpg") tileView.addDetailLevel(0.500f, "tiles/floors1/500/%d_%d.jpg") tileView.addDetailLevel(0.250f, "tiles/floors1/250/%d_%d.jpg") tileView.addDetailLevel(0.125f, "tiles/floors1/125/%d_%d.jpg") tileView.defineBounds(0.0, 0.0, floorWidth.toDouble(), floorHeight.toDouble()) tileView.setScaleLimits(0f, 5f) tileView.setMinimumScaleMode(ZoomPanLayout.MinimumScaleMode.FIT)
Semuanya, layar sudah siap. Anda dapat berlangganan acara dan menambahkan logika yang diperlukan. Misalnya, marker dapat ditampilkan seperti ini:
tileView.setMarkerAnchorPoints(-0.5f, -0.5f) tileView.addMarker(imageView, x, floorHeight - y, null, null)
Contoh lengkap tersedia di
Github .

Pro:
- kemampuan untuk melakukan sepenuhnya offline;
- persiapan data yang relatif sederhana, denah dalam bentuk gambar.
Cons:
Opsi ketiga. Data vektor
Opsi ini adalah yang paling canggih dan paling sulit. Diasumsikan bahwa Anda telah menyiapkan data vektor, yaitu lantai yang digambar sepenuhnya dalam vektor. Anda akan membutuhkan beberapa jenis objek. Area organisasi, tempat parkir, lapangan makanan, panggung, arena seluncur es, dan sebagainya. Objek linear - terutama dinding, arah aliran. Objek titik: input / output, lift, ATM dan sejenisnya.
Seperti apa bentuk denah di Fiji, sistem internal 2GIS:

Nah, untuk visualisasi mereka, mesin vektor, yang saya bicarakan di
artikel sebelumnya , mapsforge-vtm cocok untuk kita.
Untuk mendemonstrasikan pendekatan, saya menyiapkan data uji: satu set kotak dan garis untuk beberapa lantai menggunakan contoh bangunan di pulau Siprus yang cerah. Untuk persiapan, saya mengambil geometri asli bangunan dan memotongnya menjadi beberapa bagian sesuai dengan komponen geometri, semata-mata untuk kesederhanaan. Seperti yang Anda tahu, bagian yang paling sulit adalah persiapan data yang berkualitas. Sisanya adalah masalah teknologi. Anda akan membutuhkan tombol untuk berpindah lantai, gaya yang disiapkan untuk merender kotak dan garis yang berbeda, dan overlay untuk merendernya.
Lihat kode lengkapnya di
sini .
Kelas
FloorData berisi kode geodata uji untuk lantai kami, dan kelas
FloorsManager dirancang untuk membuatnya.
Dalam konstruktor, kami mendefinisikan gaya untuk kotak dan dinding:
styles.put(ObjectType.Floor, org.oscim.layers.vector.geometries.Style.builder() .fillColor(Color.GRAY) .build());
Dan dalam metode
drawFloor ,
kami menentukan logika menambahkan objek ke lapisan pada peta:
public void drawFloor(int floorId) { hideFloors(); indoorLayer = new CustomVectorLayer(this.map); List<GeoData> geoObjects = this.floorData.getFloorData(floorId); for (GeoData geo: geoObjects) { indoorLayer.add(geo.getGeometry(), styles.get(geo.getObjectType())); } this.map.layers().add(indoorLayer); indoorLayer.update(); }
Semuanya dasar di sini. Buat layer baru
indoorLayer , tambahkan data lantai yang sudah disiapkan sebelumnya dengan gaya yang diperlukan untuk itu dan tambahkan layer ke peta
this.map.layers (). Tambahkan (indoorLayer) .
Tetap menambahkan tombol untuk beralih lantai. Untuk melakukan ini, ada
FloorPickerControl berdasarkan pada
RecyclerView , yang melakukan apa yang Anda butuhkan. Jangan buang waktu untuk itu, lihat sumbernya.
Dan di sini adalah Dubai Mall dalam aplikasi kita. Ini juga menerapkan pengeditan objek geo.

Pro:
- lagi, kemampuan untuk melakukan sepenuhnya offline;
- gambar berkualitas tinggi;
- kemungkinan variasi gaya dinamis;
- kemampuan untuk mengimplementasikan editor data.
Cons:
- persiapan data yang kompleks.
Pada akhir artikel saya ingin mengatakan bahwa tugas menampilkan denah lantai dalam aplikasi tidak mengerikan seperti yang terlihat pada pandangan pertama. Anda memiliki beberapa opsi dengan pro dan kontra, di mana Anda dapat memilih yang paling cocok untuk menyelesaikan masalah Anda.
Semua referensi di satu tempat:
Artikel tentang peta di ponselAPI 2GISContoh 2GIS APIPerpustakaan TileViewContoh TileViewContoh di mapsforge-vtm