mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-08-05 13:14:19 -07:00
feat: show tribal layer on open-source map
This commit is contained in:
parent
c9ee594211
commit
bc9a58f342
12 changed files with 111 additions and 361 deletions
|
@ -1,5 +1,8 @@
|
|||
# WARNING:
|
||||
# THIS FILE IS CHECKED INTO VERSION CONTROL! DO NOT ADD ANY SECRET INFO. IF SECRETS ARE ADDED, PLEASE ADD TO # GIT IGNORE FILE
|
||||
#
|
||||
# Create an adjacent local .env file to override any settings
|
||||
#
|
||||
|
||||
# Feature Tiles env variables:
|
||||
# The TILES_BASE_URL will be determined by the DATA_SOURCE env variable
|
||||
|
@ -7,13 +10,14 @@ GATSBY_CDN_TILES_BASE_URL=https://dig0wsohit6js.cloudfront.net
|
|||
GATSBY_LOCAL_TILES_BASE_URL=http://localhost:5000/data/data-pipeline
|
||||
|
||||
GATSBY_DATA_PIPELINE_SCORE_PATH_LOCAL=data_pipeline/data/score
|
||||
GATSBY_DATA_PIPELINE_TRIBAL_PATH=data-pipeline/data/tribal
|
||||
GATSBY_DATA_PIPELINE_TRIBAL_PATH_LOCAL=data_pipeline/data/tribal
|
||||
GATSBY_2_0_TRIBAL_PATH=data-versions/2.0/data/tribal
|
||||
|
||||
GATSBY_BETA_SCORE_PATH = data-versions/beta/data/score
|
||||
GATSBY_2_0_SCORE_PATH = data-versions/2.0/data/score
|
||||
GATSBY_BETA_SCORE_PATH=data-versions/beta/data/score
|
||||
GATSBY_2_0_SCORE_PATH=data-versions/2.0/data/score
|
||||
|
||||
GATSBY_DATA_PIPELINE_SEARCH_PATH_LOCAL = data_pipeline/data/score/search/tracts.json
|
||||
GATSBY_2_0_MAP_TRACT_SEARCH_PATH = data-versions/2.0/data/score/search/tracts.json
|
||||
GATSBY_DATA_PIPELINE_SEARCH_PATH_LOCAL=data_pipeline/data/score/search/tracts.json
|
||||
GATSBY_2_0_MAP_TRACT_SEARCH_PATH=data-versions/2.0/data/score/search/tracts.json
|
||||
|
||||
GATSBY_FILE_DL_PATH_BETA_COMMUNITIES_LIST_XLS=downloadable/beta-communities.xlsx
|
||||
GATSBY_FILE_DL_PATH_BETA_COMMUNITIES_LIST_CSV=downloadable/beta-communities.csv
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
# WARNING:
|
||||
# THIS FILE IS CHECKED INTO VERSION CONTROL! DO NOT ADD ANY SECRET INFO. IF SECRETS ARE ADDED, PLEASE ADD TO # GIT IGNORE FILE
|
||||
#
|
||||
# Create an adjacent local .env file to override any settings
|
||||
#
|
||||
|
||||
# Feature Tiles env variables:
|
||||
# The TILES_BASE_URL will always point to the CDN
|
||||
GATSBY_CDN_TILES_BASE_URL=https://dig0wsohit6js.cloudfront.net
|
||||
|
||||
GATSBY_DATA_PIPELINE_TRIBAL_PATH=data-pipeline/data/tribal
|
||||
GATSBY_2_0_TRIBAL_PATH=data-versions/2.0/data/tribal
|
||||
|
||||
GATSBY_BETA_SCORE_PATH = data-versions/beta/data/score
|
||||
GATSBY_2_0_SCORE_PATH = data-versions/2.0/data/score
|
||||
GATSBY_BETA_SCORE_PATH=data-versions/beta/data/score
|
||||
GATSBY_2_0_SCORE_PATH=data-versions/2.0/data/score
|
||||
|
||||
GATSBY_2_0_MAP_TRACT_SEARCH_PATH = data-versions/2.0/data/score/search/tracts.json
|
||||
GATSBY_2_0_MAP_TRACT_SEARCH_PATH=data-versions/2.0/data/score/search/tracts.json
|
||||
|
||||
GATSBY_FILE_DL_PATH_BETA_COMMUNITIES_LIST_XLS=downloadable/beta-communities.xlsx
|
||||
GATSBY_FILE_DL_PATH_BETA_COMMUNITIES_LIST_CSV=downloadable/beta-communities.csv
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
require('dotenv').config({
|
||||
// NODE_ENV is automatically set to
|
||||
// 'development' when the app is launched via 'npm start' or 'npm develop'
|
||||
// 'production' when the app is launched via 'npm build'
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
// Depending on the node environment, the app will then use
|
||||
// .env.production or .env.development for application
|
||||
// env variables.
|
||||
path: `.env.${process.env.NODE_ENV}`,
|
||||
});
|
||||
// load .env first so any local settings take precedence over environmental defaults loaded next
|
||||
dotenv.config();
|
||||
|
||||
// NODE_ENV is automatically set to
|
||||
// 'development' when the app is launched via 'npm start' or 'npm develop'
|
||||
// 'production' when the app is launched via 'npm build'
|
||||
|
||||
// Depending on the node environment, the app will then use
|
||||
// .env.production or .env.development for application
|
||||
// env variables.
|
||||
dotenv.config({path: `.env.${process.env.NODE_ENV}`});
|
||||
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
path = require('path');
|
||||
|
||||
// https://github.com/maplibre/maplibre-gl-js/issues/83#issuecomment-877012839
|
||||
// This is require to use react-map-gl 6.x with maplibre
|
||||
// See: https://github.com/visgl/react-map-gl/blob/v6.1.21/docs/get-started/get-started.md#using-with-a-mapbox-gl-fork
|
||||
//
|
||||
// In react-map-gl 7.x this is no longer needed: https://visgl.github.io/react-map-gl/docs/get-started
|
||||
//
|
||||
exports.onCreateWebpackConfig = ({stage, loaders, actions}) => {
|
||||
actions.setWebpackConfig({
|
||||
devtool: 'eval-source-map',
|
||||
|
|
30
client/package-lock.json
generated
30
client/package-lock.json
generated
|
@ -14093,36 +14093,6 @@
|
|||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mapbox-gl": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.13.2.tgz",
|
||||
"integrity": "sha512-CPjtWygL+f7naL+sGHoC2JQR0DG7u+9ik6WdkjjVmz2uy0kBC2l+aKfdi3ZzUR7VKSQJ6Mc/CeCN+6iVNah+ww==",
|
||||
"requires": {
|
||||
"@mapbox/geojson-rewind": "^0.5.0",
|
||||
"@mapbox/geojson-types": "^1.0.2",
|
||||
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
||||
"@mapbox/mapbox-gl-supported": "^1.5.0",
|
||||
"@mapbox/point-geometry": "^0.1.0",
|
||||
"@mapbox/tiny-sdf": "^1.1.1",
|
||||
"@mapbox/unitbezier": "^0.0.0",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"@mapbox/whoots-js": "^3.1.0",
|
||||
"csscolorparser": "~1.0.3",
|
||||
"earcut": "^2.2.2",
|
||||
"geojson-vt": "^3.2.1",
|
||||
"gl-matrix": "^3.2.1",
|
||||
"grid-index": "^1.1.0",
|
||||
"minimist": "^1.2.5",
|
||||
"murmurhash-js": "^1.0.0",
|
||||
"pbf": "^3.2.1",
|
||||
"potpack": "^1.0.1",
|
||||
"quickselect": "^2.0.0",
|
||||
"rw": "^1.3.3",
|
||||
"supercluster": "^7.1.0",
|
||||
"tinyqueue": "^2.0.3",
|
||||
"vt-pbf": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"maplibre-gl": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-1.14.0.tgz",
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
"gatsby-plugin-robots-txt": "^1.7.0",
|
||||
"gatsby-plugin-sitemap": "^4.10.0",
|
||||
"js-search": "^2.0.1",
|
||||
"mapbox-gl": "^1.13.2",
|
||||
"maplibre-gl": "^1.14.0",
|
||||
"query-string": "^7.1.3",
|
||||
"react": "^17.0.2",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
// External Libs:
|
||||
import React, {useRef, useState} from 'react';
|
||||
import {Map, MapboxGeoJSONFeature, LngLatBoundsLike} from 'maplibre-gl';
|
||||
import {Map, MapGeoJSONFeature, LngLatBoundsLike} from 'maplibre-gl';
|
||||
import ReactMapGL, {
|
||||
MapEvent,
|
||||
ViewportProps,
|
||||
|
@ -28,9 +28,8 @@ import AreaDetail from './AreaDetail';
|
|||
import MapInfoPanel from './mapInfoPanel';
|
||||
import MapSearch from './MapSearch';
|
||||
import MapTractLayers from './MapTractLayers/MapTractLayers';
|
||||
// import MapTribalLayer from './MapTribalLayers/MapTribalLayers';
|
||||
import MapTribalLayer from './MapTribalLayers/MapTribalLayers';
|
||||
import TerritoryFocusControl from './territoryFocusControl';
|
||||
import {getOSBaseMap} from '../data/getOSBaseMap';
|
||||
|
||||
// Styles and constants
|
||||
import 'maplibre-gl/dist/maplibre-gl.css';
|
||||
|
@ -87,7 +86,7 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
zoom: zoom && parseFloat(zoom) ? parseFloat(zoom) : constants.GLOBAL_MIN_ZOOM,
|
||||
});
|
||||
|
||||
const [selectedFeature, setSelectedFeature] = useState<MapboxGeoJSONFeature>();
|
||||
const [selectedFeature, setSelectedFeature] = useState<MapGeoJSONFeature>();
|
||||
const [detailViewData, setDetailViewData] = useState<IDetailViewInterface>();
|
||||
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
|
||||
const [geolocationInProgress, setGeolocationInProgress] = useState<boolean>(false);
|
||||
|
@ -303,11 +302,6 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
setGeolocationInProgress(true);
|
||||
};
|
||||
|
||||
const mapBoxBaseLayer = {
|
||||
customColorsWithUpdatedTribal: `mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16`,
|
||||
streetsWithUpdatedTribal: `mapbox://styles/justice40/cl98rlidr002c14obpsvz6zzs`,
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -347,8 +341,11 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
// ****** Map state props: ******
|
||||
// http://visgl.github.io/react-map-gl/docs/api-reference/interactive-map#map-state
|
||||
{...viewport}
|
||||
mapStyle={process.env.MAPBOX_STYLES_READ_TOKEN ?
|
||||
mapBoxBaseLayer.customColorsWithUpdatedTribal : getOSBaseMap()}
|
||||
mapStyle={
|
||||
process.env.MAPBOX_STYLES_READ_TOKEN ?
|
||||
'mapbox://styles/justice40/cl9g30qh7000p15l9cp1ftw16' :
|
||||
'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json'
|
||||
}
|
||||
width="100%"
|
||||
// Ajusting this height with a conditional statement will not render the map on staging.
|
||||
// The reason for this issue is unknown. Consider styling the parent container via SASS.
|
||||
|
@ -382,6 +379,13 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
data-cy={'reactMapGL'}
|
||||
>
|
||||
|
||||
{ /* Tribal layer is baked into Mapbox source,
|
||||
* only render here if we're not using that
|
||||
**/
|
||||
process.env.MAPBOX_STYLES_READ_TOKEN ||
|
||||
<MapTribalLayer />
|
||||
}
|
||||
|
||||
<MapTractLayers
|
||||
selectedFeature={selectedFeature}
|
||||
selectedFeatureId={selectedFeatureId}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, {useMemo} from 'react';
|
||||
import {Source, Layer} from 'react-map-gl';
|
||||
import {AnyLayer} from 'mapbox-gl';
|
||||
import {MapGeoJSONFeature} from 'maplibre-gl';
|
||||
|
||||
// Contexts:
|
||||
import {useFlags} from '../../contexts/FlagContext';
|
||||
|
@ -9,8 +9,8 @@ import * as constants from '../../data/constants';
|
|||
import * as COMMON_COPY from '../../data/copy/common';
|
||||
|
||||
interface IMapTractLayers {
|
||||
selectedFeatureId: AnyLayer,
|
||||
selectedFeature: AnyLayer,
|
||||
selectedFeatureId: string | number,
|
||||
selectedFeature: MapGeoJSONFeature | undefined,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,8 +60,8 @@ export const featureURLForTilesetName = (tilesetName: string): string => {
|
|||
* 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
|
||||
* @param {string | number} selectedFeatureId
|
||||
* @param {MapGeoJSONFeature | undefined} selectedFeature
|
||||
* @return {Style}
|
||||
*/
|
||||
const MapTractLayers = ({
|
||||
|
@ -70,9 +70,7 @@ const MapTractLayers = ({
|
|||
}: IMapTractLayers) => {
|
||||
const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]);
|
||||
|
||||
return process.env.MAPBOX_STYLES_READ_TOKEN ? (
|
||||
|
||||
// In this case the MapBox token is found and All source(s)/layer(s) are returned.
|
||||
return (
|
||||
<>
|
||||
<Source
|
||||
id={constants.LOW_ZOOM_SOURCE_NAME}
|
||||
|
@ -160,34 +158,6 @@ const MapTractLayers = ({
|
|||
/>
|
||||
</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 (dynamic) - 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,24 +1,20 @@
|
|||
import React, {useMemo} from 'react';
|
||||
import React from 'react';
|
||||
import {Source, Layer} from 'react-map-gl';
|
||||
import {AnyLayer} from 'mapbox-gl';
|
||||
|
||||
import * as constants from '../../data/constants';
|
||||
|
||||
interface IMapTribalLayers {
|
||||
selectedFeatureId: AnyLayer,
|
||||
selectedFeature: AnyLayer,
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will determine the URL for the tribal tiles.
|
||||
* @return {string}
|
||||
*/
|
||||
export const tribalURL = (): string => {
|
||||
const featureTileBaseURL = constants.TILE_BASE_URL;
|
||||
const featureTilePath = constants.GATSBY_DATA_PIPELINE_TRIBAL_PATH;
|
||||
const XYZ_SUFFIX = '{z}/{x}/{y}.pbf';
|
||||
|
||||
return [
|
||||
process.env.GATSBY_CDN_TILES_BASE_URL,
|
||||
process.env.GATSBY_DATA_PIPELINE_TRIBAL_PATH,
|
||||
featureTileBaseURL,
|
||||
featureTilePath,
|
||||
process.env.GATSBY_MAP_TILES_PATH,
|
||||
XYZ_SUFFIX,
|
||||
].join('/');
|
||||
|
@ -34,17 +30,12 @@ export const tribalURL = (): string => {
|
|||
* 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
|
||||
* @param {string | number} selectedFeatureId
|
||||
* @param {MapGeoJSONFeature | undefined} selectedFeature
|
||||
* @return {Style}
|
||||
*/
|
||||
const MapTribalLayer = ({
|
||||
selectedFeatureId,
|
||||
selectedFeature,
|
||||
}: IMapTribalLayers) => {
|
||||
const tribalSelectionFilter = useMemo(() => ['in', constants.TRIBAL_ID, selectedFeatureId], [selectedFeature]);
|
||||
|
||||
return process.env.MAPBOX_STYLES_READ_TOKEN ? (
|
||||
const MapTribalLayer = () => {
|
||||
return (
|
||||
|
||||
// In this case the MapBox token is found and ALL source(s)/layer(s) are returned.
|
||||
<Source
|
||||
|
@ -52,8 +43,6 @@ const MapTribalLayer = ({
|
|||
type="vector"
|
||||
promoteId={constants.TRIBAL_ID}
|
||||
tiles={[tribalURL()]}
|
||||
minzoom={constants.TRIBAL_MIN_ZOOM}
|
||||
maxzoom={constants.TRIBAL_MAX_ZOOM}
|
||||
>
|
||||
|
||||
{/* Tribal layer */}
|
||||
|
@ -82,19 +71,6 @@ const MapTribalLayer = ({
|
|||
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}
|
||||
/>
|
||||
|
||||
{/* Alaska layer */}
|
||||
<Layer
|
||||
id={constants.TRIBAL_ALASKA_POINTS_LAYER_ID}
|
||||
|
@ -103,40 +79,47 @@ const MapTribalLayer = ({
|
|||
type='circle'
|
||||
paint={{
|
||||
'circle-radius': constants.TRIBAL_ALASKA_CIRCLE_RADIUS,
|
||||
'circle-color': constants.PRIORITIZED_FEATURE_FILL_COLOR,
|
||||
'circle-color': constants.TRIBAL_ALASKA_CIRCLE_FILL_COLOR,
|
||||
'circle-opacity': constants.TRIBAL_FEATURE_FILL_OPACITY,
|
||||
'circle-stroke-color': constants.TRIBAL_BORDER_COLOR,
|
||||
'circle-stroke-width': constants.ALAKSA_POINTS_STROKE_WIDTH,
|
||||
'circle-stroke-opacity': constants.FEATURE_BORDER_OPACITY,
|
||||
}}
|
||||
minzoom={constants.ALASKA_MIN_ZOOM}
|
||||
maxzoom={constants.ALASKA_MAX_ZOOM}
|
||||
/>
|
||||
|
||||
{/* Tribal labels layer */}
|
||||
<Layer
|
||||
id={constants.TRIBAL_LABELS_LAYER_ID}
|
||||
source-layer={constants.TRIBAL_SOURCE_LAYER}
|
||||
type='symbol'
|
||||
layout={{
|
||||
'text-field': [
|
||||
'case',
|
||||
['in', ' LAR', ['get', constants.LAND_AREA_NAME]],
|
||||
['slice', ['get', constants.LAND_AREA_NAME], 0, ['-', ['length', ['get', constants.LAND_AREA_NAME]], 4]],
|
||||
['in', ' IRA', ['get', constants.LAND_AREA_NAME]],
|
||||
['slice', ['get', constants.LAND_AREA_NAME], 0, ['-', ['length', ['get', constants.LAND_AREA_NAME]], 4]],
|
||||
['in', ' TSA', ['get', constants.LAND_AREA_NAME]],
|
||||
['slice', ['get', constants.LAND_AREA_NAME], 0, ['-', ['length', ['get', constants.LAND_AREA_NAME]], 4]],
|
||||
['get', constants.LAND_AREA_NAME],
|
||||
],
|
||||
'text-anchor': 'top',
|
||||
'text-offset': [0, 1],
|
||||
'text-size': 12,
|
||||
'text-allow-overlap': false,
|
||||
'text-ignore-placement': false,
|
||||
}}
|
||||
paint={{
|
||||
'text-color': '#333333',
|
||||
'text-halo-color': '#FFFFFF',
|
||||
'text-halo-width': 1.5,
|
||||
}}
|
||||
minzoom={constants.TRIBAL_MIN_ZOOM}
|
||||
maxzoom={constants.TRIBAL_MAX_ZOOM}
|
||||
/>
|
||||
</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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -261,10 +261,10 @@ export const LOW_ZOOM_LAYER_ID = "low-zoom-layer-id";
|
|||
export const FEATURE_BORDER_LAYER_ID = "feature-border-layer-id";
|
||||
export const SELECTED_FEATURE_BORDER_LAYER_ID =
|
||||
"selected-feature-border-layer-id";
|
||||
|
||||
export const TRIBAL_LAYER_ID = "tribal-layer-id";
|
||||
export const SELECTED_TRIBAL_FEATURE_BORDER_LAYER_ID =
|
||||
"selected-feature-tribal-border-layer-id";
|
||||
export const TRIBAL_ALASKA_POINTS_LAYER_ID = "tribal-alaska-points-layer-id";
|
||||
export const TRIBAL_LABELS_LAYER_ID = "tribal-labels-layer-id";
|
||||
|
||||
// Used in layer filters:
|
||||
export const SCORE_PROPERTY_LOW = "SCORE";
|
||||
|
@ -282,8 +282,10 @@ export const GLOBAL_MAX_ZOOM_HIGH = 11;
|
|||
|
||||
export const GLOBAL_MIN_ZOOM_FEATURE_BORDER = 5;
|
||||
export const GLOBAL_MAX_ZOOM_FEATURE_BORDER = 22;
|
||||
export const TRIBAL_MIN_ZOOM = 3;
|
||||
export const TRIBAL_MIN_ZOOM = 6.6;
|
||||
export const TRIBAL_MAX_ZOOM = 22;
|
||||
export const ALASKA_MIN_ZOOM = 3;
|
||||
export const ALASKA_MAX_ZOOM = 22;
|
||||
|
||||
// Opacity
|
||||
export const FEATURE_BORDER_OPACITY = 0.5;
|
||||
|
@ -297,7 +299,7 @@ export const FEATURE_BORDER_COLOR = "#4EA5CF";
|
|||
export const SELECTED_FEATURE_BORDER_COLOR = "#1A4480";
|
||||
export const PRIORITIZED_FEATURE_FILL_COLOR = "#768FB3";
|
||||
|
||||
export const TRIBAL_BORDER_COLOR = "##4EA5CF";
|
||||
export const TRIBAL_BORDER_COLOR = "#4EA5CF";
|
||||
export const SELECTED_TRIBAL_BORDER_COLOR = "#1A4480";
|
||||
export const TRIBAL_FILL_COLOR = "#768FB3";
|
||||
export const TRIBAL_ALASKA_CIRCLE_FILL_COLOR = "#768FB3";
|
||||
|
@ -395,3 +397,7 @@ process.env.GATSBY_2_0_SCORE_PATH;
|
|||
export const MAP_TRACT_SEARCH_PATH = process.env.DATA_SOURCE === "local" ?
|
||||
process.env.GATSBY_DATA_PIPELINE_SEARCH_PATH_LOCAL :
|
||||
process.env.GATSBY_2_0_MAP_TRACT_SEARCH_PATH;
|
||||
|
||||
export const GATSBY_DATA_PIPELINE_TRIBAL_PATH = process.env.DATA_SOURCE === "local" ?
|
||||
process.env.GATSBY_DATA_PIPELINE_TRIBAL_PATH_LOCAL :
|
||||
process.env.GATSBY_2_0_TRIBAL_PATH;
|
||||
|
|
|
@ -1,196 +0,0 @@
|
|||
import {Style} from 'maplibre-gl';
|
||||
|
||||
import {featureURLForTilesetName} from '../components/MapTractLayers/MapTractLayers';
|
||||
import * as constants from '../data/constants';
|
||||
|
||||
// *********** OPEN SOURCE BASE MAP CONSTANTS ***************
|
||||
const imageSuffix = constants.isMobile ? '' : '@2x';
|
||||
|
||||
// Original "light" Base layer
|
||||
// Additional layers found here: https://carto.com/help/building-maps/basemap-list/#carto-vector-basemaps
|
||||
const cartoLightBaseLayer = {
|
||||
noLabels: [
|
||||
`https://a.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://b.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://c.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://d.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
],
|
||||
labelsOnly: [
|
||||
`https://cartodb-basemaps-a.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://cartodb-basemaps-b.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://cartodb-basemaps-c.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
`https://cartodb-basemaps-d.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}${imageSuffix}.png`,
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
// *********** OPEN SOURCE STATIC MAP STYLES ***************
|
||||
/**
|
||||
* 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.
|
||||
* *
|
||||
* This function returns a Style in accordance to JSON spec of MapBox
|
||||
* https://docs.mapbox.com/mapbox-gl-js/style-spec/
|
||||
*
|
||||
* @return {Style}
|
||||
*/
|
||||
export const getOSBaseMap = (): Style => {
|
||||
return {
|
||||
'version': 8,
|
||||
|
||||
/**
|
||||
* Census Tract Source
|
||||
* */
|
||||
'sources': {
|
||||
|
||||
/**
|
||||
* The base map source source allows us to define where the tiles can be fetched from.
|
||||
*/
|
||||
[constants.BASE_MAP_SOURCE_NAME]: {
|
||||
'type': 'raster',
|
||||
'tiles': cartoLightBaseLayer.noLabels,
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM,
|
||||
},
|
||||
|
||||
// The High zoom source:
|
||||
[constants.HIGH_ZOOM_SOURCE_NAME]: {
|
||||
// It is only shown at high zoom levels to avoid performance issues at lower zooms
|
||||
'type': 'vector',
|
||||
// Our current tippecanoe command does not set an id.
|
||||
// The below line promotes the GEOID10 property to the ID
|
||||
'promoteId': constants.GEOID_PROPERTY,
|
||||
'tiles': [featureURLForTilesetName('high')],
|
||||
// Setting maxzoom here enables 'overzooming'
|
||||
// e.g. continued zooming beyond the max bounds.
|
||||
// More here: https://docs.mapbox.com/help/glossary/overzoom/
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM_HIGH,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM_HIGH,
|
||||
},
|
||||
|
||||
// The Low zoom source:
|
||||
[constants.LOW_ZOOM_SOURCE_NAME]: {
|
||||
// "Score-low" represents a tileset at the level of bucketed tracts.
|
||||
// census block group information is `dissolve`d into tracts, then
|
||||
// each tract is `dissolve`d into one of ten buckets. It is meant
|
||||
// to give us a favorable tradeoff between performance and fidelity.
|
||||
'type': 'vector',
|
||||
'promoteId': constants.GEOID_PROPERTY,
|
||||
'tiles': [featureURLForTilesetName('low')],
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM_LOW,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM_LOW,
|
||||
},
|
||||
|
||||
// The labels source:
|
||||
'labels': {
|
||||
'type': 'raster',
|
||||
'tiles': cartoLightBaseLayer.labelsOnly,
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Each object in the layers array references it's source via the source key.
|
||||
*/
|
||||
'layers': [
|
||||
// The baseMapLayer
|
||||
{
|
||||
'id': constants.BASE_MAP_LAYER_ID,
|
||||
'source': constants.BASE_MAP_SOURCE_NAME,
|
||||
'type': 'raster',
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM,
|
||||
},
|
||||
|
||||
// A layer for labels only
|
||||
{
|
||||
'id': 'labels-only-layer',
|
||||
'source': 'labels',
|
||||
'type': 'raster',
|
||||
'layout': {
|
||||
'visibility': 'visible',
|
||||
},
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM,
|
||||
},
|
||||
|
||||
// Low zoom layer (static) - prioritized features only
|
||||
{
|
||||
'id': constants.LOW_ZOOM_LAYER_ID,
|
||||
'source': constants.LOW_ZOOM_SOURCE_NAME,
|
||||
'source-layer': constants.SCORE_SOURCE_LAYER,
|
||||
/**
|
||||
* This shows features where the low score > score boundary threshold.
|
||||
* In other words, this filter out non-prioritized features
|
||||
*/
|
||||
'filter': ['all',
|
||||
['>', constants.SCORE_PROPERTY_LOW, constants.SCORE_BOUNDARY_THRESHOLD],
|
||||
],
|
||||
|
||||
'type': 'fill',
|
||||
'paint': {
|
||||
'fill-color': constants.PRIORITIZED_FEATURE_FILL_COLOR,
|
||||
'fill-opacity': constants.LOW_ZOOM_PRIORITIZED_FEATURE_FILL_OPACITY,
|
||||
},
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM_LOW,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM_LOW,
|
||||
},
|
||||
|
||||
// High zoom layer (static) - non-prioritized features only
|
||||
{
|
||||
'id': constants.HIGH_ZOOM_LAYER_ID,
|
||||
'source': constants.HIGH_ZOOM_SOURCE_NAME,
|
||||
'source-layer': constants.SCORE_SOURCE_LAYER,
|
||||
/**
|
||||
* The SCORE_PROPERTY_HIGH is a boolean value. True for
|
||||
* prioritized and false for non-priorirized
|
||||
*/
|
||||
'filter': ['all',
|
||||
['==', constants.SCORE_PROPERTY_HIGH, false],
|
||||
],
|
||||
|
||||
'type': 'fill',
|
||||
'paint': {
|
||||
'fill-opacity': constants.NON_PRIORITIZED_FEATURE_FILL_OPACITY,
|
||||
},
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM_HIGH,
|
||||
},
|
||||
|
||||
// High zoom layer (static) - prioritized features only
|
||||
{
|
||||
'id': constants.PRIORITIZED_HIGH_ZOOM_LAYER_ID,
|
||||
'source': constants.HIGH_ZOOM_SOURCE_NAME,
|
||||
'source-layer': constants.SCORE_SOURCE_LAYER,
|
||||
/**
|
||||
* The SCORE_PROPERTY_HIGH is a boolean value. True for
|
||||
* prioritized and false for non-priorirized
|
||||
*/
|
||||
'filter': ['all',
|
||||
['==', constants.SCORE_PROPERTY_HIGH, true],
|
||||
],
|
||||
|
||||
'type': 'fill',
|
||||
'paint': {
|
||||
'fill-color': constants.PRIORITIZED_FEATURE_FILL_COLOR,
|
||||
'fill-opacity': constants.HIGH_ZOOM_PRIORITIZED_FEATURE_FILL_OPACITY,
|
||||
},
|
||||
'minzoom': constants.GLOBAL_MIN_ZOOM_HIGH,
|
||||
},
|
||||
|
||||
// High zoom layer (static) - controls the border between features
|
||||
{
|
||||
'id': constants.FEATURE_BORDER_LAYER_ID,
|
||||
'source': constants.HIGH_ZOOM_SOURCE_NAME,
|
||||
'source-layer': constants.SCORE_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.GLOBAL_MIN_ZOOM_FEATURE_BORDER,
|
||||
'maxzoom': constants.GLOBAL_MAX_ZOOM_FEATURE_BORDER,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// other CSS libraries:
|
||||
@import "~@trussworks/react-uswds/lib/index.css";
|
||||
@import "../../node_modules/mapbox-gl/dist/mapbox-gl.css";
|
||||
@import "../../node_modules/maplibre-gl/dist/maplibre-gl.css";
|
||||
|
||||
/*
|
||||
According to the fundamental usage of USWDS:
|
||||
|
@ -537,4 +537,4 @@ button.usa-accordion__button[aria-expanded=true]:has(div[class*="disCategoryCont
|
|||
.faqs-dot-alignment{
|
||||
align-self: flex-start;
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue