Transform a geometry. * * This is an enhanced version of OGRGeometry::Transform(). * * When reprojecting geometries from a Polar Stereographic projection or a * projection naturally crossing the antimeridian (like UTM Zone 60) to a * geographic CRS, it will cut geometries along the antimeridian. So a * LineString might be returned as a MultiLineString. * * The WRAPDATELINE=YES option migh
| 4429 | * @return (new) transformed geometry. |
| 4430 | */ |
| 4431 | OGRGeometry *OGRGeometryFactory::transformWithOptions( |
| 4432 | const OGRGeometry *poSrcGeom, OGRCoordinateTransformation *poCT, |
| 4433 | CSLConstList papszOptions, |
| 4434 | CPL_UNUSED const TransformWithOptionsCache &cache) |
| 4435 | { |
| 4436 | auto poDstGeom = std::unique_ptr<OGRGeometry>(poSrcGeom->clone()); |
| 4437 | if (poCT) |
| 4438 | { |
| 4439 | #ifdef HAVE_GEOS |
| 4440 | bool bNeedPostCorrection = false; |
| 4441 | const auto poSourceCRS = poCT->GetSourceCS(); |
| 4442 | const auto poTargetCRS = poCT->GetTargetCS(); |
| 4443 | const auto eSrcGeomType = wkbFlatten(poSrcGeom->getGeometryType()); |
| 4444 | // Check if we are transforming from projected coordinates to |
| 4445 | // geographic coordinates, with a chance that there might be polar or |
| 4446 | // anti-meridian discontinuities. If so, create the inverse transform. |
| 4447 | if (eSrcGeomType != wkbPoint && eSrcGeomType != wkbMultiPoint && |
| 4448 | (poSourceCRS != cache.d->poSourceCRS || |
| 4449 | poTargetCRS != cache.d->poTargetCRS || poCT != cache.d->poCT)) |
| 4450 | { |
| 4451 | cache.d->clear(); |
| 4452 | cache.d->poSourceCRS = poSourceCRS; |
| 4453 | cache.d->poTargetCRS = poTargetCRS; |
| 4454 | cache.d->poCT = poCT; |
| 4455 | if (MayBePolarToGeographic(poSourceCRS, poTargetCRS)) |
| 4456 | { |
| 4457 | cache.d->poRevCT.reset(OGRCreateCoordinateTransformation( |
| 4458 | poTargetCRS, poSourceCRS)); |
| 4459 | cache.d->bIsNorthPolar = false; |
| 4460 | cache.d->bIsPolar = false; |
| 4461 | cache.d->poRevCT.reset(poCT->GetInverse()); |
| 4462 | if (cache.d->poRevCT && |
| 4463 | IsPolarToGeographic(poCT, cache.d->poRevCT.get(), |
| 4464 | cache.d->bIsNorthPolar)) |
| 4465 | { |
| 4466 | cache.d->bIsPolar = true; |
| 4467 | } |
| 4468 | } |
| 4469 | } |
| 4470 | |
| 4471 | if (auto poRevCT = cache.d->poRevCT.get()) |
| 4472 | { |
| 4473 | if (cache.d->bIsPolar) |
| 4474 | { |
| 4475 | poDstGeom = TransformBeforePolarToGeographic( |
| 4476 | poRevCT, cache.d->bIsNorthPolar, std::move(poDstGeom), |
| 4477 | bNeedPostCorrection); |
| 4478 | } |
| 4479 | else if (IsAntimeridianProjToGeographic(poCT, poRevCT, |
| 4480 | poDstGeom.get())) |
| 4481 | { |
| 4482 | poDstGeom = TransformBeforeAntimeridianToGeographic( |
| 4483 | poCT, poRevCT, std::move(poDstGeom), bNeedPostCorrection); |
| 4484 | } |
| 4485 | } |
| 4486 | #endif |
| 4487 | OGRErr eErr = poDstGeom->transform(poCT); |
| 4488 | if (eErr != OGRERR_NONE) |
nothing calls this directly
no test coverage detected