-
Notifications
You must be signed in to change notification settings - Fork 455
/
Copy pathGet points in current map view.html
204 lines (165 loc) · 8.12 KB
/
Get points in current map view.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<!DOCTYPE html>
<html lang="en">
<head>
<title>Get points in current map view - 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 determine which points of a data set are in the current map view." />
<meta name="keywords" content="Microsoft maps, map, gis, API, SDK, events, overview map, overview, mini map, minimap" />
<meta name="author" content="Microsoft Azure Maps" /><meta name="version" content="1.0" />
<!--link href="SiteResources/screenshots/MapsSampleIcon.png" rel="shortcut icon" /-->
<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, mockDataSize = 1000;
function getMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
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);
//Create a layer to render the point data.
map.layers.add(new atlas.layer.SymbolLayer(datasource, null, {
iconOptions: {
allowOverlap: true,
ignorePlacement: true
}
}));
//Generate some mock data.
generateMockData();
//Monitor for when the map is done moving.
map.events.add('moveend', mapChangedView);
//Do an initial calculation for the initial map view.
mapChangedView();
});
}
function mapChangedView() {
//Calculate a polygon for the map view.
var viewPolygon = getMapViewPolygon(map);
//Get all shapes in the datasource.
var shapes = datasource.getShapes();
var pointsInView = [];
//Do something with the points in view.
//For demo purposes, we will simply output the name of each pin.
var html = [];
//Search for all point shapes that intersect the polygon.
for (var i = 0; i < pins.length; i++) {
if (shapes[i].getType() === 'Point' && isPointInPolygon(shapes[i].getCoordinates(), viewPolygon)) {
pointsInView.push(shapes[i]);
html.push(shapes[i].getProperties().name, '<br/>');
}
}
document.getElementById('output').innerHTML = pointsInView.length + ' pins in view:<br/><br/>' + html.join('');
}
/**
* Generates an array of polygons to create a polygon that represents the map view.
* Coordinates are converted into mercator piels so we can do pixel accurate calculations.
* @param map The map to calculate the view polygon for.
*/
function getMapViewPolygon(map) {
//Simply using the bounding box of the map will not generate a polygon that represents the map area when it is rotated and pitched.
//Instead we need to calculate the coordinates of the corners of the map.
var mapRect = map.getCanvasContainer().getBoundingClientRect();
var width = mapRect.width;
var height = mapRect.height;
//Calculate positions from the corners of the map.
var pos = map.pixelsToPositions([
//Top Left corner
[0, 0],
//Top right corner.
[width, 0],
//Bottom Right corner.
[width, height],
//Bottom left corner.
[0, height]
]);
//Convert the positions to mercator pixels at zoom level 22.
return atlas.math.mercatorPositionsToPixels(pos, 22);
}
/**
* Checks to see if a position is within a mercator polygon.
* @param position A position point to determine if it is in a polygon.
* @param mercatorPolygon Array of Mercator coordinates that form a polygon.
*/
function isPointInPolygon(position, mercatorPolygon) {
//Convert point into a mercator pixel at zoom level 22 for pixel accurate calculations.
var p = atlas.math.mercatorPositionsToPixels([position], 22)[0];
var x = p[0];
var y = p[1];
var inside = false;
for (var i = 0, j = mercatorPolygon.length - 1; i < mercatorPolygon.length; j = i++) {
var xi = mercatorPolygon[i][0], yi = mercatorPolygon[i][1];
var xj = mercatorPolygon[j][0], yj = mercatorPolygon[j][1];
if (((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) {
inside = !inside;
}
}
return inside;
};
function generateMockData() {
//This generates a bunch of random pins.
pins = [];
for (var i = 0; i < mockDataSize; i++) {
var coord = [
Math.random() * 360 - 180, //Random longitude value.
Math.random() * 170 - 85 //Random latitude value.
];
pins.push(new atlas.data.Feature(new atlas.data.Point(coord), {
name: 'Pin_' + i
}));
}
datasource.add(pins);
}
</script>
<style>
#myMap {
position: relative;
width: calc(100% - 210px);
min-width:290px;
height: 600px;
float:left;
}
#output {
float: left;
width: 200px;
height: 600px;
margin-left: 10px;
overflow-y: auto;
}
</style>
</head>
<body onload="getMap()">
<div id="myMap"></div>
<div id="output"></div>
<div style="clear:both;"></div>
<fieldset style="width:calc(100% - 30px);min-width:290px;margin-top:10px;">
<legend>Get points in current map view</legend>
This sample shows how to determine which points of a data set are in the current map view.
Pan and zoom the map to recalculate which points are in the current map view.
To do this the map view polygon is calculated to take into consideration the rotation and pitch of the map.
Since data is rendered on the map which uses a Mercator projection, and pixel accuracy is desired, the map
view polygon and all data points are converted into mercator pixels and a point in polygon algorithm is used with that data.
</fieldset>
</body>
</html>