Skip to content

Automatic Temporal Extent Calculation for Collections#999

Open
matthewhanson wants to merge 8 commits intomainfrom
mah/auto-temporal-extent
Open

Automatic Temporal Extent Calculation for Collections#999
matthewhanson wants to merge 8 commits intomainfrom
mah/auto-temporal-extent

Conversation

@matthewhanson
Copy link
Copy Markdown
Member

@matthewhanson matthewhanson commented Oct 30, 2025

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.interval defined 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: /collections and /collections/{collectionId}

Implementation

• Added getTemporalExtentFromItems() function in src/lib/database.js that uses two parallel sort queries to find earliest and latest item datetimes
• Added populateTemporalExtentIfMissing() helper in src/lib/api.js to check and populate temporal extent
• Updated both collection endpoints to call the helper function

Configuration

When ingesting collections, omit extent.temporal.interval to enable automatic calculation:

{
  "id": "my-collection",
  "extent": {
    "spatial": {...}
    // No temporal extent defined - will be calculated automatically
  }
}

Closes #1050

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.interval now 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.

Comment thread src/lib/api.js Outdated
Comment on lines +1267 to +1268
const hasTemporalExtent = collection.extent?.temporal?.interval?.[0]?.[0] !== undefined
|| collection.extent?.temporal?.interval?.[0]?.[1] !== undefined
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]

Suggested change
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;

Copilot uses AI. Check for mistakes.
Comment thread src/lib/api.js Outdated
Comment thread README.md Outdated
@matthewhanson matthewhanson requested a review from Copilot October 30, 2025 03:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread README.md Outdated
Comment thread README.md Outdated
matthewhanson and others added 2 commits October 29, 2025 23:48
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Collaborator

@pjhartzell pjhartzell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@matthewhanson matthewhanson added this to the 5.1.0 milestone Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support automatic temporal extent calculation for collections

3 participants