-
-
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
Changes from all commits
e57719f
c95ff39
5296a12
326a9f8
870a065
d07a2ce
3deaa60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -79,14 +79,20 @@ def geom_transform_wkt_bbox(geom, dataset, bbox_crs="geographic", wkt_crs="raste | |||||
| if close_ds: | ||||||
| dataset.close() | ||||||
|
|
||||||
| def geom_transform(geom, epsg): | ||||||
| def geom_transform(geom, target_srs): | ||||||
| if not geom.srid: | ||||||
| raise ValueError("Geometry must have an SRID") | ||||||
|
|
||||||
| coords = geom.tuple | ||||||
| if len(coords) == 1: | ||||||
| xs, ys = zip(*coords[0]) | ||||||
| tx, ty = rasterio.warp.transform(CRS.from_epsg(geom.srid), CRS.from_epsg(epsg), xs, ys) | ||||||
|
|
||||||
| if isinstance(target_srs, int): | ||||||
| srs = CRS.from_epsg(target_srs) | ||||||
| elif isinstance(target_srs, str): | ||||||
| srs = CRS.from_wkt(target_srs) | ||||||
|
|
||||||
| tx, ty = rasterio.warp.transform(CRS.from_epsg(geom.srid), srs, xs, ys) | ||||||
| return list(zip(tx, ty)) | ||||||
| else: | ||||||
| raise ValueError("Cannot transform complex geometries to WKT") | ||||||
|
|
@@ -127,13 +133,19 @@ def get_raster_bounds_wkt(raster_path, target_srs="EPSG:4326"): | |||||
| return wkt | ||||||
|
|
||||||
| @lru_cache(maxsize=1000) | ||||||
| def get_srs_name_units_from_epsg(epsg): | ||||||
| if epsg is None: | ||||||
| def get_srs_name_units_from_epsg_or_wkt(epsg, wkt): | ||||||
| if epsg is None and wkt is None: | ||||||
| return {'name': '', 'units': 'm'} | ||||||
|
|
||||||
| srs = osr.SpatialReference() | ||||||
| if srs.ImportFromEPSG(epsg) != 0: | ||||||
| return {'name': '', 'units': 'm'} | ||||||
|
|
||||||
| 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'} | ||||||
|
|
||||||
| name = srs.GetAttrValue("PROJCS") | ||||||
| if name is None: | ||||||
|
|
@@ -142,6 +154,14 @@ def get_srs_name_units_from_epsg(epsg): | |||||
| if name is None: | ||||||
| return {'name': '', 'units': 'm'} | ||||||
|
|
||||||
| if name == "unknown" and wkt is not None: | ||||||
| try: | ||||||
| proj = srs.ExportToProj4() | ||||||
| if proj is not None and proj != "": | ||||||
| name = proj | ||||||
| except: | ||||||
|
||||||
| except: | |
| except Exception: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Generated by Django 2.2.27 on 2025-12-23 22:28 | ||
|
|
||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('app', '0046_redirect'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AddField( | ||
| model_name='task', | ||
| name='wkt', | ||
| field=models.TextField(blank=True, default=None, help_text='WKT definition of the dataset (if georeferenced and EPSG code is not available)', null=True, verbose_name='WKT'), | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -73,7 +73,7 @@ export default class ExportAssetPanel extends React.Component { | |||||
| this.state = { | ||||||
| error: "", | ||||||
| format: props.exportFormats[0], | ||||||
| epsg: this.props.task.epsg || null, | ||||||
| epsg: this.props.task.epsg || "", | ||||||
| customEpsg: Storage.getItem("last_export_custom_epsg") || "3857", | ||||||
| customProj: Storage.getItem("last_export_custom_proj") || "", | ||||||
| resample: 0, | ||||||
|
|
@@ -205,6 +205,8 @@ export default class ExportAssetPanel extends React.Component { | |||||
| const {epsg, customEpsg, customProj, exporting, format, resample, progress } = this.state; | ||||||
| const { exportFormats } = this.props; | ||||||
| const projEPSG = this.props.task.epsg; | ||||||
| const projWKT = this.props.task.wkt; | ||||||
| const georeferenced = this.props.task.epsg || this.props.task.wkt; | ||||||
| let projSrsName = this.props.task.srs?.name; | ||||||
| if (!projSrsName && projEPSG) projSrsName = `EPSG:${projEPSG}`; | ||||||
| else if (projSrsName && projEPSG) projSrsName = `${projSrsName} (EPSG:${projEPSG})`; | ||||||
|
|
@@ -216,11 +218,23 @@ export default class ExportAssetPanel extends React.Component { | |||||
| (epsg === "proj" && (!customProj || (typeof customProj === "string" && !customProj.toLowerCase().startsWith("+proj")))) || | ||||||
| exporting; | ||||||
|
|
||||||
| let projection = projEPSG ? (<div><div className="row form-group form-inline"> | ||||||
| let firstOpt = ""; | ||||||
| let title = ""; | ||||||
|
|
||||||
| if (projEPSG){ | ||||||
| firstOpt = (<option value={projEPSG}>{projSrsName}</option>); | ||||||
| }else if (projWKT){ | ||||||
| firstOpt = (<option value={""}>{projSrsName}</option>); | ||||||
| } | ||||||
|
|
||||||
| if (epsg == projEPSG) title = projSrsName; | ||||||
| else if (epsg == "" && projWKT) title = projWKT; | ||||||
|
||||||
| else if (epsg == "" && projWKT) title = projWKT; | |
| else if (epsg === "" && projWKT) title = projWKT; |
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
eliffor the wkt check, or handle the case where both are provided differently.