diff --git a/.github/workflows/deploy-branch.yml b/.github/workflows/deploy-branch.yml new file mode 100644 index 000000000..99f2da98a --- /dev/null +++ b/.github/workflows/deploy-branch.yml @@ -0,0 +1,60 @@ +name: Deploy Branch Preview +on: + push: + branches-ignore: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + deploy-preview: + runs-on: ubuntu-latest + env: + SEMANTIC_SEARCH_API_URL: ${{ secrets.SEMANTIC_SEARCH_API_URL }} + steps: + - uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - uses: actions/checkout@v4 + + - name: Get branch name + id: branch-name + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "branch_name=${{ github.head_ref }}" >> $GITHUB_OUTPUT + else + echo "branch_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT + fi + - name: Install dependencies + run: npm install + + - name: Build for preview + run: npm run build -- --pathPrefix="/stac-browser/preview/${{ steps.branch-name.outputs.branch_name }}" --historyMode=hash --semanticSearchApiUrl="${{ env.SEMANTIC_SEARCH_API_URL }}" + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: dist + exclude_assets: "report.html" + user_name: "STAC Browser CI" + user_email: github@developmentseed.org + destination_dir: preview/${{ steps.branch-name.outputs.branch_name }} + publish_branch: gh-pages-preview + + - name: Comment PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const url = `https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/preview/${{ steps.branch-name.outputs.branch_name }}/`; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `🚀 **Preview deployed!**\n\nYour changes are now available at: ${url}\n\nThis preview will be automatically updated on each push to this branch.` + }); diff --git a/README.md b/README.md index 69fe7b1b4..1e0abafe0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ It's not officially supported, but you may also be able to use it for certain _OGC API - Records_ and _OGC API - Features_ compliant servers. **Please note that STAC Browser is currently with limited funding for both maintenance, bug fixes and improvements. This means issues and PRs may be addressed very slowly. -If you care about STAC Browser and have some funds to support the future of STAC Browser, please contact matthias@mohr.ws** +If you care about STAC Browser and have some funds to support the future of STAC Browser, please contact ** **Table of Contents:** @@ -37,6 +37,7 @@ If you care about STAC Browser and have some funds to support the future of STAC - [Translation](#translation) - [Customize through root catalog](#customize-through-root-catalog) - [Custom extensions](#custom-extensions) + - [Natural Language Search](#natural-language-search) - [Docker](#docker) - [Contributing](#contributing) - [Adding a new language](#adding-a-new-language) @@ -269,6 +270,48 @@ STAC Browser supports some non-standardized extensions to the STAC specification Add a `name` field and it will be used as title in the tab header, the same applies for the core Asset Object. 3. A link with relation type `icon` and a Browser-supported media type in any STAC entity will show an icon in the header and the lists of Catalogs, Collections and Items. +### Natural Language Search + +STAC Browser supports natural language search functionality that allows users to search for STAC items using descriptive queries in natural language (e.g., "satellite images of forests in California from 2023"). + +To enable natural language search: + +1. **Configure the API URL**: Set the `semanticSearchApiUrl` option in your configuration file: + +```javascript +// config.js +module.exports = { + // ... other config options + semanticSearchApiUrl: "https://your-semantic-search-api.com", + // ... other config options +}; +``` + +2. **API Requirements**: Your semantic search API should accept POST requests to `/items/search` with the following format: + +```json +{ + "query": "your natural language query", + "limit": 10 +} +``` + +And return results in this format: + +```json +{ + "results": { + "items": [ + // Array of STAC items + ] + } +} +``` + +3. **User Interface**: Once configured, users will see the "Natural Language Query" search interface where they can enter descriptive queries. + +**Note**: Natural language search is disabled by default. The feature will only appear in the interface when `semanticSearchApiUrl` is configured with a valid API URL. + ## Docker You can use the Docker to work with STAC Browser. Please read [Docker documentation](docs/docker.md) for more details. diff --git a/config.js b/config.js index 2b32abc30..58f89b92f 100644 --- a/config.js +++ b/config.js @@ -48,5 +48,6 @@ module.exports = { requestQueryParameters: {}, socialSharing: ['email', 'bsky', 'mastodon', 'x'], preprocessSTAC: null, - authConfig: null + authConfig: null, + semanticSearchApiUrl: false, }; diff --git a/src/components/ApiCapabilitiesMixin.js b/src/components/ApiCapabilitiesMixin.js index d3b797fcb..904ec2158 100644 --- a/src/components/ApiCapabilitiesMixin.js +++ b/src/components/ApiCapabilitiesMixin.js @@ -73,6 +73,9 @@ export default { canFilterFreeText() { return this.supportsConformance(this.conformances.FreeText); }, + canSupportNaturalLanguage() { + return true; + }, cql() { if (!this.supportsConformance(this.conformances.CqlFilters)) { return null; diff --git a/src/components/Map.vue b/src/components/Map.vue index 69d45e71a..36d75c626 100644 --- a/src/components/Map.vue +++ b/src/components/Map.vue @@ -11,6 +11,7 @@ + ${this.$t('search.naturalLanguageSearchArea')}

${this.$t('search.naturalLanguageSearchAreaDescription')}

`; + layer.bindPopup(html); + }, addBoundsSelector() { this.areaSelect = L.areaSelect({ // eslint-disable-line width: 300, diff --git a/src/components/SearchFilter.vue b/src/components/SearchFilter.vue index 82dcd04de..7f3ffb946 100644 --- a/src/components/SearchFilter.vue +++ b/src/components/SearchFilter.vue @@ -6,6 +6,47 @@ + + +
+ {{ $t('search.naturalLanguageInfo') }} +
+ + {{ naturalLanguageError }} + +
+ +
+ + + {{ $t('search.processing') }} + + + {{ $t('search.populateForm') }} + + + + + {{ $t('search.processing') }} + + + {{ $t('search.searchDirectly') }} + + +
+
+
+ +
+ - {{ $t('search.filterBySpatialExtent') }} - + + +
+
+ {{ $t('search.spatialExtentOptions.naturalSearchArea') }}: + {{ $t('search.naturalSearchAreaDescription') }} +
+ +
@@ -116,7 +164,7 @@