I am working on building a Demo for a 3D flight tracker. It’s a React application and I’ve borrowed and stitched together some example code.
I have added an Azure Maps base layer and am using this plugin to integrate it. In a time span of approximately 5 minutes, I racked up about 2.5k api requests and I’m guessing then somewhere close to 30k tiles? Is that correct? Or is my application doing something obviously wrong. Perhaps I’m going about it the wrong way entirely.
import {
Cartesian3,
Ion,
Terrain,
Viewer,
JulianDate,
SampledPositionProperty,
Color,
TimeIntervalCollection,
TimeInterval,
PathGraphics,
createOsmBuildingsAsync,
UrlTemplateImageryProvider,
Resource,
Credit,
ImageryLayer
} from 'cesium';
import React, { useEffect, useRef, useState } from 'react';
window.CESIUM_BASE_URL = '/out/release/Cesium';
const FlightViwer3D = () => {
const [viewer, setViewer] = useState<any>(undefined);
const cesiumRef = useRef();
Ion.defaultAccessToken = 'token token token';
const flightData = JSON.parse('data data data');
useEffect(() => {
setViewer(
new Viewer('cesiumContainer', {
terrain: Terrain.fromWorldTerrain(),
baseLayerPicker: true,
baseLayer: new ImageryLayer(
new UrlTemplateImageryProvider({
url: new Resource({
url: 'https://atlas.microsoft.com/map/tile?api-version=2.0&zoom={z}&x={x}&y={y}&tileSize=512',
tileWidth: 512,
tileHeight: 512,
queryParameters: {
//Add your Azure Maps key to the map SDK. Get an Azure Maps key at https://azure.com/maps. NOTE: The primary key should be used as the key.
'subscription-key': 'primary key from azure maps here',
/*
Tileset ID specifies which data layers to render in the tiles. Can be:
'microsoft.base.road',
'microsoft.base.darkgrey',
'microsoft.imagery', //Only supports tile width/height of 256
'microsoft.weather.infrared.main',
'microsoft.weather.radar.main',
'microsoft.base.hybrid.road',
'microsoft.base.labels.road '
*/
tilesetId: 'microsoft.base.road',
//The language of labels. Supported languages: https://docs.microsoft.com/en-us/azure/azure-maps/supported-languages
language: 'en-US',
//The regional view of the map. Supported views: https://aka.ms/AzureMapsLocalizationViews
view: 'Auto'
}
}),
credit: new Credit(
`© ${new Date().getFullYear()} TomTom, Microsoft`,
true
),
maximumLevel: 12,
enablePickFeatures: false
})
)
})
);
}, [cesiumRef.current]);
useEffect(() => {
const someFunc = async () => {
if (viewer) {
// Add Cesium OSM Buildings, a global 3D buildings layer.
const buildingTileset = await createOsmBuildingsAsync();
viewer.scene.primitives.add(buildingTileset);
const timeStepInSeconds = 30;
const totalSeconds = timeStepInSeconds * (flightData.length - 1);
const start = JulianDate.fromIso8601('2020-03-09T23:10:00Z');
const stop = JulianDate.addSeconds(
start,
totalSeconds,
new JulianDate()
);
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.timeline.zoomTo(start, stop);
// Speed up the playback speed 50x.
viewer.clock.multiplier = 50;
// Start playing the scene.
viewer.clock.shouldAnimate = true;
// The SampledPositionedProperty stores the position and timestamp for each sample along the radar sample series.
const positionProperty = new SampledPositionProperty();
for (let i = 0; i < flightData.length; i++) {
const dataPoint = flightData[i];
// Declare the time for this individual sample and store it in a new JulianDate instance.
const time = JulianDate.addSeconds(
start,
i * timeStepInSeconds,
new JulianDate()
);
const position = Cartesian3.fromDegrees(
dataPoint.longitude,
dataPoint.latitude,
dataPoint.height
);
// Store the position along with its timestamp.
// Here we add the positions all upfront, but these can be added at run-time as samples are received from a server.
positionProperty.addSample(time, position);
viewer.entities.add({
description: `Location: (${dataPoint.longitude}, ${dataPoint.latitude}, ${dataPoint.height})`,
position: position,
point: { pixelSize: 10, color: Color.RED }
});
}
const airplaneEntity = viewer.entities.add({
availability: new TimeIntervalCollection([
new TimeInterval({ start: start, stop: stop })
]),
position: positionProperty,
point: { pixelSize: 30, color: Color.GREEN },
path: new PathGraphics({ width: 3 })
});
viewer.trackedEntity = airplaneEntity;
}
};
someFunc();
}, [viewer]);
return (
<div
ref={cesiumRef}
id="cesiumContainer"
style={{
position: 'relative',
width: '100%',
minWidth: '290px',
height: '600px'
}}
></div>
);
};
export default FlightViwer3D;