Skip to content

Commit 16b4132

Browse files
maiosOdNairy
authored andcommitted
[ios][example] Edit a polygon by dragging/dropping (#2949)
This PR adds example showcasing how to edit a polygon (using FillLayer) by dragging/dropping --------- Co-authored-by: Roman Gardukevich <[email protected]> GitOrigin-RevId: 2d614f9180dd0eafdd2d643b15912fd7a1db40fe
1 parent 7ec31cc commit 16b4132

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

Examples.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
38AD95B6DD9BE858F4E59C31 /* WeatherAnnotationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91D21963A6FF5DA26A210DA5 /* WeatherAnnotationExample.swift */; };
4141
38DF3926AD9DDDE883454F64 /* TestableExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CB74046A2FC03770B62B9E6 /* TestableExampleTests.swift */; platformFilter = ios; };
4242
392857DBD1231B0438144335 /* AnimatedMarkerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = D44C0F343A1B5F4DA0C19B9C /* AnimatedMarkerExample.swift */; platformFilter = ios; };
43+
3A3EF2822D92E6BB00FA88D7 /* EditPolygonExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3EF2812D92E6BB00FA88D7 /* EditPolygonExample.swift */; };
4344
3B4862E6832F23CB115D444A /* ClipLayerExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63A3027A7DA59E090DAD25F1 /* ClipLayerExample.swift */; };
4445
3E515D1DD1D9CA02F3E95AA2 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D03F5A3A0E879717BFE421 /* Constants.swift */; };
4546
3FD83483E0AE57790504CB0C /* MapRecorderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E612275E3042D0D0AF8B583E /* MapRecorderExample.swift */; platformFilter = ios; };
@@ -212,6 +213,7 @@
212213
370DFCA52EB6C7F119BF81DA /* MapEventsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapEventsExample.swift; sourceTree = "<group>"; };
213214
384FD8FC97B9F5011AF4BD61 /* GlobeFlyToExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobeFlyToExample.swift; sourceTree = "<group>"; };
214215
388932B3A65BB7E9B59FDBE0 /* InteractionsPlayground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractionsPlayground.swift; sourceTree = "<group>"; };
216+
3A3EF2812D92E6BB00FA88D7 /* EditPolygonExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditPolygonExample.swift; sourceTree = "<group>"; };
215217
3BCB1CC4577300FEF4DE017B /* InsetMapExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsetMapExample.swift; sourceTree = "<group>"; };
216218
3BDE7738CA55957F3FAC3ECE /* LineAnnotationExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineAnnotationExample.swift; sourceTree = "<group>"; };
217219
3E2F68B22AFF73A71F86CABC /* ExamplesUITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ExamplesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -527,6 +529,7 @@
527529
ACB753539ABAD3312B849CB1 /* All Examples */ = {
528530
isa = PBXGroup;
529531
children = (
532+
3A3EF2812D92E6BB00FA88D7 /* EditPolygonExample.swift */,
530533
3FB717239BBFE5103C1EB1A4 /* AdvancedViewportGesturesExample.swift */,
531534
7274E152F7FBB7894447F822 /* AnimateGeoJSONLineExample.swift */,
532535
A471857797898860C3A8F685 /* AnimateImageLayerExample.swift */,
@@ -838,6 +841,7 @@
838841
isa = PBXSourcesBuildPhase;
839842
buildActionMask = 2147483647;
840843
files = (
844+
3A3EF2822D92E6BB00FA88D7 /* EditPolygonExample.swift in Sources */,
841845
05DF15DADC248A2CAA5EEDC4 /* AddMarkersSymbolExample.swift in Sources */,
842846
2C03342240D5487880316518 /* AddOneMarkerSymbolExample.swift in Sources */,
843847
10C2E5ADC16B91D43288E820 /* AdvancedViewportGesturesExample.swift in Sources */,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import UIKit
2+
import MapboxMaps
3+
4+
final class EditPolygonExample: UIViewController, ExampleProtocol {
5+
private enum ID {
6+
static let polygonLayer = "editable-polygon-layer-id"
7+
static let geoJsonSource = "editable-geojson-source"
8+
}
9+
10+
private var mapView: MapView!
11+
private var cancelables: Set<AnyCancelable> = []
12+
13+
private lazy var circleAnnotationsManager = mapView.annotations.makeCircleAnnotationManager()
14+
15+
override func viewDidLoad() {
16+
super.viewDidLoad()
17+
18+
let cameraOptions = CameraOptions(
19+
center: .helsinki,
20+
zoom: 3,
21+
bearing: 12)
22+
let options = MapInitOptions(cameraOptions: cameraOptions)
23+
mapView = MapView(frame: view.bounds, mapInitOptions: options)
24+
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
25+
26+
view.addSubview(mapView)
27+
28+
mapView.gestures.onMapTap.observe { [weak self] context in
29+
self?.dropPin(at: context.coordinate)
30+
}.store(in: &cancelables)
31+
32+
mapView.mapboxMap.onStyleLoaded.observeNext { [weak self] _ in
33+
self?.dropPin(at: .helsinki)
34+
self?.dropPin(at: .kyiv)
35+
self?.dropPin(at: .berlin)
36+
}.store(in: &cancelables)
37+
}
38+
39+
override func viewDidAppear(_ animated: Bool) {
40+
super.viewDidAppear(animated)
41+
// The below line is used for internal testing purposes only.
42+
finish()
43+
}
44+
45+
private func dropPin(at coordinate: CLLocationCoordinate2D) {
46+
var newAnnotation = CircleAnnotation(centerCoordinate: coordinate)
47+
.circleColor(.random)
48+
.circleRadius(10)
49+
newAnnotation.isDraggable = true
50+
51+
newAnnotation.dragBeginHandler = { (annotation, _) in
52+
annotation.circleRadius = 15
53+
return true
54+
}
55+
newAnnotation.dragChangeHandler = { [weak self] (_, _) in
56+
self?.addOrEditPolygon()
57+
}
58+
newAnnotation.dragEndHandler = { (annotation, _) in
59+
annotation.circleRadius = 10
60+
}
61+
62+
circleAnnotationsManager.annotations.append(newAnnotation)
63+
addOrEditPolygon()
64+
}
65+
66+
private func addOrEditPolygon() {
67+
if !circleAnnotationsManager.annotations.isEmpty {
68+
mapView.mapboxMap.setMapStyleContent {
69+
GeoJSONSource(id: ID.geoJsonSource)
70+
.data(.geometry(Polygon(outerRing: .init(coordinates: circleAnnotationsManager.annotations.map(\.point.coordinates))).geometry))
71+
FillLayer(id: ID.polygonLayer, source: ID.geoJsonSource)
72+
.fillColor(.blue)
73+
.fillOpacity(0.3)
74+
.fillOutlineColor(.black)
75+
}
76+
}
77+
}
78+
}

Sources/Examples/All Examples/LayerSlotExample.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import MapboxMaps
33

44
final class LayerSlotExample: UIViewController, ExampleProtocol {
55
private var mapView: MapView!
6-
private lazy var source = GeoJSONSource(id: "ploygon-geojson-source")
6+
private lazy var source = GeoJSONSource(id: "polygon-geojson-source")
77
private lazy var layer = FillLayer(id: "polygon-layer", source: source.id)
88
private var cancelables = Set<AnyCancelable>()
99

Sources/Examples/Models/Examples.swift

+3
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ struct Examples {
147147
Example(title: "Combine location",
148148
description: "Shows how to use Combine framework to drive the location puck.",
149149
type: CombineLocationExample.self)
150+
Example(title: "Edit polygon with drag/drop",
151+
description: "Shows how to update a polygon with drag",
152+
type: EditPolygonExample.self)
150153
}
151154

152155
// Examples that focus on displaying the user's location.

Sources/MapboxMaps/Foundation/MapboxMap.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1798,7 +1798,7 @@ extension MapboxMap {
17981798
eventType = .longClick
17991799
case "drag":
18001800
eventType = .drag
1801-
case "dragBeing":
1801+
case "dragBegin":
18021802
eventType = .dragBegin
18031803
case "dragEnd":
18041804
eventType = .dragEnd

0 commit comments

Comments
 (0)