Skip to content

Commit e96ee5e

Browse files
authored
Sitemap NLCD Classes (#26)
* sitemap show nlcd class in location popup * sitemap show NLCD class in table view * sitemap grouped overlays support with nlcd layers * clean up grouped layer control presentation * overlay legend support * NLCD Impervious Surface support with legend * bump version to v1.5.5
1 parent 14708ac commit e96ee5e

20 files changed

+4047
-3435
lines changed

lib/components/SiteMap/SiteMapContainer.js

Lines changed: 312 additions & 34 deletions
Large diffs are not rendered by default.

lib/components/SiteMap/SiteMapContext.d.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ declare namespace Provider {
1818
unusableVerticalSpace: PropTypes.Requireable<number>;
1919
mapCenter: PropTypes.Requireable<(number | null | undefined)[]>;
2020
mapZoom: PropTypes.Requireable<number>;
21-
mapTileLayer: PropTypes.Requireable<string>;
21+
mapBaseLayer: PropTypes.Requireable<string>;
2222
location: PropTypes.Requireable<string>;
2323
selection: PropTypes.Requireable<string>;
2424
selectedItems: PropTypes.Requireable<(string | null | undefined)[]>;
@@ -50,6 +50,7 @@ declare function useSiteMapContext(): any[] | {
5050
status: null;
5151
error: null;
5252
};
53+
isAtCenter: boolean;
5354
};
5455
aspectRatio: {
5556
currentValue: null;
@@ -69,8 +70,9 @@ declare function useSiteMapContext(): any[] | {
6970
zoom: null;
7071
center: never[];
7172
bounds: null;
72-
tileLayer: null;
73-
tileLayerAutoChangedAbove17: boolean;
73+
baseLayer: null;
74+
baseLayerAutoChangedAbove17: boolean;
75+
overlays: Set<any>;
7476
zoomedIcons: {};
7577
repositionOpenPopupFunc: null;
7678
};
@@ -98,14 +100,17 @@ declare function useSiteMapContext(): any[] | {
98100
sites: {};
99101
filters: {
100102
search: null;
103+
legendOpen: boolean;
101104
features: {
102-
open: boolean;
103105
available: {};
104106
visible: {
105107
[k: string]: boolean;
106108
};
107109
collapsed: Set<any>;
108110
};
111+
overlays: {
112+
expanded: Set<any>;
113+
};
109114
};
110115
fullscreen: boolean;
111116
};

lib/components/SiteMap/SiteMapContext.js

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,30 @@ var centerIsValid = function centerIsValid(center) {
169169
return Array.isArray(center) && center.length === 2 && center.every(function (v) {
170170
return typeof v === 'number';
171171
});
172-
};
172+
}; // Creates fetch objects with an AWAITING_CALL status based on current state.
173+
// New fetches are created for all fetchable feature data found to be active (the feature is
174+
// available and visible), within the current bounds of the map, and not already fetched.
175+
// Optionally include required sites to consider "in bounds" (useful for when a focus location
176+
// is a site feature like a plot far from the site center so the site itself may not be seen as
177+
// "in bounds").
178+
173179

174180
var calculateFeatureDataFetches = function calculateFeatureDataFetches(state) {
181+
var requiredSites = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
175182
var sitesInMap = (0, _SiteMapUtils.calculateLocationsInMap)(state.sites, state.map.bounds, true, 0.06);
183+
var requiredSitesArray = [];
184+
185+
if (requiredSites) {
186+
requiredSitesArray = (Array.isArray(requiredSites) ? requiredSites : [requiredSites]).filter(function (siteCode) {
187+
return Object.keys(state.sites).includes(siteCode);
188+
});
189+
}
190+
191+
requiredSitesArray.forEach(function (siteCode) {
192+
if (!sitesInMap.includes(siteCode)) {
193+
sitesInMap.push(siteCode);
194+
}
195+
});
176196

177197
if (!sitesInMap.length) {
178198
return state;
@@ -397,6 +417,7 @@ var calculateFeatureDataFetches = function calculateFeatureDataFetches(state) {
397417

398418
var reducer = function reducer(state, action) {
399419
var setMethod = null;
420+
var calculateFetchesRequiredSites = null;
400421

401422
var newState = _extends({}, state);
402423

@@ -661,14 +682,14 @@ var reducer = function reducer(state, action) {
661682

662683

663684
var updateMapTileWithZoom = function updateMapTileWithZoom() {
664-
if (newState.map.zoom <= 17 && state.map.tileLayer !== _SiteMapUtils.TILE_LAYERS.NATGEO_WORLD_MAP.KEY && state.map.tileLayerAutoChangedAbove17) {
665-
newState.map.tileLayer = _SiteMapUtils.TILE_LAYERS.NATGEO_WORLD_MAP.KEY;
666-
newState.map.tileLayerAutoChangedAbove17 = false;
685+
if (newState.map.zoom <= 17 && state.map.baseLayer !== _SiteMapUtils.BASE_LAYERS.NATGEO_WORLD_MAP.KEY && state.map.baseLayerAutoChangedAbove17) {
686+
newState.map.baseLayer = _SiteMapUtils.BASE_LAYERS.NATGEO_WORLD_MAP.KEY;
687+
newState.map.baseLayerAutoChangedAbove17 = false;
667688
}
668689

669-
if (newState.map.zoom >= 17 && state.map.tileLayer === _SiteMapUtils.TILE_LAYERS.NATGEO_WORLD_MAP.KEY) {
670-
newState.map.tileLayer = _SiteMapUtils.TILE_LAYERS.WORLD_IMAGERY.KEY;
671-
newState.map.tileLayerAutoChangedAbove17 = true;
690+
if (newState.map.zoom >= 17 && state.map.baseLayer === _SiteMapUtils.BASE_LAYERS.NATGEO_WORLD_MAP.KEY) {
691+
newState.map.baseLayer = _SiteMapUtils.BASE_LAYERS.WORLD_IMAGERY.KEY;
692+
newState.map.baseLayerAutoChangedAbove17 = true;
672693
}
673694
}; // Shortcuts for deailing with hierarchies
674695

@@ -731,6 +752,7 @@ var reducer = function reducer(state, action) {
731752
}
732753

733754
newState.map.zoom = action.zoom;
755+
newState.focusLocation.isAtCenter = false;
734756

735757
if (centerIsValid(action.center)) {
736758
newState.map.center = action.center;
@@ -749,6 +771,7 @@ var reducer = function reducer(state, action) {
749771
newState.map.bounds = action.bounds;
750772
}
751773

774+
newState.focusLocation.isAtCenter = false;
752775
return calculateFeatureDataFetches(newState);
753776

754777
case 'setMapCenter':
@@ -761,14 +784,44 @@ var reducer = function reducer(state, action) {
761784
}
762785

763786
newState.map.center = _toConsumableArray(action.center);
787+
newState.focusLocation.isAtCenter = false;
764788
return calculateFeatureDataFetches(newState);
765789

766-
case 'setMapTileLayer':
767-
if (!Object.keys(_SiteMapUtils.TILE_LAYERS).includes(action.tileLayer)) {
790+
case 'setMapBaseLayer':
791+
if (action.baseLayer !== null && !Object.keys(_SiteMapUtils.BASE_LAYERS).includes(action.baseLayer)) {
792+
return state;
793+
}
794+
795+
newState.map.baseLayer = action.baseLayer;
796+
return newState;
797+
798+
case 'setMapOverlayVisibility':
799+
if (!_SiteMapUtils.OVERLAYS[action.overlay]) {
768800
return state;
769801
}
770802

771-
newState.map.tileLayer = action.tileLayer;
803+
if (action.visible) {
804+
newState.map.overlays.add(action.overlay);
805+
newState.filters.overlays.expanded.add(action.overlay);
806+
} else {
807+
newState.map.overlays.delete(action.overlay);
808+
newState.filters.overlays.expanded.delete(action.overlay);
809+
}
810+
811+
return newState;
812+
813+
case 'setMapOverlays':
814+
if (!Array.isArray(action.overlays) || !action.overlays.every(function (o) {
815+
return _SiteMapUtils.OVERLAYS[o];
816+
})) {
817+
return state;
818+
}
819+
820+
newState.map.overlays = new Set(action.overlays);
821+
newState.filters.overlays.expanded = new Set();
822+
action.overlays.forEach(function (overlay) {
823+
newState.filters.overlays.expanded.add(overlay);
824+
});
772825
return newState;
773826

774827
case 'setMapRepositionOpenPopupFunc':
@@ -778,14 +831,15 @@ var reducer = function reducer(state, action) {
778831
case 'showFullObservatory':
779832
newState.map.center = _SiteMapUtils.OBSERVATORY_CENTER;
780833
newState.map.zoom = (0, _SiteMapUtils.deriveFullObservatoryZoomLevel)(action.mapRef);
834+
newState.focusLocation.isAtCenter = false;
781835
return newState;
782836
// Features
783837

784-
case 'setFilterFeaturesOpen':
785-
newState.filters.features.open = !!action.open;
838+
case 'setLegendOpen':
839+
newState.filters.legendOpen = !!action.open;
786840
return newState;
787841

788-
case 'setFilterFeatureVisibility':
842+
case 'setLegendFeatureOptionVisibility':
789843
if (!Object.keys(_SiteMapUtils.FEATURES).includes(action.feature) || typeof action.visible !== 'boolean') {
790844
return state;
791845
}
@@ -794,21 +848,37 @@ var reducer = function reducer(state, action) {
794848
applyFeatureVisibilityToParents(action.feature);
795849
return calculateFeatureDataFetches(newState);
796850

797-
case 'setFilterFeatureCollapsed':
851+
case 'setLegendFeatureOptionCollapsed':
798852
if (!Object.keys(_SiteMapUtils.FEATURES).includes(action.feature)) {
799853
return state;
800854
}
801855

802856
newState.filters.features.collapsed.add(action.feature);
803857
return newState;
804858

805-
case 'setFilterFeatureExpanded':
859+
case 'setLegendFeatureOptionExpanded':
806860
if (!Object.keys(_SiteMapUtils.FEATURES).includes(action.feature)) {
807861
return state;
808862
}
809863

810864
newState.filters.features.collapsed.delete(action.feature);
811865
return newState;
866+
867+
case 'setLegendOverlayOptionCollapsed':
868+
if (!Object.keys(_SiteMapUtils.OVERLAYS).includes(action.overlay)) {
869+
return state;
870+
}
871+
872+
newState.filters.overlays.expanded.delete(action.overlay);
873+
return newState;
874+
875+
case 'setLegendOverlayOptionExpanded':
876+
if (!Object.keys(_SiteMapUtils.OVERLAYS).includes(action.overlay)) {
877+
return state;
878+
}
879+
880+
newState.filters.overlays.expanded.add(action.overlay);
881+
return newState;
812882
// Focus Location
813883

814884
case 'setNewFocusLocation':
@@ -864,7 +934,12 @@ var reducer = function reducer(state, action) {
864934
completeOverallFetch();
865935
newState.map = (0, _SiteMapUtils.getMapStateForFocusLocation)(newState);
866936
updateMapTileWithZoom();
867-
return calculateFeatureDataFetches((0, _SiteMapUtils.calculateFeatureAvailability)(newState));
937+
938+
if (newState.focusLocation.data && newState.focusLocation.data.siteCode) {
939+
calculateFetchesRequiredSites = [newState.focusLocation.data.siteCode];
940+
}
941+
942+
return calculateFeatureDataFetches((0, _SiteMapUtils.calculateFeatureAvailability)(newState), calculateFetchesRequiredSites);
868943
// Fetch and Import
869944

870945
case 'awaitingFeatureDataFetchesTriggered':
@@ -912,7 +987,12 @@ var reducer = function reducer(state, action) {
912987

913988
newState.overallFetch.pendingHierarchy -= 1;
914989
completeOverallFetch();
915-
return calculateFeatureDataFetches(newState);
990+
991+
if (state.focusLocation.isAtCenter && state.focusLocation.data && state.focusLocation.data.siteCode) {
992+
calculateFetchesRequiredSites = [state.focusLocation.data.siteCode];
993+
}
994+
995+
return calculateFeatureDataFetches(newState, calculateFetchesRequiredSites);
916996

917997
case 'setDomainLocationHierarchyFetchFailed':
918998
/* eslint-disable max-len */
@@ -1033,7 +1113,7 @@ var Provider = function Provider(props) {
10331113
fullscreen = props.fullscreen,
10341114
mapZoom = props.mapZoom,
10351115
mapCenter = props.mapCenter,
1036-
mapTileLayer = props.mapTileLayer,
1116+
mapBaseLayer = props.mapBaseLayer,
10371117
locationProp = props.location,
10381118
selection = props.selection,
10391119
validItems = props.validItems,
@@ -1060,7 +1140,7 @@ var Provider = function Provider(props) {
10601140
initialState.map = _extends({}, initialState.map, {
10611141
zoom: initialMapZoom,
10621142
center: mapCenter,
1063-
tileLayer: mapTileLayer
1143+
baseLayer: mapBaseLayer
10641144
});
10651145

10661146
if (typeof locationProp === 'string') {

lib/components/SiteMap/SiteMapFeature.js

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ var _Tooltip = _interopRequireDefault(require("@material-ui/core/Tooltip"));
3131

3232
var _Typography = _interopRequireDefault(require("@material-ui/core/Typography"));
3333

34+
var _HelpOutline = _interopRequireDefault(require("@material-ui/icons/HelpOutline"));
35+
3436
var _TouchApp = _interopRequireDefault(require("@material-ui/icons/TouchApp"));
3537

3638
var _Terrain = _interopRequireDefault(require("@material-ui/icons/Terrain"));
@@ -213,6 +215,14 @@ var useStyles = (0, _styles.makeStyles)(function (theme) {
213215
},
214216
unselectable: {
215217
filter: 'saturate(0.3) brightness(2)'
218+
},
219+
nlcdClass: {
220+
width: '36px',
221+
height: '12px',
222+
border: '1px solid black',
223+
marginLeft: theme.spacing(1.5),
224+
marginBottom: '-2px',
225+
display: 'inline-block'
216226
}
217227
};
218228
});
@@ -678,7 +688,7 @@ var SiteMapFeature = function SiteMapFeature(props) {
678688
"data-selenium": "sitemap-map-popup-plotSlope"
679689
}, /*#__PURE__*/_react.default.createElement(_Typography.default, {
680690
variant: "subtitle2"
681-
}, "Plot Slope"), renderNumericalValue(loc.slopeAspect, 'Aspect', '�', 2, 'Slope Aspect', right), renderNumericalValue(loc.slopeGradient, 'Gradient', '%', 2, 'Slope Gradient', right));
691+
}, "Plot Slope"), renderNumericalValue(loc.slopeAspect, 'Aspect', "\xB0", 2, 'Slope Aspect', right), renderNumericalValue(loc.slopeGradient, 'Gradient', '%', 2, 'Slope Gradient', right));
682692
};
683693
/**
684694
Render: Plot Sampling Modules
@@ -721,7 +731,7 @@ var SiteMapFeature = function SiteMapFeature(props) {
721731
variant: "subtitle2"
722732
}, "Area"), /*#__PURE__*/_react.default.createElement("div", {
723733
className: classes.startFlex
724-
}, renderNumericalValue(areaKm2, null, 'km²', 2, 'Area (km²)'), areaAcres === null ? null : /*#__PURE__*/_react.default.createElement("div", {
734+
}, renderNumericalValue(areaKm2, null, "km\xB2", 2, "Area (km\xB2)"), areaAcres === null ? null : /*#__PURE__*/_react.default.createElement("div", {
725735
style: {
726736
marginLeft: _Theme.default.spacing(1)
727737
}
@@ -816,6 +826,57 @@ var SiteMapFeature = function SiteMapFeature(props) {
816826
variant: "caption"
817827
}, (loc.children || []).length));
818828
};
829+
/**
830+
Render: Popup Row; NLCD Classes (nationalLandCoverDatabase2001)
831+
*/
832+
833+
834+
var renderNlcdClass = function renderNlcdClass(loc) {
835+
var nlcd = /*#__PURE__*/_react.default.createElement("i", null, "n/a");
836+
837+
var titleStyle = {};
838+
839+
if (loc.nlcdClass) {
840+
nlcd = loc.nlcdClass;
841+
842+
if (_SiteMapUtils.NLCD_CLASSES[loc.nlcdClass]) {
843+
titleStyle.marginBottom = '-4px';
844+
var tooltip = "".concat(_SiteMapUtils.NLCD_CLASSES[loc.nlcdClass].name, " - ").concat(_SiteMapUtils.NLCD_CLASSES[loc.nlcdClass].description);
845+
nlcd = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, _SiteMapUtils.NLCD_CLASSES[loc.nlcdClass].name, /*#__PURE__*/_react.default.createElement("div", {
846+
className: classes.nlcdClass,
847+
title: _SiteMapUtils.NLCD_CLASSES[loc.nlcdClass].name,
848+
style: {
849+
backgroundColor: _SiteMapUtils.NLCD_CLASSES[loc.nlcdClass].color
850+
}
851+
}), /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
852+
title: tooltip
853+
}, /*#__PURE__*/_react.default.createElement(_IconButton.default, {
854+
size: "small",
855+
style: {
856+
marginLeft: _Theme.default.spacing(0.5),
857+
marginBottom: '1px'
858+
},
859+
"aria-label": "NLCD Class Description"
860+
}, /*#__PURE__*/_react.default.createElement(_HelpOutline.default, {
861+
style: {
862+
fontSize: '1rem'
863+
}
864+
}))));
865+
}
866+
}
867+
868+
return /*#__PURE__*/_react.default.createElement(_Grid.default, {
869+
key: "nlcdClass",
870+
item: true,
871+
xs: 12,
872+
"data-selenium": "sitemap-map-popup-nlcdClass"
873+
}, /*#__PURE__*/_react.default.createElement(_Typography.default, {
874+
variant: "subtitle2",
875+
style: titleStyle
876+
}, "NLCD Class"), /*#__PURE__*/_react.default.createElement(_Typography.default, {
877+
variant: "caption"
878+
}, nlcd));
879+
};
819880
/**
820881
Render: Popup Row; Location Site and Domain
821882
*/
@@ -881,7 +942,7 @@ var SiteMapFeature = function SiteMapFeature(props) {
881942
spacing: 1
882943
}, renderCoordsAndElevation(loc), additionalRows.map(function (row) {
883944
return typeof row === 'function' ? row(loc) : row;
884-
}), renderLocationSiteAndDomain(siteCode)));
945+
}), loc.nlcdClass ? renderNlcdClass(loc) : null, renderLocationSiteAndDomain(siteCode)));
885946
};
886947
/**
887948
Render: Boundary popup

0 commit comments

Comments
 (0)