Custom Annotations
This example shows how to add custom annotations in MapView.
-
Add Annotations from GeoJson
-
Animate Annotations
-
Query Visible Annotations in Rect
-
Center Selected Annotation

For all code examples, refer to Maps Code Examples
AnnotationsViewController view source
1//
2// StyleMapLayerViewController.swift
3// maps-ios-demo
4//
5
6import Foundation
7import UIKit
8import Nbmap
9
10enum AnnotationActionType{
11 case AddAnnotations
12 case AddNumberAnnotations
13 case AnimateAnnotations
14 case QueryVisibleAnnotations
15 case CenterSelectedAnnotations
16 case AddVisibleAreaPolyline
17
18}
19
20class AnnotationsViewController: UIViewController {
21
22 var nbMapView: NGLMapView! {
23 didSet {
24 oldValue?.removeFromSuperview()
25 if let mapView = nbMapView {
26 view.insertSubview(mapView, at: 0)
27 mapView.delegate = self
28 }
29 }
30 }
31 var button: UIButton!
32
33 let typeList = [
34 AnnotationActionType.AddAnnotations,
35 AnnotationActionType.AddNumberAnnotations,
36 AnnotationActionType.AnimateAnnotations,
37 AnnotationActionType.QueryVisibleAnnotations,
38 AnnotationActionType.CenterSelectedAnnotations,
39 AnnotationActionType.AddVisibleAreaPolyline,
40 ]
41
42
43 var points : Array = [CLLocationCoordinate2D]()
44
45 override func viewDidLoad() {
46 super.viewDidLoad()
47 nbMapView = NGLMapView(frame:self.view.bounds)
48 button = UIButton(type: .system)
49 button.setTitle("Settings", for: .normal)
50 button.addTarget(self, action: #selector(showSetings), for: .touchUpInside)
51 button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
52 navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
53 }
54
55 @objc func showSetings() {
56 let tableViewController = UITableViewController(style: .plain)
57 tableViewController.tableView.delegate = self
58 tableViewController.tableView.dataSource = self
59 tableViewController.title = "Camera Settings"
60 self.present(tableViewController, animated: true)
61 }
62
63 func performeSettings(type: AnnotationActionType) {
64 switch type {
65 case AnnotationActionType.AddAnnotations :
66 addAnnotations(count: 100)
67 break
68 case AnnotationActionType.AddNumberAnnotations :
69 addAnnotations(count: 1000)
70 break
71 case .AnimateAnnotations:
72 animateAnnotations()
73 break
74 case .QueryVisibleAnnotations:
75 queryVisibleAnnotations()
76 break
77 case .CenterSelectedAnnotations:
78 centerSelectedAnnotation()
79 break
80 case .AddVisibleAreaPolyline:
81 addVisibleAreaPolyline()
82 break
83 }
84
85 }
86
87 func addAnnotations(count: Int32) {
88
89 if let annotations = self.nbMapView.annotations {
90 self.nbMapView.removeAnnotations(annotations)
91 }
92
93 DispatchQueue.global(qos: .default).async {
94 if let featuresData = try? Data(contentsOf: Bundle.main.url(forResource: "points", withExtension: "geojson")!),
95 let features = try? JSONSerialization.jsonObject(with: featuresData, options: []) as? [String: Any] {
96
97 var annotations = [NGLPointAnnotation]()
98
99 if let featureList = features["features"] as? [[String: Any]] {
100 for feature in featureList {
101 if let coordinates = feature["geometry"] as? [String: Any],
102 let coordinateList = coordinates["coordinates"] as? [Double],
103 let title = feature["properties"] as? [String: Any] {
104
105 let coordinate = CLLocationCoordinate2D(latitude: coordinateList[1], longitude: coordinateList[0])
106 let annotation = NGLPointAnnotation()
107 annotation.coordinate = coordinate
108 annotation.title = title["NAME"] as? String
109
110 annotations.append(annotation)
111
112 if annotations.count == count {
113 break
114 }
115 }
116 }
117
118 DispatchQueue.main.async {
119 self.nbMapView.addAnnotations(annotations)
120 self.nbMapView.showAnnotations(annotations, animated: true)
121 }
122 }
123 }
124 }
125
126 }
127
128 func animateAnnotations () {
129 let annot = NGLPointAnnotation()
130 annot.coordinate = self.nbMapView.centerCoordinate
131 self.nbMapView.addAnnotation(annot)
132
133 let point = CGPoint(x: self.view.frame.origin.x + 200, y: self.view.frame.midY)
134 let coord = self.nbMapView.convert(point, toCoordinateFrom: self.view)
135
136 DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
137 UIView.animate(withDuration: 1) {
138 annot.coordinate = coord
139 }
140 }
141
142 }
143
144 func queryVisibleAnnotations() {
145 let visibleAnnotationCount = NSNumber(value: self.nbMapView.visibleAnnotations?.count ?? 0)
146 var message: String
147
148 if visibleAnnotationCount.intValue == 1 {
149 message = "There is \(visibleAnnotationCount) visible annotation."
150 } else {
151 message = "There are \(visibleAnnotationCount) visible annotations."
152 }
153
154 let alertController = UIAlertController(title: "Visible Annotations", message: message, preferredStyle: .alert)
155 alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
156 self.present(alertController, animated: true, completion: nil)
157
158 }
159
160 func centerSelectedAnnotation() {
161
162 if let annotation = self.nbMapView.selectedAnnotations.first {
163 let point = self.nbMapView.convert(annotation.coordinate, toPointTo: self.nbMapView)
164 let center = self.nbMapView.convert(point, toCoordinateFrom: self.nbMapView)
165 self.nbMapView.setCenter(center, animated: true)
166 }
167 }
168
169 func addVisibleAreaPolyline() {
170 let constrainedRect = self.nbMapView.bounds.inset(by: self.nbMapView.contentInset)
171
172 var lineCoords = [CLLocationCoordinate2D]()
173
174 lineCoords.append(self.nbMapView.convert(CGPoint(x: constrainedRect.minX, y: constrainedRect.minY), toCoordinateFrom: self.nbMapView))
175 lineCoords.append(self.nbMapView.convert(CGPoint(x: constrainedRect.maxX, y: constrainedRect.minY), toCoordinateFrom: self.nbMapView))
176 lineCoords.append(self.nbMapView.convert(CGPoint(x: constrainedRect.maxX, y: constrainedRect.maxY), toCoordinateFrom: self.nbMapView))
177 lineCoords.append(self.nbMapView.convert(CGPoint(x: constrainedRect.minX, y: constrainedRect.maxY), toCoordinateFrom: self.nbMapView))
178 lineCoords.append(lineCoords[0])
179
180 let line = NGLPolyline(coordinates: &lineCoords, count: UInt(lineCoords.count))
181 self.nbMapView.addAnnotation(line)
182
183 }
184
185
186}
187
188
189extension AnnotationsViewController: NGLMapViewDelegate {
190 func mapView(_ mapView: NGLMapView, didFinishLoading style: NGLStyle){
191 nbMapView.setCenter(CLLocationCoordinate2DMake(38.87031006108791, -77.00896639534831), zoomLevel: 10, animated: true)
192
193 }
194
195 func mapView(_ mapView: NGLMapView, didSelect annotation: NGLAnnotation) {
196 let point = self.nbMapView.convert(annotation.coordinate, toPointTo: self.nbMapView)
197 let center = self.nbMapView.convert(point, toCoordinateFrom: self.nbMapView)
198 self.nbMapView.setCenter(center, zoomLevel: 14, animated: true)
199 }
200
201 func mapView(_ mapView: NGLMapView, annotationCanShowCallout annotation: NGLAnnotation) -> Bool {
202 return true
203 }
204}
205
206extension AnnotationsViewController: UITableViewDelegate, UITableViewDataSource {
207
208 func settingsTitlesForRaw(index: Int) -> String {
209 let type = typeList[index]
210 switch type {
211 case AnnotationActionType.AddAnnotations :
212 return "Add 100 Annotations"
213 case AnnotationActionType.AddNumberAnnotations :
214 return "Add 1000 Annotations"
215 case AnnotationActionType.AnimateAnnotations :
216 return "Animate Annotations"
217 case AnnotationActionType.QueryVisibleAnnotations :
218 return "Query Visible Annotations"
219 case AnnotationActionType.CenterSelectedAnnotations :
220 return "Center Selected Annotations"
221 case AnnotationActionType.AddVisibleAreaPolyline :
222 return "Add Visible Area Polyline"
223 }
224 }
225 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
226 return typeList.count
227 }
228
229 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
230 let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
231 cell.textLabel?.text = settingsTitlesForRaw(index: indexPath.row)
232 return cell
233 }
234
235 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
236 tableView.isHidden = true
237 let type = typeList[indexPath.row]
238 dismissSettings(type: type)
239 }
240
241 func dismissSettings(type: AnnotationActionType) {
242 dismiss(animated: true)
243 performeSettings(type: type)
244 }
245}
-
Initializing nbMapView:
-
The nbMapView is initialized with a frame that matches the bounds of the view controller's view.
-
The mapView is added as a subview of the view controller's view and set as the delegate of the map view.
-
-
addAnnotations:
-
Removes any existing annotations from the map view.
-
Asynchronously loads a GeoJSON file named "points.geojson" from the main bundle.
-
Parses the GeoJSON data and extracts the coordinates and title for each feature.
-
Creates NGLPointAnnotation objects for each feature and adds them to an array.
-
Adds the annotations to the map view and shows them with an animated effect.
-
3 queryVisibleAnnotations:
-
Retrieves the count of visible annotations on the map view using nbMapView.visibleAnnotations.
-
Displays an alert controller with a message indicating the number of visible annotations.
-
centerSelectedAnnotation:
-
Checks if there is a selected annotation on the map view using nbMapView.selectedAnnotations.
-
Converts the coordinate of the selected annotation to a point on the map view.
-
Converts the point to a coordinate on the map view.
-
Sets the map view's center coordinate to the new coordinate with an animated effect using nbMapView.setCenter(center, animated: true).
-
4 addVisibleAreaPolyline:
-
Creates a rectangle (constrainedRect) that represents the visible area of the map view.
-
Converts the four corners of the rectangle to coordinates on the map view.
-
Creates an NGLPolyline with the converted coordinates and adds it as an annotation to the map view.