mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-02-23 10:04:18 -08:00
Add OS map functionality
- split source/layers between Map*Layers.tsx and getOSBaseMap file - update getOSBaseMap to return eithe tribal or tracts layers/sources
This commit is contained in:
parent
bac8c85a6c
commit
31a9bf51d5
6 changed files with 156 additions and 21 deletions
|
@ -27,6 +27,7 @@ import AreaDetail from './AreaDetail';
|
||||||
import MapInfoPanel from './mapInfoPanel';
|
import MapInfoPanel from './mapInfoPanel';
|
||||||
import MapSearch from './MapSearch';
|
import MapSearch from './MapSearch';
|
||||||
import MapTractLayers from './MapTractLayers/MapTractLayers';
|
import MapTractLayers from './MapTractLayers/MapTractLayers';
|
||||||
|
import MapTribalLayer from './MapTribalLayers/MapTribalLayers';
|
||||||
import LayerSelector from './LayerSelector';
|
import LayerSelector from './LayerSelector';
|
||||||
import TerritoryFocusControl from './territoryFocusControl';
|
import TerritoryFocusControl from './territoryFocusControl';
|
||||||
import {getOSBaseMap} from '../data/getOSBaseMap';
|
import {getOSBaseMap} from '../data/getOSBaseMap';
|
||||||
|
@ -35,7 +36,6 @@ import {getOSBaseMap} from '../data/getOSBaseMap';
|
||||||
import 'maplibre-gl/dist/maplibre-gl.css';
|
import 'maplibre-gl/dist/maplibre-gl.css';
|
||||||
import * as constants from '../data/constants';
|
import * as constants from '../data/constants';
|
||||||
import * as styles from './J40Map.module.scss';
|
import * as styles from './J40Map.module.scss';
|
||||||
import MapTribalLayer from './MapTribalLayer/MapTribalLayer';
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
Cypress?: object;
|
Cypress?: object;
|
||||||
|
@ -373,9 +373,8 @@ const J40Map = ({location}: IJ40Interface) => {
|
||||||
data-cy={'reactMapGL'}
|
data-cy={'reactMapGL'}
|
||||||
>
|
>
|
||||||
|
|
||||||
{/* Load either the Tribal layer or census layer */}
|
{/* Load either the Tribal layer or Census layer depending on the censusSelected state variable */}
|
||||||
{
|
{
|
||||||
// Todo: may not need both props...
|
|
||||||
censusSelected ?
|
censusSelected ?
|
||||||
<MapTractLayers
|
<MapTractLayers
|
||||||
selectedFeature={selectedFeature}
|
selectedFeature={selectedFeature}
|
||||||
|
|
|
@ -56,13 +56,28 @@ export const featureURLForTilesetName = (tilesetName: string): string => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component will return the appropriate source and layers for the census layer on the
|
||||||
|
* map.
|
||||||
|
*
|
||||||
|
* There are two use cases here, eg, when the MapBox token is or isn't provided. When the token
|
||||||
|
* is not provided, the open-source map will be rendered. When the open-source map is rendered
|
||||||
|
* only the interactive layers are returned from this component. The reason being is that the
|
||||||
|
* other layers are supplied by he getOSBaseMap function.
|
||||||
|
*
|
||||||
|
* @param {AnyLayer} selectedFeatureId
|
||||||
|
* @param {AnyLayer} selectedFeature
|
||||||
|
* @return {Style}
|
||||||
|
*/
|
||||||
const MapTractLayers = ({
|
const MapTractLayers = ({
|
||||||
selectedFeatureId,
|
selectedFeatureId,
|
||||||
selectedFeature,
|
selectedFeature,
|
||||||
}: IMapTractLayers) => {
|
}: IMapTractLayers) => {
|
||||||
const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]);
|
const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]);
|
||||||
|
|
||||||
return (
|
return process.env.MAPBOX_STYLES_READ_TOKEN ? (
|
||||||
|
|
||||||
|
// In this case the MapBox token is found and All source(s)/layer(s) are returned.
|
||||||
<>
|
<>
|
||||||
<Source
|
<Source
|
||||||
id={constants.LOW_ZOOM_SOURCE_NAME}
|
id={constants.LOW_ZOOM_SOURCE_NAME}
|
||||||
|
@ -87,9 +102,7 @@ const MapTractLayers = ({
|
||||||
/>
|
/>
|
||||||
</Source>
|
</Source>
|
||||||
|
|
||||||
{/**
|
{/* The high zoom source */}
|
||||||
* The high zoom source
|
|
||||||
*/}
|
|
||||||
<Source
|
<Source
|
||||||
id={constants.HIGH_ZOOM_SOURCE_NAME}
|
id={constants.HIGH_ZOOM_SOURCE_NAME}
|
||||||
type="vector"
|
type="vector"
|
||||||
|
@ -152,6 +165,34 @@ const MapTractLayers = ({
|
||||||
/>
|
/>
|
||||||
</Source>
|
</Source>
|
||||||
</>
|
</>
|
||||||
|
): (
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this case the MapBox token is NOT found and ONLY interactive source(s)/layer(s) are returned
|
||||||
|
* In this case, the other layers (non-interactive) are provided by getOSBaseMap
|
||||||
|
*/
|
||||||
|
<Source
|
||||||
|
id={constants.HIGH_ZOOM_SOURCE_NAME}
|
||||||
|
type="vector"
|
||||||
|
promoteId={constants.GEOID_PROPERTY}
|
||||||
|
tiles={[featureURLForTilesetName('high')]}
|
||||||
|
maxzoom={constants.GLOBAL_MAX_ZOOM_HIGH}
|
||||||
|
minzoom={constants.GLOBAL_MIN_ZOOM_HIGH}
|
||||||
|
>
|
||||||
|
|
||||||
|
{/* High zoom layer - border styling around the selected feature */}
|
||||||
|
<Layer
|
||||||
|
id={constants.SELECTED_FEATURE_BORDER_LAYER_ID}
|
||||||
|
source-layer={constants.SCORE_SOURCE_LAYER}
|
||||||
|
filter={filter} // This filter filters out all other features except the selected feature.
|
||||||
|
type='line'
|
||||||
|
paint={{
|
||||||
|
'line-color': constants.SELECTED_FEATURE_BORDER_COLOR,
|
||||||
|
'line-width': constants.SELECTED_FEATURE_BORDER_WIDTH,
|
||||||
|
}}
|
||||||
|
minzoom={constants.GLOBAL_MIN_ZOOM_HIGH}
|
||||||
|
/>
|
||||||
|
</Source>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
import MapTribalLayer from './MapTribalLayer';
|
|
||||||
|
|
||||||
export default MapTribalLayer;
|
|
|
@ -24,13 +24,29 @@ export const tribalURL = (): string => {
|
||||||
].join('/');
|
].join('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component will return the appropriate source and layers for the tribal layer on the
|
||||||
|
* map.
|
||||||
|
*
|
||||||
|
* There are two use cases here, eg, when the MapBox token is or isn't provided. When the token
|
||||||
|
* is not provided, the open-source map will be rendered. When the open-source map is rendered
|
||||||
|
* only the interactive layers are returned from this component. The reason being is that the
|
||||||
|
* other layers are supplied by he getOSBaseMap function.
|
||||||
|
*
|
||||||
|
* @param {AnyLayer} selectedFeatureId
|
||||||
|
* @param {AnyLayer} selectedFeature
|
||||||
|
* @return {Style}
|
||||||
|
*/
|
||||||
const MapTribalLayer = ({
|
const MapTribalLayer = ({
|
||||||
selectedFeatureId,
|
selectedFeatureId,
|
||||||
selectedFeature,
|
selectedFeature,
|
||||||
}: IMapTribalLayers) => {
|
}: IMapTribalLayers) => {
|
||||||
const tribalSelectionFilter = useMemo(() => ['in', constants.TRIBAL_ID, selectedFeatureId], [selectedFeature]);
|
const tribalSelectionFilter = useMemo(() => ['in', constants.TRIBAL_ID, selectedFeatureId], [selectedFeature]);
|
||||||
|
|
||||||
return (
|
return process.env.MAPBOX_STYLES_READ_TOKEN ? (
|
||||||
|
|
||||||
|
// In this case the MapBox token is found and ALL source(s)/layer(s) are returned.
|
||||||
<Source
|
<Source
|
||||||
id={constants.TRIBAL_SOURCE_NAME}
|
id={constants.TRIBAL_SOURCE_NAME}
|
||||||
type="vector"
|
type="vector"
|
||||||
|
@ -44,7 +60,6 @@ const MapTribalLayer = ({
|
||||||
<Layer
|
<Layer
|
||||||
id={constants.TRIBAL_LAYER_ID}
|
id={constants.TRIBAL_LAYER_ID}
|
||||||
source-layer={constants.TRIBAL_SOURCE_LAYER}
|
source-layer={constants.TRIBAL_SOURCE_LAYER}
|
||||||
// filter={['>', constants.SCORE_PROPERTY_LOW, constants.SCORE_BOUNDARY_THRESHOLD]}
|
|
||||||
type='fill'
|
type='fill'
|
||||||
paint={{
|
paint={{
|
||||||
'fill-color': constants.TRIBAL_FILL_COLOR,
|
'fill-color': constants.TRIBAL_FILL_COLOR,
|
||||||
|
@ -56,7 +71,7 @@ const MapTribalLayer = ({
|
||||||
{/* Tribal layer - controls the border between features */}
|
{/* Tribal layer - controls the border between features */}
|
||||||
<Layer
|
<Layer
|
||||||
id={constants.FEATURE_BORDER_LAYER_ID}
|
id={constants.FEATURE_BORDER_LAYER_ID}
|
||||||
source-layer={constants.SCORE_SOURCE_LAYER}
|
source-layer={constants.TRIBAL_SOURCE_LAYER}
|
||||||
type='line'
|
type='line'
|
||||||
paint={{
|
paint={{
|
||||||
'line-color': constants.FEATURE_BORDER_COLOR,
|
'line-color': constants.FEATURE_BORDER_COLOR,
|
||||||
|
@ -95,8 +110,35 @@ const MapTribalLayer = ({
|
||||||
maxzoom={constants.TRIBAL_MAX_ZOOM}
|
maxzoom={constants.TRIBAL_MAX_ZOOM}
|
||||||
/>
|
/>
|
||||||
</Source>
|
</Source>
|
||||||
|
) : (
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In this case the MapBox token is NOT found and ONLY INTERACTIVE source(s)/layer(s) are returned.
|
||||||
|
* In this case, the other layers (non-interactive) are provided by getOSBaseMap
|
||||||
|
*/
|
||||||
|
<Source
|
||||||
|
id={constants.TRIBAL_SOURCE_NAME}
|
||||||
|
type="vector"
|
||||||
|
promoteId={constants.TRIBAL_ID}
|
||||||
|
tiles={[tribalURL()]}
|
||||||
|
minzoom={constants.TRIBAL_MIN_ZOOM}
|
||||||
|
maxzoom={constants.TRIBAL_MAX_ZOOM}
|
||||||
|
>
|
||||||
|
|
||||||
|
{/* Tribal layer - border styling around the selected feature */}
|
||||||
|
<Layer
|
||||||
|
id={constants.SELECTED_TRIBAL_FEATURE_BORDER_LAYER_ID}
|
||||||
|
source-layer={constants.TRIBAL_SOURCE_LAYER}
|
||||||
|
filter={tribalSelectionFilter}
|
||||||
|
type='line'
|
||||||
|
paint={{
|
||||||
|
'line-color': constants.SELECTED_FEATURE_BORDER_COLOR,
|
||||||
|
'line-width': constants.SELECTED_FEATURE_BORDER_WIDTH,
|
||||||
|
}}
|
||||||
|
minzoom={constants.TRIBAL_MIN_ZOOM}
|
||||||
|
/>
|
||||||
|
</Source>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MapTribalLayer;
|
export default MapTribalLayer;
|
||||||
//
|
|
3
client/src/components/MapTribalLayers/index.tsx
Normal file
3
client/src/components/MapTribalLayers/index.tsx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import MapTribalLayers from './MapTribalLayers';
|
||||||
|
|
||||||
|
export default MapTribalLayers;
|
|
@ -1,9 +1,11 @@
|
||||||
import {Style} from 'maplibre-gl';
|
import {Style} from 'maplibre-gl';
|
||||||
import * as constants from '../data/constants';
|
|
||||||
import {featureURLForTilesetName} from '../components/MapTractLayers/MapTractLayers';
|
|
||||||
import {tribalURL} from '../components/MapTribalLayer/MapTribalLayer';
|
|
||||||
|
|
||||||
// *********** BASE MAP SOURCES ***************
|
import {featureURLForTilesetName} from '../components/MapTractLayers/MapTractLayers';
|
||||||
|
import {tribalURL} from '../components/MapTribalLayers/MapTribalLayers';
|
||||||
|
|
||||||
|
import * as constants from '../data/constants';
|
||||||
|
|
||||||
|
// *********** OPEN SOURCE BASE MAP CONSTANTS ***************
|
||||||
const imageSuffix = constants.isMobile ? '' : '@2x';
|
const imageSuffix = constants.isMobile ? '' : '@2x';
|
||||||
|
|
||||||
// Original "light" Base layer
|
// Original "light" Base layer
|
||||||
|
@ -24,9 +26,21 @@ const cartoLightBaseLayer = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Utility function to get OpenSource base maps that are in accordance to JSON spec of MapBox
|
// *********** OPEN SOURCE STATIC MAP STYLES ***************
|
||||||
// https://docs.mapbox.com/mapbox-gl-js/style-spec/
|
/**
|
||||||
export const getOSBaseMap = (censusSelected: boolean) : Style => {
|
* This function will be called when there is no MapBox token found. This function will
|
||||||
|
* return the open source base map along with styles for the chosen source. We currently
|
||||||
|
* have two sources, either the census tracts or the tribal layer.
|
||||||
|
* *
|
||||||
|
* This function returns a Style in accordance to JSON spec of MapBox
|
||||||
|
* https://docs.mapbox.com/mapbox-gl-js/style-spec/
|
||||||
|
*
|
||||||
|
* @param {boolean} censusSelected
|
||||||
|
* @return {Style}
|
||||||
|
*/
|
||||||
|
export const getOSBaseMap = (
|
||||||
|
censusSelected: boolean,
|
||||||
|
) : Style => {
|
||||||
return !censusSelected ? {
|
return !censusSelected ? {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,6 +73,12 @@ export const getOSBaseMap = (censusSelected: boolean) : Style => {
|
||||||
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
||||||
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// The labels source:
|
||||||
|
'labels': {
|
||||||
|
'type': 'raster',
|
||||||
|
'tiles': cartoLightBaseLayer.labelsOnly,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,6 +111,39 @@ export const getOSBaseMap = (censusSelected: boolean) : Style => {
|
||||||
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
||||||
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tribal layer - controls the border between features
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
'id': constants.FEATURE_BORDER_LAYER_ID,
|
||||||
|
'source': constants.TRIBAL_SOURCE_NAME,
|
||||||
|
'source-layer': constants.TRIBAL_SOURCE_LAYER,
|
||||||
|
'type': 'line',
|
||||||
|
'paint': {
|
||||||
|
'line-color': constants.FEATURE_BORDER_COLOR,
|
||||||
|
'line-width': constants.FEATURE_BORDER_WIDTH,
|
||||||
|
'line-opacity': constants.FEATURE_BORDER_OPACITY},
|
||||||
|
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
||||||
|
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alaska layer
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
'id': constants.TRIBAL_ALASKA_POINTS_LAYER_ID,
|
||||||
|
'source': constants.TRIBAL_SOURCE_NAME,
|
||||||
|
'source-layer': constants.TRIBAL_SOURCE_LAYER,
|
||||||
|
'type': 'circle',
|
||||||
|
'filter': ['==', ['geometry-type'], 'Point'],
|
||||||
|
'paint': {
|
||||||
|
'circle-radius': constants.TRIBAL_ALASKA_CIRCLE_RADIUS,
|
||||||
|
'circle-color': constants.TRIBAL_ALASKA_CIRCLE_FILL_COLOR,
|
||||||
|
},
|
||||||
|
'minzoom': constants.TRIBAL_MIN_ZOOM,
|
||||||
|
'maxzoom': constants.TRIBAL_MAX_ZOOM,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
} :
|
} :
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue