2 * ============LICENSE_START===================================================
3 * SPARKY (AAI UI service)
4 * ============================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
8 * ============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=====================================================
22 * ECOMP and OpenECOMP are trademarks
23 * and service marks of AT&T Intellectual Property.
26 import React, {Component, PropTypes} from 'react';
27 import {geoAlbersUsa, geoEquirectangular, geoPath} from 'd3-geo';
28 import {feature, mesh} from 'topojson';
37 } from './MapConstants.js';
38 import usMapJson from './mapJson/usJson.json';
39 import worldMapJson from './mapJson/worldJson.json';
41 class TopographicMap extends Component {
43 width: PropTypes.number,
44 height: PropTypes.number,
45 pointArray: PropTypes.array,
46 currentProjection: PropTypes.string
49 static defaultProps = {
53 currentProjection: PROJECTION_TYPES.ALBERS_USA
60 landFeatures: undefined,
61 boundaryMesh: undefined,
65 this.setCurrentProjection = this.setCurrentProjection.bind(this);
66 this.processAndRenderMapData = this.processAndRenderMapData.bind(this);
67 this.generateLandFeatures = this.generateLandFeatures.bind(this);
68 this.generateBoundaryMesh = this.generateBoundaryMesh.bind(this);
69 this.generatePlotPointArray = this.generatePlotPointArray.bind(this);
70 this.extractNestedObjectInJson = this.extractNestedObjectInJson.bind(this);
71 this.areArraysEqual = this.areArraysEqual.bind(this);
73 this.setCurrentProjection(props.currentProjection);
74 this.projection.translate([this.props.width / 2, this.props.height / 2]);
75 this.path = geoPath().projection(this.projection);
76 this.didProjectionTypeChange = true;
77 this.isMapMounted = false;
80 componentWillReceiveProps(nextProps) {
81 if (!this.areArraysEqual(this.props.pointArray, nextProps.pointArray)) {
82 if (this.props.currentProjection !== nextProps.currentProjection) {
83 this.didProjectionTypeChange = true;
84 this.setCurrentProjection(nextProps.currentProjection);
86 if (this.isMapMounted) {
87 this.processAndRenderMapData(nextProps.pointArray);
93 this.isMapMounted = true;
94 this.processAndRenderMapData(this.props.pointArray);
97 setCurrentProjection(projectionType) {
98 switch (projectionType) {
99 case PROJECTION_TYPES.ALBERS_USA:
100 this.projection = geoAlbersUsa();
103 case PROJECTION_TYPES.EQUIRECTANGULAR:
104 this.projection = geoEquirectangular();
108 // TODO -> FE logging should be a thing at some point. Maybe a log call
114 processAndRenderMapData(plotPointArray) {
115 let landFeatures = this.state.landFeatures;
116 let boundaryMesh = this.state.boundaryMesh;
117 let plotPoints = this.state.plotPoints;
119 switch (this.props.currentProjection) {
120 case PROJECTION_TYPES.ALBERS_USA:
121 if (this.didProjectionTypeChange) {
123 this.generateLandFeatures(usMapJson,
124 MAP_OBJECT_KEYS.ALBERS_USA_LAND_KEYS);
126 this.generateBoundaryMesh(usMapJson,
127 MAP_OBJECT_KEYS.ALBERS_USA_BOUNDARY_KEYS);
128 this.didProjectionTypeChange = false;
130 plotPoints = this.generatePlotPointArray(plotPointArray);
132 case PROJECTION_TYPES.EQUIRECTANGULAR:
133 if (this.didProjectionTypeChange) {
135 this.generateLandFeatures(worldMapJson,
136 MAP_OBJECT_KEYS.EQUIRECTANGULAR_LAND_KEYS);
138 this.generateBoundaryMesh(worldMapJson,
139 MAP_OBJECT_KEYS.EQUIRECTANGULAR_BOUNDARY_KEYS);
140 this.didProjectionTypeChange = false;
142 plotPoints = this.generatePlotPointArray(plotPointArray);
146 // TODO -> FE logging should be a thing at some point. Maybe a log call
151 this.setState(() => {
153 landFeatures: landFeatures,
154 boundaryMesh: boundaryMesh,
155 plotPoints: plotPoints
160 generateLandFeatures(jsonData, featureKeys) {
161 let featureType = this.extractNestedObjectInJson(jsonData, featureKeys);
162 let landFeature = undefined;
163 if (featureType !== undefined) {
164 let landFeaturePath = this.path(feature(jsonData, featureType));
165 let landFeatureProps = {
166 className: 'land-features',
168 key: LAND_FEATURE_KEY
171 React.createElement(PLOT_POINT_SHAPES.PATH, landFeatureProps);
176 generateBoundaryMesh(jsonData, boundaryKeys) {
177 let boundaryType = this.extractNestedObjectInJson(jsonData, boundaryKeys);
178 let boundary = undefined;
179 if (boundaryType !== undefined) {
180 let boundaryPath = this.path(mesh(jsonData, boundaryType, (a, b) => {
183 let boundaryProps = {
184 className: 'boundary-mesh',
186 key: BOUNDARY_MESH_KEY
188 boundary = React.createElement(PLOT_POINT_SHAPES.PATH, boundaryProps);
193 generatePlotPointArray(pointArray) {
194 let generatedPoints = [];
195 if (pointArray !== undefined && pointArray.length > 0) {
196 generatedPoints = pointArray.map((longLat, index) => {
197 let projectedLongLat = this.projection(
198 [longLat.longitude, longLat.latitude]);
199 let plotPointProps = {
200 className: 'plot-point',
202 cx: projectedLongLat[0],
203 cy: projectedLongLat[1],
204 key: PLOT_POINT_KEY_BASE + index,
206 return React.createElement(PLOT_POINT_SHAPES.CIRCLE, plotPointProps);
209 return generatedPoints;
213 let {landFeatures, boundaryMesh, plotPoints} = this.state;
214 let {width, height} = this.props;
217 <div width={width} height={height}>
218 <svg width={width} height={height}>
229 extractNestedObjectInJson(jsonData, keysArray) {
230 let subObject = undefined;
231 if (jsonData !== undefined && keysArray !== undefined) {
232 subObject = jsonData[keysArray[0]];
233 if (subObject !== undefined) {
234 for (let i = 1; i < keysArray.length; i++) {
235 subObject = subObject[keysArray[i]];
242 areArraysEqual(arrayOne, arrayTwo) {
243 if (arrayOne.length !== arrayTwo.length) {
246 for (let i = 0; i < arrayOne.length; i++) {
247 if (arrayOne[i] instanceof Array && arrayTwo instanceof Array) {
248 if (!this.areArraysEqual(arrayOne[i], arrayTwo[i])) {
252 else if (arrayOne[i] !== arrayTwo[i]) {
260 export default TopographicMap;