/
Data binning points with Turfjs.html
160 lines (134 loc) · 7.51 KB
/
Data binning points with Turfjs.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
155
156
157
158
159
160
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data binning points with Turfjs - 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 create a hexagon grid and perform an aggregate to determine how many points are within each cell of a hexagon grid." />
<meta name="keywords" content="Microsoft maps, maps, map, API, SDK, GIS, bivariate, data binning, data bin, gridding, hexbins, hexgrid, hexagon bins, tessellations" />
<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>
<!-- Load turf.js a spatial math library. https://turfjs.org/ -->
<script src='/lib/turf.min.js'></script>
<script>
var map, datasource;
var pointDataUrl = '/data/geojson/US_farmers_markets.json';
function getMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
center: [-95, 38],
zoom: 3,
style: 'grayscale_light',
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 and add it to the map.
datasource = new atlas.source.DataSource();
map.sources.add(datasource);
map.layers.add([
//Create a layer to render polygon data.
new atlas.layer.PolygonLayer(datasource, null, {
//Use a data-driven expression based on a property on each polygon to assign a color.
fillColor: [
'step',
['get', 'count'],
'#ffffcc', //If value is less than 25, make it transparent.
25, '#a1dab4', //25 - 49 color
50, '#7fcdbb', //50 - 99 color
100, '#41b6c4', //100 - 149 color
150, '#2c7fb8', //150 - 199 color
200, '#253494' //200+ color
],
fillOpacity: 1// 0.5
}),
//Create a layer to color the outline of each polygon.
new atlas.layer.LineLayer(datasource, null, {
strokeColor: 'grey'
})
], 'labels');
//Load the point data.
fetch(pointDataUrl).then(r => r.json()).then(fc => {
//We need a value to interpolate. Since we only care about the count, we can add an arbitrary value to each feature with a value of 1.
fc.features.forEach(f => f.properties.value = 1);
//Calculate the bounding box of the data.
var bbox = atlas.data.BoundingBox.fromData(fc);
//Define the length of each cell edge.
var cellSide = 75;
//Define the units of the cell side.
var options = { units: 'miles' };
//Calculate a hexagon grid. There is also turf.triangleGrid, turf.squareGrid and turf.pointGrid
var grid = turf.hexGrid(bbox, cellSide, options);
//Grids generated by turf share a common property object which makes it difficult to aggregate and assign values.
//Give each grid a unique property object.
grid.features.forEach(f => f.properties = {});
//Cross reference the points with the hexagons.
var collected = turf.collect(grid, fc, 'value', 'values');
//Aggregate the values in each grid.
collected.features.forEach(f => {
f.properties.count = f.properties.values.reduce((total, val) => { return total + val }, 0)
});
//Remove any hexagons that have no value.
collected.features = collected.features.filter(f => f.properties.count > 0);
//Add the hexagons to the map.
datasource.add(collected);
});
});
}
</script>
<style>
.legend {
position: absolute;
top: 10px;
left: 10px;
background-color: white;
border-radius: 10px;
padding: 10px;
font-size: 12px;
}
.colorcell {
width: 15px;
height: 15px;
border: 1px solid grey;
}
</style>
</head>
<body >
<div id="myMap" style="position:relative;width:100%;min-width:290px;height:600px;"></div>
<div class="legend">
# of farmer markets
<table>
<tr><td><div class="colorcell" style="background-color:#253494"></div></td><td>200</td></tr>
<tr><td><div class="colorcell" style="background-color:#2c7fb8"></div></td><td>150</td></tr>
<tr><td><div class="colorcell" style="background-color:#41b6c4"></div></td><td>100</td></tr>
<tr><td><div class="colorcell" style="background-color:#7fcdbb"></div></td><td>50</td></tr>
<tr><td><div class="colorcell" style="background-color:#a1dab4"></div></td><td>25</td></tr>
<tr><td><div class="colorcell" style="background-color:#ffffcc"></div></td><td>1</td></tr>
</table>
</div>
<fieldset style="width:calc(100% - 30px);min-width:290px;margin-top:10px;">
<legend>Data binning points with Turfjs</legend>
This sample shows how to create a hexagon grid and perform an aggregate to determine how many points are within each cell of a hexagon grid.
This sample uses the open source <a href="https://turfjs.org/" target="_blank">Turf.js</a> library to perform the difference calculation.
Also take a look at the <a href="/index.html?search=gridded%20data%20source">Gridded Data Source samples</a> for a more robust solution.
</fieldset>
</body>
</html>