Loading...
Searching...
No Matches
LocationWindowCameraExample.swift
Go to the documentation of this file.
1import Foundation
2import NavigineSDK
3
4/**
5 * LocationWindowCamera usage example for Swift
6 * Demonstrates specific methods: getCamera, setCamera, addCameraListener, removeCameraListener,
7 * flyTo, moveTo, zoomFactor, minZoomFactor, maxZoomFactor
8 */
9class LocationWindowCameraExample {
10 private var locationWindow: NCLocationWindow?
11 private var cameraListener: CameraListenerImpl?
12
13 init() {
14 demonstrateLocationWindowCameraMethods()
15 }
16
17 /**
18 * Demonstrate LocationWindowCamera methods
19 */
20 private func demonstrateLocationWindowCameraMethods() {
21 print("=== LocationWindowCamera Methods ===")
22
23 demonstrateCameraProperties()
24 demonstrateGetSetCamera()
25 demonstrateCameraListeners()
26 demonstrateFlyToMethod()
27 demonstrateMoveToMethod()
28 demonstrateZoomProperties()
29 demonstrateCameraScenarios()
30 }
31
32 /**
33 * Demonstrate camera properties setup
34 */
35 private func demonstrateCameraProperties() {
36 print("--- Camera Properties Setup ---")
37
38 guard let locationWindow = locationWindow else {
39 print("LocationWindow not available yet")
40 return
41 }
42
43 // [swift_LocationWindow_minZoomFactor]
44 // Set minimum zoom factor
45 locationWindow.minZoomFactor = 10.0
46 print("Set minimum zoom factor to 10.0 pixels per meter")
47 // [swift_LocationWindow_minZoomFactor]
48
49 // [swift_LocationWindow_maxZoomFactor]
50 // Set maximum zoom factor
51 locationWindow.maxZoomFactor = 1000.0
52 print("Set maximum zoom factor to 1000.0 pixels per meter")
53 // [swift_LocationWindow_maxZoomFactor]
54 }
55
56 /**
57 * Demonstrate getCamera and setCamera methods
58 */
59 private func demonstrateGetSetCamera() {
60 print("--- getCamera and setCamera Methods ---")
61
62 guard let locationWindow = locationWindow else {
63 print("LocationWindow not available yet")
64 return
65 }
66
67 // [swift_LocationWindow_getCamera]
68 // Get current camera position
69 let currentCamera = locationWindow.camera
70 print("Current camera position:")
71 print(" Point: (\‍(currentCamera.point.x), \‍(currentCamera.point.y))")
72 print(" Zoom: \‍(currentCamera.zoom)")
73 print(" Rotation: \‍(currentCamera.rotation)°")
74 print(" Tilt: \‍(currentCamera.tilt)° (0° = straight downward / map from above)")
75 // [swift_LocationWindow_getCamera]
76
77 // [swift_Camera_constructor]
78 // Create camera with constructor
79 let newPoint = NCPoint(x: 100.0, y: 200.0)
80 let newCamera = NCCamera(point: newPoint, zoom: 50.0, rotation: 0.0, tilt: 0.0)
81 print("Created camera with point (\‍(newPoint.x), \‍(newPoint.y)), zoom 50.0, rotation 0°, tilt 0°")
82 // [swift_Camera_constructor]
83
84 // [swift_Camera_access]
85 // Access camera properties
86 print("Camera properties:")
87 print(" Point: (\‍(newCamera.point.x), \‍(newCamera.point.y))")
88 print(" Zoom: \‍(newCamera.zoom)")
89 print(" Rotation: \‍(newCamera.rotation)°")
90 print(" Tilt: \‍(newCamera.tilt)°")
91 // [swift_Camera_access]
92
93 // [swift_LocationWindow_setCamera]
94 // Set camera position without animation
95 locationWindow.camera = newCamera
96 print("Set camera position to (\‍(newPoint.x), \‍(newPoint.y)) with zoom 50.0, rotation 0°, tilt 0°")
97 // [swift_LocationWindow_setCamera]
98
99 // [swift_LocationWindow_setCamera_2]
100 // Set camera position with rotation
101 let rotatedPoint = NCPoint(x: 150.0, y: 250.0)
102 let rotatedCamera = NCCamera(point: rotatedPoint, zoom: 75.0, rotation: 45.0, tilt: 0.0)
103 locationWindow.camera = rotatedCamera
104 print("Set camera position to (\‍(rotatedPoint.x), \‍(rotatedPoint.y)) with zoom 75.0 and rotation 45°")
105 // [swift_LocationWindow_setCamera_2]
106
107 let tiltedCamera = NCCamera(point: rotatedPoint, zoom: 75.0, rotation: 45.0, tilt: 40.0)
108 locationWindow.camera = tiltedCamera
109 print("Set camera with tilt \‍(tiltedCamera.tilt)° for a perspective view")
110
111 // Test different camera positions
112 let testCameras = [
113 NCCamera(point: NCPoint(x: 0.0, y: 0.0), zoom: 10.0, rotation: 0.0, tilt: 0.0), // Overview camera
114 NCCamera(point: NCPoint(x: 50.0, y: 75.0), zoom: 500.0, rotation: 0.0, tilt: 0.0), // Detail camera
115 NCCamera(point: NCPoint(x: 100.0, y: 150.0), zoom: 100.0, rotation: 30.0, tilt: 0.0), // Angled camera
116 ]
117
118 for (i, camera) in testCameras.enumerated() {
119 locationWindow.camera = camera
120 print("Test camera \‍(i): Point (\‍(camera.point.x), \‍(camera.point.y)), Zoom \‍(camera.zoom), Rotation \‍(camera.rotation)°, Tilt \‍(camera.tilt)°")
121 }
122 }
123
124 /**
125 * Demonstrate camera listener methods
126 */
127 private func demonstrateCameraListeners() {
128 print("--- Camera Listener Methods ---")
129
130 guard let locationWindow = locationWindow else {
131 print("LocationWindow not available yet")
132 return
133 }
134
135 // [swift_LocationWindow_addCameraListener]
136 // Add camera listener
137 cameraListener = CameraListenerImpl()
138 locationWindow.addCameraListener(cameraListener!)
139 print("Added camera listener")
140 // [swift_LocationWindow_addCameraListener]
141
142 // [swift_LocationWindow_removeCameraListener]
143 // Remove camera listener
144 locationWindow.removeCameraListener(cameraListener!)
145 cameraListener = nil
146 print("Removed camera listener")
147 // [swift_LocationWindow_removeCameraListener]
148
149 // Test multiple listeners
150 let listeners = [
151 CameraListenerImpl(),
152 CameraListenerImpl(),
153 CameraListenerImpl(),
154 ]
155
156 for (i, listener) in listeners.enumerated() {
157 locationWindow.addCameraListener(listener)
158 print("Added camera listener \‍(i)")
159 }
160
161 for (i, listener) in listeners.enumerated() {
162 locationWindow.removeCameraListener(listener)
163 print("Removed camera listener \‍(i)")
164 }
165 }
166
167 /**
168 * Demonstrate flyTo method
169 */
170 private func demonstrateFlyToMethod() {
171 print("--- flyTo Method ---")
172
173 guard let locationWindow = locationWindow else {
174 print("LocationWindow not available yet")
175 return
176 }
177
178 // [swift_LocationWindow_flyTo]
179 // Fly to position with smooth animation
180 let targetPoint = NCPoint(x: 150.0, y: 250.0)
181 let targetCamera = NCCamera(point: targetPoint, zoom: 75.0, rotation: 45.0, tilt: 30.0)
182 let callback = CameraCallbackImpl()
183 locationWindow.flyTo(camera: targetCamera, duration: 2000, callback: callback)
184 print("Started fly to animation to point (\‍(targetPoint.x), \‍(targetPoint.y))")
185 // [swift_LocationWindow_flyTo]
186
187 // [swift_LocationWindow_flyTo_2]
188 // Fly to another position with different duration
189 let targetPoint2 = NCPoint(x: 300.0, y: 400.0)
190 let targetCamera2 = NCCamera(point: targetPoint2, zoom: 25.0, rotation: 180.0, tilt: 0.0)
191 let callback2 = CameraCallbackImpl()
192 locationWindow.flyTo(camera: targetCamera2, duration: 3000, callback: callback2)
193 print("Started fly to animation to point (\‍(targetPoint2.x), \‍(targetPoint2.y)) with 3 second duration")
194 // [swift_LocationWindow_flyTo_2]
195
196 // Test fly to with different parameters
197 let flyToTests = [
198 ["point": NCPoint(x: 50.0, y: 50.0), "zoom": 100.0, "rotation": 0.0, "duration": 1000],
199 ["point": NCPoint(x: 200.0, y: 300.0), "zoom": 200.0, "rotation": 90.0, "duration": 1500],
200 ["point": NCPoint(x: 400.0, y: 100.0), "zoom": 50.0, "rotation": 270.0, "duration": 2500],
201 ]
202
203 for (i, test) in flyToTests.enumerated() {
204 let point = test["point"] as! NCPoint
205 let zoom = test["zoom"] as! Double
206 let rotation = test["rotation"] as! Double
207 let duration = test["duration"] as! Int
208
209 let camera = NCCamera(point: point, zoom: zoom, rotation: rotation, tilt: 0.0)
210 let testCallback = CameraCallbackImpl()
211 locationWindow.flyTo(camera: camera, duration: duration, callback: testCallback)
212 print("Fly to test \‍(i): Point (\‍(point.x), \‍(point.y)), Zoom \‍(zoom), Rotation \‍(rotation)°, Duration \‍(duration)ms")
213 }
214 }
215
216 /**
217 * Demonstrate moveTo method
218 */
219 private func demonstrateMoveToMethod() {
220 print("--- moveTo Method ---")
221
222 guard let locationWindow = locationWindow else {
223 print("LocationWindow not available yet")
224 return
225 }
226
227 // [swift_LocationWindow_moveTo]
228 // Move to position with linear animation
229 let targetPoint = NCPoint(x: 200.0, y: 300.0)
230 let targetCamera = NCCamera(point: targetPoint, zoom: 100.0, rotation: 90.0, tilt: 0.0)
231 let callback = CameraCallbackImpl()
232 locationWindow.moveTo(camera: targetCamera, duration: 1500, animationType: .linear, callback: callback)
233 print("Started move to with linear animation")
234 // [swift_LocationWindow_moveTo]
235
236 // [swift_LocationWindow_moveTo_2]
237 // Move to position with cubic animation
238 let callback2 = CameraCallbackImpl()
239 locationWindow.moveTo(camera: targetCamera, duration: 1500, animationType: .cubic, callback: callback2)
240 print("Started move to with cubic animation")
241 // [swift_LocationWindow_moveTo_2]
242
243 // [swift_LocationWindow_moveTo_3]
244 // Move to position with sine animation
245 let callback3 = CameraCallbackImpl()
246 locationWindow.moveTo(camera: targetCamera, duration: 1500, animationType: .sine, callback: callback3)
247 print("Started move to with sine animation")
248 // [swift_LocationWindow_moveTo_3]
249
250 // [swift_LocationWindow_moveTo_4]
251 // Move to position without animation
252 let instantPoint = NCPoint(x: 300.0, y: 400.0)
253 let instantCamera = NCCamera(point: instantPoint, zoom: 25.0, rotation: 180.0, tilt: 0.0)
254 let instantCallback = CameraCallbackImpl()
255 locationWindow.moveTo(camera: instantCamera, duration: 0, animationType: .none, callback: instantCallback)
256 print("Executed instant move to position (\‍(instantPoint.x), \‍(instantPoint.y))")
257 // [swift_LocationWindow_moveTo_4]
258
259 // Test move to with different animation types
260 // [swift_AnimationType_enum]
261 let animationTypes: [NCAnimationType] = [
262 .linear,
263 .cubic,
264 .quint,
265 .sine,
266 .none,
267 ]
268 // [swift_AnimationType_enum]
269
270 for (i, animationType) in animationTypes.enumerated() {
271 let testPoint = NCPoint(x: 100.0 + Double(i) * 50.0, y: 200.0 + Double(i) * 50.0)
272 let testCamera = NCCamera(point: testPoint, zoom: 50.0 + Double(i) * 10.0, rotation: Double(i) * 30.0, tilt: 0.0)
273 let testCallback = CameraCallbackImpl()
274 locationWindow.moveTo(camera: testCamera, duration: 1000, animationType: animationType, callback: testCallback)
275 print("Move to test \‍(i): Animation \‍(animationType), Point (\‍(testPoint.x), \‍(testPoint.y))")
276 }
277 }
278
279 /**
280 * Demonstrate zoom properties
281 */
282 private func demonstrateZoomProperties() {
283 print("--- Zoom Properties ---")
284
285 guard let locationWindow = locationWindow else {
286 print("LocationWindow not available yet")
287 return
288 }
289
290 // [swift_LocationWindow_getZoomFactor]
291 // Get current zoom factor
292 let currentZoom = locationWindow.zoomFactor
293 print("Current zoom factor: \‍(currentZoom) pixels per meter")
294 // [swift_LocationWindow_getZoomFactor]
295
296 // [swift_LocationWindow_setZoomFactor]
297 // Set new zoom factor
298 locationWindow.zoomFactor = 200.0
299 print("Set zoom factor to 200.0 pixels per meter")
300 // [swift_LocationWindow_setZoomFactor]
301
302 // [swift_LocationWindow_getMinZoomFactor]
303 // Get minimum zoom factor
304 let minZoom = locationWindow.minZoomFactor
305 print("Minimum zoom factor: \‍(minZoom) pixels per meter")
306 // [swift_LocationWindow_getMinZoomFactor]
307
308 // [swift_LocationWindow_getMaxZoomFactor]
309 // Get maximum zoom factor
310 let maxZoom = locationWindow.maxZoomFactor
311 print("Maximum zoom factor: \‍(maxZoom) pixels per meter")
312 // [swift_LocationWindow_getMaxZoomFactor]
313
314 // Test zoom factor changes
315 let zoomLevels: [Double] = [50.0, 100.0, 150.0, 300.0, 500.0, 800.0]
316
317 for zoom in zoomLevels {
318 locationWindow.zoomFactor = zoom
319 print("Set zoom factor to \‍(zoom) pixels per meter")
320
321 // Verify the change
322 let actualZoom = locationWindow.zoomFactor
323 print("Actual zoom factor: \‍(actualZoom) pixels per meter")
324 }
325 }
326
327 /**
328 * Demonstrate camera scenarios
329 */
330 private func demonstrateCameraScenarios() {
331 print("--- Camera Scenarios ---")
332
333 guard let locationWindow = locationWindow else {
334 print("LocationWindow not available yet")
335 return
336 }
337
338 // [swift_LocationWindow_camera_scenarios]
339 // Create cameras for different scenarios
340 let overviewCamera = NCCamera(point: NCPoint(x: 0.0, y: 0.0), zoom: 10.0, rotation: 0.0, tilt: 0.0)
341 let detailCamera = NCCamera(point: NCPoint(x: 50.0, y: 75.0), zoom: 500.0, rotation: 0.0, tilt: 0.0)
342 let angledCamera = NCCamera(point: NCPoint(x: 100.0, y: 150.0), zoom: 100.0, rotation: 30.0, tilt: 25.0)
343
344 print("Created cameras for different scenarios:")
345 print(" Overview camera: zoom \‍(overviewCamera.zoom)")
346 print(" Detail camera: zoom \‍(detailCamera.zoom)")
347 print(" Angled camera: rotation \‍(angledCamera.rotation)°, tilt \‍(angledCamera.tilt)°")
348 // [swift_LocationWindow_camera_scenarios]
349
350 // Test scenario transitions
351 let scenarios = [overviewCamera, detailCamera, angledCamera]
352 let scenarioNames = ["Overview", "Detail", "Angled"]
353
354 for (i, scenario) in scenarios.enumerated() {
355 let name = scenarioNames[i]
356 let scenarioCallback = CameraCallbackImpl()
357 locationWindow.moveTo(camera: scenario, duration: 2000, animationType: .cubic, callback: scenarioCallback)
358 print("Transitioning to \‍(name) scenario")
359 }
360 }
361
362 /**
363 * Cleanup resources
364 */
365 func cleanup() {
366 if let cameraListener = cameraListener, let locationWindow = locationWindow {
367 locationWindow.removeCameraListener(cameraListener)
368 self.cameraListener = nil
369 print("Camera listener removed")
370 }
371 }
372}
373
374/**
375 * Camera listener implementation
376 */
377class CameraListenerImpl: NSObject, NCCameraListener {
378 // [swift_CameraListener_onCameraPositionChanged]
379 func onCameraPositionChanged(reason: NCCameraUpdateReason, finished: Bool) {
380 let reasonText = (reason == .gestures) ? "user gestures" : "application"
381 let statusText = finished ? "finished" : "in progress"
382
383 print("Camera position changed: \‍(reasonText), status: \‍(statusText)")
384
385 if finished {
386 print("Camera movement completed")
387 }
388 }
389 // [swift_CameraListener_onCameraPositionChanged]
390}
391
392/**
393 * Camera callback implementation
394 */
395class CameraCallbackImpl: NSObject, NCCameraCallback {
396 // [swift_CameraCallback_onMoveFinished]
397 func onMoveFinished(completed: Bool) {
398 if completed {
399 print("Camera movement completed successfully")
400 } else {
401 print("Camera movement was cancelled")
402 }
403 }
404 // [swift_CameraCallback_onMoveFinished]
405}
406
407/**
408 * Camera utilities
409 */
410class CameraUtils {
411 /**
412 * Create camera for centered point with given zoom
413 */
414 static func createCenteredCamera(x: Double, y: Double, zoom: Double) -> NCCamera {
415 let point = NCPoint(x: x, y: y)
416 return NCCamera(point: point, zoom: zoom, rotation: 0.0, tilt: 0.0)
417 }
418
419 /**
420 * Create camera with rotation
421 */
422 static func createRotatedCamera(x: Double, y: Double, zoom: Double, rotation: Double) -> NCCamera {
423 let point = NCPoint(x: x, y: y)
424 return NCCamera(point: point, zoom: zoom, rotation: rotation, tilt: 0.0)
425 }
426
427 /** Camera tilt in degrees (see `NCCamera.tilt`). */
428 static func createTiltedCamera(x: Double, y: Double, zoom: Double, rotation: Double, tilt: Double) -> NCCamera {
429 let point = NCPoint(x: x, y: y)
430 return NCCamera(point: point, zoom: zoom, rotation: rotation, tilt: tilt)
431 }
432
433 /**
434 * Validate camera position
435 */
436 static func isValidCamera(_ camera: NCCamera) -> Bool {
437 return camera.zoom > 0 &&
438 camera.rotation >= 0 && camera.rotation < 360 &&
439 camera.tilt >= 0
440 }
441
442 /**
443 * Create camera for showing area
444 */
445 static func createAreaCamera(centerX: Double, centerY: Double, width: Double, height: Double) -> NCCamera {
446 // Calculate zoom based on area size
447 let zoom = 100.0 / max(width, height)
448 let point = NCPoint(x: centerX, y: centerY)
449 return NCCamera(point: point, zoom: zoom, rotation: 0.0, tilt: 0.0)
450 }
451
452 /**
453 * Create camera for showing path
454 */
455 static func createPathCamera(points: [NCPoint]) -> NCCamera {
456 if points.isEmpty {
457 let point = NCPoint(x: 0.0, y: 0.0)
458 return NCCamera(point: point, zoom: 100.0, rotation: 0.0, tilt: 0.0)
459 }
460
461 // Find path center
462 let centerX = points.map { $0.x }.reduce(0, +) / Double(points.count)
463 let centerY = points.map { $0.y }.reduce(0, +) / Double(points.count)
464
465 // Calculate area size
466 let minX = points.map { $0.x }.min()!
467 let minY = points.map { $0.y }.min()!
468 let maxX = points.map { $0.x }.max()!
469 let maxY = points.map { $0.y }.max()!
470
471 let width = maxX - minX
472 let height = maxY - minY
473
474 return createAreaCamera(centerX: centerX, centerY: centerY, width: width, height: height)
475 }
476
477 /**
478 * Create camera for showing multiple points
479 */
480 static func createMultiPointCamera(points: [NCPoint], padding: Double = 10.0) -> NCCamera {
481 if points.isEmpty {
482 let point = NCPoint(x: 0.0, y: 0.0)
483 return NCCamera(point: point, zoom: 100.0, rotation: 0.0, tilt: 0.0)
484 }
485
486 // Find center
487 let centerX = points.map { $0.x }.reduce(0, +) / Double(points.count)
488 let centerY = points.map { $0.y }.reduce(0, +) / Double(points.count)
489
490 // Calculate area size with padding
491 let minX = points.map { $0.x }.min()! - padding
492 let minY = points.map { $0.y }.min()! - padding
493 let maxX = points.map { $0.x }.max()! + padding
494 let maxY = points.map { $0.y }.max()! + padding
495
496 let width = maxX - minX
497 let height = maxY - minY
498
499 return createAreaCamera(centerX: centerX, centerY: centerY, width: width, height: height)
500 }
501}
502
503/**
504 * Extensions for convenient camera operations
505 */
506extension NCLocationWindow {
507 /**
508 * Zoom to point
509 */
510 func zoomTo(point: NCPoint, zoom: Double, duration: Int = 1000) {
511 let currentCamera = camera
512 let nextCamera = NCCamera(
513 point: point,
514 zoom: zoom,
515 rotation: currentCamera.rotation,
516 tilt: currentCamera.tilt)
517 let callback = CameraCallbackImpl()
518 moveTo(camera: nextCamera, duration: duration, animationType: .cubic, callback: callback)
519 }
520
521 /**
522 * Pan to point
523 */
524 func panTo(point: NCPoint, duration: Int = 1000) {
525 let currentCamera = camera
526 let newCamera = NCCamera(point: point, zoom: currentCamera.zoom, rotation: currentCamera.rotation, tilt: currentCamera.tilt)
527 let callback = CameraCallbackImpl()
528 moveTo(camera: newCamera, duration: duration, animationType: .linear, callback: callback)
529 }
530
531 /**
532 * Rotate camera
533 */
534 func rotateTo(rotation: Double, duration: Int = 1000) {
535 let currentCamera = camera
536 let newCamera = NCCamera(point: currentCamera.point, zoom: currentCamera.zoom, rotation: rotation, tilt: currentCamera.tilt)
537 let callback = CameraCallbackImpl()
538 moveTo(camera: newCamera, duration: duration, animationType: .sine, callback: callback)
539 }
540
541 /**
542 * Fly to point with automatic zoom
543 */
544 func flyToPoint(point: NCPoint, duration: Int = 2000) {
545 let currentCamera = camera
546 let distance = sqrt(pow(point.x - currentCamera.point.x, 2) + pow(point.y - currentCamera.point.y, 2))
547 let newZoom = max(currentCamera.zoom * 0.8, min(currentCamera.zoom * 1.2, 100.0 / distance))
548
549 let targetCamera = NCCamera(point: point, zoom: newZoom, rotation: currentCamera.rotation, tilt: currentCamera.tilt)
550 let callback = CameraCallbackImpl()
551 flyTo(camera: targetCamera, duration: duration, callback: callback)
552 }
553}
554
555/**
556 * Usage example
557 */
558func main() {
559 // Create example instance
560 let example = LocationWindowCameraExample()
561
562 // Assume we have NCLocationWindow
563 // let locationWindow: NCLocationWindow = getLocationWindow()
564 // example.locationWindow = locationWindow
565
566 // Demonstrate methods
567 print("=== LocationWindowCamera Examples ===")
568
569 // Cleanup
570 example.cleanup()
571
572 print("Examples ready to use!")
573}
574
575// Run example
576main()