Skip to content

Commit 1fd36d7

Browse files
authored
Merge pull request #11153 from dbaston/ogrfeature-set-unique-ptr
OGRFeature: Add SetGeometry overloads taking unique_ptr<OGRGeometry>
2 parents 1c4caf3 + 1c459f5 commit 1fd36d7

File tree

3 files changed

+155
-27
lines changed

3 files changed

+155
-27
lines changed

autotest/cpp/test_ogr.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4394,4 +4394,67 @@ TEST_F(test_ogr, OGRPolygon_addRingDirectly)
43944394
ASSERT_EQ(p.addRingDirectly(lr.release()), OGRERR_NONE);
43954395
}
43964396

4397+
TEST_F(test_ogr, OGRFeature_SetGeometry)
4398+
{
4399+
OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn();
4400+
poFeatureDefn->Reference();
4401+
4402+
OGRFeature oFeat(poFeatureDefn);
4403+
std::unique_ptr<OGRGeometry> poGeom;
4404+
OGRGeometry *poTmpGeom;
4405+
ASSERT_EQ(
4406+
OGRGeometryFactory::createFromWkt("POINT (3 7)", nullptr, &poTmpGeom),
4407+
OGRERR_NONE);
4408+
poGeom.reset(poTmpGeom);
4409+
ASSERT_EQ(oFeat.SetGeometry(std::move(poGeom)), OGRERR_NONE);
4410+
EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getX(), 3);
4411+
EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getY(), 7);
4412+
4413+
// set it again to make sure previous feature geometry is freed
4414+
ASSERT_EQ(
4415+
OGRGeometryFactory::createFromWkt("POINT (2 8)", nullptr, &poTmpGeom),
4416+
OGRERR_NONE);
4417+
poGeom.reset(poTmpGeom);
4418+
ASSERT_EQ(oFeat.SetGeometry(std::move(poGeom)), OGRERR_NONE);
4419+
EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getX(), 2);
4420+
EXPECT_EQ(oFeat.GetGeometryRef()->toPoint()->getY(), 8);
4421+
4422+
poFeatureDefn->Release();
4423+
}
4424+
4425+
TEST_F(test_ogr, OGRFeature_SetGeomField)
4426+
{
4427+
OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn();
4428+
poFeatureDefn->Reference();
4429+
4430+
OGRGeomFieldDefn oGeomField("second", wkbPoint);
4431+
poFeatureDefn->AddGeomFieldDefn(&oGeomField);
4432+
4433+
OGRFeature oFeat(poFeatureDefn);
4434+
4435+
// failure
4436+
{
4437+
std::unique_ptr<OGRGeometry> poGeom;
4438+
OGRGeometry *poTmpGeom;
4439+
ASSERT_EQ(OGRGeometryFactory::createFromWkt("POINT (3 7)", nullptr,
4440+
&poTmpGeom),
4441+
OGRERR_NONE);
4442+
poGeom.reset(poTmpGeom);
4443+
EXPECT_EQ(oFeat.SetGeomField(13, std::move(poGeom)), OGRERR_FAILURE);
4444+
}
4445+
4446+
// success
4447+
{
4448+
std::unique_ptr<OGRGeometry> poGeom;
4449+
OGRGeometry *poTmpGeom;
4450+
ASSERT_EQ(OGRGeometryFactory::createFromWkt("POINT (3 7)", nullptr,
4451+
&poTmpGeom),
4452+
OGRERR_NONE);
4453+
poGeom.reset(poTmpGeom);
4454+
EXPECT_EQ(oFeat.SetGeomField(1, std::move(poGeom)), OGRERR_NONE);
4455+
}
4456+
4457+
poFeatureDefn->Release();
4458+
}
4459+
43974460
} // namespace

ogr/ogr_feature.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,7 @@ class CPL_DLL OGRFeature
11781178

11791179
OGRErr SetGeometryDirectly(OGRGeometry *);
11801180
OGRErr SetGeometry(const OGRGeometry *);
1181+
OGRErr SetGeometry(std::unique_ptr<OGRGeometry>);
11811182
OGRGeometry *GetGeometryRef();
11821183
const OGRGeometry *GetGeometryRef() const;
11831184
OGRGeometry *StealGeometry() CPL_WARN_UNUSED_RESULT;
@@ -1209,6 +1210,7 @@ class CPL_DLL OGRFeature
12091210
const OGRGeometry *GetGeomFieldRef(const char *pszFName) const;
12101211
OGRErr SetGeomFieldDirectly(int iField, OGRGeometry *);
12111212
OGRErr SetGeomField(int iField, const OGRGeometry *);
1213+
OGRErr SetGeomField(int iField, std::unique_ptr<OGRGeometry>);
12121214

12131215
void Reset();
12141216

ogr/ogrfeature.cpp

Lines changed: 90 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ OGRFeatureDefnH OGR_F_GetDefnRef(OGRFeatureH hFeat)
433433
/**
434434
* \brief Set feature geometry.
435435
*
436-
* This method updates the features geometry, and operate exactly as
436+
* This method updates the features geometry, and operates the same as
437437
* SetGeometry(), except that this method assumes ownership of the
438438
* passed geometry (even in case of failure of that function).
439439
*
@@ -456,11 +456,12 @@ OGRFeatureDefnH OGR_F_GetDefnRef(OGRFeatureH hFeat)
456456
OGRErr OGRFeature::SetGeometryDirectly(OGRGeometry *poGeomIn)
457457

458458
{
459-
if (GetGeomFieldCount() > 0)
460-
return SetGeomFieldDirectly(0, poGeomIn);
459+
if (poGeomIn == GetGeometryRef())
460+
{
461+
return OGRERR_NONE;
462+
}
461463

462-
delete poGeomIn;
463-
return OGRERR_FAILURE;
464+
return SetGeomField(0, std::unique_ptr<OGRGeometry>(poGeomIn));
464465
}
465466

466467
/************************************************************************/
@@ -470,7 +471,7 @@ OGRErr OGRFeature::SetGeometryDirectly(OGRGeometry *poGeomIn)
470471
/**
471472
* \brief Set feature geometry.
472473
*
473-
* This function updates the features geometry, and operate exactly as
474+
* This function updates the features geometry, and operates the same as
474475
* SetGeometry(), except that this function assumes ownership of the
475476
* passed geometry (even in case of failure of that function).
476477
*
@@ -506,7 +507,7 @@ OGRErr OGR_F_SetGeometryDirectly(OGRFeatureH hFeat, OGRGeometryH hGeom)
506507
/**
507508
* \brief Set feature geometry.
508509
*
509-
* This method updates the features geometry, and operate exactly as
510+
* This method updates the features geometry, and operates the same as
510511
* SetGeometryDirectly(), except that this method does not assume ownership
511512
* of the passed geometry, but instead makes a copy of it.
512513
*
@@ -542,7 +543,7 @@ OGRErr OGRFeature::SetGeometry(const OGRGeometry *poGeomIn)
542543
/**
543544
* \brief Set feature geometry.
544545
*
545-
* This function updates the features geometry, and operate exactly as
546+
* This function updates the features geometry, and operates the same as
546547
* SetGeometryDirectly(), except that this function does not assume ownership
547548
* of the passed geometry, but instead makes a copy of it.
548549
*
@@ -570,6 +571,37 @@ OGRErr OGR_F_SetGeometry(OGRFeatureH hFeat, OGRGeometryH hGeom)
570571
OGRGeometry::FromHandle(hGeom));
571572
}
572573

574+
/************************************************************************/
575+
/* SetGeometry() */
576+
/************************************************************************/
577+
578+
/**
579+
* \brief Set feature geometry.
580+
*
581+
* This method is the same as the C function OGR_F_SetGeometryDirectly().
582+
*
583+
* @note This method has only an effect on the in-memory feature object. If
584+
* this object comes from a layer and the modifications must be serialized back
585+
* to the datasource, OGR_L_SetFeature() must be used afterwards. Or if this is
586+
* a new feature, OGR_L_CreateFeature() must be used afterwards.
587+
*
588+
* @param poGeomIn new geometry to apply to feature. Passing NULL value here
589+
* is correct and it will result in deallocation of currently assigned geometry
590+
* without assigning new one.
591+
*
592+
* @return OGRERR_NONE if successful, or OGR_UNSUPPORTED_GEOMETRY_TYPE if
593+
* the geometry type is illegal for the OGRFeatureDefn (checking not yet
594+
* implemented).
595+
*
596+
* @since GDAL 3.11
597+
*/
598+
599+
OGRErr OGRFeature::SetGeometry(std::unique_ptr<OGRGeometry> poGeomIn)
600+
601+
{
602+
return SetGeomField(0, std::move(poGeomIn));
603+
}
604+
573605
/************************************************************************/
574606
/* StealGeometry() */
575607
/************************************************************************/
@@ -907,7 +939,7 @@ OGRGeometryH OGR_F_GetGeomFieldRef(OGRFeatureH hFeat, int iField)
907939
/**
908940
* \brief Set feature geometry of a specified geometry field.
909941
*
910-
* This method updates the features geometry, and operate exactly as
942+
* This method updates the features geometry, and operates the same as
911943
* SetGeomField(), except that this method assumes ownership of the
912944
* passed geometry (even in case of failure of that function).
913945
*
@@ -926,21 +958,13 @@ OGRGeometryH OGR_F_GetGeomFieldRef(OGRFeatureH hFeat, int iField)
926958
*/
927959

928960
OGRErr OGRFeature::SetGeomFieldDirectly(int iField, OGRGeometry *poGeomIn)
929-
930961
{
931-
if (iField < 0 || iField >= GetGeomFieldCount())
932-
{
933-
delete poGeomIn;
934-
return OGRERR_FAILURE;
935-
}
936-
937-
if (papoGeometries[iField] != poGeomIn)
962+
if (poGeomIn && poGeomIn == GetGeomFieldRef(iField))
938963
{
939-
delete papoGeometries[iField];
940-
papoGeometries[iField] = poGeomIn;
964+
return OGRERR_NONE;
941965
}
942966

943-
return OGRERR_NONE;
967+
return SetGeomField(iField, std::unique_ptr<OGRGeometry>(poGeomIn));
944968
}
945969

946970
/************************************************************************/
@@ -950,7 +974,7 @@ OGRErr OGRFeature::SetGeomFieldDirectly(int iField, OGRGeometry *poGeomIn)
950974
/**
951975
* \brief Set feature geometry of a specified geometry field.
952976
*
953-
* This function updates the features geometry, and operate exactly as
977+
* This function updates the features geometry, and operates the same as
954978
* SetGeomField(), except that this function assumes ownership of the
955979
* passed geometry (even in case of failure of that function).
956980
*
@@ -985,7 +1009,7 @@ OGRErr OGR_F_SetGeomFieldDirectly(OGRFeatureH hFeat, int iField,
9851009
/**
9861010
* \brief Set feature geometry of a specified geometry field.
9871011
*
988-
* This method updates the features geometry, and operate exactly as
1012+
* This method updates the features geometry, and operates the same as
9891013
* SetGeomFieldDirectly(), except that this method does not assume ownership
9901014
* of the passed geometry, but instead makes a copy of it.
9911015
*
@@ -1031,7 +1055,7 @@ OGRErr OGRFeature::SetGeomField(int iField, const OGRGeometry *poGeomIn)
10311055
/**
10321056
* \brief Set feature geometry of a specified geometry field.
10331057
*
1034-
* This function updates the features geometry, and operate exactly as
1058+
* This function updates the features geometry, and operates the same as
10351059
* SetGeometryDirectly(), except that this function does not assume ownership
10361060
* of the passed geometry, but instead makes a copy of it.
10371061
*
@@ -1055,6 +1079,45 @@ OGRErr OGR_F_SetGeomField(OGRFeatureH hFeat, int iField, OGRGeometryH hGeom)
10551079
iField, OGRGeometry::FromHandle(hGeom));
10561080
}
10571081

1082+
/************************************************************************/
1083+
/* SetGeomField() */
1084+
/************************************************************************/
1085+
1086+
/**
1087+
* \brief Set feature geometry of a specified geometry field.
1088+
*
1089+
* This method is the same as the C function OGR_F_SetGeomFieldDirectly().
1090+
*
1091+
* @param iField geometry field to set.
1092+
* @param poGeomIn new geometry to apply to feature. Passing NULL value here
1093+
* is correct and it will result in deallocation of currently assigned geometry
1094+
* without assigning new one.
1095+
*
1096+
* @return OGRERR_NONE if successful, or OGRERR_FAILURE if the index is invalid,
1097+
* or OGRERR_UNSUPPORTED_GEOMETRY_TYPE if the geometry type is illegal for the
1098+
* OGRFeatureDefn (checking not yet implemented).
1099+
*
1100+
* @since GDAL 3.11
1101+
*/
1102+
1103+
OGRErr OGRFeature::SetGeomField(int iField,
1104+
std::unique_ptr<OGRGeometry> poGeomIn)
1105+
1106+
{
1107+
if (iField < 0 || iField >= GetGeomFieldCount())
1108+
{
1109+
return OGRERR_FAILURE;
1110+
}
1111+
1112+
if (papoGeometries[iField] != poGeomIn.get())
1113+
{
1114+
delete papoGeometries[iField];
1115+
papoGeometries[iField] = poGeomIn.release();
1116+
}
1117+
1118+
return OGRERR_NONE;
1119+
}
1120+
10581121
/************************************************************************/
10591122
/* Clone() */
10601123
/************************************************************************/
@@ -6688,7 +6751,7 @@ const char *OGR_F_GetStyleString(OGRFeatureH hFeat)
66886751
/**
66896752
* \brief Set feature style string.
66906753
*
6691-
* This method operate exactly as OGRFeature::SetStyleStringDirectly() except
6754+
* This method operates the same as OGRFeature::SetStyleStringDirectly() except
66926755
* that it does not assume ownership of the passed string, but instead makes a
66936756
* copy of it.
66946757
*
@@ -6716,7 +6779,7 @@ void OGRFeature::SetStyleString(const char *pszString)
67166779
/**
67176780
* \brief Set feature style string.
67186781
*
6719-
* This method operate exactly as OGR_F_SetStyleStringDirectly() except that it
6782+
* This method operates the same as OGR_F_SetStyleStringDirectly() except that it
67206783
* does not assume ownership of the passed string, but instead makes a copy of
67216784
* it.
67226785
*
@@ -6741,7 +6804,7 @@ void OGR_F_SetStyleString(OGRFeatureH hFeat, const char *pszStyle)
67416804
/**
67426805
* \brief Set feature style string.
67436806
*
6744-
* This method operate exactly as OGRFeature::SetStyleString() except that it
6807+
* This method operates the same as OGRFeature::SetStyleString() except that it
67456808
* assumes ownership of the passed string.
67466809
*
67476810
* This method is the same as the C function OGR_F_SetStyleStringDirectly().
@@ -6762,7 +6825,7 @@ void OGRFeature::SetStyleStringDirectly(char *pszString)
67626825
/**
67636826
* \brief Set feature style string.
67646827
*
6765-
* This method operate exactly as OGR_F_SetStyleString() except that it assumes
6828+
* This method operates the same as OGR_F_SetStyleString() except that it assumes
67666829
* ownership of the passed string.
67676830
*
67686831
* This function is the same as the C++ method

0 commit comments

Comments
 (0)