Add Custom Style Layers

This example shows how to add customize style layer.

  • Query features in Rect

  • Add a list of features layer into map style

  • Add Multi Shape Layers source

    • Circle style layer

    • Line style layer

    • Fill style layer

docs-image

For all code examples, refer to Maps Code Examples

AddMapStyleLayerViewController view source

1
//
2
// AddMapStyleLayerViewController.swift
3
// maps-ios-demo
4
//
5
import Foundation
6
import UIKit
7
import Nbmap
8
enum AddActionType{
9
case AddQueryFeaturesLayer
10
case AddMultiShapeLayers
11
case UpdateMultiShapeLayers
12
}
13
class AddMapStyleLayerViewController: UIViewController {
14
15
var nbMapView: NGLMapView! {
16
didSet {
17
oldValue?.removeFromSuperview()
18
if let mapView = nbMapView {
19
view.insertSubview(mapView, at: 0)
20
mapView.delegate = self
21
}
22
}
23
}
24
var button: UIButton!
25
26
let typeList = [
27
AddActionType.AddQueryFeaturesLayer,
28
AddActionType.AddMultiShapeLayers,
29
AddActionType.UpdateMultiShapeLayers,
30
]
31
32
33
var points : Array = [CLLocationCoordinate2D]()
34
35
override func viewDidLoad() {
36
super.viewDidLoad()
37
nbMapView = NGLMapView(frame:self.view.bounds)
38
button = UIButton(type: .system)
39
button.setTitle("Settings", for: .normal)
40
button.addTarget(self, action: #selector(showSetings), for: .touchUpInside)
41
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
42
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
43
}
44
45
@objc func showSetings() {
46
let tableViewController = UITableViewController(style: .plain)
47
tableViewController.tableView.delegate = self
48
tableViewController.tableView.dataSource = self
49
tableViewController.title = "Camera Settings"
50
self.present(tableViewController, animated: true)
51
}
52
53
func performeSettings(type: AddActionType) {
54
switch type {
55
case AddActionType.AddQueryFeaturesLayer :
56
addQueryFeaturesLayer()
57
break
58
case AddActionType.AddMultiShapeLayers:
59
addMultiShapeLayers()
60
break
61
case AddActionType.UpdateMultiShapeLayers:
62
updateTheQueryFeaturesLayer()
63
break
64
}
65
66
}
67
68
func addQueryFeaturesLayer() {
69
let queryRect = self.nbMapView.bounds.insetBy(dx: 100, dy: 200)
70
let visibleFeatures = self.nbMapView.visibleFeatures(in: queryRect) as? [NGLShape & NGLFeature]
71
72
let querySourceID = "query-source-id"
73
let queryLayerID = "query-layer-id"
74
75
if let layer = self.nbMapView.style?.layer(withIdentifier: queryLayerID) {
76
self.nbMapView.style?.removeLayer(layer)
77
}
78
79
if let source = self.nbMapView.style?.source(withIdentifier: querySourceID) {
80
self.nbMapView.style?.removeSource(source)
81
}
82
83
DispatchQueue.main.async {
84
let shapeSource = NGLShapeSource(identifier: querySourceID, features: visibleFeatures!, options: nil)
85
self.nbMapView.style?.addSource(shapeSource)
86
87
let fillLayer = NGLFillStyleLayer(identifier: queryLayerID, source: shapeSource)
88
fillLayer.fillColor = NSExpression(forConstantValue: UIColor.blue)
89
fillLayer.fillOpacity = NSExpression(forConstantValue: 0.5)
90
self.nbMapView.style?.addLayer(fillLayer)
91
}
92
93
}
94
95
func updateTheQueryFeaturesLayer() {
96
let querySourceID = "query-source-id"
97
if let source = self.nbMapView.style?.source(withIdentifier: querySourceID) as? NGLShapeSource {
98
let queryRect = self.nbMapView.bounds.insetBy(dx: 50, dy: 100)
99
let visibleFeatures = self.nbMapView.visibleFeatures(in: queryRect) as? [NGLShape & NGLFeature]
100
let shapeSource = NGLShapeSource(identifier: querySourceID, features: visibleFeatures!, options: nil)
101
source.shape = shapeSource.shape
102
}
103
104
}
105
106
func addMultiShapeLayers() {
107
nbMapView.zoomLevel = 10
108
nbMapView.centerCoordinate = CLLocationCoordinate2D(latitude: 51.068585180672635, longitude: -114.06074523925781)
109
let leafCoords: [CLLocationCoordinate2D] = [
110
CLLocationCoordinate2D(latitude: 50.9683733218221, longitude: -114.07035827636719),
111
CLLocationCoordinate2D(latitude: 51.02325750523972, longitude: -114.06967163085938),
112
CLLocationCoordinate2D(latitude: 51.009434536947786, longitude: -114.14245605468749),
113
// ... Add the remaining coordinates here
114
]
115
let feature = NGLPolygonFeature(coordinates: leafCoords, count: UInt(leafCoords.count))
116
feature.identifier = "leaf-feature"
117
feature.attributes = ["color": "red"]
118
119
let source = NGLShapeSource(identifier: "leaf-source", shape: feature, options: nil)
120
if nbMapView.style?.source(withIdentifier: "leaf-source") == nil {
121
nbMapView.style?.addSource(source)
122
}
123
let layer = NGLFillStyleLayer(identifier: "leaf-fill-layer", source: source)
124
if let shapeLayer = self.nbMapView.style?.layer(withIdentifier: "leaf-fill-layer") {
125
self.nbMapView.style?.removeLayer(shapeLayer)
126
}
127
layer.predicate = NSPredicate(format: "color = 'red'")
128
layer.fillColor = NSExpression(forConstantValue: UIColor.red)
129
nbMapView.style?.addLayer(layer)
130
let geoJSON = "{\"type\": \"Feature\", \"properties\": {\"color\": \"green\"}, \"geometry\": { \"type\": \"Point\", \"coordinates\": [ -114.06847000122069, 51.050459433092655 ] }}"
131
let data = geoJSON.data(using: .utf8)!
132
let shape = try? NGLShape(data: data, encoding: String.Encoding.utf8.rawValue)
133
let pointSource = NGLShapeSource(identifier: "leaf-point-source", shape: shape, options: nil)
134
if self.nbMapView.style?.source(withIdentifier: "leaf-point-source") == nil {
135
nbMapView.style?.addSource(pointSource)
136
}
137
let circleLayer = NGLCircleStyleLayer(identifier: "leaf-circle-layer", source: pointSource)
138
if let shapeLayer = self.nbMapView.style?.layer(withIdentifier: "leaf-circle-layer") {
139
self.nbMapView.style?.removeLayer(shapeLayer)
140
}
141
circleLayer.circleColor = NSExpression(forConstantValue: UIColor.green)
142
circleLayer.predicate = NSPredicate(format: "color = 'green'")
143
circleLayer.circleRadius = NSExpression(forConstantValue: 10)
144
nbMapView.style?.addLayer(circleLayer)
145
let squareCoords: [CLLocationCoordinate2D] = [
146
CLLocationCoordinate2D(latitude: 51.056070541830934, longitude: -114.0274429321289),
147
CLLocationCoordinate2D(latitude: 51.07937094724242, longitude: -114.0274429321289),
148
CLLocationCoordinate2D(latitude: 50.9683733218221, longitude: -114.07035827636719)
149
// ... Add the remaining coordinates here
150
]
151
let polygon = NGLPolyline(coordinates: squareCoords, count: UInt(squareCoords.count))
152
let plainShapeSource = NGLShapeSource(identifier: "leaf-plain-shape-source", shape: polygon, options: nil)
153
if self.nbMapView.style?.source(withIdentifier: "leaf-plain-shape-source") == nil {
154
nbMapView.style?.addSource(plainShapeSource)
155
}
156
let plainLineLayer = NGLLineStyleLayer(identifier: "leaf-plain-fill-layer", source: plainShapeSource)
157
if let shapeLayer = self.nbMapView.style?.layer(withIdentifier: "leaf-plain-fill-layer") {
158
self.nbMapView.style?.removeLayer(shapeLayer)
159
}
160
plainLineLayer.lineColor = NSExpression(forConstantValue: UIColor.yellow)
161
plainLineLayer.lineWidth = NSExpression(forConstantValue: 6)
162
nbMapView.style?.addLayer(plainLineLayer)
163
}
164
165
}
166
extension AddMapStyleLayerViewController: NGLMapViewDelegate {
167
func mapView(_ mapView: NGLMapView, didFinishLoading style: NGLStyle){
168
nbMapView.setCenter(CLLocationCoordinate2DMake(12.97880156, 77.59656748), zoomLevel: 13, animated: true)
169
170
}
171
}
172
extension AddMapStyleLayerViewController: UITableViewDelegate, UITableViewDataSource {
173
174
func settingsTitlesForRaw(index: Int) -> String {
175
let type = typeList[index]
176
switch type {
177
case AddActionType.AddMultiShapeLayers :
178
return "Add Multi Shape Layers"
179
case AddActionType.AddQueryFeaturesLayer :
180
return "Add Query Features Layer"
181
case AddActionType.UpdateMultiShapeLayers :
182
return "Update Query Features Layer"
183
}
184
}
185
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
186
return typeList.count
187
}
188
189
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
190
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
191
cell.textLabel?.text = settingsTitlesForRaw(index: indexPath.row)
192
return cell
193
}
194
195
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
196
tableView.isHidden = true
197
let type = typeList[indexPath.row]
198
dismissSettings(type: type)
199
}
200
201
func dismissSettings(type: AddActionType) {
202
dismiss(animated: true)
203
performeSettings(type: type)
204
}
205
}

This code example defines a view controller (AddMapStyleLayerViewController) that manages a map view (NGLMapView) and provides functionality to add different types of map style layers. It includes methods for adding query features layers and multi-shape layers to the map view. The code uses various classes and protocols from the Nbmap framework to handle map-related operations and display map features.

  • Initializing the mapView:

    • The nbMapView property is declared as an NGLMapView.

    • In the viewDidLoad() method, the nbMapView is initialized with a frame equal to the bounds of the view.

    • The mapView is added as a subview to the view.

  • Adding Query Features Layer:

    • A query rectangle is defined based on the bounds of the nbMapView.

    • Visible features within the query rectangle are retrieved using the visibleFeatures(in:) method. The existing query source and layer are removed from the nbMapView style, if they exist.

    • A new NGLShapeSource is created with the visible features and added to the style. And a NGLFillStyleLayer is created with the NGLShapeSource and customized properties such as fill color and opacity.

    • The fill layer is added to the style.

  • Adding NGLPolygonFeature Layer:

    • An array of CLLocationCoordinate2D is created to define the leaf coordinates for a polygon feature.

    • A NGLPolygonFeature is created with the leaf coordinates and additional attributes.

    • A NGLShapeSource is created with the polygon feature and added to the style if it doesn't already exist. A NGLFillStyleLayer is created with the shape source, and properties such as fill color and predicate.

    • The fill layer is added to the style.

  • Adding GeoJson Source Layer

    • A GeoJSON string is defined to create a point feature, and a NGLShape is created from the GeoJSON data.

    • A NGLShapeSource is created with the shape and added to the style if it doesn't already exist.

    • A NGLCircleStyleLayer is created with the point source, and properties such as circle color and predicate.

    • The circle layer is added to the style.

  • Adding NGLPolyline feature layer

    • An array of CLLocationCoordinate2D is created to define the square coordinates for a polyline.

    • A NGLPolyline is created with the square coordinates.

    • A NGLShapeSource is created with the polyline and added to the style if it doesn't already exist.

    • A NGLLineStyleLayer is created with the plain shape source, and properties such as line color and width.

    • The line layer is added to the style.

© 2024 NextBillion.ai all rights reserved.