Dubai Mall di smartphone, atau cara menambahkan denah bangunan ke aplikasi Anda



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 //webView.settings.setSupportZoom(true) //webView.settings.displayZoomControls = true //webView.settings.builtInZoomControls = true webView.loadUrl("file:///android_asset/map_api.html") webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { super.onPageFinished(view, url) val js = "initMap('13933647002593772');" // The Dubai Mall webView.evaluateJavascript(js, ValueCallback { }) } } 

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:

  • kurangnya gaya dinamis.

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 ponsel
API 2GIS
Contoh 2GIS API
Perpustakaan TileView
Contoh TileView
Contoh di mapsforge-vtm

Source: https://habr.com/ru/post/id476816/


All Articles