Add basic nominatum

- this commit has errors
This commit is contained in:
Vim USDS 2021-11-22 08:10:42 -08:00
parent cd0170b0b4
commit 5f0a03818b
5 changed files with 186 additions and 28 deletions

124
client/package-lock.json generated
View file

@ -4814,12 +4814,18 @@
"dev": true "dev": true
}, },
"axios": { "axios": {
"version": "0.21.4", "version": "0.24.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
"dev": true,
"requires": { "requires": {
"follow-redirects": "^1.14.0" "follow-redirects": "^1.14.4"
},
"dependencies": {
"follow-redirects": {
"version": "1.14.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA=="
}
} }
}, },
"axobject-query": { "axobject-query": {
@ -5214,6 +5220,11 @@
"integrity": "sha512-SWg5wFIShYffEmJpI6LgbL8/3Dqhku7xI1oEiy6FroP9DbcZlG0ZDjxvPdP9t7hTGW40IpIcC6zVoGT1oxjOuA==", "integrity": "sha512-SWg5wFIShYffEmJpI6LgbL8/3Dqhku7xI1oEiy6FroP9DbcZlG0ZDjxvPdP9t7hTGW40IpIcC6zVoGT1oxjOuA==",
"dev": true "dev": true
}, },
"big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
},
"big.js": { "big.js": {
"version": "5.2.2", "version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@ -5385,6 +5396,21 @@
"fill-range": "^7.0.1" "fill-range": "^7.0.1"
} }
}, },
"broadcast-channel": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz",
"integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==",
"requires": {
"@babel/runtime": "^7.7.2",
"detect-node": "^2.1.0",
"js-sha3": "0.8.0",
"microseconds": "0.2.0",
"nano-time": "1.0.0",
"oblivious-set": "1.0.0",
"rimraf": "3.0.2",
"unload": "2.2.0"
}
},
"brorand": { "brorand": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@ -6572,6 +6598,15 @@
"type-fest": "^0.20.2" "type-fest": "^0.20.2"
}, },
"dependencies": { "dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dev": true,
"requires": {
"follow-redirects": "^1.14.0"
}
},
"type-fest": { "type-fest": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@ -7777,8 +7812,7 @@
"detect-node": { "detect-node": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
"dev": true
}, },
"detect-port": { "detect-port": {
"version": "1.3.0", "version": "1.3.0",
@ -10480,6 +10514,15 @@
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true "dev": true
}, },
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dev": true,
"requires": {
"follow-redirects": "^1.14.0"
}
},
"debug": { "debug": {
"version": "3.2.7", "version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
@ -14875,6 +14918,11 @@
"integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
"dev": true "dev": true
}, },
"js-sha3": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
},
"js-string-escape": { "js-string-escape": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@ -15767,6 +15815,15 @@
"repeat-string": "^1.0.0" "repeat-string": "^1.0.0"
} }
}, },
"match-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
"integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
"requires": {
"@babel/runtime": "^7.12.5",
"remove-accents": "0.4.2"
}
},
"matches-selector": { "matches-selector": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/matches-selector/-/matches-selector-1.2.0.tgz", "resolved": "https://registry.npmjs.org/matches-selector/-/matches-selector-1.2.0.tgz",
@ -16175,6 +16232,11 @@
"picomatch": "^2.2.3" "picomatch": "^2.2.3"
} }
}, },
"microseconds": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
"integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
},
"miller-rabin": { "miller-rabin": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@ -16525,6 +16587,14 @@
"stylis": "^4.0.6" "stylis": "^4.0.6"
} }
}, },
"nano-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
"integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=",
"requires": {
"big-integer": "^1.6.16"
}
},
"nanoid": { "nanoid": {
"version": "3.1.23", "version": "3.1.23",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
@ -16935,6 +17005,11 @@
"es-abstract": "^1.18.2" "es-abstract": "^1.18.2"
} }
}, },
"oblivious-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
},
"obuf": { "obuf": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@ -18800,6 +18875,16 @@
} }
} }
}, },
"react-query": {
"version": "3.33.1",
"resolved": "https://registry.npmjs.org/react-query/-/react-query-3.33.1.tgz",
"integrity": "sha512-RtvQKhD4sJkoAGbyFpLmftGezz1KL19SeGdmjIOLUulyPTZuhcn3gemee96yjEiBk/9LFB5CuSiqywZY20Qj5Q==",
"requires": {
"@babel/runtime": "^7.5.5",
"broadcast-channel": "^3.4.1",
"match-sorter": "^6.0.2"
}
},
"react-refresh": { "react-refresh": {
"version": "0.9.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz",
@ -19434,6 +19519,11 @@
"xtend": "^4.0.1" "xtend": "^4.0.1"
} }
}, },
"remove-accents": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
"integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U="
},
"remove-trailing-separator": { "remove-trailing-separator": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@ -22311,6 +22401,15 @@
} }
} }
}, },
"unload": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz",
"integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==",
"requires": {
"@babel/runtime": "^7.6.2",
"detect-node": "^2.0.4"
}
},
"unpipe": { "unpipe": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -22787,6 +22886,17 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"rxjs": "^6.6.3" "rxjs": "^6.6.3"
},
"dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dev": true,
"requires": {
"follow-redirects": "^1.14.0"
}
}
} }
}, },
"walker": { "walker": {

View file

@ -76,6 +76,7 @@
"@sentry/gatsby": "^6.13.2", "@sentry/gatsby": "^6.13.2",
"@trussworks/react-uswds": "^2.0.0", "@trussworks/react-uswds": "^2.0.0",
"@turf/bbox": "^6.5.0", "@turf/bbox": "^6.5.0",
"axios": "^0.24.0",
"chroma-js": "^2.1.2", "chroma-js": "^2.1.2",
"d3-ease": "^3.0.1", "d3-ease": "^3.0.1",
"gatsby-plugin-env-variables": "^2.1.0", "gatsby-plugin-env-variables": "^2.1.0",
@ -90,6 +91,7 @@
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-intl": "^5.20.4", "react-intl": "^5.20.4",
"react-map-gl": "^6.1.16", "react-map-gl": "^6.1.16",
"react-query": "^3.33.1",
"react-use": "^17.3.1", "react-use": "^17.3.1",
"uswds": "^2.10.3" "uswds": "^2.10.3"
}, },

View file

@ -17,21 +17,23 @@ import * as d3 from 'd3-ease';
import {isMobile} from 'react-device-detect'; import {isMobile} from 'react-device-detect';
import {Grid} from '@trussworks/react-uswds'; import {Grid} from '@trussworks/react-uswds';
import {useWindowSize} from 'react-use'; import {useWindowSize} from 'react-use';
import {useQuery} from 'react-query';
import axios from 'axios';
// Contexts: // Contexts:
import {useFlags} from '../contexts/FlagContext'; import {useFlags} from '../contexts/FlagContext';
// Components: // Components:
import TerritoryFocusControl from './territoryFocusControl';
import MapInfoPanel from './mapInfoPanel';
import AreaDetail from './AreaDetail'; import AreaDetail from './AreaDetail';
import MapInfoPanel from './mapInfoPanel';
import MapSearch from './MapSearch';
import TerritoryFocusControl from './territoryFocusControl';
// Styles and constants // Styles and constants
import {makeMapStyle} from '../data/mapStyle'; import {makeMapStyle} from '../data/mapStyle';
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 MapSearch from './MapSearch';
declare global { declare global {
@ -53,6 +55,15 @@ export interface IDetailViewInterface {
properties: constants.J40Properties, properties: constants.J40Properties,
}; };
const useSearchService = (searchTerm: string) => {
return useQuery('nominatumData', async () =>{
const {data} = await axios.get(`https://nominatim.openstreetmap.org/search?q=${searchTerm}&format=json`);
return data;
},
);
};
const J40Map = ({location}: IJ40Interface) => { const J40Map = ({location}: IJ40Interface) => {
// Hash portion of URL is of the form #zoom/lat/lng // Hash portion of URL is of the form #zoom/lat/lng
const [zoom, lat, lng] = location.hash.slice(1).split('/'); const [zoom, lat, lng] = location.hash.slice(1).split('/');
@ -74,8 +85,18 @@ const J40Map = ({location}: IJ40Interface) => {
const selectedFeatureId = (selectedFeature && selectedFeature.id) || ''; const selectedFeatureId = (selectedFeature && selectedFeature.id) || '';
const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]); const filter = useMemo(() => ['in', constants.GEOID_PROPERTY, selectedFeatureId], [selectedFeature]);
const [searchTerm, setSearchTerm] = useState('');
const {data, error, isFetching, isLoading} = useSearchService(searchTerm);
if (isLoading) console.log('Loading...');
else if (isFetching) console.log('Fetching...');
else if (error) console.log('Error: ', error);
else console.log('search results: ', data);
const onClick = (event: MapEvent) => { const onClick = (event: MapEvent) => {
console.log('map onclick: ', event);
const feature = event.features && event.features[0]; const feature = event.features && event.features[0];
if (feature) { if (feature) {
const [minLng, minLat, maxLng, maxLat] = bbox(feature); const [minLng, minLat, maxLng, maxLat] = bbox(feature);
@ -135,6 +156,13 @@ const J40Map = ({location}: IJ40Interface) => {
}); });
}; };
const onSearch = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const searchTermCurrent = event.currentTarget.elements.search.value;
console.log(searchTerm);
if (searchTermCurrent != searchTerm) setSearchTerm(searchTermCurrent);
};
const onClickTerritoryFocusButton = (event: MouseEvent<HTMLButtonElement>) => { const onClickTerritoryFocusButton = (event: MouseEvent<HTMLButtonElement>) => {
event.stopPropagation(); event.stopPropagation();
const buttonID = event.target && (event.target as HTMLElement).id; const buttonID = event.target && (event.target as HTMLElement).id;
@ -261,7 +289,7 @@ const J40Map = ({location}: IJ40Interface) => {
{geolocationInProgress ? <div>Geolocation in progress...</div> : ''} {geolocationInProgress ? <div>Geolocation in progress...</div> : ''}
<TerritoryFocusControl onClickTerritoryFocusButton={onClickTerritoryFocusButton}/> <TerritoryFocusControl onClickTerritoryFocusButton={onClickTerritoryFocusButton}/>
{'fs' in flags ? <FullscreenControl className={styles.fullscreenControl}/> :'' } {'fs' in flags ? <FullscreenControl className={styles.fullscreenControl}/> :'' }
<MapSearch /> <MapSearch onSearch={onSearch}/>
</ReactMapGL> </ReactMapGL>
</Grid> </Grid>

View file

@ -1,14 +1,24 @@
import React from 'react'; import React from 'react';
import {Search} from '@trussworks/react-uswds'; import {Search} from '@trussworks/react-uswds';
const onSearch = (event: React.FormEvent<HTMLFormElement>) => { interface IMapSearch {
event.preventDefault(); onSearch(e:React.FormEvent<HTMLFormElement>): void & React.FormEventHandler<HTMLFormElement>;
console.log('you searched!'); // onSearch(e:React.FormEvent<HTMLFormElement>): void
}
const onClickHandler = (e: React.MouseEvent<HTMLFormElement, MouseEvent>) => {
console.log('search on click:', e);
// Some how stop the map from doing
e.stopPropagation();
}; };
const MapSearch = () => { const MapSearch = ({onSearch}:IMapSearch) => {
return ( return (
<Search onSubmit={(e) => onSearch(e)} /> <Search
onClick={(e) => onClickHandler(e)}
placeholder="Enter in something (TBD)"
size="small"
onSubmit={(e) => onSearch(e)} />
); );
}; };

View file

@ -1,16 +1,21 @@
import React, {ReactNode} from 'react'; import React, {ReactNode} from 'react';
import J40Header from './J40Header';
import J40Footer from './J40Footer';
import {URLFlagProvider} from '../contexts/FlagContext';
import {Helmet} from 'react-helmet'; import {Helmet} from 'react-helmet';
import SurveyFab from './SurveyFab'; import {QueryClient, QueryClientProvider} from 'react-query';
import {ReactQueryDevtools} from 'react-query/devtools';
import {URLFlagProvider} from '../contexts/FlagContext';
import J40Footer from './J40Footer';
import J40Header from './J40Header';
import SurveyFab from './SurveyFab';
interface ILayoutProps { interface ILayoutProps {
children: ReactNode, children: ReactNode,
location: Location, location: Location,
title: string, title: string,
} }
const queryClient = new QueryClient();
const Layout = ({children, location, title}: ILayoutProps) => { const Layout = ({children, location, title}: ILayoutProps) => {
// @ts-ignore // @ts-ignore
return ( return (
@ -27,14 +32,17 @@ const Layout = ({children, location, title}: ILayoutProps) => {
</script> </script>
</Helmet> </Helmet>
<URLFlagProvider location={location}> <QueryClientProvider client={queryClient}>
<J40Header /> <URLFlagProvider location={location}>
<main id={'main-content'}> <J40Header />
{children} <main id={'main-content'}>
<SurveyFab /> {children}
</main> <SurveyFab />
<J40Footer/> </main>
</URLFlagProvider> <J40Footer/>
</URLFlagProvider>
<ReactQueryDevtools initialIsOpen />
</QueryClientProvider>
</> </>
); );
}; };