-
Notifications
You must be signed in to change notification settings - Fork 447
/
Display cluster area with Convex Hull.html
154 lines (124 loc) · 7.12 KB
/
Display cluster area with Convex Hull.html
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
<!DOCTYPE html>
<html lang="en">
<head>
<title>Display cluster area with Convex Hull - Azure Maps Web SDK Samples</title>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="This sample shows how to display the area of the points contained within a cluster by calculating a convex hull." />
<meta name="keywords" content="Microsoft maps, map, gis, API, SDK, markers, pins, pushpins, symbols, layer, clustering, superclusterer, convex hull, spatial math, earthquakes, USGS" />
<meta name="author" content="Microsoft Azure Maps" /><meta name="version" content="1.0" />
<meta name="screenshot" content="screenshot.jpg" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.css" rel="stylesheet" />
<script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/3/atlas.min.js"></script>
<script>
var map, datasource, polygonDatasource;
//GeoJSON feed of all earthquakes from the past 30 days. Sourced from the USGS.
var earthquakeFeed = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson";
//Find more earthquake data feeds here: https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php
function getMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-97, 39],
zoom: 3,
style: 'grayscale_dark',
view: 'Auto',
//Add authentication details for connecting to Azure Maps.
authOptions: {
//Use Microsoft Entra ID authentication.
authType: 'anonymous',
clientId: 'e6b6ab59-eb5d-4d25-aa57-581135b927f0', //Your Azure Maps client id for accessing your Azure Maps account.
getToken: function (resolve, reject, map) {
//URL to your authentication service that retrieves an Microsoft Entra ID Token.
var tokenServiceUrl = 'https://samples.azuremaps.com/api/GetAzureMapsToken';
fetch(tokenServiceUrl).then(r => r.text()).then(token => resolve(token));
}
//Alternatively, use an Azure Maps key. Get an Azure Maps key at https://azure.com/maps. NOTE: The primary key should be used as the key.
//authType: 'subscriptionKey',
//subscriptionKey: '[YOUR_AZURE_MAPS_KEY]'
}
});
//Wait until the map resources are ready.
map.events.add('ready', function () {
//Create a data source for the point data.
datasource = new atlas.source.DataSource(null, {
//Tell the data source to cluster point data.
cluster: true
});
//Create a data source for the convex hull polygon. Since this will be updated frequently it is more efficient to seperate this into its own data source.
polygonDatasource = new atlas.source.DataSource();
//Add the data sources to the map.
map.sources.add([polygonDatasource, datasource]);
//Create a symbol layer to render the clusters.
var clusterLayer = new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
image: 'marker-red'
},
textOptions: {
textField: ['get', 'point_count_abbreviated'],
offset: [0, -1.2],
color: "#ffffff",
size: 14
},
filter: ['has', 'point_count'] //Filter individual points from this layer.
});
//Add a mouse over event to calculate and display the cluster area using a convex hull.
map.events.add('mouseover', clusterLayer, displayClusterArea);
//Add a mouse leave event to remove the convex hull from the map.
map.events.add('mouseleave', clusterLayer, function () {
polygonDatasource.clear();
});
//Add a polygon layer and a line layer to display the convex hull.
//Add two symbol layers to the map, one for clusters, one for individual points.
map.layers.add([
//Create a polygon layer to display the area of the convex hull.
new atlas.layer.PolygonLayer(polygonDatasource),
//Create a line layer to display the outline of the convex hull.
new atlas.layer.LineLayer(polygonDatasource),
clusterLayer,
//Create a layer to render the individual locations.
new atlas.layer.SymbolLayer(datasource, null, {
filter: ['!', ['has', 'point_count']] //Filter out clustered points from this layer.
})
]);
//Retrieve a GeoJSON data set and add it to the data source.
datasource.importDataFromUrl(earthquakeFeed);
});
}
function displayClusterArea(e) {
if (e && e.shapes && e.shapes.length > 0 && e.shapes[0].properties.cluster) {
//Get the clustered point from the event.
var cluster = e.shapes[0];
//Get all points in the cluster. Set the offset to 0 and the limit to Infinity to return all points.
datasource.getClusterLeaves(cluster.properties.cluster_id, Infinity, 0).then(function (points) {
if (points.length === 2) {
//When only two points in a cluster. Render a line.
polygonDatasource.setShapes(new atlas.data.LineString(getPositions(points)));
} else {
var hullPolygon = atlas.math.getConvexHull(getPositions(points));
//Overwrite all data in the polygon data source with the newly calculated convex hull polygon.
polygonDatasource.setShapes(hullPolygon);
}
});
}
}
function getPositions(shapes) {
var pos = [];
if (shapes) {
for (var i = 0; i < shapes.length; i++) {
pos.push(atlas.math.getPosition(shapes[i]));
}
}
return pos;
}
</script>
</head>
<body onload="getMap()">
<div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>
<fieldset style="width:calc(100% - 30px);min-width:290px;margin-top:10px;">
<legend>Display cluster area with Convex Hull</legend>
This sample shows how to display the area of the points contained within a cluster by calculating a convex hull.
</fieldset>
</body>
</html>