Skip to content

Conversation

@pierotofy
Copy link
Member

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.

@pierotofy
Copy link
Member Author

Also adds CRS information in the task details from the project list, one-click copy to clipboard for task IDs.

image

@pierotofy pierotofy requested a review from Copilot December 24, 2025 20:10
Copy link

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 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 wkt field 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.

Comment on lines 279 to 284
if (!this._clipboardTimeout){
clearTimeout(this._clipboardTimeout);
this._clipboardTimeout = null;
}
setTimeout(() => {
this.setState({copiedToClipboard: false});
Copy link

Copilot AI Dec 24, 2025

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.

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

Copilot uses AI. Check for mistakes.
Comment on lines +142 to +148
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'}
Copy link

Copilot AI Dec 24, 2025

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.

Copilot uses AI. Check for mistakes.
}

if (epsg == projEPSG) title = projSrsName;
else if (epsg == "" && projWKT) title = projWKT;
Copy link

Copilot AI Dec 24, 2025

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.

Suggested change
else if (epsg == "" && projWKT) title = projWKT;
else if (epsg === "" && projWKT) title = projWKT;

Copilot uses AI. Check for mistakes.
proj = srs.ExportToProj4()
if proj is not None and proj != "":
name = proj
except:
Copy link

Copilot AI Dec 24, 2025

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.

Suggested change
except:
except Exception:

Copilot uses AI. Check for mistakes.
@pierotofy pierotofy merged commit 35bf93f into OpenDroneMap:master Dec 24, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant