summaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/networkMapApp/src/components/map
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/apps/networkMapApp/src/components/map')
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx59
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx53
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx697
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx94
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx161
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx57
6 files changed, 0 insertions, 1121 deletions
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx
deleted file mode 100644
index 3b5a15ce5..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/connectionInfo.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react'
-
-import { IApplicationStoreState } from "../../../../../framework/src/store/applicationStore";
-import connect, { IDispatcher, Connect } from "../../../../../framework/src/flux/connect";
-import { Paper, Typography } from "@material-ui/core";
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
-
-
-type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
-
-const ConnectionInfo: React.FunctionComponent<props> = (props) => {
-
- return ((props.isTopoServerReachable === false || props.isTileServerReachable === false )? <Paper style={{padding:5, position: 'absolute', top: 160, width: 230, left:"40%", zIndex:1}}>
- <div style={{display: 'flex', flexDirection: 'column'}}>
- <div style={{'alignSelf': 'center', marginBottom:5}}> <Typography> <FontAwesomeIcon icon={faExclamationTriangle} /> Connection Error</Typography></div>
- {props.isTileServerReachable === false && <Typography> Tile data can't be loaded.</Typography>}
- {props.isTopoServerReachable === false && <Typography > Network data can't be loaded.</Typography>}
- </div>
- </Paper> : null
-)
-
-}
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable,
- isTileServerReachable: state.network.connectivity.isTileServerAvailable
-
-});
-
-
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
-
- //zoomToSearchResult: (lat: number, lon: number) => dispatcher.dispatch(new ZoomToSearchResultAction(lat, lon))
-
-});;
-
-
-export default connect(mapStateToProps,mapDispatchToProps)(ConnectionInfo)
-
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx
deleted file mode 100644
index 221e7dab8..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/iconSwitch.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react';
-import { FormControlLabel, Switch, Paper } from "@material-ui/core";
-import connect, { Connect, IDispatcher } from '../../../../../framework/src/flux/connect';
-import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
-import { SetIconSwitchAction } from '../../actions/mapActions';
-
-type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps> & {visible: boolean}
-
-const IconSwitch: React.FunctionComponent<props> = (props) =>{
-
- const toggleChecked = () => {
- props.toogle(!props.areIconsEnabled)
- };
-
- return (
- props.visible ?
- <FormControlLabel style={{ padding:5, position: 'absolute',top: 190, zIndex:1}}
- value="end"
- control={<Switch color="secondary" style={{zIndex:1}} checked={props.areIconsEnabled} onChange={toggleChecked} />}
- label="Show icons"
- labelPlacement="end"
- />: null)
-}
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- areIconsEnabled: state.network.map.allowIconSwitch
-});
-
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
- toogle : (enable:boolean) => dispatcher.dispatch(new SetIconSwitchAction(enable))
-
-});;
-
-export default (connect(mapStateToProps,mapDispatchToProps)(IconSwitch))
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx
deleted file mode 100644
index 1314edbba..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/map.tsx
+++ /dev/null
@@ -1,697 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react'
-import * as mapboxgl from 'mapbox-gl';
-import { RouteComponentProps, withRouter } from 'react-router-dom';
-
-
-import { Site } from '../../model/site';
-import { SelectSiteAction, ClearHistoryAction, SelectLinkAction } from '../../actions/detailsAction';
-import { OSM_STYLE, URL_API, URL_BASEPATH, URL_TILE_API } from '../../config';
-import { link } from '../../model/link';
-import MapPopup from './mapPopup';
-import { SetPopupPositionAction, SelectMultipleLinksAction, SelectMultipleSitesAction } from '../../actions/popupActions';
-import { Feature } from '../../model/Feature';
-import { HighlightLinkAction, HighlightSiteAction, SetCoordinatesAction, SetStatistics } from '../../actions/mapActions';
-import { addDistance, getUniqueFeatures, increaseBoundingBox } from '../../utils/mapUtils';
-import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
-import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect';
-import SearchBar from './searchBar';
-import { verifyResponse, IsTileServerReachableAction, handleConnectionError, setTileServerReachableAction, IsBusycheckingConnectivityAction } from '../../actions/connectivityAction';
-import ConnectionInfo from './connectionInfo'
-import mapLayerService from '../../utils/mapLayers';
-import Statistics from './statistics';
-import IconSwitch from './iconSwitch';
-import { addImages } from '../../services/mapImagesService';
-import { PopupElement } from '../../model/popupElements';
-import { Button } from '@material-ui/core';
-import { NavigateToApplication } from '../../../../../framework/src/actions/navigationActions';
-import customize from '../../../icons/customize.png';
-
-type coordinates = { lat: number, lon: number, zoom: number }
-
-let alarmElements: Feature[] = [];
-let map: mapboxgl.Map;
-let isLoadingInProgress = false;
-let notLoadedBoundingBoxes: mapboxgl.LngLatBounds[] = [];
-
-let lastBoundingBox: mapboxgl.LngLatBounds | null = null;
-let myRef = React.createRef<HTMLDivElement>();
-
-import 'mapbox-gl/dist/mapbox-gl.css';
-
-class Map extends React.Component<mapProps, { isPopupOpen: boolean }> {
-
- constructor(props: mapProps) {
- super(props);
- //any state stuff
- this.state = { isPopupOpen: false }
-
- }
-
- updateTheme(){
- mapLayerService.settings=this.props.settings.themes;
- if(this.props.settings.mapSettings?.networkMap.styling.theme){
- mapLayerService.selectedTheme = this.props.settings.mapSettings?.networkMap.styling.theme;
- }
- }
-
- updateOpacity(){
- if(this.props.settings.mapSettings && this.props.settings.mapSettings.networkMap.tileOpacity){
- mapLayerService.changeMapOpacity(map, Number(this.props.settings.mapSettings.networkMap.tileOpacity));
- }
- }
-
- async componentDidMount() {
-
- // resize the map, if menu gets collapsed
- window.addEventListener("menu-resized", this.handleResize);
-
- //pass themes to mapLayerService
- this.updateTheme();
-
- // try if connection to tile + topologyserver are available
-
- try {
- const tiles = await fetch(URL_TILE_API + '/10/0/0.png');
- if (tiles.ok) {
- this.props.setTileServerLoaded(true);
- }else{
- this.props.setTileServerLoaded(false);
- }
-
- } catch (error) {
- this.props.setTileServerLoaded(false);
- console.error("tileserver " + URL_TILE_API + " can't be reached.");
- }
-
- try {
- const topology = await fetch(URL_API + "/info/count/all");
- verifyResponse(topology);
- } catch (error) {
- this.props.handleConnectionError(error)
- }
-
- //both done
- this.props.setConnectivityCheck(false);
- //map loaded in componentDidUpdate
- }
-
- setupMap = () => {
-
- let lat = this.props.lat;
- let lon = this.props.lon;
- let zoom = this.props.zoom;
-
- if(this.props.settings.mapSettings){
- if(this.props.settings.mapSettings.networkMap.startupPosition.latitude){
- lat = Number(this.props.settings.mapSettings.networkMap.startupPosition.latitude)
- }
-
- if(this.props.settings.mapSettings.networkMap.startupPosition.longitude){
- lon = Number(this.props.settings.mapSettings.networkMap.startupPosition.longitude)
- }
-
- if(this.props.settings.mapSettings.networkMap.startupPosition.zoom){
- zoom = Number(this.props.settings.mapSettings.networkMap.startupPosition.zoom)
- }
-
- }
-
- const coordinates = this.extractCoordinatesFromUrl();
- // override lat/lon/zoom with coordinates from url, if available
- if (this.areCoordinatesValid(coordinates)) {
- lat = coordinates.lat;
- lon = coordinates.lon;
- zoom = !Number.isNaN(coordinates.zoom) ? coordinates.zoom : zoom;
- }
-
- map = new mapboxgl.Map({
- container: myRef.current!,
- style: OSM_STYLE as any,
- center: [lon, lat],
- zoom: zoom,
- accessToken: ''
- });
-
- map.on('load', (ev) => {
-
- map.setMaxZoom(18);
- const bbox = map.getBounds();
- this.props.updateMapPosition(bbox.getCenter().lat, bbox.getCenter().lng, map.getZoom())
-
- mapLayerService.addBaseSources(map, this.props.selectedSite, this.props.selectedLink);
-
- addImages(map, (result: boolean)=>{
- if(map.getZoom()>11 && this.props.showIcons)
- {
- mapLayerService.addIconLayers(map, this.props.selectedSite?.properties.id)
- }else{
- mapLayerService.addBaseLayers(map);
- }
- this.updateOpacity();
-
- });
-
- const boundingBox = increaseBoundingBox(map);
-
- fetch(`${URL_API}/links/geojson/${boundingBox.west},${boundingBox.south},${boundingBox.east},${boundingBox.north}`)
- .then(result => verifyResponse(result))
- .then(result => result.json())
- .then(features => {
- if (map.getSource('lines')) {
- (map.getSource('lines') as mapboxgl.GeoJSONSource).setData(features);
- }
- })
- .catch(error => this.props.handleConnectionError(error));
-
-
- fetch(`${URL_API}/sites/geojson/${boundingBox.west},${boundingBox.south},${boundingBox.east},${boundingBox.north}`)
- .then(result => verifyResponse(result))
- .then(result => result.json())
- .then(features => {
- if (map.getSource('points')) {
- (map.getSource('points') as mapboxgl.GeoJSONSource).setData(features);
- }
- })
- .catch(error => this.props.handleConnectionError(error));
-
- map.on('click', this.mapClick);
- map.on('moveend', this.mapMoveEnd);
- map.on('move', this.mapMove);
-
- });
- }
-
- mapMove = () => {
-
- const mapZoom = map.getZoom();
-
- const boundingBox = map.getBounds();
-
- this.loadNetworkData(boundingBox);
- if (mapZoom > 9) {
-
- if (map.getLayer('points')) {
- map.setLayoutProperty('selectedPoints', 'visibility', 'visible');
- map.setPaintProperty('points', 'circle-radius', 7);
- }
- } else {
-
- // reduce size of points / lines if zoomed out
- map.setPaintProperty('points', 'circle-radius', 2);
- map.setLayoutProperty('selectedPoints', 'visibility', 'none');
-
- if (mapZoom <= 4) {
- map.setPaintProperty('fibre-lines', 'line-width', 1);
- map.setPaintProperty('microwave-lines', 'line-width', 1);
-
- } else {
- map.setPaintProperty('fibre-lines', 'line-width', 2);
- map.setPaintProperty('microwave-lines', 'line-width', 2);
- }
- }
- };
-
- mapClick = (e: any) => {
-
-
- if (map.getLayer('points')) { // data is shown as points
-
- var clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
- [e.point.x + 5, e.point.y + 5]], {
- layers: ['microwave-lines', 'fibre-lines']
- }), "id");
-
- const clickedPoints = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['points'] }), "id");
- const alarmedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['alarmedPoints'] }), "id");
-
- if (clickedPoints.length != 0) {
-
-
- if (alarmedSites.length > 0) {
- alarmedSites.forEach(alarm => {
- const index = clickedPoints.findIndex(item => item.properties!.id === alarm.properties!.id);
-
- if (index !== -1) {
- clickedPoints[index].properties!.alarmed = true;
- clickedPoints[index].properties!.type = "alarmed";
- }
- });
- }
-
- this.showSitePopup(clickedPoints, e.point.x, e.point.y);
- } else if (clickedLines.length != 0) {
- this.showLinkPopup(clickedLines, e.point.x, e.point.y);
- }
-
-
- } else { // data is shown as icons
-
- const clickedSites = getUniqueFeatures(map.queryRenderedFeatures(e.point, { layers: ['point-lamps', 'point-building', 'point-data-center', 'point-factory', 'point-remaining'] }), "id");
- const clickedLines = getUniqueFeatures(map.queryRenderedFeatures([[e.point.x - 5, e.point.y - 5],
- [e.point.x + 5, e.point.y + 5]], {
- layers: ['microwave-lines', 'fibre-lines']
- }), "id");
-
- if (clickedSites.length > 0)
- this.showSitePopup(clickedSites, e.point.x, e.point.y);
- else if (clickedLines.length != 0) {
- this.showLinkPopup(clickedLines, e.point.x, e.point.y);
- }
- }
- };
-
- mapMoveEnd = () => {
-
- const mapZoom = Number(map.getZoom().toFixed(2));
- const lat = Number(map.getCenter().lat.toFixed(4));
- const lon = Number(map.getCenter().lng.toFixed(4));
-
-
- if (this.props.lat !== lat || this.props.lon !== lon || this.props.zoom !== mapZoom) {
- this.props.updateMapPosition(lat, lon, mapZoom)
- }
-
- // update the url to current lat,lon,zoom values
-
- const currentUrl = window.location.href;
- const parts = currentUrl.split(URL_BASEPATH);
- if (parts.length > 0) {
-
- const detailsPath = parts[1].split("/details/");
-
- if (detailsPath[1] !== undefined && detailsPath[1].length > 0) {
- this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}/details/${detailsPath[1]}`)
- }
- else {
- this.props.history.replace(`/${URL_BASEPATH}/${map.getCenter().lat.toFixed(4)},${map.getCenter().lng.toFixed(4)},${mapZoom.toFixed(2)}`)
- }
- }
-
-
- //switch icon layers if applicable
-
- mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id);
-
- //update statistics
- const boundingBox = map.getBounds();
-
- fetch(`${URL_API}/info/count/${boundingBox.getWest()},${boundingBox.getSouth()},${boundingBox.getEast()},${boundingBox.getNorth()}`)
- .then(result => verifyResponse(result))
- .then(res => res.json())
- .then(result => {
- if (result.links !== this.props.linkCount || result.sites !== this.props.siteCount) {
- this.props.setStatistics(result.links, result.sites);
- }
- })
- .catch(error => this.props.handleConnectionError(error));;
- }
-
- componentDidUpdate(prevProps: mapProps, prevState: {}) {
-
- if(prevProps !== this.props){
- //(load map)
- //triggered if either settings were done loading or tile/topology server connectivity checked
- if(prevProps.settings !== this.props.settings || this.props.isConnectivityCheckBusy !== prevProps.isConnectivityCheckBusy){
-
- //update theme if settings changed
- if(prevProps.settings !== this.props.settings){
- this.updateTheme();
- }
-
- //if everything done loading/reachable, load map
- if(!this.props.isConnectivityCheckBusy && this.props.isTileServerReachable && !this.props.settings.isLoadingData && (prevProps.settings.isLoadingData !==this.props.settings.isLoadingData || prevProps.isConnectivityCheckBusy !== this.props.isConnectivityCheckBusy)){
-
- if(map == undefined){
- this.setupMap();
- }
- else
- if(map.getContainer() !== myRef.current){
- // reload map, because the current container (fresh div) doesn't hold the map and changing containers isn't supported
- map.remove();
- this.setupMap();
- }
- }
- }
-
- if (map !== undefined) {
- if (prevProps.selectedSite?.properties.id !== this.props.selectedSite?.properties.id) {
-
- if (this.props.selectedSite != null) {
- if (map.getSource("selectedLine") !== undefined) {
- (map.getSource("selectedLine") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [] });
- (map.getSource("selectedPoints") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [this.props.selectedSite] });
- }
-
-
- if (map.getLayer('point-lamps') !== undefined) {
-
- map.setFilter('point-lamps', ['==', 'type', 'street lamp']);
- map.setFilter('point-data-center', ['==', 'type', 'data center']);
- map.setFilter('point-building', ['==', 'type', 'high rise building']);
- map.setFilter('point-factory', ['==', 'type', 'factory']);
-
- if (this.props.selectedSite?.properties.type !== undefined) {
- switch (this.props.selectedSite?.properties.type) {
- case 'street lamp':
- map.setFilter('point-lamps', ["all", ['==', 'type', 'street lamp'], ['!=', 'id', this.props.selectedSite.properties.id]]);
- break;
- case 'data center':
- map.setFilter('point-data-center', ["all", ['==', 'type', 'data center'], ['!=', 'id', this.props.selectedSite.properties.id]]);
- break;
- case 'high rise building':
- map.setFilter('point-building', ["all", ['==', 'type', 'high rise building'], ['!=', 'id', this.props.selectedSite.properties.id]])
- break;
- case 'factory':
- map.setFilter('point-factory', ["all", ['==', 'type', 'factory'], ['!=', 'id', this.props.selectedSite.properties.id]]);
- break;
- }
- }
- }
-
-
- }
- else
- {
- if (map.getSource("selectedPoints") !== undefined)
- (map.getSource("selectedPoints") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [] });
-
- }
- }
-
- if (prevProps.selectedLink !== this.props.selectedLink) {
- if (this.props.selectedLink != null) {
-
- if (map.getLayer('point-lamps') !== undefined) {
- map.setFilter('point-lamps', ['==', 'type', 'street lamp']);
- map.setFilter('point-data-center', ['==', 'type', 'data center']);
- map.setFilter('point-building', ['==', 'type', 'high rise building']);
- map.setFilter('point-factory', ['==', 'type', 'factory']);
- }
-
- if (map.getSource("selectedLine") !== undefined) {
- (map.getSource("selectedPoints") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [] });
- (map.getSource("selectedLine") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [this.props.selectedLink] });
- }
- }
- else
- {
- if (map.getSource("selectedLine") !== undefined)
- (map.getSource("selectedLine") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: [] });
- }
- }
-
- if (prevProps.location.pathname !== this.props.location.pathname) {
- if (map) {
- const coordinates = this.extractCoordinatesFromUrl();
- this.moveMapToCoordinates(coordinates);
- }
- }
-
- if (prevProps.alarmlement !== this.props.alarmlement) {
- if (this.props.alarmlement !== null && !alarmElements.includes(this.props.alarmlement)) {
- if (map.getSource("alarmedPoints"))
- (map.getSource("alarmedPoints") as mapboxgl.GeoJSONSource).setData({ type: "FeatureCollection", features: alarmElements });
- alarmElements.push(this.props.alarmlement)
- }
- }
-
- if (prevProps.showIcons !== this.props.showIcons) {
- if (map && map.getZoom() > 11) {
- mapLayerService.showIconLayers(map, this.props.showIcons, this.props.selectedSite?.properties.id);
- }
- }
-
- if (prevProps.zoomToElement !== this.props.zoomToElement) {
- if (this.props.zoomToElement !== null) {
- const currentZoom = map?.getZoom();
-
- map.flyTo({
- center: [
- this.props.zoomToElement.lon,
- this.props.zoomToElement.lat
- ], zoom: currentZoom < 10 ? 10 : currentZoom,
- essential: true
- });
- }
- }
- }
- }
- }
-
- componentWillUnmount(){
-
- //unregister events
- window.removeEventListener("menu-resized", this.handleResize);
-
- if(map){
- map.off('click', this.mapClick);
- map.off('moveend', this.mapMoveEnd);
- map.off('move', this.mapMove);
- }
-
- lastBoundingBox=null;
-
- // will be checked again on next load
- this.props.setConnectivityCheck(true);
- }
-
- handleResize = () => {
- if (map) {
- // wait a moment until resizing actually happened
- window.setTimeout(() => map.resize(), 500);
- }
- }
-
- extractCoordinatesFromUrl = (): coordinates => {
- const currentUrl = window.location.href;
- const mainPathParts = currentUrl.split(URL_BASEPATH);
- const coordinatePathPart = mainPathParts[1].split("/details/"); // split by details if present
- const allCoordinates = coordinatePathPart[0].replace("/", "");
- const coordinates = allCoordinates.split(",");
- return { lat: Number(coordinates[0]), lon: Number(coordinates[1]), zoom: Number(coordinates[2]) }
- }
-
- areCoordinatesValid = (coordinates: coordinates) => {
-
- if ((!Number.isNaN(coordinates.lat)) && (!Number.isNaN(coordinates.lon))) {
- return true;
- } else {
- return false;
- }
- }
-
- moveMapToCoordinates = (coordinates: coordinates) => {
-
- if (this.areCoordinatesValid(coordinates)) {
- let zoom = -1;
-
- if (!Number.isNaN(coordinates.zoom)) {
- zoom = coordinates.zoom;
- }
-
- map.flyTo({
- center: [
- coordinates.lon,
- coordinates.lat
- ], zoom: zoom !== -1 ? zoom : this.props.zoom,
- essential: true
- })
- }
- }
-
- loadNetworkData = async (bbox: mapboxgl.LngLatBounds) => {
- if (!isLoadingInProgress) { // only load data if loading not in progress
- isLoadingInProgress = true;
-
- if (lastBoundingBox == null) {
- lastBoundingBox = bbox;
- await this.draw('lines', `${URL_API}/links/geojson/${lastBoundingBox.getWest()},${lastBoundingBox.getSouth()},${lastBoundingBox.getEast()},${lastBoundingBox.getNorth()}`);
- await this.draw('points', `${URL_API}/sites/geojson/${lastBoundingBox.getWest()},${lastBoundingBox.getSouth()},${lastBoundingBox.getEast()},${lastBoundingBox.getNorth()}`);
- } else {
-
- // new bbox is bigger than old one
- if (bbox.contains(lastBoundingBox.getNorthEast()) && bbox.contains(lastBoundingBox.getSouthWest()) && lastBoundingBox !== bbox) { //if new bb is bigger than old one
-
- lastBoundingBox = bbox;
-
- //calculate new boundingBox
- const increasedBoundingBox = increaseBoundingBox(map);
-
- await this.draw('lines', `${URL_API}/links/geojson/${increasedBoundingBox.west},${increasedBoundingBox.south},${increasedBoundingBox.east},${increasedBoundingBox.north}`);
- await this.draw('points', `${URL_API}/sites/geojson/${increasedBoundingBox.west},${increasedBoundingBox.south},${increasedBoundingBox.east},${increasedBoundingBox.north}`);
-
- } else if (lastBoundingBox.contains(bbox.getNorthEast()) && lastBoundingBox.contains(bbox.getSouthWest())) { // last one contains new one
- // bbox is contained in last one, do nothing
- isLoadingInProgress = false;
-
- } else { // bbox is not fully contained in old one, extend
-
- lastBoundingBox.extend(bbox);
-
- await this.draw('lines', `${URL_API}/links/geojson/${lastBoundingBox.getWest()},${lastBoundingBox.getSouth()},${lastBoundingBox.getEast()},${lastBoundingBox.getNorth()}`);
- await this.draw('points', `${URL_API}/sites/geojson/${lastBoundingBox.getWest()},${lastBoundingBox.getSouth()},${lastBoundingBox.getEast()},${lastBoundingBox.getNorth()}`);
- }
-
- }
-
-
- if (notLoadedBoundingBoxes.length > 0) { // load last not loaded boundingbox
- this.loadNetworkData(notLoadedBoundingBoxes.pop()!)
- notLoadedBoundingBoxes = [];
- }
-
- } else {
- notLoadedBoundingBoxes.push(bbox);
- }
- }
-
- showSitePopup = (sites: mapboxgl.MapboxGeoJSONFeature[], top: number, left: number) => {
- if (sites.length > 1) {
- const elements: PopupElement[] = sites.map(feature => {return {name: feature.properties!.name, id: feature.properties!.id}});
-
- this.props.setPopupPosition(top, left);
- this.props.selectMultipleSites(elements); //name, id object container
- this.setState({ isPopupOpen: true });
-
- } else {
- const id = sites[0].properties!.id;
-
- fetch(`${URL_API}/sites/${id}`)
- .then(result => verifyResponse(result))
- .then(res => res.json() as Promise<Site>)
- .then(result => {
- this.props.selectSite(result);
- this.props.highlightSite(result);
- this.props.clearDetailsHistory();
- })
- .catch(error => this.props.handleConnectionError(error));;
- }
- }
-
- showLinkPopup = (links: mapboxgl.MapboxGeoJSONFeature[], top: number, left: number) => {
-
- if (links.length > 1) {
-
- const elements: PopupElement[] = links.map(feature => {return {name: feature.properties!.name, id: feature.properties!.id}});
-
- this.props.setPopupPosition(top, left);
- this.props.selectMultipleLinks(elements);
- this.setState({ isPopupOpen: true });
-
- } else {
- var id = links[0].properties!.id;
-
- fetch(`${URL_API}/links/${id}`)
- .then(result => verifyResponse(result))
- .then(res => res.json() as Promise<link>)
- .then(result => {
- this.props.selectLink(result);
- this.props.highlightLink(result);
-
- this.props.clearDetailsHistory();
- })
- .catch(error => this.props.handleConnectionError(error));;
- }
- }
-
- draw = async (layer: string, url: string) => {
-
- fetch(url)
- .then(result => verifyResponse(result))
- .then(res => res.json())
- .then(result => {
- isLoadingInProgress = false;
- if (map.getSource(layer)) {
- (map.getSource(layer) as mapboxgl.GeoJSONSource).setData(result);
- }
- })
- .catch(error => this.props.handleConnectionError(error));;
- }
-
- render() {
-
- return <>
-
-{
- !this.props.settings.isLoadingData ?
-
- <div id="map" style={{ width: "70%", position: 'relative' }} ref={myRef} >
- {
- this.state.isPopupOpen &&
- <MapPopup onClose={() => { this.setState({ isPopupOpen: false }); }} />
- }
- <SearchBar />
- <Statistics />
- <IconSwitch visible={this.props.zoom>11} />
- <ConnectionInfo />
- <Button
- disabled={!this.props.isTopoServerReachable}
- style={{'position': 'absolute', 'right':5, top:5, backgroundColor:'white', zIndex:1}}
- onClick={e => this.props.navigateToApplication("network", "customize")} >
- <img src={customize} />
- </Button>
- </div>
- :<div style={{ width: "70%", position: 'relative' }} />
-
- }
- </>
- }
-
-}
-
-type mapProps = RouteComponentProps & Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- selectedLink: state.network.map.selectedLink,
- selectedSite: state.network.map.selectedSite,
- zoomToElement: state.network.map.zoomToElement,
- alarmlement: state.network.map.alarmlement,
- lat: state.network.map.lat,
- lon: state.network.map.lon,
- zoom: state.network.map.zoom,
- linkCount: state.network.map.statistics.links,
- siteCount: state.network.map.statistics.sites,
- isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable,
- isTileServerReachable: state.network.connectivity.isTileServerAvailable,
- isConnectivityCheckBusy: state.network.connectivity.isBusy,
- showIcons: state.network.map.allowIconSwitch,
- settings: state.network.settings,
-});
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
- selectSite: (site: Site) => dispatcher.dispatch(new SelectSiteAction(site)),
- selectLink: (link: link) => dispatcher.dispatch(new SelectLinkAction(link)),
- clearDetailsHistory: () => dispatcher.dispatch(new ClearHistoryAction()),
- selectMultipleLinks: (ids: PopupElement[]) => dispatcher.dispatch(new SelectMultipleLinksAction(ids)),
- selectMultipleSites: (ids: PopupElement[]) => dispatcher.dispatch(new SelectMultipleSitesAction(ids)),
- setPopupPosition: (x: number, y: number) => dispatcher.dispatch(new SetPopupPositionAction(x, y)),
- highlightLink: (link: link) => dispatcher.dispatch(new HighlightLinkAction(link)),
- highlightSite: (site: Site) => dispatcher.dispatch(new HighlightSiteAction(site)),
- updateMapPosition: (lat: number, lon: number, zoom: number) => dispatcher.dispatch(new SetCoordinatesAction(lat, lon, zoom)),
- setStatistics: (linkCount: string, siteCount: string) => dispatcher.dispatch(new SetStatistics(siteCount, linkCount)),
- setTileServerLoaded: (reachable: boolean) => dispatcher.dispatch(setTileServerReachableAction(reachable)),
- handleConnectionError: (error: Error) => dispatcher.dispatch(handleConnectionError(error)),
- navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path, "test3")),
- setConnectivityCheck: (done: boolean) => dispatcher.dispatch(new IsBusycheckingConnectivityAction(done)),
-
-})
-
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Map)); \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx
deleted file mode 100644
index 7a64f5a58..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/mapPopup.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react';
-import { Typography, Select, MenuItem, ClickAwayListener, Popper, Paper, FormGroup, Portal, Popover } from '@material-ui/core';
-import { SelectSiteAction, ClearHistoryAction, ClearDetailsAction } from '../../actions/detailsAction';
-import { Site } from '../../model/site';
-import { link } from '../../model/link';
-import { URL_API } from '../../config';
-import { HighlightLinkAction, HighlightSiteAction } from '../../actions/mapActions';
-import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
-import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect';
-import { verifyResponse, handleConnectionError } from '../../actions/connectivityAction';
-
-
-
-
-const MapPopup: React.FunctionComponent<props> = (props) => {
-
- const [value, setValue] = React.useState("");
-
- const handleChange = (event: any) => {
- setValue(event.target.value);
-
- const id = event.target.value;
-
-
- fetch(`${URL_API}/${props.type.toLocaleLowerCase()}s/${id}`)
- .then(result => verifyResponse(result))
- .then(res => res.json())
- .then(result => {
- props.clearDetailsHistory();
- props.selectElement(result);
- props.type === "link" ? props.highlightLink(result) : props.highlightSite(result)
- props.onClose();
- })
- .catch(error => {
- props.handleConnectionError(error);
- props.onClose();
- // props.clearDetails();
- });
- };
-
- return <>
- <Popover open={true} anchorEl={undefined} onClose={props.onClose} anchorReference="anchorPosition" anchorPosition={{ top: props.position.left, left: props.position.top }}>
- <Paper style={{ padding: "15px" }}>
- <Typography variant="h5">{`Multiple ${props.type.toLowerCase()}s were selected`}</Typography>
- <Typography variant="body1">Please select one.</Typography>
- <Select style={{ width: 300 }} onChange={handleChange} value={value} native>
- <option value={""} disabled>{props.type} ids</option>
- {
- props.elements.map(el => <option key={el.id} value={el.id}>{el.name}</option>)
- }
- </Select>
- </Paper>
- </Popover>
- </>
-}
-
-type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>& { onClose(): void }
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- elements: state.network.popup.selectionPendingForElements,
- type: state.network.popup.pendingDataType,
- position: state.network.popup.position
-
-});
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
- selectElement: (site: Site) => dispatcher.dispatch(new SelectSiteAction(site)),
- clearDetailsHistory:()=> dispatcher.dispatch(new ClearHistoryAction()),
- highlightLink: (link: link) => dispatcher.dispatch(new HighlightLinkAction(link)),
- highlightSite: (site: Site) => dispatcher.dispatch(new HighlightSiteAction(site)),
- handleConnectionError: (error:Error) => dispatcher.dispatch(handleConnectionError(error)),
- clearDetails: () => dispatcher.dispatch(new ClearDetailsAction()),
-
-});
-
-export default (connect(mapStateToProps, mapDispatchToProps))(MapPopup); \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx
deleted file mode 100644
index 307c5d203..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/searchBar.tsx
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react';
-import { makeStyles, Paper, InputBase, IconButton, Divider, Popover, Typography } from '@material-ui/core';
-import SearchIcon from '@material-ui/icons/Search';
-
-import { URL_API } from '../../config';
-import { isSite } from '../../utils/utils';
-import { Site } from '../../model/site';
-import { link } from '../../model/link';
-import { SelectSiteAction, SelectLinkAction } from '../../actions/detailsAction';
-import { HighlightLinkAction, HighlightSiteAction, ZoomToSearchResultAction } from '../../actions/mapActions';
-import { calculateMidPoint } from '../../utils/mapUtils';
-import { SetSearchValueAction } from '../../actions/searchAction';
-import connect,{ Connect, IDispatcher } from '../../../../../framework/src/flux/connect';
-import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
-
-
-
-
-
-
-const styles = makeStyles({
- root: {
- //{ padding:5, position: 'absolute', display:'flex', flexDirection:"column",top: 150, width: 200}
- padding: '2px 4px',
- position: 'absolute',
- display:'flex',
- alignItems: 'center',
- top: 15,
- marginLeft: 5,
- width: 400,
- zIndex:1
- },
- input: {
- flex: 1,
- marginLeft: 5
- },
- iconButton: {
- padding: 10,
- },
- divider: {
- height: 28,
- margin: 4,
- },
- });
-
-
-const SearchBar: React.FunctionComponent<searchBarProps> = (props) =>{
-
- const classes = styles();
- const [anchorEl, setAnchorEl] = React.useState<any>(null);
- const [errorMessage, setErrorMessage] = React.useState("");
-
- const divRef = React.useRef();
-
- const handleClick = (e: any) =>{
-
- setAnchorEl(null);
- if(props.searchterm.length>0){
-
- const siteResult = fetch(`${URL_API}/sites/name/${props.searchterm}`)
-
- const linkResult = fetch(`${URL_API}/links/${props.searchterm}`);
-
- Promise.all([ siteResult, linkResult]).then((result)=>{
- const suceededResults = result.filter(el=> el.ok);
-
- if(suceededResults.length==0){
- setAnchorEl(divRef.current);
- setErrorMessage("No element found.")
- // hide message after 3 sec
- window.setTimeout(()=>{setAnchorEl(null)}, 3000);
-
- }else{
- suceededResults[0].json().then(result =>{
- if(isSite(result)){
- props.selectSite(result);
- props.highlightSite(result);
- props.zoomToSearchResult(result.location.lat, result.location.lon);
- }else{
- props.selectLink(result);
- props.highlightLink(result);
- const midPoint = calculateMidPoint(result.locationA.lat, result.locationA.lon, result.locationB.lat, result.locationB.lon);
- props.zoomToSearchResult(midPoint[1], midPoint[0])
- }
- });
- }
- });
- }
- e.preventDefault();
-}
-
- const open = Boolean(anchorEl);
-
- const reachabe = props.isTopoServerReachable && props.isTileServerReachable;
-
- return (
- <>
- <Paper ref={divRef} component="form" className={classes.root}>
- <InputBase
- disabled={!reachabe}
- className={classes.input}
- placeholder="Find sites or links by name"
- inputProps={{ 'aria-label': 'networkmap-searchbar' }}
- value={props.searchterm}
- onChange={e=> props.setSearchTerm(e.currentTarget.value)}
- />
- <Divider className={classes.divider} orientation="vertical" />
- <IconButton type="submit" className={classes.iconButton} aria-label="search" onClick={handleClick}>
- <SearchIcon />
- </IconButton>
- </Paper>
- <Popover open={open} onClose={e=> setAnchorEl(null)} anchorEl={anchorEl} anchorOrigin={{
- vertical: "bottom",
- horizontal: "left"
- }}>
- <Paper style={{width: 380, padding:10}}>
- <Typography variant="body1">{errorMessage}</Typography>
- </Paper>
- </Popover>
- </>
- );
-}
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- searchterm: state.network.search.value,
- isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable,
- isTileServerReachable: state.network.connectivity.isTileServerAvailable
-
-});
-
-type searchBarProps = Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
-
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
- selectSite:(site: Site)=> dispatcher.dispatch(new SelectSiteAction(site)),
- selectLink:(link: link) => dispatcher.dispatch(new SelectLinkAction(link)),
- highlightLink:(link: link)=> dispatcher.dispatch(new HighlightLinkAction(link)),
- highlightSite: (site: Site) => dispatcher.dispatch(new HighlightSiteAction(site)),
- setSearchTerm: (value: string) => dispatcher.dispatch(new SetSearchValueAction(value)),
- zoomToSearchResult: (lat: number, lon: number) => dispatcher.dispatch(new ZoomToSearchResultAction(lat, lon)),
-});;
-
-export default (connect(mapStateToProps,mapDispatchToProps)(SearchBar)) \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx
deleted file mode 100644
index 562689198..000000000
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/map/statistics.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt odlux
- * =================================================================================================
- * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- */
-
-import * as React from 'react';
-import { Paper, Typography, Tooltip } from '@material-ui/core';
-import InfoIcon from '@material-ui/icons/Info';
-
-import { IApplicationStoreState } from '../../../../../framework/src/store/applicationStore';
-import connect, { IDispatcher, Connect } from '../../../../../framework/src/flux/connect';
-
-type props = Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
-
-const mapStateToProps = (state: IApplicationStoreState) => ({
- linkCount: state.network.map.statistics.links,
- siteCount: state.network.map.statistics.sites,
- isTopoServerReachable: state.network.connectivity.isToplogyServerAvailable,
- isTileServerReachable: state.network.connectivity.isTileServerAvailable,
-
-});
-
-const mapDispatchToProps = (dispatcher: IDispatcher) => ({
-});
-
-const Statistics: React.FunctionComponent<props> = (props: props) =>{
-
- const reachabe = props.isTopoServerReachable && props.isTileServerReachable;
-
-
- return (<Paper style={{ padding: 5, position: 'absolute', display: 'flex', flexDirection: "column", top: 70, width: 200, marginLeft: 5, zIndex:1 }}>
- <div style={{ display: 'flex', flexDirection: "row" }}>
- <Typography style={{ fontWeight: "bold", flex: "1", color: reachabe ? "black" : "lightgrey" }} >Statistics</Typography>
- <Tooltip style={{ alignSelf: "flex-end" }} title="Gets updated when the map stops moving.">
- <InfoIcon fontSize="small" />
- </Tooltip>
- </div>
-
- <Typography style={{ color: reachabe ? "black" : "lightgrey" }}>Sites: {props.siteCount}</Typography>
- <Typography style={{ color: reachabe ? "black" : "lightgrey" }}>Links: {props.linkCount}</Typography>
-</Paper>)
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(Statistics);