@@ -3124,12 +3124,14 @@ double OGRLineString::get_Area() const
3124
3124
}
3125
3125
3126
3126
/* ***********************************************************************/
3127
- /* GetGeodesicAreaOrLength() */
3127
+ /* GetGeodesicInputs() */
3128
3128
/* ***********************************************************************/
3129
3129
3130
- static bool GetGeodesicAreaOrLength (const OGRLineString *poLS,
3131
- const OGRSpatialReference *poSRSOverride,
3132
- double *pdfArea, double *pdfLength)
3130
+ static bool GetGeodesicInputs (const OGRLineString *poLS,
3131
+ const OGRSpatialReference *poSRSOverride,
3132
+ const char *pszComputationType, geod_geodesic &g,
3133
+ std::vector<double > &adfLat,
3134
+ std::vector<double > &adfLon)
3133
3135
{
3134
3136
if (!poSRSOverride)
3135
3137
poSRSOverride = poLS->getSpatialReference ();
@@ -3138,7 +3140,7 @@ static bool GetGeodesicAreaOrLength(const OGRLineString *poLS,
3138
3140
{
3139
3141
CPLError (CE_Failure, CPLE_AppDefined,
3140
3142
" Cannot compute %s on ellipsoid due to missing SRS" ,
3141
- pdfArea ? " area " : " length " );
3143
+ pszComputationType );
3142
3144
return false ;
3143
3145
}
3144
3146
@@ -3150,12 +3152,9 @@ static bool GetGeodesicAreaOrLength(const OGRLineString *poLS,
3150
3152
if (eErr != OGRERR_NONE)
3151
3153
return false ;
3152
3154
3153
- geod_geodesic g;
3154
3155
geod_init (&g, dfSemiMajor,
3155
3156
dfInvFlattening != 0 ? 1.0 / dfInvFlattening : 0.0 );
3156
3157
3157
- std::vector<double > adfLat;
3158
- std::vector<double > adfLon;
3159
3158
const int nPointCount = poLS->getNumPoints ();
3160
3159
adfLat.reserve (nPointCount);
3161
3160
adfLon.reserve (nPointCount);
@@ -3208,8 +3207,6 @@ static bool GetGeodesicAreaOrLength(const OGRLineString *poLS,
3208
3207
adfLat[i] *= dfToDegrees;
3209
3208
}
3210
3209
3211
- geod_polygonarea (&g, adfLat.data (), adfLon.data (),
3212
- static_cast <int >(adfLat.size ()), pdfArea, pdfLength);
3213
3210
return true ;
3214
3211
}
3215
3212
@@ -3220,9 +3217,14 @@ static bool GetGeodesicAreaOrLength(const OGRLineString *poLS,
3220
3217
double
3221
3218
OGRLineString::get_GeodesicArea (const OGRSpatialReference *poSRSOverride) const
3222
3219
{
3223
- double dfArea = 0 ;
3224
- if (!GetGeodesicAreaOrLength (this , poSRSOverride, &dfArea, nullptr ))
3220
+ geod_geodesic g;
3221
+ std::vector<double > adfLat;
3222
+ std::vector<double > adfLon;
3223
+ if (!GetGeodesicInputs (this , poSRSOverride, " area" , g, adfLat, adfLon))
3225
3224
return -1.0 ;
3225
+ double dfArea = -1.0 ;
3226
+ geod_polygonarea (&g, adfLat.data (), adfLon.data (),
3227
+ static_cast <int >(adfLat.size ()), &dfArea, nullptr );
3226
3228
return std::fabs (dfArea);
3227
3229
}
3228
3230
@@ -3233,9 +3235,19 @@ OGRLineString::get_GeodesicArea(const OGRSpatialReference *poSRSOverride) const
3233
3235
double OGRLineString::get_GeodesicLength (
3234
3236
const OGRSpatialReference *poSRSOverride) const
3235
3237
{
3238
+ geod_geodesic g;
3239
+ std::vector<double > adfLat;
3240
+ std::vector<double > adfLon;
3241
+ if (!GetGeodesicInputs (this , poSRSOverride, " length" , g, adfLat, adfLon))
3242
+ return -1.0 ;
3236
3243
double dfLength = 0 ;
3237
- if (!GetGeodesicAreaOrLength (this , poSRSOverride, nullptr , &dfLength))
3238
- return -1 ;
3244
+ for (size_t i = 0 ; i + 1 < adfLon.size (); ++i)
3245
+ {
3246
+ double dfSegmentLength = 0 ;
3247
+ geod_inverse (&g, adfLat[i], adfLon[i], adfLat[i + 1 ], adfLon[i + 1 ],
3248
+ &dfSegmentLength, nullptr , nullptr );
3249
+ dfLength += dfSegmentLength;
3250
+ }
3239
3251
return dfLength;
3240
3252
}
3241
3253
0 commit comments