In this page

Add Custom Style Layers

This example shows how to add customize style layer.

  1. Query features in Rect

  2. Add a list of features layer into map style

  3. Add Multi Shape Layers source

    1. Circle style layer

    2. Line style layer

    3. Fill style layer

For all code examples, refer to Maps Code Examples

AddMapStyleLayerViewController view source

1//
2//  AddMapStyleLayerViewController.swift
3//  maps-ios-demo
4//
5import Foundation
6import UIKit
7import Nbmap
8enum AddActionType{
9    case AddQueryFeaturesLayer
10    case AddMultiShapeLayers
11    case UpdateMultiShapeLayers
12}
13class 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}
166extension 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}
172extension 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.

  1. Initializing the mapView:

    1. The nbMapView property is declared as an NGLMapView.

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

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

  2. Adding Query Features Layer:

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

    2. 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.

    3. 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.

    4. The fill layer is added to the style.

  3. Adding NGLPolygonFeature Layer:

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

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

    3. 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.

    4. The fill layer is added to the style.

  4. Adding GeoJson Source Layer

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

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

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

    4. The circle layer is added to the style.

  5. Adding NGLPolyline feature layer

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

    2. A NGLPolyline is created with the square coordinates.

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

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

    5. The line layer is added to the style.

DIDN'T FIND WHAT YOU LOOKING FOR?