2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23 import React, {Component, PropTypes} from 'react';
24 import {geoAlbersUsa, geoEquirectangular, geoPath} from 'd3-geo';
25 import {feature, mesh} from 'topojson';
34 } from './MapConstants.js';
35 import usMapJson from './mapJson/usJson.json';
36 import worldMapJson from './mapJson/worldJson.json';
38 class TopographicMap extends Component {
40 width: PropTypes.number,
41 height: PropTypes.number,
42 pointArray: PropTypes.array,
43 currentProjection: PropTypes.string
46 static defaultProps = {
50 currentProjection: PROJECTION_TYPES.ALBERS_USA
57 landFeatures: undefined,
58 boundaryMesh: undefined,
62 this.setCurrentProjection = this.setCurrentProjection.bind(this);
63 this.processAndRenderMapData = this.processAndRenderMapData.bind(this);
64 this.generateLandFeatures = this.generateLandFeatures.bind(this);
65 this.generateBoundaryMesh = this.generateBoundaryMesh.bind(this);
66 this.generatePlotPointArray = this.generatePlotPointArray.bind(this);
67 this.extractNestedObjectInJson = this.extractNestedObjectInJson.bind(this);
68 this.areArraysEqual = this.areArraysEqual.bind(this);
70 this.setCurrentProjection(props.currentProjection);
71 this.projection.translate([this.props.width / 2, this.props.height / 2]);
72 this.path = geoPath().projection(this.projection);
73 this.didProjectionTypeChange = true;
74 this.isMapMounted = false;
77 componentWillReceiveProps(nextProps) {
78 if (!this.areArraysEqual(this.props.pointArray, nextProps.pointArray)) {
79 if (this.props.currentProjection !== nextProps.currentProjection) {
80 this.didProjectionTypeChange = true;
81 this.setCurrentProjection(nextProps.currentProjection);
83 if (this.isMapMounted) {
84 this.processAndRenderMapData(nextProps.pointArray);
90 this.isMapMounted = true;
91 this.processAndRenderMapData(this.props.pointArray);
94 setCurrentProjection(projectionType) {
95 switch (projectionType) {
96 case PROJECTION_TYPES.ALBERS_USA:
97 this.projection = geoAlbersUsa();
100 case PROJECTION_TYPES.EQUIRECTANGULAR:
101 this.projection = geoEquirectangular();
105 // TODO -> FE logging should be a thing at some point. Maybe a log call
111 processAndRenderMapData(plotPointArray) {
112 let landFeatures = this.state.landFeatures;
113 let boundaryMesh = this.state.boundaryMesh;
114 let plotPoints = this.state.plotPoints;
116 switch (this.props.currentProjection) {
117 case PROJECTION_TYPES.ALBERS_USA:
118 if (this.didProjectionTypeChange) {
120 this.generateLandFeatures(usMapJson,
121 MAP_OBJECT_KEYS.ALBERS_USA_LAND_KEYS);
123 this.generateBoundaryMesh(usMapJson,
124 MAP_OBJECT_KEYS.ALBERS_USA_BOUNDARY_KEYS);
125 this.didProjectionTypeChange = false;
127 plotPoints = this.generatePlotPointArray(plotPointArray);
129 case PROJECTION_TYPES.EQUIRECTANGULAR:
130 if (this.didProjectionTypeChange) {
132 this.generateLandFeatures(worldMapJson,
133 MAP_OBJECT_KEYS.EQUIRECTANGULAR_LAND_KEYS);
135 this.generateBoundaryMesh(worldMapJson,
136 MAP_OBJECT_KEYS.EQUIRECTANGULAR_BOUNDARY_KEYS);
137 this.didProjectionTypeChange = false;
139 plotPoints = this.generatePlotPointArray(plotPointArray);
143 // TODO -> FE logging should be a thing at some point. Maybe a log call
148 this.setState(() => {
150 landFeatures: landFeatures,
151 boundaryMesh: boundaryMesh,
152 plotPoints: plotPoints
157 generateLandFeatures(jsonData, featureKeys) {
158 let featureType = this.extractNestedObjectInJson(jsonData, featureKeys);
159 let landFeature = undefined;
160 if (featureType !== undefined) {
161 let landFeaturePath = this.path(feature(jsonData, featureType));
162 let landFeatureProps = {
163 className: 'land-features',
165 key: LAND_FEATURE_KEY
168 React.createElement(PLOT_POINT_SHAPES.PATH, landFeatureProps);
173 generateBoundaryMesh(jsonData, boundaryKeys) {
174 let boundaryType = this.extractNestedObjectInJson(jsonData, boundaryKeys);
175 let boundary = undefined;
176 if (boundaryType !== undefined) {
177 let boundaryPath = this.path(mesh(jsonData, boundaryType, (a, b) => {
180 let boundaryProps = {
181 className: 'boundary-mesh',
183 key: BOUNDARY_MESH_KEY
185 boundary = React.createElement(PLOT_POINT_SHAPES.PATH, boundaryProps);
190 generatePlotPointArray(pointArray) {
191 let generatedPoints = [];
192 if (pointArray !== undefined && pointArray.length > 0) {
193 generatedPoints = pointArray.map((longLat, index) => {
194 let projectedLongLat = this.projection(
195 [longLat.longitude, longLat.latitude]);
196 let plotPointProps = {
197 className: 'plot-point',
199 cx: projectedLongLat[0],
200 cy: projectedLongLat[1],
201 key: PLOT_POINT_KEY_BASE + index,
203 return React.createElement(PLOT_POINT_SHAPES.CIRCLE, plotPointProps);
206 return generatedPoints;
210 let {landFeatures, boundaryMesh, plotPoints} = this.state;
211 let {width, height} = this.props;
214 <div width={width} height={height}>
215 <svg width={width} height={height}>
226 extractNestedObjectInJson(jsonData, keysArray) {
227 let subObject = undefined;
228 if (jsonData !== undefined && keysArray !== undefined) {
229 subObject = jsonData[keysArray[0]];
230 if (subObject !== undefined) {
231 for (let i = 1; i < keysArray.length; i++) {
232 subObject = subObject[keysArray[i]];
239 areArraysEqual(arrayOne, arrayTwo) {
240 if (arrayOne.length !== arrayTwo.length) {
243 for (let i = 0; i < arrayOne.length; i++) {
244 if (arrayOne[i] instanceof Array && arrayTwo instanceof Array) {
245 if (!this.areArraysEqual(arrayOne[i], arrayTwo[i])) {
249 else if (arrayOne[i] !== arrayTwo[i]) {
257 export default TopographicMap;