{"id":31755041,"url":"https://github.com/bmcandr/stac-tile-map","last_synced_at":"2025-10-09T18:33:17.372Z","repository":{"id":130652220,"uuid":"597950961","full_name":"bmcandr/stac-tile-map","owner":"bmcandr","description":null,"archived":false,"fork":false,"pushed_at":"2023-06-04T03:52:28.000Z","size":395,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-24T09:55:35.233Z","etag":null,"topics":["aws","aws-ecr","aws-lambda","aws-lambda-python","docker","earth-observations","fastapi","folium","geojson","github-actions","pants","pantsbuild","raster","sentinel-2","stac"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bmcandr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-06T04:05:10.000Z","updated_at":"2023-10-06T17:16:05.000Z","dependencies_parsed_at":"2023-09-26T10:16:14.863Z","dependency_job_id":null,"html_url":"https://github.com/bmcandr/stac-tile-map","commit_stats":{"total_commits":222,"total_committers":2,"mean_commits":111.0,"dds":"0.37387387387387383","last_synced_commit":"41e166400f2b2be79ba03a1d8bfd25ceca7ef75e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bmcandr/stac-tile-map","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcandr%2Fstac-tile-map","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcandr%2Fstac-tile-map/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcandr%2Fstac-tile-map/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcandr%2Fstac-tile-map/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bmcandr","download_url":"https://codeload.github.com/bmcandr/stac-tile-map/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcandr%2Fstac-tile-map/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001933,"owners_count":26083226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-ecr","aws-lambda","aws-lambda-python","docker","earth-observations","fastapi","folium","geojson","github-actions","pants","pantsbuild","raster","sentinel-2","stac"],"created_at":"2025-10-09T18:30:32.810Z","updated_at":"2025-10-09T18:33:17.367Z","avatar_url":"https://github.com/bmcandr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# STAC+COG Map\n\n[![codecov](https://codecov.io/github/bmcandr/stac-tile-map/branch/main/graph/badge.svg?token=CJRUFNT8QX)](https://codecov.io/github/bmcandr/stac-tile-map) [![Docker CI/CD Pipeline](https://github.com/bmcandr/stac-tile-map/actions/workflows/ci-docker-lambda.yml/badge.svg)](https://github.com/bmcandr/stac-tile-map/actions/workflows/ci-docker-lambda.yml)\n\n**TLDR;** [click here to view an interactive map displaying a recent Sentinel-2 image over a random populated place*!](https://6ukssjutoemmbqd3x7diq2xmlm0rjrmn.lambda-url.us-east-1.on.aws/map) Refresh for a new map.\n\n_* [data source](https://www.naturalearthdata.com/downloads/10m-cultural-vectors/10m-populated-places/)_\n\n## Overview\n\nThe code contained here:\n\n* loads a GeoJSON file and randomly selects a feature\n* searches [Element 84's EarthSearch STAC Catalog](https://earth-search.aws.element84.com/v1) for the most recent Sentinel-2 L2A scenes that intersect the selected geometry\n* creates a `folium` map with a tile layer displaying a Cloud Optimized GeoTiff hosted in the [AWS Registry of Open Data](https://registry.opendata.aws/sentinel-2-l2a-cogs/) served via [Development Seed's](https://developmentseed.org/) public [COG tiler](https://api.cogeo.xyz).\n\nThere is a CLI to generate a standalone HTML file and a FastAPI app for dynamically generating maps ([docs](https://6ukssjutoemmbqd3x7diq2xmlm0rjrmn.lambda-url.us-east-1.on.aws/docs)).\n\nThe FastAPI app is deployed to an AWS Lambda function using GitHub Actions.\n\n## Setup\n\nThis repo uses [PDM](https://pdm.fming.dev/latest/) for dependency management. After cloning this repo, run `pdm install --no-self` from the root directory to create a virtual environment with the required dependencies. Run `eval $(pdm venv activate)` to activate the environment in your session.\n\nSet `$PYTHONPATH` to the source path by changing directories into `src/python` and executing:\n\n```bash\nexport PYTHONPATH=`pwd`\n```\n\nChange directories back to the root.\n\n## Running the Thing\n\n### Generating an HTML file\n\nTo generate an HTML file for local display, use the `click` CLI tool:\n\n`python src/python/stac_tiler_map/cli.py`\n\nOpen the resulting `map.html` file with any web browser.\n\n### Running a local server\n\nThere are several ways to run the FastAPI app locally: Python, `uvicorn`, Docker, and PEX.\n\n* Python: `python src/python/api/main.py` (open `localhost:8080/`)\n* `uvicorn`: `uvicorn src.python.api.main:app --reload --port 8080` (open `localhost:8080/`)\n* Docker: `docker build -t stac-tiler-map . \u0026\u0026 docker run -p 8080:8080 stac-tiler-map`\n\n[PEX](https://pex.readthedocs.io/en/v2.1.129/) is a little more involved. In short:\n\n* [install Pants](https://www.pantsbuild.org/docs/installation)\n* bootstrap Pants by running `pants -v`\n* package the FastAPI app as a PEX with `pants --tag=\"pex\" package ::`\n* run the app from the PEX with `./dist/src.python.api/stac-tiler-map-api.pex api.main:app --port 8080`\n\n### Deploying to AWS\n\nI use a GitHub Actions workflow (`.github/workflows/ci-docker-lambda.yml`) to deploy the FastAPI app as a Docker-based AWS Lambda function. The GHA workflow builds an image from `Dockerfile.aws.lambda`, pushes the image to Elastic Container Registry, and updates the Lambda function with the new image. The link at the top of this is served by the Lambda function. Serverless is neat!\n\n### Problems\n\nIt should be possible to deploy the FastAPI app to AWS Lambda as a PEX hosted in S3. The `.github/workflows/ci-pants-lambda.yml` file uses Pants to package the code in a Lambda-compliant PEX, uploads it to an S3 bucket, and updates the Lambda function. The app refuses to run, however, due to dependency issues (e.g., wheel tags don't match for `cryptography` library [`cp36` vs `cp39`]). Not sure how to fix this at the moment...\n\n### Test Coverage\n\nThe inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.\n\n![](https://codecov.io/github/bmcandr/stac-tile-map/branch/main/graphs/sunburst.svg?token=CJRUFNT8QX)\n\n## Acknowledgements\n\nThis repo began as a weekend project inspired by @scottyhq's [`share-a-map`](https://github.com/scottyhq/share-a-map) repository. The first iteration used GitHub Actions to periodically generate a new map file via the CLI tool and commit the result to the repo which was then deployed to GitHub Pages. In this iteration, I use GitHub Actions to deploy to an AWS Lambda function backed by a Docker container hosted on AWS Elastic Container Registry. This is totally overkill, but it was a fun way to practice and learn.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmcandr%2Fstac-tile-map","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbmcandr%2Fstac-tile-map","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmcandr%2Fstac-tile-map/lists"}