Realization of map function
1. Introduction
UX SDK provides the following functionalities:
Map: Configure basic settings, create points, draw lines, circles, and polygons on the map, and implement event callbacks
Location tracking: Support location tracking, backend location tracking, and direction updating
Search: Currently, only Geocode search is supported for Apple Map. The POI search is not supported.
2. Entire Framework
The map framework consists of three parts: map, search, and location tracking. The three parts are independent from each other and implemented using different map SDKs.
2.1 Map (Primary)
- Basic settings: Zoom level, display area, map type
- Drawings on the map: Points, lines, circles, and polygons
- Event callbacks: Callback of point clicking, point dragging, and map clicking events
2.2 Search and Location Tracking
3. APIs and Corresponding Class Files
Provider | Apple |
---|---|
AutelMapView: Map | AutelAppleMapView |
AutelAnnotationOptions: point configuration | |
AutelAnnotation: Marking points | AutelAppleAnnotation |
AutelAnnotationView: Marking point view | AutelAppleAnnotationView |
AutelCustomAnnotationView: point customization | |
AutelOverlay: graph | |
AutelPolyline: line | AutelApplePolyline |
AutelCircle: circle | AutelAppleCircle |
AutelPolygon: polygon | AutelApplePolygon |
AutelOverlayOptions: graphic configuration | |
AutelPolylineOptions: line configuration | |
AutelCircleOptions: circle configuration | |
AutelPolygonOptions: polygon configuration | |
AutelOverlayRenderer: graphic drawings | |
AutelPolylineRenderer: line drawings | AutelApplePolylineRenderer |
AutelCircleRenderer: circle drawings | AutelApplePolylineRenderer |
AutelPolygonRenderer: polygon drawings | AutelApplePolygonRenderer |
ATCustomRenderer: customized drawings | |
AutelLocationManager: location tracking | AutelAppleLocationManager |
AutelGeocoder: search | AutelAppleGeocoder |
AutelPlacemark: location |
4. Function Modules
The following describes core map functionalities provided by the SDK, including:
Display No Fly Zones, Restricted Altitude Zones, and Authorized Zones
Display flight paths
Display street views, GPS live maps, and hybrid maps
Find my current location or Home point
4.1 Create AutelMapView
Create a map view named AutelMapView using ATMapManager. The following shows the code for creating the view:
lazy var mapManager: ATMapManager = {
let manager = ATMapManager.manager
manager.mapView.isPitchEnabled = false
manager.drawDelegate = self
manager.startLocationAndUpdate()
return manager
}()
lazy var mapView: AutelMapView {
return mapManager.mapView
}
Add AutelMapView to the controller and configure the constraint. In this way, the map UI can be shown. The code is shown below:
view.addSubview(mapView)
mapView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
Implement ATMapDrawDelegate. The code is shown below:
extension ATBaseMapViewController: ATMapDrawDelegate{
func mapIsMainVC() -> Bool {
return true
}
func unitSystem() -> UnitSystem {
return ATSettings.shared.unitSystem
}
func maxFlightRadius() -> Float?{
return FlightLimitationService.shared.maxFlightRadius
}
func updateHomeLocation(coordinate: CLLocationCoordinate2D?){
let message = "ATMapHomePointRefresh".fLocal("ATFly")
ToastManager.shared.show(title: message)
ATSpeechManager.shared.speak(text: message, clear: false)
}
}
The displayed map is shown below:
4.2 Display No Fly Zones, Restricted Altitude Zones, and Authorized Zones
Call the showNoFlyZones method provided by ATMapDrawManager to display No Fly Zones, Restricted Altitude Zones, and Authorized Zones.
func showNoFlyZones(_ level: ATNoFlyZoneAreaLevel, show: Bool)
The code example is shown below:
ATMapManager.manager.drawManager.showNoFlyZones(level, show: isSelected)
4.3 Display Flight Paths
The code for displaying flight paths is shown below:
ATMapManager.manager.setting.isShowFlightRoute = true
When you configure to display flight paths, the map uses green lines to represent these paths, as shown in the following picture:
When you configure to hide flight paths, the green lines are hidden accordingly, as shown in the following picture:
The code for clearing flight paths is shown below:
ATMapManager.manager.cleanFlightPath()
4.4 Set the Map Type
Maps are classified into three types: Standard, Satellite, and Hybrid. The enumeration values are shown below:
public enum AutelMapType : Int {
case standard
case satellite
case hybrid
}
The following code sets the map type to Standard:
var mapType = AutelMapType.standard
ATMapManager.manager.setting.mapType = mapType
4.5 Location Tracking
You can use this functionality to find your current location, Home point, and aircraft location. The code for enabling this functionality is shown below:
ATMapManager.manager.mapLocateAround(.aircraft)
As shown in the following picture, 1 indicates your current location, 2 indicates the Home point, and 3 indicates the aircraft position.
4.6 Update the Head Direction of the Aircraft
During the flight, the head direction should be the same as the direction the aircraft will being flying. Perform the following steps to update the head direction:
1. Implement MainControllerProtocol and call a method in the updateDroneLocation method to update the head direction. The corresponding code is shown below:
@objc extension ATBaseMapViewController: MainControllerProtocol {
func updateDroneLocation(coordnidate: CLLocationCoordinate2D) {
mapManager.drawManager.updateDroneLocation(coordnidate)
upDroneHeading()
}
}
The code for updating the head direction of the aircraft icon on the map is shown below:
func upDroneHeading() {
if let annotation = mapManager.drawManager.aircraftAnnotation, let annotationView: ATAircraftAnnotationView = annotation.customAnnotationView as? ATAircraftAnnotationView {
annotationView.updateHeading(heading: (AutelMCState.shared.attitude.yaw) + Float(-mapView.cameraHeading.radian))
}
}
2. Subscribe to the headingUpdateObservable sequence. The reference code is shown below:
mapManager.headingUpdateObservable.subscribe(onNext: {[weak self] (newHeading: CLHeading) in
if newHeading.headingAccuracy < 0 {
return
}
self?.updateHeading(newHeading)
}).disposed(by: bag)
func updateHeading(_ newHeading: CLHeading) {
if mapView.cameraHeading != 0 {
mapView.cameraHeading = 0
}
upDroneHeading()
}