/**
* Asset Point Animations Functions definitions
* @module animations */
/**
* Activate Asset Point Animations
* @param {FeatureCollection} geojson_asset_points Asset Points FeatureCollection
* @param {FeatureCollection} geojson_assetpoints_directions Asset Points Directions FeatureCollection
* @param {FeatureCollection} geojson_anchors Anchors FeatureCollection
* @param {FeatureCollection} geojson_antennas Antennas FeatureCollection
* @param {FeatureCollection} wall_intersections_points Map Features Walls Points Intersections FeatureCollection
* @param {FeatureCollection} geojson_lines_of_sight Lines of Sight FeatureCollection
* @param {FeatureCollection} geojson_walls Map Features Walls FeatureCollection
* @param {Array} pulsing_dots_layers_sources Pulsing Dots sources Array
* @param {Array} asset_point_animations Asset Point Animations Array
* @param {number} cpu_frame_rate CPU frame rate
* @param {number} last_frame last frame
* @param {number} animation_speed_factor value of animation speed factor
*/
function activateAssetPointsAnimations(
geojson_asset_points,
geojson_assetpoints_directions,
geojson_anchors,
geojson_antennas,
wall_intersections_points,
geojson_lines_of_sight,
geojson_walls,
pulsing_dots_layers_sources,
asset_point_animations,
cpu_frame_rate,
last_frame,
animation_speed_factor
) {
animation_speed_factor = parseFloat(document.getElementById("animation_speed_slider").value);
geojson_asset_points.features.forEach(index => {
var currentAssetFeatureId = index.properties.id;
if (!animatingAssetPointFlags[currentAssetFeatureId]) {
// call Animation
animateAssetPointWithCustomMove(
index,
geojson_asset_points,
geojson_assetpoints_directions,
geojson_anchors,
geojson_antennas,
wall_intersections_points,
geojson_lines_of_sight,
geojson_walls,
pulsing_dots_layers_sources,
asset_point_animations,
cpu_frame_rate,
last_frame,
animation_speed_factor
);
}
});
// set printable Message
printableMessage = "Animation speed factor has been set to '" + animation_speed_factor + "x'.";
// print to console and to console_debugger
console.log(printableMessage);
printOnConsoleDebugger(printableMessage);
}
/**
* Stop Asset Point Animations
* @param {FeatureCollection} geojson_asset_points Asset Points FeatureCollection
*/
function stopAssetPointsAnimations(geojson_asset_points) {
geojson_asset_points.features.forEach(index => {
var currentAssetFeatureId = index.properties.id;
if (animatingAssetPointFlags[currentAssetFeatureId]) {
// set animatingPointFlags to false
animatingAssetPointFlags[currentAssetFeatureId] = false;
// remove 'trace' layer and source if already exists on map
if (map.getLayer(`trace-ap${currentAssetFeatureId + 1}`)) {
map.removeLayer(`trace-ap${currentAssetFeatureId + 1}`);
}
if (map.getSource(`trace-ap${currentAssetFeatureId + 1}`)) {
map.removeSource(`trace-ap${currentAssetFeatureId + 1}`);
}
// set printable Message
printableMessage3 = "Stop of Asset Point Animations... ";
// print to console and to console_debugger
console.log(printableMessage3);
printOnConsoleDebugger(printableMessage3);
}
});
}
//
/**
* Async function to animate Asset Point with a custom move
* @async
* @param {number} index Asset Point index ID
* @param {FeatureCollection} geojson_asset_points Asset Points FeatureCollection
* @param {FeatureCollection} geojson_assetpoints_directions Asset Points Directions FeatureCollection
* @param {FeatureCollection} geojson_anchors Anchors FeatureCollection
* @param {FeatureCollection} geojson_antennas Antennas FeatureCollection
* @param {FeatureCollection} wall_intersections_points Map Features Walls Points Intersections FeatureCollection
* @param {FeatureCollection} geojson_lines_of_sight Lines of Sight FeatureCollection
* @param {FeatureCollection} geojson_walls Map Features Walls FeatureCollection
* @param {Array} pulsing_dots_layers_sources Pulsing Dots sources Array
* @param {Array} animations Pulsing Dots sources Array
* @param {number} cpu_frame_rate CPU frame rate
* @param {number} last_frame last frame
* @param {number} animation_speed_factor value of animation speed factor
* @returns {null} null if no animations is setted
*/
async function animateAssetPointWithCustomMove(
index,
geojson_asset_points,
geojson_assetpoints_directions,
geojson_anchors,
geojson_antennas,
wall_intersections_points,
geojson_lines_of_sight,
geojson_walls,
pulsing_dots_layers_sources,
animations,
cpu_frame_rate,
last_frame,
animation_speed_factor
) {
// Find the index of the first symbol layer in the map style
const layers = map.getStyle().layers;
let firstLinesOfSightLayerId;
for (const layer of layers) {
if (layer.id === 'layer-with-lines') {
firstLinesOfSightLayerId = layer.id;
break;
}
}
var animation_geojson = '';
var color = '';
var currentAssetFeatureId = index.properties.id;
if (!animatingAssetPointFlags[currentAssetFeatureId]) {
switch (index.properties.animation_option_index) {
case 1:
printableMessage = `Animation 1 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[0]
color = '#69d4ff';
break;
case 2:
printableMessage = `Animation 2 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[1]
color = '#ad96ff';
break;
case 3:
printableMessage = `Animation 3 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[2]
color = '#96ffb1';
break;
case 4:
printableMessage = `Animation 4 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[3]
color = '#ff944d';
break;
case 5:
printableMessage = `Animation 5 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[4]
color = '#fcd303';
break;
case 6:
printableMessage = `Animation 6 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[5]
color = '#6bfc03';
break;
case 7:
printableMessage = `Animation 7 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[6]
color = '#0341fc';
break;
case 8:
printableMessage = `Animation 8 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[7]
color = '#de0202';
break;
case 9:
printableMessage = `Animation 9 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[8]
color = '#57ffe6';
break;
case 10:
printableMessage = `Animation 10 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[9]
color = '#90efe6';
break;
case 11:
printableMessage = `Animation 11 was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = animations[10]
color = '#9050e6';
break;
default:
printableMessage = `Default animation null was selected for AP ${currentAssetFeatureId + 1}.`
animation_geojson = null
break;
}
console.log(printableMessage);
printOnConsoleDebugger(printableMessage)
if (animation_geojson == null) {
printableMessage = `Animation for Asset Point ${currentAssetFeatureId + 1} was not setted!`
console.log(printableMessage);
printOnConsoleDebugger(printableMessage)
return;
}
// We fetch the JSON here so that we can parse and use it separately
// from GL JS's use in the added source.
const response = await fetch(animation_geojson);
const data = await response.json();
// save full coordinate list for later
const coordinates = data.features[0].geometry.coordinates;
// set animatingPointFlag to true
animatingAssetPointFlags[currentAssetFeatureId] = true;
// set disable 'Start Animation' button and enable 'Stop Animation' button
document.getElementById('btn_start_animations').disabled = true;
document.getElementById('btn_stop_animations').disabled = false;
document.getElementById('draw-assetpoint').disabled = true;
document.getElementById('delete-assetpoint').disabled = true;
document.getElementById('draw-antenna').disabled = true;
document.getElementById('delete-antenna').disabled = true;
document.getElementById('draw-anchor').disabled = true;
document.getElementById('delete-anchor').disabled = true;
// update button color
updateAnimationColorButtonsOnStart();
// start by showing just the first coordinate
data.features[0].geometry.coordinates = [coordinates[0]];
// remove 'trace' layer and source if already exists on map
if (map.getLayer(`trace-ap${currentAssetFeatureId + 1}`)) {
map.removeLayer(`trace-ap${currentAssetFeatureId + 1}`);
}
if (map.getSource(`trace-ap${currentAssetFeatureId + 1}`)) {
map.removeSource(`trace-ap${currentAssetFeatureId + 1}`);
}
// set 1st printableMessage
printableMessage1 = `Animate Asset Point ${currentAssetFeatureId + 1}... `;
// print to console and to console_debugger
console.log(printableMessage1);
printOnConsoleDebugger(printableMessage1);
// add 'trace' layer and source
map.addSource(`trace-ap${currentAssetFeatureId + 1}`, { type: 'geojson', data: data });
map.addLayer({
'id': `trace-ap${currentAssetFeatureId + 1}`,
'type': 'line',
'source': `trace-ap${currentAssetFeatureId + 1}`,
'paint': {
'line-color': color,
'line-opacity': 0.5,
'line-width': 6,
}
}, firstLinesOfSightLayerId);
// setup the viewport on coordinate index 0
map.flyTo({ 'center': coordinates[0], 'zoom': 21, 'speed': 0.5 });
// on a regular basis, add more coordinates from the saved list and update the map
let i = 0;
const timer = setInterval(async () => {
// get current date and time
const currentDate = new Date();
var now = currentDate.getTime();
// limit to (cpu_frame_rate/10) updates per second
if ((now - last_frame) < cpu_frame_rate) {
return;
};
// Call event to close all open popups
map.fire('closeAllPopups');
if (i < coordinates.length && animatingAssetPointFlags[currentAssetFeatureId]) {
// save last position coordinate
lastCoord = geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates;
// save new position coordinate
newCoord = coordinates[i];
// get bearing between two locations
directionLargeLobe = getBearingBetweenLocations(lastCoord, newCoord);
// set large and small lobes of asset point
geojson_asset_points.features[currentAssetFeatureId].properties.angle_direction_large_lobe = directionLargeLobe;
geojson_asset_points.features[currentAssetFeatureId].properties.angle_direction_small_lobe = rescrictTo180Degrees(parseFloat(directionLargeLobe) + 180);
// push actual animation coordinate
data.features[0].geometry.coordinates.push(coordinates[i]);
geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates = coordinates[i];
// Call setData to the source layer `trace` on it.
map.getSource(`trace-ap${currentAssetFeatureId + 1}`).setData(data)
// Call setData to the source layer `geojson_asset_points` on it.
map.getSource('asset-points').setData(geojson_asset_points);
// remove (splice) the direction at currentAssetFeatureId from 'geojson_assetpoints_directions' FeatureCollection
geojson_assetpoints_directions.features.splice(currentAssetFeatureId * 2, 2);
// create assetpoint Lobe Direction at currentAssetFeatureId
createAssetPointLobesDirection(geojson_asset_points.features[currentAssetFeatureId], geojson_assetpoints_directions)
// Call setData to the source layer `places` on it.
map.getSource('assetpoints_directions').setData(geojson_assetpoints_directions);
// Print the coordinates of where the point had
// finished being moved to on the map.
messageToPrint =
`<strong>${geojson_asset_points.features[currentAssetFeatureId].properties.title} Coordinates: </strong><br /> ` +
`• Longitude: ${rescrictTo180Degrees(geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[0])} ` +
`(${convertDMSLng(rescrictTo180Degrees(geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[0]))}) <br /> ` +
`• Latitude: ${geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[1]} ` +
`(${convertDMSLat(geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[1])})`;
// Update container innerHTML
updateContainerInnerHtml(coordinates_point_container, messageToPrint);
// set 2nd printableMessage
printableMessage2 = `<strong>Coordinates (Long, Lat):</strong><br />` +
`(${geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[0]}, ` +
`${geojson_asset_points.features[currentAssetFeatureId].geometry.coordinates[1]})`;
// print to console and to console_debugger
console.log(printableMessage2);
printOnConsoleDebugger(printableMessage2);
// Start the LinesOfSight animation.
animateLinesOfSight(geojson_asset_points, geojson_anchors, geojson_antennas, geojson_lines_of_sight);
// Start the IntersectionPoints animation.
animateWallIntersectionPoints(wall_intersections_points, geojson_lines_of_sight, geojson_walls);
// Start the pulsingDotPoints animation.
animatePulsingDotPoints(pulsing_dots_layers_sources);
// update last_fame with now time
last_frame = now;
// increment index
i++;
} else {
window.clearInterval(timer);
// set animatingAssetPointFlag to false
animatingAssetPointFlags[currentAssetFeatureId] = false;
// set enable 'Start Animation' button and disable 'Stop Animation' button
document.getElementById('btn_start_animations').disabled = false;
document.getElementById('btn_stop_animations').disabled = true;
document.getElementById('draw-assetpoint').disabled = false;
document.getElementById('delete-assetpoint').disabled = false;
document.getElementById('draw-antenna').disabled = false;
document.getElementById('delete-antenna').disabled = false;
document.getElementById('draw-anchor').disabled = false;
document.getElementById('delete-anchor').disabled = false;
// update button color
updateAnimationColorButtonsOnStop();
// set 3rd printableMessage
printableMessage3 = `End of Asset Point ${currentAssetFeatureId + 1} Animation!`;
// print to console and to console_debugger
console.log(printableMessage3);
printOnConsoleDebugger(printableMessage3);
}
}, 1000 / animation_speed_factor);
}
}
// =========== End of Asset Point Animations Functions =========== //
Source