Skip to content

Commit

Permalink
OGR VRT: add support for coordinate precision
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Mar 5, 2024
1 parent 39cb5fb commit f81f116
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
28 changes: 28 additions & 0 deletions autotest/ogr/ogr_vrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3330,3 +3330,31 @@ def test_ogr_vrt_field_names_same_case():
f = lyr.GetNextFeature()
assert f["id"] == "foo"
assert f["id_from_uc"] == "bar"


###############################################################################
# Test geometry coordinate precision support


def test_ogr_vrt_geom_coordinate_preicsion():

ds = ogr.Open(
"""<OGRVRTDataSource>
<OGRVRTLayer name="poly">
<SrcDataSource>data/poly.shp</SrcDataSource>
<GeometryField>
<GeometryType>wkbPolygon</GeometryType>
<XYResolution>1e-5</XYResolution>
<ZResolution>1e-3</ZResolution>
<MResolution>1e-2</MResolution>
</GeometryField>
</OGRVRTLayer>
</OGRVRTDataSource>
"""
)
lyr = ds.GetLayer(0)
geom_fld = lyr.GetLayerDefn().GetGeomFieldDefn(0)
prec = geom_fld.GetCoordinatePrecision()
assert prec.GetXYResolution() == 1e-5
assert prec.GetZResolution() == 1e-3
assert prec.GetMResolution() == 1e-2
8 changes: 8 additions & 0 deletions doc/source/drivers/vector/vrt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ layer name, and may have the following subelements:
**SrcRegion**
* **ExtentXMin**, **ExtentYMin**, **ExtentXMax** and **ExtentXMax**
(optional) : same syntax as OGRVRTLayer-level elements of same name
* **XYResolution** (optional, GDAL >= 3.9):
Resolution for the coordinate precision of the X and Y coordinates.
Expressed in the units of the X and Y axis of the SRS
* **ZResolution** (optional, GDAL >= 3.9):
Resolution for the coordinate precision of the Z coordinates.
Expressed in the units of the Z axis of the SRS
* **MResolution** (optional, GDAL >= 3.9):
Resolution for the coordinate precision of the M coordinates.

If no **GeometryField** element is specified, all the geometry fields of
the source layer will be exposed by the VRT layer. In order not to
Expand Down
3 changes: 3 additions & 0 deletions ogr/ogrsf_frmts/vrt/data/ogrvrt.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@
<xs:element name="SrcRegion" type="SrcRegionType"/>
<xs:element name="SRS" type="nonEmptyStringType"/>
<xs:group ref="ExtentType"/>
<xs:element name="XYResolution" type="xs:double" minOccurs="0" maxOccurs="1"/>
<xs:element name="ZResolution" type="xs:double" minOccurs="0" maxOccurs="1"/>
<xs:element name="MResolution" type="xs:double" minOccurs="0" maxOccurs="1"/>
</xs:choice>
</xs:sequence>
<xs:attributeGroup ref="GeometryFieldTypeAttrGroupWithoutSrc"/>
Expand Down
2 changes: 2 additions & 0 deletions ogr/ogrsf_frmts/vrt/ogr_vrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class OGRVRTGeomFieldProps

OGREnvelope sStaticEnvelope;

OGRGeomCoordinatePrecision sCoordinatePrecision{};

OGRVRTGeomFieldProps();
~OGRVRTGeomFieldProps();
};
Expand Down
30 changes: 30 additions & 0 deletions ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,34 @@ bool OGRVRTLayer::ParseGeometryField(CPLXMLNode *psNode,
poProps->bNullable =
CPLTestBool(CPLGetXMLValue(psNode, "nullable", "TRUE"));

if (GetSrcLayerDefn()->GetGeomFieldCount() == 1)
{
poProps->sCoordinatePrecision =
GetSrcLayerDefn()->GetGeomFieldDefn(0)->GetCoordinatePrecision();
}
else if (poProps->eGeometryStyle == VGS_Direct && poProps->iGeomField >= 0)
{
poProps->sCoordinatePrecision =
GetSrcLayerDefn()
->GetGeomFieldDefn(poProps->iGeomField)
->GetCoordinatePrecision();
}
if (const char *pszXYResolution =
CPLGetXMLValue(psNode, "XYResolution", nullptr))
{
poProps->sCoordinatePrecision.dfXYResolution = CPLAtof(pszXYResolution);
}
if (const char *pszZResolution =
CPLGetXMLValue(psNode, "ZResolution", nullptr))
{
poProps->sCoordinatePrecision.dfZResolution = CPLAtof(pszZResolution);
}
if (const char *pszMResolution =
CPLGetXMLValue(psNode, "MResolution", nullptr))
{
poProps->sCoordinatePrecision.dfMResolution = CPLAtof(pszMResolution);
}

return true;
}

Expand Down Expand Up @@ -811,6 +839,8 @@ bool OGRVRTLayer::FullInitialize()
apoGeomFieldProps[i]->eGeomType);
oFieldDefn.SetSpatialRef(apoGeomFieldProps[i]->poSRS);
oFieldDefn.SetNullable(apoGeomFieldProps[i]->bNullable);
oFieldDefn.SetCoordinatePrecision(
apoGeomFieldProps[i]->sCoordinatePrecision);
poFeatureDefn->AddGeomFieldDefn(&oFieldDefn);
}

Expand Down

0 comments on commit f81f116

Please sign in to comment.