-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
SymbolClusteringExample.cs
173 lines (142 loc) · 5.7 KB
/
SymbolClusteringExample.cs
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
namespace MapboxMauiQs;
public class SymbolClusteringExample : ContentPage, IExamplePage, IQueryAttributable
{
MapboxView map;
IExampleInfo info;
public SymbolClusteringExample()
{
iOSPage.SetUseSafeArea(this, false);
Content = map = new MapboxView();
map.MapReady += Map_MapReady;
map.MapLoaded += Map_MapLoaded;
}
private async void Map_MapLoaded(object sender, EventArgs e)
{
var geojson = await LoadGeojson().ConfigureAwait(true);
var image = new ResolvedImage("fire-station-icon", "fire_station_11")
{
Sdf = true,
IsTemplate = true,
};
map.Images = new[] { image };
IGeoJSONObject geojsonObj = new RawGeoJSONObject(geojson);
const string sourceID = "fire-hydrant-source";
var source = new GeoJSONSource(sourceID)
{
Data = geojsonObj,
Cluster = true,
ClusterRadius = 75,
};
// Create expression to identify the max flow rate of one hydrant in the cluster
// ["max", ["get", "FLOW"]]
var maxExpression = DslExpression.Max(
DslExpression.Get("FLOW"));
// Create expression to determine if a hydrant with EngineID E-9 is in the cluster
// ["any", ["==", ["get", "ENGINEID"], "E-9"]]
var ine9Expression = DslExpression.Any(
DslExpression.Eq(
DslExpression.Get("ENGINEID"),
"E-9"
));
// Create expression to get the sum of all of the flow rates in the cluster
// [["+",["accumulated"],["get", "sum"]],["get", "FLOW"]]
var sumExpression = DslExpression.Args(
DslExpression.Sum(
DslExpression.Accumulated(),
DslExpression.Get("sum")),
DslExpression.Get("FLOW"));
// Add the expressions to the cluster as ClusterProperties so they can be accessed below
var clusterProperties = new Dictionary<string, object> {
{ "max", maxExpression },
{ "in_e9", ine9Expression },
{ "sum", sumExpression }
};
source.ClusterProperties = clusterProperties;
map.Sources = new[] { source };
var clusteredLayer = CreateClusteredLayer(sourceID);
var unclusteredLayer = CreateUnclusteredLayer(sourceID, image);
var clusterCountLayer = CreateNumberLayer(sourceID);
unclusteredLayer.LayerPosition = LayerPosition.Below(clusteredLayer.Id);
map.Layers = new MapboxLayer[] { clusteredLayer, unclusteredLayer, clusterCountLayer, };
}
static CircleLayer CreateClusteredLayer(string sourceId)
{
// Create a symbol layer to represent the clustered points.
var clusteredLayer = new CircleLayer("clustered-circle-layer")
{
Source = sourceId,
// Filter out unclustered features by checking for `point_count`. This
// is added to clusters when the cluster is created. If your source
// data includes a `point_count` property, consider checking
// for `cluster_id`.
Filter = DslExpression.Has("point_count"),
// Set the color of the icons based on the number of points within
// a given cluster. The first value is a default value.
CircleColor = (PropertyValue<Color>)DslExpression.Step(
DslExpression.Get("point_count"),
Colors.Green,
50,
Colors.Blue,
100,
Colors.Red),
CircleRadius = 25.0,
};
return clusteredLayer;
}
static SymbolLayer CreateUnclusteredLayer(string sourceId, ResolvedImage image)
{
// Create a symbol layer to represent the points that aren't clustered.
var unclusteredLayer = new SymbolLayer("unclustered-point-layer")
{
Source = sourceId,
// Filter out clusters by checking for `point_count`.
Filter = DslExpression.Not(
DslExpression.Has("point_count")),
IconImage = image,
IconColor = Colors.White,
// Rotate the icon image based on the recorded water flow.
// The `mod` operator allows you to use the remainder after dividing
// the specified values.
IconRotate = (PropertyValue<Double>)DslExpression.Mod(
DslExpression.Get("FLOW"),
360),
};
return unclusteredLayer;
}
static SymbolLayer CreateNumberLayer(string sourceId)
{
var numberLayer = new SymbolLayer("cluster-count-layer")
{
Source = sourceId,
// check whether the point feature is clustered
Filter = DslExpression.Has("point_count"),
// Display the value for 'point_count' in the text field
TextField = (PropertyValue<string>)DslExpression.Get("point_count"),
TextSize = 12.0,
};
return numberLayer;
}
private void Map_MapReady(object sender, EventArgs e)
{
// Setup Map here
var center = new Point(38.889215, -77.039354);
var cameraOptions = new CameraOptions
{
Center = center,
Zoom = 11,
};
map.CameraOptions = cameraOptions;
map.MapboxStyle = MapboxStyle.DARK;
}
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
info = query["example"] as IExampleInfo;
Title = info?.Title;
}
async Task<string> LoadGeojson()
{
using var stream = await FileSystem.OpenAppPackageFileAsync("Fire_Hydrants.geojson");
using var reader = new StreamReader(stream);
return reader.ReadToEnd();
}
}