From 065e5914ecf4ecc46916fa74785bb080bf02498f Mon Sep 17 00:00:00 2001 From: eireland Date: Wed, 31 Jan 2024 08:59:18 -0800 Subject: [PATCH 1/2] Detects if station selection came from CODAP map and calculates distance of station from location lat long --- src/components/App.tsx | 11 +++++++---- src/components/location-picker.tsx | 11 ++++++++--- src/types.ts | 2 ++ src/utils/geonameSearch.ts | 4 ++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index f06f9fb..c167fcf 100755 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -6,14 +6,14 @@ import { AttributesSelector } from "./attribute-selector"; import { AttributeFilter } from "./attribute-filter"; import { InfoModal } from "./info-modal"; import { useStateContext } from "../hooks/use-state"; -import { adjustStationDataset, getWeatherStations } from "../utils/getWeatherStations"; +import { adjustStationDataset, calculateDistance, getWeatherStations } from "../utils/getWeatherStations"; import { addNotificationHandler, createStationsDataset, guaranteeGlobal } from "../utils/codapHelpers"; import InfoIcon from "../assets/images/icon-info.svg"; import { useCODAPApi } from "../hooks/use-codap-api"; import { composeURL, formatData } from "../utils/noaaApiHelper"; -import { IDataType } from "../types"; +// import { IDataType } from "../types"; import { StationDSName, globalMaxDate, globalMinDate } from "../constants"; -import { geoLocSearch } from "../utils/geonameSearch"; +import { geoLocSearch, geoNameSearch } from "../utils/geonameSearch"; import { DataReturnWarning } from "./data-return-warning"; import "./App.scss"; @@ -44,11 +44,14 @@ export const App = () => { const station = myCase.values; const {latitude, longitude} = station; const locationName = await geoLocSearch(latitude, longitude); + const locale = await geoNameSearch(locationName, 1); + const distance = locale && calculateDistance(latitude, longitude, locale[0].latitude, locale[0].longitude); setState((draft) => { draft.weatherStation = station; draft.location = {name: locationName, latitude, longitude}; - draft.weatherStationDistance = 0; + draft.weatherStationDistance = distance; draft.zoomMap = false; + draft.didUserSelectStationFromMap = true; }); } } diff --git a/src/components/location-picker.tsx b/src/components/location-picker.tsx index e85dfa0..a213b17 100644 --- a/src/components/location-picker.tsx +++ b/src/components/location-picker.tsx @@ -14,7 +14,7 @@ import "./location-picker.scss"; export const LocationPicker = () => { const {state, setState} = useStateContext(); - const {units, location, weatherStation, weatherStationDistance, startDate, endDate} = state; + const {units, location, weatherStation, weatherStationDistance, startDate, endDate, didUserSelectStationFromMap} = state; const [showMapButton, setShowMapButton] = useState(false); const [isEditing, setIsEditing] = useState(false); const [locationPossibilities, setLocationPossibilities] = useState([]); @@ -71,7 +71,7 @@ export const LocationPicker = () => { useEffect(() => { const _startDate = startDate ? startDate : new Date( -5364662060); // 1/1/1750 const _endDate = endDate ? endDate : new Date(Date.now()); - if (location) { + if (location && !didUserSelectStationFromMap) { findNearestActiveStations(location.latitude, location.longitude, _startDate, _endDate) .then((stationList: IStation[]) => { if (stationList) { @@ -110,7 +110,7 @@ export const LocationPicker = () => { }); } // eslint-disable-next-line react-hooks/exhaustive-deps - },[endDate, isEditing, location, startDate]); + },[endDate, isEditing, location, startDate, didUserSelectStationFromMap]); useEffect(() => { if (showStationSelectionList) { @@ -137,6 +137,7 @@ export const LocationPicker = () => { const placeNameSelected = (place: IPlace | undefined) => { setState(draft => { draft.location = place; + draft.didUserSelectStationFromMap = false; }); setShowSelectionList(false); setIsEditing(false); @@ -149,6 +150,7 @@ export const LocationPicker = () => { const stationSelected = (station: IWeatherStation | undefined) => { setState(draft => { draft.weatherStation = station; + draft.didUserSelectStationFromMap = false; }); setShowStationSelectionList(false); setStationHoveredIndex(null); @@ -218,6 +220,7 @@ export const LocationPicker = () => { setState(draft=>{ draft.location = locationPossibilities[selectedLocIdx]; draft.zoomMap = true; + draft.didUserSelectStationFromMap = false; }); } } @@ -240,6 +243,7 @@ export const LocationPicker = () => { const selectedStation = stationPossibilities[selectedLocIdx].station; stationSelected(selectedStation); setState(draft => { + draft.didUserSelectStationFromMap = false; draft.weatherStation = selectedStation; draft.weatherStationDistance = stationPossibilities[selectedLocIdx].distance; }); @@ -273,6 +277,7 @@ export const LocationPicker = () => { geoLocSearch(lat, long).then((currPosName) => { setState(draft => { draft.location = {name: currPosName, latitude: lat, longitude: long}; + draft.didUserSelectStationFromMap = false; }); setShowMapButton(true); setIsEditing(false); diff --git a/src/types.ts b/src/types.ts index 8a9c74d..c469595 100644 --- a/src/types.ts +++ b/src/types.ts @@ -121,6 +121,7 @@ export interface IState { didUserSelectDate: boolean; isMapOpen: boolean; zoomMap: boolean; + didUserSelectStationFromMap: boolean; } export const unitMap: UnitMap = { @@ -161,6 +162,7 @@ export const DefaultState: IState = { didUserSelectDate: false, isMapOpen: false, zoomMap: false, + didUserSelectStationFromMap: false, }; interface IDataTypeUnits { diff --git a/src/utils/geonameSearch.ts b/src/utils/geonameSearch.ts index 4fd8abd..b12448e 100644 --- a/src/utils/geonameSearch.ts +++ b/src/utils/geonameSearch.ts @@ -7,7 +7,7 @@ const kDefaultMaxRows = 4; const kGeonamesUser = "codap"; -async function geoNameSearch(searchString: string, maxRows?: number): Promise { +export const geoNameSearch = async (searchString: string, maxRows?: number): Promise =>{ const userClause = `username=${kGeonamesUser}`; const countryClause = "country=US"; const maxRowsClause = `maxRows=${maxRows || kDefaultMaxRows}`; @@ -34,7 +34,7 @@ async function geoNameSearch(searchString: string, maxRows?: number): Promise { let thisQuery = inputEl.value; From 87b47216a745c74c7e689159a9c1e29464739e0f Mon Sep 17 00:00:00 2001 From: eireland Date: Wed, 31 Jan 2024 10:17:18 -0800 Subject: [PATCH 2/2] Fixes distance calculation when station is selected from the CODAP map --- src/components/App.tsx | 12 ++++++------ src/types.ts | 3 +-- src/utils/geonameSearch.ts | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 49f4f6c..a99b9c3 100755 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -7,12 +7,12 @@ import { AttributesSelector } from "./attribute-selector"; import { AttributeFilter } from "./attribute-filter"; import { InfoModal } from "./info-modal"; import { useStateContext } from "../hooks/use-state"; -import { adjustStationDataset, calculateDistance, getWeatherStations } from "../utils/getWeatherStations"; +import { adjustStationDataset, getWeatherStations } from "../utils/getWeatherStations"; import { addNotificationHandler, createStationsDataset, guaranteeGlobal } from "../utils/codapHelpers"; import { useCODAPApi } from "../hooks/use-codap-api"; import { composeURL, formatData } from "../utils/noaaApiHelper"; import { StationDSName, globalMaxDate, globalMinDate } from "../constants"; -import { geoLocSearch, geoNameSearch } from "../utils/geonameSearch"; +import { geoLocSearch } from "../utils/geonameSearch"; import { DataReturnWarning } from "./data-return-warning"; import { IState } from "../types"; import InfoIcon from "../assets/images/icon-info.svg"; @@ -82,12 +82,12 @@ export const App = () => { if (myCase) { const station = myCase.values; const {latitude, longitude} = station; - const locationName = await geoLocSearch(latitude, longitude); - const locale = await geoNameSearch(locationName, 1); - const distance = locale && calculateDistance(latitude, longitude, locale[0].latitude, locale[0].longitude); + const locationInfo = await geoLocSearch(latitude, longitude); + const locale = `${locationInfo.split(",")[0]}, ${locationInfo.split(",")[1]}`; + const distance = Number(locationInfo.split(",")[2]); setState((draft) => { draft.weatherStation = station; - draft.location = {name: locationName, latitude, longitude}; + draft.location = {name: locale, latitude, longitude}; draft.weatherStationDistance = distance; draft.zoomMap = false; draft.didUserSelectStationFromMap = true; diff --git a/src/types.ts b/src/types.ts index 28f9fc7..04cdb9d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -124,7 +124,7 @@ export interface IState { didUserSelectDate: boolean; isMapOpen: boolean; zoomMap: boolean; - didUserSelectStationFromMap: boolean; + didUserSelectStationFromMap?: boolean; } export const unitMap: UnitMap = { @@ -165,7 +165,6 @@ export const DefaultState: IState = { didUserSelectDate: false, isMapOpen: false, zoomMap: false, - didUserSelectStationFromMap: false, }; interface IDataTypeUnits { diff --git a/src/utils/geonameSearch.ts b/src/utils/geonameSearch.ts index b12448e..009427f 100644 --- a/src/utils/geonameSearch.ts +++ b/src/utils/geonameSearch.ts @@ -57,7 +57,7 @@ export const geoLocSearch = async (lat: number, long: number) => { const response = await fetch(url); if (response.ok) { const data = await response.json(); - return `${data?.geonames?.[0]?.name}, ${data?.geonames?.[0]?.adminCode1}` || "Unknown Location"; + return `${data?.geonames?.[0]?.name}, ${data?.geonames?.[0]?.adminCode1}, ${data?.geonames?.[0]?.distance}` || "Unknown Location"; } else { return Promise.reject(response.statusText); }