Skip to content
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

[pull] master from OSGeo:master #184

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions MIGRATION_GUIDE.TXT
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
MIGRATION GUIDE FROM GDAL 3.10 to GDAL 3.11
-------------------------------------------

- The OGRLayer::GetExtent(OGREnvelope*, int bForce) and
OGRLayer::GetExtent(int iGeomField, OGREnvelope*, int bForce) methods are
no longer virtual methods that are implemented by drivers, and the ``int bForce``
parameter is now a ``bool bForce``.
Drivers may implement the new IGetExtent(int iGeomField, OGREnvelope*,
bool bForce) protected virtual method. The public method checks that the
iGeomField value is in range.
Similarly for OGRLayer::GetExtent3D(int iGeomField, OGREnvelope3D*, int bForce)
which is now a user facing method (with the change that the ``int bForce`` is now a
``bool bForce``). Drivers may implement the new IGetExtent3D(int iGeomField, OGREnvelope3D*,
bool bForce) protected virtual method. The public method checks that the
iGeomField value is in range.

- The OGRLayer::SetSpatialFilter() and SetSpatialFilterRect() methods are
no longer virtual methods that are implemented by drivers. They now return
OGRErr instead of void, `and accept a ``const OGRGeometry*``). Drivers may implement
the new ISetSpatialFilter(int iGeomField, const OGRGeometry*) protected virtual method.
The public methods check that the iGeomField value is in range.

- GDAL drivers may now return raster bands with the new data types
GDT_Float16 or GDT_CFloat16. Code that use the GDAL API must be
ready to react to the new data type, possibly by doing RasterIO()
Expand Down
8 changes: 2 additions & 6 deletions apps/gdalalg_vector_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,8 @@ class GDALVectorSelectAlgorithmLayer final
return OGRLayer::GetFeatureCount(bForce);
}

OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
{
return m_oSrcLayer.GetExtent(psExtent, bForce);
}

OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce) override
OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
bool bForce) override
{
return m_oSrcLayer.GetExtent(iGeomField, psExtent, bForce);
}
Expand Down
22 changes: 3 additions & 19 deletions apps/ogr2ogr_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,26 +795,10 @@ class OGRSplitListFieldLayer : public OGRLayer
return poSrcLayer->GetStyleTable();
}

virtual void SetSpatialFilter(OGRGeometry *poGeom) override
virtual OGRErr ISetSpatialFilter(int iGeom,
const OGRGeometry *poGeom) override
{
poSrcLayer->SetSpatialFilter(poGeom);
}

virtual void SetSpatialFilter(int iGeom, OGRGeometry *poGeom) override
{
poSrcLayer->SetSpatialFilter(iGeom, poGeom);
}

virtual void SetSpatialFilterRect(double dfMinX, double dfMinY,
double dfMaxX, double dfMaxY) override
{
poSrcLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
}

virtual void SetSpatialFilterRect(int iGeom, double dfMinX, double dfMinY,
double dfMaxX, double dfMaxY) override
{
poSrcLayer->SetSpatialFilterRect(iGeom, dfMinX, dfMinY, dfMaxX, dfMaxY);
return poSrcLayer->SetSpatialFilter(iGeom, poGeom);
}

virtual OGRErr SetAttributeFilter(const char *pszFilter) override
Expand Down
3 changes: 2 additions & 1 deletion autotest/ogr/ogr_geojson.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,8 @@ def test_ogr_geojson_23(tmp_vsimem):
lyr.CreateFeature(feat)
assert lyr.GetExtent() == (1.0, 2.0, 10.0, 20.0)
assert lyr.GetExtent(geom_field=0) == (1.0, 2.0, 10.0, 20.0)
assert lyr.GetExtent(geom_field=1, can_return_null=True) is None
with gdaltest.disable_exceptions():
assert lyr.GetExtent(geom_field=1, can_return_null=True) is None
lyr = None
ds = None

Expand Down
121 changes: 74 additions & 47 deletions autotest/ogr/ogr_oapif.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ def NO_LONGER_USED_test_ogr_oapif_fc_links_next_headers():
###############################################################################


def test_ogr_oapif_spatial_filter():
def test_ogr_oapif_spatial_filter_deprecated_api():

# Deprecated API
handler = webserver.SequentialHandler()
Expand All @@ -568,7 +568,31 @@ def test_ogr_oapif_spatial_filter():
ds = ogr.Open("OAPIF:http://localhost:%d/oapif" % gdaltest.webserver_port)
lyr = ds.GetLayer(0)
assert lyr.TestCapability(ogr.OLCFastGetExtent)
assert lyr.GetExtent() == (-10.0, 15.0, 40.0, 50.0)

handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
handler.add(
"GET",
"/oapif/collections/foo/items?limit=20",
200,
{"Content-Type": "application/geo+json"},
"""{ "type": "FeatureCollection", "features": [
{
"type": "Feature",
"properties": {
"foo": "bar"
}
}
] }""",
)
with webserver.install_http_handler(handler):
assert lyr.GetExtent() == (-10.0, 15.0, 40.0, 50.0)


###############################################################################


def test_ogr_oapif_spatial_filter():

# Nominal API
handler = webserver.SequentialHandler()
Expand All @@ -591,7 +615,6 @@ def test_ogr_oapif_spatial_filter():
with webserver.install_http_handler(handler):
ds = ogr.Open("OAPIF:http://localhost:%d/oapif" % gdaltest.webserver_port)
lyr = ds.GetLayer(0)
assert lyr.GetExtent() == (-10.0, 15.0, 40.0, 50.0)

handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
Expand All @@ -610,6 +633,7 @@ def test_ogr_oapif_spatial_filter():
] }""",
)
with webserver.install_http_handler(handler):
assert lyr.GetExtent() == (-10.0, 15.0, 40.0, 50.0)
assert lyr.GetLayerDefn().GetFieldCount() == 1

lyr.SetSpatialFilterRect(2, 49, 3, 50)
Expand Down Expand Up @@ -1365,11 +1389,6 @@ def test_ogr_oapif_storage_crs_easting_northing():
with webserver.install_http_handler(handler):
ds = ogr.Open("OAPIF:http://localhost:%d/oapif" % gdaltest.webserver_port)
lyr = ds.GetLayer(0)
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx(
(-611288.854779237, 4427761.561734099, 1525592.2813932528, 5620112.89047953),
abs=1e-3,
)

handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
Expand All @@ -1389,10 +1408,16 @@ def test_ogr_oapif_storage_crs_easting_northing():
] }""",
)
with webserver.install_http_handler(handler):
srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "32631"
assert lyr.GetLayerDefn().GetFieldCount() == 1
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx(
(-611288.854779237, 4427761.561734099, 1525592.2813932528, 5620112.89047953),
abs=1e-3,
)

srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "32631"
assert lyr.GetLayerDefn().GetFieldCount() == 1

handler = webserver.SequentialHandler()
handler.add(
Expand Down Expand Up @@ -1467,8 +1492,6 @@ def test_ogr_oapif_storage_crs_latitude_longitude():
with webserver.install_http_handler(handler):
ds = ogr.Open("OAPIF:http://localhost:%d/oapif" % gdaltest.webserver_port)
lyr = ds.GetLayer(0)
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx((-10, 40, 15, 50), abs=1e-3)

handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
Expand All @@ -1488,12 +1511,15 @@ def test_ogr_oapif_storage_crs_latitude_longitude():
] }""",
)
with webserver.install_http_handler(handler):
srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "4326"
assert srs.GetDataAxisToSRSAxisMapping() == [2, 1]
assert srs.GetCoordinateEpoch() == 2022.5
assert lyr.GetLayerDefn().GetFieldCount() == 1
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx((-10, 40, 15, 50), abs=1e-3)

srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "4326"
assert srs.GetDataAxisToSRSAxisMapping() == [2, 1]
assert srs.GetCoordinateEpoch() == 2022.5
assert lyr.GetLayerDefn().GetFieldCount() == 1

handler = webserver.SequentialHandler()
# Coordinates must be in lat, lon order in the GeoJSON answer
Expand Down Expand Up @@ -1573,11 +1599,6 @@ def test_ogr_oapif_storage_crs_latitude_longitude_non_compliant_server():
open_options=["SERVER_FEATURE_AXIS_ORDER=GIS_FRIENDLY"],
)
lyr = ds.GetLayer(0)
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx((-10, 40, 15, 50), abs=1e-3)

supported_srs_list = lyr.GetSupportedSRSList()
assert supported_srs_list is None

handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
Expand All @@ -1597,12 +1618,18 @@ def test_ogr_oapif_storage_crs_latitude_longitude_non_compliant_server():
] }""",
)
with webserver.install_http_handler(handler):
srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "4326"
assert srs.GetDataAxisToSRSAxisMapping() == [2, 1]
assert srs.GetCoordinateEpoch() == 2022.5
assert lyr.GetLayerDefn().GetFieldCount() == 1
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx((-10, 40, 15, 50), abs=1e-3)

supported_srs_list = lyr.GetSupportedSRSList()
assert supported_srs_list is None

srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "4326"
assert srs.GetDataAxisToSRSAxisMapping() == [2, 1]
assert srs.GetCoordinateEpoch() == 2022.5
assert lyr.GetLayerDefn().GetFieldCount() == 1

handler = webserver.SequentialHandler()
# Coordinates must be in lat, lon order in the GeoJSON answer
Expand Down Expand Up @@ -1665,19 +1692,6 @@ def get_collections_handler():
assert ds
lyr = ds.GetLayer(0)

minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx(
(-611288.854779237, 4427761.561734099, 1525592.2813932528, 5620112.89047953),
abs=1e-3,
)

supported_srs_list = lyr.GetSupportedSRSList()
assert supported_srs_list
assert len(supported_srs_list) == 2
assert supported_srs_list[0].GetAuthorityCode(None) == "32631"
# Below doesn't work with early PROJ 6 versions
# assert supported_srs_list[1].GetAuthorityCode(None) == "CRS84"

def get_items_handler():
handler = webserver.SequentialHandler()
_add_dummy_root_and_api_pages(handler)
Expand All @@ -1699,9 +1713,22 @@ def get_items_handler():
return handler

with webserver.install_http_handler(get_items_handler()):
srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "32631"
minx, maxx, miny, maxy = lyr.GetExtent()
assert (minx, miny, maxx, maxy) == pytest.approx(
(-611288.854779237, 4427761.561734099, 1525592.2813932528, 5620112.89047953),
abs=1e-3,
)

supported_srs_list = lyr.GetSupportedSRSList()
assert supported_srs_list
assert len(supported_srs_list) == 2
assert supported_srs_list[0].GetAuthorityCode(None) == "32631"
# Below doesn't work with early PROJ 6 versions
# assert supported_srs_list[1].GetAuthorityCode(None) == "CRS84"

srs = lyr.GetSpatialRef()
assert srs
assert srs.GetAuthorityCode(None) == "32631"

json_info = gdal.VectorInfo(ds, format="json", featureCount=False)
assert "supportedSRSList" in json_info["layers"][0]["geometryFields"][0]
Expand Down
4 changes: 2 additions & 2 deletions autotest/ogr/ogr_sql_sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,7 @@ def test_ogr_sql_sqlite_execute_sql_error_on_spatial_filter_mem_layer():
ds.CreateLayer("test")
geom = ogr.CreateGeometryFromWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))")
with pytest.raises(
Exception, match="Cannot set spatial filter: no geometry field selected"
Exception, match="Cannot set spatial filter: no geometry field present in layer"
):
ds.ExecuteSQL("SELECT 1 FROM test", spatialFilter=geom, dialect="SQLITE")

Expand All @@ -2490,6 +2490,6 @@ def test_ogr_sql_sqlite_execute_sql_error_on_spatial_filter_shp_layer(tmp_vsimem
ds.CreateLayer("test")
geom = ogr.CreateGeometryFromWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))")
with pytest.raises(
Exception, match="Cannot set spatial filter: no geometry field selected"
Exception, match="Cannot set spatial filter: no geometry field present in layer"
):
ds.ExecuteSQL("SELECT 1 FROM test", spatialFilter=geom, dialect="SQLITE")
4 changes: 2 additions & 2 deletions autotest/ogr/ogr_vrt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2381,9 +2381,9 @@ def test_ogr_vrt_33b(ogr_vrt_33, tmp_path):
ret = gdaltest.runexternal(
test_cli_utilities.get_test_ogrsf_path() + f" -ro {tmp_path}/ogr_vrt_33.vrt"
)
os.unlink(tmp_path / "ogr_vrt_33.vrt")

assert ret.find("INFO") != -1 and ret.find("ERROR") == -1
assert "INFO" in ret
assert "ERROR" not in ret


@pytest.mark.require_driver("CSV")
Expand Down
27 changes: 10 additions & 17 deletions frmts/eeda/eedadataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,13 @@ class GDALEEDALayer final : public OGRLayer
return -1;
}

virtual void SetSpatialFilter(OGRGeometry *poGeom) CPL_OVERRIDE;

virtual void SetSpatialFilter(int iGeomField,
OGRGeometry *poGeom) CPL_OVERRIDE
{
OGRLayer::SetSpatialFilter(iGeomField, poGeom);
}
virtual OGRErr ISetSpatialFilter(int iGeomField,
const OGRGeometry *poGeom) override;

virtual OGRErr SetAttributeFilter(const char *) CPL_OVERRIDE;

virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) CPL_OVERRIDE;

virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
int bForce) CPL_OVERRIDE
{
return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
}
virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
bool bForce) override;
};

/************************************************************************/
Expand Down Expand Up @@ -943,10 +933,11 @@ OGRErr GDALEEDALayer::SetAttributeFilter(const char *pszQuery)
}

/************************************************************************/
/* SetSpatialFilter() */
/* ISetSpatialFilter() */
/************************************************************************/

void GDALEEDALayer::SetSpatialFilter(OGRGeometry *poGeomIn)
OGRErr GDALEEDALayer::ISetSpatialFilter(int /* iGeomField */,
const OGRGeometry *poGeomIn)
{
if (poGeomIn)
{
Expand All @@ -965,13 +956,15 @@ void GDALEEDALayer::SetSpatialFilter(OGRGeometry *poGeomIn)
InstallFilter(poGeomIn);

ResetReading();
return OGRERR_NONE;
}

/************************************************************************/
/* GetExtent() */
/************************************************************************/

OGRErr GDALEEDALayer::GetExtent(OGREnvelope *psExtent, int /* bForce */)
OGRErr GDALEEDALayer::IGetExtent(int /* iGeomField*/, OGREnvelope *psExtent,
bool /* bForce */)
{
psExtent->MinX = -180;
psExtent->MinY = -90;
Expand Down
Loading