mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-07-30 10:41:18 -07:00
Search by tract needs to highlight a tract 100% of the time
This commit is contained in:
parent
5ec0d228f7
commit
aa53d519a5
2 changed files with 33 additions and 52 deletions
|
@ -91,6 +91,7 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
const [transitionInProgress, setTransitionInProgress] = useState<boolean>(false);
|
||||
const [geolocationInProgress, setGeolocationInProgress] = useState<boolean>(false);
|
||||
const [isMobileMapState, setIsMobileMapState] = useState<boolean>(false);
|
||||
const [selectTractId, setSelectTractId] = useState<string | undefined>(undefined);
|
||||
const {width: windowWidth} = useWindowSize();
|
||||
|
||||
/**
|
||||
|
@ -123,11 +124,7 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
const [minLng, minLat, maxLng, maxLat] = bbox(feature);
|
||||
|
||||
// Set the selectedFeature ID
|
||||
if (feature.id !== selectedFeatureId) {
|
||||
setSelectedFeature(feature);
|
||||
} else {
|
||||
setSelectedFeature(undefined);
|
||||
}
|
||||
setSelectedFeature(feature);
|
||||
|
||||
// Go to the newly selected feature (as long as it's not an Alaska Point)
|
||||
goToPlace([
|
||||
|
@ -250,7 +247,7 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
* @param {LngLatBoundsLike} bounds
|
||||
* @param {boolean} isTerritory
|
||||
*/
|
||||
const goToPlace = (bounds: LngLatBoundsLike, isTerritory = false) => {
|
||||
const goToPlace = (bounds: LngLatBoundsLike, isTerritory = false, selectTractId: string | undefined = undefined) => {
|
||||
const newViewPort = new WebMercatorViewport({height: viewport.height!, width: viewport.width!});
|
||||
const {longitude, latitude, zoom} = newViewPort.fitBounds(
|
||||
bounds as [[number, number], [number, number]], {
|
||||
|
@ -281,6 +278,9 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
transitionInterpolator: new FlyToInterpolator(),
|
||||
transitionEasing: d3.easeCubic,
|
||||
});
|
||||
|
||||
// Set the tract ID to be selected if any.
|
||||
setSelectTractId(selectTractId);
|
||||
};
|
||||
|
||||
const onTransitionStart = () => {
|
||||
|
@ -289,6 +289,25 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
|
||||
const onTransitionEnd = () => {
|
||||
setTransitionInProgress(false);
|
||||
|
||||
/*
|
||||
If there is a tract ID to be selected then do so once the map has finished moving.
|
||||
Note that setting the viewpoint to move the map as done in this component does not
|
||||
trigger a moveend or idle event like when using flyTo or easeTo.
|
||||
*/
|
||||
if (selectTractId) {
|
||||
// Search for features in the map that have the tract ID.
|
||||
const geoidSearchResults = mapRef.current?.getMap()
|
||||
.querySourceFeatures(constants.HIGH_ZOOM_SOURCE_NAME, {
|
||||
sourceLayer: constants.SCORE_SOURCE_LAYER,
|
||||
validate: true,
|
||||
filter: ['==', constants.GEOID_PROPERTY, selectTractId],
|
||||
});
|
||||
if (geoidSearchResults && geoidSearchResults.length > 0) {
|
||||
selectFeatureOnMap(geoidSearchResults[0]);
|
||||
}
|
||||
setSelectTractId(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
const onGeolocate = () => {
|
||||
|
@ -393,8 +412,7 @@ const J40Map = ({location}: IJ40Interface) => {
|
|||
|
||||
{/* This is the first overlayed row on the map: Search and Geolocation */}
|
||||
<div className={styles.mapHeaderRow}>
|
||||
<MapSearch goToPlace={goToPlace} mapRef={mapRef} selectFeatureOnMap={selectFeatureOnMap}
|
||||
selectedFeatureId={selectedFeatureId}/>
|
||||
<MapSearch goToPlace={goToPlace}/>
|
||||
|
||||
{/* Geolocate Icon */}
|
||||
<div className={styles.geolocateBox}>
|
||||
|
|
|
@ -4,8 +4,6 @@ import {LngLatBoundsLike} from 'maplibre-gl';
|
|||
import {useIntl} from 'gatsby-plugin-intl';
|
||||
import {Search} from '@trussworks/react-uswds';
|
||||
import {useWindowSize} from 'react-use';
|
||||
import {RefObject} from 'react';
|
||||
import {MapRef} from 'react-map-gl';
|
||||
import * as JsSearch from 'js-search';
|
||||
import * as constants from '../../data/constants';
|
||||
|
||||
|
@ -15,10 +13,7 @@ import * as styles from './MapSearch.module.scss';
|
|||
import * as EXPLORE_COPY from '../../data/copy/explore';
|
||||
|
||||
interface IMapSearch {
|
||||
goToPlace(bounds: LngLatBoundsLike):void;
|
||||
mapRef:RefObject<MapRef>;
|
||||
selectFeatureOnMap: (feature: any) => void;
|
||||
selectedFeatureId: string;
|
||||
goToPlace(bounds: LngLatBoundsLike, isTerritory: boolean, selectTractId: string | undefined):void;
|
||||
}
|
||||
|
||||
interface ISearchTractRecord {
|
||||
|
@ -27,7 +22,7 @@ interface ISearchTractRecord {
|
|||
INTPTLON10: string;
|
||||
}
|
||||
|
||||
const MapSearch = ({goToPlace, mapRef, selectFeatureOnMap, selectedFeatureId}:IMapSearch) => {
|
||||
const MapSearch = ({goToPlace}:IMapSearch) => {
|
||||
// State to hold if the search results are empty or not:
|
||||
const [isSearchResultsNull, setIsSearchResultsNull] = useState(false);
|
||||
const intl = useIntl();
|
||||
|
@ -85,33 +80,15 @@ const MapSearch = ({goToPlace, mapRef, selectFeatureOnMap, selectedFeatureId}:IM
|
|||
const searchForTract = async (tract: string) => {
|
||||
// We create a bounding box just to get the tract in the view box.
|
||||
// The size is not important.
|
||||
const BOUNDING_BOX_SIZE_DD = 0.1;
|
||||
|
||||
/**
|
||||
* Wait for the map to be done loading and moving.
|
||||
* @param {function()} callback the callback to run after the map is ready
|
||||
*/
|
||||
const waitforMap = (callback: () => void): void => {
|
||||
const isMapReady = !!mapRef.current &&
|
||||
mapRef.current.getMap().isStyleLoaded() &&
|
||||
mapRef.current.getMap().isSourceLoaded(constants.HIGH_ZOOM_SOURCE_NAME);
|
||||
if (isMapReady) {
|
||||
callback();
|
||||
} else {
|
||||
setTimeout(() => waitforMap(callback), 200);
|
||||
}
|
||||
};
|
||||
const BOUNDING_BOX_SIZE_DD = 0.2;
|
||||
|
||||
// Convert 10 digit tracts to 11.
|
||||
const searchTerm = tract.length == 10 ? '0' + tract : tract;
|
||||
|
||||
// If the search is for the same tract then do nothing.
|
||||
if (selectedFeatureId == searchTerm) return;
|
||||
const normalizedTractId = tract.length == 10 ? '0' + tract : tract;
|
||||
|
||||
setIsSearchResultsNull(true);
|
||||
|
||||
if (tractSearch) {
|
||||
const result = tractSearch.search(searchTerm);
|
||||
const result = tractSearch.search(normalizedTractId);
|
||||
if (result.length > 0) {
|
||||
const searchTractRecord = result[0] as ISearchTractRecord;
|
||||
const lat = Number(searchTractRecord.INTPTLAT10);
|
||||
|
@ -126,21 +103,7 @@ const MapSearch = ({goToPlace, mapRef, selectFeatureOnMap, selectedFeatureId}:IM
|
|||
setIsSearchResultsNull(false);
|
||||
|
||||
// Now move the map and select the tract.
|
||||
goToPlace([[Number(longMin), Number(latMin)], [Number(longMax), Number(latMax)]]);
|
||||
waitforMap(() => {
|
||||
// Set up a one-shot event handler to fire when the flyTo arrives at its destination. Once the
|
||||
// tract is in view of the map. mpRef.current will always be valid here...
|
||||
mapRef.current?.getMap().once('idle', () => {
|
||||
const geoidSearchResults = mapRef.current?.getMap().querySourceFeatures(constants.HIGH_ZOOM_SOURCE_NAME, {
|
||||
sourceLayer: constants.SCORE_SOURCE_LAYER,
|
||||
validate: true,
|
||||
filter: ['==', constants.GEOID_PROPERTY, searchTerm],
|
||||
});
|
||||
if (geoidSearchResults && geoidSearchResults.length > 0) {
|
||||
selectFeatureOnMap(geoidSearchResults[0]);
|
||||
}
|
||||
});
|
||||
});
|
||||
goToPlace([[Number(longMin), Number(latMin)], [Number(longMax), Number(latMax)]], false, normalizedTractId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -173,7 +136,7 @@ const MapSearch = ({goToPlace, mapRef, selectFeatureOnMap, selectedFeatureId}:IM
|
|||
if (searchResults && searchResults.length > 0) {
|
||||
setIsSearchResultsNull(false);
|
||||
const [latMin, latMax, longMin, longMax] = searchResults[0].boundingbox;
|
||||
goToPlace([[Number(longMin), Number(latMin)], [Number(longMax), Number(latMax)]]);
|
||||
goToPlace([[Number(longMin), Number(latMin)], [Number(longMax), Number(latMax)]], false, undefined);
|
||||
} else {
|
||||
setIsSearchResultsNull(true);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue