This server provides map tiles.
51 |Request tiles using the format: /z/x/y.png
Example: /0/0/0.png
53 | 54 | '; 55 | } 56 | 57 | location /health { 58 | access_log off; 59 | return 200 "healthy\n"; 60 | add_header Content-Type text/plain; 61 | } 62 | } 63 | 64 | upstream tileserver_backend { 65 | server tileserver:8080; 66 | } 67 | -------------------------------------------------------------------------------- /docs/images/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from 'globals'; 2 | import pluginJs from '@eslint/js'; 3 | import tseslint from 'typescript-eslint'; 4 | import pluginReact from 'eslint-plugin-react'; 5 | import reactHooks from 'eslint-plugin-react-hooks'; 6 | import reactRefresh from 'eslint-plugin-react-refresh'; 7 | import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; 8 | 9 | /** @type {import('eslint').Linter.Config[]} */ 10 | export default [ 11 | { 12 | files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'], 13 | settings: { react: { version: 'detect' } }, 14 | languageOptions: { ecmaVersion: 2020, globals: globals.browser }, 15 | plugins: { 'react-hooks': reactHooks, 'react-refresh': reactRefresh } 16 | }, 17 | pluginJs.configs.recommended, 18 | ...tseslint.configs.recommended, 19 | pluginReact.configs.flat.recommended, 20 | eslintPluginPrettierRecommended, 21 | { 22 | name: 'Custom Rules ', 23 | rules: { 24 | 'no-console': 2, 25 | 'prefer-promise-reject-errors': 0, 26 | // 'import/order': 2, 27 | 'react/button-has-type': 2, 28 | 'react/jsx-closing-bracket-location': 2, 29 | 'react/jsx-closing-tag-location': 2, 30 | 'react/jsx-curly-spacing': 2, 31 | 'react/jsx-curly-newline': 2, 32 | 'react/jsx-equals-spacing': 2, 33 | 'react/jsx-max-props-per-line': [2, { maximum: 1, when: 'multiline' }], 34 | 'react/jsx-first-prop-new-line': 2, 35 | 'react/jsx-curly-brace-presence': [ 36 | 2, 37 | { props: 'never', children: 'never' } 38 | ], 39 | 'react/jsx-pascal-case': 2, 40 | 'react/jsx-props-no-multi-spaces': 2, 41 | 'react/jsx-tag-spacing': [2, { beforeClosing: 'never' }], 42 | 'react/jsx-wrap-multilines': 2, 43 | 'react/no-array-index-key': 2, 44 | 'react/no-typos': 2, 45 | 'react/no-unused-prop-types': 2, 46 | 'react/no-unused-state': 2, 47 | 'react/react-in-jsx-scope': 'off', 48 | 'react/self-closing-comp': 2, 49 | 'react/style-prop-object': 2, 50 | 'react/void-dom-elements-no-children': 2, 51 | 'react/function-component-definition': [ 52 | 2, 53 | { namedComponents: ['function-declaration', 'arrow-function'] } 54 | ], 55 | 'react-hooks/rules-of-hooks': 2, // Checks rules of Hooks 56 | // 'react-hooks/exhaustive-deps': 1, // Checks effect dependencies 57 | // 'fp/no-mutating-methods': 1, 58 | '@typescript-eslint/no-explicit-any': 'warn' 59 | } 60 | } 61 | ]; 62 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: OpenAerialMap 2 | site_description: OpenAerialMap is an open service to provide access to a commons of openly licensed imagery and map layer services. 3 | # strict: true 4 | site_url: "https://docs.imagery.hotosm.org/" 5 | 6 | repo_name: "hotosm/openaerialmap" 7 | repo_url: "https://github.com/hotosm/openaerialmap/" 8 | edit_uri: "edit/main/docs/" 9 | 10 | extra: 11 | social: 12 | - icon: "fontawesome/brands/github" 13 | link: "https://github.com/hotosm/" 14 | - icon: "fontawesome/brands/twitter" 15 | link: "https://twitter.com/hotosm" 16 | - icon: "fontawesome/solid/globe" 17 | link: "https://www.hotosm.org" 18 | copyright: Copyright © 2010 HOTOSM 19 | generator: false 20 | 21 | theme: 22 | name: material 23 | palette: 24 | primary: custom 25 | language: en 26 | favicon: images/favicon.svg 27 | logo: images/hot_logo.png 28 | 29 | extra_css: 30 | - css/extra.css 31 | - css/timeline.css 32 | 33 | markdown_extensions: 34 | - tables 35 | - toc: 36 | permalink: true 37 | title: Page contents 38 | - admonition 39 | - pymdownx.details 40 | - pymdownx.superfences 41 | - pymdownx.highlight 42 | - pymdownx.extra 43 | - pymdownx.emoji: 44 | - pymdownx.tabbed: 45 | alternate_style: true 46 | - mdx_truly_sane_lists 47 | 48 | plugins: 49 | - search 50 | - git-revision-date-localized 51 | - exclude: 52 | glob: 53 | - plugins/* 54 | - __pycache__/* 55 | - mkdocstrings: 56 | handlers: 57 | python: 58 | paths: [.] 59 | options: 60 | members_order: source 61 | separate_signature: true 62 | filters: ["!^_"] 63 | docstring_options: 64 | ignore_init_summary: true 65 | merge_init_into_class: true 66 | 67 | nav: 68 | - Home: index.md 69 | - Get Started: 70 | - About: about/about.md 71 | # - Installation: INSTALL.md 72 | # - Contribution Guidelines: CONTRIBUTING.md 73 | - Code of Conduct: https://docs.hotosm.org/code-of-conduct 74 | - FAQ: about/faq.md 75 | - Developer Guide: 76 | - Practices: 77 | - Dev Practices: https://docs.hotosm.org/dev-practices 78 | - Tech Decisions: decisions/README.md 79 | - Pre-Commit: https://docs.hotosm.org/dev-guide/repo-management/pre-commit/ 80 | - Versioning: https://docs.hotosm.org/dev-guide/repo-management/version-control/#creating-releases 81 | - Backend: 82 | - Global Mosaic: dev/backend/global-mosaic.md 83 | - STAC API: dev/backend/stac-api.md 84 | - STAC Ingester: dev/backend/stac-ingester.md 85 | - Frontend: dev/frontend.md 86 | - Adding New Providers: dev/new-provider.md 87 | - Backup Prod STAC: dev/backup-prod-pgstac.md 88 | - Roadmap: https://github.com/hotosm/openaerialmap#roadmap 89 | - Timeline: about/timeline.md 90 | - API Docs: https://hotosm.github.io/swagger/?url=https://api.imagery.hotosm.org/raster/api 91 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openaerialmap", 3 | "description": "OpenAerialMap frontend.", 4 | "version": "0.0.1", 5 | "repository": { 6 | "type": "git", 7 | "url": "" 8 | }, 9 | "author": { 10 | "name": "Development Seed", 11 | "url": "https://developmentseed.org" 12 | }, 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com" 16 | }, 17 | "homepage": "", 18 | "scripts": { 19 | "serve": "pnpm clean && NODE_ENV=development vite", 20 | "build": "pnpm clean && NODE_ENV=production tsc -b && vite build", 21 | "stage": "pnpm clean && NODE_ENV=staging tsc -b && vite build", 22 | "clean": "rm -rf dist node_modules/.vite", 23 | "lint": "pnpm lint:scripts", 24 | "lint:scripts": "eslint app/", 25 | "ts-check": "npx tsc --noEmit --skipLibCheck", 26 | "test": "jest" 27 | }, 28 | "engines": { 29 | "node": "22.x" 30 | }, 31 | "browserslist": "> 0.5%, last 2 versions, not dead", 32 | "devDependencies": { 33 | "@eslint/js": "^9.30.1", 34 | "@tanstack/eslint-plugin-query": "^5.81.2", 35 | "@testing-library/jest-dom": "^6.6.3", 36 | "@testing-library/react": "^16.3.0", 37 | "@testing-library/user-event": "^14.6.1", 38 | "@types/babel__core": "^7.20.5", 39 | "@types/d3-scale-chromatic": "^3.1.0", 40 | "@types/geojson": "^7946.0.16", 41 | "@types/jest": "^30.0.0", 42 | "@types/node": "^24.0.10", 43 | "@types/portscanner": "^2.1.4", 44 | "@types/react": "^19.1.8", 45 | "@types/react-dom": "^19.1.6", 46 | "@vitejs/plugin-react": "^4.6.0", 47 | "babel-jest": "^30.0.2", 48 | "eslint": "^9.30.1", 49 | "eslint-config-prettier": "^10.1.5", 50 | "eslint-plugin-prettier": "^5.5.1", 51 | "eslint-plugin-react": "^7.37.5", 52 | "eslint-plugin-react-hooks": "^5.2.0", 53 | "eslint-plugin-react-refresh": "^0.4.20", 54 | "globals": "^16.3.0", 55 | "jest": "^30.0.3", 56 | "jest-environment-jsdom": "^30.0.2", 57 | "portscanner": "^2.2.0", 58 | "prettier": "^3.6.2", 59 | "ts-jest": "^29.4.0", 60 | "ts-node": "^10.9.2", 61 | "typescript": "~5.8.3", 62 | "typescript-eslint": "^8.35.1", 63 | "vite": "^7.0.0" 64 | }, 65 | "dependencies": { 66 | "@awesome.me/webawesome": "3.0.0-beta.1", 67 | "@hotosm/ui": "0.3.1-b1", 68 | "@tanstack/react-query": "^5.81.5", 69 | "d3-scale-chromatic": "^3.1.0", 70 | "maplibre-gl": "^5.6.1", 71 | "next-themes": "^0.4.6", 72 | "pmtiles": "^4.3.0", 73 | "react": "^19.1.0", 74 | "react-dom": "^19.1.0", 75 | "react-icons": "^5.5.0", 76 | "stac-ts": "^1.0.4" 77 | }, 78 | "alias": { 79 | "$components": "~/app/components", 80 | "$styles": "~/app/styles", 81 | "$utils": "~/app/utils", 82 | "$hooks": "~/app/hooks", 83 | "$pages": "~/app/pages", 84 | "$test": "~/test" 85 | }, 86 | "packageManager": "pnpm@10.6.4+sha512.da3d715bfd22a9a105e6e8088cfc7826699332ded60c423b14ec613a185f1602206702ff0fe4c438cb15c979081ce4cb02568e364b15174503a63c7a8e2a5f6c" 87 | } 88 | -------------------------------------------------------------------------------- /backend/global-mosaic/README.md: -------------------------------------------------------------------------------- 1 | # OpenAerialMap Global Mosaic 2 | 3 | On a 24hr schedule: 4 | 5 | - Generates global mosaic in PMTiles format, serving via S3. 6 | - Also server TMS via a lightweight Martin server, for clients that 7 | don't support PMTiles. 8 | 9 | ## Getting Started 10 | 11 | This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) 12 | to manage Python dependencies. 13 | 14 | Once `uv` is installed, you can install the dependencies by, 15 | 16 | ```bash 17 | uv sync --all-groups 18 | ``` 19 | 20 | ## Note On Various Scripts 21 | 22 | The following `scripts` share a lot of code, and were developed iteratively: 23 | 24 | - Attempt 1: `gen_mosaic_manual.py` - manually generate mosaics from COGs. 25 | - Attempt 2: `gen_mosaic_hybrid.py` - hybrid coverage for zooms 0-10 + mosaic 26 | for zooms 11-14 (from TiTiler instance). This is similar to the approach from 27 | the originalThis server provides map tiles.
113 |Request tiles using the format: /z/x/y.png
Example: /0/0/0.png
115 | 116 | '; 117 | } 118 | 119 | location /health { 120 | access_log off; 121 | return 200 "healthy\n"; 122 | add_header Content-Type text/plain; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 🤗 Welcome 2 | 3 | :+1::tada: First off, We are really glad you're reading this, because we need 4 | volunteer developers to help improve OpenAerialMap! 5 | :tada::+1: 6 | 7 | We welcome and encourage contributors of all skill levels, and we are committed 8 | to making sure your participation is inclusive, enjoyable, and rewarding. If 9 | you have never contributed to an open source project before, we are a good 10 | place to start, and we will make sure you are supported every step of the way. 11 | If you have **any** questions, please ask! 12 | 13 | There are many ways to contribute to the **OpenAerialMap**, including: 14 | 15 | ## Testing 16 | 17 | - User testing the functionality and reporting any issues. 18 | - Writing automated tests for the existing code. 19 | 20 | ## Code contributions 21 | 22 | Create pull requests (PRs) for changes that you think are needed. We would 23 | really appreciate your help! 24 | 25 | Skills with the following would be beneficial: 26 | 27 | - Python 28 | - React 29 | - TypeScript / JavaScript 30 | - Docker 31 | - CI/CD workflows 32 | 33 | ## Report bugs and suggest improvements 34 | 35 | The [issue queue][3] is the best way to get started. There are issue templates 36 | for BUGs and FEATURES that you can use, you could also create your own. 37 | 38 | Once you have submitted an issue, it will be assigned one label from the 39 | following [label categories][4]. 40 | 41 | If you are wondering where to start, you can filter by the 42 | **good first issue label**. 43 | 44 | ## Report security vulnerabilities 45 | 46 | Please inform a maintainer as soon as possible, including the CVE code. 47 | 48 | Message via the [HOTOSM Slack][9] or [direct email][10] would be preferred, 49 | but via Github issue is also possible. 50 | 51 | ## :handshake: Thank you 52 | 53 | Thank you very much in advance for your contributions!! Please ensure you refer 54 | to our **Code of Conduct**. 55 | If you've read the guidelines, but are still not sure how to contribute on 56 | Github, please reach out to us via our Slack **#geospatial-tech-and-innovation**. 57 | 58 | ## Code Contribution guidelines 59 | 60 | ### Workflow 61 | 62 | We operate the "Fork & Pull" model explained at [About Pull Requests][5] 63 | 64 | Further details of our development workflow can be found [on this page][8] 65 | 66 | ### If you are reporting a problem 67 | 68 | - Describe exactly what you were trying to achieve, what you did, what you 69 | expected to happen and what did happen instead. Include relevant information 70 | about the platform, OS version etc. you are using. Include shell commands you 71 | typed in, log files, errors messages etc. 72 | 73 | - Please open a separate issue for each problem, question, or comment you have. 74 | Do not reuse existing issues for other topics, even if they are similar. This 75 | keeps issues small and manageable and makes it much easier to follow through 76 | and make sure each problem is taken care of. 77 | 78 | ### Documentation 79 | 80 | Project documentation should be in [Markdown format][6], and in a _docs_ 81 | subdirectory. While it is possible to use HTML in Markdown documents 82 | for tables and images, it is preferred to use the Markdown style as 83 | it's much easier to read. 84 | 85 | See a detailed guide on documentation contributions 86 | [on this page](https://docs.hotosm.org/techdoc). 87 | 88 | ### Pre-Commit Hooks 89 | 90 | [Pre-Commit Hooks][7] are used in this repo to enforce coding style: 91 | 92 | - Python adheres mostly to PEP8 convention, amongst others, using the 93 | tool `ruff`. 94 | - TypeScript / JavaScript code is formatted using `prettier`. 95 | - Markdown files are formatted using `markdownlint`. 96 | - Raq SQL is formatted using `sqlfluff`. 97 | 98 | Please install the pre-commit hooks before contributing: 99 | 100 | ```bash 101 | pip install pre-commit 102 | pre-commit install 103 | ``` 104 | 105 | ### Commit Sign-Off Policy 106 | 107 | - In order to commit to this repository, please read and accept our 108 | [commit sign-off policy](https://developercertificate.org) 109 | - This is simply to verify that you are the author of the commits you make. 110 | - If possible, please add to your commit footer the `Signed-off-by` info: 111 | `Signed-off-by: John Doe
3 |
4 |
5 |
6 |
OpenAerialMap is an open service to provide access to a commons of openly licensed imagery and map layer services.
11 | 12 |