• Optimization
  • Navigation
  • Tracking
  • Maps
  • Places

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

For all code examples, refer to Maps Code Examples

AddMapStyleLayerViewController view source

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

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.