Untuk beberapa waktu sekarang saya telah menggunakan QML untuk membangun antarmuka grafis, tetapi sejauh ini belum ada kesempatan untuk bekerja dalam proyek nyata dengan
Qt Location API dan QML Map.
Karena itu, menjadi menarik untuk mencoba komponen ini untuk membangun saluran udara.
Di bawah pemotong adalah deskripsi implementasi editor, untuk membuat jalur seperti itu di peta:

Untuk menyederhanakan implementasi, pesawat kami terbang di pesawat 2D pada ketinggian yang sama. Kecepatan dan kelebihan beban diizinkan - 920 km / jam dan 3g, yang memberikan radius belokan
Lintasan terdiri dari segmen-segmen berikut:

di mana S adalah awal dari manuver (itu adalah titik keluar dari yang sebelumnya), M adalah awal dari belokan, E adalah jalan keluar dari itu, dan F adalah titik akhir (M untuk yang berikutnya).
Untuk menghitung titik masuk dan keluar dari lintasan, saya menggunakan
persamaan tangen ke lingkaran, perhitungan ternyata agak rumit, saya yakin itu bisa dibuat lebih sederhana.
void Manoeuvre::calculate() {
Setelah menyelesaikan kesalahan perhitungan model matematika lintasan kami, kami melanjutkan untuk bekerja langsung dengan peta. Pilihan alami untuk membuat polyline pada peta QML adalah menambahkan
MapPolyline langsung ke peta.
Map { id: map plugin: Plugin { name: "osm" } MapPolyline { path: [ { latitude: -27, longitude: 153.0 }, ... ] } }
Awalnya, saya ingin memberi pengguna kesempatan untuk mensimulasikan setiap bagian selanjutnya dari rute βon the flyβ - untuk membuat efek lintasan di belakang kursor.

Mengubah
jalur saat memindahkan kursor adalah operasi yang agak mahal, jadi saya mencoba menggunakan jalur "pixel" pendahuluan yang ditampilkan hingga pengguna akhirnya menyimpan rute.
Repeater { id: trajectoryView model: flightRegistry.hasActiveFlight ? flightRegistry.flightModel : [] FlightItem { anchors.fill: parent startPoint: start endPoint: end manoeuvreRect: rect manoeuvreStartAngle: startAngle manoeuvreSpanAngle: spanAngle isVirtualLink: isVirtual } }
FlightItem adalah
QQuickItem , dan
flightModel QAbstractListModel memungkinkan Anda untuk memperbarui bagian yang diperlukan dari lintasan ketika mengubah data untuk manuver.
QVariant FlightModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } switch (role) { case FlightRoles::StartPoint: return mFlight->flightSegment(index.row()).line().p1(); case FlightRoles::EndPoint: return mFlight->flightSegment(index.row()).line().p2(); ... }
Pembaruan langsung semacam itu memungkinkan Anda untuk memperingatkan pengguna tentang manuver yang tidak dapat direalisasi.

Hanya setelah selesainya pembuatan jalan napas (misalnya, dengan klik kanan mouse), rute tersebut akhirnya akan ditambahkan ke Peta QML sebagai GeoPath dengan kemungkinan georeferensi (sampai saat ini peta tidak dapat dipindahkan dan diperbesar, piksel tidak tahu apa-apa tentang garis bujur dan garis lintang).
Untuk menghitung ulang segmen piksel ke dalam koordinat geografis, untuk permulaan kita perlu menggunakan untuk setiap manuver sistem koordinat lokal ke titik masuk manuver (titik S kami).
QPointF FlightGeoRoute::toPlaneCoordinate(const QGeoCoordinate &origin, const QGeoCoordinate &point) { auto distance = origin.distanceTo(point); auto azimuth = origin.azimuthTo(point); auto x = qSin(qDegreesToRadians(azimuth)) * distance; auto y = qCos(qDegreesToRadians(azimuth)) * distance; return QPointF(x, y); }
Setelah kami menghitung ulang manuver yang sudah meter, Anda perlu melakukan operasi terbalik dan mengetahui geolokasi titik S untuk menerjemahkan meter dalam lintang-bujur.
QGeoCoordinate FlightGeoRoute::toGeoCoordinate(const QGeoCoordinate &origin, const QPointF &point) { auto distance = qSqrt(point.x()*point.x() + point.y()*point.y()); auto radianAngle = qAtan2(point.x(), point.y()); auto azimuth = qRadiansToDegrees(radianAngle < 0 ? radianAngle + 2*M_PI : radianAngle); return origin.atDistanceAndAzimuth(distance, azimuth); }
Dari sudut pandang formal, tentu saja tidak mungkin untuk mempertimbangkan lintasan "piksel" dan "dalam meter" kami identik, tetapi tampaknya sangat lezat bagi saya untuk melihat ke masa depan dan menunjukkan kepada pengguna apa yang akan terjadi (atau tidak akan terjadi jika pesawat tidak terbang seperti itu) ketika dia akan mengklik waktu berikutnya. Setelah menyelesaikan lintasan (sedikit berbeda dari lintasan pixel dalam warna dan transparansi, karena bahkan garis putus statis tidak terlihat sangat mulus pada peta).

Sumber tersedia di
sini , untuk kompilasi saya menggunakan Qt 5.11.2.
Pada bagian selanjutnya, kami akan mengajar editor kami untuk memindahkan titik referensi lintasan, serta menyimpan / membuka rute yang ada untuk simulasi selanjutnya dari pergerakan pesawat.