-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add support for CRSes not in the EPSG database #1816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this 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 support for handling Coordinate Reference Systems (CRSes) that lack EPSG codes by storing georeferencing information as Well-Known Text (WKT) when an EPSG code is unavailable.
Key Changes:
- Added a new
wktfield to the Task model to store WKT definitions for non-EPSG CRSes - Updated georeferencing logic to prefer EPSG codes but fall back to WKT when necessary
- Modified UI components to display CRS information from either EPSG or WKT sources
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Version bumped to 3.1.0 |
| locale | Updated subproject commit reference |
| app/tests/test_task_wkt.py | New test case validating WKT-based georeferencing |
| app/tests/test_api_task.py | Added assertion to verify WKT is null when EPSG exists |
| app/static/app/js/translations/odm_autogenerated.js | Reordered translation strings (auto-generated) |
| app/static/app/js/css/TaskListItem.scss | Added styles for task ID copy-to-clipboard feature |
| app/static/app/js/components/TaskListItem.jsx | Enhanced UI to show task ID with copy functionality and display CRS information |
| app/static/app/js/components/ExportAssetPanel.jsx | Updated export panel to handle both EPSG and WKT for CRS selection |
| app/models/task.py | Added wkt field and updated georeferencing methods to support WKT |
| app/migrations/0047_task_wkt.py | Database migration adding the wkt field |
| app/geoutils.py | Enhanced utility functions to work with both EPSG codes and WKT |
| app/api/tiler.py | Updated tiler API to include WKT in bounds information |
| app/api/tasks.py | Modified task serializer to use WKT-aware helper functions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!this._clipboardTimeout){ | ||
| clearTimeout(this._clipboardTimeout); | ||
| this._clipboardTimeout = null; | ||
| } | ||
| setTimeout(() => { | ||
| this.setState({copiedToClipboard: false}); |
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition is inverted - it should be if (this._clipboardTimeout) instead of if (!this._clipboardTimeout). Currently, the code only clears the timeout when it doesn't exist, which is the opposite of the intended behavior.
| if (!this._clipboardTimeout){ | |
| clearTimeout(this._clipboardTimeout); | |
| this._clipboardTimeout = null; | |
| } | |
| setTimeout(() => { | |
| this.setState({copiedToClipboard: false}); | |
| if (this._clipboardTimeout){ | |
| clearTimeout(this._clipboardTimeout); | |
| this._clipboardTimeout = null; | |
| } | |
| this._clipboardTimeout = setTimeout(() => { | |
| this.setState({copiedToClipboard: false}); | |
| this._clipboardTimeout = null; |
| if epsg is not None: | ||
| if srs.ImportFromEPSG(epsg) != 0: | ||
| return {'name': '', 'units': 'm'} | ||
|
|
||
| if wkt is not None: | ||
| if srs.ImportFromWkt(wkt) != 0: | ||
| return {'name': '', 'units': 'm'} |
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When both epsg and wkt are provided, the function imports epsg first but then overwrites the srs object with wkt. This can lead to incorrect results if epsg import succeeds but wkt import fails or vice versa. The logic should use elif for the wkt check, or handle the case where both are provided differently.
| } | ||
|
|
||
| if (epsg == projEPSG) title = projSrsName; | ||
| else if (epsg == "" && projWKT) title = projWKT; |
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use strict equality operators (===) instead of loose equality (==) for comparisons. This is especially important when comparing with empty strings.
| else if (epsg == "" && projWKT) title = projWKT; | |
| else if (epsg === "" && projWKT) title = projWKT; |
| proj = srs.ExportToProj4() | ||
| if proj is not None and proj != "": | ||
| name = proj | ||
| except: |
Copilot
AI
Dec 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bare except clause catches all exceptions including system exits and keyboard interrupts. Specify the exception type(s) to catch, such as except Exception: or more specific exception types.
| except: | |
| except Exception: |

Some CRSes do not have EPSG codes, which WebODM does not handle correctly.
This PR adds support for handling CRSes that don't have an explicit EPSG code by storing the georef information as WKT when an EPSG code is not available.