2GIS ada di ujung jari Anda. Bagaimana kami menambahkan peta ke Apple Watch


Apple Watch dengan cepat mendapatkan popularitas dan menjadi jam tangan paling populer di dunia, di depan Rolex dan produsen lainnya. Gagasan membuat aplikasi untuk jam tangan telah ada di kantor 2GIS sejak 2015.


Di hadapan kami, hanya Apple sendiri yang merilis aplikasi lengkap dengan kartu pada jam tangan. Aplikasi Yandex.Map hanya menampilkan widget lalu lintas dan waktu perjalanan ke rumah dan kantor. Yandex.Navigator, Google Maps, Waze, dan Maps.Me umumnya tidak tersedia di jam tangan.


Bahkan, karena banyak keterbatasan sistem dan kompleksitas pengembangan, perusahaan tidak membuat aplikasi jam tangan sama sekali, atau membuatnya sangat sederhana. Anda tidak bisa hanya mengambil dan menggambar peta di arloji. Tapi kita bisa.


Mengintip di bawah kucing untuk mengetahui bagaimana proyek hewan peliharaan telah tumbuh menjadi produk yang lengkap.


UPD.: Https://github.com/teanet/DemoWatch


Kami memutuskan untuk membuat peta. Apa yang awalnya?


  1. Pengalaman pengembangan di arloji - 2 hari bekerja pada proyek uji.
  2. Pengalaman dengan SpriteKit - 0 hari.
  3. Pengalaman menulis MapKit - 0 hari.
  4. Keraguan bahwa ada sesuatu yang salah - ∞.

Iterasi 1 - Penerbangan Pemikiran


Kami adalah orang-orang yang serius, jadi untuk awalnya kami memutuskan untuk menyusun rencana kerja. Kami memperhitungkan bahwa kami bekerja dalam sprint yang terencana dengan baik, kami memiliki lima poin cerita untuk "tugas produk kecil" dan sama sekali tidak tahu harus mulai dari mana.


Peta adalah gambar yang sangat besar. Kami dapat menunjukkan gambar pada jam, yang berarti kami dapat menangani tampilan kartu.


Kami memiliki layanan yang dapat memotong kartu menjadi beberapa bagian:



Jika Anda memotong gambar seperti itu dan memasukkannya ke dalam WKImage, kami mendapatkan prototipe kerja paling sederhana untuk lima sen.


Dan jika Anda menambahkan PanGesture ke gambar ini dan menginstal gambar baru pada setiap gesekan, kami mendapatkan simulasi interaksi dengan kartu.


/ Bersukacitalah / Kedengarannya mengerikan, kelihatannya hampir sama, bekerja lebih buruk, tetapi ternyata tugasnya sudah selesai.


Iterasi 2 - prototipe minimum


Pengunduhan gambar yang berkelanjutan mahal untuk baterai dalam hitungan jam. Ya, dan waktu bootnya sendiri akan terganggu. Kami ingin mendapatkan sesuatu yang lebih lengkap dan responsif. Dari sudut telinga kami, kami mendengar bahwa arloji memiliki dukungan untuk SpriteKit - satu-satunya kerangka kerja WatchOS dengan kemampuan untuk menggunakan koordinat, memperbesar dan menyesuaikan semua keindahan ini untuk Anda sendiri.


Setelah beberapa jam StackOverflow Driven Development (SDD) kami mendapatkan iterasi kedua:
Satu SKSpriteNode, satu WKPanGestureRecognizer.



/ Bersukacitalah / Ya ini MapKit untuk 6 kopecks, berfungsi penuh. Rilis mendesak!


Iterasi 3 — Menambahkan Ubin dan Zoom


Ketika emosi tertidur, mereka bertanya-tanya ke mana harus pergi berikutnya.


Memahami bahwa hal yang paling penting:


  • Ganti gambar dengan ubin.
  • Pasang 4 ubin ke bundel aplikasi dan hubungkan bersama.
  • Berikan gambar zoom.
    Mari kita masukkan 4 ubin ke dalam bundel aplikasi, lalu taruh di ubin tertentu:

let rootNode = SKSpriteNode() 

dengan bantuan matematika sederhana kita akan menghubungkannya bersama.
Kami melakukan zoom melalui WKCrownDelegate:


 internal func crownDidRotate( _ crownSequencer: WKCrownSequencer?, rotationalDelta: Double ) { self.scale += CGFloat(rotationalDelta * 2) self.rootNode.setScale(self.scale) } 


/ Bersukacitalah / Nah, sekarang sudah pasti! Beberapa perbaikan, dan untuk master.


Iterasi 4 - mengoptimalkan interaksi dengan peta


Keesokan harinya, ternyata untuk anchorPoint SpriteKit tidak mempengaruhi zoom. Zoom sepenuhnya mengabaikan anchorPoint dan terjadi relatif terhadap pusat dari rootNode. Ternyata untuk setiap langkah zoom kita perlu menyesuaikan posisi.


Akan lebih baik memuat ubin dari server, daripada menyimpan seluruh dunia dalam memori arloji.
Jangan lupa bahwa ubin harus diikat ke koordinat sehingga tidak terletak di tengah SKScene, tetapi di tempat yang sesuai di peta.


Ubin terlihat seperti ini:



Setiap zoomLevel (selanjutnya disebut "z") memiliki kumpulan ubin sendiri. Untuk z = 1, kami memiliki 4 ubin yang membentuk seluruh dunia.



untuk z = 2 - untuk mencakup seluruh dunia, Anda sudah membutuhkan 16 ubin,
untuk z = 3 - 64 ubin.
untuk z = 18 ≈ 68 * 10 ^ 9 ubin.
Sekarang mereka harus dimasukkan ke dalam dunia SpriteKit.


Ukuran satu ubin adalah 256 * 256 pt, yang berarti
untuk z = 1, ukuran "dunia" akan menjadi 512 * 512 pt,
untuk z = 2 ukuran "dunia" akan sama dengan 1024 * 1024 pt.
Untuk kemudahan perhitungan, letakkan ubin di dunia sebagai berikut:



Enkode ubin:


 let kTileLength: CGFloat = 256 struct TilePath { let x: Int let y: Int let z: Int } 

Tentukan koordinat ubin di dunia seperti itu:


 var position: CGPoint { let x = CGFloat(self.x) let y = CGFloat(self.y) let offset: CGFloat = pow(2, CGFloat(self.z - 1)) return CGPoint(x: kTileLength * ( -offset + x ), y: kTileLength * ( offset - y - 1 )) } var center: CGPoint { return self.position + CGPoint(x: kTileLength, y: kTileLength) * 0.5 } 

Lokasi nyaman, karena memungkinkan Anda untuk membawa semuanya ke dalam koordinat dunia nyata: lintang / bujur = 0, yang hanya di pusat "dunia".


Lintang / bujur dari dunia nyata ditransformasikan menjadi dunia kita sebagai berikut:


 extension CLLocationCoordinate2D { //     ( -1 < TileLocation < 1 ) func tileLocation() -> CGPoint { var siny = sin(self.latitude * .pi / 180) siny = min(max(siny, -1), 1) let y = CGFloat(log( ( 1 + siny ) / ( 1 - siny ))) return CGPoint( x: kTileLength * ( 0.5 + CGFloat(self.longitude) / 360 ), y: kTileLength * ( 0.5 - y / ( 4 * .pi ) ) ) } //       zoomLevel func location(for z: Int) -> CGPoint { let tile = self.tileLocation() let zoom: CGFloat = pow(2, CGFloat(z)) let offset = kTileLength * 0.5 return CGPoint( x: (tile.x - offset ) * zoom, y: (-tile.y + offset) * zoom ) } } 

Dengan masalah leveling zoom. Saya harus menghabiskan beberapa hari libur untuk mengumpulkan seluruh perangkat matematika dan memastikan penggabungan ubin yang sempurna. Yaitu, ubin untuk z = 1 idealnya masuk ke empat ubin untuk z = 2 dan sebaliknya, empat ubin untuk z = 2 harus masuk ke satu ubin untuk z = 1.



Selain itu, perlu untuk mengubah zoom linear menjadi zoom eksponensial, karena zoom bervariasi dari 1 <= z <= 18, dan skala peta seperti 2 ^ z.


Zoom halus disediakan dengan terus-menerus menyesuaikan posisi ubin. Adalah penting bahwa ubin dijahit tepat di tengah: yaitu, ubin level 1 masuk ke ubin 4 level 2 dengan zoom 1,5.


SpriteKit menggunakan pelampung di bawah kap. Untuk z = 18, kami mendapatkan sebaran koordinat (-33 554 432/33 554 432), dan akurasi float adalah 7 bit. Di pintu keluar, kami memiliki kesalahan di wilayah 30 pt. Untuk menghindari terjadinya "celah" di antara dua bagian, kami menempatkan ubin yang terlihat sedekat mungkin dengan pusat SKScene.


/ Bersukacitalah / Setelah semua gerakan ini kami mendapatkan prototipe yang siap untuk diuji.


Tanggal rilis


Karena aplikasi tersebut tidak benar-benar memiliki TK, kami menemukan beberapa sukarelawan untuk melakukan tes kecil. Mereka tidak menemukan masalah khusus, dan memutuskan untuk pergi ke samping.


Setelah rilis, ternyata pada jam seri pertama prosesor tidak punya waktu untuk menggambar bingkai kartu pertama dalam 10 detik dan jatuh pada batas waktu. Awalnya saya harus membuat kartu yang benar-benar kosong agar muat dalam 10 detik, dan kemudian secara bertahap memuatkan media. Pertama-tama kembangkan semua level peta - dan kemudian muat ubin untuknya.


Butuh banyak waktu untuk men-debug jaringan, mengkonfigurasi cache dengan benar dan Memory Footprint kecil sehingga WatchOS tidak akan mencoba untuk mematikan aplikasi kami selama mungkin.


Setelah membuat profil aplikasi, kami menemukan bahwa alih-alih ubin yang biasa, Anda dapat menggunakan ubin Retina, hampir tanpa membahayakan waktu buka dan konsumsi memori, dan pada rilis baru mereka sudah beralih ke ubin itu.


Hasil dan rencana untuk masa depan


Kita sudah bisa menampilkan rute dengan manuver yang dibangun di aplikasi utama pada peta. Fitur ini akan tersedia di salah satu rilis mendatang.


Proyek, yang awalnya tampak mustahil, terbukti sangat berguna bagi saya secara pribadi. Saya sering menggunakan aplikasi untuk memahami apakah sudah waktunya untuk berhenti di halte yang benar. Saya percaya bahwa di musim dingin akan lebih bermanfaat.


Pada saat yang sama, ia sekali lagi diyakinkan bahwa kompleksitas proyek, keyakinan orang lain dalam keberhasilan tugas atau ketersediaan waktu luang di tempat kerja, tidak begitu penting. Hal utama adalah keinginan untuk membuat proyek dan gerakan bertahap yang membosankan menuju tujuan. Hasilnya, kami memiliki MapKit lengkap, yang hampir tidak terbatas dan berfungsi dengan 3 WatchOS. Itu dapat dimodifikasi sesuai keinginan tanpa menunggu Apple untuk meluncurkan API yang sesuai untuk pengembangan.


NB Bagi yang berminat, saya dapat menyusun proyek yang sudah jadi. Level kode di sana jauh dari produksi. Tetapi, menurut prinsip militer, tidak masalah bagaimana cara kerjanya, hal utama adalah ia bekerja!

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


All Articles