Skip to content

Commit

Permalink
Add CollectionDate for ESRI standard
Browse files Browse the repository at this point in the history
Available via click of the collectionDate button
  • Loading branch information
jo-chemla committed Jul 26, 2024
1 parent 7344a40 commit 9f3d8ed
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 32 deletions.
24 changes: 16 additions & 8 deletions src/control-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import {
MAX_PLANET_DATE,
useLocalStorage,
getBingViewportDate,
getEsriViewportDate,
retrieveAppleAccessToken,
// convertLatlonTo3857,
} from "./utilities";
Expand Down Expand Up @@ -361,16 +362,19 @@ function ControlPanel(props: any) {
const setMinDate = props.clickedMap == "left" ? setLeftMinDate : setRightMinDate
const setMaxDate = props.clickedMap == "left" ? setLeftMaxDate : setRightMaxDate

const collectionDateRetrievable: BasemapsIds[] = [BasemapsIds.Bing, BasemapsIds.PlanetMonthly]
const collectionDateRetrievable: BasemapsIds[] = [+BasemapsIds.Bing, +BasemapsIds.ESRI]
async function getCollectionDateViewport(selectedTms: BasemapsIds) {
setCollectionDateStr('')
let collectionDate = { validMinDate: '?', maxDate: '?' };
let collectionDate = { minDate: '?', maxDate: '?' };
const map = props.mapRef?.current?.getMap() as any;

switch (+selectedTms) {
case BasemapsIds.Bing:
collectionDate = await getBingViewportDate(map)
break;
case BasemapsIds.ESRI:
collectionDate = await getEsriViewportDate(map)
break;

default:
console.log(`Cannot retrieve collection date for ${selectedTms}.`);
Expand Down Expand Up @@ -634,6 +638,11 @@ function ControlPanel(props: any) {
}
}
}

const timeControlled = (tms: any) => [+BasemapsIds.ESRIWayback, +BasemapsIds.PlanetMonthly].includes(+tms)
const collectionDateAvailable = (tms: any) => collectionDateRetrievable.includes(+tms)
// (props.selectedTms == BasemapsIds.PlanetMonthly || props.selectedTms == BasemapsIds.ESRIWayback)

// console.log(props.timelineDate, 'timelineDate')
return (
<div
Expand Down Expand Up @@ -720,14 +729,14 @@ function ControlPanel(props: any) {
https://mui.com/material-ui/react-autocomplete/#creatable
*/}
{Object.entries(basemapsTmsSources).map(([key, value]) => (
<MenuItem value={key} key={key}>
{BasemapsIds[key]}
<MenuItem value={key} key={key} >
{BasemapsIds[key] + (timeControlled(key) ? ' 📅' : collectionDateAvailable(key) ? ' 🕒' : '')}
</MenuItem>
))}
{/* <MenuItem value={''}>Mapbox</MenuItem> */}
</Select>
</FormControl>
{(props.selectedTms == BasemapsIds.PlanetMonthly || props.selectedTms == BasemapsIds.ESRIWayback) && (
{timeControlled(props.selectedTms) && (
<>
{" "}
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="fr">
Expand Down Expand Up @@ -828,15 +837,14 @@ function ControlPanel(props: any) {
minHeight: '31px'
}}
>
{(collectionDateActivated && props.selectedTms == BasemapsIds.Bing) ? (
// {(( collectionDateActivated && collectionDateRetrievable.includes((props.selectedTms as BasemapsIds)) )) && (
{(collectionDateActivated && collectionDateAvailable(+props.selectedTms)) ? (
<Tooltip title={"Caution, Beta feature, only for Bing for now, Seems inacurate"}>
<Button
variant="outlined" // outlined or text
size="small"
sx={{ display: 'true' }}
onClick={() => {
getCollectionDateViewport(props.selectedTms, map)
getCollectionDateViewport(props.selectedTms)
}}>
Collection Date: {collectionDateStr}
</Button>
Expand Down
91 changes: 67 additions & 24 deletions src/utilities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,25 +119,28 @@ function getSliderMarksEveryYear(minDate: Date, maxDate: Date) {
// const basemapsTmsUrls = {
// Typescript was not accepting computed strings in enums, so used open Mapbox api token for simplicity
enum BasemapsIds {
ESRIWayback,
PlanetMonthly,
GoogleSat,
Bing,
Mapbox,
ESRI,
Mapbox,
Heremaps,
Yandex,
Apple,
GoogleHybrid,
OSM,
ESRIWayback
}

// Could find other TMS tile urls on NextGis QMS
// https://qms.nextgis.com/
// Which is what QuickMapServices Qgis plugin uses

const basemapsTmsSources: any = {
[BasemapsIds.PlanetMonthly]: {
[BasemapsIds.ESRIWayback]: {
maxzoom: 19,
},
[(BasemapsIds.PlanetMonthly)]: {
url: planetBasemapUrl(subMonths(new Date(), 2)),
maxzoom: 20,
},
Expand Down Expand Up @@ -187,9 +190,6 @@ const basemapsTmsSources: any = {
// "Google sat"= "https://mts1.google.com/vt/lyrs=s@186112443&amp;hl=en&amp;src=app&amp;s=Galile&amp;rlbl=1&amp;gl=AR&amp;key=AIzaSyARVMxmX0A7aRszJUjE33fSLQFMXAiMlxk&amp;z={Z}&amp;x={X}&amp;y={Y}",
// "Heremaps Sat"= "http://1.aerial.maps.api.here.com/maptile/2.1/maptile/newest/satellite.day/{z}/{x}/{y}/256/png8?app_id=hBqHrthpuP0nRYifaTTT&amp;app_code=iA3EYhFlEcBztET4RuA7Bg",
// "Mapbox Sat"= "https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.webp?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA",
[BasemapsIds.ESRIWayback]: {
maxzoom: 19,
}
};

// Lighter to use this utility rather than import whole of proj4
Expand Down Expand Up @@ -393,17 +393,33 @@ async function getBingDatesFromUrl(url: string) {
return dates ?? "error on fetch ?";
}

function getMinMaxDates(datesArr) {
const min = Math.min(...(datesArr as any))
console.log(min)
const minDate = new Date(
min
)
.toISOString()
.slice(0, 10);
const maxDate = new Date(
Math.max(...(datesArr as any))
)
.toISOString()
.slice(0, 10);
console.log("yaya", datesArr, "\n", minDate, maxDate);
return { minDate, maxDate }
}
async function getBingViewportDate(map: any) {
const urlArray = getVisibleTilesXYZ(map, 256); // source.tileSize)
console.log(urlArray);
const quadkeysArray = urlArray.map((xyz: any) => toQuad(xyz.x, xyz.y, xyz.z));
const xyzArray = getVisibleTilesXYZ(map, 256); // source.tileSize)
console.log(xyzArray);
const quadkeysArray = xyzArray.map((xyz: any) => toQuad(xyz.x, xyz.y, xyz.z));
console.log(quadkeysArray);
const bingUrls = quadkeysArray.map((quadkey: string) => getBingUrl(quadkey));
console.log(bingUrls);

const promArray = bingUrls.map(async (url) => {
return await getBingDatesFromUrl(url);
});
// const promArray = bingUrls.map(async (url) => {
// return await getBingDatesFromUrl(url);
// });
// console.log("promArray", promArray);
// Promise.all(promArray).then((dates) => {
// console.log("after promise.all", dates);
Expand All @@ -416,18 +432,44 @@ async function getBingViewportDate(map: any) {
const tilesDates = await Promise.all(
bingUrls.map(async (url) => await getBingDatesFromUrl(url))
);
const minDate = new Date(
Math.min(...(tilesDates as any).map((d: number[]) => d[0]))
)
.toISOString()
.slice(0, 10);
const maxDate = new Date(
Math.max(...(tilesDates as any).map((d: number[]) => d[1]))
)
.toISOString()
.slice(0, 10);
console.log("yaya", tilesDates, "\n", minDate, maxDate);
return { minDate, maxDate }
console.log(tilesDates)
// Each bing dates elements has a min and max date, stored in a 2 tuple array. Can be flattened for easier min/max computation
return getMinMaxDates(tilesDates.flat())
}
async function getEsriViewportDate(map: any) {
const ESRI_MAPSERVER_URL = 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/16/query'
const esriUrl = new URL(ESRI_MAPSERVER_URL)
const bounds = map.getBounds();
const [xmax, ymin] = bounds.getSouthEast().toArray()
const [xmin, ymax] = bounds.getNorthWest().toArray()
console.log('bounds', bounds)

esriUrl.search = new URLSearchParams({
f: 'json',
geometry: JSON.stringify({ xmin, ymin, xmax, ymax }),
maxAllowableOffset: '0',
outFields: 'NICE_DESC,NICE_NAME,OBJECTID,SAMP_RES,SRC_ACC,SRC_DATE2',
spatialRel: 'esriSpatialRelIntersects',
where: '1=1',
geometryType: 'esriGeometryEnvelope',
inSR: '4326',
outSR: '4326',
}) as any

const esriResultsRaw = await ky
.get(esriUrl.toString(), {}).json()

console.log(esriResultsRaw)

const esriDates = esriResultsRaw?.features.map(f => {
const dateEpoch = f.attributes['SRC_DATE2']
const date = dateEpoch ?
new Date(dateEpoch)
: '?'
return date
})
console.log('esriDates', esriDates)
return getMinMaxDates(esriDates)
}


Expand Down Expand Up @@ -489,5 +531,6 @@ export {
debounce,
useLocalStorage,
getBingViewportDate,
getEsriViewportDate,
retrieveAppleAccessToken,
};

0 comments on commit 9f3d8ed

Please sign in to comment.