Skip to content

Instantly share code, notes, and snippets.

@boundsj
Created September 26, 2016 22:46
Show Gist options
  • Save boundsj/1a239f5f3e4d27eb7a4fba54db328152 to your computer and use it in GitHub Desktop.
Save boundsj/1a239f5f3e4d27eb7a4fba54db328152 to your computer and use it in GitHub Desktop.
Swift GeoJSON + Clustering + Filters Example
    func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
        let source = MGLSource(sourceIdentifier: "source")!
        
        let symbolLayer = MGLSymbolStyleLayer(layerIdentifier: "place-city-sm", source: source)
        let url = URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson")!
        let options = [MGLGeoJSONClusterOption: NSNumber(booleanLiteral: true),
                       MGLGeoJSONClusterRadiusOption: NSNumber(integerLiteral: 20),
                       MGLGeoJSONClusterMaximumZoomLevelOption: NSNumber(integerLiteral: 15)]
        let geoJSONSource = MGLGeoJSONSource(sourceIdentifier: "earthquakes", url: url, options: options)
        mapView.style().add(geoJSONSource)
        
        let unclusteredLayer = MGLCircleStyleLayer(layerIdentifier: "unclustered", source: geoJSONSource)
        unclusteredLayer.circleColor = UIColor(colorLiteralRed: 229/255.0, green: 94/255.0, blue: 94/255.0, alpha: 1)
        unclusteredLayer.circleRadius = NSNumber(integerLiteral: 20)
        unclusteredLayer.circleBlur = NSNumber(integerLiteral: 15)
        unclusteredLayer.predicate = NSPredicate(format: "%K != YES", argumentArray: ["cluster"])
        mapView.style().insert(unclusteredLayer, below: symbolLayer)
        
        let layers = [[NSNumber(floatLiteral: 150.0), UIColor(colorLiteralRed: 229/255.0, green: 94/255.0, blue: 94/255.0, alpha: 1)],
                      [NSNumber(floatLiteral: 20.0), UIColor(colorLiteralRed: 249/255.0, green: 136/255.0, blue: 108/255.0, alpha: 1)],
                      [NSNumber(floatLiteral: 0.0), UIColor(colorLiteralRed: 251/255.0, green: 176/255.0, blue: 59/255.0, alpha: 1)]]
        
        for index in 0..<layers.count {
            let circles = MGLCircleStyleLayer(layerIdentifier: "cluster-\(index)", source: geoJSONSource)
            circles.circleColor = layers[index][1] as! UIColor
            circles.circleRadius = NSNumber(integerLiteral: 70)
            circles.circleBlur = NSNumber(integerLiteral: 1)
            
            let gtePredicate = NSPredicate(format: "%K >= %@", argumentArray: ["point_count", layers[index][0] as! NSNumber])
            let allPredicate = index == 0 ?
                gtePredicate :
                NSCompoundPredicate(andPredicateWithSubpredicates: [gtePredicate, NSPredicate(format: "%K < %@", argumentArray: ["point_count", layers[index - 1][0] as! NSNumber])])
            
            circles.predicate = allPredicate
            
            mapView.style().insert(circles, below: symbolLayer)
        }
    }
@boundsj
Copy link
Author

boundsj commented Oct 18, 2016

Yeah @rmnblm, the implementation is changing so these examples just work for moments in time 😄

Why do you define a MGLSymbolStyleLayer when you don't add it to mapView?

Because I want to add my layer below that layer

mapView.style().insert(circles, below: symbolLayer)

@misato
Copy link

misato commented Jan 18, 2017

I updated it for Swift 3 and the latest beta SDK (3.4.0-beta7) here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment