|
| 1 | +<template> |
| 2 | + <Page> |
| 3 | + <GridLayout rows="*,auto"> |
| 4 | + <MapboxView |
| 5 | + :accessToken="accessToken" |
| 6 | + mapStyle="outdoors" |
| 7 | + latitude="50.467735" |
| 8 | + longitude="13.427718" |
| 9 | + hideCompass="true" |
| 10 | + zoomLevel="13" |
| 11 | + showUserLocation="false" |
| 12 | + disableZoom="false" |
| 13 | + disableRotation="false" |
| 14 | + disableScroll="false" |
| 15 | + disableTilt="false" |
| 16 | + rowSpan="2" |
| 17 | + @mapReady="onMapReady($event)" |
| 18 | + /> |
| 19 | + <WrapLayout orientation="horizontal" row="1"> |
| 20 | + <button text="marker" @tap="addMarker($event)" /> |
| 21 | + <button text="updateMarker" @tap="updateMarker($event)" /> |
| 22 | + <button text="camera" @tap="animateCamera($event)" /> |
| 23 | + <button text="location" @tap="trackUser($event)" @longPress="stopTracking($event)" /> |
| 24 | + <button text="source" @tap="addSource($event)" /> |
| 25 | + <button text="polygon" @tap="addPolygon($event)" @longPress="removePolygon($event)" /> |
| 26 | + <button text="polyline" @tap="addPolyline($event)" @longPress="removePolyline($event)" /> |
| 27 | + <button text="offline" @tap="offlineDownload($event)" @longPress="deleteOffline($event)" /> |
| 28 | + </WrapLayout> |
| 29 | + </GridLayout> |
| 30 | + </Page> |
| 31 | +</template> |
| 32 | + |
| 33 | +<script lang="ts"> |
| 34 | +import { Color } from '@nativescript/core'; |
| 35 | +import { LatLng, MapStyle, MapboxView } from '@nativescript-community/ui-mapbox'; |
| 36 | +export default { |
| 37 | + data() { |
| 38 | + return { |
| 39 | + map: null, |
| 40 | + accessToken: 'pk.eyJ1IjoiYWt5bGFzIiwiYSI6ImNtaDBhNGp4ajBhbjQ1dnM4dzIwYXh1NjcifQ.iQt8KEQ2YfulTZuA1BQp2w' |
| 41 | + }; |
| 42 | + }, |
| 43 | + methods: { |
| 44 | + onMapReady({ map }: { map: MapboxView }): void { |
| 45 | + this.map = map; |
| 46 | + map.onMapEvent('click', 'test', (features) => { |
| 47 | + console.log('on element click', features); |
| 48 | + map.querySourceFeatures('test', { filter: ['==', ['get', 'querySample'], '2'] }) |
| 49 | + .then((result) => console.log('query source features', result)) |
| 50 | + .catch((error) => console.error(error)); |
| 51 | + }); |
| 52 | + map.setOnMapLongClickListener((point: LatLng) => { |
| 53 | + console.log('Map longpressed at latitude: ' + point.lat + ', longitude: ' + point.lng); |
| 54 | + return false; |
| 55 | + }); |
| 56 | + map.setOnScrollListener((point?: LatLng) => { |
| 57 | + console.log('Map scrolled to latitude: ' + point.lat + ', longitude: ' + point.lng); |
| 58 | + }); |
| 59 | + map.setViewport({ |
| 60 | + bounds: { |
| 61 | + north: 50.427735, |
| 62 | + east: 13.427718, |
| 63 | + south: 50.467735, |
| 64 | + west: 13.407718 |
| 65 | + }, |
| 66 | + animated: true |
| 67 | + }); |
| 68 | + }, |
| 69 | + addMarker(event) { |
| 70 | + console.log('addMarker', this.map); |
| 71 | + this.firstMarker = { |
| 72 | + id: 2, |
| 73 | + lat: 50.467735, |
| 74 | + lng: 13.427718, |
| 75 | + title: 'One-line title here', |
| 76 | + subtitle: 'Really really nice location', |
| 77 | + selected: true, // makes the callout show immediately when the marker is added (note: only 1 marker can be selected at a time) |
| 78 | + onTap: (marker) => { |
| 79 | + console.log("Marker tapped with title: '" + marker.title + "'"); |
| 80 | + }, |
| 81 | + onCalloutTap: () => { |
| 82 | + console.log("'Nice location' marker callout tapped"); |
| 83 | + this.map.getZoomLevel().then((zoom) => { |
| 84 | + this.map.setZoomLevel({ |
| 85 | + level: zoom - 1, // mandatory, 0-20 |
| 86 | + animated: true // default true |
| 87 | + }); |
| 88 | + }); |
| 89 | + } |
| 90 | + }; |
| 91 | + this.map.addMarkers([this.firstMarker]).catch((error) => console.error(error)); |
| 92 | + this.map.setCenter({ ...this.firstMarker, animated: true }); |
| 93 | + }, |
| 94 | + updateMarker(event) { |
| 95 | + this.firstMarker?.update({ |
| 96 | + lat: 50.417735, |
| 97 | + lng: 13.427718, |
| 98 | + title: 'One-line title here (UPDATE)', |
| 99 | + subtitle: 'Updated subtitle', |
| 100 | + selected: true, // this will trigger the callout upon update |
| 101 | + onTap: (marker) => { |
| 102 | + console.log(`UPDATED Marker tapped with title: ${marker.title}`); |
| 103 | + this.map |
| 104 | + .getCenter() |
| 105 | + .then(function (result) { |
| 106 | + console.log('Mapbox getCenter done, result: ' + JSON.stringify(result)); |
| 107 | + }) |
| 108 | + .catch((error) => console.error(error, error.stack)); |
| 109 | + }, |
| 110 | + onCalloutTap: (marker) => { |
| 111 | + this.firstMarker = null; |
| 112 | + return this.map.removeMarkers([1, 2]); |
| 113 | + } |
| 114 | + }); |
| 115 | + this.map.setCenter({ ...this.firstMarker, animated: false }); |
| 116 | + }, |
| 117 | + animateCamera(event) { |
| 118 | + this.map.getTilt().then((tilt) => { |
| 119 | + console.log('Current map tilt: ' + tilt); |
| 120 | + this.map.animateCamera({ |
| 121 | + // this is where we animate to |
| 122 | + target: { |
| 123 | + lat: 52.373216, |
| 124 | + lng: 4.894168 |
| 125 | + }, |
| 126 | + zoomLevel: 17, // Android |
| 127 | + altitude: 2000, // iOS (meters from the ground) |
| 128 | + bearing: 270, // Where the camera is pointing, 0-360 (degrees) |
| 129 | + tilt: tilt + 10, |
| 130 | + duration: 5000 // default 10000 (milliseconds) |
| 131 | + }); |
| 132 | + }); |
| 133 | + }, |
| 134 | + getUserLocation(event) { |
| 135 | + this.map.getUserLocation().then(function (userLocation) { |
| 136 | + console.log('Current user location: ' + userLocation.location.lat + ', ' + userLocation.location.lng); |
| 137 | + console.log('Current user speed: ' + userLocation.speed); |
| 138 | + }); |
| 139 | + }, |
| 140 | + trackUser(event) { |
| 141 | + this.map.trackUser({ |
| 142 | + cameraMode: 'TRACKING', |
| 143 | + renderMode: 'COMPASS', |
| 144 | + animated: true |
| 145 | + }); |
| 146 | + }, |
| 147 | + stopTracking(event) { |
| 148 | + this.map.hideUserLocationMarker(); |
| 149 | + }, |
| 150 | + addSource(event) { |
| 151 | + this.map |
| 152 | + .addSource('test', { |
| 153 | + type: 'geojson', |
| 154 | + data: { |
| 155 | + type: 'FeatureCollection', |
| 156 | + features: [ |
| 157 | + { |
| 158 | + type: 'Feature', |
| 159 | + properties: { |
| 160 | + querySample: '1' |
| 161 | + }, |
| 162 | + geometry: { |
| 163 | + type: 'LineString', |
| 164 | + coordinates: [ |
| 165 | + [13.427718, 50.467735], |
| 166 | + [13.427718, 55.373216] |
| 167 | + ] |
| 168 | + } |
| 169 | + }, |
| 170 | + { |
| 171 | + type: 'Feature', |
| 172 | + properties: { |
| 173 | + querySample: '2' |
| 174 | + }, |
| 175 | + geometry: { |
| 176 | + type: 'LineString', |
| 177 | + coordinates: [ |
| 178 | + [13.427718, 50.467735], |
| 179 | + [12.427718, 50.467735] |
| 180 | + ] |
| 181 | + } |
| 182 | + } |
| 183 | + ] |
| 184 | + } |
| 185 | + }) |
| 186 | + .catch((error) => console.error(error, error.stack)) |
| 187 | + .then(() => { |
| 188 | + console.log('source added') |
| 189 | + this.map |
| 190 | + .addLayer({ |
| 191 | + id: 'test', |
| 192 | + type: 'line', |
| 193 | + source: 'test', |
| 194 | + layout: { |
| 195 | + 'line-cap': 'round', |
| 196 | + 'line-join': 'round' |
| 197 | + }, |
| 198 | + paint: { |
| 199 | + 'line-color': '#ed6498', |
| 200 | + 'line-width': 5, |
| 201 | + 'line-opacity': 0.8, |
| 202 | + 'line-dash-array': [1, 1, 1] |
| 203 | + } |
| 204 | + }) |
| 205 | + .catch((error) => console.error(error, error.stack)); |
| 206 | + }); |
| 207 | + }, |
| 208 | + addPolygon(event) { |
| 209 | + this.map |
| 210 | + .addPolygon({ |
| 211 | + id: 1, // optional, can be used in 'removePolygons' |
| 212 | + fillColor: new Color('red'), |
| 213 | + fillOpacity: 0.7, |
| 214 | +
|
| 215 | + // stroke-related properties are only effective on iOS |
| 216 | + strokeColor: new Color('green'), |
| 217 | + strokeWidth: 8, |
| 218 | + strokeOpacity: 0.5, |
| 219 | +
|
| 220 | + points: [ |
| 221 | + { |
| 222 | + lat: 52.3923633970718, |
| 223 | + lng: 4.902648925781249 |
| 224 | + }, |
| 225 | + { |
| 226 | + lat: 52.35421556258807, |
| 227 | + lng: 4.9308013916015625 |
| 228 | + }, |
| 229 | + { |
| 230 | + lat: 52.353796172573944, |
| 231 | + lng: 4.8799896240234375 |
| 232 | + }, |
| 233 | + { |
| 234 | + lat: 52.3864966440161, |
| 235 | + lng: 4.8621368408203125 |
| 236 | + }, |
| 237 | + { |
| 238 | + lat: 52.3923633970718, |
| 239 | + lng: 4.902648925781249 |
| 240 | + } |
| 241 | + ] |
| 242 | + }) |
| 243 | + .then(() => |
| 244 | + this.map.setCenter({ |
| 245 | + lat: 52.383316, |
| 246 | + lng: 4.899178, |
| 247 | + animated: true |
| 248 | + }) |
| 249 | + ) |
| 250 | + .then((result) => console.log('Mapbox addPolygon done')) |
| 251 | + .catch((error) => console.error(error, error.stack)); |
| 252 | + }, |
| 253 | + removePolygon(event) { |
| 254 | + this.map.removePolygons([1, 2]); |
| 255 | + }, |
| 256 | + addPolyline(event) { |
| 257 | + this.map |
| 258 | + .addPolyline({ |
| 259 | + id: 1, // optional, can be used in 'removePolylines' |
| 260 | + color: '#336699ff', // Set the color of the line (default black) |
| 261 | + width: 7, // Set the width of the line (default 5) |
| 262 | + opacity: 0.6, //Transparency / alpha, ranging 0-1. Default fully opaque (1). |
| 263 | + points: [ |
| 264 | + { |
| 265 | + lat: 52.383316, |
| 266 | + lng: 4.899178 |
| 267 | + }, |
| 268 | + { |
| 269 | + lat: 52.383416, |
| 270 | + lng: 4.899188 |
| 271 | + }, |
| 272 | + { |
| 273 | + lat: 52.383516, |
| 274 | + lng: 4.79198 |
| 275 | + } |
| 276 | + ] |
| 277 | + }) |
| 278 | + .then(() => { |
| 279 | + this.map.setCenter({ |
| 280 | + lat: 52.383316, |
| 281 | + lng: 4.899178, |
| 282 | + animated: true |
| 283 | + }); |
| 284 | + }); |
| 285 | + }, |
| 286 | + removePolyline(event) { |
| 287 | + this.map.removePolylines([1, 2]); |
| 288 | + }, |
| 289 | + offlineDownload(event) { |
| 290 | + console.log('offlineDownload'); |
| 291 | + this.map.getViewport().then((viewport) => { |
| 292 | + console.log('viewport for download', viewport, this.map); |
| 293 | + this.map |
| 294 | + .downloadOfflineRegion({ |
| 295 | + name: 'LastViewport', // anything you like really |
| 296 | + style: MapStyle.OUTDOORS, |
| 297 | + minZoom: viewport.zoomLevel - 2, |
| 298 | + maxZoom: viewport.zoomLevel, // higher zoom level is lower to the ground |
| 299 | + bounds: viewport.bounds, |
| 300 | + onProgress(progress) { |
| 301 | + console.log('Download %: ' + progress.percentage); |
| 302 | + } |
| 303 | + }) |
| 304 | + .then(() => { |
| 305 | + this.map |
| 306 | + .listOfflineRegions({ |
| 307 | + // required for Android in case no map has been shown yet |
| 308 | + accessToken: this.accessToken |
| 309 | + }) |
| 310 | + .then( |
| 311 | + function (regions) { |
| 312 | + console.log(JSON.stringify(regions)); |
| 313 | + }, |
| 314 | + function (error) { |
| 315 | + console.log('Error while listing offline regions: ' + error); |
| 316 | + } |
| 317 | + ); |
| 318 | + }) |
| 319 | + .catch((error) => console.error(error, error.stack)); |
| 320 | + }); |
| 321 | + }, |
| 322 | + deleteOffline(event) { |
| 323 | + console.log('deleteOffline'); |
| 324 | + this.map |
| 325 | + .deleteOfflineRegion({ |
| 326 | + name: 'LastViewport' |
| 327 | + }) |
| 328 | + .then(function () { |
| 329 | + console.log('Offline region deleted'); |
| 330 | + }) |
| 331 | + .catch((error) => console.error(error, error.stack)); |
| 332 | + } |
| 333 | + } |
| 334 | +}; |
| 335 | +</script> |
| 336 | + |
| 337 | +<style scoped> |
| 338 | +ActionBar { |
| 339 | + background-color: #53ba82; |
| 340 | + color: #ffffff; |
| 341 | +} |
| 342 | +
|
| 343 | +.message { |
| 344 | + vertical-align: center; |
| 345 | + text-align: center; |
| 346 | + font-size: 20; |
| 347 | + color: #333333; |
| 348 | +} |
| 349 | +</style> |
0 commit comments