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

Add a OGRGeometryFactory::GetDefaultArcStepSize() method to get value… #11605

Merged
merged 1 commit into from
Jan 9, 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
27 changes: 27 additions & 0 deletions autotest/cpp/test_ogr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4571,4 +4571,31 @@ TEST_F(test_ogr, OGRFieldDefnGetFieldTypeByName)
}
}

// Test OGRGeometryFactory::GetDefaultArcStepSize()
TEST_F(test_ogr, GetDefaultArcStepSize)
{
if (CPLGetConfigOption("OGR_ARC_STEPSIZE", nullptr) == nullptr)
{
EXPECT_EQ(OGRGeometryFactory::GetDefaultArcStepSize(), 4.0);
}
{
CPLConfigOptionSetter oSetter("OGR_ARC_STEPSIZE", "0.00001",
/* bSetOnlyIfUndefined = */ false);
CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
EXPECT_EQ(OGRGeometryFactory::GetDefaultArcStepSize(), 1e-2);
EXPECT_TRUE(
strstr(CPLGetLastErrorMsg(),
"Too small value for OGR_ARC_STEPSIZE. Clamping it to"));
}
{
CPLConfigOptionSetter oSetter("OGR_ARC_STEPSIZE", "190",
/* bSetOnlyIfUndefined = */ false);
CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
EXPECT_EQ(OGRGeometryFactory::GetDefaultArcStepSize(), 180);
EXPECT_TRUE(
strstr(CPLGetLastErrorMsg(),
"Too large value for OGR_ARC_STEPSIZE. Clamping it to"));
}
}

} // namespace
7 changes: 2 additions & 5 deletions ogr/gml2ogrgeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1876,9 +1876,7 @@ GML2OGRGeometry_XMLNode_Internal(const CPLXMLNode *psNode, const char *pszId,
if (bSRSUnitIsDegree && dfUOMConv > 0)
{
auto poLS = std::make_unique<OGRLineString>();
// coverity[tainted_data]
const double dfStep =
CPLAtof(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
const double dfStep = OGRGeometryFactory::GetDefaultArcStepSize();
const double dfSign = dfStartAngle < dfEndAngle ? 1 : -1;
for (double dfAngle = dfStartAngle;
(dfAngle - dfEndAngle) * dfSign < 0;
Expand Down Expand Up @@ -2010,8 +2008,7 @@ GML2OGRGeometry_XMLNode_Internal(const CPLXMLNode *psNode, const char *pszId,
if (bSRSUnitIsDegree && dfUOMConv > 0)
{
auto poLS = std::make_unique<OGRLineString>();
const double dfStep =
CPLAtof(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
const double dfStep = OGRGeometryFactory::GetDefaultArcStepSize();
for (double dfAngle = 0; dfAngle < 360; dfAngle += dfStep)
{
double dfLong = 0.0;
Expand Down
2 changes: 2 additions & 0 deletions ogr/ogr_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -4381,6 +4381,8 @@ class CPL_DLL OGRGeometryFactory
char **papszOptions,
const TransformWithOptionsCache &cache = TransformWithOptionsCache());

static double GetDefaultArcStepSize();

static OGRGeometry *
approximateArcAngles(double dfX, double dfY, double dfZ,
double dfPrimaryRadius, double dfSecondaryAxis,
Expand Down
46 changes: 40 additions & 6 deletions ogr/ogrgeometryfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4197,13 +4197,47 @@ void OGR_GeomTransformer_Destroy(OGRGeomTransformerH hTransformer)
}

/************************************************************************/
/* OGRGF_GetDefaultStepSize() */
/* OGRGeometryFactory::GetDefaultArcStepSize() */
/************************************************************************/

static double OGRGF_GetDefaultStepSize()
/** Return the default value of the angular step used when stroking curves
* as lines. Defaults to 4 degrees.
* Can be modified by setting the OGR_ARC_STEPSIZE configuration option.
* Valid values are in [1e-2, 180] degree range.
* @since 3.11
*/

/* static */
double OGRGeometryFactory::GetDefaultArcStepSize()
{
// coverity[tainted_data]
return CPLAtofM(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
const double dfVal = CPLAtofM(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
constexpr double MIN_VAL = 1e-2;
if (dfVal < MIN_VAL)
{
static bool bWarned = false;
if (!bWarned)
{
bWarned = true;
CPLError(CE_Warning, CPLE_AppDefined,
"Too small value for OGR_ARC_STEPSIZE. Clamping it to %f",
MIN_VAL);
}
return MIN_VAL;
}
constexpr double MAX_VAL = 180;
if (dfVal > MAX_VAL)
{
static bool bWarned = false;
if (!bWarned)
{
bWarned = true;
CPLError(CE_Warning, CPLE_AppDefined,
"Too large value for OGR_ARC_STEPSIZE. Clamping it to %f",
MAX_VAL);
}
return MAX_VAL;
}
return dfVal;
}

/************************************************************************/
Expand Down Expand Up @@ -4266,7 +4300,7 @@ OGRGeometry *OGRGeometryFactory::approximateArcAngles(
// Support default arc step setting.
if (dfMaxAngleStepSizeDegrees < 1e-6)
{
dfMaxAngleStepSizeDegrees = OGRGF_GetDefaultStepSize();
dfMaxAngleStepSizeDegrees = OGRGeometryFactory::GetDefaultArcStepSize();
}

// Determine maximum interpolation gap. This is the largest straight-line
Expand Down Expand Up @@ -5459,7 +5493,7 @@ OGRLineString *OGRGeometryFactory::curveToLineString(
// support default arc step setting.
if (dfMaxAngleStepSizeDegrees < 1e-6)
{
dfMaxAngleStepSizeDegrees = OGRGF_GetDefaultStepSize();
dfMaxAngleStepSizeDegrees = OGRGeometryFactory::GetDefaultArcStepSize();
}

double dfStep = dfMaxAngleStepSizeDegrees / 180 * M_PI;
Expand Down
4 changes: 1 addition & 3 deletions ogr/ogrpgeogeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,10 +1835,8 @@ static OGRCurve *OGRShapeCreateCompoundCurve(int nPartStartIdx, int nPartPoints,
dfStartAngle += 2 * M_PI;
else if (dfEndAngle + M_PI < dfStartAngle)
dfEndAngle += 2 * M_PI;
// coverity[tainted_data]
const double dfStepSizeRad =
CPLAtofM(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4")) / 180.0 *
M_PI;
OGRGeometryFactory::GetDefaultArcStepSize() / 180.0 * M_PI;
const double dfLengthTangentStart =
(dfX1 - dfX0) * (dfX1 - dfX0) + (dfY1 - dfY0) * (dfY1 - dfY0);
const double dfLengthTangentEnd =
Expand Down
2 changes: 1 addition & 1 deletion ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ static void ProcessCurve(OGRFeature *poFeature, const CPLString &osPen,
else
poSC = new OGRLineString();
const double dfArcStepSize =
CPLAtofM(CPLGetConfigOption("OGR_ARC_STEPSIZE", "4"));
OGRGeometryFactory::GetDefaultArcStepSize();
if (!ellipse.isNull())
{
nPoints = std::max(2, static_cast<int>(360 / dfArcStepSize));
Expand Down
11 changes: 2 additions & 9 deletions ogr/ogrsf_frmts/ili/ogrili1datasource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,19 +148,12 @@ int OGRILI1DataSource::Open(const char *pszNewName, char **papszOpenOptionsIn,
if (osModelFilename.length() > 0)
poReader->ReadModel(poImdReader, osModelFilename.c_str(), this);

int bResetConfigOption = FALSE;
if (EQUAL(CPLGetConfigOption("OGR_ARC_STEPSIZE", ""), ""))
{
bResetConfigOption = TRUE;
CPLSetThreadLocalConfigOption("OGR_ARC_STEPSIZE", "0.96");
}
CPLConfigOptionSetter oSetter("OGR_ARC_STEPSIZE", "0.96",
/* bSetOnlyIfUndefined = */ true);

// Parse model and read data - without surface join and area polygonizing.
poReader->ReadFeatures();

if (bResetConfigOption)
CPLSetThreadLocalConfigOption("OGR_ARC_STEPSIZE", nullptr);

return TRUE;
}

Expand Down
12 changes: 3 additions & 9 deletions ogr/ogrsf_frmts/ili/ogrili1layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,9 @@ OGRErr OGRILI1Layer::CreateField(const OGRFieldDefn *poField,
void OGRILI1Layer::JoinGeomLayers()
{
bGeomsJoined = true;
bool bResetConfigOption = false;
if (EQUAL(CPLGetConfigOption("OGR_ARC_STEPSIZE", ""), ""))
{
bResetConfigOption = true;
CPLSetThreadLocalConfigOption("OGR_ARC_STEPSIZE", "0.96");
}

CPLConfigOptionSetter oSetter("OGR_ARC_STEPSIZE", "0.96",
/* bSetOnlyIfUndefined = */ true);

for (GeomFieldInfos::const_iterator it = oGeomFieldInfos.begin();
it != oGeomFieldInfos.end(); ++it)
Expand Down Expand Up @@ -477,9 +474,6 @@ void OGRILI1Layer::JoinGeomLayers()
}
}
}

if (bResetConfigOption)
CPLSetThreadLocalConfigOption("OGR_ARC_STEPSIZE", nullptr);
}

void OGRILI1Layer::JoinSurfaceLayer(OGRILI1Layer *poSurfaceLineLayer,
Expand Down
2 changes: 1 addition & 1 deletion port/cpl_known_config_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ constexpr static const char* const apszKnownConfigOptions[] =
"OGR_API_SPY_SNAPSHOT_PATH", // from ograpispy.cpp
"OGR_APPLY_GEOM_SET_PRECISION", // from ogr2ogr_lib.cpp, ogrlayer.cpp
"OGR_ARC_MAX_GAP", // from ogrgeometryfactory.cpp
"OGR_ARC_STEPSIZE", // from gml2ogrgeometry.cpp, ogrdgnv8layer.cpp, ogrgeometryfactory.cpp, ogrili1datasource.cpp, ogrili1layer.cpp, ogrpgeogeometry.cpp
"OGR_ARC_STEPSIZE", // from ogrgeometryfactory.cpp
"OGR_ARROW_COMPUTE_GEOMETRY_TYPE", // from ogrfeatherlayer.cpp
"OGR_ARROW_LOAD_FILE_SYSTEM_FACTORIES", // from ogrfeatherdriver.cpp
"OGR_ARROW_MEM_LIMIT", // from ograrrowarrayhelper.cpp
Expand Down
Loading