Skip to content

Commit b7ee802

Browse files
committed
GDALDataset::GetExtent: Return extent for undefined CRS
1 parent 926d626 commit b7ee802

File tree

2 files changed

+90
-25
lines changed

2 files changed

+90
-25
lines changed

autotest/gcore/basic_test.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import gdaltest
2020
import pytest
2121

22-
from osgeo import gdal
22+
from osgeo import gdal, osr
2323

2424

2525
###############################################################################
@@ -1108,3 +1108,56 @@ def test_basic_block_windows(tmp_vsimem):
11081108
assert windows[8].yoff == 512
11091109
assert windows[8].xsize == 1050 - 1024
11101110
assert windows[8].ysize == 600 - 512
1111+
1112+
1113+
###############################################################################
1114+
# Test GetExtent()
1115+
1116+
1117+
def test_basic_get_extent():
1118+
1119+
with gdal.Open("data/byte.tif") as ds:
1120+
assert ds.GetExtent() == (440720.0, 441920.0, 3750120.0, 3751320.0)
1121+
1122+
1123+
def test_basic_get_extent_reprojected():
1124+
1125+
wgs84 = osr.SpatialReference(epsg=4326)
1126+
wgs84.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
1127+
1128+
with gdal.Open("data/byte.tif") as ds:
1129+
assert ds.GetExtent(wgs84) == pytest.approx(
1130+
(-117.642, -117.629, 33.892, 33.902), abs=1e-3
1131+
)
1132+
1133+
1134+
def test_basic_get_extent_no_crs():
1135+
1136+
with gdal.GetDriverByName("MEM").Create("", 5, 5) as ds:
1137+
ds.SetGeoTransform((3, 0.5, 0, 7, 0, -1))
1138+
assert ds.GetExtent() == (3, 5.5, 2, 7)
1139+
1140+
1141+
def test_basic_get_extent_no_crs_reprojected():
1142+
1143+
wgs84 = osr.SpatialReference(epsg=4326)
1144+
wgs84.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
1145+
1146+
with gdal.GetDriverByName("MEM").Create("", 5, 5) as ds:
1147+
ds.SetGeoTransform((3, 0.5, 0, 7, 0, -1))
1148+
assert ds.GetExtent(wgs84) is None
1149+
1150+
1151+
def test_basic_get_extent_bottom_up():
1152+
1153+
with gdal.GetDriverByName("MEM").Create("", 5, 5) as ds:
1154+
ds.SetGeoTransform((3, 0.5, 0, 7, 0, 1))
1155+
assert ds.GetExtent() == (3, 5.5, 7, 12)
1156+
1157+
1158+
def test_basic_get_extent_rotated():
1159+
1160+
with gdal.Open("data/geomatrix.tif") as ds:
1161+
assert ds.GetExtent() == pytest.approx(
1162+
(1840900, 1841030, 1143870, 1144000), abs=4
1163+
)

gcore/gdaldataset.cpp

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10621,7 +10621,7 @@ CPLErr GDALDataset::GetExtent(OGREnvelope *psExtent,
1062110621
if (auto poLayer = poThisDS->GetLayer(0))
1062210622
poThisCRS = poLayer->GetSpatialRef();
1062310623
}
10624-
if (!poThisCRS)
10624+
if (poCRS && !poThisCRS)
1062510625
return CE_Failure;
1062610626
}
1062710627
if (!poCRS)
@@ -10633,34 +10633,46 @@ CPLErr GDALDataset::GetExtent(OGREnvelope *psExtent,
1063310633
const bool bHasGT = poThisDS->GetGeoTransform(gt) == CE_None;
1063410634
if (bHasGT)
1063510635
{
10636-
auto poCT = std::unique_ptr<OGRCoordinateTransformation>(
10637-
OGRCreateCoordinateTransformation(poThisCRS, poCRS));
10636+
std::unique_ptr<OGRCoordinateTransformation> poCT;
10637+
if (poCRS)
10638+
{
10639+
poCT.reset(OGRCreateCoordinateTransformation(poThisCRS, poCRS));
10640+
}
10641+
10642+
constexpr int DENSIFY_POINT_COUNT = 21;
10643+
double dfULX = gt[0];
10644+
double dfULY = gt[3];
10645+
double dfURX = 0, dfURY = 0;
10646+
gt.Apply(nRasterXSize, 0, &dfURX, &dfURY);
10647+
double dfLLX = 0, dfLLY = 0;
10648+
gt.Apply(0, nRasterYSize, &dfLLX, &dfLLY);
10649+
double dfLRX = 0, dfLRY = 0;
10650+
gt.Apply(nRasterXSize, nRasterYSize, &dfLRX, &dfLRY);
10651+
const double xmin =
10652+
std::min(std::min(dfULX, dfURX), std::min(dfLLX, dfLRX));
10653+
const double ymin =
10654+
std::min(std::min(dfULY, dfURY), std::min(dfLLY, dfLRY));
10655+
const double xmax =
10656+
std::max(std::max(dfULX, dfURX), std::max(dfLLX, dfLRX));
10657+
const double ymax =
10658+
std::max(std::max(dfULY, dfURY), std::max(dfLLY, dfLRY));
1063810659
if (poCT)
1063910660
{
10640-
constexpr int DENSIFY_POINT_COUNT = 21;
1064110661
OGREnvelope sEnvTmp;
10642-
double dfULX = gt[0];
10643-
double dfULY = gt[3];
10644-
double dfURX = 0, dfURY = 0;
10645-
gt.Apply(nRasterXSize, 0, &dfURX, &dfURY);
10646-
double dfLLX = 0, dfLLY = 0;
10647-
gt.Apply(0, nRasterYSize, &dfLLX, &dfLLY);
10648-
double dfLRX = 0, dfLRY = 0;
10649-
gt.Apply(nRasterXSize, nRasterYSize, &dfLRX, &dfLRY);
10650-
const double xmin =
10651-
std::min(std::min(dfULX, dfURX), std::min(dfLLX, dfLRX));
10652-
const double ymin =
10653-
std::min(std::min(dfULY, dfURY), std::min(dfLLY, dfLRY));
10654-
const double xmax =
10655-
std::max(std::max(dfULX, dfURX), std::max(dfLLX, dfLRX));
10656-
const double ymax =
10657-
std::max(std::max(dfULY, dfURY), std::max(dfLLY, dfLRY));
10658-
if (poCT->TransformBounds(xmin, ymin, xmax, ymax, &(sEnvTmp.MinX),
10659-
&(sEnvTmp.MinY), &(sEnvTmp.MaxX),
10660-
&(sEnvTmp.MaxY), DENSIFY_POINT_COUNT))
10662+
if (!poCT->TransformBounds(xmin, ymin, xmax, ymax, &(sEnvTmp.MinX),
10663+
&(sEnvTmp.MinY), &(sEnvTmp.MaxX),
10664+
&(sEnvTmp.MaxY), DENSIFY_POINT_COUNT))
1066110665
{
10662-
*psExtent = std::move(sEnvTmp);
10666+
return CE_Failure;
1066310667
}
10668+
*psExtent = sEnvTmp;
10669+
}
10670+
else
10671+
{
10672+
psExtent->MinX = xmin;
10673+
psExtent->MinY = ymin;
10674+
psExtent->MaxX = xmax;
10675+
psExtent->MaxY = ymax;
1066410676
}
1066510677
}
1066610678

0 commit comments

Comments
 (0)