Skip to content

Commit

Permalink
FlatGeobuf writing: in SPATIAL_INDEX=NO mode, accept creating a file …
Browse files Browse the repository at this point in the history
…without features
  • Loading branch information
rouault committed Dec 5, 2024
1 parent 340f72f commit f3e4b05
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
17 changes: 17 additions & 0 deletions autotest/ogr/ogr_flatgeobuf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1585,3 +1585,20 @@ def test_ogr_flatgeobuf_write_empty_geometries_no_spatial_index(tmp_vsimem):
f = lyr.GetNextFeature()
g = f.GetGeometryRef()
assert g is None


def test_ogr_flatgeobuf_write_empty_file_no_spatial_index(tmp_vsimem):
# Verify empty geom handling without spatial index
out_filename = str(tmp_vsimem / "out.fgb")
with ogr.GetDriverByName("FlatGeobuf").CreateDataSource(out_filename) as ds:
srs = osr.SpatialReference()
srs.ImportFromEPSG(32631)
ds.CreateLayer(
"test", geom_type=ogr.wkbPolygon, srs=srs, options=["SPATIAL_INDEX=NO"]
)

with gdal.OpenEx(out_filename) as ds:
lyr = ds.GetLayer(0)
assert lyr.GetFeatureCount() == 0
assert lyr.GetExtent(can_return_null=True) is None
assert lyr.GetSpatialRef().GetAuthorityCode(None) == "32631"
28 changes: 20 additions & 8 deletions ogr/ogrsf_frmts/flatgeobuf/ogrflatgeobuflayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "geometrywriter.h"

#include <algorithm>
#include <cmath>
#include <limits>
#include <new>
#include <stdexcept>
Expand Down Expand Up @@ -70,7 +71,9 @@ OGRFlatGeobufLayer::OGRFlatGeobufLayer(const Header *poHeader, GByte *headerBuf,
m_hasM = m_poHeader->has_m();
m_hasT = m_poHeader->has_t();
const auto envelope = m_poHeader->envelope();
if (envelope && envelope->size() == 4)
if (envelope && envelope->size() == 4 && std::isfinite((*envelope)[0]) &&
std::isfinite((*envelope)[1]) && std::isfinite((*envelope)[2]) &&
std::isfinite((*envelope)[3]))
{
m_sExtent.MinX = (*envelope)[0];
m_sExtent.MinY = (*envelope)[1];
Expand Down Expand Up @@ -535,8 +538,7 @@ bool OGRFlatGeobufLayer::CreateFinalFile()
// no spatial index requested, we are (almost) done
if (!m_bCreateSpatialIndexAtClose)
{
if (m_poFpWrite == nullptr || m_featuresCount == 0 ||
!SupportsSeekWhileWriting(m_osFilename))
if (m_poFpWrite == nullptr || !SupportsSeekWhileWriting(m_osFilename))
{
return true;
}
Expand All @@ -545,14 +547,24 @@ bool OGRFlatGeobufLayer::CreateFinalFile()
VSIFSeekL(m_poFpWrite, 0, SEEK_SET);
m_writeOffset = 0;
std::vector<double> extentVector;
extentVector.push_back(m_sExtent.MinX);
extentVector.push_back(m_sExtent.MinY);
extentVector.push_back(m_sExtent.MaxX);
extentVector.push_back(m_sExtent.MaxY);
if (!m_sExtent.IsInit())
{
extentVector.resize(4, std::numeric_limits<double>::quiet_NaN());
}
else
{
extentVector.push_back(m_sExtent.MinX);
extentVector.push_back(m_sExtent.MinY);
extentVector.push_back(m_sExtent.MaxX);
extentVector.push_back(m_sExtent.MaxY);
}
writeHeader(m_poFpWrite, m_featuresCount, &extentVector);
// Sanity check to verify that the dummy header and the real header
// have the same size.
CPLAssert(m_writeOffset == m_offsetAfterHeader);
if (m_featuresCount)
{
CPLAssert(m_writeOffset == m_offsetAfterHeader);
}
CPL_IGNORE_RET_VAL(m_writeOffset); // otherwise checkers might tell the
// member is not used
return true;
Expand Down

0 comments on commit f3e4b05

Please sign in to comment.