Automatic Temporal Extent Calculation for Collections#999
Conversation
…(if not provided on ingest)
There was a problem hiding this comment.
Pull Request Overview
This PR adds automatic temporal extent calculation for STAC collections based on item datetime ranges. Collections without predefined temporal extents will have them calculated dynamically when served via the API, using efficient sort queries to find the earliest and latest item datetimes.
Key changes:
- Added
getTemporalExtentFromItems()function that uses parallel ascending/descending sort queries to efficiently find temporal boundaries - Collections without
extent.temporal.intervalnow have it auto-calculated from their items - Empty collections return
[[null, null]]as their temporal extent
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/database.js | Added getTemporalExtentFromItems() function to query earliest and latest item datetimes using parallel sort operations |
| src/lib/api.js | Added populateTemporalExtentIfMissing() helper and integrated it into collection endpoints |
| tests/system/test-api-temporal-extent.js | Added comprehensive test suite covering temporal extent calculation for collections with items and empty collections |
| README.md | Added documentation for the automatic temporal extent feature |
| CHANGELOG.md | Added entry documenting the new automatic temporal extent calculation feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const hasTemporalExtent = collection.extent?.temporal?.interval?.[0]?.[0] !== undefined | ||
| || collection.extent?.temporal?.interval?.[0]?.[1] !== undefined |
There was a problem hiding this comment.
This check is insufficient to determine if temporal extent is defined. A collection with extent.temporal.interval set to [[null, null]] will fail this check (both values are not undefined), but this should be treated as missing temporal extent since null values indicate no data. The check should verify that at least one of the values is non-null: collection.extent?.temporal?.interval?.[0]?.[0] || collection.extent?.temporal?.interval?.[0]?.[1]
| const hasTemporalExtent = collection.extent?.temporal?.interval?.[0]?.[0] !== undefined | |
| || collection.extent?.temporal?.interval?.[0]?.[1] !== undefined | |
| const start = collection.extent?.temporal?.interval?.[0]?.[0]; | |
| const end = collection.extent?.temporal?.interval?.[0]?.[1]; | |
| const hasTemporalExtent = start != null || end != null; |
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
pjhartzell
left a comment
There was a problem hiding this comment.
Looks reasonable to me.
- Resolved conflicts in database.js by including both getTemporalExtentFromItems and buildFieldsFilter exports - Accepted main's restructured README (now a landing page) - Accepted main's package-lock.json - Added automatic temporal extent documentation to docs/usage/index.md
# Conflicts: # src/lib/api.ts
Synced to
|
Align the temporal-extent test with the completed TS migration (#1095), which set ava `extensions: ["ts"]`. As a lone `.js` file it only ran via the explicit glob in system-tests.sh and would be skipped by a plain `ava` invocation. Typed `t.context` via `StandUpResult` to match the other migrated system tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the converted .ts test file (the prior commit recorded only the .js removal because the combined `git add` aborted on the already-removed .js pathspec). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Populate a collection's temporal extent per-bound: a missing start is filled from the earliest item datetime and a missing end from the latest, but any bound already declared on the collection is preserved (previously an open-ended extent had BOTH bounds recomputed, discarding a declared start). Update the system test, docs, and CHANGELOG to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The automatic temporal extent feature (#999) replaced a collection's entire extent.temporal.interval array with a single computed interval whenever the overall extent needed backfilling, discarding any declared sub-intervals (interval[1..n]). Only compute the overall extent (interval[0]) from items and preserve declared sub-intervals. Adds a regression test covering a collection with multiple intervals.
The automatic temporal extent feature (#999) replaced a collection's entire extent.temporal.interval array with a single computed interval whenever the overall extent needed backfilling, discarding any declared sub-intervals (interval[1..n]). Only compute the overall extent (interval[0]) from items and preserve declared sub-intervals. Adds a regression test covering a collection with multiple intervals.
The automatic temporal extent feature (#999) replaced a collection's entire extent.temporal.interval array with a single computed interval whenever the overall extent needed backfilling, discarding any declared sub-intervals (interval[1..n]). Only compute the overall extent (interval[0]) from items and preserve declared sub-intervals. Adds a regression test covering a collection with multiple intervals.
Adds automatic temporal extent calculation for STAC collections based on the
actual datetime range of items in the collection.
Changes
• Automatic calculation: Collections without a predefined temporal extent now have it calculated
dynamically from their items when served via the API
• Opt-in behavior: Only collections without
extent.temporal.intervaldefined will have it auto-calculated• Performant implementation: Uses efficient sorting queries (ascending/descending) rather than aggregations
• Empty collection handling: Collections with no items return
[[null, null]]• Endpoints affected:
/collectionsand/collections/{collectionId}Implementation
• Added
getTemporalExtentFromItems()function insrc/lib/database.jsthat uses two parallel sort queries to find earliest and latest item datetimes• Added
populateTemporalExtentIfMissing()helper insrc/lib/api.jsto check and populate temporal extent• Updated both collection endpoints to call the helper function
Configuration
When ingesting collections, omit
extent.temporal.intervalto enable automatic calculation:{ "id": "my-collection", "extent": { "spatial": {...} // No temporal extent defined - will be calculated automatically } }Closes #1050