Image clustering

Allow your users to cluster image annotations for better visualization. By default, clustering is disabled.

Sample use case: You want to cluster images in the FeatureCollection type provided in GeoJSON.

To enable clustering you need to set:

  • "cluster": true

and set the desired cluster radius:

  • "clusterRadius": 70

Here you can see what the TTMapSource GeoJSON style file with enabled clustering looks like:

1"IC-app-test-source": {
2 "type": "geojson",
3 "cluster": true,
4 "clusterRadius": 70,
5 "data": {
6 "type": "FeatureCollection",
7 "features": [
8 {
9 "type": "Feature",
10 "geometry": {
11 "type": "Point",
12 "coordinates": [
13 4.710759,
14 52.340415
15 ]
16 },
17 "properties": {
18 "icon": "jet_airplane_landing"
19 }
20 }
21 ]
22 }
23}

You also need to add the new TTMapStyle to the current style, that defines the behaviour when your features do not fulfill clustering contraints.

1{
2 "id": "IC-app-test-layer",
3 "filter": [
4 "!has",
5 "point_count"
6 ],
7 "type": "symbol",
8 "layout": {
9 "icon-image": "{icon}",
10 "icon-allow-overlap": true
11 },
12 "source": "IC-app-test-source"
13}

Please also remember if the feature "properties": {"icon": "jet_airplane_landing"} is set, you need to add the image to TTMapStyle as follows:

SWIFT
OBJECTIVEC
let jetAirPlainLanding = UIImage(named: "jet_airplane_landing")
currentStyle.add(jetAirPlainLanding!, withID: "jet_airplane_landing")
UIImage *jetAirPlainLanding = [UIImage imageNamed:@"jet_airplane_landing"];
[self.currentStyle addImage:jetAirPlainLanding withID:@"jet_airplane_landing"];

Sample use case: You want to add a background overlay under the cluster size.

You need to create TTMapLayer with the given content:

1{
2 "id": "IC-app-test-layer-cluster",
3 "filter": [
4 "has",
5 "point_count"
6 ],
7 "type": "symbol",
8 "layout": {
9 "icon-image": "ic_cluster",
10 "icon-allow-overlap": true,
11 "icon-ignore-placement": true
12 },
13 "source": "IC-app-test-source"
14}

and add it to current map style.

Sample use case: You want to customize the cluster symbol text color, text size, and offset.

You need to define TTMapLayer with the given JSON content:

1{
2 "filter": [
3 "has",
4 "point_count"
5 ],
6 "id": "IC-app-test-layer-symbol-count",
7 "source": "IC-app-test-source",
8 "type": "symbol",
9 "layout": {
10 "text-field": "{point_count}",
11 "text-font": [
12 "Noto-Bold"
13 ],
14 "text-size": 14,
15 "text-offset": [
16 0.0,
17 0.0
18 ]
19 },
20 "paint": {
21 "text-color": "#FFFFFF"
22 }
23}

and add it to current map style.

Code Example

Here you can check what an example implementation may look like:

  • Adding a map source
SWIFT
OBJECTIVEC
1let path = Bundle.main.path(forResource: "ic_app_test_source", ofType: "json")
2let geojsonJSON = try! String(contentsOfFile: path!, encoding: .utf8)
3let sourceMap = TTMapSource.create(withSourceJSON: geojsonJSON)
4currentStyle.add(sourceMap!)
1NSString *path = [[NSBundle mainBundle] pathForResource:@"ic_app_test_source" ofType:@"json"];
2NSString *geojsonJSON = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
3TTMapSource *sourceMap = [TTMapSource createWithSourceJSON:geojsonJSON];
4[self.currentStyle addSource:sourceMap];
  • Adding a map layer with a given file name
SWIFT
OBJECTIVEC
1guard let path = Bundle.main.path(forResource: jsonStyleName, ofType: "json") else {
2 print("Failed to find path for name: \(jsonStyleName).json")
3 return
4}
5guard let layerContentJSONString = try? String(contentsOfFile: path, encoding: .utf8) else {
6 print("Failed to read file at path: \(path)")
7 return
8}
9guard let mapLayer = TTMapLayer.create(withStyleJSON: layerContentJSONString, withMap: map) else {
10 print("Failed to create TTMapLayer from: \(layerContentJSONString)")
11 return
12}
13style.add(mapLayer)
1NSString *path = [[NSBundle mainBundle] pathForResource:jsonStyleName ofType:@"json"];
2NSString *layerContentJSONString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
3TTMapLayer *mapLayer = [TTMapLayer createWithStyleJSON:layerContentJSONString withMap:map];
4[style addLayer:mapLayer];

Clusters and images