From f6232db745af1acd2473f51f82d006372c04fc55 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 10:36:14 +0100 Subject: Add VERTCON grid name alternatives in database, and handle filename substitution for VERTCON method --- src/iso19111/coordinateoperation.cpp | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 2128124b..90266307 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -8001,6 +8001,46 @@ TransformationNNPtr Transformation::substitutePROJAlternativeGridNames( } } + if (methodEPSGCode == EPSG_CODE_METHOD_VERTCON) { + auto fileParameter = + parameterValue(EPSG_NAME_PARAMETER_VERTICAL_OFFSET_FILE, + EPSG_CODE_PARAMETER_VERTICAL_OFFSET_FILE); + if (fileParameter && + fileParameter->type() == ParameterValue::Type::FILENAME) { + + auto filename = fileParameter->valueFile(); + if (databaseContext->lookForGridAlternative( + filename, projFilename, projGridFormat, inverseDirection)) { + + if (filename == projFilename) { + assert(!inverseDirection); + return self; + } + + auto parameters = std::vector{ + createOpParamNameEPSGCode( + EPSG_CODE_PARAMETER_VERTICAL_OFFSET_FILE)}; + if (inverseDirection) { + return create(createPropertiesForInverse( + self.as_nullable().get(), true, false), + targetCRS(), sourceCRS(), nullptr, + createSimilarPropertiesMethod(method()), + parameters, {ParameterValue::createFilename( + projFilename)}, + coordinateOperationAccuracies()) + ->inverseAsTransformation(); + } else { + return create( + createSimilarPropertiesTransformation(self), + sourceCRS(), targetCRS(), nullptr, + createSimilarPropertiesMethod(method()), parameters, + {ParameterValue::createFilename(projFilename)}, + coordinateOperationAccuracies()); + } + } + } + } + return self; } // --------------------------------------------------------------------------- -- cgit v1.2.3 From b08b9580ab0aca70c8762b3f8f0039484ddaca60 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 11:02:53 +0100 Subject: vgridshift: propagate multiplier to avoid false-positive detection of nodata values in the grids with US VERTCON grids that are in millimeters --- src/apply_vgridshift.cpp | 20 ++++++++++---------- src/proj_internal.h | 2 +- src/transformations/deformation.cpp | 2 +- src/transformations/vgridshift.cpp | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index 61e0c528..951bdf6d 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -35,16 +35,16 @@ #include "proj_internal.h" #include "proj_internal.h" -static int is_nodata(float value) +static int is_nodata(float value, double vmultiplier) { /* nodata? */ /* GTX official nodata value if -88.88880f, but some grids also */ /* use other big values for nodata (e.g naptrans2008.gtx has */ /* nodata values like -2147479936), so test them too */ - return value > 1000 || value < -1000 || value == -88.88880f; + return value * vmultiplier > 1000 || value * vmultiplier < -1000 || value == -88.88880f; } -static double read_vgrid_value( PJ *defn, PJ_LP input, int *gridlist_count_p, PJ_GRIDINFO **tables, struct CTABLE *ct) { +static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int *gridlist_count_p, PJ_GRIDINFO **tables, struct CTABLE *ct) { int itable = 0; double value = HUGE_VAL; double grid_x, grid_y; @@ -129,28 +129,28 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, int *gridlist_count_p, PJ double total_weight = 0.0; int n_weights = 0; value = 0.0f; - if( !is_nodata(value_a) ) + if( !is_nodata(value_a, vmultiplier) ) { double weight = (1.0-grid_x) * (1.0-grid_y); value += value_a * weight; total_weight += weight; n_weights ++; } - if( !is_nodata(value_b) ) + if( !is_nodata(value_b, vmultiplier) ) { double weight = (grid_x) * (1.0-grid_y); value += value_b * weight; total_weight += weight; n_weights ++; } - if( !is_nodata(value_c) ) + if( !is_nodata(value_c, vmultiplier) ) { double weight = (1.0-grid_x) * (grid_y); value += value_c * weight; total_weight += weight; n_weights ++; } - if( !is_nodata(value_d) ) + if( !is_nodata(value_d, vmultiplier) ) { double weight = (grid_x) * (grid_y); value += value_d * weight; @@ -218,7 +218,7 @@ int pj_apply_vgridshift( PJ *defn, const char *listname, input.phi = y[io]; input.lam = x[io]; - value = read_vgrid_value(defn, input, gridlist_count_p, tables, &ct); + value = read_vgrid_value(defn, input, 1.0, gridlist_count_p, tables, &ct); if( inverse ) z[io] -= value; @@ -310,7 +310,7 @@ int proj_vgrid_init(PJ* P, const char *grids) { } /***********************************************/ -double proj_vgrid_value(PJ *P, PJ_LP lp){ +double proj_vgrid_value(PJ *P, PJ_LP lp, double vmultiplier){ /*********************************************** Read grid value at position lp in grids loaded @@ -324,7 +324,7 @@ double proj_vgrid_value(PJ *P, PJ_LP lp){ double value; memset(&used_grid, 0, sizeof(struct CTABLE)); - value = read_vgrid_value(P, lp, &(P->vgridlist_geoid_count), P->vgridlist_geoid, &used_grid); + value = read_vgrid_value(P, lp, vmultiplier, &(P->vgridlist_geoid_count), P->vgridlist_geoid, &used_grid); proj_log_trace(P, "proj_vgrid_value: (%f, %f) = %f", lp.lam*RAD_TO_DEG, lp.phi*RAD_TO_DEG, value); return value; diff --git a/src/proj_internal.h b/src/proj_internal.h index 14b69492..448b65c8 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -203,7 +203,7 @@ PJ_COORD PROJ_DLL pj_approx_3D_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD co /* Grid functionality */ int proj_vgrid_init(PJ *P, const char *grids); int proj_hgrid_init(PJ *P, const char *grids); -double proj_vgrid_value(PJ *P, PJ_LP lp); +double proj_vgrid_value(PJ *P, PJ_LP lp, double vmultiplier); PJ_LP proj_hgrid_value(PJ *P, PJ_LP lp); PJ_LP proj_hgrid_apply(PJ *P, PJ_LP lp, PJ_DIRECTION direction); diff --git a/src/transformations/deformation.cpp b/src/transformations/deformation.cpp index c28e1489..0e0d641c 100644 --- a/src/transformations/deformation.cpp +++ b/src/transformations/deformation.cpp @@ -92,7 +92,7 @@ static PJ_XYZ get_grid_shift(PJ* P, PJ_XYZ cartesian) { /* look up correction values in grids */ shift.lp = proj_hgrid_value(P, geodetic.lp); - shift.enu.u = proj_vgrid_value(P, geodetic.lp); + shift.enu.u = proj_vgrid_value(P, geodetic.lp, 1.0); if (proj_errno(P) == PJD_ERR_GRID_AREA) proj_log_debug(P, "deformation: coordinate (%.3f, %.3f) outside deformation model", diff --git a/src/transformations/vgridshift.cpp b/src/transformations/vgridshift.cpp index fda38ec3..664010b8 100644 --- a/src/transformations/vgridshift.cpp +++ b/src/transformations/vgridshift.cpp @@ -26,7 +26,7 @@ static PJ_XYZ forward_3d(PJ_LPZ lpz, PJ *P) { if (P->vgridlist_geoid != nullptr) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - point.xyz.z += Q->forward_multiplier * proj_vgrid_value(P, point.lp); + point.xyz.z += Q->forward_multiplier * proj_vgrid_value(P, point.lp, Q->forward_multiplier); } return point.xyz; @@ -41,7 +41,7 @@ static PJ_LPZ reverse_3d(PJ_XYZ xyz, PJ *P) { if (P->vgridlist_geoid != nullptr) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - point.xyz.z -= Q->forward_multiplier * proj_vgrid_value(P, point.lp); + point.xyz.z -= Q->forward_multiplier * proj_vgrid_value(P, point.lp, Q->forward_multiplier); } return point.lpz; -- cgit v1.2.3 From 3664cb546811146c588cab6db41b1ccef6fcee7a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 11:12:38 +0100 Subject: compoundCRS to compoundCRS: avoid emitting dummy 'Null geographic offset from X to X' in transformation name --- src/iso19111/coordinateoperation.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 90266307..ed98832f 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -10748,8 +10748,13 @@ static CoordinateOperationNNPtr createHorizVerticalHorizPROJBased( interpolationGeogCRS); bool dummy = false; - auto ops = std::vector{ - opSrcCRSToGeogCRS, verticalTransform, opGeogCRStoDstCRS}; + auto ops = opSrcCRSToGeogCRS->sourceCRS()->_isEquivalentTo( + opSrcCRSToGeogCRS->targetCRS().get()) + ? std::vector{verticalTransform, + opGeogCRStoDstCRS} + : std::vector{opSrcCRSToGeogCRS, + verticalTransform, + opGeogCRStoDstCRS}; auto extent = getExtent(ops, true, dummy); auto properties = util::PropertyMap(); properties.set(common::IdentifiedObject::NAME_KEY, -- cgit v1.2.3 From 70bc293a43def169fa34ed8e97a5cb06b336f247 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 12:18:16 +0100 Subject: Vertical CRS transformation: synthetize a vertical unit change transformation when needed, and also sort Null geographic offset transformation in last --- src/iso19111/coordinateoperation.cpp | 153 ++++++++++++++++++++++++++++++----- 1 file changed, 131 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index ed98832f..d3446460 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -106,6 +106,7 @@ constexpr double UTM_SOUTH_FALSE_NORTHING = 10000000.0; static const std::string INVERSE_OF = "Inverse of "; static const char *NULL_GEOCENTRIC_TRANSLATION = "Null geocentric translation"; static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset"; +static const char *APPROXIMATE_TRANSFORMATION = " (approximate transformation)"; //! @endcond //! @cond Doxygen_Suppress @@ -7054,6 +7055,39 @@ TransformationNNPtr Transformation::createVerticalOffset( // --------------------------------------------------------------------------- +/** \brief Instantiate a transformation based on the Change of Vertical Unit + * method. + * + * This method is defined as [EPSG:1069] + * (https://www.epsg-registry.org/export.htm?gml=urn:ogc:def:method:EPSG::1069) + * + * @param properties See \ref general_properties of the conversion. If the name + * is not provided, it is automatically set. + * @param sourceCRSIn Source CRS. + * @param targetCRSIn Target CRS. + * @param factor Conversion factor + * @param accuracies Vector of positional accuracy (might be empty). + * @return a new Transformation. + */ +TransformationNNPtr Transformation::createChangeVerticalUnit( + const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn, + const crs::CRSNNPtr &targetCRSIn, const common::Scale &factor, + const std::vector &accuracies) { + return create( + properties, sourceCRSIn, targetCRSIn, nullptr, + createMethodMapNameEPSGCode(EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT), + VectorOfParameters{ + createOpParamNameEPSGCode( + EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR), + }, + VectorOfValues{ + factor, + }, + accuracies); +} + +// --------------------------------------------------------------------------- + static const char *getCRSQualifierStr(const crs::CRSPtr &crs) { auto geod = dynamic_cast(crs.get()); if (geod) { @@ -7481,6 +7515,17 @@ TransformationNNPtr Transformation::inverseAsTransformation() const { coordinateOperationAccuracies())); } + if (methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT) { + const double convFactor = parameterValueNumericAsSI( + EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR); + return d->registerInv( + shared_from_this(), + createChangeVerticalUnit( + createPropertiesForInverse(this, false, false), l_targetCRS, + l_sourceCRS, common::Scale(1.0 / convFactor), + coordinateOperationAccuracies())); + } + return InverseTransformation::create(NN_NO_CHECK( util::nn_dynamic_pointer_cast(shared_from_this()))); } @@ -8835,6 +8880,31 @@ bool SingleOperation::exportToPROJStringGeneric( "conversion"); } + if (methodEPSGCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT) { + double convFactor = parameterValueNumericAsSI( + EPSG_CODE_PARAMETER_UNIT_CONVERSION_SCALAR); + auto uom = common::UnitOfMeasure(std::string(), convFactor, + common::UnitOfMeasure::Type::LINEAR) + .exportToPROJString(); + auto reverse_uom = + common::UnitOfMeasure(std::string(), 1.0 / convFactor, + common::UnitOfMeasure::Type::LINEAR) + .exportToPROJString(); + if (!uom.empty()) { + formatter->addStep("unitconvert"); + formatter->addParam("z_in", uom); + formatter->addParam("z_out", "m"); + } else if (!reverse_uom.empty()) { + formatter->addStep("unitconvert"); + formatter->addParam("z_in", "m"); + formatter->addParam("z_out", reverse_uom); + } else { + formatter->addStep("affine"); + formatter->addParam("s33", convFactor); + } + return true; + } + return false; } @@ -9667,14 +9737,18 @@ struct PrecomputedOpCharacteristics { bool gridsAvailable_ = false; bool gridsKnown_ = false; size_t stepCount_ = 0; + bool isApprox_ = false; + bool isNullTransformation_ = false; PrecomputedOpCharacteristics() = default; PrecomputedOpCharacteristics(double area, double accuracy, bool hasGrids, bool gridsAvailable, bool gridsKnown, - size_t stepCount) + size_t stepCount, bool isApprox, + bool isNullTransformation) : area_(area), accuracy_(accuracy), hasGrids_(hasGrids), gridsAvailable_(gridsAvailable), gridsKnown_(gridsKnown), - stepCount_(stepCount) {} + stepCount_(stepCount), isApprox_(isApprox), + isNullTransformation_(isNullTransformation) {} }; // --------------------------------------------------------------------------- @@ -9701,6 +9775,22 @@ struct SortFunction { // CAUTION: the order of the comparisons is extremely important // to get the intended result. + if (!iterA->second.isApprox_ && iterB->second.isApprox_) { + return true; + } + if (iterA->second.isApprox_ && !iterB->second.isApprox_) { + return false; + } + + if (!iterA->second.isNullTransformation_ && + iterB->second.isNullTransformation_) { + return true; + } + if (iterA->second.isNullTransformation_ && + !iterB->second.isNullTransformation_) { + return false; + } + if (iterA->second.hasGrids_ && iterB->second.hasGrids_) { // Operations where grids are all available go before other if (iterA->second.gridsAvailable_ && @@ -9926,6 +10016,8 @@ struct FilterResults { if (name.find(NULL_GEOGRAPHIC_OFFSET) == std::string::npos && name.find(NULL_GEOCENTRIC_TRANSLATION) == + std::string::npos && + name.find(APPROXIMATE_TRANSFORMATION) == std::string::npos) { hasOpThatContainsAreaOfInterest = true; } @@ -9961,6 +10053,8 @@ struct FilterResults { if (name.find(NULL_GEOGRAPHIC_OFFSET) == std::string::npos && name.find(NULL_GEOCENTRIC_TRANSLATION) == + std::string::npos && + name.find(APPROXIMATE_TRANSFORMATION) == std::string::npos) { hasOpThatContainsAreaOfInterest = true; } @@ -10067,9 +10161,17 @@ struct FilterResults { const auto stepCount = getStepCount(op); + const bool isApprox = + op->nameStr().find(APPROXIMATE_TRANSFORMATION) != + std::string::npos; + const bool isNullTransformation = + op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) != + std::string::npos || + op->nameStr().find(NULL_GEOCENTRIC_TRANSLATION) != + std::string::npos; map[op.get()] = PrecomputedOpCharacteristics( area, getAccuracy(op), hasGrids, gridsAvailable, gridsKnown, - stepCount); + stepCount, isApprox, isNullTransformation); } // Sort ! @@ -10082,7 +10184,8 @@ struct FilterResults { // If we have more than one result, and than the last result is the // default "Null geographic offset" or "Null geocentric translation" - // operations we have synthetized, remove it as + // operations we have synthetized, and that at least one operation + // has the desired area of interest, remove it as // all previous results are necessarily better if (hasOpThatContainsAreaOfInterest && res.size() > 1) { const std::string &name = res.back()->nameStr(); @@ -11571,29 +11674,35 @@ CoordinateOperationFactory::Private::createOperations( if (vertSrc && vertDst) { const auto &srcDatum = vertSrc->datum(); const auto &dstDatum = vertDst->datum(); - if (srcDatum && dstDatum && - srcDatum->_isEquivalentTo( - dstDatum.get(), util::IComparable::Criterion::EQUIVALENT)) { - const double convSrc = vertSrc->coordinateSystem() - ->axisList()[0] - ->unit() - .conversionToSI(); - const double convDst = vertDst->coordinateSystem() - ->axisList()[0] - ->unit() - .conversionToSI(); - if (convSrc != convDst) { - const double factor = convSrc / convDst; + const bool equivalentVDatum = + (srcDatum && dstDatum && + srcDatum->_isEquivalentTo( + dstDatum.get(), util::IComparable::Criterion::EQUIVALENT)); + + const double convSrc = + vertSrc->coordinateSystem()->axisList()[0]->unit().conversionToSI(); + const double convDst = + vertDst->coordinateSystem()->axisList()[0]->unit().conversionToSI(); + if (convSrc != convDst) { + const double factor = convSrc / convDst; + auto name = + buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()); + if (!equivalentVDatum) { + name += APPROXIMATE_TRANSFORMATION; + auto conv = Transformation::createChangeVerticalUnit( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + name), + sourceCRS, targetCRS, common::Scale(factor), {}); + res.push_back(conv); + } else { auto conv = Conversion::createChangeVerticalUnit( - util::PropertyMap().set( - common::IdentifiedObject::NAME_KEY, - buildTransfName(sourceCRS->nameStr(), - targetCRS->nameStr())), + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + name), common::Scale(factor)); conv->setCRSs(sourceCRS, targetCRS, nullptr); res.push_back(conv); - return res; } + return res; } } -- cgit v1.2.3 From 545936e04bda914a9caf8c1e4e0eefb4c5c80397 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 12:57:26 +0100 Subject: Operation sorting: tweak --- src/iso19111/coordinateoperation.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index d3446460..d66afd0d 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -9821,6 +9821,17 @@ struct SortFunction { return false; } + if (accuracyA < 0 && accuracyB < 0) { + // unknown accuracy ? then prefer operations with grids, which + // are likely to have best practical accuracy + if (iterA->second.hasGrids_ && !iterB->second.hasGrids_) { + return true; + } + if (!iterA->second.hasGrids_ && iterB->second.hasGrids_) { + return false; + } + } + // Operations with larger non-zero area of use go before those with // lower one const double areaA = iterA->second.area_; @@ -9852,15 +9863,6 @@ struct SortFunction { if (iterA->second.hasGrids_ && !iterB->second.hasGrids_) { return false; } - } else if (accuracyA < 0 && accuracyB < 0) { - // unknown accuracy ? then prefer operations with grids, which - // are likely to have best practical accuracy - if (iterA->second.hasGrids_ && !iterB->second.hasGrids_) { - return true; - } - if (!iterA->second.hasGrids_ && iterB->second.hasGrids_) { - return false; - } } // The less intermediate steps, the better @@ -10136,13 +10138,7 @@ struct FilterResults { bool hasGrids = false; bool gridsAvailable = true; bool gridsKnown = true; - if (context->getAuthorityFactory() && - (gridAvailabilityUse == - CoordinateOperationContext::GridAvailabilityUse:: - USE_FOR_SORTING || - gridAvailabilityUse == - CoordinateOperationContext::GridAvailabilityUse:: - IGNORE_GRID_AVAILABILITY)) { + if (context->getAuthorityFactory()) { const auto gridsNeeded = op->gridsNeeded( context->getAuthorityFactory()->databaseContext()); for (const auto &gridDesc : gridsNeeded) { -- cgit v1.2.3 From 0d8600e46b20fba28eb0cf0cabbbb4c6b586c6bf Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 13:18:20 +0100 Subject: PROJStringFormatter: remove useless push/pop in another case --- src/iso19111/io.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index e14239b0..f602c7c0 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -5141,6 +5141,33 @@ const std::string &PROJStringFormatter::toString() const { } } + // push v_3, unitconvert xy_in xy_out, axisswap order=2,1, pop v_3 + // -> can suppress push/pop + if (i + 2 < d->steps_.size() && prevStep.name == "push" && + prevStepParamCount == 1 && + prevStep.paramValues[0].key == "v_3" && + curStep.name == "unitconvert" && curStepParamCount == 2 && + curStep.paramValues[0].key == "xy_in" && + curStep.paramValues[1].key == "xy_out") { + auto iterNext = iterCur; + ++iterNext; + auto &nextStep = *iterNext; + auto iterNextNext = iterNext; + ++iterNextNext; + auto &nextNextStep = *iterNextNext; + if (nextStep.name == "axisswap" && + nextStep.paramValues.size() == 1 && + nextStep.paramValues[0].equals("order", "2,1") && + nextNextStep.name == "pop" && + nextNextStep.paramValues.size() == 1 && + nextNextStep.paramValues[0].key == "v_3") { + d->steps_.erase(iterPrev); + d->steps_.erase(iterNextNext); + changeDone = true; + break; + } + } + // unitconvert xy_in=A xy_out=B, pop/push v_3, unitconvert xy_in=B // xy_out=A -> can suppress unitconvert if (i + 1 < d->steps_.size() && prevStep.name == "unitconvert" && -- cgit v1.2.3 From 04844ac495f65e824a0bd9f9e49ea3360f2c063f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 13:21:15 +0100 Subject: Apply multiplier in proj_vgrid_value() --- src/apply_vgridshift.cpp | 2 +- src/transformations/vgridshift.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index 951bdf6d..ae23e39a 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -165,7 +165,7 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * } - return value; + return value * vmultiplier; } /************************************************************************/ diff --git a/src/transformations/vgridshift.cpp b/src/transformations/vgridshift.cpp index 664010b8..4cd48fb6 100644 --- a/src/transformations/vgridshift.cpp +++ b/src/transformations/vgridshift.cpp @@ -26,7 +26,7 @@ static PJ_XYZ forward_3d(PJ_LPZ lpz, PJ *P) { if (P->vgridlist_geoid != nullptr) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - point.xyz.z += Q->forward_multiplier * proj_vgrid_value(P, point.lp, Q->forward_multiplier); + point.xyz.z += proj_vgrid_value(P, point.lp, Q->forward_multiplier); } return point.xyz; @@ -41,7 +41,7 @@ static PJ_LPZ reverse_3d(PJ_XYZ xyz, PJ *P) { if (P->vgridlist_geoid != nullptr) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - point.xyz.z -= Q->forward_multiplier * proj_vgrid_value(P, point.lp, Q->forward_multiplier); + point.xyz.z -= proj_vgrid_value(P, point.lp, Q->forward_multiplier); } return point.lpz; -- cgit v1.2.3 From 2272ba8f6a77903203632111a44b44e544fe332b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 15:03:55 +0100 Subject: projinfo: advertize the use of '--spatial-test intersects' when it can bring more results --- src/apps/projinfo.cpp | 106 +++++++++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 9f908c8a..9472d99e 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -136,11 +136,11 @@ static std::string c_ify_string(const std::string &str) { // --------------------------------------------------------------------------- -static BaseObjectNNPtr buildObject(DatabaseContextPtr dbContext, - const std::string &user_string, - bool kindIsCRS, const std::string &context, - bool buildBoundCRSToWGS84, CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, - bool quiet) { +static BaseObjectNNPtr buildObject( + DatabaseContextPtr dbContext, const std::string &user_string, + bool kindIsCRS, const std::string &context, bool buildBoundCRSToWGS84, + CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, + bool quiet) { BaseObjectPtr obj; std::string l_user_string(user_string); @@ -213,7 +213,8 @@ static BaseObjectNNPtr buildObject(DatabaseContextPtr dbContext, if (buildBoundCRSToWGS84) { auto crs = std::dynamic_pointer_cast(obj); if (crs) { - obj = crs->createBoundCRSToWGS84IfPossible(dbContext, allowUseIntermediateCRS) + obj = crs->createBoundCRSToWGS84IfPossible(dbContext, + allowUseIntermediateCRS) .as_nullable(); } } @@ -223,8 +224,10 @@ static BaseObjectNNPtr buildObject(DatabaseContextPtr dbContext, // --------------------------------------------------------------------------- -static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, - CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, const OutputOptions &outputOpt) { +static void outputObject( + DatabaseContextPtr dbContext, BaseObjectNNPtr obj, + CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, + const OutputOptions &outputOpt) { auto identified = dynamic_cast(obj.get()); if (!outputOpt.quiet && identified && identified->isDeprecated()) { @@ -260,7 +263,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, } auto crs = nn_dynamic_pointer_cast(obj); if (!outputOpt.quiet) { - if( crs ) { + if (crs) { std::cout << "PROJ.4 string:" << std::endl; } else { std::cout << "PROJ string:" << std::endl; @@ -271,8 +274,8 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, if (crs) { objToExport = nn_dynamic_pointer_cast( - crs->createBoundCRSToWGS84IfPossible(dbContext, - allowUseIntermediateCRS)); + crs->createBoundCRSToWGS84IfPossible( + dbContext, allowUseIntermediateCRS)); } if (!objToExport) { objToExport = projStringExportable; @@ -411,8 +414,8 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, std::shared_ptr objToExport; if (crs) { objToExport = nn_dynamic_pointer_cast( - crs->createBoundCRSToWGS84IfPossible(dbContext, - allowUseIntermediateCRS)); + crs->createBoundCRSToWGS84IfPossible( + dbContext, allowUseIntermediateCRS)); } if (!objToExport) { objToExport = wktExportable; @@ -514,26 +517,25 @@ static void outputOperations( DatabaseContextPtr dbContext, const std::string &sourceCRSStr, const std::string &targetCRSStr, const ExtentPtr &bboxFilter, CoordinateOperationContext::SpatialCriterion spatialCriterion, + bool spatialCriterionExplictlySpecified, CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse, CoordinateOperationContext::GridAvailabilityUse gridAvailabilityUse, CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, const std::vector> &pivots, const std::string &authority, bool usePROJGridAlternatives, bool showSuperseded, const OutputOptions &outputOpt, bool summary) { - auto sourceObj = buildObject(dbContext, sourceCRSStr, true, "source CRS", - false, - CoordinateOperationContext::IntermediateCRSUse::NEVER, - outputOpt.quiet); + auto sourceObj = buildObject( + dbContext, sourceCRSStr, true, "source CRS", false, + CoordinateOperationContext::IntermediateCRSUse::NEVER, outputOpt.quiet); auto sourceCRS = nn_dynamic_pointer_cast(sourceObj); if (!sourceCRS) { std::cerr << "source CRS string is not a CRS" << std::endl; std::exit(1); } - auto targetObj = buildObject(dbContext, targetCRSStr, true, "target CRS", - false, - CoordinateOperationContext::IntermediateCRSUse::NEVER, - outputOpt.quiet); + auto targetObj = buildObject( + dbContext, targetCRSStr, true, "target CRS", false, + CoordinateOperationContext::IntermediateCRSUse::NEVER, outputOpt.quiet); auto targetCRS = nn_dynamic_pointer_cast(targetObj); if (!targetCRS) { std::cerr << "target CRS string is not a CRS" << std::endl; @@ -541,6 +543,7 @@ static void outputOperations( } std::vector list; + size_t spatialCriterionPartialIntersectionResultCount = 0; try { auto authFactory = dbContext @@ -558,6 +561,21 @@ static void outputOperations( ctxt->setDiscardSuperseded(!showSuperseded); list = CoordinateOperationFactory::create()->createOperations( NN_NO_CHECK(sourceCRS), NN_NO_CHECK(targetCRS), ctxt); + if (!spatialCriterionExplictlySpecified && + spatialCriterion == CoordinateOperationContext::SpatialCriterion:: + STRICT_CONTAINMENT) { + try { + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion:: + PARTIAL_INTERSECTION); + spatialCriterionPartialIntersectionResultCount = + CoordinateOperationFactory::create() + ->createOperations(NN_NO_CHECK(sourceCRS), + NN_NO_CHECK(targetCRS), ctxt) + .size(); + } catch (const std::exception &) { + } + } } catch (const std::exception &e) { std::cerr << "createOperations() failed with: " << e.what() << std::endl; @@ -567,8 +585,14 @@ static void outputOperations( outputObject(dbContext, list[0], allowUseIntermediateCRS, outputOpt); return; } + std::cout << "Candidate operations found: " << list.size() << std::endl; + if (spatialCriterionPartialIntersectionResultCount > list.size()) { + std::cout << "Note: using '--spatial-test intersects' would bring " + "more results (" + << spatialCriterionPartialIntersectionResultCount << ")" + << std::endl; + } if (summary) { - std::cout << "Candidate operations found: " << list.size() << std::endl; for (const auto &op : list) { outputOperationSummary(op); } @@ -576,18 +600,15 @@ static void outputOperations( bool first = true; for (size_t i = 0; i < list.size(); ++i) { const auto &op = list[i]; - if (list.size() > 1) { - if (!first) { - std::cout << std::endl; - } - first = false; - std::cout << "-------------------------------------" - << std::endl; - std::cout << "Operation n" - "\xC2\xB0" - << (i + 1) << ":" << std::endl - << std::endl; + if (!first) { + std::cout << std::endl; } + first = false; + std::cout << "-------------------------------------" << std::endl; + std::cout << "Operation n" + "\xC2\xB0" + << (i + 1) << ":" << std::endl + << std::endl; outputOperationSummary(op); std::cout << std::endl; outputObject(dbContext, op, allowUseIntermediateCRS, outputOpt); @@ -614,6 +635,7 @@ int main(int argc, char **argv) { bool summary = false; ExtentPtr bboxFilter = nullptr; std::string area; + bool spatialCriterionExplictlySpecified = false; CoordinateOperationContext::SpatialCriterion spatialCriterion = CoordinateOperationContext::SpatialCriterion::STRICT_CONTAINMENT; CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse = @@ -622,7 +644,8 @@ int main(int argc, char **argv) { CoordinateOperationContext::GridAvailabilityUse gridAvailabilityUse = CoordinateOperationContext::GridAvailabilityUse::USE_FOR_SORTING; CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS = - CoordinateOperationContext::IntermediateCRSUse::IF_NO_DIRECT_TRANSFORMATION; + CoordinateOperationContext::IntermediateCRSUse:: + IF_NO_DIRECT_TRANSFORMATION; std::vector> pivots; bool usePROJGridAlternatives = true; std::string mainDBPath; @@ -768,6 +791,7 @@ int main(int argc, char **argv) { } else if (arg == "--spatial-test" && i + 1 < argc) { i++; std::string value(argv[i]); + spatialCriterionExplictlySpecified = true; if (ci_equal(value, "contains")) { spatialCriterion = CoordinateOperationContext:: SpatialCriterion::STRICT_CONTAINMENT; @@ -822,9 +846,10 @@ int main(int argc, char **argv) { if (ci_equal(std::string(value), "always")) { allowUseIntermediateCRS = CoordinateOperationContext::IntermediateCRSUse::ALWAYS; - } else if (ci_equal(std::string(value), "if_no_direct_transformation")) { - allowUseIntermediateCRS = - CoordinateOperationContext::IntermediateCRSUse::IF_NO_DIRECT_TRANSFORMATION; + } else if (ci_equal(std::string(value), + "if_no_direct_transformation")) { + allowUseIntermediateCRS = CoordinateOperationContext:: + IntermediateCRSUse::IF_NO_DIRECT_TRANSFORMATION; } else if (ci_equal(std::string(value), "never")) { allowUseIntermediateCRS = CoordinateOperationContext::IntermediateCRSUse::NEVER; @@ -918,8 +943,8 @@ int main(int argc, char **argv) { } if (outputOpt.quiet && - (outputOpt.PROJ5 + outputOpt.WKT2_2018 + - outputOpt.WKT2_2015 + outputOpt.WKT1_GDAL) != 1) { + (outputOpt.PROJ5 + outputOpt.WKT2_2018 + outputOpt.WKT2_2015 + + outputOpt.WKT1_GDAL) != 1) { std::cerr << "-q can only be used with a single output format" << std::endl; usage(); @@ -1055,7 +1080,8 @@ int main(int argc, char **argv) { outputOperations( dbContext, sourceCRSStr, targetCRSStr, bboxFilter, spatialCriterion, - crsExtentUse, gridAvailabilityUse, allowUseIntermediateCRS, pivots, authority, + spatialCriterionExplictlySpecified, crsExtentUse, + gridAvailabilityUse, allowUseIntermediateCRS, pivots, authority, usePROJGridAlternatives, showSuperseded, outputOpt, summary); } -- cgit v1.2.3 From ca8f21ecbcc404b9e9c648784216846c048a3d69 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 15:29:38 +0100 Subject: PROJStringFormatting: change order of emission of push/pop w.r.t axis swap/unitconvert to avoid useless simplification rules --- src/iso19111/coordinateoperation.cpp | 77 +++++++++++++----------------- src/iso19111/io.cpp | 92 ------------------------------------ 2 files changed, 33 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index d66afd0d..fdcb6af8 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -8101,7 +8101,7 @@ static void ThrowExceptionNotGeodeticGeographic(const char *trfrm_name) { // --------------------------------------------------------------------------- static void setupPROJGeodeticSourceCRS(io::PROJStringFormatter *formatter, - const crs::CRSNNPtr &crs, + const crs::CRSNNPtr &crs, bool addPushV3, const char *trfrm_name) { auto sourceCRSGeog = dynamic_cast(crs.get()); if (sourceCRSGeog) { @@ -8109,6 +8109,11 @@ static void setupPROJGeodeticSourceCRS(io::PROJStringFormatter *formatter, sourceCRSGeog->_exportToPROJString(formatter); formatter->stopInversion(); + if (addPushV3) { + formatter->addStep("push"); + formatter->addParam("v_3"); + } + formatter->addStep("cart"); sourceCRSGeog->ellipsoid()->_exportToPROJString(formatter); } else { @@ -8124,7 +8129,7 @@ static void setupPROJGeodeticSourceCRS(io::PROJStringFormatter *formatter, // --------------------------------------------------------------------------- static void setupPROJGeodeticTargetCRS(io::PROJStringFormatter *formatter, - const crs::CRSNNPtr &crs, + const crs::CRSNNPtr &crs, bool addPopV3, const char *trfrm_name) { auto targetCRSGeog = dynamic_cast(crs.get()); if (targetCRSGeog) { @@ -8132,6 +8137,11 @@ static void setupPROJGeodeticTargetCRS(io::PROJStringFormatter *formatter, formatter->setCurrentStepInverted(true); targetCRSGeog->ellipsoid()->_exportToPROJString(formatter); + if (addPopV3) { + formatter->addStep("pop"); + formatter->addParam("v_3"); + } + targetCRSGeog->_exportToPROJString(formatter); } else { auto targetCRSGeod = dynamic_cast(crs.get()); @@ -8223,19 +8233,19 @@ void Transformation::_exportToPROJString( double z = parameterValueNumericAsSI(EPSG_CODE_PARAMETER_Z_AXIS_TRANSLATION); - if (methodEPSGCode == EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D || - methodEPSGCode == EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D) { - formatter->addStep("push"); - formatter->addParam("v_3"); - } + bool addPushPopV3 = + (methodEPSGCode == + EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D || + methodEPSGCode == + EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D || + methodEPSGCode == EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D || + methodEPSGCode == + EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D || + methodEPSGCode == + EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D); - setupPROJGeodeticSourceCRS(formatter, sourceCRS(), "Helmert"); + setupPROJGeodeticSourceCRS(formatter, sourceCRS(), addPushPopV3, + "Helmert"); formatter->addStep("helmert"); formatter->addParam("x", x); @@ -8299,19 +8309,8 @@ void Transformation::_exportToPROJString( } } - setupPROJGeodeticTargetCRS(formatter, targetCRS(), "Helmert"); - - if (methodEPSGCode == EPSG_CODE_METHOD_COORDINATE_FRAME_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_TIME_DEPENDENT_COORDINATE_FRAME_GEOGRAPHIC_2D || - methodEPSGCode == EPSG_CODE_METHOD_POSITION_VECTOR_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_TIME_DEPENDENT_POSITION_VECTOR_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_GEOCENTRIC_TRANSLATION_GEOGRAPHIC_2D) { - formatter->addStep("pop"); - formatter->addParam("v_3"); - } + setupPROJGeodeticTargetCRS(formatter, targetCRS(), addPushPopV3, + "Helmert"); return; } @@ -8359,15 +8358,13 @@ void Transformation::_exportToPROJString( double pz = parameterValueNumericAsSI( EPSG_CODE_PARAMETER_ORDINATE_3_EVAL_POINT); - if (methodEPSGCode == - EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D) { - formatter->addStep("push"); - formatter->addParam("v_3"); - } + bool addPushPopV3 = + (methodEPSGCode == + EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D || + methodEPSGCode == + EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D); - setupPROJGeodeticSourceCRS(formatter, sourceCRS(), + setupPROJGeodeticSourceCRS(formatter, sourceCRS(), addPushPopV3, "Molodensky-Badekas"); formatter->addStep("molobadekas"); @@ -8387,17 +8384,9 @@ void Transformation::_exportToPROJString( formatter->addParam("convention", "coordinate_frame"); } - setupPROJGeodeticTargetCRS(formatter, targetCRS(), + setupPROJGeodeticTargetCRS(formatter, targetCRS(), addPushPopV3, "Molodensky-Badekas"); - if (methodEPSGCode == - EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_PV_GEOGRAPHIC_2D || - methodEPSGCode == - EPSG_CODE_METHOD_MOLODENSKY_BADEKAS_CF_GEOGRAPHIC_2D) { - formatter->addStep("pop"); - formatter->addParam("v_3"); - } - return; } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index f602c7c0..a1608464 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -5102,98 +5102,6 @@ const std::string &PROJStringFormatter::toString() const { } } - // axisswap order=2,1, pop/push v_3, axisswap order=2,1 -> can - // suppress axisswap - if (i + 1 < d->steps_.size() && prevStep.name == "axisswap" && - (curStep.name == "push" || curStep.name == "pop") && - prevStepParamCount == 1 && - prevStep.paramValues[0].equals("order", "2,1") && - curStepParamCount == 1 && curStep.paramValues[0].key == "v_3") { - auto iterNext = iterCur; - ++iterNext; - auto &nextStep = *iterNext; - if (nextStep.name == "axisswap" && - nextStep.paramValues.size() == 1 && - nextStep.paramValues[0].equals("order", "2,1")) { - d->steps_.erase(iterPrev); - d->steps_.erase(iterNext); - changeDone = true; - break; - } - } - - // push v_3, axisswap order=2,1, pop v_3 -> can suppress push/pop - if (i + 1 < d->steps_.size() && prevStep.name == "push" && - prevStepParamCount == 1 && - prevStep.paramValues[0].key == "v_3" && - curStep.name == "axisswap" && curStepParamCount == 1 && - curStep.paramValues[0].equals("order", "2,1")) { - auto iterNext = iterCur; - ++iterNext; - auto &nextStep = *iterNext; - if (nextStep.name == "pop" && - nextStep.paramValues.size() == 1 && - nextStep.paramValues[0].key == "v_3") { - d->steps_.erase(iterPrev); - d->steps_.erase(iterNext); - changeDone = true; - break; - } - } - - // push v_3, unitconvert xy_in xy_out, axisswap order=2,1, pop v_3 - // -> can suppress push/pop - if (i + 2 < d->steps_.size() && prevStep.name == "push" && - prevStepParamCount == 1 && - prevStep.paramValues[0].key == "v_3" && - curStep.name == "unitconvert" && curStepParamCount == 2 && - curStep.paramValues[0].key == "xy_in" && - curStep.paramValues[1].key == "xy_out") { - auto iterNext = iterCur; - ++iterNext; - auto &nextStep = *iterNext; - auto iterNextNext = iterNext; - ++iterNextNext; - auto &nextNextStep = *iterNextNext; - if (nextStep.name == "axisswap" && - nextStep.paramValues.size() == 1 && - nextStep.paramValues[0].equals("order", "2,1") && - nextNextStep.name == "pop" && - nextNextStep.paramValues.size() == 1 && - nextNextStep.paramValues[0].key == "v_3") { - d->steps_.erase(iterPrev); - d->steps_.erase(iterNextNext); - changeDone = true; - break; - } - } - - // unitconvert xy_in=A xy_out=B, pop/push v_3, unitconvert xy_in=B - // xy_out=A -> can suppress unitconvert - if (i + 1 < d->steps_.size() && prevStep.name == "unitconvert" && - (curStep.name == "push" || curStep.name == "pop") && - prevStepParamCount == 2 && - prevStep.paramValues[0].key == "xy_in" && - prevStep.paramValues[1].key == "xy_out" && - curStepParamCount == 1 && curStep.paramValues[0].key == "v_3") { - auto iterNext = iterCur; - ++iterNext; - auto &nextStep = *iterNext; - if (nextStep.name == "unitconvert" && - nextStep.paramValues.size() == 2 && - nextStep.paramValues[0].key == "xy_in" && - nextStep.paramValues[1].key == "xy_out" && - nextStep.paramValues[0].value == - prevStep.paramValues[1].value && - nextStep.paramValues[1].value == - prevStep.paramValues[0].value) { - d->steps_.erase(iterPrev); - d->steps_.erase(iterNext); - changeDone = true; - break; - } - } - // for practical purposes WGS84 and GRS80 ellipsoids are // equivalents (cartesian transform between both lead to differences // of the order of 1e-14 deg..). -- cgit v1.2.3 From 374cc258510428fa3bfb9d8ca61ad7ac83a00db1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 16:13:24 +0100 Subject: CompoundCRS to Geog3DCRS: in synthetised transformation, document in the name we are lacking an ellipsoid height to vertCRS height correction --- src/iso19111/coordinateoperation.cpp | 78 +++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index fdcb6af8..ede6b72e 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -106,7 +106,12 @@ constexpr double UTM_SOUTH_FALSE_NORTHING = 10000000.0; static const std::string INVERSE_OF = "Inverse of "; static const char *NULL_GEOCENTRIC_TRANSLATION = "Null geocentric translation"; static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset"; +static const char *APPROXIMATE_TRANSFORMATION_PREFIX = + " (approximate transformation"; static const char *APPROXIMATE_TRANSFORMATION = " (approximate transformation)"; +static const char *APPROXIMATE_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT = + " (approximate transformation, without ellipsoid height to vertical height " + "correction)"; //! @endcond //! @cond Doxygen_Suppress @@ -5645,7 +5650,9 @@ void Conversion::_exportToPROJString( common::UnitOfMeasure(std::string(), 1.0 / convFactor, common::UnitOfMeasure::Type::LINEAR) .exportToPROJString(); - if (!uom.empty()) { + if (uom == "m") { + // do nothing + } else if (!uom.empty()) { formatter->addStep("unitconvert"); formatter->addParam("z_in", uom); formatter->addParam("z_out", "m"); @@ -8879,7 +8886,9 @@ bool SingleOperation::exportToPROJStringGeneric( common::UnitOfMeasure(std::string(), 1.0 / convFactor, common::UnitOfMeasure::Type::LINEAR) .exportToPROJString(); - if (!uom.empty()) { + if (uom == "m") { + // do nothing + } else if (!uom.empty()) { formatter->addStep("unitconvert"); formatter->addParam("z_in", uom); formatter->addParam("z_out", "m"); @@ -10008,7 +10017,7 @@ struct FilterResults { std::string::npos && name.find(NULL_GEOCENTRIC_TRANSLATION) == std::string::npos && - name.find(APPROXIMATE_TRANSFORMATION) == + name.find(APPROXIMATE_TRANSFORMATION_PREFIX) == std::string::npos) { hasOpThatContainsAreaOfInterest = true; } @@ -10045,7 +10054,7 @@ struct FilterResults { std::string::npos && name.find(NULL_GEOCENTRIC_TRANSLATION) == std::string::npos && - name.find(APPROXIMATE_TRANSFORMATION) == + name.find(APPROXIMATE_TRANSFORMATION_PREFIX) == std::string::npos) { hasOpThatContainsAreaOfInterest = true; } @@ -10147,7 +10156,7 @@ struct FilterResults { const auto stepCount = getStepCount(op); const bool isApprox = - op->nameStr().find(APPROXIMATE_TRANSFORMATION) != + op->nameStr().find(APPROXIMATE_TRANSFORMATION_PREFIX) != std::string::npos; const bool isNullTransformation = op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) != @@ -11668,27 +11677,25 @@ CoordinateOperationFactory::Private::createOperations( vertSrc->coordinateSystem()->axisList()[0]->unit().conversionToSI(); const double convDst = vertDst->coordinateSystem()->axisList()[0]->unit().conversionToSI(); - if (convSrc != convDst) { - const double factor = convSrc / convDst; - auto name = - buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()); - if (!equivalentVDatum) { - name += APPROXIMATE_TRANSFORMATION; - auto conv = Transformation::createChangeVerticalUnit( - util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, - name), - sourceCRS, targetCRS, common::Scale(factor), {}); - res.push_back(conv); - } else { - auto conv = Conversion::createChangeVerticalUnit( - util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, - name), - common::Scale(factor)); - conv->setCRSs(sourceCRS, targetCRS, nullptr); - res.push_back(conv); - } - return res; + + const double factor = convSrc / convDst; + auto name = buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()); + if (!equivalentVDatum) { + name += APPROXIMATE_TRANSFORMATION; + auto conv = Transformation::createChangeVerticalUnit( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + name), + sourceCRS, targetCRS, common::Scale(factor), {}); + res.push_back(conv); + } else if (convSrc != convDst) { + auto conv = Conversion::createChangeVerticalUnit( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + name), + common::Scale(factor)); + conv->setCRSs(sourceCRS, targetCRS, nullptr); + res.push_back(conv); } + return res; } // A bit odd case as we are comparing apples to oranges, but in case @@ -11701,17 +11708,16 @@ CoordinateOperationFactory::Private::createOperations( if (geogAxis.size() == 3) { convDst = geogAxis[2]->unit().conversionToSI(); } - if (convSrc != convDst) { - const double factor = convSrc / convDst; - auto conv = Conversion::createChangeVerticalUnit( - util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, - buildTransfName(sourceCRS->nameStr(), - targetCRS->nameStr())), - common::Scale(factor)); - conv->setCRSs(sourceCRS, targetCRS, nullptr); - res.push_back(conv); - return res; - } + + const double factor = convSrc / convDst; + auto conv = Transformation::createChangeVerticalUnit( + util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, + buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()) + + APPROXIMATE_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT), + sourceCRS, targetCRS, common::Scale(factor), {}); + res.push_back(conv); + return res; } // reverse of previous case -- cgit v1.2.3 From 94578ea8ff38f4bc6b1f6f52b80ecf7359f5dfc2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 18:04:35 +0100 Subject: CoordinateOperation: add a hasBallparkTransformation() method that can be used to know if it includes a very approximative transformation term --- src/4D_api.cpp | 4 +- src/apps/projinfo.cpp | 4 + src/iso19111/c_api.cpp | 30 ++++++ src/iso19111/coordinateoperation.cpp | 174 ++++++++++++++++++++++------------- src/iso19111/crs.cpp | 6 +- src/proj.h | 3 + 6 files changed, 150 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 1b3374f3..4f13f238 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1102,8 +1102,8 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char double north_lat = 0.0; const char* name = proj_get_name(op); - if( name && (strstr(name, "Null geographic offset") || - strstr(name, "Null geocentric translation")) ) + if( name && (strstr(name, "Ballpark geographic offset") || + strstr(name, "Ballpark geocentric translation")) ) { // Skip default transformations } diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 9472d99e..55a8d622 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -508,6 +508,10 @@ static void outputOperationSummary(const CoordinateOperationNNPtr &op) { std::cout << "unknown domain of validity"; } + if (op->hasBallparkTransformation()) { + std::cout << ", has ballpark transformation"; + } + std::cout << std::endl; } diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index b3f200fe..e731615c 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -5754,6 +5754,36 @@ int proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx, // --------------------------------------------------------------------------- +/** \brief Return whether a coordinate operation has a "ballpark" + * transformation, + * that is a very approximate one, due to lack of more accurate transformations. + * + * Typically a null geographic offset between two horizontal datum, or a + * null vertical offset (or limited to unit changes) between two vertical + * datum. Errors of several tens to one hundred meters might be expected, + * compared to more accurate transformations. + * + * @param ctx PROJ context, or NULL for default context + * @param coordoperation Objet of type CoordinateOperation or derived classes + * (must not be NULL) + * @return TRUE or FALSE. + */ + +int proj_coordoperation_has_ballpark_transformation(PJ_CONTEXT *ctx, + const PJ *coordoperation) { + assert(coordoperation); + auto op = dynamic_cast( + coordoperation->iso_obj.get()); + if (!op) { + proj_log_error(ctx, __FUNCTION__, + "Object is not a CoordinateOperation"); + return 0; + } + return op->hasBallparkTransformation(); +} + +// --------------------------------------------------------------------------- + /** \brief Return the number of parameters of a SingleOperation * * @param ctx PROJ context, or NULL for default context diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index ede6b72e..65588923 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -104,14 +104,16 @@ constexpr double UTM_NORTH_FALSE_NORTHING = 0.0; constexpr double UTM_SOUTH_FALSE_NORTHING = 10000000.0; static const std::string INVERSE_OF = "Inverse of "; -static const char *NULL_GEOCENTRIC_TRANSLATION = "Null geocentric translation"; -static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset"; -static const char *APPROXIMATE_TRANSFORMATION_PREFIX = - " (approximate transformation"; -static const char *APPROXIMATE_TRANSFORMATION = " (approximate transformation)"; -static const char *APPROXIMATE_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT = - " (approximate transformation, without ellipsoid height to vertical height " - "correction)"; +static const char *BALLPARK_GEOCENTRIC_TRANSLATION = + "Ballpark geocentric translation"; +static const char *BALLPARK_GEOGRAPHIC_OFFSET = "Ballpark geographic offset"; +static const char *BALLPARK_VERTICAL_TRANSFORMATION_PREFIX = + " (ballpark vertical transformation"; +static const char *BALLPARK_VERTICAL_TRANSFORMATION = + " (ballpark vertical transformation)"; +static const char *BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT = + " (ballpark vertical transformation, without ellipsoid height to vertical " + "height correction)"; //! @endcond //! @cond Doxygen_Suppress @@ -519,6 +521,7 @@ struct CoordinateOperation::Private { crs::CRSPtr interpolationCRS_{}; util::optional sourceCoordinateEpoch_{}; util::optional targetCoordinateEpoch_{}; + bool hasBallparkTransformation_ = false; // do not set this for a ProjectedCRS.definingConversion struct CRSStrongRef { @@ -729,6 +732,27 @@ bool CoordinateOperation::isPROJInstanciable( // --------------------------------------------------------------------------- +/** \brief Return whether a coordinate operation has a "ballpark" + * transformation, + * that is a very approximate one, due to lack of more accurate transformations. + * + * Typically a null geographic offset between two horizontal datum, or a + * null vertical offset (or limited to unit changes) between two vertical + * datum. Errors of several tens to one hundred meters might be expected, + * compared to more accurate transformations. + */ +bool CoordinateOperation::hasBallparkTransformation() const { + return d->hasBallparkTransformation_; +} + +// --------------------------------------------------------------------------- + +void CoordinateOperation::setHasBallparkTransformation(bool b) { + d->hasBallparkTransformation_ = b; +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress struct OperationMethod::Private { util::optional formula_{}; @@ -1529,11 +1553,12 @@ static SingleOperationNNPtr createPROJBased( const util::PropertyMap &properties, const io::IPROJStringExportableNNPtr &projExportable, const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, - const std::vector &accuracies = - std::vector()) { + const std::vector &accuracies, + bool hasBallparkTransformation) { return util::nn_static_pointer_cast( PROJBasedOperation::create(properties, projExportable, false, sourceCRS, - targetCRS, accuracies)); + targetCRS, accuracies, + hasBallparkTransformation)); } //! @endcond @@ -6149,6 +6174,11 @@ TransformationNNPtr Transformation::create( accuracies); conv->assignSelf(conv); conv->setProperties(properties); + std::string name; + if (properties.getStringValue(common::IdentifiedObject::NAME_KEY, name) && + ci_find(name, "ballpark") != std::string::npos) { + conv->setHasBallparkTransformation(true); + } return conv; } @@ -7155,10 +7185,10 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom, // Forge a name for the inverse, either from the forward name, or // from the source and target CRS names const char *opType; - if (starts_with(forwardName, NULL_GEOCENTRIC_TRANSLATION)) { - opType = NULL_GEOCENTRIC_TRANSLATION; - } else if (starts_with(forwardName, NULL_GEOGRAPHIC_OFFSET)) { - opType = NULL_GEOGRAPHIC_OFFSET; + if (starts_with(forwardName, BALLPARK_GEOCENTRIC_TRANSLATION)) { + opType = BALLPARK_GEOCENTRIC_TRANSLATION; + } else if (starts_with(forwardName, BALLPARK_GEOGRAPHIC_OFFSET)) { + opType = BALLPARK_GEOGRAPHIC_OFFSET; } else if (dynamic_cast(op) || starts_with(forwardName, "Transformation from ")) { opType = "Transformation"; @@ -9188,7 +9218,9 @@ CoordinateOperationNNPtr ConcatenatedOperation::createComputeMetadata( } std::vector flattenOps; + bool hasBallparkTransformation = false; for (const auto &subOp : operationsIn) { + hasBallparkTransformation |= subOp->hasBallparkTransformation(); auto subOpConcat = dynamic_cast(subOp.get()); if (subOpConcat) { @@ -9228,6 +9260,7 @@ CoordinateOperationNNPtr ConcatenatedOperation::createComputeMetadata( } auto op = create(properties, flattenOps, accuracies); + op->setHasBallparkTransformation(hasBallparkTransformation); op->d->computedName_ = true; return op; } @@ -10012,13 +10045,7 @@ struct FilterResults { bool extentContains = extent->contains(NN_NO_CHECK(areaOfInterest)); if (extentContains) { - const auto &name = op->nameStr(); - if (name.find(NULL_GEOGRAPHIC_OFFSET) == - std::string::npos && - name.find(NULL_GEOCENTRIC_TRANSLATION) == - std::string::npos && - name.find(APPROXIMATE_TRANSFORMATION_PREFIX) == - std::string::npos) { + if (!op->hasBallparkTransformation()) { hasOpThatContainsAreaOfInterest = true; } } @@ -10049,13 +10076,7 @@ struct FilterResults { !targetCRSExtent || extent->contains(NN_NO_CHECK(targetCRSExtent)); if (extentContainsSource && extentContainsTarget) { - const auto &name = op->nameStr(); - if (name.find(NULL_GEOGRAPHIC_OFFSET) == - std::string::npos && - name.find(NULL_GEOCENTRIC_TRANSLATION) == - std::string::npos && - name.find(APPROXIMATE_TRANSFORMATION_PREFIX) == - std::string::npos) { + if (!op->hasBallparkTransformation()) { hasOpThatContainsAreaOfInterest = true; } } @@ -10156,12 +10177,12 @@ struct FilterResults { const auto stepCount = getStepCount(op); const bool isApprox = - op->nameStr().find(APPROXIMATE_TRANSFORMATION_PREFIX) != + op->nameStr().find(BALLPARK_VERTICAL_TRANSFORMATION_PREFIX) != std::string::npos; const bool isNullTransformation = - op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) != + op->nameStr().find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || - op->nameStr().find(NULL_GEOCENTRIC_TRANSLATION) != + op->nameStr().find(BALLPARK_GEOCENTRIC_TRANSLATION) != std::string::npos; map[op.get()] = PrecomputedOpCharacteristics( area, getAccuracy(op), hasGrids, gridsAvailable, gridsKnown, @@ -10177,14 +10198,16 @@ struct FilterResults { void removeSyntheticNullTransforms() { // If we have more than one result, and than the last result is the - // default "Null geographic offset" or "Null geocentric translation" + // default "Ballpark geographic offset" or "Ballpark geocentric + // translation" // operations we have synthetized, and that at least one operation // has the desired area of interest, remove it as // all previous results are necessarily better if (hasOpThatContainsAreaOfInterest && res.size() > 1) { const std::string &name = res.back()->nameStr(); - if (name.find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos || - name.find(NULL_GEOCENTRIC_TRANSLATION) != std::string::npos) { + if (name.find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || + name.find(BALLPARK_GEOCENTRIC_TRANSLATION) != + std::string::npos) { std::vector resTemp; for (size_t i = 0; i < res.size() - 1; i++) { resTemp.emplace_back(res[i]); @@ -10597,9 +10620,9 @@ static std::vector findsOpsInRegistryWithIntermediate( //! @cond Doxygen_Suppress static TransformationNNPtr -createNullGeographicOffset(const crs::CRSNNPtr &sourceCRS, - const crs::CRSNNPtr &targetCRS) { - std::string name(NULL_GEOGRAPHIC_OFFSET); +createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS, + const crs::CRSNNPtr &targetCRS) { + std::string name(BALLPARK_GEOGRAPHIC_OFFSET); name += " from "; name += sourceCRS->nameStr(); name += " to "; @@ -10790,7 +10813,7 @@ createGeodToGeodPROJBased(const crs::CRSNNPtr &geodSrc, auto properties = util::PropertyMap().set( common::IdentifiedObject::NAME_KEY, buildTransfName(geodSrc->nameStr(), geodDst->nameStr())); - return createPROJBased(properties, exportable, geodSrc, geodDst); + return createPROJBased(properties, exportable, geodSrc, geodDst, {}, false); } // --------------------------------------------------------------------------- @@ -10827,7 +10850,9 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased( } return createPROJBased(properties, exportable, sourceCRS, targetCRS, - accuracies); + accuracies, + horizTransform->hasBallparkTransformation() || + verticalTransform->hasBallparkTransformation()); } // --------------------------------------------------------------------------- @@ -10852,6 +10877,10 @@ static CoordinateOperationNNPtr createHorizVerticalHorizPROJBased( : std::vector{opSrcCRSToGeogCRS, verticalTransform, opGeogCRStoDstCRS}; + bool hasBallparkTransformation = false; + for (const auto &op : ops) { + hasBallparkTransformation |= op->hasBallparkTransformation(); + } auto extent = getExtent(ops, true, dummy); auto properties = util::PropertyMap(); properties.set(common::IdentifiedObject::NAME_KEY, @@ -10870,7 +10899,7 @@ static CoordinateOperationNNPtr createHorizVerticalHorizPROJBased( } return createPROJBased(properties, exportable, sourceCRS, targetCRS, - accuracies); + accuracies, hasBallparkTransformation); } //! @endcond @@ -10926,6 +10955,11 @@ CoordinateOperationFactory::Private::createOperationsGeogToGeog( std::string name(buildTransfName(geogSrc->nameStr(), geogDst->nameStr())); + const bool sameDatum = + geogSrc->datum() != nullptr && geogDst->datum() != nullptr && + geogSrc->datum()->_isEquivalentTo( + geogDst->datum().get(), util::IComparable::Criterion::EQUIVALENT); + // Do they differ by vertical units ? if (vconvSrc != vconvDst && geogSrc->ellipsoid()->_isEquivalentTo( @@ -10941,18 +10975,19 @@ CoordinateOperationFactory::Private::createOperationsGeogToGeog( name), common::Scale(factor)); conv->setCRSs(sourceCRS, targetCRS, nullptr); + conv->setHasBallparkTransformation(!sameDatum); res.push_back(conv); return res; } else { - res.emplace_back(createGeodToGeodPROJBased(sourceCRS, targetCRS)); + auto op = createGeodToGeodPROJBased(sourceCRS, targetCRS); + op->setHasBallparkTransformation(!sameDatum); + res.emplace_back(op); return res; } } // Do the CRS differ only by their axis order ? - if (geogSrc->datum() != nullptr && geogDst->datum() != nullptr && - geogSrc->datum()->_isEquivalentTo( - geogDst->datum().get(), util::IComparable::Criterion::EQUIVALENT) && + if (sameDatum && !srcCS->_isEquivalentTo(dstCS.get(), util::IComparable::Criterion::EQUIVALENT)) { auto srcOrder = srcCS->axisOrder(); @@ -11013,7 +11048,8 @@ CoordinateOperationFactory::Private::createOperationsGeogToGeog( metadata::Extent::WORLD), datum, dstCS)); - steps.emplace_back(createNullGeographicOffset(sourceCRS, interm_crs)); + steps.emplace_back( + createBallparkGeographicOffset(sourceCRS, interm_crs)); steps.emplace_back(Transformation::createLongitudeRotation( util::PropertyMap() @@ -11048,15 +11084,17 @@ CoordinateOperationFactory::Private::createOperationsGeogToGeog( metadata::Extent::WORLD), sourceCRS, interm_crs, offset_pm)); steps.emplace_back( - createNullGeographicOffset(interm_crs, targetCRS)); + createBallparkGeographicOffset(interm_crs, targetCRS)); } else { steps.emplace_back( - createNullGeographicOffset(sourceCRS, targetCRS)); + createBallparkGeographicOffset(sourceCRS, targetCRS)); } } - res.emplace_back(ConcatenatedOperation::createComputeMetadata( - steps, !allowEmptyIntersection)); + auto op = ConcatenatedOperation::createComputeMetadata( + steps, !allowEmptyIntersection); + op->setHasBallparkTransformation(!sameDatum); + res.emplace_back(op); return res; } @@ -11108,8 +11146,8 @@ findCandidateGeodCRSForDatum(const io::AuthorityFactoryPtr &authFactory, static bool isNullTransformation(const std::string &name) { - return starts_with(name, NULL_GEOCENTRIC_TRANSLATION) || - starts_with(name, NULL_GEOGRAPHIC_OFFSET); + return starts_with(name, BALLPARK_GEOCENTRIC_TRANSLATION) || + starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET); } // --------------------------------------------------------------------------- @@ -11227,9 +11265,9 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( // --------------------------------------------------------------------------- static CoordinateOperationNNPtr -createNullGeocentricTranslation(const crs::CRSNNPtr &sourceCRS, - const crs::CRSNNPtr &targetCRS) { - std::string name(NULL_GEOCENTRIC_TRANSLATION); +createBallparkGeocentricTranslation(const crs::CRSNNPtr &sourceCRS, + const crs::CRSNNPtr &targetCRS) { + std::string name(BALLPARK_GEOCENTRIC_TRANSLATION); name += " from "; name += sourceCRS->nameStr(); name += " to "; @@ -11451,7 +11489,7 @@ CoordinateOperationFactory::Private::createOperations( util::nn_dynamic_pointer_cast( geodSrc->coordinateSystem())))); auto opFirst = - createNullGeocentricTranslation(sourceCRS, interm_crs); + createBallparkGeocentricTranslation(sourceCRS, interm_crs); auto opSecond = createGeographicGeocentric(interm_crs, targetCRS); res.emplace_back(ConcatenatedOperation::createComputeMetadata( @@ -11466,7 +11504,7 @@ CoordinateOperationFactory::Private::createOperations( if (isSrcGeocentric && isTargetGeocentric) { res.emplace_back( - createNullGeocentricTranslation(sourceCRS, targetCRS)); + createBallparkGeocentricTranslation(sourceCRS, targetCRS)); return res; } @@ -11681,11 +11719,12 @@ CoordinateOperationFactory::Private::createOperations( const double factor = convSrc / convDst; auto name = buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()); if (!equivalentVDatum) { - name += APPROXIMATE_TRANSFORMATION; + name += BALLPARK_VERTICAL_TRANSFORMATION; auto conv = Transformation::createChangeVerticalUnit( util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, name), sourceCRS, targetCRS, common::Scale(factor), {}); + conv->setHasBallparkTransformation(true); res.push_back(conv); } else if (convSrc != convDst) { auto conv = Conversion::createChangeVerticalUnit( @@ -11714,8 +11753,9 @@ CoordinateOperationFactory::Private::createOperations( util::PropertyMap().set( common::IdentifiedObject::NAME_KEY, buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()) + - APPROXIMATE_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT), + BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT), sourceCRS, targetCRS, common::Scale(factor), {}); + conv->setHasBallparkTransformation(true); res.push_back(conv); return res; } @@ -12022,7 +12062,8 @@ PROJBasedOperationNNPtr PROJBasedOperation::create( const util::PropertyMap &properties, const io::IPROJStringExportableNNPtr &projExportable, bool inverse, const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, - const std::vector &accuracies) { + const std::vector &accuracies, + bool hasBallparkTransformation) { auto formatter = io::PROJStringFormatter::create(); if (inverse) { @@ -12048,6 +12089,7 @@ PROJBasedOperationNNPtr PROJBasedOperation::create( op->setAccuracies(accuracies); op->projStringExportable_ = projExportable.as_nullable(); op->inverse_ = inverse; + op->setHasBallparkTransformation(hasBallparkTransformation); return op; } @@ -12061,7 +12103,7 @@ CoordinateOperationNNPtr PROJBasedOperation::inverse() const { createPropertiesForInverse(this, false, false), NN_NO_CHECK(projStringExportable_), !inverse_, NN_NO_CHECK(targetCRS()), NN_NO_CHECK(sourceCRS()), - coordinateOperationAccuracies())); + coordinateOperationAccuracies(), hasBallparkTransformation())); } auto formatter = io::PROJStringFormatter::create(); @@ -12074,11 +12116,11 @@ CoordinateOperationNNPtr PROJBasedOperation::inverse() const { } formatter->stopInversion(); - return util::nn_static_pointer_cast( - PROJBasedOperation::create( - createPropertiesForInverse(this, false, false), - formatter->toString(), targetCRS(), sourceCRS(), - coordinateOperationAccuracies())); + auto op = PROJBasedOperation::create( + createPropertiesForInverse(this, false, false), formatter->toString(), + targetCRS(), sourceCRS(), coordinateOperationAccuracies()); + op->setHasBallparkTransformation(hasBallparkTransformation()); + return util::nn_static_pointer_cast(op); } // --------------------------------------------------------------------------- diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 01a588e3..aabb15a1 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -453,7 +453,7 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible( auto transf = util::nn_dynamic_pointer_cast( op); - if (transf && !starts_with(transf->nameStr(), "Null geo")) { + if (transf && !starts_with(transf->nameStr(), "Ballpark geo")) { try { transf->getTOWGS84Parameters(); } catch (const std::exception &) { @@ -486,7 +486,7 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible( operation::Transformation>(subops[1]); if (transf && !starts_with(transf->nameStr(), - "Null geo")) { + "Ballpark geo")) { try { transf->getTOWGS84Parameters(); } catch (const std::exception &) { @@ -3855,7 +3855,7 @@ BoundCRS::_identify(const io::AuthorityFactoryPtr &authorityFactory) const { for (const auto &op : ops) { std::string opTransfPROJString; bool opTransfPROJStringValid = false; - if (op->nameStr().find("Null geographic") == 0) { + if (op->nameStr().find("Ballpark geographic") == 0) { if (isTOWGS84Compatible()) { auto params = transformation()->getTOWGS84Parameters(); diff --git a/src/proj.h b/src/proj.h index af22c341..edbbd798 100644 --- a/src/proj.h +++ b/src/proj.h @@ -1002,6 +1002,9 @@ int PROJ_DLL proj_coordoperation_get_method_info(PJ_CONTEXT *ctx, int PROJ_DLL proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx, const PJ *coordoperation); +int PROJ_DLL proj_coordoperation_has_ballpark_transformation(PJ_CONTEXT *ctx, + const PJ *coordoperation); + int PROJ_DLL proj_coordoperation_get_param_count(PJ_CONTEXT *ctx, const PJ *coordoperation); -- cgit v1.2.3 From 69ef7449f5f26453a8b6cab1ba02cb870055615f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 20:42:26 +0100 Subject: typo fixes: s/Explictly/Explicitly/ and s/instanciat/instantiat/ --- src/apps/cs2cs.cpp | 8 ++++---- src/apps/projinfo.cpp | 10 +++++----- src/iso19111/c_api.cpp | 8 ++++---- src/iso19111/coordinateoperation.cpp | 2 +- src/iso19111/factory.cpp | 2 +- src/proj.h | 2 +- src/proj_symbol_rename.h | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 150548c5..dafd06f8 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -206,10 +206,10 @@ static void process(FILE *fid) } /************************************************************************/ -/* instanciate_crs() */ +/* instantiate_crs() */ /************************************************************************/ -static PJ *instanciate_crs(const std::string &definition, +static PJ *instantiate_crs(const std::string &definition, bool &isGeog, double &toRadians, bool &isLatFirst) { PJ *crs = proj_create(nullptr, @@ -541,7 +541,7 @@ int main(int argc, char **argv) { PJ *src = nullptr; if (!fromStr.empty()) { bool ignored; - src = instanciate_crs(fromStr, srcIsGeog, + src = instantiate_crs(fromStr, srcIsGeog, srcToRadians, ignored); if (!src) { emess(3, "cannot instantiate source coordinate system"); @@ -550,7 +550,7 @@ int main(int argc, char **argv) { PJ *dst = nullptr; if (!toStr.empty()) { - dst = instanciate_crs(toStr, destIsGeog, + dst = instantiate_crs(toStr, destIsGeog, destToRadians, destIsLatLong); if (!dst) { emess(3, "cannot instantiate target coordinate system"); diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 55a8d622..094587e2 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -521,7 +521,7 @@ static void outputOperations( DatabaseContextPtr dbContext, const std::string &sourceCRSStr, const std::string &targetCRSStr, const ExtentPtr &bboxFilter, CoordinateOperationContext::SpatialCriterion spatialCriterion, - bool spatialCriterionExplictlySpecified, + bool spatialCriterionExplicitlySpecified, CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse, CoordinateOperationContext::GridAvailabilityUse gridAvailabilityUse, CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, @@ -565,7 +565,7 @@ static void outputOperations( ctxt->setDiscardSuperseded(!showSuperseded); list = CoordinateOperationFactory::create()->createOperations( NN_NO_CHECK(sourceCRS), NN_NO_CHECK(targetCRS), ctxt); - if (!spatialCriterionExplictlySpecified && + if (!spatialCriterionExplicitlySpecified && spatialCriterion == CoordinateOperationContext::SpatialCriterion:: STRICT_CONTAINMENT) { try { @@ -639,7 +639,7 @@ int main(int argc, char **argv) { bool summary = false; ExtentPtr bboxFilter = nullptr; std::string area; - bool spatialCriterionExplictlySpecified = false; + bool spatialCriterionExplicitlySpecified = false; CoordinateOperationContext::SpatialCriterion spatialCriterion = CoordinateOperationContext::SpatialCriterion::STRICT_CONTAINMENT; CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse = @@ -795,7 +795,7 @@ int main(int argc, char **argv) { } else if (arg == "--spatial-test" && i + 1 < argc) { i++; std::string value(argv[i]); - spatialCriterionExplictlySpecified = true; + spatialCriterionExplicitlySpecified = true; if (ci_equal(value, "contains")) { spatialCriterion = CoordinateOperationContext:: SpatialCriterion::STRICT_CONTAINMENT; @@ -1084,7 +1084,7 @@ int main(int argc, char **argv) { outputOperations( dbContext, sourceCRSStr, targetCRSStr, bboxFilter, spatialCriterion, - spatialCriterionExplictlySpecified, crsExtentUse, + spatialCriterionExplicitlySpecified, crsExtentUse, gridAvailabilityUse, allowUseIntermediateCRS, pivots, authority, usePROJGridAlternatives, showSuperseded, outputOpt, summary); } diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index e731615c..f7dcd354 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1950,7 +1950,7 @@ void proj_string_list_destroy(PROJ_STRING_LIST list) { // --------------------------------------------------------------------------- -/** \brief Instanciate a default set of parameters to be used by +/** \brief Instantiate a default set of parameters to be used by * proj_get_crs_list(). * * @return a new object to free with proj_get_crs_list_parameters_destroy() */ @@ -1987,7 +1987,7 @@ void proj_get_crs_list_parameters_destroy(PROJ_CRS_LIST_PARAMETERS *params) { * entry is NULL. This array should be freed with proj_crs_info_list_destroy() * * When no filter parameters are set, this is functionnaly equivalent to - * proj_get_crs_info_list_from_database(), instanciating a PJ* object for each + * proj_get_crs_info_list_from_database(), instantiating a PJ* object for each * of the proj_create_from_database() and retrieving information with the * various getters. However this function will be much faster. * @@ -5734,7 +5734,7 @@ PJ *proj_create_conversion_equal_earth(PJ_CONTEXT *ctx, double center_long, * @return TRUE or FALSE. */ -int proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx, +int proj_coordoperation_is_instantiable(PJ_CONTEXT *ctx, const PJ *coordoperation) { assert(coordoperation); auto op = dynamic_cast( @@ -5746,7 +5746,7 @@ int proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx, } auto dbContext = getDBcontextNoException(ctx, __FUNCTION__); try { - return op->isPROJInstanciable(dbContext) ? 1 : 0; + return op->isPROJInstantiable(dbContext) ? 1 : 0; } catch (const std::exception &) { return 0; } diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 65588923..224b19ef 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -715,7 +715,7 @@ void CoordinateOperation::setAccuracies( * a PROJ pipeline, checking in particular that referenced grids are * available. */ -bool CoordinateOperation::isPROJInstanciable( +bool CoordinateOperation::isPROJInstantiable( const io::DatabaseContextPtr &databaseContext) const { try { exportToPROJString(io::PROJStringFormatter::create().get()); diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 81abcdf1..bafa1b5d 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -3873,7 +3873,7 @@ AuthorityFactory::getDescriptionText(const std::string &code) const { /** \brief Return a list of information on CRS objects * * This is functionnaly equivalent of listing the codes from an authority, - * instanciating + * instantiating * a CRS object for each of them and getting the information from this CRS * object, but this implementation has much less overhead. * diff --git a/src/proj.h b/src/proj.h index edbbd798..1f71e115 100644 --- a/src/proj.h +++ b/src/proj.h @@ -999,7 +999,7 @@ int PROJ_DLL proj_coordoperation_get_method_info(PJ_CONTEXT *ctx, const char **out_method_auth_name, const char **out_method_code); -int PROJ_DLL proj_coordoperation_is_instanciable(PJ_CONTEXT *ctx, +int PROJ_DLL proj_coordoperation_is_instantiable(PJ_CONTEXT *ctx, const PJ *coordoperation); int PROJ_DLL proj_coordoperation_has_ballpark_transformation(PJ_CONTEXT *ctx, diff --git a/src/proj_symbol_rename.h b/src/proj_symbol_rename.h index 0ce342fd..b6e887ca 100644 --- a/src/proj_symbol_rename.h +++ b/src/proj_symbol_rename.h @@ -115,7 +115,7 @@ #define proj_coordoperation_get_param_count internal_proj_coordoperation_get_param_count #define proj_coordoperation_get_param_index internal_proj_coordoperation_get_param_index #define proj_coordoperation_get_towgs84_values internal_proj_coordoperation_get_towgs84_values -#define proj_coordoperation_is_instanciable internal_proj_coordoperation_is_instanciable +#define proj_coordoperation_is_instantiable internal_proj_coordoperation_is_instantiable #define proj_create internal_proj_create #define proj_create_argv internal_proj_create_argv #define proj_create_cartesian_2D_cs internal_proj_create_cartesian_2D_cs -- cgit v1.2.3 From 5c691e7fec7c244b1a1a6b5ef97df2cf69e403df Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 21 Feb 2019 01:04:55 +0100 Subject: projinfo: add information about missing grids --- src/apps/projinfo.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 094587e2..7e401887 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -464,11 +464,42 @@ static void outputObject( } } } + + auto op = dynamic_cast(obj.get()); + if (op && dbContext && getenv("PROJINFO_NO_GRID_CHECK") == nullptr) { + try { + auto setGrids = op->gridsNeeded(dbContext); + bool firstWarning = true; + for (const auto &grid : setGrids) { + if (!grid.available) { + if (firstWarning) { + std::cout << std::endl; + firstWarning = false; + } + std::cout << "Grid " << grid.shortName + << " needed but not found on the system."; + if (!grid.packageName.empty()) { + std::cout << " Can be obtained from the " + << grid.packageName << " package"; + if (!grid.url.empty()) { + std::cout << " at " << grid.url; + } + } else if (!grid.url.empty()) { + std::cout << " Can be obtained at " << grid.url; + } + std::cout << std::endl; + } + } + } catch (const std::exception &e) { + std::cerr << "Error in gridsNeeded(): " << e.what() << std::endl; + } + } } // --------------------------------------------------------------------------- -static void outputOperationSummary(const CoordinateOperationNNPtr &op) { +static void outputOperationSummary(const CoordinateOperationNNPtr &op, + const DatabaseContextPtr &dbContext) { auto ids = op->identifiers(); if (!ids.empty()) { std::cout << *(ids[0]->codeSpace()) << ":" << ids[0]->code(); @@ -512,6 +543,18 @@ static void outputOperationSummary(const CoordinateOperationNNPtr &op) { std::cout << ", has ballpark transformation"; } + if (dbContext && getenv("PROJINFO_NO_GRID_CHECK") == nullptr) { + try { + auto setGrids = op->gridsNeeded(dbContext); + for (const auto &grid : setGrids) { + if (!grid.available) { + std::cout << ", at least one grid missing"; + break; + } + } + } catch (const std::exception &) { + } + } std::cout << std::endl; } @@ -598,7 +641,7 @@ static void outputOperations( } if (summary) { for (const auto &op : list) { - outputOperationSummary(op); + outputOperationSummary(op, dbContext); } } else { bool first = true; @@ -613,7 +656,7 @@ static void outputOperations( "\xC2\xB0" << (i + 1) << ":" << std::endl << std::endl; - outputOperationSummary(op); + outputOperationSummary(op, dbContext); std::cout << std::endl; outputObject(dbContext, op, allowUseIntermediateCRS, outputOpt); } -- cgit v1.2.3 From 34168532d3f3773e1afa2e560bdfba9bd369a0aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 21 Feb 2019 12:47:38 +0100 Subject: Geog2D+Height -> Geog3D of same datum: avoid inserting a useless ballpark horizontal transformation --- src/iso19111/coordinateoperation.cpp | 70 +++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 224b19ef..6e2d7f4f 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -10829,30 +10829,58 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased( auto exportable = util::nn_make_shared( horizTransform, verticalTransform, geogDst); - bool dummy = false; - auto ops = std::vector{horizTransform, - verticalTransform}; - auto extent = getExtent(ops, true, dummy); - auto properties = util::PropertyMap(); - properties.set(common::IdentifiedObject::NAME_KEY, - computeConcatenatedName(ops)); - - if (extent) { - properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, - NN_NO_CHECK(extent)); + bool horizTransformIsNoOp = horizTransform->sourceCRS()->_isEquivalentTo( + horizTransform->targetCRS().get()); + if (!horizTransformIsNoOp) { + const crs::GeographicCRS *geogSrc = + dynamic_cast( + horizTransform->sourceCRS().get()); + if (geogSrc) { + horizTransformIsNoOp = + geogSrc->is2DPartOf3D(NN_NO_CHECK(geogDst.get())); + } } - std::vector accuracies; - const double accuracy = getAccuracy(ops); - if (accuracy >= 0.0) { - accuracies.emplace_back( - metadata::PositionalAccuracy::create(toString(accuracy))); - } + if (horizTransformIsNoOp) { + auto properties = util::PropertyMap(); + properties.set(common::IdentifiedObject::NAME_KEY, + verticalTransform->nameStr()); + bool dummy = false; + auto extent = getExtent(verticalTransform, true, dummy); + if (extent) { + properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + NN_NO_CHECK(extent)); + } + return createPROJBased( + properties, exportable, sourceCRS, targetCRS, + verticalTransform->coordinateOperationAccuracies(), + verticalTransform->hasBallparkTransformation()); + } else { + bool dummy = false; + auto ops = std::vector{horizTransform, + verticalTransform}; + auto extent = getExtent(ops, true, dummy); + auto properties = util::PropertyMap(); + properties.set(common::IdentifiedObject::NAME_KEY, + computeConcatenatedName(ops)); - return createPROJBased(properties, exportable, sourceCRS, targetCRS, - accuracies, - horizTransform->hasBallparkTransformation() || - verticalTransform->hasBallparkTransformation()); + if (extent) { + properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + NN_NO_CHECK(extent)); + } + + std::vector accuracies; + const double accuracy = getAccuracy(ops); + if (accuracy >= 0.0) { + accuracies.emplace_back( + metadata::PositionalAccuracy::create(toString(accuracy))); + } + + return createPROJBased( + properties, exportable, sourceCRS, targetCRS, accuracies, + horizTransform->hasBallparkTransformation() || + verticalTransform->hasBallparkTransformation()); + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 287230f86d89a26574c777bb5e5b498084a84897 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 21 Feb 2019 13:48:28 +0100 Subject: Transformation: reintroduce the term of 'Null geographic offset' for transformations between geographic CRS of same datum (typically 3D to 2D) --- src/iso19111/coordinateoperation.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 6e2d7f4f..7b0adc6f 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -106,6 +106,7 @@ constexpr double UTM_SOUTH_FALSE_NORTHING = 10000000.0; static const std::string INVERSE_OF = "Inverse of "; static const char *BALLPARK_GEOCENTRIC_TRANSLATION = "Ballpark geocentric translation"; +static const char *NULL_GEOGRAPHIC_OFFSET = "Null geographic offset"; static const char *BALLPARK_GEOGRAPHIC_OFFSET = "Ballpark geographic offset"; static const char *BALLPARK_VERTICAL_TRANSFORMATION_PREFIX = " (ballpark vertical transformation"; @@ -7189,6 +7190,8 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom, opType = BALLPARK_GEOCENTRIC_TRANSLATION; } else if (starts_with(forwardName, BALLPARK_GEOGRAPHIC_OFFSET)) { opType = BALLPARK_GEOGRAPHIC_OFFSET; + } else if (starts_with(forwardName, NULL_GEOGRAPHIC_OFFSET)) { + opType = NULL_GEOGRAPHIC_OFFSET; } else if (dynamic_cast(op) || starts_with(forwardName, "Transformation from ")) { opType = "Transformation"; @@ -10182,6 +10185,8 @@ struct FilterResults { const bool isNullTransformation = op->nameStr().find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || + op->nameStr().find(NULL_GEOGRAPHIC_OFFSET) != + std::string::npos || op->nameStr().find(BALLPARK_GEOCENTRIC_TRANSLATION) != std::string::npos; map[op.get()] = PrecomputedOpCharacteristics( @@ -10206,6 +10211,7 @@ struct FilterResults { if (hasOpThatContainsAreaOfInterest && res.size() > 1) { const std::string &name = res.back()->nameStr(); if (name.find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || + name.find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos || name.find(BALLPARK_GEOCENTRIC_TRANSLATION) != std::string::npos) { std::vector resTemp; @@ -10622,7 +10628,18 @@ static std::vector findsOpsInRegistryWithIntermediate( static TransformationNNPtr createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS) { - std::string name(BALLPARK_GEOGRAPHIC_OFFSET); + + const crs::GeographicCRS *geogSrc = + dynamic_cast(sourceCRS.get()); + const crs::GeographicCRS *geogDst = + dynamic_cast(targetCRS.get()); + const bool isSameDatum = + geogSrc && geogDst && geogSrc->datum() && geogDst->datum() && + geogSrc->datum()->_isEquivalentTo( + geogDst->datum().get(), util::IComparable::Criterion::EQUIVALENT); + + std::string name(isSameDatum ? NULL_GEOGRAPHIC_OFFSET + : BALLPARK_GEOGRAPHIC_OFFSET); name += " from "; name += sourceCRS->nameStr(); name += " to "; @@ -10641,6 +10658,12 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS, sameExtent ? NN_NO_CHECK(sourceCRSExtent) : metadata::Extent::WORLD); const common::Angle angle0(0); + + std::vector accuracies; + if (isSameDatum) { + accuracies.emplace_back(metadata::PositionalAccuracy::create("0")); + } + if (dynamic_cast(sourceCRS.get()) ->coordinateSystem() ->axisList() @@ -10650,10 +10673,11 @@ createBallparkGeographicOffset(const crs::CRSNNPtr &sourceCRS, ->axisList() .size() == 3) { return Transformation::createGeographic3DOffsets( - map, sourceCRS, targetCRS, angle0, angle0, common::Length(0), {}); + map, sourceCRS, targetCRS, angle0, angle0, common::Length(0), + accuracies); } else { return Transformation::createGeographic2DOffsets( - map, sourceCRS, targetCRS, angle0, angle0, {}); + map, sourceCRS, targetCRS, angle0, angle0, accuracies); } } //! @endcond @@ -11175,7 +11199,8 @@ findCandidateGeodCRSForDatum(const io::AuthorityFactoryPtr &authFactory, static bool isNullTransformation(const std::string &name) { return starts_with(name, BALLPARK_GEOCENTRIC_TRANSLATION) || - starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET); + starts_with(name, BALLPARK_GEOGRAPHIC_OFFSET) || + starts_with(name, NULL_GEOGRAPHIC_OFFSET); } // --------------------------------------------------------------------------- -- cgit v1.2.3 From d775b0b07bf8b7f3c78ec259238265d15abac224 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 23 Feb 2019 15:16:56 +0100 Subject: Doc: add minimal documentation for sch projection --- src/projections/sch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/sch.cpp b/src/projections/sch.cpp index f4c66688..c6fb6145 100644 --- a/src/projections/sch.cpp +++ b/src/projections/sch.cpp @@ -215,7 +215,7 @@ PJ *PROJECTION(sch) { return pj_default_destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } - /* Check if peg latitude is defined */ + /* Check if peg heading is defined */ if (pj_param(P->ctx, P->params, "tphdg_0").i) Q->phdg = pj_param(P->ctx, P->params, "rphdg_0").f; else { -- cgit v1.2.3 From 246ee8c20e0501ef50148db6f2abb9805b9c8a0a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Feb 2019 12:01:06 +0100 Subject: jniproj.cpp: fix compiler warning --- src/jniproj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/jniproj.cpp b/src/jniproj.cpp index 59b5b2a0..6f441529 100644 --- a/src/jniproj.cpp +++ b/src/jniproj.cpp @@ -279,7 +279,7 @@ JNIEXPORT jcharArray JNICALL Java_org_proj4_PJ_getAxisDirections { PJ *pj = getPJ(env, object); if (pj) { - int length = strlen(pj->axis); + int length = static_cast(strlen(pj->axis)); jcharArray array = env->NewCharArray(length); if (array) { jchar* axis = env->GetCharArrayElements(array, nullptr); -- cgit v1.2.3 From 22a786693f66c815220861f15fd041584d32a1f1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Feb 2019 12:06:58 +0100 Subject: ParameterValue::_exportToWKT(): fix null pointer dereference with -D_GLIBCXX_ASSERTIONS on WKT with PARAMETERFILE (fixes #1290) --- src/iso19111/coordinateoperation.cpp | 85 +++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 7b0adc6f..fbb67e6b 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -2156,52 +2156,55 @@ void ParameterValue::_exportToWKT(io::WKTFormatter *formatter) const { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; const auto &l_type = type(); - const auto &l_value = value(); - if (formatter->abridgedTransformation() && l_type == Type::MEASURE) { - const auto &unit = l_value.unit(); - const auto &unitType = unit.type(); - if (unitType == common::UnitOfMeasure::Type::LINEAR) { - formatter->add(l_value.getSIValue()); - } else if (unitType == common::UnitOfMeasure::Type::ANGULAR) { - formatter->add( - l_value.convertToUnit(common::UnitOfMeasure::ARC_SECOND)); - } else if (unit == common::UnitOfMeasure::PARTS_PER_MILLION) { - formatter->add(1.0 + l_value.value() * 1e-6); - } else { - formatter->add(l_value.value()); - } - } else if (l_type == Type::MEASURE) { - const auto &unit = l_value.unit(); - if (isWKT2) { - formatter->add(l_value.value()); - } else { - // In WKT1, as we don't output the natural unit, output to the - // registered linear / angular unit. + if (l_type == Type::MEASURE) { + const auto &l_value = value(); + if (formatter->abridgedTransformation()) { + const auto &unit = l_value.unit(); const auto &unitType = unit.type(); if (unitType == common::UnitOfMeasure::Type::LINEAR) { - const auto &targetUnit = *(formatter->axisLinearUnit()); - if (targetUnit.conversionToSI() == 0.0) { - throw io::FormattingException( - "cannot convert value to target linear unit"); - } - formatter->add(l_value.convertToUnit(targetUnit)); + formatter->add(l_value.getSIValue()); } else if (unitType == common::UnitOfMeasure::Type::ANGULAR) { - const auto &targetUnit = *(formatter->axisAngularUnit()); - if (targetUnit.conversionToSI() == 0.0) { - throw io::FormattingException( - "cannot convert value to target angular unit"); - } - formatter->add(l_value.convertToUnit(targetUnit)); + formatter->add( + l_value.convertToUnit(common::UnitOfMeasure::ARC_SECOND)); + } else if (unit == common::UnitOfMeasure::PARTS_PER_MILLION) { + formatter->add(1.0 + l_value.value() * 1e-6); } else { - formatter->add(l_value.getSIValue()); + formatter->add(l_value.value()); } - } - if (isWKT2 && unit != common::UnitOfMeasure::NONE) { - if (!formatter->primeMeridianOrParameterUnitOmittedIfSameAsAxis() || - (unit != common::UnitOfMeasure::SCALE_UNITY && - unit != *(formatter->axisLinearUnit()) && - unit != *(formatter->axisAngularUnit()))) { - unit._exportToWKT(formatter); + } else { + const auto &unit = l_value.unit(); + if (isWKT2) { + formatter->add(l_value.value()); + } else { + // In WKT1, as we don't output the natural unit, output to the + // registered linear / angular unit. + const auto &unitType = unit.type(); + if (unitType == common::UnitOfMeasure::Type::LINEAR) { + const auto &targetUnit = *(formatter->axisLinearUnit()); + if (targetUnit.conversionToSI() == 0.0) { + throw io::FormattingException( + "cannot convert value to target linear unit"); + } + formatter->add(l_value.convertToUnit(targetUnit)); + } else if (unitType == common::UnitOfMeasure::Type::ANGULAR) { + const auto &targetUnit = *(formatter->axisAngularUnit()); + if (targetUnit.conversionToSI() == 0.0) { + throw io::FormattingException( + "cannot convert value to target angular unit"); + } + formatter->add(l_value.convertToUnit(targetUnit)); + } else { + formatter->add(l_value.getSIValue()); + } + } + if (isWKT2 && unit != common::UnitOfMeasure::NONE) { + if (!formatter + ->primeMeridianOrParameterUnitOmittedIfSameAsAxis() || + (unit != common::UnitOfMeasure::SCALE_UNITY && + unit != *(formatter->axisLinearUnit()) && + unit != *(formatter->axisAngularUnit()))) { + unit._exportToWKT(formatter); + } } } } else if (l_type == Type::STRING || l_type == Type::FILENAME) { -- cgit v1.2.3 From 911852371a6a109445cd79e5176a89c539b2e768 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Feb 2019 15:58:16 +0100 Subject: Robinson: fix wrong values for forward path for latitudes >= 87.5 (fixes #1172), and fix inaccurate inverse method --- src/projections/robin.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/projections/robin.cpp b/src/projections/robin.cpp index 8f142aad..9f7908f6 100644 --- a/src/projections/robin.cpp +++ b/src/projections/robin.cpp @@ -7,7 +7,7 @@ PROJ_HEAD(robin, "Robinson") "\n\tPCyl, Sph"; #define V(C,z) (C.c0 + z * (C.c1 + z * (C.c2 + z * C.c3))) -#define DV(C,z) (C.c1 + z * (C.c2 + C.c2 + z * 3. * C.c3)) +#define DV(C,z) (C.c1 + 2 * z * C.c2 + z * z * 3. * C.c3) /* note: following terms based upon 5 deg. intervals in degrees. @@ -74,7 +74,7 @@ static const struct COEFS Y[] = { #define RC1 0.08726646259971647884 #define NODES 18 #define ONEEPS 1.000001 -#define EPS 1e-8 +#define EPS 1e-10 /* Not sure at all of the appropriate number for MAX_ITER... */ #define MAX_ITER 100 @@ -90,7 +90,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); return xy; } - if (i >= NODES) i = NODES - 1; + if (i >= NODES) i = NODES; dphi = RAD_TO_DEG * (dphi - RC1 * i); xy.x = V(X[i], dphi) * FXC * lp.lam; xy.y = V(Y[i], dphi) * FYC; @@ -133,10 +133,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ T = Y[i]; /* first guess, linear interp */ t = 5. * (lp.phi - T.c0)/(Y[i+1].c0 - T.c0); - /* make into root */ - T.c0 = (float)(T.c0 - lp.phi); for (iters = MAX_ITER; iters ; --iters) { /* Newton-Raphson */ - t -= t1 = V(T,t) / DV(T,t); + t -= t1 = (V(T,t) - lp.phi) / DV(T,t); if (fabs(t1) < EPS) break; } -- cgit v1.2.3 From c715ac511777707f9302246684e3118a9cc51c13 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Feb 2019 18:22:43 +0100 Subject: mutex.cpp: remove _XOPEN_SOURCE definition that causes compilation problem on netBSD 8 and is useless on Linux --- src/mutex.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/mutex.cpp b/src/mutex.cpp index 12251f0f..da415e55 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -25,14 +25,6 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ - -/* projects.h and windows.h conflict - avoid this! */ - -#if defined(MUTEX_pthread) && !defined(_XOPEN_SOURCE) && !defined(__sun) -/* For pthread_mutexattr_settype */ -#define _XOPEN_SOURCE 500 -#endif - /* For PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */ #ifndef _GNU_SOURCE #define _GNU_SOURCE -- cgit v1.2.3 From 855f0f3e778de66ba3943ca3ba79606f58b8b887 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Feb 2019 19:40:14 +0100 Subject: io.cpp: cast to 'unsigned char' before isspace() to avoid undefined behaviour, for example on netBSD 8 --- src/iso19111/io.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index a1608464..d17d6329 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -973,7 +973,7 @@ const std::vector &WKTNode::children() const { //! @cond Doxygen_Suppress static size_t skipSpace(const std::string &str, size_t start) { size_t i = start; - while (i < str.size() && ::isspace(str[i])) { + while (i < str.size() && ::isspace(static_cast(str[i]))) { ++i; } return i; @@ -1002,8 +1002,9 @@ WKTNodeNNPtr WKTNode::createFrom(const std::string &wkt, size_t indexStart, bool inString = false; for (; i < wkt.size() && - (inString || (wkt[i] != '[' && wkt[i] != '(' && wkt[i] != ',' && - wkt[i] != ']' && wkt[i] != ')' && !::isspace(wkt[i]))); + (inString || + (wkt[i] != '[' && wkt[i] != '(' && wkt[i] != ',' && wkt[i] != ']' && + wkt[i] != ')' && !::isspace(static_cast(wkt[i])))); ++i) { if (wkt[i] == '"') { if (!inString) { @@ -5317,7 +5318,7 @@ PROJStringSyntaxParser(const std::string &projString, std::vector &steps, { size_t i = 0; while (true) { - for (; isspace(c_str[i]); i++) { + for (; isspace(static_cast(c_str[i])); i++) { } std::string token; bool in_string = false; @@ -5334,7 +5335,7 @@ PROJStringSyntaxParser(const std::string &projString, std::vector &steps, token += c_str[i]; i++; continue; - } else if (isspace(c_str[i])) { + } else if (isspace(static_cast(c_str[i]))) { break; } token += c_str[i]; -- cgit v1.2.3 From 2f8bd934860b135044c5122e3272f7cc41ba81e7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Feb 2019 20:30:08 +0100 Subject: Rename internal constant to avoid conflict with macro in Solaris system headers --- src/iso19111/coordinatesystem.cpp | 2 +- src/iso19111/io.cpp | 40 +++++++++++++++++++-------------------- src/iso19111/static.cpp | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinatesystem.cpp b/src/iso19111/coordinatesystem.cpp index efba8c05..2f6c5af7 100644 --- a/src/iso19111/coordinatesystem.cpp +++ b/src/iso19111/coordinatesystem.cpp @@ -483,7 +483,7 @@ void CoordinateSystem::_exportToWKT( const auto &l_axisList = axisList(); if (isWKT2) { - formatter->startNode(io::WKTConstants::CS, !identifiers().empty()); + formatter->startNode(io::WKTConstants::CS_, !identifiers().empty()); formatter->add(getWKT2Type(formatter->use2018Keywords())); formatter->add(static_cast(l_axisList.size())); formatter->endNode(); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index d17d6329..eb4403ea 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2557,13 +2557,13 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) { auto &dynamicNode = nodeP->lookForChild(WKTConstants::DYNAMIC); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); const auto &nodeName = nodeP->value(); if (isNull(csNode) && !ci_equal(nodeName, WKTConstants::GEOGCS) && !ci_equal(nodeName, WKTConstants::GEOCCS) && !ci_equal(nodeName, WKTConstants::BASEGEODCRS) && !ci_equal(nodeName, WKTConstants::BASEGEOGCRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto &primeMeridianNode = @@ -2713,9 +2713,9 @@ CRSNNPtr WKTParser::Private::buildDerivedGeodeticCRS(const WKTNodeNNPtr &node) { auto derivingConversion = buildConversion( derivingConversionNode, UnitOfMeasure::NONE, UnitOfMeasure::NONE); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); if (isNull(csNode)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); @@ -3540,11 +3540,11 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) { ? buildConversion(conversionNode, linearUnit, angularUnit) : buildProjection(node, projectionNode, linearUnit, angularUnit); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); const auto &nodeValue = nodeP->value(); if (isNull(csNode) && !ci_equal(nodeValue, WKTConstants::PROJCS) && !ci_equal(nodeValue, WKTConstants::BASEPROJCRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); auto cartesianCS = nn_dynamic_pointer_cast(cs); @@ -3727,11 +3727,11 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { ? buildDatumEnsemble(ensembleNode, nullptr, false).as_nullable() : nullptr; - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); const auto &nodeValue = nodeP->value(); if (isNull(csNode) && !ci_equal(nodeValue, WKTConstants::VERT_CS) && !ci_equal(nodeValue, WKTConstants::BASEVERTCRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); auto verticalCS = nn_dynamic_pointer_cast(cs); @@ -3788,9 +3788,9 @@ WKTParser::Private::buildDerivedVerticalCRS(const WKTNodeNNPtr &node) { auto derivingConversion = buildConversion( derivingConversionNode, UnitOfMeasure::NONE, UnitOfMeasure::NONE); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); if (isNull(csNode)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); @@ -3893,10 +3893,10 @@ BoundCRSNNPtr WKTParser::Private::buildBoundCRS(const WKTNodeNNPtr &node) { TemporalCSNNPtr WKTParser::Private::buildTemporalCS(const WKTNodeNNPtr &parentNode) { - auto &csNode = parentNode->GP()->lookForChild(WKTConstants::CS); + auto &csNode = parentNode->GP()->lookForChild(WKTConstants::CS_); if (isNull(csNode) && !ci_equal(parentNode->GP()->value(), WKTConstants::BASETIMECRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, parentNode, UnitOfMeasure::NONE); auto temporalCS = nn_dynamic_pointer_cast(cs); @@ -3954,9 +3954,9 @@ WKTParser::Private::buildEngineeringCRS(const WKTNodeNNPtr &node) { throw ParsingException("Missing EDATUM / ENGINEERINGDATUM node"); } - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); if (isNull(csNode) && !ci_equal(nodeP->value(), WKTConstants::BASEENGCRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); @@ -3999,9 +3999,9 @@ WKTParser::Private::buildDerivedEngineeringCRS(const WKTNodeNNPtr &node) { auto derivingConversion = buildConversion( derivingConversionNode, UnitOfMeasure::NONE, UnitOfMeasure::NONE); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); if (isNull(csNode)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); @@ -4014,10 +4014,10 @@ WKTParser::Private::buildDerivedEngineeringCRS(const WKTNodeNNPtr &node) { ParametricCSNNPtr WKTParser::Private::buildParametricCS(const WKTNodeNNPtr &parentNode) { - auto &csNode = parentNode->GP()->lookForChild(WKTConstants::CS); + auto &csNode = parentNode->GP()->lookForChild(WKTConstants::CS_); if (isNull(csNode) && !ci_equal(parentNode->GP()->value(), WKTConstants::BASEPARAMCRS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, parentNode, UnitOfMeasure::NONE); auto parametricCS = nn_dynamic_pointer_cast(cs); @@ -4087,9 +4087,9 @@ WKTParser::Private::buildDerivedProjectedCRS(const WKTNodeNNPtr &node) { auto conversion = buildConversion(conversionNode, linearUnit, angularUnit); - auto &csNode = nodeP->lookForChild(WKTConstants::CS); + auto &csNode = nodeP->lookForChild(WKTConstants::CS_); if (isNull(csNode) && !ci_equal(nodeP->value(), WKTConstants::PROJCS)) { - ThrowMissing(WKTConstants::CS); + ThrowMissing(WKTConstants::CS_); } auto cs = buildCS(csNode, node, UnitOfMeasure::NONE); return DerivedProjectedCRS::create(buildProperties(node), baseProjCRS, diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp index 5de046f1..588d05da 100644 --- a/src/iso19111/static.cpp +++ b/src/iso19111/static.cpp @@ -215,7 +215,7 @@ DEFINE_WKT_CONSTANT(ANGLEUNIT); DEFINE_WKT_CONSTANT(SCALEUNIT); DEFINE_WKT_CONSTANT(TIMEUNIT); DEFINE_WKT_CONSTANT(ELLIPSOID); -DEFINE_WKT_CONSTANT(CS); +const std::string WKTConstants::CS_(createAndAddToConstantList("CS")); DEFINE_WKT_CONSTANT(ID); DEFINE_WKT_CONSTANT(PROJCRS); DEFINE_WKT_CONSTANT(BASEGEODCRS); -- cgit v1.2.3 From c9b27a248d3ed9964b6ac0847a83eba383b62537 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Feb 2019 21:17:33 +0100 Subject: Fix build issues on Solaris --- src/apps/proj_strtod.cpp | 2 +- src/projections/eqearth.cpp | 2 +- src/projections/igh.cpp | 2 +- src/projections/isea.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/proj_strtod.cpp b/src/apps/proj_strtod.cpp index b8edc6a3..d4674705 100644 --- a/src/apps/proj_strtod.cpp +++ b/src/apps/proj_strtod.cpp @@ -309,7 +309,7 @@ double proj_strtod(const char *str, char **endptr) { number = exponent < 0? number / ex: number * ex; } else - number *= pow (10, exponent); + number *= pow (10.0, static_cast(exponent)); return number; } diff --git a/src/projections/eqearth.cpp b/src/projections/eqearth.cpp index dc58eed9..73499262 100644 --- a/src/projections/eqearth.cpp +++ b/src/projections/eqearth.cpp @@ -26,7 +26,7 @@ PROJ_HEAD(eqearth, "Equal Earth") "\n\tPCyl, Sph&Ell"; #define A2 -0.081106 #define A3 0.000893 #define A4 0.003796 -#define M (sqrt(3) / 2.0) +#define M (sqrt(3.0) / 2.0) #define MAX_Y 1.3173627591574 /* 90° latitude on a sphere with radius 1 */ #define EPS 1e-11 diff --git a/src/projections/igh.cpp b/src/projections/igh.cpp index a8efbb9d..d6b2d38d 100644 --- a/src/projections/igh.cpp +++ b/src/projections/igh.cpp @@ -77,7 +77,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); - const double y90 = Q->dy0 + sqrt(2); /* lt=90 corresponds to y=y0+sqrt(2) */ + const double y90 = Q->dy0 + sqrt(2.0); /* lt=90 corresponds to y=y0+sqrt(2) */ int z = 0; if (xy.y > y90+EPSLN || xy.y < -y90+EPSLN) /* 0 */ diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index 3a0a0a48..d53317c1 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -847,7 +847,7 @@ static long isea_disn(struct isea_dgg *g, int quad, struct isea_pt *di) { return g->serial; } /* hexes in a quad */ - hexes = lround(pow(g->aperture, g->resolution)); + hexes = lround(pow(static_cast(g->aperture), static_cast(g->resolution))); if (quad == 11) { g->serial = 1 + 10 * hexes + 1; return g->serial; -- cgit v1.2.3 From e1e52f28fa0f7fd14fe7dfd23aea2dbf65cda11e Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 27 Feb 2019 05:58:12 -0500 Subject: Fix null dereference warning. Counter-intuitively, this means removing checks for nullptr. The compiler sees these checks and thinks the one remaining dereference is missing a check. However, since pj_get_default_ctx cannot return nullptr, these tests are redundant. --- src/open_lib.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/open_lib.cpp b/src/open_lib.cpp index 510704e9..a00d3d0e 100644 --- a/src/open_lib.cpp +++ b/src/open_lib.cpp @@ -194,10 +194,10 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, sysname = name; /* or try to use application provided file finder */ - else if( ctx && ctx->file_finder != nullptr && (sysname = ctx->file_finder( ctx, name, ctx->file_finder_user_data )) != nullptr ) + else if( ctx->file_finder != nullptr && (sysname = ctx->file_finder( ctx, name, ctx->file_finder_user_data )) != nullptr ) ; - else if( ctx && ctx->file_finder_legacy != nullptr && (sysname = ctx->file_finder_legacy( name )) != nullptr ) + else if( ctx->file_finder_legacy != nullptr && (sysname = ctx->file_finder_legacy( name )) != nullptr ) ; /* or is environment PROJ_LIB defined */ @@ -234,7 +234,7 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, } /* If none of those work and we have a search path, try it */ - if (!fid && ctx && !ctx->search_paths.empty() ) + if( !fid && !ctx->search_paths.empty() ) { for( const auto& path: ctx->search_paths ) { try { -- cgit v1.2.3 From 38f7a68edbb0a5d4a64d98b8297f4281a5d400d0 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Wed, 27 Feb 2019 06:04:31 -0500 Subject: Fix default context fallback in proj_log_func. --- src/internal.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/internal.cpp b/src/internal.cpp index 44246842..b4b7a683 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -491,9 +491,7 @@ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION logf) { passed as first arg at each call to the logger ******************************************************************************/ if (nullptr==ctx) - pj_get_default_ctx (); - if (nullptr==ctx) - return; + ctx = pj_get_default_ctx (); ctx->logger_app_data = app_data; if (nullptr!=logf) ctx->logger = logf; -- cgit v1.2.3 From 1a2513badd1406ef061fd044273268a1e0ab3eed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 1 Mar 2019 14:53:22 +0100 Subject: Doc: rename to ISO-19111:2019 And publish link to corresponding promoted and public OGC doc: http://docs.opengeospatial.org/as/18-005r4/18-005r4.html --- src/general_doc.dox | 11 +++++------ src/iso19111/common.cpp | 4 ++-- src/iso19111/coordinateoperation.cpp | 2 +- src/iso19111/coordinatesystem.cpp | 2 +- src/iso19111/crs.cpp | 2 +- src/iso19111/datum.cpp | 10 +++++----- src/iso19111/factory.cpp | 2 +- src/iso19111/internal.cpp | 2 +- src/iso19111/io.cpp | 2 +- src/iso19111/metadata.cpp | 2 +- src/iso19111/static.cpp | 2 +- src/iso19111/util.cpp | 2 +- 12 files changed, 21 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/general_doc.dox b/src/general_doc.dox index ce5a8130..04248ae5 100644 --- a/src/general_doc.dox +++ b/src/general_doc.dox @@ -4,7 +4,7 @@ \section general_api_design General API design -The design of the class hierarchy is strongly derived from \ref ISO_19111_2018. +The design of the class hierarchy is strongly derived from \ref ISO_19111_2019. Classes for which the constructors are not directly accessible have their instances constructed with create() methods. The returned object is a non-null @@ -78,13 +78,12 @@ Coordinate Reference Systems (CRS), coordinate systems (CS) and coordinate transformation or coordinate conversion between two different coordinate reference systems. -\subsubsection ISO_19111_2018 ISO 19111:2018 +\subsubsection ISO_19111_2019 ISO 19111:2019 This is the revision mostly used for PROJ C++ modelling. -[OGC 18-005r1, 2018-04-04, ISO 19111:2018] -(https://portal.opengeospatial.org/files/?artifact_id=78556) -(not yet adopted, at time of writing) +[OGC 18-005r4, 2019-02-08, ISO 19111:2019] +(http://docs.opengeospatial.org/as/18-005r4/18-005r4.html) \subsubsection ISO_19111_2007 ISO 19111:2007 @@ -111,7 +110,7 @@ PROJ implements the two following revisions of the standard: \subsubsection WKT2_2015 WKT2:2015 -[OGC 12-063r5, 2015-05-01, WKT2-2015] +[OGC 12-063r5, 2015-05-01, ISO 19162:2015(E), WKT2-2015] (http://docs.opengeospatial.org/is/12-063r5/12-063r5.html) \subsection WKT1 WKT1 specification diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp index bdd836e1..4b947dc9 100644 --- a/src/iso19111/common.cpp +++ b/src/iso19111/common.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** @@ -641,7 +641,7 @@ const std::string &IdentifiedObject::remarks() PROJ_PURE_DEFN { /** \brief Return whether the object is deprecated. * - * \remark Extension of \ref ISO_19111_2018 + * \remark Extension of \ref ISO_19111_2019 */ bool IdentifiedObject::isDeprecated() PROJ_PURE_DEFN { return d->isDeprecated; } diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index fbb67e6b..d5bcfa84 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/coordinatesystem.cpp b/src/iso19111/coordinatesystem.cpp index 2f6c5af7..ef9cac93 100644 --- a/src/iso19111/coordinatesystem.cpp +++ b/src/iso19111/coordinatesystem.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index aabb15a1..4293c087 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 66717f70..5f7e4775 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** @@ -154,7 +154,7 @@ const util::optional &Datum::anchorDefinition() const { /** \brief Return the date on which the datum definition was published. * - * \note Departure from \ref ISO_19111_2018 : we return a DateTime instead of + * \note Departure from \ref ISO_19111_2019 : we return a DateTime instead of * a Citation::Date. * * @return the publication date, or empty. @@ -1010,7 +1010,7 @@ GeodeticReferenceFrame::primeMeridian() PROJ_PURE_DEFN { /** \brief Return the Ellipsoid associated with a GeodeticReferenceFrame. * - * \note The \ref ISO_19111_2018 modelling allows (but discourages) a + * \note The \ref ISO_19111_2019 modelling allows (but discourages) a * GeodeticReferenceFrame * to not be associated with a Ellipsoid in the case where it is used by a * geocentric crs::GeodeticCRS. We have made the choice of making the ellipsoid @@ -1223,7 +1223,7 @@ DynamicGeodeticReferenceFrame::frameReferenceEpoch() const { /** \brief Return the name of the deformation model. * - * @note This is an extension to the \ref ISO_19111_2018 modeling, to + * @note This is an extension to the \ref ISO_19111_2019 modeling, to * hold the content of the DYNAMIC.MODEL WKT2 node. * * @return the name of the deformation model. @@ -1660,7 +1660,7 @@ DynamicVerticalReferenceFrame::frameReferenceEpoch() const { /** \brief Return the name of the deformation model. * - * @note This is an extension to the \ref ISO_19111_2018 modeling, to + * @note This is an extension to the \ref ISO_19111_2019 modeling, to * hold the content of the DYNAMIC.MODEL WKT2 node. * * @return the name of the deformation model. diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index bafa1b5d..b00a2c1a 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/internal.cpp b/src/iso19111/internal.cpp index 0c330d30..240c98f4 100644 --- a/src/iso19111/internal.cpp +++ b/src/iso19111/internal.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index eb4403ea..51f93e2f 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/metadata.cpp b/src/iso19111/metadata.cpp index 6bf9d600..3725b072 100644 --- a/src/iso19111/metadata.cpp +++ b/src/iso19111/metadata.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp index 588d05da..ef2635b5 100644 --- a/src/iso19111/static.cpp +++ b/src/iso19111/static.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** diff --git a/src/iso19111/util.cpp b/src/iso19111/util.cpp index d6cfa9f4..25207d5c 100644 --- a/src/iso19111/util.cpp +++ b/src/iso19111/util.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * * Project: PROJ - * Purpose: ISO19111:2018 implementation + * Purpose: ISO19111:2019 implementation * Author: Even Rouault * ****************************************************************************** -- cgit v1.2.3 From a6add0dc054a55334ee880d83aca8c19510ab858 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Fri, 1 Mar 2019 19:25:43 +0100 Subject: Bump version numbers in preparation for 6.1.0 --- src/proj.h | 2 +- src/proj_api.h | 2 +- src/release.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/proj.h b/src/proj.h index 1f71e115..6f53bb07 100644 --- a/src/proj.h +++ b/src/proj.h @@ -153,7 +153,7 @@ extern "C" { /* The version numbers should be updated with every release! **/ #define PROJ_VERSION_MAJOR 6 -#define PROJ_VERSION_MINOR 0 +#define PROJ_VERSION_MINOR 1 #define PROJ_VERSION_PATCH 0 extern char const PROJ_DLL pj_release[]; /* global release id string */ diff --git a/src/proj_api.h b/src/proj_api.h index 5c4d5e7a..53b0edfa 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -38,7 +38,7 @@ #endif #ifndef PJ_VERSION -#define PJ_VERSION 600 +#define PJ_VERSION 610 #endif #ifdef PROJ_RENAME_SYMBOLS diff --git a/src/release.cpp b/src/release.cpp index ddc768c6..13ed45f0 100644 --- a/src/release.cpp +++ b/src/release.cpp @@ -11,7 +11,7 @@ char const pj_release[] = STR(PROJ_VERSION_MAJOR)"." STR(PROJ_VERSION_MINOR)"." STR(PROJ_VERSION_PATCH)", " - "March 1st, 2019"; + "September 1st, 2019"; const char *pj_get_release() { return pj_release; -- cgit v1.2.3 From 0ec59ca29500fad156c8f2dd6a96e13bb6595f88 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 6 Mar 2019 14:31:22 +0100 Subject: Make gie return non-zero exit code when file can't be opened --- src/apps/gie.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index abed11c0..e6b63d51 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -300,6 +300,20 @@ int main (int argc, char **argv) { return 1; } + for (i = 0; i < o->fargc; i++ ) { + FILE* f = fopen (o->fargv[i], "rt"); + if (f == nullptr) { + fprintf ( + T.fout, + "%sCannot open specified input file '%s' - bye!\n", + delim, + o->fargv[i] + ); + return 1; + } + fclose(f); + } + for (i = 0; i < o->fargc; i++) process_file (o->fargv[i]); @@ -370,8 +384,6 @@ static int another_failing_roundtrip (void) { } static int process_file (const char *fname) { - FILE *f; - F->lineno = F->next_lineno = F->level = 0; T.op_ok = T.total_ok = 0; T.op_ko = T.total_ko = 0; @@ -383,15 +395,8 @@ static int process_file (const char *fname) { return 0; } - f = fopen (fname, "rt"); - if (nullptr==f) { - if (T.verbosity > 0) { - fprintf (T.fout, "%sCannot open spec'd input file '%s' - bye!\n", delim, fname); - return 2; - } - errmsg (2, "Cannot open spec'd input file '%s' - bye!\n", fname); - } - F->f = f; + /* We have already tested in main that the file exists */ + F->f = fopen (fname, "rt"); if (T.verbosity > 0) fprintf (T.fout, "%sReading file '%s'\n", delim, fname); @@ -405,7 +410,7 @@ static int process_file (const char *fname) { } } - fclose (f); + fclose (F->f); F->lineno = F->next_lineno = 0; T.grand_ok += T.total_ok; -- cgit v1.2.3 From 0cd621da5791a99528f6a5fe892c659cab3bda23 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 9 Mar 2019 10:30:11 +0100 Subject: Allow gie to use proj_create_crs_to_crs (#1314) The commands crs_src and crs_dst are introduced to allow operation initialization with proj_create_crs_to_crs. This has the benefit of using proj.db to select the proper operation. Additionally axis order is respected for the coordinate systems that are tested. This is beneficial when running the GIGS test suite for instance. --- src/apps/gie.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index e6b63d51..5407c0ba 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -148,7 +148,7 @@ static ffio *ffio_destroy (ffio *G); static ffio *ffio_create (const char **tags, size_t n_tags, size_t max_record_size); static const char *gie_tags[] = { - "", "operation", "use_proj4_init_rules", + "", "operation", "crs_src", "crs_dst", "use_proj4_init_rules", "accept", "expect", "roundtrip", "banner", "verbose", "direction", "tolerance", "ignore", "require_grid", "echo", "skip", "" }; @@ -175,6 +175,8 @@ static const char *err_const_from_errno (int err); typedef struct { char operation[MAX_OPERATION+1]; + char crs_dst[MAX_OPERATION+1]; + char crs_src[MAX_OPERATION+1]; PJ *P; PJ_COORD a, b, c, e; PJ_DIRECTION dir; @@ -607,6 +609,65 @@ either a conversion or a transformation) return 0; } +static int crs_to_crs_operation() { + T.op_id++; + T.operation_lineno = F->lineno; + + if (T.verbosity > 1) { + char buffer[80]; + finish_previous_operation (F->args); + snprintf(buffer, 80, "%-36.36s -> %-36.36s", T.crs_src, T.crs_dst); + banner (buffer); + } + + T.op_ok = 0; + T.op_ko = 0; + T.op_skip = 0; + T.skip_test = 0; + + direction ("forward"); + tolerance ("0.5 mm"); + ignore ("pjd_err_dont_skip"); + + proj_errno_reset (T.P); + + if (T.P) + proj_destroy (T.P); + proj_errno_reset (nullptr); + proj_context_use_proj4_init_rules(nullptr, T.use_proj4_init_rules); + + + T.P = proj_create_crs_to_crs(nullptr, T.crs_src, T.crs_dst, nullptr); + + strcpy(T.crs_src, ""); + strcpy(T.crs_dst, ""); + return 0; +} + +static int crs_src(const char *args) { + strncpy (&(T.crs_src[0]), F->args, MAX_OPERATION); + T.crs_src[MAX_OPERATION] = '\0'; + (void) args; + + if (strcmp(T.crs_src, "") != 0 && strcmp(T.crs_dst, "") != 0) { + crs_to_crs_operation(); + } + + return 0; +} + +static int crs_dst(const char *args) { + strncpy (&(T.crs_dst[0]), F->args, MAX_OPERATION); + T.crs_dst[MAX_OPERATION] = '\0'; + (void) args; + + if (strcmp(T.crs_src, "") != 0 && strcmp(T.crs_dst, "") != 0) { + crs_to_crs_operation(); + } + + return 0; +} + static PJ_COORD torad_coord (PJ *P, PJ_DIRECTION dir, PJ_COORD a) { size_t i, n; const char *axis = "enut"; @@ -1000,6 +1061,8 @@ static int dispatch (const char *cmnd, const char *args) { if (T.skip) return SKIP; if (0==strcmp (cmnd, "operation")) return operation ((char *) args); + if (0==strcmp (cmnd, "crs_src")) return crs_src (args); + if (0==strcmp (cmnd, "crs_dst")) return crs_dst (args); if (T.skip_test) { if (0==strcmp (cmnd, "expect")) return another_skip(); -- cgit v1.2.3 From fde6150b61aa225bb960d46f1611c82bf81315b3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 14 Mar 2019 23:07:29 +0100 Subject: Reject eccentricity values larger than one Valid eccentricity should be between 0 (included) or 1 (excluded) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13665 Credit to OSS Fuzz --- src/ell_set.cpp | 20 ++++++++++++-------- src/init.cpp | 2 +- src/proj_internal.h | 2 +- src/strerrno.cpp | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ell_set.cpp b/src/ell_set.cpp index 4c9fc892..71746895 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -280,8 +280,8 @@ static int ellps_shape (PJ *P) { P->es = pj_atof (pj_param_value (par)); if (HUGE_VAL==P->es) return proj_errno_set (P, PJD_ERR_INVALID_ARG); - if (1==P->es) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE); + if (P->es >= 1) + return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); break; /* eccentricity, e */ @@ -291,8 +291,8 @@ static int ellps_shape (PJ *P) { return proj_errno_set (P, PJD_ERR_INVALID_ARG); if (0==P->e) return proj_errno_set (P, PJD_ERR_INVALID_ARG); - if (1==P->e) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE); + if (P->e >= 1) + return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); P->es = P->e * P->e; break; @@ -301,8 +301,8 @@ static int ellps_shape (PJ *P) { P->b = pj_atof (pj_param_value (par)); if (HUGE_VAL==P->b) return proj_errno_set (P, PJD_ERR_INVALID_ARG); - if (0==P->b) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE); + if (P->b <= 0) + return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); if (P->b==P->a) break; P->f = (P->a - P->b) / P->a; @@ -556,8 +556,8 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { P->one_es = 1. - P->es; if (P->one_es == 0.) { - pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE); - return PJD_ERR_ECCENTRICITY_IS_ONE; + pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER; } P->rone_es = 1./P->one_es; @@ -712,6 +712,10 @@ bomb: pj_ctx_set_errno(ctx, PJD_ERR_ES_LESS_THAN_ZERO); return 1; } + if (*es >= 1.) { + pj_ctx_set_errno(ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return 1; + } if (*a <= 0.) { pj_ctx_set_errno(ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); return 1; diff --git a/src/init.cpp b/src/init.cpp index 2961bcca..13ea4ae8 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -680,7 +680,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i PIN->a_orig = PIN->a; PIN->es_orig = PIN->es; if (pj_calc_ellipsoid_params (PIN, PIN->a, PIN->es)) - return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE); + return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); /* Now that we have ellipse information check for WGS84 datum */ if( PIN->datum_type == PJD_3PARAM diff --git a/src/proj_internal.h b/src/proj_internal.h index 448b65c8..cdde6bad 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -624,7 +624,7 @@ struct FACTORS { #define PJD_ERR_NO_COLON_IN_INIT_STRING -3 #define PJD_ERR_PROJ_NOT_NAMED -4 #define PJD_ERR_UNKNOWN_PROJECTION_ID -5 -#define PJD_ERR_ECCENTRICITY_IS_ONE -6 +#define PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER -6 #define PJD_ERR_UNKNOWN_UNIT_ID -7 #define PJD_ERR_INVALID_BOOLEAN_PARAM -8 #define PJD_ERR_UNKNOWN_ELLP_PARAM -9 diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 01097a42..5dedef98 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -14,7 +14,7 @@ pj_err_list[] = { "no colon in init= string", /* -3 */ "projection not named", /* -4 */ "unknown projection id", /* -5 */ - "effective eccentricity = 1.", /* -6 */ + "effective eccentricity >= 1.", /* -6 */ "unknown unit conversion id", /* -7 */ "invalid boolean param argument", /* -8 */ "unknown elliptical parameter name", /* -9 */ -- cgit v1.2.3 From db29f2ecf6f49250079b962ad788b93fbc497fa3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 00:10:02 +0100 Subject: Molodensky: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13069 Credit to OSS Fuzz --- src/transformations/molodensky.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/transformations/molodensky.cpp b/src/transformations/molodensky.cpp index c389fd32..373b1095 100644 --- a/src/transformations/molodensky.cpp +++ b/src/transformations/molodensky.cpp @@ -146,10 +146,20 @@ static PJ_LPZ calc_standard_params(PJ_LPZ lpz, PJ *P) { dphi = (-dx*sphi*clam) - (dy*sphi*slam) + (dz*cphi) + ((nu * P->es * sphi * cphi * da) / a) + (sphi*cphi * ( rho/(1-f) + nu*(1-f))*df); - dphi /= (rho + lpz.z); + const double dphi_denom = rho + lpz.z; + if( dphi_denom == 0.0 ) { + lpz.lam = HUGE_VAL; + return lpz; + } + dphi /= dphi_denom; /* delta lambda */ - dlam = (-dx*slam + dy*clam) / ((nu+lpz.z)*cphi); + const double dlam_denom = (nu+lpz.z)*cphi; + if( dlam_denom == 0.0 ) { + lpz.lam = HUGE_VAL; + return lpz; + } + dlam = (-dx*slam + dy*clam) / dlam_denom; /* delta h */ dh = dx*cphi*clam + dy*cphi*slam + dz*sphi - (a/nu)*da + nu*(1-f)*sphi*sphi*df; @@ -183,7 +193,12 @@ static PJ_LPZ calc_abridged_params(PJ_LPZ lpz, PJ *P) { /* delta lambda */ dlam = -dx*slam + dy*clam; - dlam /= RN(P->a, P->e2s, lpz.phi)*cphi; + const double dlam_denom = RN(P->a, P->e2s, lpz.phi)*cphi; + if( dlam_denom == 0.0 ) { + lpz.lam = HUGE_VAL; + return lpz; + } + dlam /= dlam_denom; /* delta h */ dh = dx*cphi*clam + dy*cphi*slam + dz*sphi - da + adffda*sphi*sphi; @@ -230,6 +245,10 @@ static PJ_XYZ forward_3d(PJ_LPZ lpz, PJ *P) { } else { lpz = calc_standard_params(lpz, P); } + if( lpz.lam == HUGE_VAL ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().xyz; + } /* offset coordinate */ point.lpz.phi += lpz.phi; @@ -258,6 +277,11 @@ static PJ_LPZ reverse_3d(PJ_XYZ xyz, PJ *P) { else lpz = calc_standard_params(point.lpz, P); + if( lpz.lam == HUGE_VAL ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().lpz; + } + /* offset coordinate */ point.lpz.phi -= lpz.phi; point.lpz.lam -= lpz.lam; -- cgit v1.2.3 From 7dd1a2ee6bfb33807594f115c59548f8cf1d3475 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 20:04:15 +0100 Subject: aea: validate |lat_1| and |lat_2| <= 90 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13028 Credit to OSS Fuzz --- src/projections/aea.cpp | 2 ++ src/strerrno.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp index 9a0c4656..f457e836 100644 --- a/src/projections/aea.cpp +++ b/src/projections/aea.cpp @@ -155,6 +155,8 @@ static PJ *setup(PJ *P) { P->inv = e_inverse; P->fwd = e_forward; + if (fabs(Q->phi1) > M_HALFPI || fabs(Q->phi2) > M_HALFPI) + return destructor(P, PJD_ERR_LAT_LARGER_THAN_90); if (fabs(Q->phi1 + Q->phi2) < EPS10) return destructor(P, PJD_ERR_CONIC_LAT_EQUAL); Q->n = sinphi = sin(Q->phi1); diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 5dedef98..a9310a55 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -30,7 +30,7 @@ pj_err_list[] = { "acos/asin: |arg| >1.+1e-14", /* -19 */ "tolerance condition error", /* -20 */ "conic lat_1 = -lat_2", /* -21 */ - "lat_1 >= 90", /* -22 */ + "lat_0, lat_1 or lat_2 >= 90", /* -22 */ "lat_1 = 0", /* -23 */ "lat_ts >= 90", /* -24 */ "no distance between control points", /* -25 */ -- cgit v1.2.3 From 44fc7dda9fc411f7c2f052c2271d563bc52f2518 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 20:17:28 +0100 Subject: ellps_spherification(): detect invalid semi-major axis value Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12909 Credit to OSS Fuzz --- src/ell_set.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ell_set.cpp b/src/ell_set.cpp index 71746895..386b4f46 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -399,6 +399,10 @@ static int ellps_spherification (PJ *P) { break; } + if (P->a <= 0.) { + return proj_errno_set(P, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); + } + /* Clean up the ellipsoidal parameters to reflect the sphere */ P->es = P->e = P->f = 0; P->rf = HUGE_VAL; -- cgit v1.2.3 From ed2b26a09b407f7b580297d8a2cc516f786cbcc6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 22:24:31 +0100 Subject: Hammer: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12799 Credit to OSS Fuzz --- src/projections/hammer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/hammer.cpp b/src/projections/hammer.cpp index aa7d1ba9..b2e56a2c 100644 --- a/src/projections/hammer.cpp +++ b/src/projections/hammer.cpp @@ -24,7 +24,14 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ struct pj_opaque *Q = static_cast(P->opaque); double cosphi, d; - d = sqrt(2./(1. + (cosphi = cos(lp.phi)) * cos(lp.lam *= Q->w))); + cosphi = cos(lp.phi); + lp.lam *= Q->w; + double denom = 1. + cosphi * cos(lp.lam); + if( denom == 0.0 ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().xy; + } + d = sqrt(2./denom); xy.x = Q->m * d * cosphi * sin(lp.lam); xy.y = Q->rm * d * sin(lp.phi); return xy; -- cgit v1.2.3 From 1c4988d6be1cce93c866df98786d2eca3a244816 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 23:17:03 +0100 Subject: sterea: fix lat_0 = -90 A division by zero caused NaN values to be returned. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12062 Credit to OSS Fuzz --- src/gauss.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gauss.cpp b/src/gauss.cpp index b7a27191..49ccfa1c 100644 --- a/src/gauss.cpp +++ b/src/gauss.cpp @@ -65,9 +65,14 @@ void *pj_gauss_ini(double e, double phi0, double *chi, double *rc) { } *chi = asin(sphi / en->C); en->ratexp = 0.5 * en->C * e; - en->K = tan(.5 * *chi + M_FORTPI) / ( - pow(tan(.5 * phi0 + M_FORTPI), en->C) * - srat(en->e * sphi, en->ratexp) ); + if( .5 * phi0 + M_FORTPI < 1e-10 ) { + en->K = 1.0 / srat(en->e * sphi, en->ratexp); + } + else { + en->K = tan(.5 * *chi + M_FORTPI) / ( + pow(tan(.5 * phi0 + M_FORTPI), en->C) * + srat(en->e * sphi, en->ratexp) ); + } return ((void *)en); } -- cgit v1.2.3 From 6bde8881169cdf37256b0148e7d383232a4e305e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 15 Mar 2019 23:52:33 +0100 Subject: Helmert: avoid potential division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11893 Credit to OSS Fuzz --- src/transformations/helmert.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/transformations/helmert.cpp b/src/transformations/helmert.cpp index 034f76f4..c00fad2f 100644 --- a/src/transformations/helmert.cpp +++ b/src/transformations/helmert.cpp @@ -567,14 +567,14 @@ PJ *TRANSFORMATION(helmert, 0) { if (pj_param_exists (P->params, "theta")) { P->left = PJ_IO_UNITS_PROJECTED; P->right = PJ_IO_UNITS_PROJECTED; + P->fwd = helmert_forward; + P->inv = helmert_reverse; } P->fwd4d = helmert_forward_4d; P->inv4d = helmert_reverse_4d; P->fwd3d = helmert_forward_3d; P->inv3d = helmert_reverse_3d; - P->fwd = helmert_forward; - P->inv = helmert_reverse; Q = (struct pj_opaque_helmert *)P->opaque; -- cgit v1.2.3 From b81d78b291658438c91a50995e546c853ef5ef7a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 01:29:55 +0100 Subject: ocea: code cleanup to use Snyder's conventions --- src/projections/ocea.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp index 75aa6666..4930e587 100644 --- a/src/projections/ocea.cpp +++ b/src/projections/ocea.cpp @@ -15,8 +15,6 @@ struct pj_opaque { double rtk; double sinphi; double cosphi; - double singam; - double cosgam; }; } // anonymous namespace @@ -61,15 +59,16 @@ PJ *PROJECTION(ocea) { Q->rok = 1. / P->k0; Q->rtk = P->k0; + double lam_p, phi_p; /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/ if ( pj_param(P->ctx, P->params, "talpha").i) { /*Define Pole of oblique transformation from 1 point & 1 azimuth*/ alpha = pj_param(P->ctx, P->params, "ralpha").f; lonz = pj_param(P->ctx, P->params, "rlonc").f; /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - Q->singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; + lam_p = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - Q->sinphi = asin(cos(phi_0) * sin(alpha)); + phi_p = asin(cos(phi_0) * sin(alpha)); /*If the keyword "alpha" is NOT found in the sentence then use 2points*/ } else { /*Define Pole of oblique transformation from 2 points*/ @@ -78,23 +77,21 @@ PJ *PROJECTION(ocea) { lam_1 = pj_param(P->ctx, P->params, "rlon_1").f; lam_2 = pj_param(P->ctx, P->params, "rlon_2").f; /*Equation 9-1 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - Q->singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - + lam_p = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) - sin(phi_1) * cos(phi_2) * cos(lam_2), sin(phi_1) * cos(phi_2) * sin(lam_2) - cos(phi_1) * sin(phi_2) * sin(lam_1) ); /* take care of P->lam0 wrap-around when +lam_1=-90*/ if (lam_1 == -M_HALFPI) - Q->singam = -Q->singam; + lam_p = -lam_p; /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - Q->sinphi = atan(-cos(Q->singam - lam_1) / tan(phi_1)); + phi_p = atan(-cos(lam_p - lam_1) / tan(phi_1)); } - P->lam0 = Q->singam + M_HALFPI; - Q->cosphi = cos(Q->sinphi); - Q->sinphi = sin(Q->sinphi); - Q->cosgam = cos(Q->singam); - Q->singam = sin(Q->singam); + P->lam0 = lam_p + M_HALFPI; + Q->cosphi = cos(phi_p); + Q->sinphi = sin(phi_p); P->inv = s_inverse; P->fwd = s_forward; P->es = 0.; -- cgit v1.2.3 From c6f41f0176d744de5de1ca48e764148ed18e6489 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 01:51:05 +0100 Subject: ocea: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11699 Credit to OSS Fuzz --- src/projections/ocea.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp index 4930e587..4e28f727 100644 --- a/src/projections/ocea.cpp +++ b/src/projections/ocea.cpp @@ -87,7 +87,16 @@ PJ *PROJECTION(ocea) { lam_p = -lam_p; /*Equation 9-2 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - phi_p = atan(-cos(lam_p - lam_1) / tan(phi_1)); + double cos_lamp_m_minus_lam_1 = cos(lam_p - lam_1); + double tan_phi_1 = tan(phi_1); + if( tan_phi_1 == 0.0 ) { + // Not sure if we want to support this case, but at least this avoids + // a division by zero, and gives the same result as the below atan() + phi_p = (cos_lamp_m_minus_lam_1 >= 0.0 ) ? -M_HALFPI : M_HALFPI; + } + else { + phi_p = atan(- cos_lamp_m_minus_lam_1 / tan_phi_1); + } } P->lam0 = lam_p + M_HALFPI; Q->cosphi = cos(phi_p); -- cgit v1.2.3 From 644a592cc866ae2871eb82fdd428182dab47fab2 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 16 Mar 2019 09:53:56 +0100 Subject: Use 1st eccentricity instead of 2nd eccentricity By mistake the second eccentricity was used in a few places in the Molodensky transform. According to the literature the first eccentricity should always be used in the eccentricity. This only affects the output slightly. Reported test coordinates differed by less than a millimeter. Fixes #1321 --- src/transformations/molodensky.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/transformations/molodensky.cpp b/src/transformations/molodensky.cpp index 373b1095..289c321e 100644 --- a/src/transformations/molodensky.cpp +++ b/src/transformations/molodensky.cpp @@ -140,7 +140,7 @@ static PJ_LPZ calc_standard_params(PJ_LPZ lpz, PJ *P) { /* ellipsoid radii of curvature */ double rho = RM(a, P->es, lpz.phi); - double nu = RN(a, P->e2s, lpz.phi); + double nu = RN(a, P->es, lpz.phi); /* delta phi */ dphi = (-dx*sphi*clam) - (dy*sphi*slam) + (dz*cphi) @@ -193,7 +193,7 @@ static PJ_LPZ calc_abridged_params(PJ_LPZ lpz, PJ *P) { /* delta lambda */ dlam = -dx*slam + dy*clam; - const double dlam_denom = RN(P->a, P->e2s, lpz.phi)*cphi; + const double dlam_denom = RN(P->a, P->es, lpz.phi)*cphi; if( dlam_denom == 0.0 ) { lpz.lam = HUGE_VAL; return lpz; -- cgit v1.2.3 From a1cc9977decb62b4576c6c7f17a0d64cab9bf36a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 11:03:07 +0100 Subject: Fix doc generation with Breathe 4.12.0 Breathe 4.12.0 (as pulled by MacOSX builds such as https://travis-ci.com/OSGeo/proj.4/jobs/185395222) does not seem to like default initialization in documented C++ structs (regression/bug) /Users/travis/build/OSGeo/proj.4/docs/source/development/reference/cpp/io.rst:6:Parsing of expression failed. Using fallback parser. Error was: Error in postfix expression, expected primary expression or type. If primary expression: Invalid definition: Expected identifier in nested name. [error at 67] std::string osgeo::proj::io::AuthorityFactory::CRSInfo::authName = {} -------------------------------------------------------------------^ If type: Invalid definition: Expected identifier in nested name. [error at 67] std::string osgeo::proj::io::AuthorityFactory::CRSInfo::authName = {} -------------------------------------------------------------------^ --- src/iso19111/coordinateoperation.cpp | 11 ++++++++++- src/iso19111/factory.cpp | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index d5bcfa84..0eef9954 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -552,7 +552,16 @@ struct CoordinateOperation::Private { // --------------------------------------------------------------------------- -GridDescription::GridDescription() = default; +GridDescription::GridDescription(): + shortName{}, + fullName{}, + packageName{}, + url{}, + directDownload(false), + openLicense(false), + available(false) +{} + GridDescription::~GridDescription() = default; diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index b00a2c1a..d1fd4d0b 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1359,6 +1359,25 @@ const DatabaseContextNNPtr &AuthorityFactory::databaseContext() const { // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +AuthorityFactory::CRSInfo::CRSInfo(): + authName{}, + code{}, + name{}, + type{ObjectType::CRS}, + deprecated{}, + bbox_valid{}, + west_lon_degree{}, + south_lat_degree{}, + east_lon_degree{}, + north_lat_degree{}, + areaName{}, + projectionMethodName{} +{} +//! @endcond + +// --------------------------------------------------------------------------- + /** \brief Returns an arbitrary object from a code. * * The returned object will typically be an instance of Datum, -- cgit v1.2.3 From a9886a5e4a64610aa605e98afeb467d1c44ed925 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 13:31:09 +0100 Subject: Run scripts/reformat_cpp.sh --- src/iso19111/coordinateoperation.cpp | 15 ++++----------- src/iso19111/factory.cpp | 18 ++++-------------- 2 files changed, 8 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 0eef9954..575eae39 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -552,16 +552,9 @@ struct CoordinateOperation::Private { // --------------------------------------------------------------------------- -GridDescription::GridDescription(): - shortName{}, - fullName{}, - packageName{}, - url{}, - directDownload(false), - openLicense(false), - available(false) -{} - +GridDescription::GridDescription() + : shortName{}, fullName{}, packageName{}, url{}, directDownload(false), + openLicense(false), available(false) {} GridDescription::~GridDescription() = default; @@ -10811,7 +10804,7 @@ struct MyPROJStringExportableHorizVerticalHorizPROJBased final MyPROJStringExportableHorizVerticalHorizPROJBased:: ~MyPROJStringExportableHorizVerticalHorizPROJBased() = default; -} +} // namespace operation NS_PROJ_END #if 0 diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index d1fd4d0b..3530f5d8 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1360,20 +1360,10 @@ const DatabaseContextNNPtr &AuthorityFactory::databaseContext() const { // --------------------------------------------------------------------------- //! @cond Doxygen_Suppress -AuthorityFactory::CRSInfo::CRSInfo(): - authName{}, - code{}, - name{}, - type{ObjectType::CRS}, - deprecated{}, - bbox_valid{}, - west_lon_degree{}, - south_lat_degree{}, - east_lon_degree{}, - north_lat_degree{}, - areaName{}, - projectionMethodName{} -{} +AuthorityFactory::CRSInfo::CRSInfo() + : authName{}, code{}, name{}, type{ObjectType::CRS}, deprecated{}, + bbox_valid{}, west_lon_degree{}, south_lat_degree{}, east_lon_degree{}, + north_lat_degree{}, areaName{}, projectionMethodName{} {} //! @endcond // --------------------------------------------------------------------------- -- cgit v1.2.3 From d95b0cb8b317d0a8142b664c42928083145194ed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 15:14:55 +0100 Subject: createOperation(): fix geocent <--> nadgrids+geoidgrids case (fixes #1323) --- src/iso19111/coordinateoperation.cpp | 31 ++++++++++++++++++++++++++++++- src/iso19111/io.cpp | 20 ++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 575eae39..240833df 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11914,11 +11914,40 @@ CoordinateOperationFactory::Private::createOperations( return horizTransforms; } } + } else if (compoundSrc && geodDst) { + auto datum = geodDst->datum(); + if (datum) { + auto cs = + cs::EllipsoidalCS::createLatitudeLongitudeEllipsoidalHeight( + common::UnitOfMeasure::DEGREE, + common::UnitOfMeasure::METRE); + auto intermGeog3DCRS = util::nn_static_pointer_cast( + crs::GeographicCRS::create( + util::PropertyMap() + .set(common::IdentifiedObject::NAME_KEY, + geodDst->nameStr()) + .set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + metadata::Extent::WORLD), + NN_NO_CHECK(datum), cs)); + auto sourceToGeog3DOps = + createOperations(sourceCRS, intermGeog3DCRS, context); + auto geog3DToTargetOps = + createOperations(intermGeog3DCRS, targetCRS, context); + if (!geog3DToTargetOps.empty()) { + for (const auto &op : sourceToGeog3DOps) { + res.emplace_back( + ConcatenatedOperation::createComputeMetadata( + {op, geog3DToTargetOps.front()}, + !allowEmptyIntersection)); + } + return res; + } + } } // reverse of previous case auto compoundDst = dynamic_cast(targetCRS.get()); - if (geogSrc && compoundDst) { + if (geodSrc && compoundDst) { return applyInverse(createOperations(targetCRS, sourceCRS, context)); } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 51f93e2f..d5f38fd5 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -5049,7 +5049,7 @@ const std::string &PROJStringFormatter::toString() const { first.paramValues[1].keyEquals("z_in") && first.paramValues[2].keyEquals("xy_out") && first.paramValues[3].keyEquals("z_out") && - second.paramValues[0].keyEquals("xy_in=") && + second.paramValues[0].keyEquals("xy_in") && second.paramValues[1].keyEquals("xy_out") && first.paramValues[0].value == second.paramValues[1].value && first.paramValues[2].value == second.paramValues[0].value) { @@ -5074,6 +5074,22 @@ const std::string &PROJStringFormatter::toString() const { break; } + // unitconvert (1), axisswap order=2,1, unitconvert(2) ==> + // axisswap order=2,1, unitconvert (1), unitconvert(2) which + // will get further optimized by previous case + if (i + 1 < d->steps_.size() && prevStep.name == "unitconvert" && + curStep.name == "axisswap" && curStepParamCount == 1 && + curStep.paramValues[0].equals("order", "2,1")) { + auto iterNext = iterCur; + ++iterNext; + auto &nextStep = *iterNext; + if (nextStep.name == "unitconvert") { + std::swap(*iterPrev, *iterCur); + changeDone = true; + break; + } + } + // axisswap order=2,1 followed by itself is a no-op if (curStep.name == "axisswap" && prevStep.name == "axisswap" && curStepParamCount == 1 && prevStepParamCount == 1 && @@ -6707,7 +6723,7 @@ PROJStringParser::Private::buildGeocentricCRS(int iStep, int iUnitConvert) { auto datum = buildDatum(step, title); - UnitOfMeasure unit = UnitOfMeasure::METRE; + UnitOfMeasure unit = buildUnit(step, "units", ""); if (iUnitConvert >= 0) { auto &stepUnitConvert = steps_[iUnitConvert]; const std::string *xy_in = &getParamValue(stepUnitConvert, "xy_in"); -- cgit v1.2.3 From 70c9d0f75c9ecbb6f1ae9b5c7cefbe3a6fdbd5b9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 17:26:17 +0100 Subject: createOperations(): fix nadgrids+geoidgrids -> nadgrids+geoidgrids --- src/iso19111/coordinateoperation.cpp | 43 ++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 240833df..c1b3704c 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11879,6 +11879,34 @@ CoordinateOperationFactory::Private::createOperations( } } + auto vertCRSOfBaseOfBoundSrc = + boundSrc->baseCRS()->extractVerticalCRS(); + auto vertCRSOfBaseOfBoundDst = + boundDst->baseCRS()->extractVerticalCRS(); + if (hubSrcGeog && hubDstGeog && + hubSrcGeog->_isEquivalentTo( + hubDstGeog, util::IComparable::Criterion::EQUIVALENT) && + vertCRSOfBaseOfBoundSrc && vertCRSOfBaseOfBoundDst) { + auto opsFirst = createOperations(sourceCRS, hubSrc, context); + auto opsLast = createOperations(hubSrc, targetCRS, context); + if (!opsFirst.empty() && !opsLast.empty()) { + for (const auto &opFirst : opsFirst) { + for (const auto &opLast : opsLast) { + try { + res.emplace_back( + ConcatenatedOperation::createComputeMetadata( + {opFirst, opLast}, + !allowEmptyIntersection)); + } catch (const InvalidOperationEmptyIntersection &) { + } + } + } + if (!res.empty()) { + return res; + } + } + } + return createOperations(boundSrc->baseCRS(), boundDst->baseCRS(), context); } @@ -11987,6 +12015,21 @@ CoordinateOperationFactory::Private::createOperations( nn_interpTransformCRS)); } } + } else { + auto compSrc0BoundCrs = dynamic_cast( + componentsSrc[0].get()); + auto compDst0BoundCrs = dynamic_cast( + componentsDst[0].get()); + if (compSrc0BoundCrs && compDst0BoundCrs && + dynamic_cast( + compSrc0BoundCrs->hubCRS().get()) && + compSrc0BoundCrs->hubCRS()->_isEquivalentTo( + compDst0BoundCrs->hubCRS().get())) { + interpolationGeogCRS = + NN_NO_CHECK(util::nn_dynamic_pointer_cast< + crs::GeographicCRS>( + compSrc0BoundCrs->hubCRS())); + } } auto opSrcCRSToGeogCRS = createOperations( componentsSrc[0], interpolationGeogCRS, context); -- cgit v1.2.3 From b5fb5f070793c29bb9b60faec9d221b25e7017d4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 23:11:25 +0100 Subject: createOperations(): fix nadgrids -> nadgrids+geoidgrids --- src/iso19111/coordinateoperation.cpp | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index c1b3704c..7ee20758 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12054,6 +12054,89 @@ CoordinateOperationFactory::Private::createOperations( } } + // '+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +type=crs' to + // '+proj=longlat +ellps=GRS80 +nadgrids=@bar.gsb +geoidgrids=@bar.gtx + // +type=crs' + if (boundSrc && compoundDst) { + const auto &componentsDst = compoundDst->componentReferenceSystems(); + if (!componentsDst.empty()) { + auto compDst0BoundCrs = + dynamic_cast(componentsDst[0].get()); + if (compDst0BoundCrs) { + auto boundSrcHubAsGeogCRS = dynamic_cast( + boundSrc->hubCRS().get()); + auto compDst0BoundCrsHubAsGeogCRS = + dynamic_cast( + compDst0BoundCrs->hubCRS().get()); + if (boundSrcHubAsGeogCRS && compDst0BoundCrsHubAsGeogCRS) { + const auto &boundSrcHubAsGeogCRSDatum = + boundSrcHubAsGeogCRS->datum(); + const auto &compDst0BoundCrsHubAsGeogCRSDatum = + compDst0BoundCrsHubAsGeogCRS->datum(); + if (boundSrcHubAsGeogCRSDatum && + compDst0BoundCrsHubAsGeogCRSDatum && + boundSrcHubAsGeogCRSDatum->_isEquivalentTo( + compDst0BoundCrsHubAsGeogCRSDatum.get())) { + auto cs = cs::EllipsoidalCS:: + createLatitudeLongitudeEllipsoidalHeight( + common::UnitOfMeasure::DEGREE, + common::UnitOfMeasure::METRE); + auto intermGeog3DCRS = util::nn_static_pointer_cast< + crs::CRS>(crs::GeographicCRS::create( + util::PropertyMap() + .set(common::IdentifiedObject::NAME_KEY, + boundSrcHubAsGeogCRS->nameStr()) + .set( + common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + metadata::Extent::WORLD), + NN_NO_CHECK(boundSrcHubAsGeogCRSDatum), cs)); + auto sourceToGeog3DOps = createOperations( + sourceCRS, intermGeog3DCRS, context); + auto geog3DToTargetOps = createOperations( + intermGeog3DCRS, targetCRS, context); + for (const auto &opSrc : sourceToGeog3DOps) { + for (const auto &opDst : geog3DToTargetOps) { + if (opSrc->targetCRS() && opDst->sourceCRS() && + !opSrc->targetCRS()->_isEquivalentTo( + opDst->sourceCRS().get())) { + // Shouldn't happen normally, but typically + // one of them can be 2D and the other 3D + // due to above createOperations() not + // exactly setting the expected source and + // target CRS. + // So create an adapter operation... + auto intermOps = createOperations( + NN_NO_CHECK(opSrc->targetCRS()), + NN_NO_CHECK(opDst->sourceCRS()), + context); + if (!intermOps.empty()) { + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {opSrc, intermOps.front(), + opDst}, + !allowEmptyIntersection)); + } + } else { + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {opSrc, opDst}, + !allowEmptyIntersection)); + } + } + } + } + } + } + } + } + + // reverse of previous case + if (boundDst && compoundSrc) { + return applyInverse(createOperations(targetCRS, sourceCRS, context)); + } + return res; } //! @endcond -- cgit v1.2.3 From e1350cac43d5a9854207af3fb318a74be7fcd12f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 17 Mar 2019 19:16:04 +0100 Subject: Fix some issues raised by latest cppcheck - coordinateoperation_internal.hpp: missing 'explicit' keyword - proj.cpp: unused 'generic' member in enumeration - init.cpp: useless assignment to a_orig and es_orig, because done again a few lines below. - crs.cpp: unused variable - datum.cpp: inefficient use of find() function - io.cpp: * missing 'static' qualifier for method * useles ternary test (left and right have same value) - aeqd.cpp: useless assignment of inv and fwd, snice done again a few lines below - isea.cpp: useless assignment of resolution and aperture since done again a few lines below, and with default values when params are absent - mod_ster.cpp: useless assignment of lp.lam, overriden in below code paths. - stere.cpp: false positive, but better not modify another variable than the iterator in a for() loop. --- src/apps/proj.cpp | 1 - src/init.cpp | 4 ++-- src/iso19111/crs.cpp | 1 - src/iso19111/datum.cpp | 4 ++-- src/iso19111/io.cpp | 8 ++++---- src/projections/aeqd.cpp | 1 - src/projections/isea.cpp | 8 -------- src/projections/mod_ster.cpp | 1 - src/projections/stere.cpp | 3 ++- 9 files changed, 10 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 298a44e8..40fc5695 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -22,7 +22,6 @@ static PJ *Proj; static union { - PJ_UV (*generic)(PJ_UV, PJ *); PJ_XY (*fwd)(PJ_LP, PJ *); PJ_LP (*inv)(PJ_XY, PJ *); } proj; diff --git a/src/init.cpp b/src/init.cpp index 13ea4ae8..1c0eddf0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -673,8 +673,8 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i if (PJD_ERR_MAJOR_AXIS_NOT_GIVEN==proj_errno (PIN)) proj_errno_reset (PIN); PIN->f = 1.0/298.257223563; - PIN->a_orig = PIN->a = 6378137.0; - PIN->es_orig = PIN->es = PIN->f*(2-PIN->f); + PIN->a = 6378137.0; + PIN->es = PIN->f*(2-PIN->f); } } PIN->a_orig = PIN->a; diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 4293c087..9688883d 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2096,7 +2096,6 @@ void VerticalCRS::addLinearUnitConvert( auto &axisList = coordinateSystem()->axisList(); if (!axisList.empty()) { - auto projUnit = axisList[0]->unit().exportToPROJString(); if (axisList[0]->unit().conversionToSI() != 1.0) { formatter->addStep("unitconvert"); formatter->addParam("z_in", "m"); diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 5f7e4775..bf3092c1 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -783,7 +783,7 @@ bool Ellipsoid::lookForProjWellKnownEllps(std::string &projEllpsName, if (::fabs(b - b_iter) < 1e-10 * b_iter) { projEllpsName = proj_ellps[i].id; ellpsName = proj_ellps[i].name; - if (ellpsName.find("GRS 1980") == 0) { + if (starts_with(ellpsName, "GRS 1980")) { ellpsName = "GRS 1980"; } return true; @@ -794,7 +794,7 @@ bool Ellipsoid::lookForProjWellKnownEllps(std::string &projEllpsName, if (::fabs(rf - rf_iter) < 1e-10 * rf_iter) { projEllpsName = proj_ellps[i].id; ellpsName = proj_ellps[i].name; - if (ellpsName.find("GRS 1980") == 0) { + if (starts_with(ellpsName, "GRS 1980")) { ellpsName = "GRS 1980"; } return true; diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index d5f38fd5..7c2eb625 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -1186,7 +1186,7 @@ struct WKTParser::Private { buildPrimeMeridian(const WKTNodeNNPtr &node, const UnitOfMeasure &defaultAngularUnit); - optional getAnchor(const WKTNodeNNPtr &node); + static optional getAnchor(const WKTNodeNNPtr &node); static void parseDynamic(const WKTNodeNNPtr &dynamicNode, double &frameReferenceEpoch, @@ -6545,9 +6545,9 @@ PROJStringParser::Private::processAxisSwap(Step &step, ? AxisDirection::NORTH : (axisType == AxisType::NORTH_POLE) ? AxisDirection::SOUTH - : (axisType == AxisType::SOUTH_POLE) - ? AxisDirection::NORTH - : AxisDirection::NORTH; + /*: (axisType == AxisType::SOUTH_POLE) + ? AxisDirection::NORTH*/ + : AxisDirection::NORTH; CoordinateSystemAxisNNPtr north = createAxis( northName, northAbbev, northDir, unit, (!isGeographic && axisType == AxisType::NORTH_POLE) diff --git a/src/projections/aeqd.cpp b/src/projections/aeqd.cpp index 8566062d..882d9531 100644 --- a/src/projections/aeqd.cpp +++ b/src/projections/aeqd.cpp @@ -310,7 +310,6 @@ PJ *PROJECTION(aeqd) { break; case EQUIT: case OBLIQ: - P->inv = e_inverse; P->fwd = e_forward; Q->N1 = 1. / sqrt(1. - P->es * Q->sinph0 * Q->sinph0); Q->G = Q->sinph0 * (Q->He = P->e / sqrt(P->one_es)); Q->He *= Q->cosph0; diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index d53317c1..fc74bebe 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -1051,14 +1051,6 @@ PJ *PROJECTION(isea) { Q->dgg.o_lat = pj_param(P->ctx,P->params, "rlat_0").f; } - if (pj_param(P->ctx,P->params, "taperture").i) { - Q->dgg.aperture = pj_param(P->ctx,P->params, "iaperture").i; - } - - if (pj_param(P->ctx,P->params, "tresolution").i) { - Q->dgg.resolution = pj_param(P->ctx,P->params, "iresolution").i; - } - opt = pj_param(P->ctx,P->params, "smode").s; if (opt) { if (!strcmp(opt, "plane")) { diff --git a/src/projections/mod_ster.cpp b/src/projections/mod_ster.cpp index 83390178..b26ea289 100644 --- a/src/projections/mod_ster.cpp +++ b/src/projections/mod_ster.cpp @@ -72,7 +72,6 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ z = 2. * atan(.5 * rh); sinz = sin(z); cosz = cos(z); - lp.lam = P->lam0; if (fabs(rh) <= EPSLN) { /* if we end up here input coordinates were (0,0). * pj_inv() adds P->lam0 to lp.lam, this way we are diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp index 9b24a596..9836f341 100644 --- a/src/projections/stere.cpp +++ b/src/projections/stere.cpp @@ -165,7 +165,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ break; } - for (i = NITER; i--; phi_l = lp.phi) { + for (i = NITER; i--; ) { sinphi = P->e * sin(phi_l); lp.phi = 2. * atan (tp * pow ((1.+sinphi)/(1.-sinphi), halfe)) - halfpi; if (fabs (phi_l - lp.phi) < CONV) { @@ -174,6 +174,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ lp.lam = (xy.x == 0. && xy.y == 0.) ? 0. : atan2 (xy.x, xy.y); return lp; } + phi_l = lp.phi; } proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); -- cgit v1.2.3 From 2622d3851573cd44fc7b36bfd15f07215f434d4b Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Mon, 18 Mar 2019 23:58:41 +1300 Subject: Normalize CMake with cmakelint, 2-space indent --- src/CMakeLists.txt | 64 +++--- src/bin_cct.cmake | 10 +- src/bin_cs2cs.cmake | 11 +- src/bin_geod.cmake | 13 +- src/bin_geodtest.cmake | 6 +- src/bin_gie.cmake | 12 +- src/bin_proj.cmake | 15 +- src/bin_projinfo.cmake | 10 +- src/lib_proj.cmake | 542 +++++++++++++++++++++++++++---------------------- 9 files changed, 379 insertions(+), 304 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 122227bf..48c785a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,71 +3,77 @@ include(lib_proj.cmake) # configure executable build -option(BUILD_CCT "Build cct (coordinate conversion and transformation tool)" ON) -option(BUILD_CS2CS "Build cs2cs (coordinate systems to coordinate systems translation tool)" ON) -option(BUILD_GEOD "Build geod (computation of geodesic lines)" ON) -option(BUILD_GIE "Build gie (geospatial integrity investigation environment - a PROJ.4 test tool)" ON) -option(BUILD_PROJ "Build proj (cartographic projection tool : latlong <-> projected coordinates)" ON) -option(BUILD_PROJINFO "Build projinfo (SRS and coordinate operation metadata/query tool)" ON) +option(BUILD_CCT + "Build cct (coordinate conversion and transformation tool)" ON) +option(BUILD_CS2CS + "Build cs2cs (coordinate systems to coordinate systems translation tool)" ON) +option(BUILD_GEOD + "Build geod (computation of geodesic lines)" ON) +option(BUILD_GIE + "Build gie (geospatial integrity investigation environment)" ON) +option(BUILD_PROJ + "Build proj (cartographic projection tool)" ON) +option(BUILD_PROJINFO + "Build projinfo (SRS and coordinate operation metadata/query tool)" ON) if(NOT MSVC) - if (NOT APPLE) + if(NOT APPLE) # Use relative path so that package is relocatable set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${LIBDIR}") - else () - set (CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIBDIR}") + else() + set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIBDIR}") # TO DO: cmake 2.8.12 introduces a way to make the install tree # relocatable with OSX via # (1) set(CMAKE_MACOSX_RPATH ON) and # (2) setting the INSTALL_RPATH property on the executables to # "@loader_path/../${LIBDIR}" - endif () + endif() -else () +else() # Linking to setargv.obj enables wildcard globbing for the # command line utilities, when compiling with MSVC - # https://docs.microsoft.com/da-dk/cpp/c-language/expanding-wildcard-arguments + # https://docs.microsoft.com/cpp/c-language/expanding-wildcard-arguments set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} setargv.obj") -endif () +endif() if(BUILD_CCT) - include(bin_cct.cmake) - set(BIN_TARGETS ${BIN_TARGETS} cct) -endif(BUILD_CCT) + include(bin_cct.cmake) + set(BIN_TARGETS ${BIN_TARGETS} cct) +endif() if(BUILD_CS2CS) - include(bin_cs2cs.cmake) - set(BIN_TARGETS ${BIN_TARGETS} cs2cs) -endif(BUILD_CS2CS) + include(bin_cs2cs.cmake) + set(BIN_TARGETS ${BIN_TARGETS} cs2cs) +endif() if(BUILD_GEOD) include(bin_geod.cmake) include(bin_geodtest.cmake) set(BIN_TARGETS ${BIN_TARGETS} geod) -endif(BUILD_GEOD) +endif() if(BUILD_PROJ) include(bin_proj.cmake) set(BIN_TARGETS ${BIN_TARGETS} binproj) -endif(BUILD_PROJ) +endif() if(BUILD_PROJINFO) include(bin_projinfo.cmake) set(BIN_TARGETS ${BIN_TARGETS} binprojinfo) -endif(BUILD_PROJINFO) +endif() if(BUILD_GIE) - include(bin_gie.cmake) - set(BIN_TARGETS ${BIN_TARGETS} gie) -endif(BUILD_GIE) + include(bin_gie.cmake) + set(BIN_TARGETS ${BIN_TARGETS} gie) +endif() -if (MSVC OR CMAKE_CONFIGURATION_TYPES) +if(MSVC OR CMAKE_CONFIGURATION_TYPES) if(BIN_TARGETS) # Add _d suffix for your debug versions of the tools - set_target_properties (${BIN_TARGETS} PROPERTIES + set_target_properties(${BIN_TARGETS} PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) - endif(BIN_TARGETS) -endif () + endif() +endif() diff --git a/src/bin_cct.cmake b/src/bin_cct.cmake index e400caf3..9c4b0804 100644 --- a/src/bin_cct.cmake +++ b/src/bin_cct.cmake @@ -1,4 +1,8 @@ -set(CCT_SRC apps/cct.cpp apps/proj_strtod.cpp apps/proj_strtod.h) +set(CCT_SRC + apps/cct.cpp + apps/proj_strtod.cpp + apps/proj_strtod.h +) set(CCT_INCLUDE apps/optargpm.h) source_group("Source Files\\Bin" FILES ${CCT_SRC}) @@ -6,8 +10,8 @@ source_group("Source Files\\Bin" FILES ${CCT_SRC}) add_executable(cct ${CCT_SRC} ${CCT_INCLUDE}) target_link_libraries(cct ${PROJ_LIBRARIES}) install(TARGETS cct - RUNTIME DESTINATION ${BINDIR}) + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(cct PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(cct PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_cs2cs.cmake b/src/bin_cs2cs.cmake index d520192c..9b2f2f4f 100644 --- a/src/bin_cs2cs.cmake +++ b/src/bin_cs2cs.cmake @@ -1,14 +1,15 @@ -set(CS2CS_SRC apps/cs2cs.cpp - apps/emess.cpp +set(CS2CS_SRC + apps/cs2cs.cpp + apps/emess.cpp ) source_group("Source Files\\Bin" FILES ${CS2CS_SRC}) add_executable(cs2cs ${CS2CS_SRC} ${CS2CS_INCLUDE}) target_link_libraries(cs2cs ${PROJ_LIBRARIES}) -install(TARGETS cs2cs - RUNTIME DESTINATION ${BINDIR}) +install(TARGETS cs2cs + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(cs2cs PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(cs2cs PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_geod.cmake b/src/bin_geod.cmake index 049da318..7221958a 100644 --- a/src/bin_geod.cmake +++ b/src/bin_geod.cmake @@ -1,7 +1,8 @@ -set(GEOD_SRC apps/geod.cpp - apps/geod_set.cpp - apps/geod_interface.cpp - apps/emess.cpp +set(GEOD_SRC + apps/geod.cpp + apps/geod_set.cpp + apps/geod_interface.cpp + apps/emess.cpp ) set(GEOD_INCLUDE apps/geod_interface.h) @@ -11,8 +12,8 @@ source_group("Source Files\\Bin" FILES ${GEOD_SRC} ${GEOD_INCLUDE}) add_executable(geod ${GEOD_SRC} ${GEOD_INCLUDE}) target_link_libraries(geod ${PROJ_LIBRARIES}) install(TARGETS geod - RUNTIME DESTINATION ${BINDIR}) + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(geod PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(geod PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_geodtest.cmake b/src/bin_geodtest.cmake index 31de499d..4cc98197 100644 --- a/src/bin_geodtest.cmake +++ b/src/bin_geodtest.cmake @@ -1,4 +1,4 @@ -set(GEODTEST_SRC tests/geodtest.cpp ) +set(GEODTEST_SRC tests/geodtest.cpp) set(GEODTEST_INCLUDE) source_group("Source Files\\Bin" FILES ${GEODTEST_SRC} ${GEODTEST_INCLUDE}) @@ -9,8 +9,8 @@ target_link_libraries(geodtest ${PROJ_LIBRARIES}) # Do not install # Instead run as a test -add_test (NAME geodesic-test COMMAND geodtest) +add_test(NAME geodesic-test COMMAND geodtest) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(geodtest PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(geodtest PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_gie.cmake b/src/bin_gie.cmake index 497315f9..a96c4c1c 100644 --- a/src/bin_gie.cmake +++ b/src/bin_gie.cmake @@ -1,6 +1,8 @@ -set(GIE_SRC apps/gie.cpp - apps/proj_strtod.cpp - apps/proj_strtod.h) +set(GIE_SRC + apps/gie.cpp + apps/proj_strtod.cpp + apps/proj_strtod.h +) set(GIE_INCLUDE apps/optargpm.h) source_group("Source Files\\Bin" FILES ${GIE_SRC}) @@ -8,8 +10,8 @@ source_group("Source Files\\Bin" FILES ${GIE_SRC}) add_executable(gie ${GIE_SRC} ${GIE_INCLUDE}) target_link_libraries(gie ${PROJ_LIBRARIES}) install(TARGETS gie - RUNTIME DESTINATION ${BINDIR}) + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(gie PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(gie PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_proj.cmake b/src/bin_proj.cmake index 76e2ae9f..c55ccfda 100644 --- a/src/bin_proj.cmake +++ b/src/bin_proj.cmake @@ -1,5 +1,6 @@ -set(PROJ_SRC apps/proj.cpp - apps/emess.cpp +set(PROJ_SRC + apps/proj.cpp + apps/emess.cpp ) source_group("Source Files\\Bin" FILES ${PROJ_SRC}) @@ -7,12 +8,12 @@ source_group("Source Files\\Bin" FILES ${PROJ_SRC}) #Executable add_executable(binproj ${PROJ_SRC}) set_target_properties(binproj - PROPERTIES - OUTPUT_NAME proj) + PROPERTIES + OUTPUT_NAME proj) target_link_libraries(binproj ${PROJ_LIBRARIES}) -install(TARGETS binproj - RUNTIME DESTINATION ${BINDIR}) +install(TARGETS binproj + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(binproj PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(binproj PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/bin_projinfo.cmake b/src/bin_projinfo.cmake index ea6f1006..0691d739 100644 --- a/src/bin_projinfo.cmake +++ b/src/bin_projinfo.cmake @@ -5,12 +5,12 @@ source_group("Source Files\\Bin" FILES ${PROJINFO_SRC}) #Executable add_executable(binprojinfo ${PROJINFO_SRC}) set_target_properties(binprojinfo - PROPERTIES - OUTPUT_NAME projinfo) + PROPERTIES + OUTPUT_NAME projinfo) target_link_libraries(binprojinfo ${PROJ_LIBRARIES}) -install(TARGETS binprojinfo - RUNTIME DESTINATION ${BINDIR}) +install(TARGETS binprojinfo + RUNTIME DESTINATION ${BINDIR}) if(MSVC AND BUILD_LIBPROJ_SHARED) - target_compile_definitions(binprojinfo PRIVATE PROJ_MSVC_DLL_IMPORT=1) + target_compile_definitions(binprojinfo PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index f28a1d68..72a8cc59 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -6,48 +6,52 @@ message(STATUS "") # default config, shared on unix and static on Windows if(UNIX) - set(BUILD_LIBPROJ_SHARED_DEFAULT ON ) -endif(UNIX) -if( WIN32) - set(BUILD_LIBPROJ_SHARED_DEFAULT OFF) -endif(WIN32) -option(BUILD_LIBPROJ_SHARED "Build libproj library shared." ${BUILD_LIBPROJ_SHARED_DEFAULT}) + set(BUILD_LIBPROJ_SHARED_DEFAULT ON) +endif() +if(WIN32) + set(BUILD_LIBPROJ_SHARED_DEFAULT OFF) +endif() +option(BUILD_LIBPROJ_SHARED + "Build libproj library shared." ${BUILD_LIBPROJ_SHARED_DEFAULT}) if(BUILD_LIBPROJ_SHARED) set(PROJ_LIBRARY_TYPE SHARED) -else(BUILD_LIBPROJ_SHARED) +else() set(PROJ_LIBRARY_TYPE STATIC) -endif(BUILD_LIBPROJ_SHARED) +endif() option(USE_THREAD "Build libproj with thread/mutex support " ON) if(NOT USE_THREAD) - add_definitions( -DMUTEX_stub) -endif(NOT USE_THREAD) + add_definitions(-DMUTEX_stub) +endif() find_package(Threads QUIET) -if(USE_THREAD AND Threads_FOUND AND CMAKE_USE_WIN32_THREADS_INIT ) - add_definitions( -DMUTEX_win32) -elseif(USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT ) - add_definitions( -DMUTEX_pthread) +if(USE_THREAD AND Threads_FOUND AND CMAKE_USE_WIN32_THREADS_INIT) + add_definitions(-DMUTEX_win32) +elseif(USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) + add_definitions(-DMUTEX_pthread) elseif(USE_THREAD AND NOT Threads_FOUND) - message(FATAL_ERROR "No thread library found and thread/mutex support is required by USE_THREAD option") + message(FATAL_ERROR + "No thread library found and thread/mutex support is " + "required by USE_THREAD option") endif() option(ENABLE_LTO "Build library with LTO optimization (if available)." OFF) if(ENABLE_LTO) - if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") - include (CheckCXXSourceCompiles) - SET(CMAKE_REQUIRED_FLAGS "-Wl,-flto") - check_cxx_source_compiles("int main(){ return 0; }" COMPILER_SUPPORTS_FLTO_FLAG) - IF(COMPILER_SUPPORTS_FLTO_FLAG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") - ENDIF() - else() - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-flto" COMPILER_SUPPORTS_FLTO_FLAG) - if(COMPILER_SUPPORTS_FLTO_FLAG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") - endif() + if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_FLAGS "-Wl,-flto") + check_cxx_source_compiles("int main(){ return 0; }" + COMPILER_SUPPORTS_FLTO_FLAG) + if(COMPILER_SUPPORTS_FLTO_FLAG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") endif() + else() + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_FLTO_FLAG) + if(COMPILER_SUPPORTS_FLTO_FLAG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") + endif() + endif() endif() @@ -55,196 +59,247 @@ endif() ### library source list and include_list ### ############################################## -SET(SRC_LIBPROJ_PROJECTIONS - projections/aeqd.cpp - projections/gnom.cpp - projections/laea.cpp - projections/mod_ster.cpp - projections/nsper.cpp - projections/nzmg.cpp - projections/ortho.cpp - projections/stere.cpp - projections/sterea.cpp - projections/aea.cpp - projections/bipc.cpp - projections/bonne.cpp - projections/eqdc.cpp - projections/isea.cpp - projections/ccon.cpp - projections/imw_p.cpp - projections/krovak.cpp - projections/lcc.cpp - projections/poly.cpp - projections/rpoly.cpp - projections/sconics.cpp - projections/rouss.cpp - projections/cass.cpp - projections/cc.cpp - projections/cea.cpp - projections/eqc.cpp - projections/gall.cpp - projections/labrd.cpp - projections/lsat.cpp - projections/misrsom.cpp - projections/merc.cpp - projections/mill.cpp - projections/ocea.cpp - projections/omerc.cpp - projections/somerc.cpp - projections/tcc.cpp - projections/tcea.cpp - projections/times.cpp - projections/tmerc.cpp - projections/tobmerc.cpp - projections/airy.cpp - projections/aitoff.cpp - projections/august.cpp - projections/bacon.cpp - projections/bertin1953.cpp - projections/chamb.cpp - projections/hammer.cpp - projections/lagrng.cpp - projections/larr.cpp - projections/lask.cpp - projections/latlong.cpp - projections/nicol.cpp - projections/ob_tran.cpp - projections/oea.cpp - projections/tpeqd.cpp - projections/vandg.cpp - projections/vandg2.cpp - projections/vandg4.cpp - projections/wag7.cpp - projections/lcca.cpp - projections/geos.cpp - projections/boggs.cpp - projections/collg.cpp - projections/comill.cpp - projections/crast.cpp - projections/denoy.cpp - projections/eck1.cpp - projections/eck2.cpp - projections/eck3.cpp - projections/eck4.cpp - projections/eck5.cpp - projections/fahey.cpp - projections/fouc_s.cpp - projections/gins8.cpp - projections/gstmerc.cpp - projections/gn_sinu.cpp - projections/goode.cpp - projections/igh.cpp - projections/hatano.cpp - projections/loxim.cpp - projections/mbt_fps.cpp - projections/mbtfpp.cpp - projections/mbtfpq.cpp - projections/moll.cpp - projections/nell.cpp - projections/nell_h.cpp - projections/patterson.cpp - projections/putp2.cpp - projections/putp3.cpp - projections/putp4p.cpp - projections/putp5.cpp - projections/putp6.cpp - projections/qsc.cpp - projections/robin.cpp - projections/sch.cpp - projections/sts.cpp - projections/urm5.cpp - projections/urmfps.cpp - projections/wag2.cpp - projections/wag3.cpp - projections/wink1.cpp - projections/wink2.cpp - projections/healpix.cpp - projections/natearth.cpp - projections/natearth2.cpp - projections/calcofi.cpp - projections/eqearth.cpp +set(SRC_LIBPROJ_PROJECTIONS + projections/aeqd.cpp + projections/gnom.cpp + projections/laea.cpp + projections/mod_ster.cpp + projections/nsper.cpp + projections/nzmg.cpp + projections/ortho.cpp + projections/stere.cpp + projections/sterea.cpp + projections/aea.cpp + projections/bipc.cpp + projections/bonne.cpp + projections/eqdc.cpp + projections/isea.cpp + projections/ccon.cpp + projections/imw_p.cpp + projections/krovak.cpp + projections/lcc.cpp + projections/poly.cpp + projections/rpoly.cpp + projections/sconics.cpp + projections/rouss.cpp + projections/cass.cpp + projections/cc.cpp + projections/cea.cpp + projections/eqc.cpp + projections/gall.cpp + projections/labrd.cpp + projections/lsat.cpp + projections/misrsom.cpp + projections/merc.cpp + projections/mill.cpp + projections/ocea.cpp + projections/omerc.cpp + projections/somerc.cpp + projections/tcc.cpp + projections/tcea.cpp + projections/times.cpp + projections/tmerc.cpp + projections/tobmerc.cpp + projections/airy.cpp + projections/aitoff.cpp + projections/august.cpp + projections/bacon.cpp + projections/bertin1953.cpp + projections/chamb.cpp + projections/hammer.cpp + projections/lagrng.cpp + projections/larr.cpp + projections/lask.cpp + projections/latlong.cpp + projections/nicol.cpp + projections/ob_tran.cpp + projections/oea.cpp + projections/tpeqd.cpp + projections/vandg.cpp + projections/vandg2.cpp + projections/vandg4.cpp + projections/wag7.cpp + projections/lcca.cpp + projections/geos.cpp + projections/boggs.cpp + projections/collg.cpp + projections/comill.cpp + projections/crast.cpp + projections/denoy.cpp + projections/eck1.cpp + projections/eck2.cpp + projections/eck3.cpp + projections/eck4.cpp + projections/eck5.cpp + projections/fahey.cpp + projections/fouc_s.cpp + projections/gins8.cpp + projections/gstmerc.cpp + projections/gn_sinu.cpp + projections/goode.cpp + projections/igh.cpp + projections/hatano.cpp + projections/loxim.cpp + projections/mbt_fps.cpp + projections/mbtfpp.cpp + projections/mbtfpq.cpp + projections/moll.cpp + projections/nell.cpp + projections/nell_h.cpp + projections/patterson.cpp + projections/putp2.cpp + projections/putp3.cpp + projections/putp4p.cpp + projections/putp5.cpp + projections/putp6.cpp + projections/qsc.cpp + projections/robin.cpp + projections/sch.cpp + projections/sts.cpp + projections/urm5.cpp + projections/urmfps.cpp + projections/wag2.cpp + projections/wag3.cpp + projections/wink1.cpp + projections/wink2.cpp + projections/healpix.cpp + projections/natearth.cpp + projections/natearth2.cpp + projections/calcofi.cpp + projections/eqearth.cpp ) -SET(SRC_LIBPROJ_CONVERSIONS - conversions/axisswap.cpp - conversions/cart.cpp - conversions/geoc.cpp - conversions/geocent.cpp - conversions/unitconvert.cpp +set(SRC_LIBPROJ_CONVERSIONS + conversions/axisswap.cpp + conversions/cart.cpp + conversions/geoc.cpp + conversions/geocent.cpp + conversions/unitconvert.cpp ) -SET(SRC_LIBPROJ_TRANSFORMATIONS - transformations/affine.cpp - transformations/deformation.cpp - transformations/helmert.cpp - transformations/hgridshift.cpp - transformations/horner.cpp - transformations/molodensky.cpp - transformations/vgridshift.cpp +set(SRC_LIBPROJ_TRANSFORMATIONS + transformations/affine.cpp + transformations/deformation.cpp + transformations/helmert.cpp + transformations/hgridshift.cpp + transformations/horner.cpp + transformations/molodensky.cpp + transformations/vgridshift.cpp ) -SET(SRC_LIBPROJ_ISO19111 - iso19111/static.cpp - iso19111/util.cpp - iso19111/metadata.cpp - iso19111/common.cpp - iso19111/crs.cpp - iso19111/datum.cpp - iso19111/coordinatesystem.cpp - iso19111/coordinateoperation.cpp - iso19111/io.cpp - iso19111/internal.cpp - iso19111/factory.cpp - iso19111/c_api.cpp +set(SRC_LIBPROJ_ISO19111 + iso19111/static.cpp + iso19111/util.cpp + iso19111/metadata.cpp + iso19111/common.cpp + iso19111/crs.cpp + iso19111/datum.cpp + iso19111/coordinatesystem.cpp + iso19111/coordinateoperation.cpp + iso19111/io.cpp + iso19111/internal.cpp + iso19111/factory.cpp + iso19111/c_api.cpp ) -SET(SRC_LIBPROJ_CORE - pj_list.h proj_internal.h proj_math.h - aasincos.cpp adjlon.cpp - dmstor.cpp auth.cpp - deriv.cpp ell_set.cpp ellps.cpp errno.cpp - factors.cpp fwd.cpp init.cpp inv.cpp - list.cpp malloc.cpp mlfn.cpp msfn.cpp proj_mdist.cpp - open_lib.cpp param.cpp phi2.cpp pr_list.cpp - qsfn.cpp strerrno.cpp - tsfn.cpp units.cpp ctx.cpp log.cpp zpoly1.cpp rtodms.cpp - release.cpp gauss.cpp - fileapi.cpp - gc_reader.cpp gridcatalog.cpp - nad_cvt.cpp nad_init.cpp nad_intr.cpp - apply_gridshift.cpp datums.cpp datum_set.cpp transform.cpp - geocent.cpp geocent.h utils.cpp gridinfo.cpp gridlist.cpp - jniproj.cpp mutex.cpp initcache.cpp apply_vgridshift.cpp geodesic.c - strtod.cpp math.cpp - 4D_api.cpp pipeline.cpp - internal.cpp - wkt_parser.hpp wkt_parser.cpp - wkt1_parser.h wkt1_parser.cpp - wkt1_generated_parser.h wkt1_generated_parser.c - wkt2_parser.h wkt2_parser.cpp - wkt2_generated_parser.h wkt2_generated_parser.c - ${CMAKE_CURRENT_BINARY_DIR}/proj_config.h +set(SRC_LIBPROJ_CORE + 4D_api.cpp + aasincos.cpp + adjlon.cpp + apply_gridshift.cpp + apply_vgridshift.cpp + auth.cpp + ctx.cpp + datum_set.cpp + datums.cpp + deriv.cpp + dmstor.cpp + ell_set.cpp + ellps.cpp + errno.cpp + factors.cpp + fileapi.cpp + fwd.cpp + gauss.cpp + gc_reader.cpp + geocent.cpp + geocent.h + geodesic.c + gridcatalog.cpp + gridinfo.cpp + gridlist.cpp + init.cpp + initcache.cpp + internal.cpp + inv.cpp + jniproj.cpp + list.cpp + log.cpp + malloc.cpp + math.cpp + mlfn.cpp + msfn.cpp + mutex.cpp + nad_cvt.cpp + nad_init.cpp + nad_intr.cpp + open_lib.cpp + param.cpp + phi2.cpp + pipeline.cpp + pj_list.h + pr_list.cpp + proj_internal.h + proj_math.h + proj_mdist.cpp + qsfn.cpp + release.cpp + rtodms.cpp + strerrno.cpp + strtod.cpp + transform.cpp + tsfn.cpp + units.cpp + utils.cpp + wkt1_generated_parser.c + wkt1_generated_parser.h + wkt1_parser.cpp + wkt1_parser.h + wkt2_generated_parser.c + wkt2_generated_parser.h + wkt2_parser.cpp + wkt2_parser.h + wkt_parser.cpp + wkt_parser.hpp + zpoly1.cpp + ${CMAKE_CURRENT_BINARY_DIR}/proj_config.h ) set(HEADERS_LIBPROJ - proj_api.h - proj.h - proj_experimental.h - proj_constants.h - geodesic.h + proj_api.h + proj.h + proj_experimental.h + proj_constants.h + geodesic.h ) # Group source files for IDE source explorers (e.g. Visual Studio) -source_group("Header Files" FILES ${HEADERS_LIBPROJ}) -source_group("Source Files\\Core" FILES ${SRC_LIBPROJ_CORE}) -source_group("Source Files\\Conversions" FILES ${SRC_LIBPROJ_CONVERSIONS}) -source_group("Source Files\\Projections" FILES ${SRC_LIBPROJ_PROJECTIONS}) -source_group("Source Files\\Transformations" FILES ${SRC_LIBPROJ_TRANSFORMATIONS}) -source_group("Source Files\\ISO19111" FILES ${SRC_LIBPROJ_ISO19111}) +source_group("Header Files" + FILES ${HEADERS_LIBPROJ}) +source_group("Source Files\\Core" + FILES ${SRC_LIBPROJ_CORE}) +source_group("Source Files\\Conversions" + FILES ${SRC_LIBPROJ_CONVERSIONS}) +source_group("Source Files\\Projections" + FILES ${SRC_LIBPROJ_PROJECTIONS}) +source_group("Source Files\\Transformations" + FILES ${SRC_LIBPROJ_TRANSFORMATIONS}) +source_group("Source Files\\ISO19111" + FILES ${SRC_LIBPROJ_ISO19111}) include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories( ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) source_group("CMake Files" FILES CMakeLists.txt) @@ -258,45 +313,48 @@ option(JNI_SUPPORT "Build support of java/jni wrapping for proj library" OFF) find_package(JNI QUIET) if(JNI_SUPPORT AND NOT JNI_FOUND) message(FATAL_ERROR "jni support is required but jni is not found") -endif(JNI_SUPPORT AND NOT JNI_FOUND) +endif() boost_report_value(JNI_SUPPORT) if(JNI_SUPPORT) - set(SRC_LIBPROJ_CORE ${SRC_LIBPROJ_CORE} - jniproj.cpp ) - set(HEADERS_LIBPROJ ${HEADERS_LIBPROJ} - org_proj4_PJ.h) + set(SRC_LIBPROJ_CORE + ${SRC_LIBPROJ_CORE} jniproj.cpp) + set(HEADERS_LIBPROJ + ${HEADERS_LIBPROJ} org_proj4_PJ.h) source_group("Source Files\\JNI" FILES ${SRC_LIBPROJ_JNI}) add_definitions(-DJNI_ENABLED) - include_directories( ${JNI_INCLUDE_DIRS}) + include_directories(${JNI_INCLUDE_DIRS}) boost_report_value(JNI_INCLUDE_DIRS) -endif(JNI_SUPPORT) +endif() ################################################# ## targets: libproj and proj_config.h ################################################# -set(ALL_LIBPROJ_SOURCES ${SRC_LIBPROJ_CORE} - ${SRC_LIBPROJ_CONVERSIONS} - ${SRC_LIBPROJ_PROJECTIONS} - ${SRC_LIBPROJ_TRANSFORMATIONS} - ${SRC_LIBPROJ_ISO19111} +set(ALL_LIBPROJ_SOURCES + ${SRC_LIBPROJ_CORE} + ${SRC_LIBPROJ_CONVERSIONS} + ${SRC_LIBPROJ_PROJECTIONS} + ${SRC_LIBPROJ_TRANSFORMATIONS} + ${SRC_LIBPROJ_ISO19111} ) -set(ALL_LIBPROJ_HEADERS ${HEADERS_LIBPROJ} ) +set(ALL_LIBPROJ_HEADERS ${HEADERS_LIBPROJ}) # Core targets configuration string(TOLOWER "${PROJECT_INTERN_NAME}" PROJECTNAMEL) set(PROJ_CORE_TARGET ${PROJECTNAMEL}) proj_target_output_name(${PROJ_CORE_TARGET} PROJ_CORE_TARGET_OUTPUT_NAME) -add_library( ${PROJ_CORE_TARGET} - ${PROJ_LIBRARY_TYPE} - ${ALL_LIBPROJ_SOURCES} - ${ALL_LIBPROJ_HEADERS} - ${PROJ_RESOURCES} ) +add_library( + ${PROJ_CORE_TARGET} + ${PROJ_LIBRARY_TYPE} + ${ALL_LIBPROJ_SOURCES} + ${ALL_LIBPROJ_HEADERS} + ${PROJ_RESOURCES} +) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories (${PROJ_CORE_TARGET} INTERFACE +if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + target_include_directories(${PROJ_CORE_TARGET} INTERFACE $) -endif () +endif() if(WIN32) set_target_properties(${PROJ_CORE_TARGET} @@ -319,45 +377,47 @@ else() endif() set_target_properties(${PROJ_CORE_TARGET} - PROPERTIES - LINKER_LANGUAGE CXX) + PROPERTIES + LINKER_LANGUAGE CXX) ############################################## # Link properties ############################################## set(PROJ_LIBRARIES ${PROJ_CORE_TARGET}) -set(PROJ_LIBRARIES ${PROJ_LIBRARIES} PARENT_SCOPE) # hack, required for test/unit +# hack, required for test/unit +set(PROJ_LIBRARIES ${PROJ_LIBRARIES} PARENT_SCOPE) if(UNIX) - find_library(M_LIB m) - if(M_LIB) - TARGET_LINK_LIBRARIES(${PROJ_CORE_TARGET} -lm) - endif() -endif(UNIX) + find_library(M_LIB m) + if(M_LIB) + target_link_libraries(${PROJ_CORE_TARGET} -lm) + endif() +endif() if(USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) - TARGET_LINK_LIBRARIES(${PROJ_CORE_TARGET} ${CMAKE_THREAD_LIBS_INIT}) -endif(USE_THREAD AND Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) + target_link_libraries(${PROJ_CORE_TARGET} ${CMAKE_THREAD_LIBS_INIT}) +endif() include_directories(${SQLITE3_INCLUDE_DIR}) -TARGET_LINK_LIBRARIES(${PROJ_CORE_TARGET} ${SQLITE3_LIBRARY}) +target_link_libraries(${PROJ_CORE_TARGET} ${SQLITE3_LIBRARY}) if(MSVC) - target_compile_definitions(${PROJ_CORE_TARGET} PRIVATE PROJ_MSVC_DLL_EXPORT=1) + target_compile_definitions(${PROJ_CORE_TARGET} + PRIVATE PROJ_MSVC_DLL_EXPORT=1) endif() ############################################## # install ############################################## install(TARGETS ${PROJ_CORE_TARGET} - EXPORT targets - RUNTIME DESTINATION ${BINDIR} - LIBRARY DESTINATION ${LIBDIR} - ARCHIVE DESTINATION ${LIBDIR} - FRAMEWORK DESTINATION ${FRAMEWORKDIR}) + EXPORT targets + RUNTIME DESTINATION ${BINDIR} + LIBRARY DESTINATION ${LIBDIR} + ARCHIVE DESTINATION ${LIBDIR} + FRAMEWORK DESTINATION ${FRAMEWORKDIR}) if(NOT BUILD_FRAMEWORKS_AND_BUNDLE) install(FILES ${ALL_LIBPROJ_HEADERS} - DESTINATION ${INCLUDEDIR}) -endif(NOT BUILD_FRAMEWORKS_AND_BUNDLE) + DESTINATION ${INCLUDEDIR}) +endif() ############################################## # Core configuration summary -- cgit v1.2.3 From c5cc0f74fd912cef2872da227fa2bb2b47f116c6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 19 Mar 2019 11:11:42 +0100 Subject: Doc: impove doc about OGC URN --- src/iso19111/io.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 7c2eb625..a160a4e3 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4455,8 +4455,10 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, *
  • WKT string
  • *
  • PROJ string
  • *
  • database code, prefixed by its authoriy. e.g. "EPSG:4326"
  • - *
  • URN. e.g. "urn:ogc:def:crs:EPSG::4326", - * "urn:ogc:def:coordinateOperation:EPSG::1671"
  • + *
  • OGC URN. e.g. "urn:ogc:def:crs:EPSG::4326", + * "urn:ogc:def:coordinateOperation:EPSG::1671", + * "urn:ogc:def:ellipsoid:EPSG::7001" + * or "urn:ogc:def:datum:EPSG::6326"
  • *
  • an objet name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
  • @@ -4489,8 +4491,10 @@ BaseObjectNNPtr createFromUserInput(const std::string &text, *
  • WKT string
  • *
  • PROJ string
  • *
  • database code, prefixed by its authoriy. e.g. "EPSG:4326"
  • - *
  • URN. e.g. "urn:ogc:def:crs:EPSG::4326", - * "urn:ogc:def:coordinateOperation:EPSG::1671"
  • + *
  • OGC URN. e.g. "urn:ogc:def:crs:EPSG::4326", + * "urn:ogc:def:coordinateOperation:EPSG::1671", + * "urn:ogc:def:ellipsoid:EPSG::7001" + * or "urn:ogc:def:datum:EPSG::6326"
  • *
  • an objet name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
  • -- cgit v1.2.3 From 1b8b720bb742a50815b70f2025d9e1d5378899b2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 19 Mar 2019 12:56:33 +0100 Subject: proj_create_crs_to_crs: better deal with coordinates outside of bbox (fixes #1329) In case several coordinate operations are returned for a CRS to CRS transformation, we currently determine the one to use by selecting the first operation whose bounding box contains the input point. This commit adds a fallback case where after doing that first iteration and finding no appropriate candidate, we try again by selecting the first operation available that does not involve grid based transformations. --- src/4D_api.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 4f13f238..d0b2748e 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -51,6 +51,7 @@ #include "proj/common.hpp" #include "proj/coordinateoperation.hpp" #include "proj/internal/internal.hpp" +#include "proj/internal/io_internal.hpp" using namespace NS_PROJ::internal; @@ -192,6 +193,8 @@ similarly, but prefers the 2D resp. 3D interfaces if available. direction = opposite_direction(direction); if( !P->alternativeCoordinateOperations.empty() ) { + // Do a first pass and select the first coordinate operation whose area + // of use is compatible with the input coordinate int i = 0; for( const auto &alt: P->alternativeCoordinateOperations ) { if( direction == PJ_FWD ) { @@ -223,6 +226,35 @@ similarly, but prefers the 2D resp. 3D interfaces if available. } i ++; } + + // In case we did not find an operation whose area of use is compatible + // with the input coordinate, then goes through again the list, and + // use the first operation that does not require grids. + i = 0; + for( const auto &alt: P->alternativeCoordinateOperations ) { + auto coordOperation = dynamic_cast< + NS_PROJ::operation::CoordinateOperation*>(alt.pj->iso_obj.get()); + if( coordOperation ) { + if( coordOperation->gridsNeeded(P->ctx->cpp_context ? + P->ctx->cpp_context->databaseContext.as_nullable() : + nullptr).empty() ) { + if( P->iCurCoordOp != i ) { + std::string msg("Using coordinate operation "); + msg += alt.name; + pj_log(P->ctx, PJ_LOG_TRACE, msg.c_str()); + P->iCurCoordOp = i; + } + if( direction == PJ_FWD ) { + return pj_fwd4d( coord, alt.pj ); + } + else { + return pj_inv4d( coord, alt.pj ); + } + } + } + i++; + } + proj_errno_set (P, EINVAL); return proj_coord_error (); } -- cgit v1.2.3 From 20b1fac56fc23950790b2f46761b8308d455daa9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 11:46:39 +0100 Subject: sterea: prevent division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13790 Credit to OSS Fuzz --- src/projections/sterea.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/sterea.cpp b/src/projections/sterea.cpp index b6ebc7b4..964bb588 100644 --- a/src/projections/sterea.cpp +++ b/src/projections/sterea.cpp @@ -53,7 +53,12 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ sinc = sin(lp.phi); cosc = cos(lp.phi); cosl = cos(lp.lam); - k = P->k0 * Q->R2 / (1. + Q->sinc0 * sinc + Q->cosc0 * cosc * cosl); + const double denom = 1. + Q->sinc0 * sinc + Q->cosc0 * cosc * cosl; + if( denom == 0.0 ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().xy; + } + k = P->k0 * Q->R2 / denom; xy.x = k * cosc * sin(lp.lam); xy.y = k * (Q->cosc0 * sinc - Q->sinc0 * cosc * cosl); return xy; -- cgit v1.2.3 From 7ae1b8e86a694e25ef3785ac1896fdb8ee5f487c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 18:07:21 +0100 Subject: imw_p: prevent division by zero in inverse path Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13828 Credit to OSS Fuzz --- src/projections/imw_p.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp index 723fcc48..41882df2 100644 --- a/src/projections/imw_p.cpp +++ b/src/projections/imw_p.cpp @@ -116,7 +116,12 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ lp.lam = xy.x / cos(lp.phi); do { t = loc_for(lp, P, &yc); - lp.phi = ((lp.phi - Q->phi_1) * (xy.y - yc) / (t.y - yc)) + Q->phi_1; + const double denom = t.y - yc; + if( denom == 0 ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().lp; + } + lp.phi = ((lp.phi - Q->phi_1) * (xy.y - yc) / denom) + Q->phi_1; lp.lam = lp.lam * xy.x / t.x; i ++; } while (i < N_MAX_ITER && @@ -124,7 +129,8 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ if( i == N_MAX_ITER ) { - lp.lam = lp.phi = HUGE_VAL; + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().lp; } return lp; -- cgit v1.2.3 From 61166380276a0e99b980dfdc6b43ea4656846c08 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 18:13:12 +0100 Subject: laea: error out if |lat_0|>90 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13829 Credit to OSS Fuzz --- src/projections/laea.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/projections/laea.cpp b/src/projections/laea.cpp index 22fb1691..11b89a96 100644 --- a/src/projections/laea.cpp +++ b/src/projections/laea.cpp @@ -248,6 +248,9 @@ PJ *PROJECTION(laea) { P->destructor = destructor; t = fabs(P->phi0); + if (t > M_HALFPI + EPS10 ) { + return destructor(P, PJD_ERR_LAT_LARGER_THAN_90); + } if (fabs(t - M_HALFPI) < EPS10) Q->mode = P->phi0 < 0. ? S_POLE : N_POLE; else if (fabs(t) < EPS10) -- cgit v1.2.3 From 81ee400af413e4b2449213d269c1422b8611e3aa Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 18:25:46 +0100 Subject: pj_calc_ellipsoid_params(): reject f=1 To avoid division by zero of b. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13830 Credit to OSS Fuzz --- src/ell_set.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ell_set.cpp b/src/ell_set.cpp index 386b4f46..d0714bee 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -542,6 +542,10 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { /* flattening */ if (0==P->f) P->f = 1 - cos (P->alpha); /* = 1 - sqrt (1 - PIN->es); */ + if (P->f == 1.0) { + pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER; + } P->rf = P->f != 0.0 ? 1.0/P->f: HUGE_VAL; /* second flattening */ -- cgit v1.2.3 From c223eb7753c9241defcfba361ade49f1b20e6fd3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 18:58:04 +0100 Subject: ob_tran: detect potential recursion Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12266 Credit to OSS Fuzz --- src/projections/ob_tran.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/projections/ob_tran.cpp b/src/projections/ob_tran.cpp index 6daae394..f9eaa6f0 100644 --- a/src/projections/ob_tran.cpp +++ b/src/projections/ob_tran.cpp @@ -154,6 +154,11 @@ static ARGS ob_tran_target_params (paralist *params) { if (0!=strncmp (args.argv[i], "o_proj=", 7)) continue; args.argv[i] += 2; + if (strcmp(args.argv[i], "proj=ob_tran") == 0 ) { + pj_dealloc (args.argv); + args.argc = 0; + args.argv = nullptr; + } break; } @@ -164,7 +169,6 @@ static ARGS ob_tran_target_params (paralist *params) { PJ *PROJECTION(ob_tran) { double phip; - char *name; ARGS args; PJ *R; /* projection to rotate */ @@ -176,15 +180,15 @@ PJ *PROJECTION(ob_tran) { P->destructor = destructor; /* get name of projection to be translated */ - if (!(name = pj_param(P->ctx, P->params, "so_proj").s)) + if (pj_param(P->ctx, P->params, "so_proj").s == nullptr) return destructor(P, PJD_ERR_NO_ROTATION_PROJ); - /* avoid endless recursion */ - if( strcmp(name, "ob_tran") == 0 ) - return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); - /* Create the target projection object to rotate */ args = ob_tran_target_params (P->params); + /* avoid endless recursion */ + if (args.argv == nullptr ) { + return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); + } R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv); pj_dealloc (args.argv); -- cgit v1.2.3 From fe01efca4e02d4ded4b397c6dcd0cd8ab8f6123a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 19:55:46 +0100 Subject: isea: detect various int overflows and div by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2199 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2241 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2390 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7674 Credit to OSS Fuzz --- src/projections/isea.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index fc74bebe..659ca790 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -10,6 +10,8 @@ #include #include +#include + #define PJ_LIB__ #include "proj_internal.h" #include "proj_math.h" @@ -89,6 +91,9 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { y = y - x / 2.0; /* adjustment for rotated X */ /* adjust for actual hexwidth */ + if( width == 0 ) { + throw "Division by zero"; + } x /= width; y /= width; @@ -100,6 +105,9 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { iy = lround(ry); rz = floor(z + 0.5); iz = lround(rz); + if( fabs(rx + ry + rz) > std::numeric_limits::max() ) { + throw "Integer overflow"; + } s = ix + iy + iz; @@ -764,11 +772,18 @@ static int isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt, } /* todo might want to do this as an iterated loop */ if (g->aperture >0) { - sidelength = lround(pow(g->aperture, g->resolution / 2.0)); + double sidelengthDouble = pow(g->aperture, g->resolution / 2.0); + if( fabs(sidelengthDouble) > std::numeric_limits::max() ) { + throw "Integer overflow"; + } + sidelength = lround(sidelengthDouble); } else { sidelength = g->resolution; } + if( sidelength == 0 ) { + throw "Division by zero"; + } hexwidth = 1.0 / sidelength; v = *pt; @@ -1004,7 +1019,12 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ in.lon = lp.lam; in.lat = lp.phi; - out = isea_forward(&Q->dgg, &in); + try { + out = isea_forward(&Q->dgg, &in); + } catch( const char* ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().xy; + } xy.x = out.x; xy.y = out.y; -- cgit v1.2.3 From 17f2f7cf8bcaa5a4edc9e94d2bd6d8e633455c03 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 22:22:38 +0100 Subject: lcc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12935 Credit to OSS Fuzz --- src/projections/lcc.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index a1fe79a9..5eee0d14 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -108,6 +108,10 @@ PJ *PROJECTION(lcc) { if (secant) { /* secant cone */ sinphi = sin(Q->phi2); Q->n = log(m1 / pj_msfn(sinphi, cos(Q->phi2), P->es)); + if (Q->n == 0) { + // Not quite, but es is very close to 1... + return pj_default_destructor(P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + } Q->n /= log(ml1 / pj_tsfn(Q->phi2, sinphi, P->e)); } Q->c = (Q->rho0 = m1 * pow(ml1, -Q->n) / Q->n); -- cgit v1.2.3 From 5d74522573291a8af698acf3102a662eb3a675eb Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 21 Mar 2019 17:30:06 +1000 Subject: Add -k ellipsoid option to projinfo (#1338) Allows querying of ellipsoid definitions by auth:code lookup --- src/apps/projinfo.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 7e401887..ae97b9c1 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -77,7 +77,7 @@ struct OutputOptions { static void usage() { std::cerr - << "usage: projinfo [-o formats] [-k crs|operation] [--summary] [-q]" + << "usage: projinfo [-o formats] [-k crs|operation|ellipsoid] [--summary] [-q]" << std::endl << " ([--area name_or_code] | " "[--bbox west_long,south_lat,east_long,north_lat]) " @@ -138,7 +138,7 @@ static std::string c_ify_string(const std::string &str) { static BaseObjectNNPtr buildObject( DatabaseContextPtr dbContext, const std::string &user_string, - bool kindIsCRS, const std::string &context, bool buildBoundCRSToWGS84, + const std::string &kind, const std::string &context, bool buildBoundCRSToWGS84, CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, bool quiet) { BaseObjectPtr obj; @@ -174,10 +174,14 @@ static BaseObjectNNPtr buildObject( try { auto tokens = split(l_user_string, ':'); - if (!kindIsCRS && tokens.size() == 2) { + if (kind == "operation" && tokens.size() == 2) { auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); + } else if (kind == "ellipsoid" && tokens.size() == 2) { + auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + + tokens[1]; + obj = createFromUserInput(urn, dbContext).as_nullable(); } else { // Convenience to be able to use C escaped strings... if (l_user_string.size() > 2 && l_user_string[0] == '"' && @@ -572,7 +576,7 @@ static void outputOperations( const std::string &authority, bool usePROJGridAlternatives, bool showSuperseded, const OutputOptions &outputOpt, bool summary) { auto sourceObj = buildObject( - dbContext, sourceCRSStr, true, "source CRS", false, + dbContext, sourceCRSStr, "crs", "source CRS", false, CoordinateOperationContext::IntermediateCRSUse::NEVER, outputOpt.quiet); auto sourceCRS = nn_dynamic_pointer_cast(sourceObj); if (!sourceCRS) { @@ -581,7 +585,7 @@ static void outputOperations( } auto targetObj = buildObject( - dbContext, targetCRSStr, true, "target CRS", false, + dbContext, targetCRSStr, "crs", "target CRS", false, CoordinateOperationContext::IntermediateCRSUse::NEVER, outputOpt.quiet); auto targetCRS = nn_dynamic_pointer_cast(targetObj); if (!targetCRS) { @@ -678,7 +682,7 @@ int main(int argc, char **argv) { std::string targetCRSStr; bool outputSwithSpecified = false; OutputOptions outputOpt; - bool kindIsCRS = true; + std::string objectKind; bool summary = false; ExtentPtr bboxFilter = nullptr; std::string area; @@ -806,9 +810,11 @@ int main(int argc, char **argv) { i++; std::string kind(argv[i]); if (ci_equal(kind, "crs") || ci_equal(kind, "srs")) { - kindIsCRS = true; + objectKind = "crs"; } else if (ci_equal(kind, "operation")) { - kindIsCRS = false; + objectKind = "operation"; + } else if (ci_equal(kind, "ellipsoid")) { + objectKind = "ellipsoid"; } else { std::cerr << "Unrecognized value for option -k: " << kind << std::endl; @@ -998,7 +1004,7 @@ int main(int argc, char **argv) { } if (!user_string.empty()) { - auto obj(buildObject(dbContext, user_string, kindIsCRS, "input string", + auto obj(buildObject(dbContext, user_string, objectKind, "input string", buildBoundCRSToWGS84, allowUseIntermediateCRS, outputOpt.quiet)); if (guessDialect) { -- cgit v1.2.3 From ab19f0d7aec223b89537d07d5f5f3f2e1f5db822 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 21 Mar 2019 09:54:04 +0100 Subject: aea: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13827 Credit to OSS Fuzz --- src/projections/aea.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp index f457e836..8a80c49c 100644 --- a/src/projections/aea.cpp +++ b/src/projections/aea.cpp @@ -180,6 +180,10 @@ static PJ *setup(PJ *P) { return destructor(P, 0); Q->n = (m1 * m1 - m2 * m2) / (ml2 - ml1); + if (Q->n == 0) { + // Not quite, but es is very close to 1... + return destructor(P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + } } Q->ec = 1. - .5 * P->one_es * log((1. - P->e) / (1. + P->e)) / P->e; -- cgit v1.2.3 From ddd333e6bd6f5e033a2b829067910165e64eb0b9 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Thu, 21 Mar 2019 19:53:37 +0000 Subject: Build: automatically enable system error messages Define HAVE_STRERROR during configuration. Before: $ cs2cs +proj=latlong +to +proj=latlong dummy : Sys errno: 2: dummy After: $ cs2cs +proj=latlong +to +proj=latlong dummy : Sys errno: 2: No such file or directory dummy --- src/apps/emess.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp index 144e9e23..52f88aa3 100644 --- a/src/apps/emess.cpp +++ b/src/apps/emess.cpp @@ -20,6 +20,7 @@ #include #include "proj_api.h" +#include "proj_config.h" #define EMESS_ROUTINE #include "emess.h" -- cgit v1.2.3 From eb80638397ccd80b2b2ef8db5fcd8f2823bbec07 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Thu, 21 Mar 2019 20:04:48 +0000 Subject: strtod.cpp: remove support for no proj_config.h The nmake build system has been dropped in favour of CMake which is used to create proj_config.h. --- src/strtod.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/strtod.cpp b/src/strtod.cpp index 7ab271c5..d45e62db 100644 --- a/src/strtod.cpp +++ b/src/strtod.cpp @@ -33,13 +33,8 @@ #include #include "proj.h" -#include "proj_internal.h" - -/* Windows nmake build doesn't have a proj_config.h, but HAVE_LOCALECONV */ -/* is defined in the compilation line */ -#ifndef HAVE_LOCALECONV #include "proj_config.h" -#endif +#include "proj_internal.h" #define PJ_STRTOD_WORK_BUFFER_SIZE 64 -- cgit v1.2.3 From 93b119b0abcdf76ad2b01465c5109381837b387e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 22 Mar 2019 16:11:52 +0100 Subject: Really fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2390 --- src/projections/isea.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index 659ca790..7dc890e0 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -105,7 +105,8 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { iy = lround(ry); rz = floor(z + 0.5); iz = lround(rz); - if( fabs(rx + ry + rz) > std::numeric_limits::max() ) { + if( fabs(rx + ry) > std::numeric_limits::max() || + fabs(rx + ry + rz) > std::numeric_limits::max() ) { throw "Integer overflow"; } -- cgit v1.2.3 From 11e3047990c46cd5b705b20caaa70c37713e229f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 23 Mar 2019 21:29:22 +0100 Subject: Fix GCC 9 warning about useless std::move() --- src/iso19111/coordinateoperation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 7ee20758..57cf9832 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -4816,7 +4816,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { common::Length( parameterValueMeasure(EPSG_CODE_PARAMETER_FALSE_NORTHING))); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } if (current_epsg_code == EPSG_CODE_METHOD_MERCATOR_VARIANT_B && @@ -4837,7 +4837,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { common::Length( parameterValueMeasure(EPSG_CODE_PARAMETER_FALSE_NORTHING))); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } if (current_epsg_code == EPSG_CODE_METHOD_LAMBERT_CONIC_CONFORMAL_1SP && @@ -4872,7 +4872,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { common::Length( parameterValueMeasure(EPSG_CODE_PARAMETER_FALSE_NORTHING))); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } else { const double K = k0 * m0 / std::pow(t0, n); const double phi1 = @@ -4928,7 +4928,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { EPSG_CODE_PARAMETER_FALSE_EASTING)), common::Length(FN_corrected_rounded)); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } } @@ -4942,7 +4942,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { parameterValueMeasure(EPSG_CODE_PARAMETER_FALSE_EASTING)), common::Length(FN)); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } } @@ -5006,7 +5006,7 @@ ConversionPtr Conversion::convertToOtherMethod(int targetEPSGCode) const { EPSG_CODE_PARAMETER_NORTHING_FALSE_ORIGIN) + (std::fabs(FN_correction) > 1e-8 ? FN_correction : 0))); conv->setCRSs(this, false); - return std::move(conv); + return conv.as_nullable(); } return nullptr; -- cgit v1.2.3 From 10e1b7b75f70c704cf78a7eb7197beebb4b82d4a Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sun, 24 Mar 2019 11:35:16 +0100 Subject: Make cs2cs support 4D coordinates. This is a bit of a hack, 4D coordinates *will* be written to STDOUT but the output format speficied with -f is not respected for the t component, rather it is forward verbatim from the input. Fixes #1354 --- src/apps/cs2cs.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index dafd06f8..c68572fa 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -113,6 +113,17 @@ static void process(FILE *fid) z = strtod(s, &s); + /* To avoid breaking existing tests, we read what is a possible t */ + /* component of the input and rewind the s-pointer so that the final */ + /* output has consistant behaviour, with or without t values. */ + /* This is a bit of a hack, in most cases 4D coordinates will be */ + /* written to STDOUT (except when using -E) but the output format */ + /* speficied with -f is not respected for the t component, rather it */ + /* is forward verbatim from the input. */ + char *before_time = s; + double t = strtod(s, &s); + s = before_time; + if (data.v == HUGE_VAL) data.u = HUGE_VAL; @@ -120,11 +131,11 @@ static void process(FILE *fid) --s; /* assumed we gobbled \n */ if (echoin) { - char t; - t = *s; + char temp; + temp = *s; *s = '\0'; (void)fputs(line, stdout); - *s = t; + *s = temp; putchar('\t'); } @@ -141,7 +152,7 @@ static void process(FILE *fid) coord.xyzt.x = data.u; coord.xyzt.y = data.v; coord.xyzt.z = z; - coord.xyzt.t = HUGE_VAL; + coord.xyzt.t = t; coord = proj_trans(transformation, PJ_FWD, coord); data.u = coord.xyz.x; data.v = coord.xyz.y; -- cgit v1.2.3 From 36beda51b769f1e61c33d8230a4718b2bdc6fe46 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 12:56:09 +0100 Subject: isea: really fix integer overflow of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2390 --- src/projections/isea.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index 7dc890e0..18b1cf55 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -105,8 +105,8 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { iy = lround(ry); rz = floor(z + 0.5); iz = lround(rz); - if( fabs(rx + ry) > std::numeric_limits::max() || - fabs(rx + ry + rz) > std::numeric_limits::max() ) { + if( fabs((double)ix + iy) > std::numeric_limits::max() || + fabs((double)ix + iy + iz) > std::numeric_limits::max() ) { throw "Integer overflow"; } -- cgit v1.2.3 From 1eadd02ac0b28486e98aed9407f27c4956619bae Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Sun, 24 Mar 2019 11:56:35 +0000 Subject: Doc: consistently use +opt and brackets +opt represents one parameter. An ellipsis indicates additional instances of the previous parameter may be given. Spaces are used between parameters and before an ellipsis, not purely to format brackets. See man(1) SYNOPSIS conventions. --- src/apps/cs2cs.cpp | 4 ++-- src/apps/geod.cpp | 2 +- src/apps/proj.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index dafd06f8..b6a0f2ac 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -68,8 +68,8 @@ static const char *oform = static char oform_buffer[16]; /* buffer for oform when using -d */ static const char *oterr = "*\t*"; /* output line for unprojectable input */ static const char *usage = - "%s\nusage: %s [ -dDeEfIlrstvwW [args] ] [ +opts[=arg] ]\n" - " [+to [+opts[=arg] [ files ]\n"; + "%s\nusage: %s [-dDeEfIlrstvwW [args]] [+opt[=arg] ...]\n" + " [+to +opt[=arg] ...] [file ...]\n"; static double (*informat)(const char *, char **); /* input data deformatter function */ diff --git a/src/apps/geod.cpp b/src/apps/geod.cpp index 7225856e..b46188d3 100644 --- a/src/apps/geod.cpp +++ b/src/apps/geod.cpp @@ -22,7 +22,7 @@ static const char *osform = "%.3f"; /* output format for S */ static char pline[50]; /* work string */ static const char *usage = -"%s\nusage: %s [ -afFIlptwW [args] ] [ +opts[=arg] ] [ files ]\n"; +"%s\nusage: %s [-afFIlptwW [args]] [+opt[=arg] ...] [file ...]\n"; static void printLL(double p, double l) { diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 40fc5695..5f0ee71f 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -45,7 +45,7 @@ static char oform_buffer[16]; /* Buffer for oform when using -d */ static const char *oterr = "*\t*", /* output line for unprojectable input */ - *usage = "%s\nusage: %s [ -bdeEfiIlmorsStTvVwW [args] ] [ +opts[=arg] ] [ files ]\n"; + *usage = "%s\nusage: %s [-bdeEfiIlmorsStTvVwW [args]] [+opt[=arg] ...] [file ...]\n"; static PJ_FACTORS facs; -- cgit v1.2.3 From c64972d10d44ea21b41a67ab581ac439d1a7f63b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 16:06:06 +0100 Subject: strerrno.cpp: fix inverted messages for PJD_ERR_LAT_1_OR_2_ZERO_OR_90 and PJD_ERR_LAT_0_OR_ALPHA_EQ_90 --- src/strerrno.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/strerrno.cpp b/src/strerrno.cpp index a9310a55..20255747 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -40,8 +40,8 @@ pj_err_list[] = { "path not in range", /* -29 */ "h <= 0", /* -30 */ "k <= 0", /* -31 */ - "lat_0 = 0 or 90 or alpha = 90", /* -32 */ - "lat_1=lat_2 or lat_1=0 or lat_2=90", /* -33 */ + "lat_1=lat_2 or lat_1=0 or lat_2=90", /* -32 */ + "lat_0 = 0 or 90 or alpha = 90", /* -33 */ "elliptical usage required", /* -34 */ "invalid UTM zone number", /* -35 */ "", /* no longer used */ /* -36 */ -- cgit v1.2.3 From 8f22c17b2ef9c1e216a1da0206acea41587f67ce Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 16:06:25 +0100 Subject: urm5: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13891 Credit to OSS Fuzz --- src/projections/urm5.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/urm5.cpp b/src/projections/urm5.cpp index a93293c0..f89bb1d5 100644 --- a/src/projections/urm5.cpp +++ b/src/projections/urm5.cpp @@ -45,7 +45,11 @@ PJ *PROJECTION(urm5) { Q->q3 = pj_param(P->ctx, P->params, "dq").f / 3.; alpha = pj_param(P->ctx, P->params, "ralpha").f; t = Q->n * sin (alpha); - Q->m = cos (alpha) / sqrt (1. - t * t); + const double denom = sqrt (1. - t * t); + if( denom == 0 ) { + return pj_default_destructor(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); + } + Q->m = cos (alpha) / denom; Q->rmn = 1. / (Q->m * Q->n); P->es = 0.; -- cgit v1.2.3 From ad889fc63abd2b1352e107c947ed589108cc7bc0 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 16:50:52 +0100 Subject: lcc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13892 Credit to OSS Fuzz --- src/projections/lcc.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 5eee0d14..55d28b80 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -105,6 +105,9 @@ PJ *PROJECTION(lcc) { m1 = pj_msfn(sinphi, cosphi, P->es); ml1 = pj_tsfn(Q->phi1, sinphi, P->e); + if( ml1 == 0 ) { + return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + } if (secant) { /* secant cone */ sinphi = sin(Q->phi2); Q->n = log(m1 / pj_msfn(sinphi, cos(Q->phi2), P->es)); @@ -112,7 +115,11 @@ PJ *PROJECTION(lcc) { // Not quite, but es is very close to 1... return pj_default_destructor(P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); } - Q->n /= log(ml1 / pj_tsfn(Q->phi2, sinphi, P->e)); + const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e); + if( ml2 == 0 ) { + return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + } + Q->n /= log(ml1 / ml2); } Q->c = (Q->rho0 = m1 * pow(ml1, -Q->n) / Q->n); Q->rho0 *= (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) ? 0. : -- cgit v1.2.3 From 0529b07f81d3c027e101c6e1eddb4685e957934d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 17:05:11 +0100 Subject: tmerc inverse: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13893 Credit to OSS Fuzz --- src/projections/tmerc.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index c91c5174..bb56f8ae 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -188,6 +188,10 @@ static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) { double h, g; h = exp(xy.x / static_cast(P->opaque)->esp); + if( h == 0 ) { + proj_errno_set(P, PJD_ERR_INVALID_X_OR_Y); + return proj_coord_error().lp; + } g = .5 * (h - 1. / h); h = cos (P->phi0 + xy.y / static_cast(P->opaque)->esp); lp.phi = asin(sqrt((1. - h * h) / (1. + g * g))); -- cgit v1.2.3 From f41da8f8e0f6f41ca522279274da1f2441828eda Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 17:11:55 +0100 Subject: vandg inverse: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13894 Credit to OSS Fuzz --- src/projections/vandg.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/vandg.cpp b/src/projections/vandg.cpp index 89620356..c669f8fa 100644 --- a/src/projections/vandg.cpp +++ b/src/projections/vandg.cpp @@ -80,7 +80,14 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ al = c1 / c3 - THIRD * c2 * c2; m = 2. * sqrt(-THIRD * al); d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3; - if (((t = fabs(d = 3. * d / (al * m))) - TOL) <= 1.) { + const double al_mul_m = al * m; + if( al_mul_m == 0 ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().lp; + } + d = 3. * d /al_mul_m; + t = fabs(d); + if ((t - TOL) <= 1.) { d = t > 1. ? (d > 0. ? 0. : M_PI) : acos(d); lp.phi = M_PI * (m * cos(d * THIRD + PI4_3) - THIRD * c2); if (xy.y < 0.) lp.phi = -lp.phi; -- cgit v1.2.3 From 2e60df106deba4455089143e5ae0a4ea1858a3e1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 17:20:51 +0100 Subject: stere: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13895 Credit to OSS Fuzz --- src/projections/stere.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp index 9836f341..fd9f9827 100644 --- a/src/projections/stere.cpp +++ b/src/projections/stere.cpp @@ -55,11 +55,18 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } switch (Q->mode) { - case OBLIQ: - A = Q->akm1 / (Q->cosX1 * (1. + Q->sinX1 * sinX + - Q->cosX1 * cosX * coslam)); + case OBLIQ: { + const double denom = Q->cosX1 * (1. + Q->sinX1 * sinX + + Q->cosX1 * cosX * coslam); + if( denom == 0 ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return proj_coord_error().xy; + } + A = Q->akm1 / denom; xy.y = A * (Q->cosX1 * sinX - Q->sinX1 * cosX * coslam); - goto xmul; /* but why not just xy.x = A * cosX; break; ? */ + xy.x = A * cosX; + break; + } case EQUIT: /* avoid zero division */ @@ -69,7 +76,6 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ A = Q->akm1 / (1. + cosX * coslam); xy.y = A * sinX; } -xmul: xy.x = A * cosX; break; -- cgit v1.2.3 From 8763ea7f01bd349df29c5c4ce3b4edd6252eff37 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 20:01:45 +0100 Subject: WKT2 parser: update to OGC 18-010r6 - Allow ID[] in base CRS of Derived CRS - Allow VERSION[] in non-conversion coordinate operations - Use VERSION[] to set operationVersion member of CoordinateOperation - Export operationVersion in WKT2:2018 --- src/iso19111/coordinateoperation.cpp | 37 +- src/iso19111/io.cpp | 11 + src/iso19111/static.cpp | 12 + src/wkt2_generated_parser.c | 2582 +++++++++++++++++----------------- src/wkt2_generated_parser.h | 141 +- src/wkt2_grammar.y | 92 +- src/wkt2_parser.cpp | 2 +- 7 files changed, 1509 insertions(+), 1368 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 57cf9832..80c1a572 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -756,6 +756,15 @@ void CoordinateOperation::setHasBallparkTransformation(bool b) { // --------------------------------------------------------------------------- +void CoordinateOperation::setProperties( + const util::PropertyMap &properties) // throw(InvalidValueTypeException) +{ + ObjectUsage::setProperties(properties); + properties.getStringValue(OPERATION_VERSION_KEY, d->operationVersion_); +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress struct OperationMethod::Private { util::optional formula_{}; @@ -6175,17 +6184,17 @@ TransformationNNPtr Transformation::create( throw InvalidOperation( "Inconsistent number of parameters and parameter values"); } - auto conv = Transformation::nn_make_shared( + auto transf = Transformation::nn_make_shared( sourceCRSIn, targetCRSIn, interpolationCRSIn, methodIn, values, accuracies); - conv->assignSelf(conv); - conv->setProperties(properties); + transf->assignSelf(transf); + transf->setProperties(properties); std::string name; if (properties.getStringValue(common::IdentifiedObject::NAME_KEY, name) && ci_find(name, "ballpark") != std::string::npos) { - conv->setHasBallparkTransformation(true); + transf->setHasBallparkTransformation(true); } - return conv; + return transf; } // --------------------------------------------------------------------------- @@ -7653,6 +7662,15 @@ void SingleOperation::exportTransformationToWKT( formatter->addQuotedString(nameStr()); + if (isWKT2 && formatter->use2018Keywords()) { + const auto &version = operationVersion(); + if (version.has_value()) { + formatter->startNode(io::WKTConstants::VERSION, false); + formatter->addQuotedString(*version); + formatter->endNode(); + } + } + if (!formatter->abridgedTransformation()) { formatter->startNode(io::WKTConstants::SOURCECRS, false); l_sourceCRS->_exportToWKT(formatter); @@ -9310,6 +9328,15 @@ void ConcatenatedOperation::_exportToWKT(io::WKTFormatter *formatter) const { !identifiers().empty()); formatter->addQuotedString(nameStr()); + if (isWKT2 && formatter->use2018Keywords()) { + const auto &version = operationVersion(); + if (version.has_value()) { + formatter->startNode(io::WKTConstants::VERSION, false); + formatter->addQuotedString(*version); + formatter->endNode(); + } + } + formatter->startNode(io::WKTConstants::SOURCECRS, false); sourceCRS()->_exportToWKT(formatter); formatter->endNode(); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index a160a4e3..220ee967 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -1581,6 +1581,17 @@ PropertyMap &WKTParser::Private::buildProperties(const WKTNodeNNPtr &node, } } + auto &versionNode = nodeP->lookForChild(WKTConstants::VERSION); + if (!isNull(versionNode)) { + const auto &versionChildren = versionNode->GP()->children(); + if (versionChildren.size() == 1) { + properties->set(CoordinateOperation::OPERATION_VERSION_KEY, + stripQuotes(versionChildren[0])); + } else { + ThrowNotRequiredNumberOfChildren(versionNode->GP()->value()); + } + } + return *properties; } diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp index ef2635b5..824047f0 100644 --- a/src/iso19111/static.cpp +++ b/src/iso19111/static.cpp @@ -31,6 +31,7 @@ #endif #include "proj/common.hpp" +#include "proj/coordinateoperation.hpp" #include "proj/coordinatesystem.hpp" #include "proj/crs.hpp" #include "proj/datum.hpp" @@ -57,6 +58,7 @@ using namespace NS_PROJ::crs; using namespace NS_PROJ::datum; using namespace NS_PROJ::io; using namespace NS_PROJ::metadata; +using namespace NS_PROJ::operation; using namespace NS_PROJ::util; NS_PROJ_START @@ -271,6 +273,7 @@ DEFINE_WKT_CONSTANT(BASEVERTCRS); DEFINE_WKT_CONSTANT(BASEENGCRS); DEFINE_WKT_CONSTANT(BASEPARAMCRS); DEFINE_WKT_CONSTANT(BASETIMECRS); +DEFINE_WKT_CONSTANT(VERSION); DEFINE_WKT_CONSTANT(GEODETICCRS); DEFINE_WKT_CONSTANT(GEODETICDATUM); @@ -641,4 +644,13 @@ const GeographicCRSNNPtr // --------------------------------------------------------------------------- +/** \brief Key to set the operation version of a operation::CoordinateOperation + * + * The value is to be provided as a string. + */ +const std::string + operation::CoordinateOperation::OPERATION_VERSION_KEY("operationVersion"); + +// --------------------------------------------------------------------------- + NS_PROJ_END diff --git a/src/wkt2_generated_parser.c b/src/wkt2_generated_parser.c index f6b1f6b1..b3a9eb24 100644 --- a/src/wkt2_generated_parser.c +++ b/src/wkt2_generated_parser.c @@ -211,76 +211,77 @@ extern int pj_wkt2_debug; T_COORDEPOCH = 330, T_COORDINATEMETADATA = 331, T_POINTMOTIONOPERATION = 332, - T_GEODETICCRS = 333, - T_GEODETICDATUM = 334, - T_PROJECTEDCRS = 335, - T_PRIMEMERIDIAN = 336, - T_GEOGRAPHICCRS = 337, - T_TRF = 338, - T_VERTICALCRS = 339, - T_VERTICALDATUM = 340, - T_VRF = 341, - T_TIMEDATUM = 342, - T_TEMPORALQUANTITY = 343, - T_ENGINEERINGDATUM = 344, - T_ENGINEERINGCRS = 345, - T_PARAMETRICDATUM = 346, - T_AFFINE = 347, - T_CARTESIAN = 348, - T_CYLINDRICAL = 349, - T_ELLIPSOIDAL = 350, - T_LINEAR = 351, - T_PARAMETRIC = 352, - T_POLAR = 353, - T_SPHERICAL = 354, - T_VERTICAL = 355, - T_TEMPORAL = 356, - T_TEMPORALCOUNT = 357, - T_TEMPORALMEASURE = 358, - T_ORDINAL = 359, - T_TEMPORALDATETIME = 360, - T_NORTH = 361, - T_NORTHNORTHEAST = 362, - T_NORTHEAST = 363, - T_EASTNORTHEAST = 364, - T_EAST = 365, - T_EASTSOUTHEAST = 366, - T_SOUTHEAST = 367, - T_SOUTHSOUTHEAST = 368, - T_SOUTH = 369, - T_SOUTHSOUTHWEST = 370, - T_SOUTHWEST = 371, - T_WESTSOUTHWEST = 372, - T_WEST = 373, - T_WESTNORTHWEST = 374, - T_NORTHWEST = 375, - T_NORTHNORTHWEST = 376, - T_UP = 377, - T_DOWN = 378, - T_GEOCENTRICX = 379, - T_GEOCENTRICY = 380, - T_GEOCENTRICZ = 381, - T_COLUMNPOSITIVE = 382, - T_COLUMNNEGATIVE = 383, - T_ROWPOSITIVE = 384, - T_ROWNEGATIVE = 385, - T_DISPLAYRIGHT = 386, - T_DISPLAYLEFT = 387, - T_DISPLAYUP = 388, - T_DISPLAYDOWN = 389, - T_FORWARD = 390, - T_AFT = 391, - T_PORT = 392, - T_STARBOARD = 393, - T_CLOCKWISE = 394, - T_COUNTERCLOCKWISE = 395, - T_TOWARDS = 396, - T_AWAYFROM = 397, - T_FUTURE = 398, - T_PAST = 399, - T_UNSPECIFIED = 400, - T_STRING = 401, - T_UNSIGNED_INTEGER_DIFFERENT_ONE_TWO_THREE = 402 + T_VERSION = 333, + T_GEODETICCRS = 334, + T_GEODETICDATUM = 335, + T_PROJECTEDCRS = 336, + T_PRIMEMERIDIAN = 337, + T_GEOGRAPHICCRS = 338, + T_TRF = 339, + T_VERTICALCRS = 340, + T_VERTICALDATUM = 341, + T_VRF = 342, + T_TIMEDATUM = 343, + T_TEMPORALQUANTITY = 344, + T_ENGINEERINGDATUM = 345, + T_ENGINEERINGCRS = 346, + T_PARAMETRICDATUM = 347, + T_AFFINE = 348, + T_CARTESIAN = 349, + T_CYLINDRICAL = 350, + T_ELLIPSOIDAL = 351, + T_LINEAR = 352, + T_PARAMETRIC = 353, + T_POLAR = 354, + T_SPHERICAL = 355, + T_VERTICAL = 356, + T_TEMPORAL = 357, + T_TEMPORALCOUNT = 358, + T_TEMPORALMEASURE = 359, + T_ORDINAL = 360, + T_TEMPORALDATETIME = 361, + T_NORTH = 362, + T_NORTHNORTHEAST = 363, + T_NORTHEAST = 364, + T_EASTNORTHEAST = 365, + T_EAST = 366, + T_EASTSOUTHEAST = 367, + T_SOUTHEAST = 368, + T_SOUTHSOUTHEAST = 369, + T_SOUTH = 370, + T_SOUTHSOUTHWEST = 371, + T_SOUTHWEST = 372, + T_WESTSOUTHWEST = 373, + T_WEST = 374, + T_WESTNORTHWEST = 375, + T_NORTHWEST = 376, + T_NORTHNORTHWEST = 377, + T_UP = 378, + T_DOWN = 379, + T_GEOCENTRICX = 380, + T_GEOCENTRICY = 381, + T_GEOCENTRICZ = 382, + T_COLUMNPOSITIVE = 383, + T_COLUMNNEGATIVE = 384, + T_ROWPOSITIVE = 385, + T_ROWNEGATIVE = 386, + T_DISPLAYRIGHT = 387, + T_DISPLAYLEFT = 388, + T_DISPLAYUP = 389, + T_DISPLAYDOWN = 390, + T_FORWARD = 391, + T_AFT = 392, + T_PORT = 393, + T_STARBOARD = 394, + T_CLOCKWISE = 395, + T_COUNTERCLOCKWISE = 396, + T_TOWARDS = 397, + T_AWAYFROM = 398, + T_FUTURE = 399, + T_PAST = 400, + T_UNSPECIFIED = 401, + T_STRING = 402, + T_UNSIGNED_INTEGER_DIFFERENT_ONE_TWO_THREE = 403 }; #endif @@ -541,21 +542,21 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 105 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 3221 +#define YYLAST 3309 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 163 +#define YYNTOKENS 164 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 339 +#define YYNNTS 350 /* YYNRULES -- Number of rules. */ -#define YYNRULES 670 +#define YYNRULES 687 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1371 +#define YYNSTATES 1411 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 402 +#define YYMAXUTOK 403 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -568,12 +569,12 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 159, 161, 2, 153, 162, 154, 148, 2, 2, 150, - 151, 152, 2, 2, 2, 2, 2, 2, 155, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 149, + 160, 162, 2, 154, 163, 155, 149, 2, 2, 151, + 152, 153, 2, 2, 2, 2, 2, 2, 156, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 150, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 156, 2, 2, 2, 2, 2, - 157, 158, 2, 160, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 157, 2, 2, 2, 2, 2, + 158, 159, 2, 161, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -604,81 +605,82 @@ static const yytype_uint8 yytranslate[] = 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147 + 145, 146, 147, 148 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 206, 206, 206, 206, 206, 206, 206, 207, 207, - 207, 208, 211, 211, 212, 212, 212, 213, 215, 215, - 219, 223, 223, 225, 227, 229, 229, 231, 231, 233, - 235, 237, 239, 241, 241, 243, 243, 245, 245, 245, - 245, 247, 247, 251, 253, 257, 258, 259, 261, 261, - 263, 265, 267, 269, 273, 274, 277, 278, 280, 282, - 284, 287, 288, 289, 291, 293, 295, 295, 297, 300, - 301, 303, 303, 308, 308, 310, 310, 312, 314, 316, - 320, 321, 324, 325, 326, 328, 328, 329, 332, 333, - 337, 338, 339, 343, 344, 345, 346, 348, 352, 354, - 357, 359, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, 397, 399, 401, 405, 410, 412, 414, 416, - 418, 422, 427, 428, 430, 432, 434, 438, 442, 444, - 444, 446, 446, 451, 456, 457, 458, 459, 460, 461, - 462, 464, 466, 468, 468, 470, 470, 472, 474, 476, - 478, 480, 482, 486, 488, 492, 492, 495, 498, 503, - 503, 503, 503, 503, 506, 511, 511, 511, 511, 514, - 518, 519, 521, 537, 541, 542, 544, 544, 546, 546, - 552, 552, 554, 556, 563, 563, 563, 565, 572, 573, - 574, 575, 577, 584, 591, 592, 593, 595, 597, 597, - 597, 597, 597, 597, 597, 597, 597, 600, 600, 600, - 602, 602, 604, 604, 604, 606, 611, 617, 622, 625, - 628, 629, 630, 631, 632, 633, 634, 635, 636, 639, - 640, 641, 642, 643, 644, 645, 646, 649, 650, 651, - 652, 653, 654, 655, 656, 659, 660, 663, 664, 665, - 666, 671, 672, 673, 674, 675, 676, 677, 678, 679, - 682, 683, 684, 685, 688, 689, 690, 691, 694, 695, - 698, 699, 704, 705, 708, 709, 710, 711, 714, 715, - 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, - 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, - 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, - 746, 747, 748, 749, 751, 754, 756, 758, 760, 762, - 764, 780, 780, 782, 790, 791, 793, 794, 796, 804, - 805, 807, 809, 811, 816, 817, 819, 821, 823, 825, - 827, 829, 831, 836, 840, 842, 845, 848, 849, 850, - 852, 853, 855, 860, 861, 863, 863, 865, 869, 869, - 869, 871, 871, 873, 881, 890, 898, 908, 909, 911, - 913, 913, 915, 915, 918, 919, 923, 929, 930, 931, - 933, 933, 935, 937, 939, 943, 948, 948, 950, 953, - 954, 958, 963, 963, 963, 965, 967, 968, 969, 970, - 972, 975, 977, 981, 987, 987, 991, 991, 992, 992, - 994, 999, 1000, 1001, 1002, 1004, 1010, 1015, 1021, 1023, - 1025, 1027, 1031, 1037, 1038, 1039, 1041, 1043, 1045, 1049, - 1049, 1051, 1053, 1058, 1059, 1061, 1063, 1065, 1067, 1071, - 1071, 1073, 1079, 1086, 1086, 1089, 1096, 1097, 1098, 1099, - 1100, 1102, 1106, 1108, 1110, 1110, 1114, 1119, 1119, 1119, - 1123, 1128, 1128, 1130, 1134, 1134, 1138, 1143, 1145, 1149, - 1149, 1153, 1158, 1160, 1164, 1165, 1166, 1167, 1168, 1170, - 1170, 1172, 1175, 1177, 1177, 1179, 1181, 1183, 1187, 1193, - 1194, 1195, 1196, 1198, 1200, 1204, 1209, 1211, 1214, 1219, - 1223, 1229, 1229, 1229, 1229, 1229, 1229, 1233, 1238, 1240, - 1245, 1245, 1246, 1248, 1248, 1250, 1257, 1257, 1259, 1266, - 1266, 1268, 1275, 1282, 1287, 1288, 1290, 1296, 1301, 1309, - 1315, 1317, 1319, 1324, 1326, 1326, 1327, 1327, 1331, 1337, - 1337, 1339, 1342, 1346, 1351, 1357, 1360, 1365, 1371, 1374, - 1379, 1385, 1388, 1393, 1399, 1399, 1400, 1400, 1401, 1401, - 1402, 1402, 1403, 1403, 1404, 1404, 1407, 1407, 1409, 1410, - 1411, 1413, 1415, 1419, 1422, 1422, 1425, 1426, 1427, 1429, - 1433, 1434, 1436, 1438, 1438, 1439, 1439, 1440, 1440, 1440, - 1441, 1442, 1442, 1443, 1443, 1444, 1444, 1446, 1446, 1447, - 1447, 1448, 1449, 1449, 1453, 1459, 1460, 1461, 1462, 1463, - 1464, 1465, 1467, 1469, 1471, 1473, 1475, 1477, 1479, 1481, - 1483, 1485, 1490, 1496, 1497, 1498, 1499, 1500, 1502, 1507, - 1515, 1515, 1515, 1515, 1517, 1518, 1519, 1520, 1522, 1524, - 1529, 1535, 1537, 1544, 1544, 1546, 1547, 1548, 1549, 1551, - 1553 + 0, 207, 207, 207, 207, 207, 207, 207, 208, 208, + 208, 209, 212, 212, 213, 213, 213, 214, 216, 216, + 220, 224, 224, 226, 228, 230, 230, 232, 232, 234, + 236, 238, 240, 242, 242, 244, 244, 246, 246, 246, + 246, 248, 248, 252, 254, 258, 259, 260, 262, 262, + 264, 266, 268, 270, 274, 275, 278, 279, 281, 283, + 285, 288, 289, 290, 292, 294, 296, 296, 298, 301, + 302, 304, 304, 309, 309, 311, 311, 313, 315, 317, + 321, 322, 325, 326, 327, 329, 329, 330, 333, 334, + 338, 339, 340, 344, 345, 346, 347, 349, 353, 355, + 358, 360, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 380, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 398, 400, 402, 406, 411, 413, 415, 417, + 419, 423, 428, 429, 431, 433, 435, 439, 443, 445, + 445, 447, 447, 452, 457, 458, 459, 460, 461, 462, + 463, 465, 467, 469, 469, 471, 471, 473, 475, 477, + 479, 481, 483, 487, 489, 493, 493, 496, 499, 504, + 504, 504, 504, 504, 507, 512, 512, 512, 512, 515, + 519, 520, 522, 538, 542, 543, 545, 545, 547, 547, + 553, 553, 555, 557, 564, 564, 564, 566, 573, 574, + 575, 576, 578, 585, 592, 593, 594, 596, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 601, 601, 601, + 603, 603, 605, 605, 605, 607, 612, 618, 623, 626, + 629, 630, 631, 632, 633, 634, 635, 636, 637, 640, + 641, 642, 643, 644, 645, 646, 647, 650, 651, 652, + 653, 654, 655, 656, 657, 660, 661, 664, 665, 666, + 667, 672, 673, 674, 675, 676, 677, 678, 679, 680, + 683, 684, 685, 686, 689, 690, 691, 692, 695, 696, + 699, 700, 705, 706, 709, 710, 711, 712, 715, 716, + 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, + 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, + 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, + 747, 748, 749, 750, 752, 755, 757, 759, 761, 763, + 765, 781, 781, 783, 791, 792, 794, 795, 797, 805, + 806, 808, 810, 812, 817, 818, 820, 822, 824, 826, + 828, 830, 832, 837, 841, 843, 846, 849, 850, 851, + 853, 854, 856, 861, 862, 864, 864, 866, 870, 870, + 870, 872, 872, 874, 882, 891, 899, 909, 910, 912, + 914, 914, 916, 916, 919, 920, 924, 930, 931, 932, + 934, 934, 936, 938, 940, 944, 949, 949, 951, 954, + 955, 959, 964, 964, 964, 966, 968, 969, 970, 971, + 973, 976, 978, 982, 988, 988, 992, 992, 993, 993, + 995, 1000, 1001, 1002, 1003, 1004, 1006, 1012, 1017, 1023, + 1025, 1027, 1029, 1033, 1039, 1040, 1041, 1043, 1045, 1047, + 1051, 1051, 1053, 1055, 1060, 1061, 1063, 1065, 1067, 1069, + 1073, 1073, 1075, 1081, 1088, 1088, 1091, 1098, 1099, 1100, + 1101, 1102, 1104, 1108, 1110, 1112, 1112, 1116, 1121, 1121, + 1121, 1125, 1130, 1130, 1132, 1136, 1136, 1140, 1145, 1147, + 1151, 1151, 1155, 1160, 1162, 1166, 1167, 1168, 1169, 1170, + 1172, 1172, 1174, 1177, 1179, 1179, 1181, 1183, 1185, 1189, + 1195, 1196, 1197, 1198, 1200, 1202, 1206, 1211, 1213, 1216, + 1221, 1225, 1231, 1231, 1231, 1231, 1231, 1231, 1235, 1240, + 1242, 1247, 1247, 1248, 1250, 1250, 1252, 1259, 1259, 1261, + 1268, 1268, 1270, 1277, 1284, 1289, 1290, 1291, 1293, 1299, + 1304, 1312, 1318, 1320, 1322, 1328, 1330, 1330, 1331, 1331, + 1335, 1341, 1341, 1343, 1348, 1354, 1359, 1365, 1370, 1375, + 1381, 1386, 1391, 1397, 1402, 1407, 1413, 1413, 1414, 1414, + 1415, 1415, 1416, 1416, 1417, 1417, 1418, 1418, 1421, 1421, + 1423, 1424, 1425, 1427, 1429, 1433, 1436, 1436, 1439, 1440, + 1441, 1443, 1447, 1448, 1450, 1452, 1452, 1453, 1453, 1454, + 1454, 1454, 1455, 1456, 1456, 1457, 1457, 1458, 1458, 1460, + 1460, 1461, 1461, 1462, 1463, 1463, 1467, 1471, 1472, 1475, + 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1488, 1490, 1492, + 1495, 1497, 1499, 1501, 1503, 1505, 1507, 1509, 1511, 1513, + 1518, 1522, 1523, 1526, 1531, 1532, 1533, 1534, 1535, 1537, + 1542, 1547, 1548, 1551, 1557, 1557, 1557, 1557, 1559, 1560, + 1561, 1562, 1564, 1566, 1571, 1577, 1579, 1584, 1585, 1588, + 1594, 1594, 1596, 1597, 1598, 1599, 1601, 1603 }; #endif @@ -707,13 +709,13 @@ static const char *const yytname[] = "\"PARAMETRICCRS\"", "\"PARAMETRICUNIT\"", "\"BASEVERTCRS\"", "\"BASEENGCRS\"", "\"BASEPARAMCRS\"", "\"BASETIMECRS\"", "\"EPOCH\"", "\"COORDEPOCH\"", "\"COORDINATEMETADATA\"", "\"POINTMOTIONOPERATION\"", - "\"GEODETICCRS\"", "\"GEODETICDATUM\"", "\"PROJECTEDCRS\"", - "\"PRIMEMERIDIAN\"", "\"GEOGRAPHICCRS\"", "\"TRF\"", "\"VERTICALCRS\"", - "\"VERTICALDATUM\"", "\"VRF\"", "\"TIMEDATUM\"", "\"TEMPORALQUANTITY\"", - "\"ENGINEERINGDATUM\"", "\"ENGINEERINGCRS\"", "\"PARAMETRICDATUM\"", - "\"affine\"", "\"Cartesian\"", "\"cylindrical\"", "\"ellipsoidal\"", - "\"linear\"", "\"parametric\"", "\"polar\"", "\"spherical\"", - "\"vertical\"", "\"temporal\"", "\"temporalCount\"", + "\"VERSION\"", "\"GEODETICCRS\"", "\"GEODETICDATUM\"", + "\"PROJECTEDCRS\"", "\"PRIMEMERIDIAN\"", "\"GEOGRAPHICCRS\"", "\"TRF\"", + "\"VERTICALCRS\"", "\"VERTICALDATUM\"", "\"VRF\"", "\"TIMEDATUM\"", + "\"TEMPORALQUANTITY\"", "\"ENGINEERINGDATUM\"", "\"ENGINEERINGCRS\"", + "\"PARAMETRICDATUM\"", "\"affine\"", "\"Cartesian\"", "\"cylindrical\"", + "\"ellipsoidal\"", "\"linear\"", "\"parametric\"", "\"polar\"", + "\"spherical\"", "\"vertical\"", "\"temporal\"", "\"temporalCount\"", "\"temporalMeasure\"", "\"ordinal\"", "\"temporalDateTime\"", "\"north\"", "\"northNorthEast\"", "\"northEast\"", "\"eastNorthEast\"", "\"east\"", "\"eastSouthEast\"", "\"southEast\"", "\"southSouthEast\"", @@ -819,12 +821,12 @@ static const char *const yytname[] = "opt_separator_datum_anchor_identifier_list", "datum_anchor", "datum_anchor_keyword", "datum_anchor_description", "projected_crs", "projected_crs_keyword", "base_geodetic_crs", "base_static_geodetic_crs", - "opt_separator_pm_ellipsoidal_cs_unit", "base_dynamic_geodetic_crs", - "base_static_geographic_crs", "base_dynamic_geographic_crs", - "base_geodetic_crs_keyword", "base_geographic_crs_keyword", - "base_crs_name", "ellipsoidal_cs_unit", "map_projection", - "opt_separator_parameter_list_identifier_list", "map_projection_keyword", - "map_projection_name", "map_projection_method", + "opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list", + "base_dynamic_geodetic_crs", "base_static_geographic_crs", + "base_dynamic_geographic_crs", "base_geodetic_crs_keyword", + "base_geographic_crs_keyword", "base_crs_name", "ellipsoidal_cs_unit", + "map_projection", "opt_separator_parameter_list_identifier_list", + "map_projection_keyword", "map_projection_name", "map_projection_method", "map_projection_method_keyword", "map_projection_method_name", "map_projection_parameter", "opt_separator_param_unit_identifier_list", "parameter_keyword", "parameter_name", "parameter_value", @@ -857,10 +859,10 @@ static const char *const yytname[] = "derived_dynamic_geod_crs", "base_dynamic_geod_crs_or_base_dynamic_geog_crs", "derived_static_geog_crs", "derived_dynamic_geog_crs", - "base_static_geod_crs", "opt_separator_pm", "base_dynamic_geod_crs", - "base_static_geog_crs", "base_dynamic_geog_crs", "derived_projected_crs", - "derived_projected_crs_keyword", "derived_crs_name", - "base_projected_crs", "base_projected_crs_keyword", + "base_static_geod_crs", "opt_separator_pm_opt_separator_identifier_list", + "base_dynamic_geod_crs", "base_static_geog_crs", "base_dynamic_geog_crs", + "derived_projected_crs", "derived_projected_crs_keyword", + "derived_crs_name", "base_projected_crs", "base_projected_crs_keyword", "base_geodetic_geographic_crs", "derived_vertical_crs", "base_vertical_crs", "base_static_vertical_crs", "base_dynamic_vertical_crs", "base_vertical_crs_keyword", @@ -874,17 +876,23 @@ static const char *const yytname[] = "coordinate_epoch_keyword", "coordinate_epoch", "coordinate_metadata", "coordinate_metadata_crs", "coordinate_metadata_keyword", "static_crs_coordinate_metadata", "dynamic_crs_coordinate_metadata", - "coordinate_operation", + "coordinate_operation", "coordinate_operation_next", + "coordinate_operation_end", "opt_parameter_or_parameter_file_list_opt_interpolation_crs_opt_operation_accuracy_opt_separator_scope_extent_identifier_remark", - "operation_keyword", "operation_name", "source_crs", + "operation_keyword", "operation_name", "operation_version", + "operation_version_keyword", "operation_version_text", "source_crs", "source_crs_keyword", "target_crs", "target_crs_keyword", "interpolation_crs", "interpolation_crs_keyword", "operation_accuracy", "operation_accuracy_keyword", "point_motion_operation", + "point_motion_operation_next", "point_motion_operation_end", "opt_parameter_or_parameter_file_list_opt_operation_accuracy_opt_separator_scope_extent_identifier_remark", - "point_motion_keyword", "concatenated_operation", "step", + "point_motion_keyword", "concatenated_operation", + "concatenated_operation_next", "concatenated_operation_end", "step", "opt_concatenated_operation_end", "concatenated_operation_keyword", "step_keyword", "bound_crs", "bound_crs_keyword", "abridged_coordinate_transformation", + "abridged_coordinate_transformation_next", + "abridged_coordinate_transformation_end", "abridged_parameter_or_parameter_file", "opt_end_abridged_coordinate_transformation", "abridged_transformation_keyword", "abridged_transformation_parameter", YY_NULLPTR @@ -910,18 +918,18 @@ static const yytype_uint16 yytoknum[] = 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 46, 69, - 49, 50, 51, 43, 45, 58, 84, 90, 91, 40, - 93, 41, 44 + 395, 396, 397, 398, 399, 400, 401, 402, 403, 46, + 69, 49, 50, 51, 43, 45, 58, 84, 90, 91, + 40, 93, 41, 44 }; # endif -#define YYPACT_NINF -1145 +#define YYPACT_NINF -1187 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-1145))) + (!!((Yystate) == (-1187))) -#define YYTABLE_NINF -624 +#define YYTABLE_NINF -626 #define yytable_value_is_error(Yytable_value) \ 0 @@ -930,144 +938,148 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 799, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, 132, -1145, -1145, - -1145, 304, -1145, -1145, -1145, 304, -1145, -1145, -1145, -1145, - -1145, -1145, 304, 304, -1145, 304, -1145, 304, -1145, 304, - -1145, 304, -1145, -1145, -1145, 304, -1145, 304, -1145, 304, - -1145, 304, -1145, 304, -1145, 304, -1145, 304, -1145, 304, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, 304, -1145, -1145, - -1145, -1145, -1145, -1145, 304, -1145, 304, -1145, 304, -1145, - 304, -1145, 304, -1145, 304, -1145, -1145, -1145, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1044, 30, 30, 30, - 170, -1145, -1145, 61, -1145, 61, -1145, 61, 61, -1145, - 61, -1145, 61, 61, -1145, 61, 61, 61, 61, 61, - 61, 61, 61, 61, -1145, 61, -1145, 61, -1145, -1145, - -1145, -1145, 78, -1145, -1145, -1145, -1145, -1145, 148, 229, - 241, -1145, -1145, -1145, -1145, 315, -1145, 61, -1145, 61, - 61, 61, -1145, 61, 304, -1145, 922, 284, 445, 445, - 577, 345, 279, 321, 412, 342, 315, 250, 315, 393, - 315, 67, 280, 315, 351, 1285, -1145, -1145, -1145, 446, - 170, 170, 170, 381, 1044, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, 624, -1145, -1145, -1145, -1145, 299, 302, 307, - 577, -1145, 61, -1145, 61, 304, -1145, -1145, -1145, -1145, - 304, 61, 304, 61, -1145, 304, 304, 61, 61, -1145, - -1145, -1145, -1145, 61, 61, 61, 61, -1145, 61, 61, - 61, -1145, -1145, -1145, -1145, 304, 304, -1145, -1145, 61, - 304, -1145, -1145, 304, 61, 61, -1145, 61, -1145, -1145, - 304, -1145, 61, 61, 304, -1145, -1145, 61, 61, 304, - -1145, -1145, 61, 61, 304, -1145, -1145, 61, 61, 304, - -1145, -1145, 61, 61, 304, 61, 304, -1145, -1145, 61, - 304, -1145, 61, -1145, -1145, -1145, -1145, 304, 61, 61, - 61, -1145, 61, 304, 315, -1145, 400, 624, -1145, -1145, - 365, 315, 122, 315, 315, 30, 30, 115, 402, 127, - 30, 30, 419, 419, 115, 127, 419, 419, 577, 315, - 456, 30, 30, 423, 315, 30, 30, 189, 480, 419, - 30, 490, -1145, 490, 30, 480, 419, 30, 480, 419, - 30, 480, 419, 30, -1145, -1145, 506, 146, -1145, 30, - 419, 30, 1285, 624, 381, 485, 381, 487, 1044, -1145, - 624, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, 61, - 61, 304, -1145, 304, -1145, -1145, 61, 61, 304, 61, - -1145, -1145, -1145, 61, 61, 61, -1145, 61, 304, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, 304, 315, 61, 304, - -1145, 61, 61, -1145, 61, 304, 61, 61, 315, 61, - 61, -1145, 61, -1145, 61, 61, 61, -1145, 61, 61, - 304, -1145, -1145, 61, 61, 61, 304, 315, 61, 61, - 61, 61, -1145, 315, 315, 61, 61, 315, 61, 61, - 315, 61, 61, -1145, -1145, 376, -1145, 315, 61, -1145, - 315, 61, 61, 61, 307, 315, 61, -1145, 61, 304, - 61, -1145, 61, 304, 315, -1145, 510, 505, 30, 30, - -1145, -1145, 490, -1145, 752, 515, 490, 315, 284, 127, - 532, 315, 624, 1049, -1145, 480, 30, 272, 272, 480, - 30, 480, 127, -1145, 480, 480, 470, 315, 480, 272, - 272, -1145, -1145, 30, 315, 284, 480, 1313, -1145, 480, - 106, -1145, -1145, -1145, -1145, 480, 100, -1145, 480, 152, - -1145, 480, 74, -1145, -1145, 624, -1145, -1145, 624, -1145, - -1145, -1145, 480, 279, 953, 315, 624, -1145, 485, 1361, - 315, 30, 502, 843, 315, 30, -1145, 61, -1145, -1145, - 315, -1145, 315, -1145, 61, -1145, 315, 61, -1145, 61, - -1145, 61, 315, -1145, -1145, -1145, 304, -1145, 307, 315, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, 61, 61, 61, -1145, -1145, 61, - 61, 61, 61, 61, 315, -1145, 61, 315, 315, 315, - 315, -1145, -1145, 61, 61, 304, -1145, 315, 61, 61, - 61, 61, -1145, 61, -1145, 61, 315, 61, 315, 61, - 315, 315, 315, 315, 315, 315, 315, 428, 418, -1145, - 534, 315, -1145, -1145, -1145, -1145, 61, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, 61, 304, - 61, 304, -1145, 61, 304, 61, 304, 61, 304, 61, - 304, 61, -1145, 304, 61, -1145, -1145, 61, -1145, -1145, - -1145, 304, 61, 61, 304, 61, 304, -1145, -1145, 61, - -1145, 304, -1145, -1145, 61, 505, -1145, -1145, -1145, -1145, - -1145, -1145, 110, -1145, 30, 624, -1145, 409, 409, 409, - 400, 115, 89, 315, 115, 315, -1145, 485, -1145, -1145, - -1145, -1145, -1145, -1145, 30, -1145, 115, 105, 315, 115, - 315, 400, 569, -1145, 409, -1145, 189, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, 624, -1145, -1145, 624, 624, - -1145, 431, -1145, -1145, -1145, -1145, 456, 130, 566, 469, - -1145, 30, 340, -1145, 30, 183, -1145, 752, 282, -1145, - 752, 335, -1145, 506, -1145, 453, -1145, 1330, 315, 30, - -1145, -1145, 30, -1145, 752, 490, 315, 90, 485, -1145, - 61, -1145, 61, -1145, -1145, -1145, -1145, 61, 61, 61, - 61, 577, 315, 61, -1145, -1145, 61, -1145, 61, -1145, - 61, 61, -1145, -1145, -1145, 304, 61, -1145, -1145, 61, - -1145, -1145, 61, 61, 61, 315, -1145, 449, 431, -1145, - 534, 624, -1145, 315, -1145, 61, -1145, 61, -1145, 61, - -1145, -1145, 315, 61, 61, 61, -1145, 315, 61, 61, - -1145, 61, 61, -1145, 61, -1145, -1145, 61, -1145, 315, - -1145, -1145, 61, 61, 61, 304, 61, -1145, 61, 61, - 315, -1145, -1145, -1145, -1145, -1145, -1145, 315, 61, 315, - 315, 315, 315, 497, -1145, -1145, -1145, 315, 315, 339, - 315, 577, 315, 30, 157, 315, 616, 315, 315, -1145, - -1145, -1145, 624, -1145, -1145, -1145, -1145, -1145, 273, -1145, - -1145, 183, -1145, 282, -1145, -1145, -1145, 282, -1145, -1145, - 752, -1145, 752, 506, -1145, -1145, -1145, 801, -1145, 1044, - -1145, 400, 30, -1145, 61, 221, -1145, 61, 61, 61, - 61, -1145, -1145, 61, 61, 61, -1145, -1145, 61, -1145, - 61, -1145, -1145, -1145, -1145, -1145, -1145, -1145, 304, 61, - -1145, 61, -1145, -1145, 802, 315, 61, 61, 61, -1145, - 61, 61, 61, 61, -1145, 61, -1145, 61, -1145, -1145, - 315, 61, 315, 61, -1145, 61, 502, 304, -1145, 61, - -1145, 599, 599, 599, -1145, -1145, -1145, -1145, 315, 577, - 30, -1145, 599, 761, -1145, -1145, 347, 583, 559, 282, - -1145, -1145, -1145, -1145, 752, 395, 315, -1145, -1145, -1145, - 305, 315, 304, 30, 1085, 315, -1145, 61, 304, 61, - 304, 61, 304, -1145, 61, 61, 61, 328, 761, -1145, - 61, 61, -1145, 61, -1145, -1145, 61, -1145, 61, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, 61, -1145, 304, - -1145, 90, 61, -1145, 61, 61, -1145, 666, -1145, 30, - -1145, 30, 715, -1145, 30, 315, 577, 912, -1145, -1145, - 583, 559, 559, -1145, 752, 315, 30, 315, 400, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, 304, -1145, 304, 61, 61, -1145, 61, 61, - -1145, 61, 61, -1145, 61, -1145, -1145, 61, 61, 304, - 61, -1145, -1145, -1145, -1145, 315, -1145, 61, 61, 61, - 30, 30, -1145, -1145, 1410, 1663, -1145, 1450, 315, 1160, - -1145, -1145, 30, 559, -1145, 577, 315, 943, 315, 315, - 61, 61, 61, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - 61, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, 61, 61, -1145, -1145, -1145, - -1145, -1145, 315, -1145, 61, 61, 61, 61, 61, 61, - 315, -1145, 61, -1145, 61, -1145, 61, -1145, 61, -1145, - -1145, 61, 304, -1145, -1145, 577, 315, 524, 524, 696, - 696, -1145, 597, 117, 315, 523, 524, 545, 545, -1145, - 358, -1145, 315, -1145, -1145, 90, 61, -1145, -1145, -1145, - 61, 61, -1145, 61, 304, 61, 304, -1145, -1145, 61, - 61, -1145, 61, 304, 61, -1145, 61, 61, -1145, 61, - 61, 61, -1145, 61, -1145, 61, -1145, 61, 61, -1145, - 61, -1145, 61, 61, -1145, 61, -1145, 61, -1145, 315, - 315, -1145, -1145, 597, -1145, 752, 397, -1145, 624, -1145, - -1145, 597, -1145, 752, 397, -1145, -1145, -1145, 397, -1145, - -1145, -1145, 134, -1145, -1145, 358, -1145, -1145, -1145, 358, - -1145, -1145, -1145, -1145, 61, -1145, 61, 61, 61, 61, - 315, 61, 61, 315, 61, 61, 61, 61, 61, -1145, - -1145, 397, -1145, 157, -1145, -1145, -1145, 397, -1145, -1145, - -1145, -1145, -1145, -1145, -1145, 61, 315, 61, -1145, -1145, - -1145 + 820, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, 147, -1187, -1187, + -1187, 213, -1187, -1187, -1187, 213, -1187, -1187, -1187, -1187, + -1187, -1187, 213, 213, -1187, 213, -1187, 213, -1187, 213, + -1187, 213, -1187, -1187, -1187, 213, -1187, 213, -1187, 213, + -1187, 213, -1187, 213, -1187, 213, -1187, 213, -1187, 213, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, 213, -1187, -1187, + -1187, -1187, -1187, -1187, 213, -1187, 213, -1187, 213, -1187, + 213, -1187, 213, -1187, 213, -1187, -1187, -1187, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 928, 19, 19, 19, + 164, -1187, -1187, 17, -1187, 17, -1187, 17, 17, -1187, + 17, -1187, 17, 17, -1187, 17, 17, 17, 17, 17, + 17, 17, 17, 17, -1187, 17, -1187, 17, -1187, -1187, + -1187, -1187, 78, -1187, -1187, -1187, -1187, -1187, 94, 167, + 185, -1187, -1187, -1187, -1187, 345, -1187, 17, -1187, 17, + 17, 17, -1187, 17, 213, -1187, 1290, 154, 97, 97, + 680, 330, 412, 301, 499, 113, 345, 304, 345, 312, + 345, 160, 255, 345, 231, 1501, -1187, -1187, -1187, 487, + 100, -1187, -1187, 100, -1187, -1187, 100, -1187, -1187, 382, + 928, -1187, -1187, -1187, -1187, -1187, -1187, -1187, 385, -1187, + -1187, -1187, -1187, 292, 299, 317, 680, -1187, 17, -1187, + 17, 213, -1187, -1187, -1187, -1187, 213, 17, 213, 17, + -1187, 213, 213, 17, 17, -1187, -1187, -1187, -1187, 17, + 17, 17, 17, -1187, 17, 17, 17, -1187, -1187, -1187, + -1187, 213, 213, -1187, -1187, 17, 213, -1187, -1187, 213, + 17, 17, -1187, 17, -1187, -1187, 213, -1187, 17, 17, + 213, -1187, -1187, 17, 17, 213, -1187, -1187, 17, 17, + 213, -1187, -1187, 17, 17, 213, -1187, -1187, 17, 17, + 213, 17, 213, -1187, -1187, 17, 213, -1187, 17, -1187, + -1187, -1187, -1187, 213, -1187, 17, 213, 17, 17, 17, + 17, 17, -1187, 17, 213, 345, -1187, 459, 385, -1187, + -1187, 329, 345, 157, 345, 345, 19, 19, 102, 422, + 112, 19, 19, 442, 442, 102, 112, 442, 442, 680, + 345, 470, 19, 19, 243, 345, 19, 19, 242, 496, + 442, 19, 486, -1187, 486, 19, 496, 442, 19, 496, + 442, 19, 496, 442, 19, -1187, -1187, 669, 107, -1187, + 19, 442, 19, 1501, 385, 164, -1187, 19, 382, 164, + -1187, 505, 164, -1187, 382, 493, 928, -1187, 385, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, 17, 17, 213, + -1187, 213, -1187, -1187, 17, 17, 213, 17, -1187, -1187, + -1187, 17, 17, 17, -1187, 17, 213, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, 213, 345, 17, 213, -1187, 17, + 17, -1187, 17, 213, 17, 17, 345, 17, 17, -1187, + 17, -1187, 17, 17, 17, -1187, 17, 17, 213, -1187, + -1187, 17, 17, 17, 213, 345, 17, 17, 17, 17, + -1187, 345, 345, 17, 17, 345, 17, 17, 345, 17, + 17, -1187, -1187, 363, -1187, 345, 17, -1187, 345, 17, + 17, 17, 317, 345, -1187, 345, 17, -1187, 17, 213, + 17, -1187, 17, 213, 345, -1187, 489, 514, 19, 19, + -1187, -1187, 486, -1187, 1298, 506, 486, 345, 154, 112, + 565, 345, 385, 1217, -1187, 496, 19, 90, 90, 496, + 19, 496, 112, -1187, 496, 496, 327, 345, 496, 90, + 90, -1187, -1187, 19, 345, 154, 496, 1258, -1187, 496, + 364, -1187, -1187, -1187, -1187, 496, 108, -1187, 496, 245, + -1187, 496, 72, -1187, -1187, 385, -1187, -1187, 385, -1187, + -1187, -1187, 496, 412, 1402, 345, 385, -1187, -1187, 505, + 694, 345, 19, 534, 1206, 345, 19, -1187, 17, -1187, + -1187, 345, -1187, 345, -1187, 17, -1187, 345, 17, -1187, + 17, -1187, 17, 345, -1187, -1187, -1187, 213, -1187, 317, + 345, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, 17, 17, 17, -1187, -1187, + 17, 17, 17, 17, 17, 345, -1187, 17, 345, 345, + 345, 345, -1187, -1187, 17, 17, 213, -1187, 345, 17, + 17, 17, 17, -1187, 17, -1187, 17, 345, 17, 345, + 17, 17, 345, 17, 345, 17, 345, 17, 386, 427, + -1187, 635, 345, -1187, -1187, -1187, -1187, 17, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, 17, + 213, 17, 213, -1187, 17, 213, 17, 213, 17, 213, + 17, 213, 17, -1187, 213, 17, -1187, -1187, 17, -1187, + -1187, -1187, 213, 17, 17, 213, 17, 213, -1187, -1187, + 17, -1187, 213, -1187, -1187, 17, 514, -1187, -1187, -1187, + -1187, -1187, -1187, 140, -1187, 19, 385, -1187, 398, 398, + 398, 459, 102, 131, 345, 102, 345, -1187, 505, -1187, + -1187, -1187, -1187, -1187, -1187, 19, -1187, 102, 132, 345, + 102, 345, 459, 568, -1187, 398, -1187, 242, 345, -1187, + 345, -1187, 345, -1187, 345, -1187, 385, -1187, -1187, 385, + 385, -1187, 437, -1187, -1187, -1187, -1187, 470, 315, 572, + 754, -1187, 19, 527, -1187, 19, 323, -1187, 1298, 115, + -1187, 1298, 474, -1187, 669, -1187, 462, -1187, 688, 345, + 19, -1187, -1187, 19, -1187, 1298, 486, 345, 151, 101, + -1187, -1187, -1187, 17, -1187, 17, -1187, -1187, -1187, -1187, + 17, 17, 17, 17, 680, 345, 17, 17, 17, -1187, + 17, -1187, 17, -1187, 17, 17, -1187, -1187, 17, -1187, + 213, 17, 17, -1187, 17, -1187, -1187, 17, 17, 17, + 17, -1187, -1187, -1187, -1187, -1187, 449, 437, -1187, 635, + 385, -1187, 17, -1187, 17, -1187, 17, -1187, 17, -1187, + -1187, 345, 17, 17, 17, -1187, 345, 17, 17, -1187, + 17, 17, -1187, 17, -1187, -1187, 17, -1187, 345, -1187, + -1187, 17, 17, 17, 213, 17, -1187, 17, 17, 345, + -1187, -1187, -1187, -1187, -1187, -1187, 345, 17, 17, 345, + 345, 345, 345, 390, -1187, -1187, -1187, 345, -1187, -1187, + 345, 179, 345, 680, 345, -1187, 19, 390, -1187, -1187, + 345, 733, 345, 345, 345, -1187, -1187, 385, -1187, -1187, + -1187, 345, -1187, 457, -1187, -1187, 323, -1187, 115, -1187, + -1187, -1187, 115, -1187, -1187, 1298, -1187, 1298, 669, -1187, + -1187, -1187, 991, -1187, 928, -1187, 459, 19, -1187, 17, + 114, 505, -1187, -1187, 17, 17, 17, 17, -1187, -1187, + 17, 17, 17, -1187, -1187, 17, -1187, 17, 17, -1187, + -1187, -1187, -1187, -1187, -1187, 213, 17, -1187, 17, -1187, + -1187, -1187, 1034, -1187, 345, 17, 17, 17, -1187, 17, + 17, 17, 17, -1187, 17, -1187, 17, -1187, -1187, 345, + 17, 345, 17, -1187, 17, 534, 213, -1187, 17, -1187, + 596, 596, 596, -1187, -1187, -1187, -1187, 345, 680, -1187, + 19, -1187, 596, 1148, -1187, -1187, 190, 591, 557, 115, + -1187, -1187, -1187, -1187, 1298, 376, 345, -1187, -1187, -1187, + 287, 345, 213, 19, 972, 345, -1187, 17, 213, 17, + 213, 17, 213, -1187, 17, 17, 17, 204, 1148, -1187, + 17, 17, -1187, 17, -1187, -1187, 17, -1187, 17, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, 17, -1187, 213, + -1187, 151, 17, -1187, 17, 17, -1187, 906, -1187, 19, + -1187, 19, 566, -1187, 19, 345, 680, 1240, -1187, -1187, + 591, 557, 557, -1187, 1298, 345, 19, 345, 459, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, 213, -1187, 213, 17, 17, -1187, 17, 17, + -1187, 17, 17, -1187, 17, -1187, -1187, 17, 17, 213, + 17, -1187, -1187, -1187, -1187, 345, -1187, 17, 17, 17, + 19, 19, -1187, -1187, 1544, 1736, -1187, 1584, 345, 1080, + -1187, -1187, 19, 557, -1187, 680, 345, 899, 345, 345, + 17, 17, 17, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + 17, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, 17, 17, -1187, -1187, -1187, + -1187, -1187, 345, -1187, 17, 17, 17, 17, 17, 17, + 345, -1187, 17, -1187, 17, -1187, 17, -1187, 17, -1187, + -1187, 17, 213, -1187, -1187, 680, 345, 417, 417, 625, + 625, -1187, 605, 137, 345, 447, 417, 404, 404, -1187, + 476, -1187, 345, -1187, -1187, 151, 17, -1187, -1187, -1187, + 17, 17, -1187, 17, 213, 17, 213, -1187, -1187, 17, + 17, -1187, 17, 213, 17, -1187, 17, 17, -1187, 17, + 17, 17, -1187, 17, -1187, 17, -1187, 17, 17, -1187, + 17, -1187, 17, 17, -1187, 17, -1187, 17, -1187, 345, + 345, -1187, -1187, 605, -1187, 1298, 379, -1187, 385, -1187, + -1187, 605, -1187, 1298, 379, -1187, -1187, -1187, 379, -1187, + -1187, -1187, 103, -1187, -1187, 476, -1187, -1187, -1187, 476, + -1187, -1187, -1187, -1187, 17, -1187, 17, 17, 17, 17, + 345, 17, 17, 345, 17, 17, 17, 17, 17, -1187, + -1187, 379, -1187, 490, -1187, -1187, -1187, 379, -1187, -1187, + -1187, -1187, -1187, -1187, -1187, 17, 345, 17, -1187, -1187, + -1187 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1075,141 +1087,145 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 412, 401, 390, 400, 161, 424, 446, 392, 474, - 477, 591, 632, 658, 661, 499, 492, 351, 550, 484, - 481, 489, 487, 602, 648, 391, 414, 425, 393, 413, - 475, 479, 478, 500, 485, 482, 490, 0, 4, 5, - 2, 0, 13, 341, 342, 0, 574, 380, 378, 379, - 381, 382, 0, 0, 3, 0, 12, 0, 576, 0, - 11, 0, 578, 459, 460, 0, 14, 0, 580, 0, - 15, 0, 582, 0, 16, 0, 584, 0, 17, 0, - 575, 532, 530, 531, 533, 534, 577, 0, 579, 581, - 583, 585, 19, 18, 0, 7, 0, 8, 0, 9, + 0, 412, 401, 390, 400, 161, 424, 447, 392, 475, + 478, 593, 637, 672, 675, 500, 493, 351, 552, 485, + 482, 490, 488, 604, 659, 391, 414, 425, 393, 413, + 476, 480, 479, 501, 486, 483, 491, 0, 4, 5, + 2, 0, 13, 341, 342, 0, 576, 380, 378, 379, + 381, 382, 0, 0, 3, 0, 12, 0, 578, 0, + 11, 0, 580, 460, 461, 0, 14, 0, 582, 0, + 15, 0, 584, 0, 16, 0, 586, 0, 17, 0, + 577, 533, 531, 532, 534, 535, 579, 0, 581, 583, + 585, 587, 19, 18, 0, 7, 0, 8, 0, 9, 0, 10, 0, 6, 0, 1, 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 162, 0, 352, 0, 389, 0, 0, 402, - 0, 415, 0, 0, 447, 0, 0, 416, 0, 416, - 0, 416, 0, 494, 551, 0, 592, 0, 603, 617, - 604, 618, 605, 606, 620, 607, 608, 609, 610, 611, - 612, 613, 614, 615, 616, 0, 600, 0, 633, 0, - 0, 0, 635, 0, 0, 77, 0, 0, 0, 0, + 0, 415, 0, 0, 448, 0, 0, 416, 0, 416, + 0, 416, 0, 495, 553, 0, 594, 0, 605, 619, + 606, 620, 607, 608, 622, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 0, 602, 0, 638, 0, + 0, 0, 643, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 76, 599, 0, - 0, 0, 0, 0, 0, 40, 20, 37, 38, 39, - 41, 42, 0, 163, 21, 22, 26, 0, 25, 35, - 0, 164, 154, 356, 0, 0, 438, 439, 364, 395, - 0, 0, 0, 0, 394, 0, 0, 0, 0, 536, - 539, 537, 540, 0, 0, 0, 0, 403, 0, 416, - 0, 426, 427, 428, 429, 0, 0, 450, 449, 443, - 0, 563, 464, 0, 0, 0, 463, 0, 559, 560, - 0, 421, 190, 417, 0, 476, 566, 0, 0, 0, - 483, 569, 0, 0, 0, 488, 572, 0, 0, 0, - 506, 502, 190, 190, 0, 190, 0, 493, 553, 0, - 0, 586, 0, 587, 594, 595, 601, 0, 0, 0, - 0, 637, 0, 0, 0, 34, 27, 0, 33, 23, + 0, 0, 0, 0, 0, 0, 75, 76, 601, 0, + 0, 626, 628, 0, 650, 652, 0, 660, 662, 0, + 0, 40, 20, 37, 38, 39, 41, 42, 0, 163, + 21, 22, 26, 0, 25, 35, 0, 164, 154, 356, + 0, 0, 439, 440, 364, 395, 0, 0, 0, 0, + 394, 0, 0, 0, 0, 537, 540, 538, 541, 0, + 0, 0, 0, 403, 0, 416, 0, 426, 427, 428, + 429, 0, 0, 451, 450, 444, 0, 565, 465, 0, + 0, 0, 464, 0, 561, 562, 0, 421, 190, 417, + 0, 477, 568, 0, 0, 0, 484, 571, 0, 0, + 0, 489, 574, 0, 0, 0, 507, 503, 190, 190, + 0, 190, 0, 494, 555, 0, 0, 588, 0, 589, + 596, 597, 603, 0, 640, 0, 0, 0, 0, 0, + 0, 0, 645, 0, 0, 0, 34, 27, 0, 33, + 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 418, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 498, 497, 0, 0, 495, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 634, - 0, 29, 31, 28, 36, 168, 171, 165, 166, 155, - 158, 0, 160, 0, 153, 360, 0, 346, 0, 0, - 343, 348, 357, 354, 0, 0, 366, 370, 0, 406, - 217, 407, 388, 204, 205, 206, 0, 0, 0, 0, - 440, 0, 0, 513, 0, 0, 0, 0, 0, 0, - 0, 404, 397, 411, 0, 0, 0, 455, 190, 443, - 0, 442, 451, 190, 0, 0, 0, 0, 0, 0, - 190, 190, 422, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 50, 503, 48, 504, 0, 190, 507, - 0, 0, 0, 588, 596, 0, 0, 516, 643, 0, - 0, 669, 80, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 418, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 499, 498, 0, 0, 496, + 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, + 651, 0, 0, 661, 0, 0, 0, 642, 0, 29, + 31, 28, 36, 168, 171, 165, 166, 155, 158, 0, + 160, 0, 153, 360, 0, 346, 0, 0, 343, 348, + 357, 354, 0, 0, 366, 370, 0, 406, 217, 407, + 388, 204, 205, 206, 0, 0, 0, 0, 441, 0, + 0, 514, 0, 0, 0, 0, 0, 0, 0, 404, + 397, 411, 0, 0, 0, 456, 190, 444, 0, 443, + 452, 190, 0, 0, 0, 0, 0, 0, 190, 190, + 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 504, 48, 505, 0, 190, 508, 0, 0, + 0, 590, 598, 0, 641, 0, 0, 517, 654, 0, + 0, 686, 80, 0, 0, 32, 0, 0, 0, 0, 345, 350, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, 0, 0, 385, 0, 0, 0, 0, 0, 0, - 0, 444, 445, 0, 0, 0, 0, 0, 461, 0, - 0, 191, 419, 420, 480, 0, 0, 486, 0, 0, - 491, 0, 0, 44, 58, 0, 45, 49, 0, 501, - 496, 505, 0, 0, 0, 0, 597, 593, 0, 0, - 0, 0, 0, 0, 0, 0, 636, 156, 159, 169, - 0, 172, 0, 362, 346, 361, 0, 346, 358, 354, - 353, 0, 0, 375, 376, 371, 0, 363, 367, 0, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 0, 0, 0, 387, 408, 0, - 0, 544, 0, 544, 0, 514, 0, 0, 0, 0, - 0, 199, 198, 190, 190, 0, 396, 0, 0, 431, - 0, 431, 456, 0, 448, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 0, 59, - 0, 0, 554, 555, 556, 557, 0, 174, 100, 133, - 136, 144, 148, 98, 590, 82, 88, 89, 93, 0, - 85, 0, 92, 85, 0, 85, 0, 85, 0, 85, - 0, 85, 84, 0, 588, 573, 598, 625, 528, 641, - 647, 0, 643, 643, 0, 80, 0, 642, 517, 373, - 659, 0, 81, 660, 0, 0, 167, 170, 347, 359, - 344, 355, 0, 384, 0, 368, 365, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 535, 0, 538, 386, - 541, 542, 399, 398, 0, 423, 0, 0, 0, 0, - 0, 27, 0, 462, 0, 558, 0, 561, 564, 565, - 567, 568, 570, 571, 46, 0, 43, 68, 0, 0, - 53, 71, 55, 66, 67, 549, 0, 0, 0, 0, - 91, 0, 0, 117, 0, 0, 118, 0, 0, 119, - 0, 0, 120, 0, 83, 0, 589, 0, 0, 0, - 644, 645, 0, 646, 0, 0, 0, 0, 0, 157, - 0, 377, 373, 369, 232, 233, 234, 190, 190, 190, - 190, 0, 0, 544, 545, 543, 544, 547, 509, 202, - 0, 431, 197, 196, 441, 0, 432, 434, 430, 431, - 436, 457, 453, 0, 190, 0, 52, 48, 71, 60, - 0, 0, 70, 0, 96, 85, 94, 0, 90, 85, - 87, 101, 0, 85, 85, 85, 134, 0, 85, 85, - 137, 0, 85, 145, 0, 149, 150, 0, 79, 0, - 639, 631, 625, 625, 80, 0, 80, 624, 0, 0, - 0, 374, 515, 652, 653, 650, 651, 0, 0, 0, - 0, 0, 0, 0, 410, 24, 405, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 562, - 47, 69, 0, 54, 57, 72, 552, 95, 0, 86, - 99, 0, 121, 0, 122, 123, 132, 0, 124, 125, - 0, 126, 0, 0, 173, 626, 627, 0, 628, 0, - 630, 27, 0, 640, 0, 0, 372, 0, 0, 0, - 190, 546, 548, 190, 509, 509, 508, 203, 190, 435, - 0, 433, 437, 188, 186, 185, 187, 458, 0, 190, - 452, 0, 64, 56, 0, 0, 102, 103, 104, 105, - 85, 85, 85, 85, 138, 0, 146, 142, 151, 152, - 0, 80, 0, 0, 529, 373, 0, 0, 664, 665, - 663, 0, 0, 0, 409, 512, 510, 511, 0, 0, - 0, 454, 0, 0, 63, 97, 0, 0, 0, 0, - 127, 128, 129, 130, 0, 0, 0, 147, 629, 638, + 0, 445, 446, 0, 0, 0, 0, 0, 462, 0, + 0, 191, 419, 420, 481, 0, 0, 487, 0, 0, + 492, 0, 0, 44, 58, 0, 45, 49, 0, 502, + 497, 506, 0, 0, 0, 0, 599, 595, 639, 0, + 0, 0, 0, 0, 0, 0, 0, 644, 156, 159, + 169, 0, 172, 0, 362, 346, 361, 0, 346, 358, + 354, 353, 0, 0, 375, 376, 371, 0, 363, 367, + 0, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 0, 0, 0, 387, 408, + 0, 0, 545, 0, 545, 0, 515, 0, 0, 0, + 0, 0, 199, 198, 190, 190, 0, 396, 0, 0, + 431, 0, 431, 457, 0, 449, 0, 0, 0, 0, + 0, 190, 0, 190, 0, 190, 0, 190, 48, 0, + 59, 0, 0, 556, 557, 558, 559, 0, 174, 100, + 133, 136, 144, 148, 98, 592, 82, 88, 89, 93, + 0, 85, 0, 92, 85, 0, 85, 0, 85, 0, + 85, 0, 85, 84, 0, 590, 575, 600, 630, 529, + 649, 658, 0, 654, 654, 0, 80, 0, 653, 518, + 373, 673, 0, 81, 674, 0, 0, 167, 170, 347, + 359, 344, 355, 0, 384, 0, 368, 365, 0, 0, + 0, 27, 0, 0, 0, 0, 0, 536, 0, 539, + 386, 542, 543, 399, 398, 0, 423, 0, 0, 0, + 0, 0, 27, 0, 463, 0, 560, 0, 0, 566, + 0, 569, 0, 572, 0, 46, 0, 43, 68, 0, + 0, 53, 71, 55, 66, 67, 551, 0, 0, 0, + 0, 91, 0, 0, 117, 0, 0, 118, 0, 0, + 119, 0, 0, 120, 0, 83, 0, 591, 0, 0, + 0, 655, 656, 0, 657, 0, 0, 0, 0, 0, + 676, 678, 157, 0, 377, 373, 369, 232, 233, 234, + 190, 190, 190, 190, 0, 0, 545, 190, 190, 544, + 545, 549, 510, 202, 0, 431, 197, 196, 190, 442, + 0, 190, 190, 430, 431, 437, 458, 454, 0, 190, + 190, 563, 567, 570, 573, 52, 48, 71, 60, 0, + 0, 70, 190, 96, 85, 94, 0, 90, 85, 87, + 101, 0, 85, 85, 85, 134, 0, 85, 85, 137, + 0, 85, 145, 0, 149, 150, 0, 79, 0, 647, + 636, 630, 630, 80, 0, 80, 629, 0, 0, 0, + 374, 516, 666, 667, 664, 665, 0, 0, 0, 0, + 0, 0, 0, 0, 410, 24, 405, 0, 547, 546, + 0, 0, 0, 0, 0, 435, 0, 0, 432, 434, + 0, 0, 0, 0, 0, 47, 69, 0, 54, 57, + 72, 0, 95, 0, 86, 99, 0, 121, 0, 122, + 123, 132, 0, 124, 125, 0, 126, 0, 0, 173, + 631, 632, 0, 633, 0, 635, 27, 0, 648, 0, + 0, 0, 677, 372, 0, 0, 0, 190, 548, 550, + 190, 510, 510, 509, 203, 190, 436, 0, 190, 438, + 188, 186, 185, 187, 459, 0, 190, 453, 0, 564, + 64, 56, 0, 554, 0, 102, 103, 104, 105, 85, + 85, 85, 85, 138, 0, 146, 142, 151, 152, 0, + 80, 0, 0, 530, 373, 0, 0, 681, 682, 680, + 0, 0, 0, 409, 513, 511, 512, 0, 0, 433, + 0, 455, 0, 0, 63, 97, 0, 0, 0, 0, + 127, 128, 129, 130, 0, 0, 0, 147, 634, 646, 0, 0, 0, 0, 0, 0, 238, 208, 0, 80, - 0, 214, 0, 192, 190, 0, 466, 65, 0, 61, + 0, 214, 0, 192, 190, 0, 467, 65, 0, 61, 106, 107, 108, 109, 110, 111, 85, 139, 0, 143, - 141, 526, 521, 522, 523, 524, 525, 373, 519, 0, - 527, 0, 0, 668, 665, 665, 662, 0, 207, 0, - 212, 0, 0, 213, 0, 0, 0, 0, 465, 62, - 0, 0, 0, 131, 0, 0, 0, 0, 27, 667, - 666, 183, 180, 179, 182, 200, 181, 201, 211, 340, + 141, 527, 522, 523, 524, 525, 526, 373, 520, 0, + 528, 0, 0, 685, 682, 682, 679, 0, 207, 0, + 212, 0, 0, 213, 0, 0, 0, 0, 466, 62, + 0, 0, 0, 131, 0, 0, 0, 0, 27, 684, + 683, 183, 180, 179, 182, 200, 181, 201, 211, 340, 175, 177, 0, 176, 0, 208, 80, 239, 0, 0, - 216, 214, 0, 189, 190, 472, 470, 80, 80, 0, - 112, 113, 114, 115, 140, 0, 518, 194, 654, 190, + 216, 214, 0, 189, 190, 473, 471, 80, 80, 0, + 112, 113, 114, 115, 140, 0, 519, 194, 668, 190, 0, 0, 210, 209, 0, 0, 215, 0, 0, 0, - 467, 469, 0, 0, 135, 0, 0, 0, 0, 0, + 468, 470, 0, 0, 135, 0, 0, 0, 0, 0, 0, 194, 241, 298, 299, 300, 301, 302, 303, 304, 243, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 245, 247, 329, 330, 331, 332, 333, 0, 240, 265, 292, 272, 274, 276, 278, - 0, 271, 288, 184, 80, 473, 373, 116, 190, 520, - 657, 80, 0, 649, 670, 0, 0, 0, 0, 0, + 0, 271, 288, 184, 80, 474, 373, 116, 190, 521, + 671, 80, 0, 663, 687, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 468, 0, 195, 656, 0, 190, 193, 335, 339, + 0, 469, 0, 195, 670, 0, 190, 193, 335, 339, 190, 190, 242, 190, 0, 190, 0, 244, 337, 190, 190, 246, 190, 0, 190, 248, 190, 190, 266, 190, 190, 190, 293, 190, 236, 190, 273, 190, 190, 275, - 190, 277, 190, 190, 279, 190, 289, 190, 471, 0, + 190, 277, 190, 190, 279, 190, 289, 190, 472, 0, 0, 249, 256, 0, 253, 0, 0, 255, 0, 257, 264, 0, 261, 0, 0, 263, 267, 270, 0, 268, 294, 297, 0, 295, 280, 0, 282, 283, 284, 0, - 286, 287, 290, 291, 654, 178, 190, 190, 0, 190, - 0, 190, 190, 0, 190, 190, 190, 190, 190, 655, + 286, 287, 290, 291, 668, 178, 190, 190, 0, 190, + 0, 190, 190, 0, 190, 190, 190, 190, 190, 669, 252, 0, 250, 0, 254, 338, 260, 0, 258, 336, 262, 269, 296, 281, 285, 190, 0, 190, 251, 334, 259 @@ -1218,79 +1234,81 @@ static const yytype_uint16 yydefact[] = /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -1145, -1145, -1145, -206, -222, -184, -1145, -98, -180, 320, - -1145, -1145, -1145, -1145, -1145, -1145, -217, -325, -571, -33, - -675, -564, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -507, - -203, -1145, -1145, -1145, -794, -1145, -1145, -193, -39, 1855, - 1023, -42, -1145, -668, -517, -563, -1145, -1145, -107, -1145, - -1145, -103, -1145, -1145, -1145, -108, -252, -1145, -1145, -741, - -1145, -1145, -1145, -1145, -1145, -684, -1145, -1145, -1145, -1145, - -608, -1145, -1145, -1145, 0, -1145, -1145, -1145, -1145, -1145, - 194, -1145, -1145, -452, -1145, -1145, -685, -1145, -1145, -872, - -1145, -1145, -1145, -1145, -892, 1299, -342, -1144, -477, -1145, - -1145, -1145, -878, -966, 73, -1145, -426, -1145, -1145, -430, - -270, 167, -1145, -1145, -496, -915, -1145, -386, -904, -702, - -1145, -793, -529, -1145, -1145, -1145, -1145, -533, -1145, -1145, - -1145, -1145, -555, -523, -1145, -609, -1145, -1090, -1145, -367, - -1145, 736, -387, -151, 544, -391, 62, -45, -315, 151, - -1145, -1145, -1145, 242, -1145, -56, -1145, -145, -1145, -1145, - -1145, -1145, -1145, -1145, -791, -1145, -1145, -1145, -1145, 627, - 629, 633, 635, -232, 467, -1145, -1145, -105, 58, -1145, - -1145, -1145, -1145, -1145, -611, -1145, -1145, -1145, 3, -1145, - 593, -47, -1145, -1145, -1145, 637, -1145, -1145, -1145, -550, - -1145, -1145, -1145, 558, 572, 198, -148, 4, 323, -1145, - -1145, -1145, -1145, -1145, -1145, -1145, -344, -756, -855, -1145, - -1145, 647, 652, -1145, 245, -1145, -375, -1145, -1145, -1145, - -182, -1145, 660, -1145, -158, -1145, 661, -1145, -166, -1145, - 663, -1145, -170, -1145, -1145, 413, -1145, -1145, -1145, -1145, - -1145, 852, -321, -1145, -1145, -526, -1145, -1145, -692, -1145, - -1145, -1145, -774, -1145, -1145, 667, -1145, -1145, 603, -1145, - 605, -1145, -1145, 232, -569, 235, 237, 238, 673, -1145, - -1145, -1145, -1145, -1145, 676, -1145, -1145, -1145, -1145, 681, - -1145, -1145, 682, -1145, -1145, 684, -1145, -1145, 685, -178, - -322, 118, -1145, -1145, -1145, -1145, -1145, -1145, -1145, -1145, - -1145, -1145, 813, -219, -1145, -104, 405, -1145, 236, -1145, - -1145, -1145, -768, -1145, -1145, -34, 815, -1145, -1017, -515, - -1145, -916, 820, -1145, -1145, -1145, -424, -1145, -223 + -1187, -1187, -1187, -219, -226, -180, -1187, -126, -132, 296, + -1187, -1187, -1187, -1187, -1187, -1187, -223, -334, -589, -38, + -715, -585, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -528, + -245, -1187, -1187, -1187, -831, -1187, -1187, -238, -41, 1769, + 915, -44, -1187, -707, -567, -577, -1187, -1187, -147, -1187, + -1187, -144, -1187, -1187, -1187, -142, -298, -1187, -1187, -741, + -1187, -1187, -1187, -1187, -1187, -708, -1187, -1187, -1187, -1187, + -553, -1187, -1187, -1187, 0, -1187, -1187, -1187, -1187, -1187, + 144, -1187, -1187, -470, -1187, -1187, -698, -1187, -1187, -819, + -1187, -1187, -1187, -1187, -908, 1902, -408, -1186, -531, -1187, + -1187, -1187, -904, -1002, -40, -1187, -483, -1187, -1187, -484, + -278, 133, -1187, -1187, -513, -943, -1187, -440, -939, -726, + -1187, -959, -581, -1187, -1187, -1187, -1187, -593, -1187, -1187, + -1187, -1187, -641, -572, -1187, -639, -1187, -680, -1187, -427, + -1187, 715, -397, -162, 522, -395, 52, -184, -308, 117, + -1187, -1187, -1187, 197, -1187, -92, -1187, -149, -1187, -1187, + -1187, -1187, -1187, -1187, -804, -1187, -1187, -1187, -1187, 609, + 610, 612, 613, -246, 582, -1187, -1187, -93, 88, -1187, + -1187, -1187, -1187, -1187, -529, -1187, -1187, -1187, 2, -1187, + 454, -42, -1187, -1187, -1187, 624, -1187, -1187, -1187, -575, + -1187, -1187, -1187, 559, 560, 291, -191, 7, 293, -1187, + -1187, -1187, -1187, -1187, -1187, -1187, -356, -769, -883, -1187, + -1187, 633, 636, -1187, 207, -1187, -433, -1187, -1187, -1187, + -179, -1187, 641, -1187, -148, -1187, 647, -1187, -160, -1187, + 648, -1187, -158, -1187, -1187, 387, -1187, -1187, -1187, -1187, + -1187, 488, -325, -1187, -1187, -360, -1187, -1187, -729, -1187, + -1187, -1187, -774, -1187, -1187, 651, -1187, -1187, 589, -1187, + 592, -1187, -1187, 199, -558, 209, 211, 218, 676, -1187, + -1187, -1187, -1187, -1187, 679, -1187, -1187, -1187, -1187, 684, + -1187, -1187, 687, -1187, -1187, 689, -1187, -1187, 697, -168, + -303, 119, -1187, -1187, -1187, -1187, -1187, -1187, -1187, -1187, + -1187, -1187, 827, -1187, 511, -233, -1187, -107, -203, -1187, + -1187, -48, -1187, 43, -1187, -1187, -1187, -785, -1187, -1187, + -1187, 515, -17, 839, -1187, -1187, 518, -1061, -525, -1187, + -923, 850, -1187, -1187, -1187, -77, -1187, -416, -1187, -232 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 37, 38, 39, 222, 585, 224, 841, 225, 821, - 226, 227, 391, 392, 228, 328, 229, 230, 851, 555, - 474, 556, 475, 658, 847, 557, 770, 923, 558, 771, - 850, 983, 984, 1058, 772, 773, 774, 852, 108, 208, - 361, 430, 879, 574, 712, 780, 675, 676, 677, 678, - 679, 680, 681, 862, 985, 682, 683, 684, 867, 685, - 686, 871, 995, 1068, 1145, 687, 1036, 688, 874, 997, - 689, 690, 877, 1000, 460, 331, 41, 133, 232, 399, - 400, 401, 580, 402, 403, 582, 692, 693, 1119, 1261, - 1121, 1122, 977, 978, 834, 362, 634, 1123, 1166, 835, - 635, 1124, 830, 968, 422, 423, 1088, 424, 425, 1093, - 426, 614, 615, 616, 817, 1047, 1049, 1051, 1048, 1128, - 1212, 1262, 1271, 1213, 1278, 1220, 1286, 1291, 1221, 1296, - 1244, 1282, 1214, 1263, 1264, 1272, 1273, 1265, 1266, 1126, - 42, 239, 333, 503, 44, 334, 240, 135, 234, 507, - 235, 413, 589, 407, 408, 586, 584, 241, 242, 417, - 418, 599, 511, 595, 806, 596, 812, 46, 47, 48, - 49, 50, 51, 427, 137, 52, 53, 243, 409, 527, - 55, 140, 258, 442, 428, 429, 619, 822, 244, 57, - 142, 196, 283, 284, 463, 58, 59, 260, 261, 748, - 262, 263, 264, 245, 246, 431, 837, 893, 354, 61, - 145, 269, 270, 453, 449, 917, 701, 643, 842, 979, - 62, 63, 64, 275, 457, 1098, 1138, 1139, 1226, 65, + -1, 37, 38, 39, 228, 606, 230, 866, 231, 844, + 232, 233, 409, 410, 234, 339, 235, 236, 880, 575, + 492, 576, 493, 679, 876, 577, 791, 958, 578, 792, + 879, 1021, 1022, 1098, 793, 794, 795, 881, 108, 208, + 372, 448, 908, 595, 733, 801, 696, 697, 698, 699, + 700, 701, 702, 891, 1024, 703, 704, 705, 896, 706, + 707, 900, 1034, 1108, 1185, 708, 1076, 709, 903, 1036, + 710, 711, 906, 1039, 478, 342, 41, 133, 238, 417, + 418, 419, 601, 420, 421, 603, 713, 714, 1159, 1301, + 1161, 1162, 1014, 1015, 859, 373, 655, 1163, 1206, 860, + 656, 1164, 854, 1005, 440, 441, 1128, 442, 443, 1133, + 444, 635, 636, 637, 840, 1087, 1089, 1091, 1088, 1168, + 1252, 1302, 1311, 1253, 1318, 1260, 1326, 1331, 1261, 1336, + 1284, 1322, 1254, 1303, 1304, 1312, 1313, 1305, 1306, 1166, + 42, 245, 344, 523, 44, 345, 246, 135, 240, 527, + 241, 431, 610, 425, 426, 607, 605, 247, 248, 435, + 436, 620, 531, 616, 827, 617, 835, 46, 47, 48, + 49, 50, 51, 445, 137, 52, 53, 249, 427, 547, + 55, 140, 264, 460, 446, 447, 640, 845, 250, 57, + 142, 196, 289, 290, 481, 58, 59, 266, 267, 769, + 268, 269, 270, 251, 252, 449, 862, 922, 365, 61, + 145, 275, 276, 471, 467, 952, 722, 664, 867, 1016, + 62, 63, 64, 281, 475, 1138, 1178, 1179, 1266, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 203, 79, 303, 304, 477, 305, 306, - 480, 894, 910, 435, 626, 488, 489, 709, 702, 1077, - 1078, 1079, 703, 704, 1005, 80, 81, 82, 247, 83, - 248, 84, 85, 249, 733, 250, 251, 252, 86, 87, - 155, 309, 310, 666, 88, 277, 278, 279, 280, 89, - 288, 289, 90, 293, 294, 91, 298, 299, 92, 93, - 312, 565, 94, 157, 316, 317, 485, 95, 175, 96, - 176, 177, 895, 798, 98, 179, 183, 184, 322, 323, - 884, 885, 705, 706, 99, 570, 896, 101, 897, 1168, - 102, 711, 313, 104, 492, 1009, 1045, 493, 1010 + 76, 77, 78, 203, 79, 309, 310, 495, 311, 312, + 498, 923, 942, 453, 647, 927, 509, 730, 723, 1117, + 1118, 1119, 724, 725, 1044, 80, 81, 82, 253, 83, + 254, 84, 85, 255, 754, 256, 257, 258, 86, 87, + 155, 315, 316, 687, 88, 283, 284, 285, 286, 89, + 294, 295, 90, 299, 300, 91, 304, 305, 92, 93, + 318, 585, 94, 157, 322, 323, 503, 95, 175, 96, + 176, 177, 924, 211, 212, 819, 98, 179, 325, 326, + 505, 327, 184, 333, 334, 913, 914, 726, 727, 99, + 214, 215, 591, 925, 101, 217, 218, 926, 1208, 102, + 732, 319, 104, 512, 830, 831, 1048, 1085, 513, 1049 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1298,656 +1316,672 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 40, 393, 223, 56, 60, 325, 109, 327, 324, 450, - 257, 960, 276, 110, 111, 501, 112, 406, 113, 500, - 114, 899, 115, 883, 180, 181, 116, 311, 117, 886, - 118, 297, 119, 292, 120, 970, 121, 803, 122, 287, - 123, 863, 697, 888, 253, 578, 889, 674, 124, 274, - 329, 660, 700, 1054, 735, 125, 924, 126, 54, 127, - 483, 128, 45, 129, 1107, 130, 132, 134, 136, 136, - 139, 141, 136, 144, 136, 141, 136, 141, 136, 141, - 136, 141, 154, 156, 254, 178, 178, 178, 456, 769, - 1042, 750, 856, 764, 860, 419, 1003, 860, 864, 1281, - 860, 868, 198, 860, 200, 882, 860, 1056, 1050, 1052, - 394, 419, 832, 438, 7, 2, 15, 833, 875, 1, - 783, 824, 786, 15, 789, 4, 792, 2, 794, 12, - 1134, 1115, 105, 419, 5, 965, 836, 4, 433, 1259, - 296, 10, 1055, 420, 231, 214, 397, 5, 1115, 1274, - 1274, 5, 1279, 1283, 33, 1288, 667, 1293, 1293, 473, - 1297, 33, 238, 5, 832, 19, 484, 24, 441, 833, - 421, 233, 1125, 495, 865, 455, 131, 869, 1346, 1001, - 872, 1008, 494, 233, 405, 673, 421, 987, 1052, 34, - 1024, 31, 32, 591, 26, 282, 335, 301, 29, 1228, - 5, 336, 302, 338, 311, 1117, 340, 341, 421, 667, - 182, 828, 349, 1337, 1041, 1120, 948, 964, 950, 21, - 645, 1342, 1117, 185, 10, 1120, 351, 352, 1147, 1059, - 447, 355, 818, 819, 356, 1347, 671, 672, 1299, 1348, - -619, 360, 694, 36, 988, 364, 860, 990, 860, 259, - 367, 1232, 860, 1149, 907, 370, 273, 908, 844, 698, - 373, 848, 566, 809, 1099, 376, 456, 379, 998, 1256, - 1084, 381, 1170, 1171, 31, 32, 1, 592, 383, 922, - 881, 912, 898, 920, 388, 1060, 1105, 1082, 398, 915, - 628, 414, 927, 412, 134, 598, 929, 5, 236, 5, - 932, 934, 935, 669, 670, 938, 939, 237, 667, 941, - -621, 454, 1071, 452, 134, 19, 1072, 1073, 1074, 1075, - 989, 286, 462, 991, 267, 992, 671, 672, 238, 993, - 300, 301, 17, 1038, 476, 768, 672, 479, 657, 34, - 415, 659, 1061, 1063, 860, 233, 268, 437, 447, 696, - 2, 26, 5, 448, 444, 29, 5, 5, 650, 5, - 4, 667, 498, 461, 499, 281, 667, 1270, 1270, 504, - 1277, 670, 620, 622, 1076, 5, 725, 698, 670, 512, - 1259, 1090, 656, 654, 638, 640, 311, 513, 652, 1129, - 516, -622, 1132, 671, 672, 649, 520, 395, 396, 1231, - 671, 672, 631, -623, 1111, 393, 632, 810, 1112, 1113, - 1114, 533, 621, 623, 5, 308, 1140, 537, 1062, 1064, - 1065, 1066, 321, 500, 639, 641, 393, 1030, 1031, 1032, - 1033, 1336, 447, 718, 1339, 1252, 720, 843, 464, 1341, - 5, 467, 1344, 659, 470, 1267, 1345, 10, 326, 1, - 571, -30, 501, 1289, 575, 216, 579, 581, 1153, 416, - 21, 1366, 106, 107, 236, 291, 1116, 433, 238, 1160, - 1161, 714, 17, 237, 618, 206, 207, 631, 625, 1365, - 7, 632, 271, -59, 36, 1367, 5, 5, -59, -59, - -59, 642, 1141, 1142, 1143, 667, 420, 31, 32, 669, - 670, 238, 583, 1103, 832, 17, 588, 5, 813, 833, - 487, 131, 215, 216, 5, 217, 218, 219, 220, 221, - 314, 315, 671, 672, 26, 768, 633, 1083, 29, 708, - 553, 1111, 554, 178, 491, 1112, 1113, 1114, 396, 432, - 5, 5, 395, 1258, 1258, 1259, 1259, 710, 846, 445, - 446, 659, 849, 220, 221, 1227, 1251, 724, 459, 814, - 815, 816, 5, 1254, 691, 466, 1268, 1259, 469, 691, - 1118, 472, 553, 691, 845, 1130, 473, 405, 138, 482, - 1136, 143, -51, 146, 554, 148, 766, 150, 617, 152, - 593, 594, 624, 1116, 627, 668, 744, 629, 630, 878, - 1215, 637, 1222, 870, 1111, 554, 873, 1046, 1112, 1113, - 1114, 1007, 648, 672, 5, 318, 319, 320, 651, 1259, - 486, 653, 490, 973, 655, 765, 393, 974, 975, 976, - 233, 405, 820, 659, 849, 661, 671, 672, 1292, 1292, - 778, 905, 781, 1016, 1017, 784, 390, 787, 925, 790, - 1230, 793, 131, 215, 795, 921, 217, 218, 219, 768, - 1109, 1110, 799, 945, 946, 802, 1116, 804, 800, 801, - 854, 858, 807, 1111, 1046, 857, 986, 1112, 1113, 1114, - 1115, 215, 811, 5, 217, 218, 219, 220, 221, 766, - 577, 767, 667, 1069, 1236, 668, 669, 670, 768, 1152, - 1007, 1156, 829, 1111, 647, 982, 1131, 1112, 1113, 1114, - 147, 1275, 149, 5, 151, 1294, 153, 1268, 1259, 671, - 672, 673, 1287, 1046, 215, 216, 473, 217, 218, 219, - 1137, 967, 5, 768, 823, 1116, 43, 826, 272, 861, - 721, 667, 866, 1002, 668, 669, 670, 587, 890, 831, - 265, 876, 839, 158, 1117, 159, 994, 642, 996, 160, - 642, 161, 1023, 162, 266, 1116, 971, 659, 671, 672, - 673, 215, 532, 163, 217, 218, 219, 855, 164, 859, - 853, 646, 859, 393, 1224, 859, 165, 166, 859, 167, - 478, 859, 255, 168, 256, 662, 913, 691, 663, 169, - 664, 665, 170, 1, 2, 891, 1057, 171, 172, 3, - 173, 174, 796, 97, 4, 100, 5, 6, 5, 1349, - 103, 1085, 0, 7, 0, 0, 8, 667, 0, 0, - 668, 669, 670, 9, 10, 0, 11, 0, 12, 967, - 0, 659, 0, 13, 699, 14, 949, 0, 15, 0, - 1067, 16, 0, 0, 671, 672, 673, 0, 0, 17, - 5, 0, 18, 0, 19, 20, 21, 22, 0, 667, - 0, 829, 668, 669, 670, 23, 24, 25, 26, 27, - 0, 28, 29, 30, 31, 32, 33, 0, 34, 35, - 36, 0, 0, 0, 0, 0, 671, 672, 673, 215, - 216, 999, 217, 218, 219, 220, 221, 0, 215, 963, - 1004, 217, 218, 219, 220, 221, 967, 0, 767, 1111, - 1144, 0, 0, 1112, 1113, 1114, 1115, 0, 0, 5, - 0, 859, 0, 859, 0, 0, 0, 859, 667, 1020, - 0, 668, 669, 670, 0, 0, 0, 691, 1135, 215, - 216, 0, 217, 218, 219, 220, 221, 0, 0, 767, - 5, 0, 0, 3, 0, 671, 672, 673, 1043, 667, - 5, 6, 668, 669, 670, 0, 0, 0, 829, 667, - 8, 1116, 668, 669, 670, 967, 699, 9, 710, 0, - 0, 0, 0, 0, 0, 0, 671, 672, 673, 14, - 1117, 642, 0, 1081, 0, 16, 671, 672, 673, 1089, - 0, 1091, 0, 1094, 0, 0, 18, 0, 0, 20, - 0, 22, 0, 0, 0, 0, 0, 0, 0, 859, + 40, 335, 56, 411, 109, 336, 229, 60, 468, 338, + 328, 110, 111, 330, 112, 282, 113, 695, 114, 824, + 115, 180, 181, 721, 116, 997, 117, 520, 118, 521, + 119, 929, 120, 915, 121, 424, 122, 317, 123, 298, + 259, 508, 1007, 303, 912, 280, 124, 599, 959, 293, + 681, 917, 45, 125, 918, 126, 1094, 127, 263, 128, + 1147, 129, 892, 130, 132, 134, 136, 136, 139, 141, + 136, 144, 136, 141, 136, 141, 136, 141, 136, 141, + 154, 156, 183, 178, 178, 178, 756, 771, 54, 911, + 501, 474, 790, 785, 1, 893, 260, 1321, 897, 904, + 885, 1, 889, 1042, 340, 889, 1, 198, 889, 200, + 456, 889, 1090, 1092, 889, 412, 242, 1155, 437, 1096, + 5, 15, 1082, 465, 5, 243, 507, 804, 438, 807, + 5, 810, 5, 813, 1174, 815, 287, 437, 437, 856, + 182, 688, 237, 220, 857, 2, 244, 105, 5, 5, + 17, 1155, 719, 244, 5, 4, 1095, 17, 307, 1299, + 33, 415, 2, 432, 491, 329, 131, 1002, 331, 693, + 26, 502, 4, 19, 29, 7, 1386, 26, 324, 324, + 185, 29, 26, 472, 1165, 515, 29, 514, 465, 473, + 12, 1064, 1157, 1092, 439, 288, 5, 1040, 34, 451, + 346, 239, 308, 1268, 182, 347, 983, 349, 985, 15, + 351, 352, 1001, 439, 439, 239, 1047, 719, 239, 423, + 612, 691, 1026, 360, 848, 317, 1157, 459, 24, 718, + 362, 363, 1099, 302, 1339, 366, 841, 842, 367, 861, + 1081, -621, 1187, 692, 693, 371, 279, 666, 33, 375, + 894, 910, 465, 898, 378, 1027, 901, -623, 1029, 381, + 5, 877, 869, 1037, 384, 1189, 832, 1139, 889, 387, + 889, 390, 5, 1296, 889, 392, 586, 10, 474, 265, + 944, 715, 394, 613, 1272, 397, 1210, 1211, 937, 950, + 957, 955, 940, 406, 1111, 314, 649, 416, 1112, 1113, + 1114, 1115, 430, 134, 273, 306, 307, 962, 1160, 619, + 1124, 964, 21, 1145, 1122, 967, 969, 970, 1160, 1307, + 973, 974, 470, 134, 976, 1100, 274, 1329, 31, 32, + -624, 480, 5, 1078, 652, 2, 482, 36, 653, 485, + 5, 688, 488, 494, 5, 4, 497, 789, -625, 688, + 433, 329, 678, 504, 331, 680, 1116, 455, 1101, 1103, + -59, 413, 414, 717, 466, -59, -59, -59, 462, 19, + 694, 889, 106, 107, 479, 292, 692, 693, 518, 21, + 519, 671, 1130, 652, 297, 524, 1151, 653, 641, 643, + 1152, 1153, 1154, 746, 34, 532, 5, 856, 852, 10, + 659, 661, 857, 533, 36, 1169, 536, 5, 1172, 675, + 1028, 670, 540, 1030, 677, 1031, 317, 411, 673, 1032, + 244, 5, 1271, 332, 1151, 1308, 1299, 553, 1152, 1153, + 1154, 242, 1180, 557, 5, 833, 520, 1298, 411, 1299, + 243, 506, 337, 739, 642, 644, 741, 510, 1156, -30, + 31, 32, 1070, 1071, 1072, 1073, 660, 662, 680, 1193, + 1310, 1310, 1292, 1317, 5, 868, 222, 1298, 592, 1299, + 1200, 1201, 596, 521, 600, 602, 131, 221, 222, 434, + 223, 224, 225, 226, 227, 1406, 1156, 690, 691, 735, + 451, 5, 639, 5, 7, 638, 646, 856, 1299, 645, + 688, 648, 857, 5, 650, 651, 206, 207, 658, 663, + 692, 693, 438, 1102, 1104, 1105, 1106, 1123, 573, 669, + 574, 413, 604, 836, 1376, 672, 609, 1379, 674, 1143, + 507, 676, 1381, 221, 10, 1384, 223, 224, 225, 1385, + 511, -51, 682, 574, 5, 789, 654, 414, 729, 837, + 838, 839, 178, 688, 1255, 244, 1262, 1291, 691, 17, + 1158, 320, 321, 875, 1294, 1170, 680, 878, 423, 277, + 1176, 147, 1405, 149, 1086, 151, 745, 153, 1407, 731, + 692, 693, 573, 5, 712, 31, 32, 1181, 1182, 1183, + 712, 491, 688, 787, 712, 689, 690, 691, 870, 1314, + 1314, 689, 1319, 1323, 1086, 1328, 574, 1333, 1333, 907, + 1337, 693, 1151, 226, 227, 765, 1152, 1153, 1154, 692, + 693, 694, 5, 614, 615, 843, 928, 1299, 899, 239, + 423, 902, 1151, 408, 1046, 960, 1152, 1153, 1154, 956, + 1270, 786, 5, 450, 692, 693, 1308, 1299, 1332, 1332, + 1267, 883, 411, 463, 464, 886, 680, 878, 887, 799, + 598, 802, 477, 1377, 805, 1025, 808, 1109, 811, 484, + 814, 1382, 487, 816, 1156, 490, 1055, 1056, 980, 981, + 1276, 820, 1192, 500, 823, 1387, 825, 1196, 789, 1388, + 668, 828, 1171, 138, 1156, 1334, 143, 465, 146, 1315, + 148, 834, 150, 465, 152, 5, 821, 822, 1149, 1150, + 1177, 5, 935, 1327, 688, 43, 278, 689, 690, 691, + 688, 853, 608, 689, 690, 691, 719, 742, 1046, 789, + 909, 720, 719, 919, 1020, 158, 159, 720, 160, 161, + 1010, 692, 693, 694, 1011, 1012, 1013, 692, 693, 694, + 162, 271, 272, 847, 846, 491, 1008, 850, 890, 163, + 552, 895, 164, 667, 789, 1041, 1264, 165, 858, 855, + 905, 5, 864, 166, 167, 496, 663, 168, 261, 663, + 688, 262, 683, 221, 690, 691, 223, 224, 225, 226, + 227, 787, 684, 788, 685, 1033, 1063, 1035, 884, 680, + 888, 686, 169, 888, 882, 170, 888, 692, 693, 888, + 171, 1004, 888, 172, 411, 173, 131, 221, 712, 946, + 223, 224, 225, 174, 1, 2, 920, 97, 221, 222, + 3, 223, 224, 225, 817, 4, 396, 5, 6, 100, + 1097, 452, 454, 400, 7, 457, 458, 8, 403, 1389, + 103, 992, 1125, 0, 9, 10, 0, 11, 476, 12, + 0, 0, 0, 0, 13, 483, 14, 0, 486, 15, + 0, 489, 16, 984, 0, 680, 0, 0, 0, 499, + 17, 0, 0, 18, 0, 19, 20, 21, 22, 0, + 0, 0, 0, 0, 1107, 0, 23, 24, 0, 25, + 26, 27, 853, 28, 29, 30, 31, 32, 33, 0, + 34, 35, 36, 1151, 1086, 0, 5, 1152, 1153, 1154, + 1155, 0, 0, 5, 0, 688, 1004, 0, 689, 690, + 691, 0, 688, 0, 1038, 689, 690, 691, 3, 0, + 0, 1000, 720, 1043, 731, 0, 6, 0, 0, 0, + 0, 0, 692, 693, 694, 8, 0, 0, 0, 692, + 693, 694, 9, 0, 1184, 11, 888, 0, 888, 0, + 0, 0, 888, 0, 1060, 1156, 0, 0, 0, 0, + 16, 465, 712, 0, 0, 0, 0, 0, 0, 5, + 0, 18, 0, 0, 20, 1157, 22, 0, 688, 0, + 0, 689, 690, 691, 1004, 1083, 0, 25, 5, 27, + 719, 28, 0, 30, 0, 0, 853, 688, 0, 35, + 689, 690, 691, 0, 0, 692, 693, 694, 0, 0, + 0, 0, 0, 0, 720, 0, 0, 0, 0, 663, + 0, 1121, 0, 0, 692, 693, 694, 1129, 186, 1131, + 187, 1134, 188, 189, 0, 190, 0, 191, 192, 0, + 193, 194, 195, 197, 195, 199, 195, 201, 202, 888, + 204, 0, 205, 1004, 0, 0, 0, 0, 1146, 0, + 0, 0, 0, 0, 712, 1167, 0, 1167, 0, 0, + 1167, 0, 209, 0, 210, 213, 216, 5, 219, 0, + 0, 0, 853, 0, 0, 0, 688, 0, 0, 689, + 690, 691, 0, 0, 0, 0, 1175, 0, 0, 0, + 0, 1190, 0, 1191, 0, 1380, 0, 712, 0, 0, + 0, 0, 712, 692, 693, 694, 0, 712, 1202, 0, + 0, 0, 0, 1004, 0, 0, 853, 853, 0, 0, + 0, 0, 0, 341, 0, 343, 0, 0, 1265, 0, + 0, 0, 348, 0, 350, 1378, 0, 0, 353, 354, + 0, 0, 0, 1383, 355, 356, 357, 358, 0, 359, + 195, 361, 221, 222, 0, 223, 224, 225, 226, 227, + 364, 0, 788, 0, 0, 368, 369, 0, 370, 712, + 0, 0, 0, 0, 374, 0, 0, 712, 376, 377, + 0, 0, 0, 379, 380, 0, 0, 0, 382, 383, + 0, 0, 0, 5, 0, 0, 388, 0, 0, 0, + 391, 1295, 688, 393, 0, 689, 690, 691, 0, 0, + 395, 0, 398, 399, 401, 402, 404, 1151, 405, 0, + 0, 1152, 1153, 1154, 1155, 0, 0, 5, 0, 692, + 693, 694, 0, 1345, 0, 1348, 688, 0, 0, 689, + 690, 691, 1353, 0, 0, 0, 1175, 1300, 1300, 1309, + 1309, 0, 1316, 1320, 0, 1325, 1300, 1330, 1330, 0, + 1335, 0, 0, 692, 693, 694, 221, 0, 0, 223, + 224, 225, 226, 227, 0, 0, 788, 0, 0, 1156, + 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, + 631, 632, 633, 634, 0, 0, 0, 0, 0, 1157, + 0, 0, 516, 517, 0, 0, 0, 0, 0, 343, + 522, 0, 525, 0, 0, 0, 526, 528, 529, 0, + 530, 621, 622, 623, 624, 625, 626, 627, 628, 629, + 0, 535, 0, 0, 537, 538, 0, 539, 0, 541, + 542, 0, 544, 545, 0, 546, 0, 548, 549, 550, + 0, 0, 364, 0, 0, 0, 0, 555, 556, 0, + 0, 559, 560, 0, 0, 0, 0, 0, 565, 566, + 0, 568, 569, 0, 571, 572, 0, 0, 0, 0, + 0, 0, 3, 0, 582, 583, 584, 0, 0, 5, + 6, 589, 0, 590, 0, 593, 0, 594, 688, 8, + 0, 689, 690, 691, 0, 0, 9, 131, 221, 222, + 0, 223, 224, 225, 226, 227, 221, 222, 14, 223, + 224, 225, 226, 227, 16, 692, 693, 694, 0, 0, + 0, 0, 0, 0, 0, 18, 0, 0, 20, 0, + 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 27, 0, 28, 0, 30, 0, 0, - 1106, 0, 0, 35, 691, 0, 0, 1127, 0, 1127, - 0, 0, 1127, 0, 3, 967, 0, 0, 0, 0, - 0, 0, 6, 0, 829, 0, 0, 0, 131, 215, - 216, 8, 217, 218, 219, 220, 221, 0, 9, 0, - 0, 11, 0, 1150, 0, 1151, 0, 691, 0, 0, - 0, 1340, 691, 0, 447, 0, 16, 691, 0, 0, - 1162, 0, 5, 0, 0, 0, 0, 18, 829, 829, - 20, 667, 22, 0, 668, 669, 670, 0, 0, 0, - 1225, 1338, 25, 698, 27, 0, 28, 0, 30, 1343, - 0, 0, 0, 0, 35, 0, 0, 0, 671, 672, - 673, 600, 601, 602, 603, 604, 605, 606, 607, 608, - 609, 610, 611, 612, 613, 0, 186, 0, 187, 691, - 188, 189, 0, 190, 0, 191, 192, 691, 193, 194, - 195, 197, 195, 199, 195, 201, 202, 5, 204, 0, - 205, 0, 0, 0, 0, 0, 667, 0, 0, 668, - 669, 670, 0, 1255, 434, 436, 1135, 0, 439, 440, - 209, 0, 210, 211, 212, 0, 213, 0, 0, 0, - 0, 458, 0, 671, 672, 673, 0, 0, 465, 0, - 0, 468, 0, 0, 471, 1305, 0, 1308, 0, 0, - 0, 0, 481, 0, 1313, 0, 0, 1260, 1260, 1269, - 1269, 0, 1276, 1280, 0, 1285, 1260, 1290, 1290, 0, - 1295, 0, 0, 0, 0, 330, 0, 332, 0, 0, - 0, 0, 0, 0, 337, 0, 339, 0, 0, 0, - 342, 343, 0, 0, 0, 0, 344, 345, 346, 347, - 0, 348, 195, 350, 0, 0, 0, 0, 0, 0, - 0, 0, 353, 0, 0, 3, 0, 357, 358, 0, - 359, 0, 0, 6, 0, 0, 363, 0, 0, 0, - 365, 366, 8, 0, 0, 368, 369, 0, 0, 9, - 371, 372, 0, 0, 0, 0, 0, 0, 377, 0, - 0, 14, 380, 0, 0, 382, 0, 16, 0, 447, - 0, 384, 385, 386, 0, 387, 0, 5, 18, 0, - 0, 20, 0, 22, 0, 0, 667, 0, 0, 668, - 669, 670, 0, 25, 0, 27, 0, 28, 698, 30, - 447, 0, 880, 699, 0, 35, 0, 0, 5, 0, - 0, 0, 0, 671, 672, 673, 0, 667, 0, 0, - 668, 669, 670, 0, 0, 0, 0, 0, 0, 698, - 0, 0, 0, 0, 699, 600, 601, 602, 603, 604, - 605, 606, 607, 608, 671, 672, 673, 0, 0, 0, - 0, 0, 496, 497, 0, 0, 0, 0, 0, 332, - 502, 0, 505, 0, 0, 0, 506, 508, 509, 0, - 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 515, 0, 0, 517, 518, 0, 519, 0, 521, - 522, 0, 524, 525, 0, 526, 0, 528, 529, 530, - 0, 0, 353, 0, 0, 0, 0, 535, 536, 0, - 0, 539, 540, 0, 0, 0, 0, 0, 545, 546, - 0, 548, 549, 0, 551, 552, 0, 0, 0, 0, - 0, 0, 0, 0, 562, 563, 564, 0, 0, 568, - 0, 569, 0, 572, 0, 573, 1172, 1173, 1174, 1175, - 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, - 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, - 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, - 1206, 1207, 1208, 1209, 1210, 1211, 1216, 1173, 1174, 1175, - 1176, 1177, 1178, 1179, 1217, 1181, 1182, 1183, 1184, 1185, - 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, - 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1218, - 1219, 1207, 1208, 1209, 1210, 1211, 0, 0, 0, 0, - 715, 374, 375, 0, 378, 0, 0, 502, 0, 0, - 502, 0, 506, 0, 722, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 727, 728, 729, - 0, 0, 730, 731, 732, 734, 732, 0, 0, 737, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 746, 747, 749, 747, 0, 751, 0, 752, 0, - 754, 0, 756, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 776, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 777, 0, 779, 0, 0, 782, 0, 785, 0, - 788, 0, 791, 0, 791, 0, 0, 564, 0, 0, - 797, 0, 0, 0, 0, 569, 569, 0, 573, 0, - 0, 0, 805, 0, 0, 0, 0, 808, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, - 0, 0, 534, 0, 0, 0, 0, 0, 0, 541, - 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1173, 1174, 1175, 1176, 1177, 1178, 1179, 560, 1181, 1182, - 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, - 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, - 1203, 1204, 0, 0, 1207, 1208, 1209, 1210, 1211, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 722, 0, 805, 0, 0, 0, 0, - 0, 0, 0, 903, 0, 0, 732, 0, 0, 732, - 0, 909, 0, 911, 747, 0, 0, 0, 0, 914, - 0, 0, 747, 0, 0, 916, 752, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 791, 0, - 928, 0, 791, 0, 0, 0, 931, 933, 791, 0, - 0, 937, 791, 0, 940, 791, 0, 942, 0, 0, - 943, 0, 0, 0, 0, 797, 797, 947, 0, 573, - 0, 951, 952, 0, 0, 0, 0, 0, 0, 0, - 0, 955, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 742, 743, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 736, 0, 0, 0, 0, 0, 6, + 522, 0, 0, 522, 0, 526, 0, 743, 8, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, + 748, 749, 750, 16, 0, 751, 752, 753, 755, 753, + 0, 0, 758, 0, 18, 0, 0, 20, 0, 22, + 0, 0, 0, 0, 767, 768, 770, 768, 0, 772, + 25, 773, 27, 775, 28, 777, 30, 0, 0, 0, + 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 797, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 798, 0, 800, 0, 0, 803, + 0, 806, 0, 809, 0, 812, 0, 812, 0, 0, + 584, 0, 0, 818, 0, 0, 0, 0, 590, 590, + 0, 594, 0, 0, 0, 826, 0, 0, 0, 0, + 829, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, + 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, + 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, + 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, + 1251, 1256, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1257, + 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, + 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, + 1241, 1242, 1243, 1244, 1258, 1259, 1247, 1248, 1249, 1250, + 1251, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 743, 0, + 826, 0, 0, 0, 0, 0, 0, 0, 933, 0, + 0, 753, 0, 0, 0, 753, 0, 941, 0, 943, + 768, 0, 0, 0, 0, 0, 947, 0, 0, 768, + 0, 0, 951, 773, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 812, + 0, 963, 0, 812, 0, 0, 0, 966, 968, 812, + 0, 0, 972, 812, 0, 975, 812, 0, 977, 0, + 0, 978, 0, 0, 0, 0, 818, 818, 982, 0, + 594, 0, 986, 987, 0, 0, 0, 0, 0, 0, + 0, 0, 990, 991, 1213, 1214, 1215, 1216, 1217, 1218, + 1219, 0, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, + 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, + 1239, 1240, 1241, 1242, 1243, 1244, 0, 0, 1247, 1248, + 1249, 1250, 1251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1006, 0, 0, - 1011, 1012, 1013, 0, 0, 0, 0, 909, 909, 0, - 0, 0, 0, 1019, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1022, 0, 0, 0, 0, 1026, - 1027, 1028, 0, 1029, 791, 791, 791, 0, 1034, 0, - 1035, 0, 0, 0, 573, 0, 1040, 0, 805, 0, - 0, 0, 1044, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1045, 0, 0, 0, 0, 1050, + 1051, 1052, 0, 0, 0, 0, 941, 941, 0, 0, + 0, 0, 1058, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1062, 0, 0, 0, 0, 0, 0, + 1066, 1067, 1068, 0, 1069, 812, 812, 812, 0, 1074, + 0, 1075, 0, 0, 0, 594, 0, 1080, 0, 826, + 0, 0, 0, 1084, 0, 291, 0, 296, 0, 301, + 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 285, 0, 290, 0, 295, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1087, 0, 573, 0, 1092, 0, 0, 0, 1096, 1097, - 0, 0, 0, 1100, 1101, 0, 1102, 0, 0, 791, - 0, 1104, 0, 0, 0, 0, 0, 0, 0, 0, - 805, 0, 0, 0, 0, 1108, 0, 1044, 1044, 0, - 0, 0, 0, 0, 0, 0, 900, 901, 902, 904, + 0, 0, 1127, 0, 594, 0, 1132, 0, 0, 0, + 1136, 1137, 0, 0, 0, 1140, 1141, 0, 1142, 0, + 0, 812, 0, 1144, 0, 0, 0, 0, 0, 0, + 0, 0, 826, 0, 0, 0, 0, 1148, 0, 1084, + 1084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 918, 0, 0, 0, 0, 1087, 573, - 0, 1154, 1155, 0, 1092, 1157, 0, 0, 0, 0, - 1159, 573, 0, 1163, 0, 0, 0, 0, 0, 0, - 1165, 1167, 0, 0, 0, 0, 0, 0, 0, 389, - 0, 0, 0, 0, 0, 0, 404, 0, 410, 411, - 0, 0, 0, 1235, 1165, 1237, 0, 0, 0, 0, - 0, 0, 0, 1238, 443, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1239, 1240, - 0, 0, 0, 0, 0, 0, 0, 1242, 1243, 1245, - 1246, 1247, 1248, 0, 0, 1250, 0, 573, 0, 805, - 0, 0, 0, 0, 573, 0, 0, 0, 0, 1014, - 0, 0, 1015, 0, 0, 0, 0, 1018, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1021, 0, - 0, 0, 514, 0, 0, 0, 1303, 0, 1306, 0, - 0, 0, 0, 523, 0, 1311, 0, 1314, 0, 0, - 0, 0, 1318, 0, 0, 0, 1322, 0, 0, 0, - 1325, 0, 538, 0, 0, 1329, 0, 0, 543, 544, - 0, 0, 547, 0, 0, 550, 0, 0, 0, 0, - 0, 0, 559, 0, 0, 561, 0, 0, 0, 0, - 567, 0, 0, 0, 0, 0, 0, 0, 0, 576, - 0, 0, 0, 1095, 0, 0, 0, 1167, 0, 0, - 1351, 1353, 590, 0, 0, 1357, 597, 0, 0, 0, + 1127, 594, 0, 1194, 1195, 0, 1132, 1197, 0, 0, + 0, 0, 1199, 594, 0, 1203, 0, 0, 0, 0, + 0, 0, 1205, 1207, 407, 0, 0, 0, 0, 0, + 0, 422, 0, 428, 429, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1275, 1205, 1277, 0, 461, + 0, 0, 0, 0, 469, 1278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 636, 0, 0, 0, 0, 0, 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1279, 1280, 0, 0, 0, 0, 0, 0, 0, 1282, + 1283, 1285, 1286, 1287, 1288, 0, 0, 1290, 0, 594, + 0, 826, 0, 0, 0, 0, 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 695, 0, 0, 0, 0, 707, 0, 0, 0, 713, - 0, 0, 0, 1158, 0, 716, 0, 717, 0, 0, - 0, 719, 0, 0, 0, 0, 0, 723, 1169, 0, - 0, 0, 0, 0, 726, 0, 0, 0, 0, 0, + 385, 386, 0, 389, 534, 0, 0, 0, 1343, 0, + 1346, 0, 0, 0, 0, 543, 0, 1351, 0, 1354, + 0, 0, 0, 0, 1358, 0, 0, 0, 1362, 0, + 0, 0, 1365, 0, 558, 0, 0, 1369, 0, 0, + 563, 564, 0, 0, 567, 0, 0, 570, 0, 0, + 0, 0, 0, 0, 579, 0, 0, 581, 0, 0, + 0, 0, 587, 0, 588, 0, 0, 0, 0, 0, + 0, 0, 0, 597, 0, 0, 0, 0, 0, 1207, + 0, 0, 1391, 1393, 0, 0, 611, 1397, 0, 0, + 618, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 657, 0, 0, 0, + 0, 0, 0, 665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 736, - 0, 0, 738, 739, 740, 741, 0, 0, 0, 0, - 0, 0, 745, 0, 0, 0, 0, 0, 0, 0, - 0, 753, 0, 755, 0, 757, 758, 759, 760, 761, - 762, 763, 0, 0, 0, 0, 775, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 716, 0, 0, 0, 0, 0, + 728, 0, 0, 0, 734, 0, 0, 0, 551, 0, + 737, 0, 738, 554, 0, 0, 740, 0, 0, 0, + 561, 562, 744, 0, 0, 0, 0, 0, 0, 747, + 0, 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1300, 0, 0, 0, 1301, - 1302, 0, 1304, 0, 1307, 0, 0, 0, 1309, 1310, - 0, 1312, 0, 1315, 0, 1316, 1317, 0, 1319, 1320, - 1321, 0, 1323, 0, 1324, 0, 1326, 1327, 825, 1328, - 827, 1330, 1331, 0, 1332, 0, 1333, 0, 0, 0, - 0, 0, 0, 838, 0, 840, 0, 0, 0, 0, + 0, 0, 0, 0, 757, 0, 0, 759, 760, 761, + 762, 0, 0, 0, 0, 0, 0, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 774, 0, 776, 0, + 0, 779, 0, 781, 0, 783, 0, 0, 0, 0, + 0, 796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1350, 1352, 0, 1354, 0, - 1356, 1358, 0, 1360, 1361, 1362, 1363, 1364, 0, 0, - 0, 0, 0, 887, 0, 0, 0, 0, 0, 0, - 0, 892, 0, 0, 1368, 0, 1370, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 919, 0, 0, 0, 0, 0, 0, 0, 926, 0, - 0, 0, 0, 0, 0, 0, 0, 930, 0, 0, - 0, 0, 936, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 944, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 953, 0, 0, 0, 0, - 0, 0, 954, 0, 956, 957, 958, 959, 0, 0, - 0, 0, 961, 962, 0, 966, 0, 969, 0, 0, - 972, 0, 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 849, 0, 851, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 863, 0, + 865, 0, 0, 0, 0, 0, 0, 871, 0, 872, + 0, 873, 0, 874, 0, 0, 763, 764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 778, 0, 780, 0, 782, 0, 784, + 0, 0, 0, 0, 0, 0, 0, 0, 916, 0, + 0, 0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1025, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1037, 0, 1039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1070, 0, 0, 0, 0, 1080, 0, 0, 0, - 1086, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 965, 0, 0, 0, 0, 971, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 979, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 988, 0, + 0, 0, 0, 0, 0, 989, 0, 0, 993, 994, + 995, 996, 0, 0, 0, 0, 998, 0, 0, 999, + 0, 1003, 0, 1006, 0, 0, 0, 0, 0, 1009, + 0, 1017, 1018, 1019, 0, 0, 0, 0, 0, 0, + 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 930, 931, 932, 934, 0, 0, 0, 938, + 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 945, 0, 0, 948, 949, 0, 0, 0, 0, 0, + 0, 953, 954, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 961, 0, 0, 0, 0, 0, + 0, 0, 0, 1065, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1077, 0, + 1079, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1093, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1110, 0, 0, 0, 0, + 1120, 0, 0, 0, 1126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1133, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1146, 0, 1148, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1053, + 0, 0, 1054, 0, 1173, 0, 0, 1057, 0, 0, + 1059, 0, 0, 0, 1186, 0, 1188, 0, 1061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1164, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1223, 0, 0, 0, 0, 0, 0, - 0, 1229, 0, 1233, 1234, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1204, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1263, 0, 0, + 0, 0, 0, 0, 0, 1269, 0, 1273, 1274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1241, 0, 0, - 0, 0, 0, 0, 0, 1249, 0, 0, 0, 0, + 0, 1281, 0, 0, 0, 0, 0, 0, 0, 1289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1257, 0, 0, 0, 0, 0, 0, 0, 1284, - 0, 0, 0, 0, 0, 0, 0, 1298, 0, 0, + 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, + 0, 0, 0, 1324, 0, 0, 0, 0, 0, 0, + 0, 1338, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1209, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1374, 1375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1334, 1335, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1395, + 0, 0, 1399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1293, 0, 0, 0, 0, 1409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1340, 0, + 0, 0, 1341, 1342, 0, 1344, 0, 1347, 0, 0, + 0, 1349, 1350, 0, 1352, 0, 1355, 0, 1356, 1357, + 0, 1359, 1360, 1361, 0, 1363, 0, 1364, 0, 1366, + 1367, 0, 1368, 0, 1370, 1371, 0, 1372, 0, 1373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1355, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1369 + 0, 0, 0, 0, 0, 0, 0, 0, 1390, 1392, + 0, 1394, 0, 1396, 1398, 0, 1400, 1401, 1402, 1403, + 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1408, 0, 1410 }; static const yytype_int16 yycheck[] = { - 0, 326, 186, 0, 0, 222, 45, 229, 214, 353, - 190, 903, 194, 52, 53, 406, 55, 332, 57, 406, - 59, 812, 61, 797, 128, 129, 65, 205, 67, 797, - 69, 201, 71, 199, 73, 913, 75, 705, 77, 197, - 79, 782, 568, 799, 189, 497, 802, 564, 87, 194, - 230, 558, 569, 1019, 623, 94, 850, 96, 0, 98, - 382, 100, 0, 102, 1081, 104, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 189, 127, 128, 129, 358, 660, - 1006, 641, 777, 657, 779, 6, 951, 782, 782, 1243, - 785, 785, 149, 788, 151, 797, 791, 1022, 1012, 1013, - 327, 6, 7, 345, 24, 5, 49, 12, 793, 4, - 683, 732, 685, 49, 687, 15, 689, 5, 691, 39, - 1096, 14, 0, 6, 17, 909, 747, 15, 48, 22, - 73, 35, 1020, 16, 186, 184, 330, 17, 14, 1239, - 1240, 17, 1242, 1243, 87, 1245, 26, 1247, 1248, 376, - 1250, 87, 56, 17, 7, 65, 383, 77, 348, 12, - 81, 61, 1087, 390, 782, 357, 146, 785, 1322, 947, - 788, 955, 388, 61, 62, 55, 81, 928, 1092, 89, - 984, 85, 86, 508, 79, 195, 235, 51, 83, 1165, - 17, 240, 202, 242, 382, 88, 245, 246, 81, 26, - 40, 737, 259, 1303, 1005, 1087, 884, 909, 886, 67, - 535, 1311, 88, 162, 35, 1097, 265, 266, 1106, 1023, - 9, 270, 728, 729, 273, 1325, 53, 54, 1255, 1329, - 162, 280, 564, 91, 928, 284, 931, 931, 933, 191, - 289, 1167, 937, 1108, 823, 294, 194, 826, 754, 38, - 299, 768, 484, 715, 1058, 304, 536, 306, 943, 1235, - 1044, 310, 1150, 1151, 85, 86, 4, 509, 317, 850, - 797, 831, 808, 847, 323, 1026, 1077, 1043, 330, 839, - 522, 336, 855, 335, 336, 512, 859, 17, 19, 17, - 863, 864, 865, 30, 31, 868, 869, 28, 26, 872, - 162, 356, 7, 355, 356, 65, 11, 12, 13, 14, - 928, 71, 364, 931, 3, 933, 53, 54, 56, 937, - 50, 51, 60, 1001, 376, 660, 54, 379, 555, 89, - 337, 558, 1026, 1027, 1029, 61, 25, 344, 9, 566, - 5, 79, 17, 353, 350, 83, 17, 17, 540, 17, - 15, 26, 401, 363, 403, 23, 26, 1239, 1240, 408, - 1242, 31, 517, 518, 69, 17, 598, 38, 31, 418, - 22, 1049, 552, 549, 529, 530, 564, 426, 546, 1091, - 429, 162, 1094, 53, 54, 540, 435, 32, 33, 1167, - 53, 54, 7, 162, 7, 730, 11, 722, 11, 12, - 13, 450, 517, 518, 17, 64, 1100, 456, 1026, 1027, - 1028, 1029, 41, 810, 529, 530, 751, 990, 991, 992, - 993, 1303, 9, 584, 1306, 1226, 587, 752, 365, 1311, - 17, 368, 1314, 660, 371, 1238, 1318, 35, 149, 4, - 489, 149, 843, 1246, 493, 148, 498, 499, 1126, 57, - 67, 1353, 158, 159, 19, 72, 69, 48, 56, 1137, - 1138, 575, 60, 28, 516, 160, 161, 7, 520, 1351, - 24, 11, 70, 155, 91, 1357, 17, 17, 160, 161, - 162, 533, 1100, 1101, 1102, 26, 16, 85, 86, 30, - 31, 56, 502, 1066, 7, 60, 506, 17, 725, 12, - 25, 146, 147, 148, 17, 150, 151, 152, 153, 154, - 74, 75, 53, 54, 79, 850, 526, 1044, 83, 571, - 154, 7, 156, 575, 47, 11, 12, 13, 33, 341, - 17, 17, 32, 20, 20, 22, 22, 45, 765, 351, - 352, 768, 769, 153, 154, 1163, 1224, 596, 360, 150, - 151, 152, 17, 1231, 564, 367, 21, 22, 370, 569, - 1087, 373, 154, 573, 756, 1092, 793, 62, 111, 381, - 1097, 114, 154, 116, 156, 118, 155, 120, 515, 122, - 58, 59, 519, 69, 521, 29, 635, 524, 525, 146, - 1155, 528, 1157, 787, 7, 156, 790, 8, 11, 12, - 13, 955, 539, 54, 17, 210, 211, 212, 545, 22, - 384, 548, 386, 7, 551, 658, 951, 11, 12, 13, - 61, 62, 730, 850, 851, 562, 53, 54, 1247, 1248, - 679, 821, 681, 964, 965, 684, 326, 686, 851, 688, - 1167, 690, 146, 147, 693, 848, 150, 151, 152, 984, - 1084, 1085, 701, 882, 883, 704, 69, 706, 702, 703, - 777, 779, 711, 7, 8, 778, 928, 11, 12, 13, - 14, 147, 724, 17, 150, 151, 152, 153, 154, 155, - 496, 157, 26, 1035, 1171, 29, 30, 31, 1023, 1125, - 1044, 1131, 744, 7, 537, 922, 1092, 11, 12, 13, - 117, 1240, 119, 17, 121, 1248, 123, 21, 22, 53, - 54, 55, 1245, 8, 147, 148, 943, 150, 151, 152, - 1097, 911, 17, 1058, 731, 69, 0, 734, 194, 781, - 589, 26, 784, 949, 29, 30, 31, 505, 804, 746, - 192, 793, 749, 126, 88, 126, 940, 799, 942, 126, - 802, 126, 984, 126, 192, 69, 914, 984, 53, 54, - 55, 147, 449, 126, 150, 151, 152, 777, 126, 779, - 776, 536, 782, 1108, 1159, 785, 126, 126, 788, 126, - 377, 791, 189, 126, 189, 563, 835, 797, 563, 126, - 563, 563, 126, 4, 5, 805, 1023, 126, 126, 10, - 126, 126, 694, 0, 15, 0, 17, 18, 17, 1334, - 0, 1044, -1, 24, -1, -1, 27, 26, -1, -1, - 29, 30, 31, 34, 35, -1, 37, -1, 39, 1019, - -1, 1058, -1, 44, 43, 46, 885, -1, 49, -1, - 1034, 52, -1, -1, 53, 54, 55, -1, -1, 60, - 17, -1, 63, -1, 65, 66, 67, 68, -1, 26, - -1, 913, 29, 30, 31, 76, 77, 78, 79, 80, - -1, 82, 83, 84, 85, 86, 87, -1, 89, 90, - 91, -1, -1, -1, -1, -1, 53, 54, 55, 147, - 148, 943, 150, 151, 152, 153, 154, -1, 147, 909, - 952, 150, 151, 152, 153, 154, 1096, -1, 157, 7, - 1104, -1, -1, 11, 12, 13, 14, -1, -1, 17, - -1, 931, -1, 933, -1, -1, -1, 937, 26, 978, - -1, 29, 30, 31, -1, -1, -1, 947, 36, 147, - 148, -1, 150, 151, 152, 153, 154, -1, -1, 157, - 17, -1, -1, 10, -1, 53, 54, 55, 1007, 26, - 17, 18, 29, 30, 31, -1, -1, -1, 1020, 26, - 27, 69, 29, 30, 31, 1165, 43, 34, 45, -1, - -1, -1, -1, -1, -1, -1, 53, 54, 55, 46, - 88, 1043, -1, 1042, -1, 52, 53, 54, 55, 1048, - -1, 1050, -1, 1052, -1, -1, 63, -1, -1, 66, - -1, 68, -1, -1, -1, -1, -1, -1, -1, 1029, - -1, 78, -1, 80, -1, 82, -1, 84, -1, -1, - 1079, -1, -1, 90, 1044, -1, -1, 1089, -1, 1091, - -1, -1, 1094, -1, 10, 1235, -1, -1, -1, -1, - -1, -1, 18, -1, 1106, -1, -1, -1, 146, 147, - 148, 27, 150, 151, 152, 153, 154, -1, 34, -1, - -1, 37, -1, 1122, -1, 1124, -1, 1087, -1, -1, - -1, 1308, 1092, -1, 9, -1, 52, 1097, -1, -1, - 1139, -1, 17, -1, -1, -1, -1, 63, 1150, 1151, - 66, 26, 68, -1, 29, 30, 31, -1, -1, -1, - 1162, 1305, 78, 38, 80, -1, 82, -1, 84, 1313, - -1, -1, -1, -1, 90, -1, -1, -1, 53, 54, - 55, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, -1, 133, -1, 135, 1159, - 137, 138, -1, 140, -1, 142, 143, 1167, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 17, 155, -1, - 157, -1, -1, -1, -1, -1, 26, -1, -1, 29, - 30, 31, -1, 1232, 342, 343, 36, -1, 346, 347, - 177, -1, 179, 180, 181, -1, 183, -1, -1, -1, - -1, 359, -1, 53, 54, 55, -1, -1, 366, -1, - -1, 369, -1, -1, 372, 1264, -1, 1266, -1, -1, - -1, -1, 380, -1, 1273, -1, -1, 1237, 1238, 1239, - 1240, -1, 1242, 1243, -1, 1245, 1246, 1247, 1248, -1, - 1250, -1, -1, -1, -1, 232, -1, 234, -1, -1, - -1, -1, -1, -1, 241, -1, 243, -1, -1, -1, - 247, 248, -1, -1, -1, -1, 253, 254, 255, 256, - -1, 258, 259, 260, -1, -1, -1, -1, -1, -1, - -1, -1, 269, -1, -1, 10, -1, 274, 275, -1, - 277, -1, -1, 18, -1, -1, 283, -1, -1, -1, - 287, 288, 27, -1, -1, 292, 293, -1, -1, 34, - 297, 298, -1, -1, -1, -1, -1, -1, 305, -1, - -1, 46, 309, -1, -1, 312, -1, 52, -1, 9, - -1, 318, 319, 320, -1, 322, -1, 17, 63, -1, - -1, 66, -1, 68, -1, -1, 26, -1, -1, 29, - 30, 31, -1, 78, -1, 80, -1, 82, 38, 84, - 9, -1, 42, 43, -1, 90, -1, -1, 17, -1, - -1, -1, -1, 53, 54, 55, -1, 26, -1, -1, - 29, 30, 31, -1, -1, -1, -1, -1, -1, 38, - -1, -1, -1, -1, 43, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 53, 54, 55, -1, -1, -1, - -1, -1, 399, 400, -1, -1, -1, -1, -1, 406, - 407, -1, 409, -1, -1, -1, 413, 414, 415, -1, - 417, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 428, -1, -1, 431, 432, -1, 434, -1, 436, - 437, -1, 439, 440, -1, 442, -1, 444, 445, 446, - -1, -1, 449, -1, -1, -1, -1, 454, 455, -1, - -1, 458, 459, -1, -1, -1, -1, -1, 465, 466, - -1, 468, 469, -1, 471, 472, -1, -1, -1, -1, - -1, -1, -1, -1, 481, 482, 483, -1, -1, 486, - -1, 488, -1, 490, -1, 492, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, -1, -1, -1, -1, - 577, 302, 303, -1, 305, -1, -1, 584, -1, -1, - 587, -1, 589, -1, 591, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 614, 615, 616, - -1, -1, 619, 620, 621, 622, 623, -1, -1, 626, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 638, 639, 640, 641, -1, 643, -1, 645, -1, - 647, -1, 649, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 666, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 678, -1, 680, -1, -1, 683, -1, 685, -1, - 687, -1, 689, -1, 691, -1, -1, 694, -1, -1, - 697, -1, -1, -1, -1, 702, 703, -1, 705, -1, - -1, -1, 709, -1, -1, -1, -1, 714, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 448, -1, -1, - -1, -1, 453, -1, -1, -1, -1, -1, -1, 460, - 461, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 107, 108, 109, 110, 111, 112, 113, 478, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, -1, -1, 141, 142, 143, 144, 145, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 810, -1, 812, -1, -1, -1, -1, - -1, -1, -1, 820, -1, -1, 823, -1, -1, 826, - -1, 828, -1, 830, 831, -1, -1, -1, -1, 836, - -1, -1, 839, -1, -1, 842, 843, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 855, -1, - 857, -1, 859, -1, -1, -1, 863, 864, 865, -1, - -1, 868, 869, -1, 871, 872, -1, 874, -1, -1, - 877, -1, -1, -1, -1, 882, 883, 884, -1, 886, - -1, 888, 889, -1, -1, -1, -1, -1, -1, -1, - -1, 898, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 633, 634, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 220, 0, 337, 45, 228, 186, 0, 364, 235, + 213, 52, 53, 216, 55, 194, 57, 584, 59, 726, + 61, 128, 129, 590, 65, 933, 67, 424, 69, 424, + 71, 835, 73, 818, 75, 343, 77, 205, 79, 199, + 189, 401, 946, 201, 818, 194, 87, 517, 879, 197, + 578, 820, 0, 94, 823, 96, 1058, 98, 190, 100, + 1121, 102, 803, 104, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 130, 127, 128, 129, 644, 662, 0, 818, + 393, 369, 681, 678, 4, 803, 189, 1283, 806, 814, + 798, 4, 800, 986, 236, 803, 4, 149, 806, 151, + 356, 809, 1051, 1052, 812, 338, 19, 14, 6, 1062, + 17, 49, 1045, 9, 17, 28, 25, 704, 16, 706, + 17, 708, 17, 710, 1136, 712, 23, 6, 6, 7, + 40, 26, 186, 184, 12, 5, 56, 0, 17, 17, + 60, 14, 38, 56, 17, 15, 1060, 60, 51, 22, + 88, 341, 5, 347, 387, 213, 147, 941, 216, 54, + 80, 394, 15, 65, 84, 24, 1362, 80, 78, 78, + 163, 84, 80, 367, 1127, 408, 84, 406, 9, 368, + 39, 1022, 89, 1132, 82, 195, 17, 982, 90, 48, + 241, 61, 202, 1205, 40, 246, 913, 248, 915, 49, + 251, 252, 941, 82, 82, 61, 990, 38, 61, 62, + 528, 31, 963, 265, 753, 393, 89, 359, 77, 589, + 271, 272, 1063, 73, 1295, 276, 749, 750, 279, 768, + 1044, 163, 1146, 53, 54, 286, 194, 555, 88, 290, + 803, 818, 9, 806, 295, 963, 809, 163, 966, 300, + 17, 789, 775, 978, 305, 1148, 736, 1098, 966, 310, + 968, 312, 17, 1275, 972, 316, 502, 35, 556, 191, + 855, 584, 323, 529, 1207, 326, 1190, 1191, 846, 864, + 879, 876, 850, 334, 7, 64, 542, 341, 11, 12, + 13, 14, 346, 347, 3, 50, 51, 884, 1127, 532, + 1084, 888, 67, 1117, 1083, 892, 893, 894, 1137, 1278, + 897, 898, 366, 367, 901, 1066, 25, 1286, 86, 87, + 163, 375, 17, 1040, 7, 5, 376, 92, 11, 379, + 17, 26, 382, 387, 17, 15, 390, 681, 163, 26, + 348, 399, 575, 397, 402, 578, 69, 355, 1066, 1067, + 156, 32, 33, 586, 364, 161, 162, 163, 361, 65, + 55, 1069, 159, 160, 374, 71, 53, 54, 419, 67, + 421, 560, 1089, 7, 72, 426, 7, 11, 537, 538, + 11, 12, 13, 619, 90, 436, 17, 7, 758, 35, + 549, 550, 12, 444, 92, 1131, 447, 17, 1134, 569, + 963, 560, 453, 966, 572, 968, 584, 751, 566, 972, + 56, 17, 1207, 41, 7, 21, 22, 468, 11, 12, + 13, 19, 1140, 474, 17, 743, 833, 20, 772, 22, + 28, 398, 150, 605, 537, 538, 608, 404, 69, 150, + 86, 87, 1029, 1030, 1031, 1032, 549, 550, 681, 1166, + 1279, 1280, 1266, 1282, 17, 773, 149, 20, 509, 22, + 1177, 1178, 513, 868, 518, 519, 147, 148, 149, 57, + 151, 152, 153, 154, 155, 1393, 69, 30, 31, 596, + 48, 17, 536, 17, 24, 535, 540, 7, 22, 539, + 26, 541, 12, 17, 544, 545, 161, 162, 548, 553, + 53, 54, 16, 1066, 1067, 1068, 1069, 1084, 155, 559, + 157, 32, 522, 746, 1343, 565, 526, 1346, 568, 1106, + 25, 571, 1351, 148, 35, 1354, 151, 152, 153, 1358, + 47, 155, 582, 157, 17, 879, 546, 33, 592, 151, + 152, 153, 596, 26, 1195, 56, 1197, 1264, 31, 60, + 1127, 74, 75, 786, 1271, 1132, 789, 790, 62, 70, + 1137, 117, 1391, 119, 8, 121, 617, 123, 1397, 45, + 53, 54, 155, 17, 584, 86, 87, 1140, 1141, 1142, + 590, 814, 26, 156, 594, 29, 30, 31, 777, 1279, + 1280, 29, 1282, 1283, 8, 1285, 157, 1287, 1288, 147, + 1290, 54, 7, 154, 155, 656, 11, 12, 13, 53, + 54, 55, 17, 58, 59, 751, 829, 22, 808, 61, + 62, 811, 7, 337, 990, 880, 11, 12, 13, 877, + 1207, 679, 17, 352, 53, 54, 21, 22, 1287, 1288, + 1203, 798, 986, 362, 363, 799, 879, 880, 800, 700, + 516, 702, 371, 1343, 705, 963, 707, 1075, 709, 378, + 711, 1351, 381, 714, 69, 384, 1001, 1002, 911, 912, + 1211, 722, 1165, 392, 725, 1365, 727, 1171, 1022, 1369, + 557, 732, 1132, 111, 69, 1288, 114, 9, 116, 1280, + 118, 745, 120, 9, 122, 17, 723, 724, 1124, 1125, + 1137, 17, 844, 1285, 26, 0, 194, 29, 30, 31, + 26, 765, 525, 29, 30, 31, 38, 610, 1084, 1063, + 42, 43, 38, 825, 957, 126, 126, 43, 126, 126, + 7, 53, 54, 55, 11, 12, 13, 53, 54, 55, + 126, 192, 192, 753, 752, 978, 947, 755, 802, 126, + 467, 805, 126, 556, 1098, 984, 1199, 126, 768, 767, + 814, 17, 770, 126, 126, 388, 820, 126, 189, 823, + 26, 189, 583, 148, 30, 31, 151, 152, 153, 154, + 155, 156, 583, 158, 583, 975, 1022, 977, 798, 1022, + 800, 583, 126, 803, 797, 126, 806, 53, 54, 809, + 126, 943, 812, 126, 1148, 126, 147, 148, 818, 860, + 151, 152, 153, 126, 4, 5, 826, 0, 148, 149, + 10, 151, 152, 153, 715, 15, 325, 17, 18, 0, + 1063, 353, 354, 328, 24, 357, 358, 27, 330, 1374, + 0, 928, 1084, -1, 34, 35, -1, 37, 370, 39, + -1, -1, -1, -1, 44, 377, 46, -1, 380, 49, + -1, 383, 52, 914, -1, 1098, -1, -1, -1, 391, + 60, -1, -1, 63, -1, 65, 66, 67, 68, -1, + -1, -1, -1, -1, 1074, -1, 76, 77, -1, 79, + 80, 81, 946, 83, 84, 85, 86, 87, 88, -1, + 90, 91, 92, 7, 8, -1, 17, 11, 12, 13, + 14, -1, -1, 17, -1, 26, 1058, -1, 29, 30, + 31, -1, 26, -1, 978, 29, 30, 31, 10, -1, + -1, 941, 43, 987, 45, -1, 18, -1, -1, -1, + -1, -1, 53, 54, 55, 27, -1, -1, -1, 53, + 54, 55, 34, -1, 1144, 37, 966, -1, 968, -1, + -1, -1, 972, -1, 1015, 69, -1, -1, -1, -1, + 52, 9, 982, -1, -1, -1, -1, -1, -1, 17, + -1, 63, -1, -1, 66, 89, 68, -1, 26, -1, + -1, 29, 30, 31, 1136, 1046, -1, 79, 17, 81, + 38, 83, -1, 85, -1, -1, 1060, 26, -1, 91, + 29, 30, 31, -1, -1, 53, 54, 55, -1, -1, + -1, -1, -1, -1, 43, -1, -1, -1, -1, 1083, + -1, 1082, -1, -1, 53, 54, 55, 1088, 133, 1090, + 135, 1092, 137, 138, -1, 140, -1, 142, 143, -1, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 1069, + 155, -1, 157, 1205, -1, -1, -1, -1, 1119, -1, + -1, -1, -1, -1, 1084, 1129, -1, 1131, -1, -1, + 1134, -1, 177, -1, 179, 180, 181, 17, 183, -1, + -1, -1, 1146, -1, -1, -1, 26, -1, -1, 29, + 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, + -1, 1162, -1, 1164, -1, 1348, -1, 1127, -1, -1, + -1, -1, 1132, 53, 54, 55, -1, 1137, 1179, -1, + -1, -1, -1, 1275, -1, -1, 1190, 1191, -1, -1, + -1, -1, -1, 238, -1, 240, -1, -1, 1202, -1, + -1, -1, 247, -1, 249, 1345, -1, -1, 253, 254, + -1, -1, -1, 1353, 259, 260, 261, 262, -1, 264, + 265, 266, 148, 149, -1, 151, 152, 153, 154, 155, + 275, -1, 158, -1, -1, 280, 281, -1, 283, 1199, + -1, -1, -1, -1, 289, -1, -1, 1207, 293, 294, + -1, -1, -1, 298, 299, -1, -1, -1, 303, 304, + -1, -1, -1, 17, -1, -1, 311, -1, -1, -1, + 315, 1272, 26, 318, -1, 29, 30, 31, -1, -1, + 325, -1, 327, 328, 329, 330, 331, 7, 333, -1, + -1, 11, 12, 13, 14, -1, -1, 17, -1, 53, + 54, 55, -1, 1304, -1, 1306, 26, -1, -1, 29, + 30, 31, 1313, -1, -1, -1, 36, 1277, 1278, 1279, + 1280, -1, 1282, 1283, -1, 1285, 1286, 1287, 1288, -1, + 1290, -1, -1, 53, 54, 55, 148, -1, -1, 151, + 152, 153, 154, 155, -1, -1, 158, -1, -1, 69, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, -1, -1, -1, -1, -1, 89, + -1, -1, 417, 418, -1, -1, -1, -1, -1, 424, + 425, -1, 427, -1, -1, -1, 431, 432, 433, -1, + 435, 93, 94, 95, 96, 97, 98, 99, 100, 101, + -1, 446, -1, -1, 449, 450, -1, 452, -1, 454, + 455, -1, 457, 458, -1, 460, -1, 462, 463, 464, + -1, -1, 467, -1, -1, -1, -1, 472, 473, -1, + -1, 476, 477, -1, -1, -1, -1, -1, 483, 484, + -1, 486, 487, -1, 489, 490, -1, -1, -1, -1, + -1, -1, 10, -1, 499, 500, 501, -1, -1, 17, + 18, 506, -1, 508, -1, 510, -1, 512, 26, 27, + -1, 29, 30, 31, -1, -1, 34, 147, 148, 149, + -1, 151, 152, 153, 154, 155, 148, 149, 46, 151, + 152, 153, 154, 155, 52, 53, 54, 55, -1, -1, + -1, -1, -1, -1, -1, 63, -1, -1, 66, -1, + 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 79, -1, 81, -1, 83, -1, 85, -1, -1, + -1, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, -1, 598, -1, -1, -1, -1, -1, 18, + 605, -1, -1, 608, -1, 610, -1, 612, 27, -1, + -1, -1, -1, -1, -1, 34, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 46, -1, -1, + 635, 636, 637, 52, -1, 640, 641, 642, 643, 644, + -1, -1, 647, -1, 63, -1, -1, 66, -1, 68, + -1, -1, -1, -1, 659, 660, 661, 662, -1, 664, + 79, 666, 81, 668, 83, 670, 85, -1, -1, -1, + -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 687, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 699, -1, 701, -1, -1, 704, + -1, 706, -1, 708, -1, 710, -1, 712, -1, -1, + 715, -1, -1, 718, -1, -1, -1, -1, 723, 724, + -1, 726, -1, -1, -1, 730, -1, -1, -1, -1, + 735, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 833, -1, + 835, -1, -1, -1, -1, -1, -1, -1, 843, -1, + -1, 846, -1, -1, -1, 850, -1, 852, -1, 854, + 855, -1, -1, -1, -1, -1, 861, -1, -1, 864, + -1, -1, 867, 868, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 884, + -1, 886, -1, 888, -1, -1, -1, 892, 893, 894, + -1, -1, 897, 898, -1, 900, 901, -1, 903, -1, + -1, 906, -1, -1, -1, -1, 911, 912, 913, -1, + 915, -1, 917, 918, -1, -1, -1, -1, -1, -1, + -1, -1, 927, 928, 108, 109, 110, 111, 112, 113, + 114, -1, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, + 144, 145, 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 954, -1, -1, - 957, 958, 959, -1, -1, -1, -1, 964, 965, -1, - -1, -1, -1, 970, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 981, -1, -1, -1, -1, 986, - 987, 988, -1, 990, 991, 992, 993, -1, 995, -1, - 997, -1, -1, -1, 1001, -1, 1003, -1, 1005, -1, - -1, -1, 1009, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 989, -1, -1, -1, -1, 994, + 995, 996, -1, -1, -1, -1, 1001, 1002, -1, -1, + -1, -1, 1007, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1018, -1, -1, -1, -1, -1, -1, + 1025, 1026, 1027, -1, 1029, 1030, 1031, 1032, -1, 1034, + -1, 1036, -1, -1, -1, 1040, -1, 1042, -1, 1044, + -1, -1, -1, 1048, -1, 196, -1, 198, -1, 200, + -1, -1, 203, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 196, -1, 198, -1, 200, -1, -1, 203, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1047, -1, 1049, -1, 1051, -1, -1, -1, 1055, 1056, - -1, -1, -1, 1060, 1061, -1, 1063, -1, -1, 1066, - -1, 1068, -1, -1, -1, -1, -1, -1, -1, -1, - 1077, -1, -1, -1, -1, 1082, -1, 1084, 1085, -1, - -1, -1, -1, -1, -1, -1, 817, 818, 819, 820, + -1, -1, 1087, -1, 1089, -1, 1091, -1, -1, -1, + 1095, 1096, -1, -1, -1, 1100, 1101, -1, 1103, -1, + -1, 1106, -1, 1108, -1, -1, -1, -1, -1, -1, + -1, -1, 1117, -1, -1, -1, -1, 1122, -1, 1124, + 1125, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 844, -1, -1, -1, -1, 1125, 1126, - -1, 1128, 1129, -1, 1131, 1132, -1, -1, -1, -1, - 1137, 1138, -1, 1140, -1, -1, -1, -1, -1, -1, - 1147, 1148, -1, -1, -1, -1, -1, -1, -1, 324, - -1, -1, -1, -1, -1, -1, 331, -1, 333, 334, - -1, -1, -1, 1170, 1171, 1172, -1, -1, -1, -1, - -1, -1, -1, 1180, 349, -1, -1, -1, -1, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1205, 1206, - -1, -1, -1, -1, -1, -1, -1, 1214, 1215, 1216, - 1217, 1218, 1219, -1, -1, 1222, -1, 1224, -1, 1226, - -1, -1, -1, -1, 1231, -1, -1, -1, -1, 960, - -1, -1, 963, -1, -1, -1, -1, 968, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 979, -1, - -1, -1, 427, -1, -1, -1, 1263, -1, 1265, -1, - -1, -1, -1, 438, -1, 1272, -1, 1274, -1, -1, - -1, -1, 1279, -1, -1, -1, 1283, -1, -1, -1, - 1287, -1, 457, -1, -1, 1292, -1, -1, 463, 464, - -1, -1, 467, -1, -1, 470, -1, -1, -1, -1, - -1, -1, 477, -1, -1, 480, -1, -1, -1, -1, - 485, -1, -1, -1, -1, -1, -1, -1, -1, 494, - -1, -1, -1, 1054, -1, -1, -1, 1334, -1, -1, - 1337, 1338, 507, -1, -1, 1342, 511, -1, -1, -1, + 1165, 1166, -1, 1168, 1169, -1, 1171, 1172, -1, -1, + -1, -1, 1177, 1178, -1, 1180, -1, -1, -1, -1, + -1, -1, 1187, 1188, 335, -1, -1, -1, -1, -1, + -1, 342, -1, 344, 345, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1210, 1211, 1212, -1, 360, + -1, -1, -1, -1, 365, 1220, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 527, -1, -1, -1, -1, -1, -1, 534, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1245, 1246, -1, -1, -1, -1, -1, -1, -1, 1254, + 1255, 1256, 1257, 1258, 1259, -1, -1, 1262, -1, 1264, + -1, 1266, -1, -1, -1, -1, 1271, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 565, -1, -1, -1, -1, 570, -1, -1, -1, 574, - -1, -1, -1, 1134, -1, 580, -1, 582, -1, -1, - -1, 586, -1, -1, -1, -1, -1, 592, 1149, -1, - -1, -1, -1, -1, 599, -1, -1, -1, -1, -1, + 308, 309, -1, 311, 445, -1, -1, -1, 1303, -1, + 1305, -1, -1, -1, -1, 456, -1, 1312, -1, 1314, + -1, -1, -1, -1, 1319, -1, -1, -1, 1323, -1, + -1, -1, 1327, -1, 475, -1, -1, 1332, -1, -1, + 481, 482, -1, -1, 485, -1, -1, 488, -1, -1, + -1, -1, -1, -1, 495, -1, -1, 498, -1, -1, + -1, -1, 503, -1, 505, -1, -1, -1, -1, -1, + -1, -1, -1, 514, -1, -1, -1, -1, -1, 1374, + -1, -1, 1377, 1378, -1, -1, 527, 1382, -1, -1, + 531, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 547, -1, -1, -1, + -1, -1, -1, 554, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 624, - -1, -1, 627, 628, 629, 630, -1, -1, -1, -1, - -1, -1, 637, -1, -1, -1, -1, -1, -1, -1, - -1, 646, -1, 648, -1, 650, 651, 652, 653, 654, - 655, 656, -1, -1, -1, -1, 661, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1228, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 585, -1, -1, -1, -1, -1, + 591, -1, -1, -1, 595, -1, -1, -1, 466, -1, + 601, -1, 603, 471, -1, -1, 607, -1, -1, -1, + 478, 479, 613, -1, -1, -1, -1, -1, -1, 620, + -1, -1, -1, -1, -1, -1, -1, -1, 496, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1256, -1, -1, -1, 1260, - 1261, -1, 1263, -1, 1265, -1, -1, -1, 1269, 1270, - -1, 1272, -1, 1274, -1, 1276, 1277, -1, 1279, 1280, - 1281, -1, 1283, -1, 1285, -1, 1287, 1288, 733, 1290, - 735, 1292, 1293, -1, 1295, -1, 1297, -1, -1, -1, - -1, -1, -1, 748, -1, 750, -1, -1, -1, -1, + -1, -1, -1, -1, 645, -1, -1, 648, 649, 650, + 651, -1, -1, -1, -1, -1, -1, 658, -1, -1, + -1, -1, -1, -1, -1, -1, 667, -1, 669, -1, + -1, 672, -1, 674, -1, 676, -1, -1, -1, -1, + -1, 682, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1336, 1337, -1, 1339, -1, - 1341, 1342, -1, 1344, 1345, 1346, 1347, 1348, -1, -1, - -1, -1, -1, 798, -1, -1, -1, -1, -1, -1, - -1, 806, -1, -1, 1365, -1, 1367, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 822, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 845, -1, -1, -1, -1, -1, -1, -1, 853, -1, - -1, -1, -1, -1, -1, -1, -1, 862, -1, -1, - -1, -1, 867, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 879, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 890, -1, -1, -1, -1, - -1, -1, 897, -1, 899, 900, 901, 902, -1, -1, - -1, -1, 907, 908, -1, 910, -1, 912, -1, -1, - 915, -1, 917, 918, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 754, -1, 756, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 769, -1, + 771, -1, -1, -1, -1, -1, -1, 778, -1, 780, + -1, 782, -1, 784, -1, -1, 654, 655, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 671, -1, 673, -1, 675, -1, 677, + -1, -1, -1, -1, -1, -1, -1, -1, 819, -1, + -1, -1, -1, -1, -1, -1, 827, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 845, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 985, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1000, -1, 1002, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1018, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1036, -1, -1, -1, -1, 1041, -1, -1, -1, - 1045, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 891, -1, -1, -1, -1, 896, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 908, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 919, -1, + -1, -1, -1, -1, -1, 926, -1, -1, 929, 930, + 931, 932, -1, -1, -1, -1, 937, -1, -1, 940, + -1, 942, -1, 944, -1, -1, -1, -1, -1, 950, + -1, 952, 953, 954, -1, -1, -1, -1, -1, -1, + 961, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 840, 841, 842, 843, -1, -1, -1, 847, + 848, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 858, -1, -1, 861, 862, -1, -1, -1, -1, -1, + -1, 869, 870, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 882, -1, -1, -1, -1, -1, + -1, -1, -1, 1024, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1039, -1, + 1041, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1057, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1076, -1, -1, -1, -1, + 1081, -1, -1, -1, 1085, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1095, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1105, -1, 1107, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 997, + -1, -1, 1000, -1, 1135, -1, -1, 1005, -1, -1, + 1008, -1, -1, -1, 1145, -1, 1147, -1, 1016, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1145, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1158, -1, -1, -1, -1, -1, -1, - -1, 1166, -1, 1168, 1169, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1185, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1198, -1, -1, + -1, -1, -1, -1, -1, 1206, -1, 1208, 1209, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1094, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1212, -1, -1, - -1, -1, -1, -1, -1, 1220, -1, -1, -1, -1, + -1, 1252, -1, -1, -1, -1, -1, -1, -1, 1260, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1236, -1, -1, -1, -1, -1, -1, -1, 1244, - -1, -1, -1, -1, -1, -1, -1, 1252, -1, -1, + -1, -1, -1, -1, -1, 1276, -1, -1, -1, -1, + -1, -1, -1, 1284, -1, -1, -1, -1, -1, -1, + -1, 1292, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1174, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1189, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1339, 1340, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1299, 1300, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1380, + -1, -1, 1383, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1268, -1, -1, -1, -1, 1406, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1296, -1, + -1, -1, 1300, 1301, -1, 1303, -1, 1305, -1, -1, + -1, 1309, 1310, -1, 1312, -1, 1314, -1, 1316, 1317, + -1, 1319, 1320, 1321, -1, 1323, -1, 1325, -1, 1327, + 1328, -1, 1330, -1, 1332, 1333, -1, 1335, -1, 1337, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1340, -1, -1, 1343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1366 + -1, -1, -1, -1, -1, -1, -1, -1, 1376, 1377, + -1, 1379, -1, 1381, 1382, -1, 1384, 1385, 1386, 1387, + 1388, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1405, -1, 1407 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1956,215 +1990,220 @@ static const yytype_uint16 yystos[] = { 0, 4, 5, 10, 15, 17, 18, 24, 27, 34, 35, 37, 39, 44, 46, 49, 52, 60, 63, 65, - 66, 67, 68, 76, 77, 78, 79, 80, 82, 83, - 84, 85, 86, 87, 89, 90, 91, 164, 165, 166, - 237, 239, 303, 304, 307, 309, 330, 331, 332, 333, - 334, 335, 338, 339, 341, 343, 351, 352, 358, 359, - 370, 372, 383, 384, 385, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 404, 405, 407, - 428, 429, 430, 432, 434, 435, 441, 442, 447, 452, - 455, 458, 461, 462, 465, 470, 472, 475, 477, 487, - 489, 490, 493, 495, 496, 0, 158, 159, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 146, 204, 240, 204, 310, 204, 337, 337, 204, - 344, 204, 353, 337, 204, 373, 337, 353, 337, 353, - 337, 353, 337, 353, 204, 443, 204, 466, 332, 333, - 334, 335, 358, 384, 385, 395, 399, 403, 428, 441, - 447, 452, 455, 458, 461, 471, 473, 474, 204, 478, - 478, 478, 40, 479, 480, 162, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 354, 203, 354, 203, - 354, 203, 203, 406, 203, 203, 160, 161, 202, 203, - 203, 203, 203, 203, 201, 147, 148, 150, 151, 152, - 153, 154, 167, 168, 169, 171, 173, 174, 177, 179, - 180, 204, 241, 61, 311, 313, 19, 28, 56, 304, - 309, 320, 321, 340, 351, 366, 367, 431, 433, 436, - 438, 439, 440, 320, 340, 431, 433, 171, 345, 341, - 360, 361, 363, 364, 365, 366, 367, 3, 25, 374, - 375, 70, 307, 309, 320, 386, 393, 448, 449, 450, - 451, 23, 237, 355, 356, 202, 71, 397, 453, 454, - 202, 72, 401, 456, 457, 202, 73, 405, 459, 460, - 50, 51, 237, 408, 409, 411, 412, 202, 64, 444, - 445, 462, 463, 495, 74, 75, 467, 468, 479, 479, - 479, 41, 481, 482, 166, 179, 149, 167, 178, 171, - 203, 238, 203, 305, 308, 201, 201, 203, 201, 203, - 201, 201, 203, 203, 203, 203, 203, 203, 203, 354, - 203, 201, 201, 203, 371, 201, 201, 203, 203, 203, - 201, 203, 258, 203, 201, 203, 203, 201, 203, 203, - 201, 203, 203, 201, 258, 258, 201, 203, 258, 201, - 203, 201, 203, 201, 203, 203, 203, 203, 201, 202, - 172, 175, 176, 180, 179, 32, 33, 168, 204, 242, - 243, 244, 246, 247, 202, 62, 311, 316, 317, 341, - 202, 202, 204, 314, 310, 351, 57, 322, 323, 6, - 16, 81, 267, 268, 270, 271, 273, 336, 347, 348, - 204, 368, 368, 48, 414, 416, 414, 351, 336, 414, - 414, 171, 346, 202, 370, 368, 368, 9, 237, 377, - 379, 202, 204, 376, 310, 393, 273, 387, 414, 368, - 237, 237, 204, 357, 267, 414, 368, 267, 414, 368, - 267, 414, 368, 179, 183, 185, 204, 410, 408, 204, - 413, 414, 368, 463, 179, 469, 481, 25, 418, 419, - 481, 47, 497, 500, 166, 179, 203, 203, 201, 201, - 305, 308, 203, 306, 201, 203, 203, 312, 203, 203, - 203, 325, 201, 201, 202, 203, 201, 203, 203, 203, - 201, 203, 203, 202, 203, 203, 203, 342, 203, 203, - 203, 258, 371, 201, 258, 203, 203, 201, 202, 203, - 203, 258, 258, 202, 202, 203, 203, 202, 203, 203, - 202, 203, 203, 154, 156, 182, 184, 188, 191, 202, - 258, 202, 203, 203, 203, 464, 167, 202, 203, 203, - 488, 201, 203, 203, 206, 201, 202, 243, 246, 204, - 245, 204, 248, 237, 319, 168, 318, 316, 237, 315, - 202, 311, 336, 58, 59, 326, 328, 202, 179, 324, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 274, 275, 276, 267, 204, 349, - 320, 340, 320, 340, 267, 204, 417, 267, 336, 267, - 267, 7, 11, 237, 259, 263, 202, 267, 320, 340, - 320, 340, 204, 380, 202, 311, 387, 274, 267, 320, - 393, 267, 397, 267, 401, 267, 405, 179, 186, 179, - 192, 267, 436, 438, 439, 440, 446, 26, 29, 30, - 31, 53, 54, 55, 207, 209, 210, 211, 212, 213, - 214, 215, 218, 219, 220, 222, 223, 228, 230, 233, - 234, 237, 249, 250, 463, 202, 179, 418, 38, 43, - 207, 379, 421, 425, 426, 485, 486, 202, 204, 420, - 45, 494, 207, 202, 478, 203, 202, 202, 306, 202, - 306, 312, 203, 202, 201, 167, 202, 203, 203, 203, - 203, 203, 203, 437, 203, 437, 202, 203, 202, 202, - 202, 202, 258, 258, 201, 202, 203, 203, 362, 203, - 362, 203, 203, 202, 203, 202, 203, 202, 202, 202, - 202, 202, 202, 202, 184, 182, 155, 157, 180, 181, - 189, 192, 197, 198, 199, 202, 203, 203, 201, 203, - 208, 201, 203, 208, 201, 203, 208, 201, 203, 208, - 201, 203, 208, 201, 208, 201, 464, 203, 476, 201, - 488, 488, 201, 206, 201, 203, 327, 201, 203, 246, - 311, 204, 329, 179, 150, 151, 152, 277, 277, 277, - 170, 172, 350, 351, 347, 202, 351, 202, 418, 204, - 265, 351, 7, 12, 257, 262, 347, 369, 202, 351, - 202, 170, 381, 311, 277, 393, 179, 187, 192, 179, - 193, 181, 200, 370, 211, 237, 249, 214, 218, 237, - 249, 204, 216, 222, 228, 233, 204, 221, 228, 233, - 168, 224, 233, 168, 231, 183, 204, 235, 146, 205, - 42, 207, 421, 425, 483, 484, 485, 202, 380, 380, - 318, 237, 202, 370, 414, 475, 489, 491, 418, 327, - 258, 258, 258, 203, 258, 171, 202, 437, 437, 203, - 415, 203, 362, 201, 203, 362, 203, 378, 258, 202, - 184, 200, 181, 190, 197, 193, 202, 208, 203, 208, - 202, 203, 208, 203, 208, 208, 202, 203, 208, 208, - 203, 208, 203, 203, 202, 476, 476, 203, 206, 201, - 206, 203, 203, 202, 202, 203, 202, 202, 202, 202, - 257, 202, 202, 237, 421, 425, 202, 171, 266, 202, - 265, 369, 202, 7, 11, 12, 13, 255, 256, 382, - 202, 202, 179, 194, 195, 217, 219, 222, 228, 233, - 228, 233, 233, 233, 168, 225, 168, 232, 183, 204, - 236, 485, 166, 381, 204, 427, 203, 379, 425, 498, - 501, 203, 203, 203, 258, 258, 415, 415, 258, 203, - 201, 258, 203, 167, 197, 202, 203, 203, 203, 203, - 208, 208, 208, 208, 203, 203, 229, 202, 206, 202, - 203, 327, 494, 201, 203, 499, 8, 278, 281, 279, - 281, 280, 281, 202, 266, 265, 278, 179, 196, 197, - 222, 228, 233, 228, 233, 233, 233, 168, 226, 259, - 202, 7, 11, 12, 13, 14, 69, 422, 423, 424, - 202, 201, 380, 207, 425, 501, 202, 203, 269, 201, - 206, 201, 203, 272, 201, 258, 203, 203, 388, 197, - 203, 203, 203, 208, 203, 327, 201, 491, 203, 499, - 499, 7, 11, 12, 13, 14, 69, 88, 207, 251, - 252, 253, 254, 260, 264, 278, 302, 204, 282, 282, - 207, 280, 282, 202, 266, 36, 207, 302, 389, 390, - 228, 233, 233, 233, 168, 227, 202, 265, 202, 381, - 201, 201, 269, 206, 203, 203, 272, 203, 258, 203, - 206, 206, 201, 203, 202, 203, 261, 203, 492, 258, - 265, 265, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 283, 286, 295, 295, 106, 114, 139, 140, - 288, 291, 295, 202, 389, 204, 391, 233, 266, 202, - 207, 485, 494, 202, 202, 203, 261, 203, 203, 203, - 203, 202, 203, 203, 293, 203, 203, 203, 203, 202, - 203, 206, 327, 258, 206, 201, 266, 202, 20, 22, - 237, 252, 284, 296, 297, 300, 301, 284, 21, 237, - 252, 285, 298, 299, 300, 285, 237, 252, 287, 300, - 237, 260, 294, 300, 202, 237, 289, 296, 300, 284, - 237, 290, 298, 300, 290, 237, 292, 300, 202, 491, - 258, 258, 258, 203, 258, 201, 203, 258, 201, 258, - 258, 203, 258, 201, 203, 258, 258, 258, 203, 258, - 258, 258, 203, 258, 258, 203, 258, 258, 258, 203, - 258, 258, 258, 258, 202, 202, 252, 300, 168, 252, - 179, 252, 300, 168, 252, 252, 260, 300, 300, 492, - 258, 203, 258, 203, 258, 202, 258, 203, 258, 202, - 258, 258, 258, 258, 258, 252, 257, 252, 258, 202, - 258 + 66, 67, 68, 76, 77, 79, 80, 81, 83, 84, + 85, 86, 87, 88, 90, 91, 92, 165, 166, 167, + 238, 240, 304, 305, 308, 310, 331, 332, 333, 334, + 335, 336, 339, 340, 342, 344, 352, 353, 359, 360, + 371, 373, 384, 385, 386, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 408, + 429, 430, 431, 433, 435, 436, 442, 443, 448, 453, + 456, 459, 462, 463, 466, 471, 473, 476, 480, 493, + 497, 498, 503, 505, 506, 0, 159, 160, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 147, 205, 241, 205, 311, 205, 338, 338, 205, + 345, 205, 354, 338, 205, 374, 338, 354, 338, 354, + 338, 354, 338, 354, 205, 444, 205, 467, 333, 334, + 335, 336, 359, 385, 386, 396, 400, 404, 429, 442, + 448, 453, 456, 459, 462, 472, 474, 475, 205, 481, + 481, 481, 40, 485, 486, 163, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 355, 204, 355, 204, + 355, 204, 204, 407, 204, 204, 161, 162, 203, 204, + 204, 477, 478, 204, 494, 495, 204, 499, 500, 204, + 202, 148, 149, 151, 152, 153, 154, 155, 168, 169, + 170, 172, 174, 175, 178, 180, 181, 205, 242, 61, + 312, 314, 19, 28, 56, 305, 310, 321, 322, 341, + 352, 367, 368, 432, 434, 437, 439, 440, 441, 321, + 341, 432, 434, 172, 346, 342, 361, 362, 364, 365, + 366, 367, 368, 3, 25, 375, 376, 70, 308, 310, + 321, 387, 394, 449, 450, 451, 452, 23, 238, 356, + 357, 203, 71, 398, 454, 455, 203, 72, 402, 457, + 458, 203, 73, 406, 460, 461, 50, 51, 238, 409, + 410, 412, 413, 203, 64, 445, 446, 463, 464, 505, + 74, 75, 468, 469, 78, 482, 483, 485, 482, 485, + 482, 485, 41, 487, 488, 167, 180, 150, 168, 179, + 172, 204, 239, 204, 306, 309, 202, 202, 204, 202, + 204, 202, 202, 204, 204, 204, 204, 204, 204, 204, + 355, 204, 202, 202, 204, 372, 202, 202, 204, 204, + 204, 202, 204, 259, 204, 202, 204, 204, 202, 204, + 204, 202, 204, 204, 202, 259, 259, 202, 204, 259, + 202, 204, 202, 204, 202, 204, 478, 202, 204, 204, + 495, 204, 204, 500, 204, 204, 202, 203, 173, 176, + 177, 181, 180, 32, 33, 169, 205, 243, 244, 245, + 247, 248, 203, 62, 312, 317, 318, 342, 203, 203, + 205, 315, 311, 352, 57, 323, 324, 6, 16, 82, + 268, 269, 271, 272, 274, 337, 348, 349, 205, 369, + 369, 48, 415, 417, 415, 352, 337, 415, 415, 172, + 347, 203, 371, 369, 369, 9, 238, 378, 380, 203, + 205, 377, 311, 394, 274, 388, 415, 369, 238, 238, + 205, 358, 268, 415, 369, 268, 415, 369, 268, 415, + 369, 180, 184, 186, 205, 411, 409, 205, 414, 415, + 369, 464, 180, 470, 205, 484, 487, 25, 419, 420, + 487, 47, 507, 512, 167, 180, 204, 204, 202, 202, + 306, 309, 204, 307, 202, 204, 204, 313, 204, 204, + 204, 326, 202, 202, 203, 204, 202, 204, 204, 204, + 202, 204, 204, 203, 204, 204, 204, 343, 204, 204, + 204, 259, 372, 202, 259, 204, 204, 202, 203, 204, + 204, 259, 259, 203, 203, 204, 204, 203, 204, 204, + 203, 204, 204, 155, 157, 183, 185, 189, 192, 203, + 259, 203, 204, 204, 204, 465, 168, 203, 203, 204, + 204, 496, 202, 204, 204, 207, 202, 203, 244, 247, + 205, 246, 205, 249, 238, 320, 169, 319, 317, 238, + 316, 203, 312, 337, 58, 59, 327, 329, 203, 180, + 325, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 275, 276, 277, 268, 205, + 350, 321, 341, 321, 341, 268, 205, 418, 268, 337, + 268, 268, 7, 11, 238, 260, 264, 203, 268, 321, + 341, 321, 341, 205, 381, 203, 312, 388, 275, 268, + 321, 394, 268, 398, 268, 402, 268, 406, 180, 187, + 180, 193, 268, 437, 439, 440, 441, 447, 26, 29, + 30, 31, 53, 54, 55, 208, 210, 211, 212, 213, + 214, 215, 216, 219, 220, 221, 223, 224, 229, 231, + 234, 235, 238, 250, 251, 464, 203, 180, 419, 38, + 43, 208, 380, 422, 426, 427, 491, 492, 203, 205, + 421, 45, 504, 208, 203, 481, 204, 203, 203, 307, + 203, 307, 313, 204, 203, 202, 168, 203, 204, 204, + 204, 204, 204, 204, 438, 204, 438, 203, 204, 203, + 203, 203, 203, 259, 259, 202, 203, 204, 204, 363, + 204, 363, 204, 204, 203, 204, 203, 204, 259, 203, + 259, 203, 259, 203, 259, 185, 183, 156, 158, 181, + 182, 190, 193, 198, 199, 200, 203, 204, 204, 202, + 204, 209, 202, 204, 209, 202, 204, 209, 202, 204, + 209, 202, 204, 209, 202, 209, 202, 465, 204, 479, + 202, 496, 496, 202, 207, 202, 204, 328, 202, 204, + 508, 509, 247, 312, 205, 330, 180, 151, 152, 153, + 278, 278, 278, 171, 173, 351, 352, 238, 348, 203, + 352, 203, 419, 205, 266, 352, 7, 12, 238, 258, + 263, 348, 370, 203, 352, 203, 171, 382, 312, 278, + 394, 203, 203, 203, 203, 180, 188, 193, 180, 194, + 182, 201, 371, 212, 238, 250, 215, 219, 238, 250, + 205, 217, 223, 229, 234, 205, 222, 229, 234, 169, + 225, 234, 169, 232, 184, 205, 236, 147, 206, 42, + 208, 422, 426, 489, 490, 491, 203, 381, 381, 319, + 238, 203, 371, 415, 476, 497, 501, 419, 482, 328, + 259, 259, 259, 204, 259, 172, 203, 438, 259, 259, + 438, 204, 416, 204, 363, 259, 202, 204, 259, 259, + 363, 204, 379, 259, 259, 185, 201, 182, 191, 198, + 194, 259, 209, 204, 209, 203, 204, 209, 204, 209, + 209, 203, 204, 209, 209, 204, 209, 204, 204, 203, + 479, 479, 204, 207, 202, 207, 204, 204, 203, 203, + 204, 204, 509, 203, 203, 203, 203, 258, 203, 203, + 238, 422, 426, 203, 172, 267, 203, 266, 370, 203, + 7, 11, 12, 13, 256, 257, 383, 203, 203, 203, + 180, 195, 196, 203, 218, 220, 223, 229, 234, 229, + 234, 234, 234, 169, 226, 169, 233, 184, 205, 237, + 491, 167, 382, 205, 428, 204, 380, 426, 510, 513, + 204, 204, 204, 259, 259, 416, 416, 259, 204, 259, + 202, 259, 204, 168, 198, 203, 204, 204, 204, 204, + 209, 209, 209, 209, 204, 204, 230, 203, 207, 203, + 204, 328, 504, 202, 204, 511, 8, 279, 282, 280, + 282, 281, 282, 203, 267, 266, 279, 180, 197, 198, + 223, 229, 234, 229, 234, 234, 234, 169, 227, 260, + 203, 7, 11, 12, 13, 14, 69, 423, 424, 425, + 203, 202, 381, 208, 426, 513, 203, 204, 270, 202, + 207, 202, 204, 273, 202, 259, 204, 204, 389, 198, + 204, 204, 204, 209, 204, 328, 202, 501, 204, 511, + 511, 7, 11, 12, 13, 14, 69, 89, 208, 252, + 253, 254, 255, 261, 265, 279, 303, 205, 283, 283, + 208, 281, 283, 203, 267, 36, 208, 303, 390, 391, + 229, 234, 234, 234, 169, 228, 203, 266, 203, 382, + 202, 202, 270, 207, 204, 204, 273, 204, 259, 204, + 207, 207, 202, 204, 203, 204, 262, 204, 502, 259, + 266, 266, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 284, 287, 296, 296, 107, 115, 140, 141, + 289, 292, 296, 203, 390, 205, 392, 234, 267, 203, + 208, 491, 504, 203, 203, 204, 262, 204, 204, 204, + 204, 203, 204, 204, 294, 204, 204, 204, 204, 203, + 204, 207, 328, 259, 207, 202, 267, 203, 20, 22, + 238, 253, 285, 297, 298, 301, 302, 285, 21, 238, + 253, 286, 299, 300, 301, 286, 238, 253, 288, 301, + 238, 261, 295, 301, 203, 238, 290, 297, 301, 285, + 238, 291, 299, 301, 291, 238, 293, 301, 203, 501, + 259, 259, 259, 204, 259, 202, 204, 259, 202, 259, + 259, 204, 259, 202, 204, 259, 259, 259, 204, 259, + 259, 259, 204, 259, 259, 204, 259, 259, 259, 204, + 259, 259, 259, 259, 203, 203, 253, 301, 169, 253, + 180, 253, 301, 169, 253, 253, 261, 301, 301, 502, + 259, 204, 259, 204, 259, 203, 259, 204, 259, 203, + 259, 259, 259, 259, 259, 253, 258, 253, 259, 203, + 259 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 163, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 165, 165, 165, 165, 165, 165, 166, 166, - 167, 168, 168, 169, 170, 171, 171, 172, 172, 173, - 174, 175, 176, 177, 177, 178, 178, 179, 179, 179, - 179, 180, 180, 181, 182, 183, 183, 183, 184, 184, - 185, 186, 187, 188, 189, 189, 190, 190, 191, 192, - 193, 194, 194, 194, 195, 196, 197, 197, 198, 199, - 199, 200, 200, 201, 201, 202, 202, 203, 204, 205, - 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, - 210, 210, 210, 211, 211, 211, 211, 212, 213, 214, - 215, 216, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 218, 218, 218, - 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, - 218, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 229, 230, 231, 232, 233, 234, 235, - 235, 236, 236, 237, 238, 238, 238, 238, 238, 238, - 238, 239, 240, 241, 241, 242, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 251, 252, 253, 254, - 254, 254, 254, 254, 255, 256, 256, 256, 256, 257, - 258, 258, 259, 260, 261, 261, 262, 262, 263, 263, - 264, 264, 265, 266, 267, 267, 267, 268, 269, 269, - 269, 269, 270, 271, 272, 272, 272, 273, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, - 276, 276, 277, 277, 277, 278, 279, 280, 281, 282, - 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, - 284, 284, 284, 284, 284, 284, 284, 285, 285, 285, - 285, 285, 285, 285, 285, 286, 286, 287, 287, 287, - 287, 288, 288, 288, 288, 288, 288, 288, 288, 288, - 289, 289, 289, 289, 290, 290, 290, 290, 291, 291, - 292, 292, 293, 293, 294, 294, 294, 294, 295, 295, - 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, - 295, 295, 295, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 303, 304, 305, 305, 306, 306, 307, 308, - 308, 309, 310, 311, 312, 312, 313, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 324, 324, - 325, 325, 326, 327, 327, 328, 328, 329, 330, 330, - 330, 331, 331, 332, 333, 334, 335, 336, 336, 337, - 338, 338, 339, 339, 340, 340, 341, 342, 342, 342, - 343, 343, 344, 345, 346, 347, 348, 348, 349, 350, - 350, 351, 352, 352, 352, 353, 354, 354, 354, 354, - 355, 356, 357, 358, 359, 359, 360, 360, 360, 360, - 361, 362, 362, 362, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 371, 371, 372, 373, 374, 375, - 375, 376, 377, 378, 378, 379, 380, 381, 382, 383, - 383, 384, 385, 386, 386, 387, 388, 388, 388, 388, - 388, 389, 390, 391, 392, 392, 393, 394, 394, 394, - 395, 396, 396, 397, 398, 398, 399, 400, 401, 402, - 402, 403, 404, 405, 406, 406, 406, 406, 406, 407, - 407, 408, 409, 410, 410, 411, 412, 413, 414, 415, - 415, 415, 415, 416, 417, 418, 419, 420, 421, 422, - 423, 424, 424, 424, 424, 424, 424, 425, 426, 427, - 428, 428, 428, 429, 429, 430, 431, 431, 432, 433, - 433, 434, 435, 436, 437, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 446, 446, 446, 447, 448, - 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, - 458, 459, 460, 461, 462, 462, 462, 462, 462, 462, - 462, 462, 462, 462, 462, 462, 463, 463, 464, 464, - 464, 465, 466, 467, 468, 468, 469, 469, 469, 470, - 471, 471, 472, 473, 473, 473, 473, 473, 473, 473, - 473, 473, 473, 473, 473, 473, 473, 474, 474, 474, - 474, 474, 474, 474, 475, 476, 476, 476, 476, 476, - 476, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 488, 488, 488, 488, 489, 490, - 491, 491, 491, 491, 492, 492, 492, 492, 493, 494, - 495, 496, 497, 498, 498, 499, 499, 499, 499, 500, - 501 + 0, 164, 165, 165, 165, 165, 165, 165, 165, 165, + 165, 165, 166, 166, 166, 166, 166, 166, 167, 167, + 168, 169, 169, 170, 171, 172, 172, 173, 173, 174, + 175, 176, 177, 178, 178, 179, 179, 180, 180, 180, + 180, 181, 181, 182, 183, 184, 184, 184, 185, 185, + 186, 187, 188, 189, 190, 190, 191, 191, 192, 193, + 194, 195, 195, 195, 196, 197, 198, 198, 199, 200, + 200, 201, 201, 202, 202, 203, 203, 204, 205, 206, + 207, 207, 208, 208, 208, 209, 209, 209, 210, 210, + 211, 211, 211, 212, 212, 212, 212, 213, 214, 215, + 216, 217, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 230, 231, 232, 233, 234, 235, 236, + 236, 237, 237, 238, 239, 239, 239, 239, 239, 239, + 239, 240, 241, 242, 242, 243, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 252, 253, 254, 255, + 255, 255, 255, 255, 256, 257, 257, 257, 257, 258, + 259, 259, 260, 261, 262, 262, 263, 263, 264, 264, + 265, 265, 266, 267, 268, 268, 268, 269, 270, 270, + 270, 270, 271, 272, 273, 273, 273, 274, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, + 277, 277, 278, 278, 278, 279, 280, 281, 282, 283, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 285, + 285, 285, 285, 285, 285, 285, 285, 286, 286, 286, + 286, 286, 286, 286, 286, 287, 287, 288, 288, 288, + 288, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 290, 290, 290, 290, 291, 291, 291, 291, 292, 292, + 293, 293, 294, 294, 295, 295, 295, 295, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 304, 305, 306, 306, 307, 307, 308, 309, + 309, 310, 311, 312, 313, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 325, 325, + 326, 326, 327, 328, 328, 329, 329, 330, 331, 331, + 331, 332, 332, 333, 334, 335, 336, 337, 337, 338, + 339, 339, 340, 340, 341, 341, 342, 343, 343, 343, + 344, 344, 345, 346, 347, 348, 349, 349, 350, 351, + 351, 352, 353, 353, 353, 354, 355, 355, 355, 355, + 356, 357, 358, 359, 360, 360, 361, 361, 361, 361, + 362, 363, 363, 363, 363, 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 372, 372, 373, 374, 375, + 376, 376, 377, 378, 379, 379, 380, 381, 382, 383, + 384, 384, 385, 386, 387, 387, 388, 389, 389, 389, + 389, 389, 390, 391, 392, 393, 393, 394, 395, 395, + 395, 396, 397, 397, 398, 399, 399, 400, 401, 402, + 403, 403, 404, 405, 406, 407, 407, 407, 407, 407, + 408, 408, 409, 410, 411, 411, 412, 413, 414, 415, + 416, 416, 416, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 425, 425, 425, 425, 425, 426, 427, + 428, 429, 429, 429, 430, 430, 431, 432, 432, 433, + 434, 434, 435, 436, 437, 438, 438, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 447, 447, 447, + 448, 449, 449, 450, 451, 452, 453, 454, 455, 456, + 457, 458, 459, 460, 461, 462, 463, 463, 463, 463, + 463, 463, 463, 463, 463, 463, 463, 463, 464, 464, + 465, 465, 465, 466, 467, 468, 469, 469, 470, 470, + 470, 471, 472, 472, 473, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 475, + 475, 475, 475, 475, 475, 475, 476, 477, 477, 478, + 479, 479, 479, 479, 479, 479, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 494, 495, 496, 496, 496, 496, 496, 497, + 498, 499, 499, 500, 501, 501, 501, 501, 502, 502, + 502, 502, 503, 504, 505, 506, 507, 508, 508, 509, + 510, 510, 511, 511, 511, 511, 512, 513 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -2213,31 +2252,32 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 6, 1, 1, 1, 4, 2, 7, 1, 1, 1, 1, 0, 2, 3, 5, 4, 1, 1, 10, 1, 1, 1, 1, 1, 1, - 7, 0, 2, 4, 2, 9, 7, 9, 1, 1, - 1, 1, 7, 0, 3, 3, 1, 1, 5, 1, - 1, 1, 7, 0, 3, 1, 1, 1, 1, 1, - 1, 8, 10, 1, 1, 10, 0, 3, 5, 3, - 2, 5, 1, 1, 1, 1, 5, 1, 1, 1, - 8, 1, 1, 5, 1, 1, 8, 1, 5, 1, - 1, 8, 1, 5, 0, 3, 5, 3, 3, 1, - 1, 4, 1, 1, 1, 4, 1, 1, 7, 0, - 3, 3, 3, 1, 1, 5, 1, 1, 9, 1, - 5, 1, 1, 1, 1, 1, 1, 7, 1, 1, - 1, 1, 1, 1, 1, 10, 1, 1, 10, 1, - 1, 10, 10, 7, 0, 2, 9, 7, 9, 10, - 1, 1, 8, 1, 1, 1, 1, 1, 10, 1, - 1, 6, 8, 1, 10, 6, 1, 10, 6, 1, - 10, 6, 1, 9, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, - 2, 1, 1, 4, 1, 1, 1, 2, 3, 4, - 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 0, 3, 5, 3, 3, 9, 7, 9, 1, + 1, 1, 1, 7, 0, 3, 3, 1, 1, 5, + 1, 1, 1, 7, 0, 3, 1, 1, 1, 1, + 1, 1, 8, 10, 1, 1, 10, 0, 3, 5, + 3, 2, 5, 1, 1, 1, 1, 5, 1, 1, + 1, 8, 1, 1, 5, 1, 1, 8, 1, 5, + 1, 1, 8, 1, 5, 0, 3, 5, 3, 3, + 1, 1, 4, 1, 1, 1, 4, 1, 1, 7, + 0, 3, 3, 3, 1, 1, 5, 1, 1, 9, + 1, 5, 1, 1, 1, 1, 1, 1, 7, 1, + 1, 1, 1, 1, 1, 1, 10, 1, 1, 10, + 1, 1, 10, 10, 7, 0, 3, 3, 9, 7, + 9, 10, 1, 1, 9, 1, 1, 1, 1, 1, + 10, 1, 1, 7, 9, 1, 10, 7, 1, 10, + 7, 1, 10, 7, 1, 9, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 3, 2, 1, 1, 4, 1, 1, 1, 2, + 3, 4, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 11, 0, 3, 3, 3, 5, - 3, 2, 1, 1, 4, 1, 4, 1, 4, 1, - 4, 1, 9, 0, 3, 3, 3, 2, 1, 19, - 1, 1, 1, 1, 0, 6, 3, 2, 1, 1, - 9, 1, 9, 1, 1, 0, 3, 3, 2, 1, - 7 + 1, 1, 1, 1, 1, 1, 4, 3, 1, 8, + 0, 3, 3, 3, 5, 3, 2, 1, 1, 4, + 1, 1, 4, 1, 4, 1, 4, 1, 4, 1, + 4, 3, 1, 6, 0, 3, 3, 3, 2, 1, + 4, 3, 1, 16, 1, 1, 1, 1, 0, 6, + 3, 2, 1, 1, 9, 1, 4, 3, 1, 6, + 1, 1, 0, 3, 3, 2, 1, 7 }; diff --git a/src/wkt2_generated_parser.h b/src/wkt2_generated_parser.h index baeb0b4f..80b0c34b 100644 --- a/src/wkt2_generated_parser.h +++ b/src/wkt2_generated_parser.h @@ -121,76 +121,77 @@ extern int pj_wkt2_debug; T_COORDEPOCH = 330, T_COORDINATEMETADATA = 331, T_POINTMOTIONOPERATION = 332, - T_GEODETICCRS = 333, - T_GEODETICDATUM = 334, - T_PROJECTEDCRS = 335, - T_PRIMEMERIDIAN = 336, - T_GEOGRAPHICCRS = 337, - T_TRF = 338, - T_VERTICALCRS = 339, - T_VERTICALDATUM = 340, - T_VRF = 341, - T_TIMEDATUM = 342, - T_TEMPORALQUANTITY = 343, - T_ENGINEERINGDATUM = 344, - T_ENGINEERINGCRS = 345, - T_PARAMETRICDATUM = 346, - T_AFFINE = 347, - T_CARTESIAN = 348, - T_CYLINDRICAL = 349, - T_ELLIPSOIDAL = 350, - T_LINEAR = 351, - T_PARAMETRIC = 352, - T_POLAR = 353, - T_SPHERICAL = 354, - T_VERTICAL = 355, - T_TEMPORAL = 356, - T_TEMPORALCOUNT = 357, - T_TEMPORALMEASURE = 358, - T_ORDINAL = 359, - T_TEMPORALDATETIME = 360, - T_NORTH = 361, - T_NORTHNORTHEAST = 362, - T_NORTHEAST = 363, - T_EASTNORTHEAST = 364, - T_EAST = 365, - T_EASTSOUTHEAST = 366, - T_SOUTHEAST = 367, - T_SOUTHSOUTHEAST = 368, - T_SOUTH = 369, - T_SOUTHSOUTHWEST = 370, - T_SOUTHWEST = 371, - T_WESTSOUTHWEST = 372, - T_WEST = 373, - T_WESTNORTHWEST = 374, - T_NORTHWEST = 375, - T_NORTHNORTHWEST = 376, - T_UP = 377, - T_DOWN = 378, - T_GEOCENTRICX = 379, - T_GEOCENTRICY = 380, - T_GEOCENTRICZ = 381, - T_COLUMNPOSITIVE = 382, - T_COLUMNNEGATIVE = 383, - T_ROWPOSITIVE = 384, - T_ROWNEGATIVE = 385, - T_DISPLAYRIGHT = 386, - T_DISPLAYLEFT = 387, - T_DISPLAYUP = 388, - T_DISPLAYDOWN = 389, - T_FORWARD = 390, - T_AFT = 391, - T_PORT = 392, - T_STARBOARD = 393, - T_CLOCKWISE = 394, - T_COUNTERCLOCKWISE = 395, - T_TOWARDS = 396, - T_AWAYFROM = 397, - T_FUTURE = 398, - T_PAST = 399, - T_UNSPECIFIED = 400, - T_STRING = 401, - T_UNSIGNED_INTEGER_DIFFERENT_ONE_TWO_THREE = 402 + T_VERSION = 333, + T_GEODETICCRS = 334, + T_GEODETICDATUM = 335, + T_PROJECTEDCRS = 336, + T_PRIMEMERIDIAN = 337, + T_GEOGRAPHICCRS = 338, + T_TRF = 339, + T_VERTICALCRS = 340, + T_VERTICALDATUM = 341, + T_VRF = 342, + T_TIMEDATUM = 343, + T_TEMPORALQUANTITY = 344, + T_ENGINEERINGDATUM = 345, + T_ENGINEERINGCRS = 346, + T_PARAMETRICDATUM = 347, + T_AFFINE = 348, + T_CARTESIAN = 349, + T_CYLINDRICAL = 350, + T_ELLIPSOIDAL = 351, + T_LINEAR = 352, + T_PARAMETRIC = 353, + T_POLAR = 354, + T_SPHERICAL = 355, + T_VERTICAL = 356, + T_TEMPORAL = 357, + T_TEMPORALCOUNT = 358, + T_TEMPORALMEASURE = 359, + T_ORDINAL = 360, + T_TEMPORALDATETIME = 361, + T_NORTH = 362, + T_NORTHNORTHEAST = 363, + T_NORTHEAST = 364, + T_EASTNORTHEAST = 365, + T_EAST = 366, + T_EASTSOUTHEAST = 367, + T_SOUTHEAST = 368, + T_SOUTHSOUTHEAST = 369, + T_SOUTH = 370, + T_SOUTHSOUTHWEST = 371, + T_SOUTHWEST = 372, + T_WESTSOUTHWEST = 373, + T_WEST = 374, + T_WESTNORTHWEST = 375, + T_NORTHWEST = 376, + T_NORTHNORTHWEST = 377, + T_UP = 378, + T_DOWN = 379, + T_GEOCENTRICX = 380, + T_GEOCENTRICY = 381, + T_GEOCENTRICZ = 382, + T_COLUMNPOSITIVE = 383, + T_COLUMNNEGATIVE = 384, + T_ROWPOSITIVE = 385, + T_ROWNEGATIVE = 386, + T_DISPLAYRIGHT = 387, + T_DISPLAYLEFT = 388, + T_DISPLAYUP = 389, + T_DISPLAYDOWN = 390, + T_FORWARD = 391, + T_AFT = 392, + T_PORT = 393, + T_STARBOARD = 394, + T_CLOCKWISE = 395, + T_COUNTERCLOCKWISE = 396, + T_TOWARDS = 397, + T_AWAYFROM = 398, + T_FUTURE = 399, + T_PAST = 400, + T_UNSPECIFIED = 401, + T_STRING = 402, + T_UNSIGNED_INTEGER_DIFFERENT_ONE_TWO_THREE = 403 }; #endif diff --git a/src/wkt2_grammar.y b/src/wkt2_grammar.y index dddb0b30..6773d1e1 100644 --- a/src/wkt2_grammar.y +++ b/src/wkt2_grammar.y @@ -115,6 +115,7 @@ %token T_COORDEPOCH "COORDEPOCH" %token T_COORDINATEMETADATA "COORDINATEMETADATA" %token T_POINTMOTIONOPERATION "POINTMOTIONOPERATION" +%token T_VERSION "VERSION" /* WKT2 alternate (longer or shorter) */ %token T_GEODETICCRS "GEODETICCRS"; @@ -993,29 +994,30 @@ base_geodetic_crs: base_static_geodetic_crs | base_dynamic_geodetic_crs | base_static_geodetic_crs: base_geodetic_crs_keyword left_delimiter base_crs_name wkt_separator geodetic_reference_frame_or_geodetic_datum_ensemble_without_pm - opt_separator_pm_ellipsoidal_cs_unit + opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list right_delimiter -opt_separator_pm_ellipsoidal_cs_unit: - | wkt_separator prime_meridian - | wkt_separator prime_meridian wkt_separator ellipsoidal_cs_unit - | wkt_separator ellipsoidal_cs_unit +opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list: + | wkt_separator prime_meridian opt_separator_identifier_list + | wkt_separator prime_meridian wkt_separator ellipsoidal_cs_unit opt_separator_identifier_list + | wkt_separator ellipsoidal_cs_unit opt_separator_identifier_list + | wkt_separator identifier opt_separator_identifier_list base_dynamic_geodetic_crs: base_geodetic_crs_keyword left_delimiter base_crs_name wkt_separator dynamic_crs wkt_separator geodetic_reference_frame_without_pm - opt_separator_pm_ellipsoidal_cs_unit + opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list right_delimiter base_static_geographic_crs: base_geographic_crs_keyword left_delimiter base_crs_name wkt_separator geodetic_reference_frame_or_geodetic_datum_ensemble_without_pm - opt_separator_pm_ellipsoidal_cs_unit + opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list right_delimiter base_dynamic_geographic_crs: base_geographic_crs_keyword left_delimiter base_crs_name wkt_separator dynamic_crs wkt_separator geodetic_reference_frame_without_pm - opt_separator_pm_ellipsoidal_cs_unit + opt_separator_pm_ellipsoidal_cs_unit_opt_separator_identifier_list right_delimiter base_geodetic_crs_keyword: T_BASEGEODCRS @@ -1281,27 +1283,28 @@ derived_dynamic_geog_crs: geographic_crs_keyword base_static_geod_crs: base_geodetic_crs_keyword left_delimiter base_crs_name wkt_separator geodetic_reference_frame_or_geodetic_datum_ensemble_without_pm - opt_separator_pm + opt_separator_pm_opt_separator_identifier_list right_delimiter -opt_separator_pm: - | wkt_separator prime_meridian +opt_separator_pm_opt_separator_identifier_list: + | wkt_separator prime_meridian opt_separator_identifier_list + | wkt_separator identifier opt_separator_identifier_list base_dynamic_geod_crs: base_geodetic_crs_keyword left_delimiter base_crs_name wkt_separator dynamic_crs wkt_separator geodetic_reference_frame_without_pm - opt_separator_pm + opt_separator_pm_opt_separator_identifier_list right_delimiter base_static_geog_crs: base_geographic_crs_keyword left_delimiter base_crs_name wkt_separator geodetic_reference_frame_or_geodetic_datum_ensemble_without_pm - opt_separator_pm + opt_separator_pm_opt_separator_identifier_list right_delimiter base_dynamic_geog_crs: base_geographic_crs_keyword left_delimiter base_crs_name wkt_separator dynamic_crs wkt_separator geodetic_reference_frame_without_pm - opt_separator_pm + opt_separator_pm_opt_separator_identifier_list right_delimiter // Derived projected CRS @@ -1319,6 +1322,7 @@ derived_crs_name: quoted_latin_text base_projected_crs: base_projected_crs_keyword left_delimiter base_crs_name wkt_separator base_geodetic_geographic_crs wkt_separator map_projection + opt_separator_identifier_list right_delimiter base_projected_crs_keyword: T_BASEPROJCRS @@ -1337,11 +1341,15 @@ derived_vertical_crs: vertical_crs_keyword left_delimiter crs_name base_vertical_crs: base_static_vertical_crs | base_dynamic_vertical_crs base_static_vertical_crs: base_vertical_crs_keyword left_delimiter base_crs_name - wkt_separator vertical_reference_frame right_delimiter + wkt_separator vertical_reference_frame + opt_separator_identifier_list + right_delimiter base_dynamic_vertical_crs: base_vertical_crs_keyword left_delimiter base_crs_name wkt_separator dynamic_crs - wkt_separator vertical_reference_frame right_delimiter + wkt_separator vertical_reference_frame + opt_separator_identifier_list + right_delimiter base_vertical_crs_keyword: T_BASEVERTCRS @@ -1355,7 +1363,9 @@ derived_engineering_crs: engineering_crs_keyword left_delimiter crs_name right_delimiter base_engineering_crs: base_engineering_crs_keyword left_delimiter base_crs_name - wkt_separator engineering_datum right_delimiter + wkt_separator engineering_datum + opt_separator_identifier_list + right_delimiter base_engineering_crs_keyword: T_BASEENGCRS @@ -1369,7 +1379,9 @@ derived_parametric_crs: parametric_crs_keyword left_delimiter crs_name right_delimiter base_parametric_crs: base_parametric_crs_keyword left_delimiter base_crs_name - wkt_separator parametric_datum right_delimiter + wkt_separator parametric_datum + opt_separator_identifier_list + right_delimiter base_parametric_crs_keyword: T_BASEPARAMCRS @@ -1383,7 +1395,9 @@ derived_temporal_crs: temporal_crs_keyword left_delimiter crs_name right_delimiter base_temporal_crs: base_temporal_crs_keyword left_delimiter base_crs_name - wkt_separator temporal_datum right_delimiter + wkt_separator temporal_datum + opt_separator_identifier_list + right_delimiter base_temporal_crs_keyword: T_BASETIMECRS @@ -1451,6 +1465,13 @@ dynamic_crs_coordinate_metadata: dynamic_geodetic_crs | dynamic_geographic_crs | // Coordinate operations coordinate_operation: operation_keyword left_delimiter operation_name + coordinate_operation_next + +coordinate_operation_next: + wkt_separator operation_version coordinate_operation_end + | coordinate_operation_end + +coordinate_operation_end: wkt_separator source_crs wkt_separator target_crs wkt_separator operation_method opt_parameter_or_parameter_file_list_opt_interpolation_crs_opt_operation_accuracy_opt_separator_scope_extent_identifier_remark @@ -1468,6 +1489,13 @@ operation_keyword: T_COORDINATEOPERATION operation_name: quoted_latin_text +operation_version: operation_version_keyword left_delimiter + operation_version_text right_delimiter + +operation_version_keyword: T_VERSION + +operation_version_text: quoted_latin_text + source_crs: source_crs_keyword left_delimiter crs right_delimiter source_crs_keyword: T_SOURCECRS @@ -1488,6 +1516,13 @@ operation_accuracy_keyword: T_OPERATIONACCURACY // Point motion operation point_motion_operation: point_motion_keyword left_delimiter operation_name + point_motion_operation_next + +point_motion_operation_next: + wkt_separator operation_version point_motion_operation_end + | point_motion_operation_end + +point_motion_operation_end: wkt_separator source_crs wkt_separator operation_method opt_parameter_or_parameter_file_list_opt_operation_accuracy_opt_separator_scope_extent_identifier_remark @@ -1506,6 +1541,13 @@ point_motion_keyword: T_POINTMOTIONOPERATION concatenated_operation: concatenated_operation_keyword left_delimiter operation_name + concatenated_operation_next + +concatenated_operation_next: + wkt_separator operation_version concatenated_operation_end + | concatenated_operation_end + +concatenated_operation_end: wkt_separator source_crs wkt_separator target_crs wkt_separator step_keyword left_delimiter step right_delimiter wkt_separator step_keyword left_delimiter step right_delimiter @@ -1535,8 +1577,16 @@ bound_crs: bound_crs_keyword left_delimiter bound_crs_keyword: T_BOUNDCRS abridged_coordinate_transformation: abridged_transformation_keyword left_delimiter - operation_name wkt_separator - operation_method wkt_separator + operation_name + abridged_coordinate_transformation_next + +abridged_coordinate_transformation_next: + wkt_separator operation_version abridged_coordinate_transformation_end + | abridged_coordinate_transformation_end + +abridged_coordinate_transformation_end: + wkt_separator operation_method + wkt_separator abridged_parameter_or_parameter_file opt_end_abridged_coordinate_transformation right_delimiter diff --git a/src/wkt2_parser.cpp b/src/wkt2_parser.cpp index f77c7ceb..921d6dd4 100644 --- a/src/wkt2_parser.cpp +++ b/src/wkt2_parser.cpp @@ -100,7 +100,7 @@ static const wkt2_tokens tokens[] = { PAIR(GEOGRAPHICCRS), PAIR(TRF), PAIR(VERTICALCRS), PAIR(VERTICALDATUM), PAIR(VRF), PAIR(TIMEDATUM), PAIR(TEMPORALQUANTITY), PAIR(ENGINEERINGDATUM), PAIR(ENGINEERINGCRS), PAIR(PARAMETRICDATUM), PAIR(EPOCH), PAIR(COORDEPOCH), - PAIR(COORDINATEMETADATA), PAIR(POINTMOTIONOPERATION), + PAIR(COORDINATEMETADATA), PAIR(POINTMOTIONOPERATION), PAIR(VERSION), // CS types PAIR(AFFINE), PAIR(CARTESIAN), PAIR(CYLINDRICAL), PAIR(ELLIPSOIDAL), -- cgit v1.2.3 From 66774791d16d1b197911e595aaaceb9690c8ca14 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:22:33 +0100 Subject: projinfo.cpp: formatting fix --- src/apps/projinfo.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index ae97b9c1..4c99d7ce 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -77,7 +77,8 @@ struct OutputOptions { static void usage() { std::cerr - << "usage: projinfo [-o formats] [-k crs|operation|ellipsoid] [--summary] [-q]" + << "usage: projinfo [-o formats] [-k crs|operation|ellipsoid] " + "[--summary] [-q]" << std::endl << " ([--area name_or_code] | " "[--bbox west_long,south_lat,east_long,north_lat]) " @@ -138,7 +139,8 @@ static std::string c_ify_string(const std::string &str) { static BaseObjectNNPtr buildObject( DatabaseContextPtr dbContext, const std::string &user_string, - const std::string &kind, const std::string &context, bool buildBoundCRSToWGS84, + const std::string &kind, const std::string &context, + bool buildBoundCRSToWGS84, CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, bool quiet) { BaseObjectPtr obj; @@ -179,8 +181,7 @@ static BaseObjectNNPtr buildObject( tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); } else if (kind == "ellipsoid" && tokens.size() == 2) { - auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + - tokens[1]; + auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); } else { // Convenience to be able to use C escaped strings... -- cgit v1.2.3 From 72f0e8a895a861e4323cac61b73f807c8a5f1c0d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:11:21 +0100 Subject: crs.cpp: remove non-intented (harmless here) pass by reference of a pointer --- src/iso19111/crs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 9688883d..74f6f999 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2421,7 +2421,7 @@ void DerivedCRS::setDerivingConversionCRS() { // --------------------------------------------------------------------------- -void DerivedCRS::baseExportToWKT(io::WKTFormatter *&formatter, +void DerivedCRS::baseExportToWKT(io::WKTFormatter *formatter, const std::string &keyword, const std::string &baseKeyword) const { formatter->startNode(keyword, !identifiers().empty()); @@ -4848,7 +4848,7 @@ DerivedCRSTemplate::create( // --------------------------------------------------------------------------- -static void DerivedCRSTemplateCheckExportToWKT(io::WKTFormatter *&formatter, +static void DerivedCRSTemplateCheckExportToWKT(io::WKTFormatter *formatter, const std::string &crsName, bool wkt2_2018_only) { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; -- cgit v1.2.3 From d4fd50f10ecabb9e9642cb4f877262e082677be4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:07:35 +0100 Subject: WKT2_2018: export ID in base crs node, when there is none on top of upper node This is the standard logic, that is now possible since ID is allowed in BASEGEOGCRS and similar node --- src/iso19111/crs.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 74f6f999..9779d817 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2428,9 +2428,13 @@ void DerivedCRS::baseExportToWKT(io::WKTFormatter *formatter, formatter->addQuotedString(nameStr()); const auto &l_baseCRS = d->baseCRS_; - formatter->startNode(baseKeyword, !l_baseCRS->identifiers().empty()); + formatter->startNode(baseKeyword, formatter->use2018Keywords() && + !l_baseCRS->identifiers().empty()); formatter->addQuotedString(l_baseCRS->nameStr()); l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter); + if (formatter->use2018Keywords() && formatter->outputId()) { + l_baseCRS->formatID(formatter); + } formatter->endNode(); formatter->setUseDerivingConversion(true); @@ -2658,7 +2662,7 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { dynamic_cast(l_baseCRS.get())) ? io::WKTConstants::BASEGEOGCRS : io::WKTConstants::BASEGEODCRS, - !l_baseCRS->identifiers().empty()); + formatter->use2018Keywords() && !l_baseCRS->identifiers().empty()); formatter->addQuotedString(l_baseCRS->nameStr()); l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter); // insert ellipsoidal cs unit when the units of the map @@ -2669,6 +2673,9 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { geodeticCRSAxisList[0]->unit()._exportToWKT(formatter); } l_baseCRS->primeMeridian()->_exportToWKT(formatter); + if (formatter->use2018Keywords() && formatter->outputId()) { + l_baseCRS->formatID(formatter); + } formatter->endNode(); } else { const auto oldAxisOutputRule = formatter->outputAxis(); -- cgit v1.2.3 From 46f08f1434f66a4160d7c74923efcfb81505b398 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:44:05 +0100 Subject: WKT2_2018: always export ID in base crs node, even if there is one on upper node This is a particular logic allowed by paragraph 7.3.3 Identifier of OGC 18-010r6 --- src/iso19111/crs.cpp | 6 ++++-- src/iso19111/io.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 9779d817..2dc6b3bf 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2432,7 +2432,8 @@ void DerivedCRS::baseExportToWKT(io::WKTFormatter *formatter, !l_baseCRS->identifiers().empty()); formatter->addQuotedString(l_baseCRS->nameStr()); l_baseCRS->exportDatumOrDatumEnsembleToWkt(formatter); - if (formatter->use2018Keywords() && formatter->outputId()) { + if (formatter->use2018Keywords() && + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) { l_baseCRS->formatID(formatter); } formatter->endNode(); @@ -2673,7 +2674,8 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { geodeticCRSAxisList[0]->unit()._exportToWKT(formatter); } l_baseCRS->primeMeridian()->_exportToWKT(formatter); - if (formatter->use2018Keywords() && formatter->outputId()) { + if (formatter->use2018Keywords() && + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())) { l_baseCRS->formatID(formatter); } formatter->endNode(); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 220ee967..78b18719 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -634,6 +634,18 @@ bool WKTFormatter::primeMeridianInDegree() const { // --------------------------------------------------------------------------- +bool WKTFormatter::idOnTopLevelOnly() const { + return d->params_.idOnTopLevelOnly_; +} + +// --------------------------------------------------------------------------- + +bool WKTFormatter::topLevelHasId() const { + return d->stackHasId_.size() >= 2 && d->stackHasId_[1]; +} + +// --------------------------------------------------------------------------- + WKTFormatter::Version WKTFormatter::version() const { return d->params_.version_; } -- cgit v1.2.3 From 09db4826d4a1e5df900cb4b93a4b3eae2c487cb9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 13:56:43 +0100 Subject: WKT2_2018: always export ID of SOURCECRS/TARGETCRS and STEPs even if there is one on upper node This is a particular logic allowed by paragraph 7.3.3 Identifier of OGC 18-010r6 --- src/iso19111/common.cpp | 2 +- src/iso19111/coordinateoperation.cpp | 88 ++++++++++++++++++++++++++++-------- src/iso19111/io.cpp | 28 ++++++++++++ 3 files changed, 98 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp index 4b947dc9..d46da0da 100644 --- a/src/iso19111/common.cpp +++ b/src/iso19111/common.cpp @@ -1073,7 +1073,7 @@ void ObjectUsage::setProperties( void ObjectUsage::baseExportToWKT(WKTFormatter *formatter) const { const bool isWKT2 = formatter->version() == WKTFormatter::Version::WKT2; - if (isWKT2 && formatter->outputId()) { + if (isWKT2 && formatter->outputUsage()) { auto l_domains = domains(); if (!l_domains.empty()) { if (formatter->use2018Keywords()) { diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 80c1a572..d7f138a4 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -7639,6 +7639,53 @@ void Transformation::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- +static void exportSourceCRSAndTargetCRSToWKT(const CoordinateOperation *co, + io::WKTFormatter *formatter) { + auto l_sourceCRS = co->sourceCRS(); + assert(l_sourceCRS); + auto l_targetCRS = co->targetCRS(); + assert(l_targetCRS); + const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; + const bool canExportCRSId = + (isWKT2 && formatter->use2018Keywords() && + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId())); + + const bool hasDomains = !co->domains().empty(); + if (hasDomains) { + formatter->pushDisableUsage(); + } + + formatter->startNode(io::WKTConstants::SOURCECRS, false); + if (canExportCRSId && !l_sourceCRS->identifiers().empty()) { + // fake that top node has no id, so that the sourceCRS id is + // considered + formatter->pushHasId(false); + l_sourceCRS->_exportToWKT(formatter); + formatter->popHasId(); + } else { + l_sourceCRS->_exportToWKT(formatter); + } + formatter->endNode(); + + formatter->startNode(io::WKTConstants::TARGETCRS, false); + if (canExportCRSId && !l_targetCRS->identifiers().empty()) { + // fake that top node has no id, so that the targetCRS id is + // considered + formatter->pushHasId(false); + l_targetCRS->_exportToWKT(formatter); + formatter->popHasId(); + } else { + l_targetCRS->_exportToWKT(formatter); + } + formatter->endNode(); + + if (hasDomains) { + formatter->popDisableUsage(); + } +} + +// --------------------------------------------------------------------------- + void SingleOperation::exportTransformationToWKT( io::WKTFormatter *formatter) const { const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2; @@ -7647,11 +7694,6 @@ void SingleOperation::exportTransformationToWKT( "Transformation can only be exported to WKT2"); } - auto l_sourceCRS = sourceCRS(); - assert(l_sourceCRS); - auto l_targetCRS = targetCRS(); - assert(l_targetCRS); - if (formatter->abridgedTransformation()) { formatter->startNode(io::WKTConstants::ABRIDGEDTRANSFORMATION, !identifiers().empty()); @@ -7672,13 +7714,7 @@ void SingleOperation::exportTransformationToWKT( } if (!formatter->abridgedTransformation()) { - formatter->startNode(io::WKTConstants::SOURCECRS, false); - l_sourceCRS->_exportToWKT(formatter); - formatter->endNode(); - - formatter->startNode(io::WKTConstants::TARGETCRS, false); - l_targetCRS->_exportToWKT(formatter); - formatter->endNode(); + exportSourceCRSAndTargetCRSToWKT(this, formatter); } method()->_exportToWKT(formatter); @@ -9337,20 +9373,34 @@ void ConcatenatedOperation::_exportToWKT(io::WKTFormatter *formatter) const { } } - formatter->startNode(io::WKTConstants::SOURCECRS, false); - sourceCRS()->_exportToWKT(formatter); - formatter->endNode(); + exportSourceCRSAndTargetCRSToWKT(this, formatter); - formatter->startNode(io::WKTConstants::TARGETCRS, false); - targetCRS()->_exportToWKT(formatter); - formatter->endNode(); + const bool canExportOperationId = + !(formatter->idOnTopLevelOnly() && formatter->topLevelHasId()); + + const bool hasDomains = !domains().empty(); + if (hasDomains) { + formatter->pushDisableUsage(); + } for (const auto &operation : operations()) { formatter->startNode(io::WKTConstants::STEP, false); - operation->_exportToWKT(formatter); + if (canExportOperationId && !operation->identifiers().empty()) { + // fake that top node has no id, so that the operation id is + // considered + formatter->pushHasId(false); + operation->_exportToWKT(formatter); + formatter->popHasId(); + } else { + operation->_exportToWKT(formatter); + } formatter->endNode(); } + if (hasDomains) { + formatter->popDisableUsage(); + } + ObjectUsage::baseExportToWKT(formatter); formatter->endNode(); } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 78b18719..578234b4 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -141,6 +141,7 @@ struct WKTFormatter::Private { std::vector stackHasChild_{}; std::vector stackHasId_{false}; std::vector stackEmptyKeyword_{}; + std::vector stackDisableUsage_{}; std::vector outputUnitStack_{true}; std::vector outputIdStack_{true}; std::vector axisLinearUnitStack_{ @@ -272,6 +273,11 @@ const std::string &WKTFormatter::toString() const { if (d->outputUnitStack_.size() != 1) throw FormattingException( "Unbalanced pushOutputUnit() / popOutputUnit()"); + if (d->stackHasId_.size() != 1) + throw FormattingException("Unbalanced pushHasId() / popHasId()"); + if (!d->stackDisableUsage_.empty()) + throw FormattingException( + "Unbalanced pushDisableUsage() / popDisableUsage()"); return d->result_; } @@ -556,6 +562,28 @@ bool WKTFormatter::outputId() const { // --------------------------------------------------------------------------- +void WKTFormatter::pushHasId(bool hasId) { d->stackHasId_.push_back(hasId); } + +// --------------------------------------------------------------------------- + +void WKTFormatter::popHasId() { d->stackHasId_.pop_back(); } + +// --------------------------------------------------------------------------- + +void WKTFormatter::pushDisableUsage() { d->stackDisableUsage_.push_back(true); } + +// --------------------------------------------------------------------------- + +void WKTFormatter::popDisableUsage() { d->stackDisableUsage_.pop_back(); } + +// --------------------------------------------------------------------------- + +bool WKTFormatter::outputUsage() const { + return outputId() && d->stackDisableUsage_.empty(); +} + +// --------------------------------------------------------------------------- + void WKTFormatter::pushAxisLinearUnit(const UnitOfMeasureNNPtr &unit) { d->axisLinearUnitStack_.push_back(unit); } -- cgit v1.2.3 From 054d02760db6fc2c33889d577cd671baa8807909 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 17:00:04 +0100 Subject: Database: add operation_version column to coordinate operation tables --- src/iso19111/factory.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 3530f5d8..b893faff 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2597,7 +2597,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( "rate_scale_difference, rate_scale_difference_uom_auth_name, " "rate_scale_difference_uom_code, epoch, epoch_uom_auth_name, " "epoch_uom_code, px, py, pz, pivot_uom_auth_name, pivot_uom_code, " - "deprecated FROM " + "operation_version, deprecated FROM " "helmert_transformation WHERE auth_name = ? AND code = ?", code); if (res.empty()) { @@ -2658,6 +2658,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &pivot_uom_auth_name = row[idx++]; const auto &pivot_uom_code = row[idx++]; + const auto &operation_version = row[idx++]; const auto &deprecated_str = row[idx++]; const bool deprecated = deprecated_str == "1"; assert(idx == row.size()); @@ -2798,6 +2799,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( auto props = d->createProperties(code, name, deprecated, area_of_use_auth_name, area_of_use_code); + if (!operation_version.empty()) { + props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, + operation_version); + } auto propsMethod = util::PropertyMap() @@ -2828,8 +2833,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( "grid_name, " "grid2_param_auth_name, grid2_param_code, grid2_param_name, " "grid2_name, " - "interpolation_crs_auth_name, interpolation_crs_code, deprecated " - "FROM " + "interpolation_crs_auth_name, interpolation_crs_code, " + "operation_version, deprecated FROM " "grid_transformation WHERE auth_name = ? AND code = ?", code); if (res.empty()) { @@ -2861,7 +2866,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &grid2_name = row[idx++]; const auto &interpolation_crs_auth_name = row[idx++]; const auto &interpolation_crs_code = row[idx++]; - + const auto &operation_version = row[idx++]; const auto &deprecated_str = row[idx++]; const bool deprecated = deprecated_str == "1"; assert(idx == row.size()); @@ -2907,6 +2912,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( auto props = d->createProperties(code, name, deprecated, area_of_use_auth_name, area_of_use_code); + if (!operation_version.empty()) { + props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, + operation_version); + } auto propsMethod = util::PropertyMap() .set(metadata::Identifier::CODESPACE_KEY, method_auth_name) @@ -2948,8 +2957,8 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( buffer << ", param" << i << "_uom_auth_name"; buffer << ", param" << i << "_uom_code"; } - buffer << ", deprecated FROM other_transformation WHERE auth_name = ? " - "AND code = ?"; + buffer << ", operation_version, deprecated FROM other_transformation " + "WHERE auth_name = ? AND code = ?"; auto res = d->runWithCodeParam(buffer.str(), code); if (res.empty()) { @@ -3002,6 +3011,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( } idx = base_param_idx + 6 * N_MAX_PARAMS; + const auto &operation_version = row[idx++]; const auto &deprecated_str = row[idx++]; const bool deprecated = deprecated_str == "1"; assert(idx == row.size()); @@ -3016,6 +3026,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( auto props = d->createProperties(code, name, deprecated, area_of_use_auth_name, area_of_use_code); + if (!operation_version.empty()) { + props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, + operation_version); + } std::vector accuracies; if (!accuracy.empty()) { @@ -3069,7 +3083,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( "target_crs_auth_name, target_crs_code, " "area_of_use_auth_name, area_of_use_code, accuracy, " "step1_auth_name, step1_code, step2_auth_name, step2_code, " - "step3_auth_name, step3_code, deprecated FROM " + "step3_auth_name, step3_code, operation_version, deprecated FROM " "concatenated_operation WHERE auth_name = ? AND code = ?", code); if (res.empty()) { @@ -3094,6 +3108,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( const auto &step2_code = row[idx++]; const auto &step3_auth_name = row[idx++]; const auto &step3_code = row[idx++]; + const auto &operation_version = row[idx++]; const auto &deprecated_str = row[idx++]; const bool deprecated = deprecated_str == "1"; @@ -3127,6 +3142,10 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( auto props = d->createProperties(code, name, deprecated, area_of_use_auth_name, area_of_use_code); + if (!operation_version.empty()) { + props.set(operation::CoordinateOperation::OPERATION_VERSION_KEY, + operation_version); + } std::vector accuracies; if (!accuracy.empty()) { -- cgit v1.2.3 From b4bbcc3f264602bb4b58a5c703cc220ed404d127 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Mon, 25 Mar 2019 18:12:03 +0000 Subject: pj_strerrno: enable system error messages HAVE_STRERROR is defined in proj_config.h. --- src/strerrno.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 20255747..af130fc4 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -5,6 +5,7 @@ #include #include "proj.h" +#include "proj_config.h" #include "proj_internal.h" static const char * const -- cgit v1.2.3 From 399ebef6a66e57d389a7b7761e7373a4cebe86e5 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 20:51:56 +0100 Subject: lookForGridInfo(): correctly return that a grid is present, if present on the file system, but not in the database --- src/iso19111/coordinateoperation.cpp | 16 ++++++++++++++-- src/iso19111/factory.cpp | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 80c1a572..a8a25a6a 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -8742,13 +8742,25 @@ void Transformation::_exportToPROJString( if (fileParameter && fileParameter->type() == ParameterValue::Type::FILENAME) { auto filename = fileParameter->valueFile(); - if (isMethodInverseOf) { + bool doInversion = isMethodInverseOf; + if (!identifiers().empty() && + *identifiers().front()->codeSpace() == + metadata::Identifier::EPSG && + method()->nameStr() == + "Geographic3D to GravityRelatedHeight (US .gtx)" && + ends_with(filename, ".gtx")) { + // gtx files, from straight EPSG definition, must be applied in + // reverse order for "Geographic3D to GravityRelatedHeight" + // method + doInversion = !doInversion; + } + if (doInversion) { formatter->startInversion(); } formatter->addStep("vgridshift"); formatter->addParam("grids", filename); formatter->addParam("multiplier", 1.0); - if (isMethodInverseOf) { + if (doInversion) { formatter->stopInversion(); } return; diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 3530f5d8..2e18c885 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1024,8 +1024,8 @@ bool DatabaseContext::lookForGridInfo(const std::string &projFilename, info.url = url; info.directDownload = directDownload; info.openLicense = openLicense; - info.gridAvailable = gridAvailable; } + info.gridAvailable = gridAvailable; info.found = ret; d->cache(projFilename, info); return ret; -- cgit v1.2.3 From 3fe2e50dc8af9e4557f0303786282f1ba68ceff6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:17:27 +0100 Subject: factory.cpp: avoid warning about int truncation. Coverity CID 193544 --- src/iso19111/factory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 14421022..d6517748 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1615,7 +1615,8 @@ static double normalizeMeasure(const std::string &uom_code, assert(seconds.size() == precision - 2); normalized_value = (normalized_value < 0 ? -1.0 : 1.0) * - (int(std::fabs(normalized_value)) + c_locale_stod(minutes) / 60. + + (std::floor(std::fabs(normalized_value)) + + c_locale_stod(minutes) / 60. + (c_locale_stod(seconds) / std::pow(10, seconds.size() - 2)) / 3600.); normalized_uom_code = common::UnitOfMeasure::DEGREE.code(); -- cgit v1.2.3 From a3325679bfe3890b4764d70bdbe1850fc992bc31 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:28:44 +0100 Subject: c_api.cpp: avoid mixing enum types. Coverity CID 193542 --- src/iso19111/c_api.cpp | 85 +++++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index f7dcd354..8e1a60a5 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -975,29 +975,18 @@ int proj_is_equivalent_to(const PJ *obj, const PJ *other, return false; } - // Make sure that the C and C++ enumerations match - static_assert(static_cast(PJ_COMP_STRICT) == - static_cast(IComparable::Criterion::STRICT), - ""); - static_assert(static_cast(PJ_COMP_EQUIVALENT) == - static_cast(IComparable::Criterion::EQUIVALENT), - ""); - static_assert( - static_cast(PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS) == - static_cast( - IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS), - ""); + const auto cppCriterion = ([](PJ_COMPARISON_CRITERION l_criterion) { + switch (l_criterion) { + case PJ_COMP_STRICT: + return IComparable::Criterion::STRICT; + case PJ_COMP_EQUIVALENT: + return IComparable::Criterion::EQUIVALENT; + case PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS: + break; + } + return IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS; + })(criterion); - // Make sure we enumerate all values. If adding a new value, as we - // don't have a default clause, the compiler will warn. - switch (criterion) { - case PJ_COMP_STRICT: - case PJ_COMP_EQUIVALENT: - case PJ_COMP_EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS: - break; - } - const IComparable::Criterion cppCriterion = - static_cast(criterion); return obj->iso_obj->isEquivalentTo(other->iso_obj.get(), cppCriterion); } @@ -1121,40 +1110,24 @@ const char *proj_as_wkt(PJ_CONTEXT *ctx, const PJ *obj, PJ_WKT_TYPE type, return nullptr; } - // Make sure that the C and C++ enumerations match - static_assert(static_cast(PJ_WKT2_2015) == - static_cast(WKTFormatter::Convention::WKT2_2015), - ""); - static_assert( - static_cast(PJ_WKT2_2015_SIMPLIFIED) == - static_cast(WKTFormatter::Convention::WKT2_2015_SIMPLIFIED), - ""); - static_assert(static_cast(PJ_WKT2_2018) == - static_cast(WKTFormatter::Convention::WKT2_2018), - ""); - static_assert( - static_cast(PJ_WKT2_2018_SIMPLIFIED) == - static_cast(WKTFormatter::Convention::WKT2_2018_SIMPLIFIED), - ""); - static_assert(static_cast(PJ_WKT1_GDAL) == - static_cast(WKTFormatter::Convention::WKT1_GDAL), - ""); - static_assert(static_cast(PJ_WKT1_ESRI) == - static_cast(WKTFormatter::Convention::WKT1_ESRI), - ""); - // Make sure we enumerate all values. If adding a new value, as we - // don't have a default clause, the compiler will warn. - switch (type) { - case PJ_WKT2_2015: - case PJ_WKT2_2015_SIMPLIFIED: - case PJ_WKT2_2018: - case PJ_WKT2_2018_SIMPLIFIED: - case PJ_WKT1_GDAL: - case PJ_WKT1_ESRI: - break; - } - const WKTFormatter::Convention convention = - static_cast(type); + const auto convention = ([](PJ_WKT_TYPE l_type) { + switch (l_type) { + case PJ_WKT2_2015: + return WKTFormatter::Convention::WKT2_2015; + case PJ_WKT2_2015_SIMPLIFIED: + return WKTFormatter::Convention::WKT2_2015_SIMPLIFIED; + case PJ_WKT2_2018: + return WKTFormatter::Convention::WKT2_2018; + case PJ_WKT2_2018_SIMPLIFIED: + return WKTFormatter::Convention::WKT2_2018_SIMPLIFIED; + case PJ_WKT1_GDAL: + return WKTFormatter::Convention::WKT1_GDAL; + case PJ_WKT1_ESRI: + break; + } + return WKTFormatter::Convention::WKT1_ESRI; + })(type); + try { auto dbContext = getDBcontextNoException(ctx, __FUNCTION__); auto formatter = WKTFormatter::create(convention, dbContext); -- cgit v1.2.3 From af0e994486346d89cdbe68fff68ce3c8d27b0c94 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:30:52 +0100 Subject: coordinateoperation.cpp: silent false positive about copy paste error. Coverity CID 193519 --- src/iso19111/coordinateoperation.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 50a6a003..ff104026 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -9163,6 +9163,7 @@ void ConcatenatedOperation::fixStepsDirection( op = op->inverse(); } } else if (i + 1 < operationsInOut.size()) { + /* coverity[copy_paste_error] */ l_targetCRS = operationsInOut[i + 1]->sourceCRS(); if (l_targetCRS) { op->setCRSs(concatOpSourceCRS, NN_NO_CHECK(l_targetCRS), -- cgit v1.2.3 From 71c4439617a77051ec8049f08c08c61f89946e95 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:32:46 +0100 Subject: coordinateoperation.cpp: remove dead code. Coverity CID 193522 --- src/iso19111/coordinateoperation.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index ff104026..1abb74b3 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -7704,7 +7704,7 @@ void SingleOperation::exportTransformationToWKT( formatter->addQuotedString(nameStr()); - if (isWKT2 && formatter->use2018Keywords()) { + if (formatter->use2018Keywords()) { const auto &version = operationVersion(); if (version.has_value()) { formatter->startNode(io::WKTConstants::VERSION, false); @@ -7719,10 +7719,8 @@ void SingleOperation::exportTransformationToWKT( method()->_exportToWKT(formatter); - const MethodMapping *mapping = - !isWKT2 ? getMapping(method().get()) : nullptr; for (const auto ¶mValue : parameterValues()) { - paramValue->_exportToWKT(formatter, mapping); + paramValue->_exportToWKT(formatter, nullptr); } if (!formatter->abridgedTransformation()) { -- cgit v1.2.3 From fcce544e8bc6799632df6276fe92758b9eb3aa7b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:37:15 +0100 Subject: crs.cpp: make it clear to analyzer that buffer will not overflow. Coverity CID 193528 and 193540 --- src/iso19111/crs.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 2dc6b3bf..b51d03c9 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1892,9 +1892,7 @@ void GeographicCRS::addAngularUnitConvertAndAxisSwap( if (order[0] && order[1] && (order[0] != one || order[1] != two)) { formatter->addStep("axisswap"); char orderStr[10]; - strcpy(orderStr, order[0]); - strcat(orderStr, ","); - strcat(orderStr, order[1]); + sprintf(orderStr, "%.2s,%.2s", order[0], order[1]); formatter->addParam("order", orderStr); } } @@ -2851,9 +2849,7 @@ void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter, if (order[0] && order[1]) { formatter->addStep("axisswap"); char orderStr[10]; - strcpy(orderStr, order[0]); - strcat(orderStr, ","); - strcat(orderStr, order[1]); + sprintf(orderStr, "%.2s,%.2s", order[0], order[1]); formatter->addParam("order", orderStr); } } else { -- cgit v1.2.3 From d9008cf85aa499bdf298a237c60676a9f8c4de14 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:40:24 +0100 Subject: factory.cpp: make closeDB() noexcept so that DatabaseContext::Private destructor cannot throw. Coverity CID 193518 --- src/iso19111/factory.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index d6517748..e42ed89f 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -259,7 +259,7 @@ struct DatabaseContext::Private { static void getFromCache(LRUCacheOfObjects &cache, const std::string &code, util::BaseObjectPtr &obj); - void closeDB(); + void closeDB() noexcept; // cppcheck-suppress functionStatic void registerFunctions(); @@ -295,7 +295,7 @@ DatabaseContext::Private::~Private() { // --------------------------------------------------------------------------- -void DatabaseContext::Private::closeDB() { +void DatabaseContext::Private::closeDB() noexcept { if (detach_) { // Workaround a bug visible in SQLite 3.8.1 and 3.8.2 that causes @@ -309,7 +309,10 @@ void DatabaseContext::Private::closeDB() { // https://github.com/mackyle/sqlite/commit/ccf328c4318eacedab9ed08c404bc4f402dcad19 // also seemed to hide the issue. // Detaching a database hides the issue, not sure if it is by chance... - run("DETACH DATABASE db_0"); + try { + run("DETACH DATABASE db_0"); + } catch (...) { + } detach_ = false; } -- cgit v1.2.3 From 909f5253bc2963ab4368f19af517adb844a80752 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:41:43 +0100 Subject: io.cpp: make it obvious that nullptr deref cannot happen. Coverity CID 193523 --- src/iso19111/io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 578234b4..afacb1be 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -3168,7 +3168,6 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } const auto *wkt2_mapping = getMapping(esriMapping->wkt2_name); - assert(wkt2_mapping); if (ci_equal(esriProjectionName, "Stereographic")) { try { if (std::fabs(io::asDouble( @@ -3179,6 +3178,7 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } catch (const std::exception &) { } } + assert(wkt2_mapping); PropertyMap propertiesMethod; propertiesMethod.set(IdentifiedObject::NAME_KEY, wkt2_mapping->wkt2_name); -- cgit v1.2.3 From 9772b40bba6c020bfc48d00a886ca6c7c0e2770b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:47:20 +0100 Subject: io.cpp: avoid error about unchecked return value. Coverity CID 193541 --- src/iso19111/io.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index afacb1be..502f30e6 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6734,6 +6734,9 @@ static double getNumericValue(const std::string ¶mValue, } // --------------------------------------------------------------------------- +namespace { +template inline void ignoreRetVal(T) {} +} GeographicCRSNNPtr PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert, @@ -6746,7 +6749,7 @@ PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert, // units=m is often found in the wild. // No need to create a extension string for this - hasParamValue(step, "units"); + ignoreRetVal(hasParamValue(step, "units")); auto datum = buildDatum(step, title); -- cgit v1.2.3 From 0297ae118871bfc4de54a8ab972220c89aa60c65 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:49:49 +0100 Subject: nad_init(): remove useless string copy. Coverity CID 193531 --- src/nad_init.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/nad_init.cpp b/src/nad_init.cpp index d9701e70..315318be 100644 --- a/src/nad_init.cpp +++ b/src/nad_init.cpp @@ -265,7 +265,6 @@ struct CTABLE *nad_ctable2_init( projCtx ctx, struct projFileAPI_t* fileapi ) struct CTABLE *nad_init(projCtx ctx, char *name) { - char fname[MAX_PATH_FILENAME+1]; struct CTABLE *ct; PAFile fid; @@ -274,8 +273,7 @@ struct CTABLE *nad_init(projCtx ctx, char *name) /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ - strcpy(fname, name); - if (!(fid = pj_open_lib(ctx, fname, "rb"))) { + if (!(fid = pj_open_lib(ctx, name, "rb"))) { return nullptr; } -- cgit v1.2.3 From 4849c52a986e4618ab66649aad9e21789ba6735d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 13:53:52 +0100 Subject: pj_gridinfo_init(): remove useless string copy. Coverity CID 193529 --- src/gridinfo.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gridinfo.cpp b/src/gridinfo.cpp index 14759557..bff487f5 100644 --- a/src/gridinfo.cpp +++ b/src/gridinfo.cpp @@ -851,7 +851,6 @@ static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) { - char fname[MAX_PATH_FILENAME+1]; PJ_GRIDINFO *gilist; PAFile fp; char header[160]; @@ -885,13 +884,12 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) /* -------------------------------------------------------------------- */ /* Open the file using the usual search rules. */ /* -------------------------------------------------------------------- */ - strcpy(fname, gridname); - if (!(fp = pj_open_lib(ctx, fname, "rb"))) { + if (!(fp = pj_open_lib(ctx, gridname, "rb"))) { ctx->last_errno = 0; /* don't treat as a persistent error */ return gilist; } - gilist->filename = pj_strdup(fname); + gilist->filename = pj_strdup(gridname); if (!gilist->filename) { pj_dalloc(gilist->gridname); pj_dalloc(gilist); -- cgit v1.2.3 From 53aefd520aa7f0607263fa2f2a7b89be81dfeac6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:06:23 +0100 Subject: pj_gc_findgrid(): annotate likely memory leak. Coverity CID 193539 --- src/gridcatalog.cpp | 10 ++++++++++ src/proj_internal.h | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gridcatalog.cpp b/src/gridcatalog.cpp index ca5750ab..15d81dd7 100644 --- a/src/gridcatalog.cpp +++ b/src/gridcatalog.cpp @@ -37,6 +37,13 @@ static PJ_GridCatalog *grid_catalog_list = nullptr; +static +PJ_GRIDINFO *pj_gc_findgrid( projCtx_t *ctx, + PJ_GridCatalog *catalog, int after, + PJ_LP location, double date, + PJ_Region *optional_region, + double *grid_date ); + /************************************************************************/ /* pj_gc_unloadall() */ /* */ @@ -236,6 +243,7 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, /* pj_c_findgrid() */ /************************************************************************/ +static PJ_GRIDINFO *pj_gc_findgrid( projCtx ctx, PJ_GridCatalog *catalog, int after, PJ_LP location, double date, PJ_Region *optional_region, @@ -287,6 +295,8 @@ PJ_GRIDINFO *pj_gc_findgrid( projCtx ctx, PJ_GridCatalog *catalog, int after, int grid_count = 0; gridlist = pj_gridlist_from_nadgrids( ctx, entry->definition, &grid_count); + // FIXME: this leaks gridlist itself, and memory ownership of + // entry->gridinfo is also confusing. Coverity CID 193539 if( grid_count == 1 ) entry->gridinfo = gridlist[0]; } diff --git a/src/proj_internal.h b/src/proj_internal.h index cdde6bad..880e194f 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -898,12 +898,6 @@ int pj_gc_apply_gridshift( PJ *defn, int inverse, long point_count, int point_offset, double *x, double *y, double *z ); -PJ_GRIDINFO *pj_gc_findgrid( projCtx_t *ctx, - PJ_GridCatalog *catalog, int after, - PJ_LP location, double date, - PJ_Region *optional_region, - double *grid_date ); - double pj_gc_parsedate( projCtx_t *, const char * ); void *proj_mdist_ini(double); -- cgit v1.2.3 From 01f6d08f0a0d3b05c28d6772d63b506171c59371 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:09:11 +0100 Subject: projinfo: catch potentially uncaugh exception. Coverity CID 193527 --- src/apps/projinfo.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 4c99d7ce..7d4a8399 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -1132,11 +1132,18 @@ int main(int argc, char **argv) { } } - outputOperations( - dbContext, sourceCRSStr, targetCRSStr, bboxFilter, spatialCriterion, - spatialCriterionExplicitlySpecified, crsExtentUse, - gridAvailabilityUse, allowUseIntermediateCRS, pivots, authority, - usePROJGridAlternatives, showSuperseded, outputOpt, summary); + try { + outputOperations(dbContext, sourceCRSStr, targetCRSStr, bboxFilter, + spatialCriterion, + spatialCriterionExplicitlySpecified, crsExtentUse, + gridAvailabilityUse, allowUseIntermediateCRS, + pivots, authority, usePROJGridAlternatives, + showSuperseded, outputOpt, summary); + } catch (const std::exception &e) { + std::cerr << "outputOperations() failed with: " << e.what() + << std::endl; + std::exit(1); + } } return 0; -- cgit v1.2.3 From 703805a646f827971135af1b4e60087d88fed974 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:11:34 +0100 Subject: optargpm.h: fix memory leaks in error code paths. Coverity CID 193537 --- src/apps/optargpm.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/apps/optargpm.h b/src/apps/optargpm.h index 035c6f92..e7f4f8e5 100644 --- a/src/apps/optargpm.h +++ b/src/apps/optargpm.h @@ -534,6 +534,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, *equals = '='; if (opt_is_flag (o, c)) { fprintf (stderr, "Option \"%s\" takes no arguments\n", crepr); + free (o); return nullptr; } o->optarg[c] = equals + 1; @@ -544,6 +545,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (!opt_is_flag (o, c)) { if ((argc==i + 1) || ('+'==argv[i+1][0]) || ('-'==argv[i+1][0])) { fprintf (stderr, "Missing argument for option \"%s\"\n", crepr); + free (o); return nullptr; } o->optarg[c] = argv[i + 1]; @@ -553,6 +555,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (!opt_is_flag (o, c)) { fprintf (stderr, "Expected flag style long option here, but got \"%s\"\n", crepr); + free (o); return nullptr; } @@ -564,6 +567,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, /* classic short options */ if (nullptr==o->optarg[c]) { fprintf (stderr, "Invalid option \"%s\"\n", crepr); + free (o); return nullptr; } @@ -580,6 +584,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if ((argc==i + 1) || ('+'==argv[i+1][0]) || ('-'==argv[i+1][0])) { fprintf (stderr, "Bad or missing arg for option \"%s\"\n", crepr); + free (o); return nullptr; } o->optarg[(int) c] = argv[i + 1]; -- cgit v1.2.3 From 6c22035b270aa46f03e6252cd552be14d170e501 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:12:31 +0100 Subject: gie.cpp: silence Coverity CID 193520 --- src/apps/gie.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 5407c0ba..a84e77ab 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -249,6 +249,7 @@ int main (int argc, char **argv) { T.ignore = 5555; /* Error code that will not be issued by proj_create() */ T.use_proj4_init_rules = FALSE; + /* coverity[tainted_data] */ o = opt_parse (argc, argv, "hlvq", "o", longflags, longkeys); if (nullptr==o) return 0; -- cgit v1.2.3 From 60b71b6187b6190b9ff626c8b0548789aa5c54d7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:17:31 +0100 Subject: proj/emess: fix null pointer dereference. CID 193533 --- src/apps/emess.cpp | 2 +- src/apps/proj.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp index 52f88aa3..53018ba8 100644 --- a/src/apps/emess.cpp +++ b/src/apps/emess.cpp @@ -30,7 +30,7 @@ emess(int code, const char *fmt, ...) { va_start(args, fmt); /* prefix program name, if given */ - if (fmt != nullptr) + if (emess_dat.Prog_name != nullptr) (void)fprintf(stderr,"%s\n<%s>: ",pj_get_release(), emess_dat.Prog_name); /* print file name and line, if given */ diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 40fc5695..88074280 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -532,7 +532,7 @@ int main(int argc, char **argv) { } else { if ((fid = fopen(*eargv, "rb")) == nullptr) { - emess(-2, *eargv, "input file"); + emess(-2, "input file: %s", *eargv); continue; } emess_dat.File_name = *eargv; -- cgit v1.2.3 From 473a8c133be66af64c227e7d24cb0031ebc6ebd7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:24:48 +0100 Subject: cs2cs: remove dead code that would leak memory. Coverity CID 193534 --- src/apps/cs2cs.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index c68572fa..31f0ae8e 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -274,13 +274,6 @@ static std::string get_geog_crs_proj_string_from_proj_crs(PJ *src, double &toRadians, bool &isLatFirst) { auto srcType = proj_get_type(src); - if (srcType == PJ_TYPE_BOUND_CRS) { - auto base = proj_get_source_crs(nullptr, src); - assert(base); - proj_destroy(src); - src = base; - srcType = proj_get_type(src); - } if (srcType != PJ_TYPE_PROJECTED_CRS) { return std::string(); } -- cgit v1.2.3 From 920ecd18f02d67d3344a3be979748586755a2cf6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:25:27 +0100 Subject: cct.cpp: silence Coverity CID 193536 --- src/apps/cct.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 34bf0777..87a60e2f 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -228,6 +228,7 @@ int main(int argc, char **argv) { fout = stdout; + /* coverity[tainted_data] */ o = opt_parse (argc, argv, "hvI", "cdozts", longflags, longkeys); if (nullptr==o) return 0; -- cgit v1.2.3 From a53f81de2f5fc5a6366dfea3806f4062abca4ecf Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:27:11 +0100 Subject: cct.cpp: silence Coverity CID 193526 --- src/apps/cct.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 87a60e2f..65718aca 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -369,6 +369,7 @@ int main(int argc, char **argv) { point.lpzt.phi = proj_torad (point.lpzt.phi); } err = proj_errno_reset (P); + /* coverity[returned_value] */ point = proj_trans (P, direction, point); if (HUGE_VAL==point.xyzt.x) { -- cgit v1.2.3 From 63224ed0e81b0e5795610c10e44578c932bbc33b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:30:33 +0100 Subject: read_vgrid_value(): make it clear that nullptr deref of ct->cvs cannot happen. Coverity CID 193525 --- src/apply_vgridshift.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index ae23e39a..9be65f08 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -98,10 +98,13 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * } /* load the grid shift info if we don't have it. */ - if( ct->cvs == nullptr && !pj_gridinfo_load( pj_get_ctx(defn), gi ) ) + if( ct->cvs == nullptr ) { - pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); - return PJD_ERR_FAILED_TO_LOAD_GRID; + if( !pj_gridinfo_load( pj_get_ctx(defn), gi ) || ct->cvs == nullptr ) + { + pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return PJD_ERR_FAILED_TO_LOAD_GRID; + } } -- cgit v1.2.3 From 3529081bce702ddbc7c68f677f91d3c8f5bbb897 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:32:15 +0100 Subject: pj_apply_gridshift(): make it obvious there is no memory leak. Coverity CID 193535 --- src/apply_gridshift.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/apply_gridshift.cpp b/src/apply_gridshift.cpp index c7070432..d9b5286d 100644 --- a/src/apply_gridshift.cpp +++ b/src/apply_gridshift.cpp @@ -59,7 +59,10 @@ int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, gridlist = pj_gridlist_from_nadgrids( ctx, nadgrids, &grid_count ); if( gridlist == nullptr || grid_count == 0 ) + { + pj_dalloc( gridlist ); return ctx->last_errno; + } ret = pj_apply_gridshift_3( ctx, gridlist, grid_count, inverse, point_count, point_offset, x, y, z ); -- cgit v1.2.3 From c05a91da2e9e008d77bd148d4de62045f9f149c8 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 14:34:13 +0100 Subject: path_append(): make it clear that nullptr deref cannot happen. Coverity CID 193530 --- src/4D_api.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index d0b2748e..81e16600 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1365,6 +1365,7 @@ static char *path_append (char *buf, const char *app, size_t *buf_size) { pj_dealloc (buf); buf = p; } + assert(buf); /* Only append a semicolon if something's already there */ if (0 != buflen) -- cgit v1.2.3 From e08b7bddd25349a24a294616e4d9c984c138e531 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 15:49:42 +0100 Subject: omerc inverse: fix division Test case https://oss-fuzz.com/testcase-detail/5739351578771456 of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13894 Credit to OSS Fuzz --- src/projections/omerc.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index e9b7b4a0..c33f6489 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -97,6 +97,10 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ u = xy.y * Q->cosrot + xy.x * Q->sinrot + Q->u_0; } Qp = exp(- Q->BrA * v); + if( Qp == 0 ) { + proj_errno_set(P, PJD_ERR_INVALID_X_OR_Y); + return proj_coord_error().lp; + } Sp = .5 * (Qp - 1. / Qp); Tp = .5 * (Qp + 1. / Qp); Vp = sin(Q->BrA * u); -- cgit v1.2.3 From d0ffa6c9702228aa55c7d2f1c887bf547c46b283 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 26 Mar 2019 22:55:56 +0100 Subject: misrsom inverse: avoid division by zero Fixes testcase https://oss-fuzz.com/testcase-detail/5768588923764736 of https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13894 --- src/projections/misrsom.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/misrsom.cpp b/src/projections/misrsom.cpp index c53f22a1..d16dd62d 100644 --- a/src/projections/misrsom.cpp +++ b/src/projections/misrsom.cpp @@ -151,10 +151,14 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ lamdp -= TOL; spp = sin(phidp); sppsq = spp * spp; + const double denom = 1. - sppsq * (1. + Q->u); + if( denom == 0.0 ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().lp; + } lamt = atan(((1. - sppsq * P->rone_es) * tan(lamdp) * Q->ca - spp * Q->sa * sqrt((1. + Q->q * dd) * ( - 1. - sppsq) - sppsq * Q->u) / cos(lamdp)) / (1. - sppsq - * (1. + Q->u))); + 1. - sppsq) - sppsq * Q->u) / cos(lamdp)) / denom); sl = lamt >= 0. ? 1. : -1.; scl = cos(lamdp) >= 0. ? 1. : -1; lamt -= M_HALFPI * (1. - scl) * sl; -- cgit v1.2.3 From 3987c3f22206768e875b45ff10b3824c52903d09 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 27 Mar 2019 12:53:20 +0100 Subject: optargpm.h: fix remaining memleak in error code path. Coverity CID 193537 --- src/apps/optargpm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/apps/optargpm.h b/src/apps/optargpm.h index e7f4f8e5..f293ad98 100644 --- a/src/apps/optargpm.h +++ b/src/apps/optargpm.h @@ -526,6 +526,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, c = opt_ordinal (o, crepr); if (0==c) { fprintf (stderr, "Invalid option \"%s\"\n", crepr); + free (o); return nullptr; } -- cgit v1.2.3 From e3806d999a86a1ab0e832f1ab6586ad181f64be1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 27 Mar 2019 12:58:42 +0100 Subject: projinfo: caught uncaught exception. Coverity CID 193527 --- src/apps/projinfo.cpp | 119 +++++++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 7d4a8399..9d724522 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -1005,69 +1005,78 @@ int main(int argc, char **argv) { } if (!user_string.empty()) { - auto obj(buildObject(dbContext, user_string, objectKind, "input string", - buildBoundCRSToWGS84, allowUseIntermediateCRS, - outputOpt.quiet)); - if (guessDialect) { - auto dialect = WKTParser().guessDialect(user_string); - std::cout << "Guessed WKT dialect: "; - if (dialect == WKTParser::WKTGuessedDialect::WKT2_2018) { - std::cout << "WKT2_2018"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT2_2015) { - std::cout << "WKT2_2015"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_GDAL) { - std::cout << "WKT1_GDAL"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_ESRI) { - std::cout << "WKT1_ESRI"; - } else { - std::cout << "Not WKT / unknown"; + try { + auto obj(buildObject(dbContext, user_string, objectKind, + "input string", buildBoundCRSToWGS84, + allowUseIntermediateCRS, outputOpt.quiet)); + if (guessDialect) { + auto dialect = WKTParser().guessDialect(user_string); + std::cout << "Guessed WKT dialect: "; + if (dialect == WKTParser::WKTGuessedDialect::WKT2_2018) { + std::cout << "WKT2_2018"; + } else if (dialect == WKTParser::WKTGuessedDialect::WKT2_2015) { + std::cout << "WKT2_2015"; + } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_GDAL) { + std::cout << "WKT1_GDAL"; + } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_ESRI) { + std::cout << "WKT1_ESRI"; + } else { + std::cout << "Not WKT / unknown"; + } + std::cout << std::endl; } - std::cout << std::endl; - } - outputObject(dbContext, obj, allowUseIntermediateCRS, outputOpt); - if (identify) { - auto crs = dynamic_cast(obj.get()); - if (crs) { - try { - auto res = crs->identify( - dbContext - ? AuthorityFactory::create(NN_NO_CHECK(dbContext), - authority) - .as_nullable() - : nullptr); - std::cout << std::endl; - std::cout << "Identification match count: " << res.size() - << std::endl; - for (const auto &pair : res) { - const auto &identifiedCRS = pair.first; - const auto &ids = identifiedCRS->identifiers(); - if (!ids.empty()) { - std::cout << *ids[0]->codeSpace() << ":" - << ids[0]->code() << ": " << pair.second - << " %" << std::endl; - } else { - auto boundCRS = - dynamic_cast(identifiedCRS.get()); - if (boundCRS && - !boundCRS->baseCRS()->identifiers().empty()) { - const auto &idsBase = - boundCRS->baseCRS()->identifiers(); - std::cout << "BoundCRS of " - << *idsBase[0]->codeSpace() << ":" - << idsBase[0]->code() << ": " + outputObject(dbContext, obj, allowUseIntermediateCRS, outputOpt); + if (identify) { + auto crs = dynamic_cast(obj.get()); + if (crs) { + try { + auto res = crs->identify( + dbContext + ? AuthorityFactory::create( + NN_NO_CHECK(dbContext), authority) + .as_nullable() + : nullptr); + std::cout << std::endl; + std::cout + << "Identification match count: " << res.size() + << std::endl; + for (const auto &pair : res) { + const auto &identifiedCRS = pair.first; + const auto &ids = identifiedCRS->identifiers(); + if (!ids.empty()) { + std::cout << *ids[0]->codeSpace() << ":" + << ids[0]->code() << ": " << pair.second << " %" << std::endl; } else { - std::cout - << "un-identifier CRS: " << pair.second - << " %" << std::endl; + auto boundCRS = dynamic_cast( + identifiedCRS.get()); + if (boundCRS && + !boundCRS->baseCRS() + ->identifiers() + .empty()) { + const auto &idsBase = + boundCRS->baseCRS()->identifiers(); + std::cout << "BoundCRS of " + << *idsBase[0]->codeSpace() << ":" + << idsBase[0]->code() << ": " + << pair.second << " %" + << std::endl; + } else { + std::cout + << "un-identifier CRS: " << pair.second + << " %" << std::endl; + } } } + } catch (const std::exception &e) { + std::cerr << "Identification failed: " << e.what() + << std::endl; } - } catch (const std::exception &e) { - std::cerr << "Identification failed: " << e.what() - << std::endl; } } + } catch (const std::exception &e) { + std::cerr << "buildObject failed: " << e.what() << std::endl; + std::exit(1); } } else { -- cgit v1.2.3 From 15a9adb5ff112184ea5abfe083ea280b7bef7dd4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 27 Mar 2019 13:01:10 +0100 Subject: factory.cpp: silence false positive warning. Coverity CID 193544 --- src/iso19111/factory.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index e42ed89f..f24b3457 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -1623,6 +1623,7 @@ static double normalizeMeasure(const std::string &uom_code, (c_locale_stod(seconds) / std::pow(10, seconds.size() - 2)) / 3600.); normalized_uom_code = common::UnitOfMeasure::DEGREE.code(); + /* coverity[overflow_sink] */ return normalized_value; } else { normalized_uom_code = uom_code; -- cgit v1.2.3 From d9885ef9577697951660ca68bc6f381939bc5dbe Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 28 Mar 2019 10:44:58 +1000 Subject: Objet -> Object --- src/iso19111/c_api.cpp | 50 +++++++++++++++++++++++++------------------------- src/iso19111/io.cpp | 4 ++-- 2 files changed, 27 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 8e1a60a5..e62d3f56 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1338,7 +1338,7 @@ static const GeodeticCRS *extractGeodeticCRS(PJ_CONTEXT *ctx, const PJ *crs, * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type CRS (must not be NULL) + * @param crs Object of type CRS (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error. */ @@ -1362,7 +1362,7 @@ PJ *proj_crs_get_geodetic_crs(PJ_CONTEXT *ctx, const PJ *crs) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type CRS (must not be NULL) + * @param crs Object of type CRS (must not be NULL) * @param index Index of the CRS component (typically 0 = horizontal, 1 = * vertical) * @return Object that must be unreferenced with proj_destroy(), or NULL @@ -1444,7 +1444,7 @@ PJ *proj_crs_create_bound_crs(PJ_CONTEXT *ctx, const PJ *base_crs, * osgeo::proj::crs::CRS::createBoundCRSToWGS84IfPossible() * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type CRS (must not be NULL) + * @param crs Object of type CRS (must not be NULL) * @param options null-terminated list of options, or NULL. Currently * supported options are: *
      @@ -1503,7 +1503,7 @@ PJ *proj_crs_create_bound_crs_to_WGS84(PJ_CONTEXT *ctx, const PJ *crs, * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param obj Objet of type CRS or GeodeticReferenceFrame (must not be NULL) + * @param obj Object of type CRS or GeodeticReferenceFrame (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error. */ @@ -1535,7 +1535,7 @@ PJ *proj_get_ellipsoid(PJ_CONTEXT *ctx, const PJ *obj) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type CRS (must not be NULL) + * @param crs Object of type CRS (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error. */ @@ -1618,7 +1618,7 @@ int proj_ellipsoid_get_parameters(PJ_CONTEXT *ctx, const PJ *ellipsoid, * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param obj Objet of type CRS or GeodeticReferenceFrame (must not be NULL) + * @param obj Object of type CRS or GeodeticReferenceFrame (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error. */ @@ -1693,7 +1693,7 @@ int proj_prime_meridian_get_parameters(PJ_CONTEXT *ctx, * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param obj Objet of type BoundCRS or CoordinateOperation (must not be NULL) + * @param obj Object of type BoundCRS or CoordinateOperation (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error, or missing source CRS. */ @@ -1736,7 +1736,7 @@ PJ *proj_get_source_crs(PJ_CONTEXT *ctx, const PJ *obj) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param obj Objet of type BoundCRS or CoordinateOperation (must not be NULL) + * @param obj Object of type BoundCRS or CoordinateOperation (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error, or missing target CRS. */ @@ -2140,7 +2140,7 @@ void proj_crs_info_list_destroy(PROJ_CRS_INFO **list) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type DerivedCRS or BoundCRSs (must not be NULL) + * @param crs Object of type DerivedCRS or BoundCRSs (must not be NULL) * @return Object of type SingleOperation that must be unreferenced with * proj_destroy(), or NULL in case of error. */ @@ -2171,7 +2171,7 @@ PJ *proj_crs_get_coordoperation(PJ_CONTEXT *ctx, const PJ *crs) { /** \brief Return information on the operation method of the SingleOperation. * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type SingleOperation (typically a Conversion + * @param coordoperation Object of type SingleOperation (typically a Conversion * or Transformation) (must not be NULL) * @param out_method_name Pointer to a string value to store the method * (projection) name. or NULL @@ -5702,7 +5702,7 @@ PJ *proj_create_conversion_equal_earth(PJ_CONTEXT *ctx, double center_long, * available. * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type CoordinateOperation or derived classes + * @param coordoperation Object of type CoordinateOperation or derived classes * (must not be NULL) * @return TRUE or FALSE. */ @@ -5737,7 +5737,7 @@ int proj_coordoperation_is_instantiable(PJ_CONTEXT *ctx, * compared to more accurate transformations. * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type CoordinateOperation or derived classes + * @param coordoperation Object of type CoordinateOperation or derived classes * (must not be NULL) * @return TRUE or FALSE. */ @@ -5760,7 +5760,7 @@ int proj_coordoperation_has_ballpark_transformation(PJ_CONTEXT *ctx, /** \brief Return the number of parameters of a SingleOperation * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type SingleOperation or derived classes + * @param coordoperation Object of type SingleOperation or derived classes * (must not be NULL) */ @@ -5782,7 +5782,7 @@ int proj_coordoperation_get_param_count(PJ_CONTEXT *ctx, /** \brief Return the index of a parameter of a SingleOperation * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type SingleOperation or derived classes + * @param coordoperation Object of type SingleOperation or derived classes * (must not be NULL) * @param name Parameter name. Must not be NULL * @return index (>=0), or -1 in case of error. @@ -5815,7 +5815,7 @@ int proj_coordoperation_get_param_index(PJ_CONTEXT *ctx, /** \brief Return a parameter of a SingleOperation * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type SingleOperation or derived classes + * @param coordoperation Object of type SingleOperation or derived classes * (must not be NULL) * @param index Parameter index. * @param out_name Pointer to a string value to store the parameter name. or @@ -5955,7 +5955,7 @@ int proj_coordoperation_get_param( * values. * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type Transformation, that can be represented + * @param coordoperation Object of type Transformation, that can be represented * as a WKT1 TOWGS84 node (must not be NULL) * @param out_values Pointer to an array of value_count double values. * @param value_count Size of out_values array. @@ -6000,7 +6000,7 @@ int proj_coordoperation_get_towgs84_values(PJ_CONTEXT *ctx, /** \brief Return the number of grids used by a CoordinateOperation * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type CoordinateOperation or derived classes + * @param coordoperation Object of type CoordinateOperation or derived classes * (must not be NULL) */ @@ -6036,7 +6036,7 @@ int proj_coordoperation_get_grid_used_count(PJ_CONTEXT *ctx, /** \brief Return a parameter of a SingleOperation * * @param ctx PROJ context, or NULL for default context - * @param coordoperation Objet of type SingleOperation or derived classes + * @param coordoperation Object of type SingleOperation or derived classes * (must not be NULL) * @param index Parameter index. * @param out_short_name Pointer to a string value to store the grid short name. @@ -6511,7 +6511,7 @@ proj_create_operations(PJ_CONTEXT *ctx, const PJ *source_crs, /** \brief Return the number of objects in the result set * - * @param result Objet of type PJ_OBJ_LIST (must not be NULL) + * @param result Object of type PJ_OBJ_LIST (must not be NULL) */ int proj_list_get_count(const PJ_OBJ_LIST *result) { assert(result); @@ -6527,7 +6527,7 @@ int proj_list_get_count(const PJ_OBJ_LIST *result) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param result Objet of type PJ_OBJ_LIST (must not be NULL) + * @param result Object of type PJ_OBJ_LIST (must not be NULL) * @param index Index * @return a new object that must be unreferenced with proj_destroy(), * or nullptr in case of error. @@ -6593,7 +6593,7 @@ double proj_coordoperation_get_accuracy(PJ_CONTEXT *ctx, * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type SingleCRS (must not be NULL) + * @param crs Object of type SingleCRS (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error (or if there is no datum) */ @@ -6621,7 +6621,7 @@ PJ *proj_crs_get_datum(PJ_CONTEXT *ctx, const PJ *crs) { * It should be used by at most one thread at a time. * * @param ctx PROJ context, or NULL for default context - * @param crs Objet of type SingleCRS (must not be NULL) + * @param crs Object of type SingleCRS (must not be NULL) * @return Object that must be unreferenced with proj_destroy(), or NULL * in case of error. */ @@ -6641,7 +6641,7 @@ PJ *proj_crs_get_coordinate_system(PJ_CONTEXT *ctx, const PJ *crs) { /** \brief Returns the type of the coordinate system. * * @param ctx PROJ context, or NULL for default context - * @param cs Objet of type CoordinateSystem (must not be NULL) + * @param cs Object of type CoordinateSystem (must not be NULL) * @return type, or PJ_CS_TYPE_UNKNOWN in case of error. */ PJ_COORDINATE_SYSTEM_TYPE proj_cs_get_type(PJ_CONTEXT *ctx, const PJ *cs) { @@ -6687,7 +6687,7 @@ PJ_COORDINATE_SYSTEM_TYPE proj_cs_get_type(PJ_CONTEXT *ctx, const PJ *cs) { /** \brief Returns the number of axis of the coordinate system. * * @param ctx PROJ context, or NULL for default context - * @param cs Objet of type CoordinateSystem (must not be NULL) + * @param cs Object of type CoordinateSystem (must not be NULL) * @return number of axis, or -1 in case of error. */ int proj_cs_get_axis_count(PJ_CONTEXT *ctx, const PJ *cs) { @@ -6706,7 +6706,7 @@ int proj_cs_get_axis_count(PJ_CONTEXT *ctx, const PJ *cs) { /** \brief Returns information on an axis * * @param ctx PROJ context, or NULL for default context - * @param cs Objet of type CoordinateSystem (must not be NULL) + * @param cs Object of type CoordinateSystem (must not be NULL) * @param index Index of the coordinate system (between 0 and * proj_cs_get_axis_count() - 1) * @param out_name Pointer to a string value to store the axis name. or NULL diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 502f30e6..03fb6977 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4510,7 +4510,7 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, * "urn:ogc:def:coordinateOperation:EPSG::1671", * "urn:ogc:def:ellipsoid:EPSG::7001" * or "urn:ogc:def:datum:EPSG::6326" - *
    • an objet name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as + *
    • an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
    • *
    @@ -4546,7 +4546,7 @@ BaseObjectNNPtr createFromUserInput(const std::string &text, * "urn:ogc:def:coordinateOperation:EPSG::1671", * "urn:ogc:def:ellipsoid:EPSG::7001" * or "urn:ogc:def:datum:EPSG::6326" - *
  • an objet name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as + *
  • an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
  • * -- cgit v1.2.3 From 5cad2f68f2a68c8c6854d0bfc62700299598dfa1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 27 Mar 2019 18:55:35 +0100 Subject: ocea: fix behaviour when +alpha is specified The one-point case was completely broken with lat_0 being ignored. I've fixed that, and also modified the alpha orientation, so that the angle corresponds to the one of the 2 point case when going from point 1 to point 2, similarly to what omerc does. This was found rather experimentaly with the added test cases that try to find equivalence between 1-point and 2-point cases. Fixes #1379 and adresses https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13930 --- src/projections/ocea.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp index 4e28f727..3141dd11 100644 --- a/src/projections/ocea.cpp +++ b/src/projections/ocea.cpp @@ -50,7 +50,7 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(ocea) { - double phi_0=0.0, phi_1, phi_2, lam_1, lam_2, lonz, alpha; + double phi_1, phi_2, lam_1, lam_2, lonz, alpha; struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) @@ -63,12 +63,17 @@ PJ *PROJECTION(ocea) { /*If the keyword "alpha" is found in the sentence then use 1point+1azimuth*/ if ( pj_param(P->ctx, P->params, "talpha").i) { /*Define Pole of oblique transformation from 1 point & 1 azimuth*/ - alpha = pj_param(P->ctx, P->params, "ralpha").f; + // ERO: I've added M_PI so that the alpha is the angle from point 1 to point 2 + // from the North in a clockwise direction + // (to be consistent with omerc behaviour) + alpha = M_PI + pj_param(P->ctx, P->params, "ralpha").f; lonz = pj_param(P->ctx, P->params, "rlonc").f; /*Equation 9-8 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - lam_p = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz; + // Actually slightliy modified to use atan2(), as it is suggested by + // Snyder for equation 9-1, but this is not mentionned here + lam_p = atan2(-cos(alpha) , -sin(P->phi0) * sin(alpha)) + lonz; /*Equation 9-7 page 80 (http://pubs.usgs.gov/pp/1395/report.pdf)*/ - phi_p = asin(cos(phi_0) * sin(alpha)); + phi_p = asin(cos(P->phi0) * sin(alpha)); /*If the keyword "alpha" is NOT found in the sentence then use 2points*/ } else { /*Define Pole of oblique transformation from 2 points*/ -- cgit v1.2.3 From 5893c7ddef817df0c42c7ee636e6e083b0c65aed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 28 Mar 2019 17:33:26 +0100 Subject: createOperations(): improve BoundCRS<-->non-bound-CRS case Fixes #1388 Typically helps for projinfo -s "+proj=longlat +ellps=GRS80 +towgs84=1,2,3 +type=crs" -t EPSG:4258 by researching operations from the pivot WGS84 implied by the towgs84 clause to EPSG:4258. --- src/iso19111/coordinateoperation.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 1abb74b3..043d09bc 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11689,7 +11689,6 @@ CoordinateOperationFactory::Private::createOperations( return applyInverse(createOperations(targetCRS, sourceCRS, context)); } - // boundCRS to a geogCRS that is the same as the hubCRS auto boundSrc = dynamic_cast(sourceCRS.get()); auto geogDst = dynamic_cast(targetCRS.get()); if (boundSrc && geogDst) { @@ -11698,6 +11697,7 @@ CoordinateOperationFactory::Private::createOperations( dynamic_cast(hubSrc.get()); auto geogCRSOfBaseOfBoundSrc = boundSrc->baseCRS()->extractGeographicCRS(); + // Is it: boundCRS to a geogCRS that is the same as the hubCRS ? if (hubSrcGeog && geogCRSOfBaseOfBoundSrc && (hubSrcGeog->_isEquivalentTo( geogDst, util::IComparable::Criterion::EQUIVALENT) || @@ -11815,6 +11815,35 @@ CoordinateOperationFactory::Private::createOperations( return res; } + if (hubSrcGeog && geogCRSOfBaseOfBoundSrc) { + // This one should go to the above 'Is it: boundCRS to a geogCRS + // that is the same as the hubCRS ?' case + auto opsFirst = createOperations(sourceCRS, hubSrc, context); + auto opsLast = createOperations(hubSrc, targetCRS, context); + if (!opsFirst.empty() && !opsLast.empty()) { + for (const auto &opFirst : opsFirst) { + for (const auto &opLast : opsLast) { + // Exclude artificial transformations from the hub + // to the target CRS + if (!opLast->hasBallparkTransformation()) { + try { + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {opFirst, opLast}, + !allowEmptyIntersection)); + } catch ( + const InvalidOperationEmptyIntersection &) { + } + } + } + } + if (!res.empty()) { + return res; + } + } + } + return createOperations(boundSrc->baseCRS(), targetCRS, context); } -- cgit v1.2.3 From 3d670b859026218045cf972e4b38af9e3e9a3c6f Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 28 Mar 2019 20:52:33 +0100 Subject: Add no-op operation. It does nothing. --- src/Makefile.am | 1 + src/conversions/noop.cpp | 19 +++++++++++++++++++ src/lib_proj.cmake | 1 + src/pj_list.h | 1 + 4 files changed, 22 insertions(+) create mode 100644 src/conversions/noop.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index b62a11b0..9858d78f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -173,6 +173,7 @@ libproj_la_SOURCES = \ conversions/cart.cpp \ conversions/geoc.cpp \ conversions/geocent.cpp \ + conversions/noop.cpp \ conversions/unitconvert.cpp \ \ transformations/affine.cpp \ diff --git a/src/conversions/noop.cpp b/src/conversions/noop.cpp new file mode 100644 index 00000000..a5dd6023 --- /dev/null +++ b/src/conversions/noop.cpp @@ -0,0 +1,19 @@ +#define PJ_LIB__ + +#include "proj_internal.h" + +PROJ_HEAD(noop, "No operation"); + +static PJ_COORD noop(PJ_COORD coord, PJ *P) { + (void) P; + return coord; +} + +PJ *CONVERSION(noop, 0) { + P->fwd4d = noop; + P->inv4d = noop; + P->left = PJ_IO_UNITS_WHATEVER; + P->right = PJ_IO_UNITS_WHATEVER; + return P; +} + diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 72a8cc59..38bc05d8 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -174,6 +174,7 @@ set(SRC_LIBPROJ_CONVERSIONS conversions/cart.cpp conversions/geoc.cpp conversions/geocent.cpp + conversions/noop.cpp conversions/unitconvert.cpp ) diff --git a/src/pj_list.h b/src/pj_list.h index 8ab4cdc0..0923bba8 100644 --- a/src/pj_list.h +++ b/src/pj_list.h @@ -106,6 +106,7 @@ PROJ_HEAD(nell_h, "Nell-Hammer") PROJ_HEAD(nicol, "Nicolosi Globular") PROJ_HEAD(nsper, "Near-sided perspective") PROJ_HEAD(nzmg, "New Zealand Map Grid") +PROJ_HEAD(noop, "No operation") PROJ_HEAD(ob_tran, "General Oblique Transformation") PROJ_HEAD(ocea, "Oblique Cylindrical Equal Area") PROJ_HEAD(oea, "Oblated Equal Area") -- cgit v1.2.3 From 6a7e24dce79f93b73f4919f267df2fdf3ee95713 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 28 Mar 2019 15:26:00 +0100 Subject: Add proj_normalize_for_visualization() Fixes #1301 This function takes the output PJ from proj_create_crs_to_crs(), and add (or undo) the needed axis swap operations so that the object returned by proj_normalize_for_visualization() has the usual GIS axis order. In this implementation, this does something only if the coordinate system of the source or target CRS, geographic or projected, has NORTH, EAST ordering. CompoundCRS wrapping those objects are also handled. --- src/iso19111/c_api.cpp | 32 ++++++++++++ src/iso19111/coordinateoperation.cpp | 40 +++++++++++++++ src/iso19111/crs.cpp | 98 ++++++++++++++++++++++++++++++++++++ src/proj.h | 1 + 4 files changed, 171 insertions(+) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index e62d3f56..1f4cecde 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -6767,3 +6767,35 @@ int proj_cs_get_axis_info(PJ_CONTEXT *ctx, const PJ *cs, int index, } return true; } + +// --------------------------------------------------------------------------- + +/** \brief Returns a PJ* object whose axis order is the one expected for + * visualization purposes. + * + * The input object must be a coordinate operation, that has been created with + * proj_create_crs_to_crs(). + * If the axis order of its source or target CRS is northing,easting, then an + * axis swap operation will be inserted. + * + * @param ctx PROJ context, or NULL for default context + * @param obj Object of type CoordinateOperation, + * created with proj_create_crs_to_crs() (must not be NULL) + * @return a new PJ* object to free with proj_destroy() in case of success, or + * nullptr in case of error + */ +PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) { + auto co = dynamic_cast(obj->iso_obj.get()); + if (!co) { + proj_log_error(ctx, __FUNCTION__, "Object is not a CoordinateOperation " + "created with " + "proj_create_crs_to_crs"); + return nullptr; + } + try { + return pj_obj_create(ctx, co->normalizeForVisualization()); + } catch (const std::exception &e) { + proj_log_debug(ctx, __FUNCTION__, e.what()); + return nullptr; + } +} diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 1abb74b3..58e97272 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -765,6 +765,46 @@ void CoordinateOperation::setProperties( // --------------------------------------------------------------------------- +/** \brief Return a variation of the current coordinate operation whose axis + * order is the one expected for visualization purposes. + */ +CoordinateOperationNNPtr +CoordinateOperation::normalizeForVisualization() const { + auto l_sourceCRS = sourceCRS(); + auto l_targetCRS = targetCRS(); + if (!l_sourceCRS || !l_targetCRS) { + throw util::UnsupportedOperationException( + "Cannot retrieve source or target CRS"); + } + const bool swapSource = + l_sourceCRS->mustAxisOrderBeSwitchedForVisualization(); + const bool swapTarget = + l_targetCRS->mustAxisOrderBeSwitchedForVisualization(); + auto l_this = NN_NO_CHECK(std::dynamic_pointer_cast( + shared_from_this().as_nullable())); + if (!swapSource && !swapTarget) { + return l_this; + } + std::vector subOps; + if (swapSource) { + auto op = Conversion::createAxisOrderReversal(false); + op->setCRSs(l_sourceCRS->normalizeForVisualization(), + NN_NO_CHECK(l_sourceCRS), nullptr); + subOps.emplace_back(op); + } + subOps.emplace_back(l_this); + if (swapTarget) { + auto op = Conversion::createAxisOrderReversal(false); + op->setCRSs(NN_NO_CHECK(l_targetCRS), + l_targetCRS->normalizeForVisualization(), nullptr); + subOps.emplace_back(op); + } + return util::nn_static_pointer_cast( + ConcatenatedOperation::createComputeMetadata(subOps, true)); +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress struct OperationMethod::Private { util::optional formula_{}; diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index b51d03c9..1ef7dcda 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -591,6 +591,104 @@ CRSNNPtr CRS::alterId(const std::string &authName, // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress + +static bool isAxisListNorthEast( + const std::vector &axisList) { + const auto &dir0 = axisList[0]->direction(); + const auto &dir1 = axisList[1]->direction(); + return (&dir0 == &cs::AxisDirection::NORTH && + &dir1 == &cs::AxisDirection::EAST); +} +// --------------------------------------------------------------------------- + +bool CRS::mustAxisOrderBeSwitchedForVisualization() const { + + const CompoundCRS *compoundCRS = dynamic_cast(this); + if (compoundCRS) { + const auto &comps = compoundCRS->componentReferenceSystems(); + if (!comps.empty()) { + return comps[0]->mustAxisOrderBeSwitchedForVisualization(); + } + } + + const GeographicCRS *geogCRS = dynamic_cast(this); + if (geogCRS) { + return isAxisListNorthEast(geogCRS->coordinateSystem()->axisList()); + } + + const ProjectedCRS *projCRS = dynamic_cast(this); + if (projCRS) { + return isAxisListNorthEast(projCRS->coordinateSystem()->axisList()); + } + + return false; +} + +//! @endcond + +// --------------------------------------------------------------------------- + +//! @cond Doxygen_Suppress + +CRSNNPtr CRS::normalizeForVisualization() const { + auto props = util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, + nameStr() + " (with axis order normalized for visualization)"); + + const CompoundCRS *compoundCRS = dynamic_cast(this); + if (compoundCRS) { + const auto &comps = compoundCRS->componentReferenceSystems(); + if (!comps.empty()) { + std::vector newComps; + newComps.emplace_back(comps[0]->normalizeForVisualization()); + for (size_t i = 1; i < comps.size(); i++) { + newComps.emplace_back(comps[i]); + } + return util::nn_static_pointer_cast( + CompoundCRS::create(props, newComps)); + } + } + + const GeographicCRS *geogCRS = dynamic_cast(this); + if (geogCRS) { + const auto &axisList = geogCRS->coordinateSystem()->axisList(); + if (isAxisListNorthEast(axisList)) { + auto cs = axisList.size() == 2 + ? cs::EllipsoidalCS::create(util::PropertyMap(), + axisList[1], axisList[0]) + : cs::EllipsoidalCS::create(util::PropertyMap(), + axisList[1], axisList[0], + axisList[2]); + return util::nn_static_pointer_cast(GeographicCRS::create( + props, geogCRS->datum(), geogCRS->datumEnsemble(), cs)); + } + } + + const ProjectedCRS *projCRS = dynamic_cast(this); + if (projCRS) { + const auto &axisList = projCRS->coordinateSystem()->axisList(); + if (isAxisListNorthEast(axisList)) { + auto cs = + axisList.size() == 2 + ? cs::CartesianCS::create(util::PropertyMap(), axisList[1], + axisList[0]) + : cs::CartesianCS::create(util::PropertyMap(), axisList[1], + axisList[0], axisList[2]); + return util::nn_static_pointer_cast( + ProjectedCRS::create(props, projCRS->baseCRS(), + projCRS->derivingConversionRef(), cs)); + } + } + + return NN_NO_CHECK( + std::static_pointer_cast(shared_from_this().as_nullable())); +} + +//! @endcond + +// --------------------------------------------------------------------------- + /** \brief Identify the CRS with reference CRSs. * * The candidate CRSs are either hard-coded, or looked in the database when diff --git a/src/proj.h b/src/proj.h index 6f53bb07..a412f266 100644 --- a/src/proj.h +++ b/src/proj.h @@ -356,6 +356,7 @@ int PROJ_DLL proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_leg PJ PROJ_DLL *proj_create (PJ_CONTEXT *ctx, const char *definition); PJ PROJ_DLL *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv); PJ PROJ_DLL *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area); +PJ PROJ_DLL *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ* obj); PJ PROJ_DLL *proj_destroy (PJ *P); -- cgit v1.2.3 From 47dd4dbc40cbba140f4ceb775ea5d5d628fba961 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 28 Mar 2019 22:12:32 +0100 Subject: Adopt use of the noop conversion in ISO19111 code --- src/iso19111/c_api.cpp | 3 +-- src/iso19111/io.cpp | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index f7dcd354..f6138e9b 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -134,8 +134,7 @@ static PJ *pj_obj_create(PJ_CONTEXT *ctx, const IdentifiedObjectNNPtr &objIn) { auto formatter = PROJStringFormatter::create( PROJStringFormatter::Convention::PROJ_5, dbContext); auto projString = coordop->exportToPROJString(formatter.get()); - auto pj = pj_create_internal( - ctx, projString.empty() ? "+proj=affine" : projString.c_str()); + auto pj = pj_create_internal(ctx, projString.c_str()); if (pj) { pj->iso_obj = objIn; return pj; diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 578234b4..a933dcad 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -5342,6 +5342,11 @@ const std::string &PROJStringFormatter::toString() const { } } } + + if (d->result_.empty()) { + d->appendToResult("+proj=noop"); + } + return d->result_; } -- cgit v1.2.3 From 88f2661c9fd9fbf9d714a184243340cafb64d91d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 29 Mar 2019 13:30:57 +0100 Subject: createOperations(): improve behaviour with input CRS from WKT that lacks intermediate IDs (fixes #1343) --- src/iso19111/coordinateoperation.cpp | 147 ++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 24e5f8ab..15532a89 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11311,16 +11311,37 @@ static bool hasIdentifiers(const CoordinateOperationNNPtr &op) { static std::vector findCandidateGeodCRSForDatum(const io::AuthorityFactoryPtr &authFactory, - const datum::GeodeticReferenceFramePtr &datum) { + const datum::GeodeticReferenceFrame *datum) { std::vector candidates; - for (const auto &id : datum->identifiers()) { - const auto &authName = *(id->codeSpace()); - const auto &code = id->code(); - if (!authName.empty()) { - auto l_candidates = authFactory->createGeodeticCRSFromDatum( - authName, code, std::string()); - for (const auto &candidate : l_candidates) { - candidates.emplace_back(candidate); + assert(datum); + const auto &ids = datum->identifiers(); + const auto &datumName = datum->nameStr(); + if (!ids.empty()) { + for (const auto &id : ids) { + const auto &authName = *(id->codeSpace()); + const auto &code = id->code(); + if (!authName.empty()) { + auto l_candidates = authFactory->createGeodeticCRSFromDatum( + authName, code, std::string()); + for (const auto &candidate : l_candidates) { + candidates.emplace_back(candidate); + } + } + } + } else if (datumName != "unknown" && datumName != "unnamed") { + auto matches = authFactory->createObjectsFromName( + datumName, + {io::AuthorityFactory::ObjectType::GEODETIC_REFERENCE_FRAME}, false, + 2); + if (matches.size() == 1) { + const auto &match = matches.front(); + if (datum->_isEquivalentTo( + match.get(), util::IComparable::Criterion::EQUIVALENT) && + !match->identifiers().empty()) { + return findCandidateGeodCRSForDatum( + authFactory, + dynamic_cast( + match.get())); } } } @@ -11362,9 +11383,9 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( const auto &authFactory = context.context->getAuthorityFactory(); const auto candidatesSrcGeod( - findCandidateGeodCRSForDatum(authFactory, geodSrc->datum())); + findCandidateGeodCRSForDatum(authFactory, geodSrc->datum().get())); const auto candidatesDstGeod( - findCandidateGeodCRSForDatum(authFactory, geodDst->datum())); + findCandidateGeodCRSForDatum(authFactory, geodDst->datum().get())); auto createTransformations = [&](const crs::CRSNNPtr &candidateSrcGeod, const crs::CRSNNPtr &candidateDstGeod, @@ -11605,12 +11626,8 @@ CoordinateOperationFactory::Private::createOperations( // but transformations are only available between their // corresponding geocentric CRS. const auto &srcDatum = geodSrc->datum(); - const bool srcHasDatumWithId = - srcDatum && !srcDatum->identifiers().empty(); const auto &dstDatum = geodDst->datum(); - const bool dstHasDatumWithId = - dstDatum && !dstDatum->identifiers().empty(); - if (srcHasDatumWithId && dstHasDatumWithId && + if (srcDatum != nullptr && dstDatum != nullptr && !srcDatum->_isEquivalentTo( dstDatum.get(), util::IComparable::Criterion::EQUIVALENT)) { createOperationsWithDatumPivot(res, sourceCRS, targetCRS, @@ -11955,6 +11972,31 @@ CoordinateOperationFactory::Private::createOperations( // A bit odd case as we are comparing apples to oranges, but in case // the vertical unit differ, do something useful. if (vertSrc && geogDst) { + + if (vertSrc->identifiers().empty()) { + const auto &authFactory = context.context->getAuthorityFactory(); + const auto &vertSrcName = vertSrc->nameStr(); + if (authFactory != nullptr && vertSrcName != "unnamed" && + vertSrcName != "unknown") { + auto matches = authFactory->createObjectsFromName( + vertSrcName, + {io::AuthorityFactory::ObjectType::VERTICAL_CRS}, false, 2); + if (matches.size() == 1) { + const auto &match = matches.front(); + if (vertSrc->_isEquivalentTo( + match.get(), + util::IComparable::Criterion::EQUIVALENT) && + !match->identifiers().empty()) { + return createOperations( + NN_NO_CHECK( + util::nn_dynamic_pointer_cast( + match)), + targetCRS, context); + } + } + } + } + const double convSrc = vertSrc->coordinateSystem()->axisList()[0]->unit().conversionToSI(); double convDst = 1.0; @@ -12300,6 +12342,67 @@ CoordinateOperationFactory::Private::createOperations( // --------------------------------------------------------------------------- +static crs::CRSNNPtr +getResolvedCRS(const crs::CRSNNPtr &crs, + const CoordinateOperationContextNNPtr &context) { + const auto &authFactory = context->getAuthorityFactory(); + + auto projectedCrs = dynamic_cast(crs.get()); + if (projectedCrs && authFactory) { + const auto &ids = projectedCrs->identifiers(); + if (!ids.empty() && projectedCrs->baseCRS()->identifiers().empty()) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), *ids.front()->codeSpace()); + try { + crs::CRSNNPtr resolvedCrs( + tmpAuthFactory->createProjectedCRS(ids.front()->code())); + if (resolvedCrs->_isEquivalentTo( + crs.get(), util::IComparable::Criterion::EQUIVALENT)) { + return resolvedCrs; + } + } catch (const std::exception &) { + } + } + } + + auto compoundCrs = dynamic_cast(crs.get()); + // If we get a CompoundCRS that has an EPSG code, but whose component CRS + // lack one, typically from WKT2, this might be an issue to get proper + // results in createOperations(), so import the CompoundCRS from the + // registry, and if equivalent to the original one, then use the version + // from the registry. + if (compoundCrs && authFactory) { + const auto &ids = compoundCrs->identifiers(); + if (!ids.empty()) { + const auto &components = compoundCrs->componentReferenceSystems(); + bool hasMissingId = false; + for (const auto &comp : components) { + if (comp->identifiers().empty()) { + hasMissingId = true; + break; + } + } + if (hasMissingId) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), *ids.front()->codeSpace()); + try { + crs::CRSNNPtr resolvedCrs( + tmpAuthFactory->createCompoundCRS(ids.front()->code())); + if (resolvedCrs->_isEquivalentTo( + crs.get(), + util::IComparable::Criterion::EQUIVALENT)) { + return resolvedCrs; + } + } catch (const std::exception &) { + } + } + } + } + return crs; +} + +// --------------------------------------------------------------------------- + /** \brief Find a list of CoordinateOperation from sourceCRS to targetCRS. * * The operations are sorted with the most relevant ones first: by @@ -12328,10 +12431,14 @@ CoordinateOperationFactory::createOperations( auto l_sourceCRS = srcBoundCRS ? NN_NO_CHECK(srcBoundCRS) : sourceCRS; auto l_targetCRS = targetBoundCRS ? NN_NO_CHECK(targetBoundCRS) : targetCRS; - Private::Context contextPrivate(sourceCRS, targetCRS, context); - return filterAndSort( - Private::createOperations(l_sourceCRS, l_targetCRS, contextPrivate), - context, l_sourceCRS, l_targetCRS); + auto l_resolvedSourceCRS = getResolvedCRS(l_sourceCRS, context); + auto l_resolvedTargetCRS = getResolvedCRS(l_targetCRS, context); + Private::Context contextPrivate(l_resolvedSourceCRS, l_resolvedTargetCRS, + context); + return filterAndSort(Private::createOperations(l_resolvedSourceCRS, + l_resolvedTargetCRS, + contextPrivate), + context, l_resolvedSourceCRS, l_resolvedTargetCRS); } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 095d2204f8bb05d172936aebbb1e9e44852c049f Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Fri, 29 Mar 2019 19:17:37 +0000 Subject: Remove duplicate instances of #include "proj_internal.h" Introduced by "Merge projects.h into proj_internal.h" 8ab6f683. --- src/apply_gridshift.cpp | 1 - src/apply_vgridshift.cpp | 1 - src/apps/cct.cpp | 1 - src/apps/gie.cpp | 1 - src/conversions/axisswap.cpp | 1 - src/conversions/cart.cpp | 1 - src/conversions/geoc.cpp | 1 - src/conversions/unitconvert.cpp | 1 - src/ell_set.cpp | 1 - src/factors.cpp | 1 - src/fwd.cpp | 1 - src/gridinfo.cpp | 1 - src/init.cpp | 1 - src/inv.cpp | 1 - src/nad_intr.cpp | 3 +-- src/pipeline.cpp | 1 - src/projections/bertin1953.cpp | 1 - src/projections/healpix.cpp | 1 - src/projections/isea.cpp | 3 +-- src/projections/latlong.cpp | 1 - src/projections/merc.cpp | 3 +-- src/projections/ortho.cpp | 1 - src/projections/robin.cpp | 3 +-- src/projections/tobmerc.cpp | 3 +-- src/transformations/deformation.cpp | 1 - src/transformations/helmert.cpp | 1 - src/transformations/hgridshift.cpp | 1 - src/transformations/horner.cpp | 1 - src/transformations/molodensky.cpp | 1 - src/transformations/vgridshift.cpp | 1 - 30 files changed, 5 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/apply_gridshift.cpp b/src/apply_gridshift.cpp index d9b5286d..fcd9fa01 100644 --- a/src/apply_gridshift.cpp +++ b/src/apply_gridshift.cpp @@ -34,7 +34,6 @@ #include #include -#include "proj_internal.h" #include "proj.h" #include "proj_internal.h" diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index 9be65f08..e73c6da7 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -33,7 +33,6 @@ #include "proj_math.h" #include "proj_internal.h" -#include "proj_internal.h" static int is_nodata(float value, double vmultiplier) { diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 65718aca..d29b58fb 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -81,7 +81,6 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 #include "proj.h" #include "proj_internal.h" #include "proj_strtod.h" -#include "proj_internal.h" #include "optargpm.h" diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index a84e77ab..47211aa8 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -117,7 +117,6 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-10-01/2017-10-08 #include "proj_internal.h" #include "proj_math.h" #include "proj_strtod.h" -#include "proj_internal.h" #include "optargpm.h" diff --git a/src/conversions/axisswap.cpp b/src/conversions/axisswap.cpp index 97c8899a..15ec016b 100644 --- a/src/conversions/axisswap.cpp +++ b/src/conversions/axisswap.cpp @@ -59,7 +59,6 @@ operation: #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(axisswap, "Axis ordering"); diff --git a/src/conversions/cart.cpp b/src/conversions/cart.cpp index d9aea9b8..e6942d65 100644 --- a/src/conversions/cart.cpp +++ b/src/conversions/cart.cpp @@ -42,7 +42,6 @@ #define PJ_LIB__ -#include "proj_internal.h" #include "proj_internal.h" #include "proj_math.h" diff --git a/src/conversions/geoc.cpp b/src/conversions/geoc.cpp index e0ca3df3..3d86b531 100644 --- a/src/conversions/geoc.cpp +++ b/src/conversions/geoc.cpp @@ -32,7 +32,6 @@ #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(geoc, "Geocentric Latitude"); diff --git a/src/conversions/unitconvert.cpp b/src/conversions/unitconvert.cpp index 1e3372d6..e436a222 100644 --- a/src/conversions/unitconvert.cpp +++ b/src/conversions/unitconvert.cpp @@ -72,7 +72,6 @@ Last update: 2017-05-16 #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" PROJ_HEAD(unitconvert, "Unit conversion"); diff --git a/src/ell_set.cpp b/src/ell_set.cpp index d0714bee..c0b9016d 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -6,7 +6,6 @@ #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" /* Prototypes of the pj_ellipsoid helper functions */ diff --git a/src/factors.cpp b/src/factors.cpp index f50c8e21..7c59ee7a 100644 --- a/src/factors.cpp +++ b/src/factors.cpp @@ -3,7 +3,6 @@ #include "proj.h" #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" #include diff --git a/src/fwd.cpp b/src/fwd.cpp index a8c51934..c267045a 100644 --- a/src/fwd.cpp +++ b/src/fwd.cpp @@ -33,7 +33,6 @@ #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" #define INPUT_UNITS P->left #define OUTPUT_UNITS P->right diff --git a/src/gridinfo.cpp b/src/gridinfo.cpp index bff487f5..7f7d930f 100644 --- a/src/gridinfo.cpp +++ b/src/gridinfo.cpp @@ -35,7 +35,6 @@ #include #include -#include "proj_internal.h" #include "proj_internal.h" /************************************************************************/ diff --git a/src/init.cpp b/src/init.cpp index 1c0eddf0..cfcba96f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -40,7 +40,6 @@ #include "proj.h" #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" /**************************************************************************************/ diff --git a/src/inv.cpp b/src/inv.cpp index a05f8376..b9520c53 100644 --- a/src/inv.cpp +++ b/src/inv.cpp @@ -32,7 +32,6 @@ #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" #define INPUT_UNITS P->right #define OUTPUT_UNITS P->left diff --git a/src/nad_intr.cpp b/src/nad_intr.cpp index 2c301ef8..8dc2f652 100644 --- a/src/nad_intr.cpp +++ b/src/nad_intr.cpp @@ -1,9 +1,8 @@ /* Determine nad table correction value */ #define PJ_LIB__ -#include "proj_internal.h" -#include "proj_math.h" #include "proj.h" #include "proj_internal.h" +#include "proj_math.h" PJ_LP nad_intr(PJ_LP t, struct CTABLE *ct) { PJ_LP val, frct; diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 39563c65..afa3b19a 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -105,7 +105,6 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-20 #include "geodesic.h" #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(pipeline, "Transformation pipeline manager"); PROJ_HEAD(pop, "Retrieve coordinate value from pipeline stack"); diff --git a/src/projections/bertin1953.cpp b/src/projections/bertin1953.cpp index 96de6d4b..add9f0b3 100644 --- a/src/projections/bertin1953.cpp +++ b/src/projections/bertin1953.cpp @@ -14,7 +14,6 @@ #include #include -#include "proj_internal.h" #include "proj.h" #include "proj_internal.h" diff --git a/src/projections/healpix.cpp b/src/projections/healpix.cpp index 8e4846ed..e9924e04 100644 --- a/src/projections/healpix.cpp +++ b/src/projections/healpix.cpp @@ -33,7 +33,6 @@ #include #include -#include "proj_internal.h" #include "proj.h" #include "proj_internal.h" diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index 18b1cf55..28510cb0 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -13,10 +13,9 @@ #include #define PJ_LIB__ -#include "proj_internal.h" -#include "proj_math.h" #include "proj.h" #include "proj_internal.h" +#include "proj_math.h" #define DEG36 0.62831853071795864768 #define DEG72 1.25663706143591729537 diff --git a/src/projections/latlong.cpp b/src/projections/latlong.cpp index 970c4893..2c98a4cd 100644 --- a/src/projections/latlong.cpp +++ b/src/projections/latlong.cpp @@ -30,7 +30,6 @@ /* very loosely based upon DMA code by Bradford W. Drew */ #define PJ_LIB__ #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(lonlat, "Lat/long (Geodetic)") "\n\t"; PROJ_HEAD(latlon, "Lat/long (Geodetic alias)") "\n\t"; diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index 5b65de90..4975b6c5 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -3,10 +3,9 @@ #include #include -#include "proj_internal.h" #include "proj.h" -#include "proj_math.h" #include "proj_internal.h" +#include "proj_math.h" PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts="; PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t"; diff --git a/src/projections/ortho.cpp b/src/projections/ortho.cpp index d4300bd5..eda325fe 100644 --- a/src/projections/ortho.cpp +++ b/src/projections/ortho.cpp @@ -3,7 +3,6 @@ #include "proj.h" #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" PROJ_HEAD(ortho, "Orthographic") "\n\tAzi, Sph"; diff --git a/src/projections/robin.cpp b/src/projections/robin.cpp index 9f7908f6..dfb750dd 100644 --- a/src/projections/robin.cpp +++ b/src/projections/robin.cpp @@ -1,8 +1,7 @@ #define PJ_LIB__ -#include "proj_math.h" -#include "proj_internal.h" #include "proj.h" #include "proj_internal.h" +#include "proj_math.h" PROJ_HEAD(robin, "Robinson") "\n\tPCyl, Sph"; diff --git a/src/projections/tobmerc.cpp b/src/projections/tobmerc.cpp index 95960097..126d6be2 100644 --- a/src/projections/tobmerc.cpp +++ b/src/projections/tobmerc.cpp @@ -3,10 +3,9 @@ #include #include -#include "proj_internal.h" #include "proj.h" -#include "proj_math.h" #include "proj_internal.h" +#include "proj_math.h" PROJ_HEAD(tobmerc, "Tobler-Mercator") "\n\tCyl, Sph"; diff --git a/src/transformations/deformation.cpp b/src/transformations/deformation.cpp index 0e0d641c..5bb86909 100644 --- a/src/transformations/deformation.cpp +++ b/src/transformations/deformation.cpp @@ -56,7 +56,6 @@ grid-values in units of mm/year in ENU-space. #include "proj.h" #include "proj_internal.h" #include "proj_math.h" -#include "proj_internal.h" PROJ_HEAD(deformation, "Kinematic grid shift"); diff --git a/src/transformations/helmert.cpp b/src/transformations/helmert.cpp index c00fad2f..63785ea5 100644 --- a/src/transformations/helmert.cpp +++ b/src/transformations/helmert.cpp @@ -52,7 +52,6 @@ Last update: 2018-10-26 #include #include -#include "proj_internal.h" #include "proj_internal.h" #include "geocent.h" diff --git a/src/transformations/hgridshift.cpp b/src/transformations/hgridshift.cpp index 2e2294cb..90633939 100644 --- a/src/transformations/hgridshift.cpp +++ b/src/transformations/hgridshift.cpp @@ -5,7 +5,6 @@ #include #include -#include "proj_internal.h" #include "proj_internal.h" PROJ_HEAD(hgridshift, "Horizontal grid shift"); diff --git a/src/transformations/horner.cpp b/src/transformations/horner.cpp index f5d749c4..a6638773 100644 --- a/src/transformations/horner.cpp +++ b/src/transformations/horner.cpp @@ -85,7 +85,6 @@ #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(horner, "Horner polynomial evaluation"); diff --git a/src/transformations/molodensky.cpp b/src/transformations/molodensky.cpp index 289c321e..7d17f64c 100644 --- a/src/transformations/molodensky.cpp +++ b/src/transformations/molodensky.cpp @@ -49,7 +49,6 @@ #include "proj.h" #include "proj_internal.h" -#include "proj_internal.h" PROJ_HEAD(molodensky, "Molodensky transform"); diff --git a/src/transformations/vgridshift.cpp b/src/transformations/vgridshift.cpp index 4cd48fb6..de0cdd8c 100644 --- a/src/transformations/vgridshift.cpp +++ b/src/transformations/vgridshift.cpp @@ -5,7 +5,6 @@ #include #include -#include "proj_internal.h" #include "proj_internal.h" PROJ_HEAD(vgridshift, "Vertical grid shift"); -- cgit v1.2.3 From 884da6cc0a2d9e85927fe30ba90d535db9d65317 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 29 Mar 2019 22:45:01 +0100 Subject: unitconvert: prevent division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13947 Credit to OSS Fuzz --- src/conversions/unitconvert.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/conversions/unitconvert.cpp b/src/conversions/unitconvert.cpp index 1e3372d6..d7edea55 100644 --- a/src/conversions/unitconvert.cpp +++ b/src/conversions/unitconvert.cpp @@ -473,11 +473,11 @@ PJ *CONVERSION(unitconvert,0) { if (f != 0.0) { proj_log_debug(P, "xy_in unit: %s", normalized_name); } else { - if ( (f = pj_param (P->ctx, P->params, "dxy_in").f) == 0.0) + f = pj_param (P->ctx, P->params, "dxy_in").f; + if (f == 0.0 || 1.0 / f == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); } - if (f != 0.0) - Q->xy_factor *= f; + Q->xy_factor = f; if (normalized_name != nullptr && strcmp(normalized_name, "Radian") == 0) P->left = PJ_IO_UNITS_RADIANS; } @@ -488,11 +488,11 @@ PJ *CONVERSION(unitconvert,0) { if (f != 0.0) { proj_log_debug(P, "xy_out unit: %s", normalized_name); } else { - if ( (f = pj_param (P->ctx, P->params, "dxy_out").f) == 0.0) + f = pj_param (P->ctx, P->params, "dxy_out").f; + if (f == 0.0 || 1.0 / f == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); } - if (f != 0.0) - Q->xy_factor /= f; + Q->xy_factor /= f; if (normalized_name != nullptr && strcmp(normalized_name, "Radian") == 0) P->right= PJ_IO_UNITS_RADIANS; } @@ -509,11 +509,11 @@ PJ *CONVERSION(unitconvert,0) { if (f != 0.0) { proj_log_debug(P, "z_in unit: %s", normalized_name); } else { - if ( (f = pj_param (P->ctx, P->params, "dz_in").f) == 0.0) + f = pj_param (P->ctx, P->params, "dz_in").f; + if (f == 0.0 || 1.0 / f == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); } - if (f != 0.0) - Q->z_factor *= f; + Q->z_factor = f; } if ((name = pj_param (P->ctx, P->params, "sz_out").s) != nullptr) { @@ -522,11 +522,11 @@ PJ *CONVERSION(unitconvert,0) { if (f != 0.0) { proj_log_debug(P, "z_out unit: %s", normalized_name); } else { - if ( (f = pj_param (P->ctx, P->params, "dz_out").f) == 0.0) + f = pj_param (P->ctx, P->params, "dz_out").f; + if (f == 0.0 || 1.0 / f == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); } - if (f != 0.0) - Q->z_factor /= f; + Q->z_factor /= f; } if( z_in_is_linear >= 0 && z_out_is_linear >= 0 && -- cgit v1.2.3 From ff1e495525969352f83507950dd4e1fd3cec69c2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 29 Mar 2019 23:09:16 +0100 Subject: tpeqd: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13948 Credit to OSS Fuzz --- src/projections/tpeqd.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/tpeqd.cpp b/src/projections/tpeqd.cpp index 20921de4..9904bb8c 100644 --- a/src/projections/tpeqd.cpp +++ b/src/projections/tpeqd.cpp @@ -87,6 +87,10 @@ PJ *PROJECTION(tpeqd) { Q->sc = Q->sp1 * Q->cp2; Q->ccs = Q->cp1 * Q->cp2 * sin(Q->dlam2); Q->z02 = aacos(P->ctx, Q->sp1 * Q->sp2 + Q->cp1 * Q->cp2 * cos (Q->dlam2)); + if( Q->z02 == 0.0 ) { + // Actually happens when both lat_1 = lat_2 and |lat_1| = 90 + return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + } Q->hz0 = .5 * Q->z02; A12 = atan2(Q->cp2 * sin (Q->dlam2), Q->cp1 * Q->sp2 - Q->sp1 * Q->cp2 * cos (Q->dlam2)); -- cgit v1.2.3 From 6ae93423b74cee676e356e7f9e0a72725f61b5b6 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Sat, 30 Mar 2019 19:30:28 +0000 Subject: affine: remove duplicate #include "proj_internal.h" Introduced by "Merge projects.h into proj_internal.h" 8ab6f68. --- src/transformations/affine.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/transformations/affine.cpp b/src/transformations/affine.cpp index bda54f1e..28f73b9a 100644 --- a/src/transformations/affine.cpp +++ b/src/transformations/affine.cpp @@ -25,7 +25,6 @@ #include #include -#include "proj_internal.h" #include "proj.h" #include "proj_internal.h" -- cgit v1.2.3 From 530913a5517fea6d23daecdb6b4d8d62fcb0a9cc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 1 Apr 2019 22:05:22 +0200 Subject: pj_gauss_ini(): fix division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14003 Credit to OSS Fuzz --- src/gauss.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gauss.cpp b/src/gauss.cpp index 49ccfa1c..a34a8f5b 100644 --- a/src/gauss.cpp +++ b/src/gauss.cpp @@ -65,13 +65,18 @@ void *pj_gauss_ini(double e, double phi0, double *chi, double *rc) { } *chi = asin(sphi / en->C); en->ratexp = 0.5 * en->C * e; + double srat_val = srat(en->e * sphi, en->ratexp); + if (srat_val == 0.0) { + free(en); + return nullptr; + } if( .5 * phi0 + M_FORTPI < 1e-10 ) { - en->K = 1.0 / srat(en->e * sphi, en->ratexp); + en->K = 1.0 / srat_val; } else { en->K = tan(.5 * *chi + M_FORTPI) / ( pow(tan(.5 * phi0 + M_FORTPI), en->C) * - srat(en->e * sphi, en->ratexp) ); + srat_val ); } return ((void *)en); } -- cgit v1.2.3 From d3eada4ec2a1b825aaacc1e3ad9fc1cd4da09ee5 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 1 Apr 2019 22:18:18 +0200 Subject: bonne: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14010 Credit to OSS Fuzz --- src/projections/bonne.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/projections/bonne.cpp b/src/projections/bonne.cpp index 0e9bae79..289eb23d 100644 --- a/src/projections/bonne.cpp +++ b/src/projections/bonne.cpp @@ -26,9 +26,14 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ double rh, E, c; rh = Q->am1 + Q->m1 - pj_mlfn(lp.phi, E = sin(lp.phi), c = cos(lp.phi), Q->en); - E = c * lp.lam / (rh * sqrt(1. - P->es * E * E)); - xy.x = rh * sin(E); - xy.y = Q->am1 - rh * cos(E); + if (fabs(rh) > EPS10) { + E = c * lp.lam / (rh * sqrt(1. - P->es * E * E)); + xy.x = rh * sin(E); + xy.y = Q->am1 - rh * cos(E); + } else { + xy.x = 0.; + xy.y = 0.; + } return xy; } -- cgit v1.2.3 From e31cd44d2b53a6dae71fd767f41ea5823f0612a9 Mon Sep 17 00:00:00 2001 From: snowman2 Date: Sun, 31 Mar 2019 23:11:28 -0500 Subject: paths set by user take priority over PROJ_LIB for search paths --- src/open_lib.cpp | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/open_lib.cpp b/src/open_lib.cpp index a00d3d0e..68477996 100644 --- a/src/open_lib.cpp +++ b/src/open_lib.cpp @@ -200,9 +200,24 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, else if( ctx->file_finder_legacy != nullptr && (sysname = ctx->file_finder_legacy( name )) != nullptr ) ; - /* or is environment PROJ_LIB defined */ + /* The user has search paths set */ + else if( !ctx->search_paths.empty() ) { + for( const auto& path: ctx->search_paths ) { + try { + fname = path; + fname += DIR_CHAR; + fname += name; + sysname = fname.c_str(); + fid = pj_ctx_fopen(ctx, sysname, mode); + } catch( const std::exception& ) + { + } + if( fid ) + break; + } + } + /* if is environment PROJ_LIB defined */ else if ((sysname = getenv("PROJ_LIB")) != nullptr) { - auto paths = NS_PROJ::internal::split(std::string(sysname), dirSeparator); for( const auto& path: paths ) { fname = path; @@ -213,15 +228,16 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, if( fid ) break; } - /* or hardcoded path */ } else if ((sysname = proj_lib_name) != nullptr) { fname = sysname; fname += DIR_CHAR; fname += name; sysname = fname.c_str(); - } else /* just try it bare bones */ + /* just try it bare bones */ + } else { sysname = name; + } if ( fid != nullptr || (fid = pj_ctx_fopen(ctx, sysname, mode)) != nullptr) { @@ -233,33 +249,6 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, errno = 0; } - /* If none of those work and we have a search path, try it */ - if( !fid && !ctx->search_paths.empty() ) - { - for( const auto& path: ctx->search_paths ) { - try { - fname = path; - fname += DIR_CHAR; - fname += name; - sysname = fname.c_str(); - fid = pj_ctx_fopen(ctx, sysname, mode); - } catch( const std::exception& ) - { - } - if( fid ) - break; - } - if (fid) - { - if( out_full_filename != nullptr && out_full_filename_size > 0 ) - { - strncpy(out_full_filename, sysname, out_full_filename_size); - out_full_filename[out_full_filename_size-1] = '\0'; - } - errno = 0; - } - } - if( ctx->last_errno == 0 && errno != 0 ) pj_ctx_set_errno( ctx, errno ); -- cgit v1.2.3 From 20300c1fd5b35bf1d577a3726f02940d02c73f54 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 2 Apr 2019 13:30:33 +0200 Subject: Make sure that ISO19111 C++ code sets pj_errno on errors --- src/apps/gie.cpp | 1 + src/iso19111/c_api.cpp | 5 +++++ src/proj_internal.h | 1 + src/strerrno.cpp | 1 + 4 files changed, 8 insertions(+) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 47211aa8..912113b4 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -1151,6 +1151,7 @@ static const struct errno_vs_err_const lookup[] = { {"pjd_err_invalid_arg" , -58}, {"pjd_err_inconsistent_unit" , -59}, {"pjd_err_mutually_exclusive_args" , -60}, + {"pjd_err_generic_error" , -61}, {"pjd_err_dont_skip" , 5555}, {"pjd_err_unknown" , 9999}, {"pjd_err_enomem" , ENOMEM}, diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index b15b8e34..970d38d8 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -77,6 +77,11 @@ static void PROJ_NO_INLINE proj_log_error(PJ_CONTEXT *ctx, const char *function, msg += ": "; msg += text; ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str()); + auto previous_errno = pj_ctx_get_errno(ctx); + if (previous_errno == 0) { + // only set errno if it wasn't set deeper down the call stack + pj_ctx_set_errno(ctx, PJD_ERR_GENERIC_ERROR); + } } // --------------------------------------------------------------------------- diff --git a/src/proj_internal.h b/src/proj_internal.h index 880e194f..507bd329 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -679,6 +679,7 @@ struct FACTORS { #define PJD_ERR_INVALID_ARG -58 #define PJD_ERR_INCONSISTENT_UNIT -59 #define PJD_ERR_MUTUALLY_EXCLUSIVE_ARGS -60 +#define PJD_ERR_GENERIC_ERROR -61 /* NOTE: Remember to update src/strerrno.cpp, src/apps/gie.cpp and transient_error in */ /* src/transform.cpp when adding new value */ diff --git a/src/strerrno.cpp b/src/strerrno.cpp index af130fc4..4020cb23 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -70,6 +70,7 @@ pj_err_list[] = { "argument not numerical or out of range", /* -58 */ "inconsistent unit type between input and output", /* -59 */ "arguments are mutually exclusive", /* -60 */ + "generic error of unknow origin", /* -61 */ /* When adding error messages, remember to update ID defines in projects.h, and transient_error array in pj_transform */ -- cgit v1.2.3 From 20e67e474e5708b4d3a22cdf5a3ceb71ba627120 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 2 Apr 2019 22:48:39 +0200 Subject: Krovak: avoid divison by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14015 Credit to OSS Fuzz --- src/projections/krovak.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp index 591f8dcc..c30be411 100644 --- a/src/projections/krovak.cpp +++ b/src/projections/krovak.cpp @@ -115,7 +115,14 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forwar deltav = -lp.lam * Q->alpha; s = asin(cos(Q->ad) * sin(u) + sin(Q->ad) * cos(u) * cos(deltav)); - d = asin(cos(u) * sin(deltav) / cos(s)); + const double cos_s = cos(s); + if( cos_s < 1e-12 ) + { + xy.x = 0; + xy.y = 0; + return xy; + } + d = asin(cos(u) * sin(deltav) / cos_s); eps = Q->n * d; rho = Q->rho0 * pow(tan(S0 / 2. + M_PI_4) , Q->n) / pow(tan(s / 2. + M_PI_4) , Q->n); @@ -148,7 +155,12 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, invers eps = atan2(xy.y, xy.x); d = eps / sin(S0); - s = 2. * (atan( pow(Q->rho0 / rho, 1. / Q->n) * tan(S0 / 2. + M_PI_4)) - M_PI_4); + if( rho == 0.0 ) { + s = M_PI_2; + } + else { + s = 2. * (atan( pow(Q->rho0 / rho, 1. / Q->n) * tan(S0 / 2. + M_PI_4)) - M_PI_4); + } u = asin(cos(Q->ad) * sin(s) - sin(Q->ad) * cos(s) * cos(d)); deltav = asin(cos(s) * sin(d) / cos(u)); -- cgit v1.2.3 From c1f5b5105065d6cb9f4e547b6b79c83357f1d759 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 2 Apr 2019 23:04:37 +0200 Subject: gie: fix tolerance checking When comparing expected result with got result, in the case the distance computation returns NaN, gie incorrectly considered the test to be OK. Adapt / comment out a few broken tests revealed after that fix. --- src/apps/gie.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 47211aa8..03dc1556 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -1005,7 +1005,8 @@ Tell GIE what to expect, when transforming the ACCEPTed input else d = proj_xyz_dist (co, ce); - if (d > T.tolerance) + // Test written like that to handle NaN + if (!(d <= T.tolerance)) return expect_message (d, args); succs++; -- cgit v1.2.3 From 70ed3efe60718be74d73d92ec2d121e2de268e53 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 4 Apr 2019 22:36:00 +0200 Subject: Reject negative e parameter to avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14044 Credit to OSS Fuzz --- src/apps/gie.cpp | 2 +- src/ell_set.cpp | 24 +++++++++++++----------- src/init.cpp | 2 +- src/proj_internal.h | 2 +- src/projections/aea.cpp | 2 +- src/projections/lcc.cpp | 2 +- src/strerrno.cpp | 2 +- 7 files changed, 19 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index f0f7968f..5a86ebb7 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -1097,7 +1097,7 @@ static const struct errno_vs_err_const lookup[] = { {"pjd_err_no_colon_in_init_string" , -3}, {"pjd_err_proj_not_named" , -4}, {"pjd_err_unknown_projection_id" , -5}, - {"pjd_err_eccentricity_is_one" , -6}, + {"pjd_err_invalid_eccentricity" , -6}, {"pjd_err_unknown_unit_id" , -7}, {"pjd_err_invalid_boolean_param" , -8}, {"pjd_err_unknown_ellp_param" , -9}, diff --git a/src/ell_set.cpp b/src/ell_set.cpp index c0b9016d..0d7fb6d5 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -280,7 +280,7 @@ static int ellps_shape (PJ *P) { if (HUGE_VAL==P->es) return proj_errno_set (P, PJD_ERR_INVALID_ARG); if (P->es >= 1) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return proj_errno_set (P, PJD_ERR_INVALID_ECCENTRICITY); break; /* eccentricity, e */ @@ -288,10 +288,8 @@ static int ellps_shape (PJ *P) { P->e = pj_atof (pj_param_value (par)); if (HUGE_VAL==P->e) return proj_errno_set (P, PJD_ERR_INVALID_ARG); - if (0==P->e) - return proj_errno_set (P, PJD_ERR_INVALID_ARG); - if (P->e >= 1) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + if (P->e < 0 || P->e >= 1) + return proj_errno_set (P, PJD_ERR_INVALID_ECCENTRICITY); P->es = P->e * P->e; break; @@ -301,7 +299,7 @@ static int ellps_shape (PJ *P) { if (HUGE_VAL==P->b) return proj_errno_set (P, PJD_ERR_INVALID_ARG); if (P->b <= 0) - return proj_errno_set (P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return proj_errno_set (P, PJD_ERR_INVALID_ECCENTRICITY); if (P->b==P->a) break; P->f = (P->a - P->b) / P->a; @@ -542,8 +540,8 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { if (0==P->f) P->f = 1 - cos (P->alpha); /* = 1 - sqrt (1 - PIN->es); */ if (P->f == 1.0) { - pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); - return PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER; + pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); + return PJD_ERR_INVALID_ECCENTRICITY; } P->rf = P->f != 0.0 ? 1.0/P->f: HUGE_VAL; @@ -563,8 +561,8 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { P->one_es = 1. - P->es; if (P->one_es == 0.) { - pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); - return PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER; + pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); + return PJD_ERR_INVALID_ECCENTRICITY; } P->rone_es = 1./P->one_es; @@ -651,6 +649,10 @@ int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) { *es = pj_param(ctx,pl, "des").f; else if (pj_param(ctx,pl, "te").i) { /* eccentricity */ e = pj_param(ctx,pl, "de").f; + if (e < 0) { + pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY); + return 1; + } *es = e * e; } else if (pj_param(ctx,pl, "trf").i) { /* recip flattening */ *es = pj_param(ctx,pl, "drf").f; @@ -720,7 +722,7 @@ bomb: return 1; } if (*es >= 1.) { - pj_ctx_set_errno(ctx, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY); return 1; } if (*a <= 0.) { diff --git a/src/init.cpp b/src/init.cpp index cfcba96f..0fd303f5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -679,7 +679,7 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i PIN->a_orig = PIN->a; PIN->es_orig = PIN->es; if (pj_calc_ellipsoid_params (PIN, PIN->a, PIN->es)) - return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return pj_default_destructor (PIN, PJD_ERR_INVALID_ECCENTRICITY); /* Now that we have ellipse information check for WGS84 datum */ if( PIN->datum_type == PJD_3PARAM diff --git a/src/proj_internal.h b/src/proj_internal.h index 507bd329..66cadb1a 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -624,7 +624,7 @@ struct FACTORS { #define PJD_ERR_NO_COLON_IN_INIT_STRING -3 #define PJD_ERR_PROJ_NOT_NAMED -4 #define PJD_ERR_UNKNOWN_PROJECTION_ID -5 -#define PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER -6 +#define PJD_ERR_INVALID_ECCENTRICITY -6 #define PJD_ERR_UNKNOWN_UNIT_ID -7 #define PJD_ERR_INVALID_BOOLEAN_PARAM -8 #define PJD_ERR_UNKNOWN_ELLP_PARAM -9 diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp index 8a80c49c..e488ddd9 100644 --- a/src/projections/aea.cpp +++ b/src/projections/aea.cpp @@ -182,7 +182,7 @@ static PJ *setup(PJ *P) { Q->n = (m1 * m1 - m2 * m2) / (ml2 - ml1); if (Q->n == 0) { // Not quite, but es is very close to 1... - return destructor(P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return destructor(P, PJD_ERR_INVALID_ECCENTRICITY); } } Q->ec = 1. - .5 * P->one_es * log((1. - P->e) / diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 55d28b80..3e93f98c 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -113,7 +113,7 @@ PJ *PROJECTION(lcc) { Q->n = log(m1 / pj_msfn(sinphi, cos(Q->phi2), P->es)); if (Q->n == 0) { // Not quite, but es is very close to 1... - return pj_default_destructor(P, PJD_ERR_ECCENTRICITY_IS_ONE_OR_GREATER); + return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); } const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e); if( ml2 == 0 ) { diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 4020cb23..c230d226 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -15,7 +15,7 @@ pj_err_list[] = { "no colon in init= string", /* -3 */ "projection not named", /* -4 */ "unknown projection id", /* -5 */ - "effective eccentricity >= 1.", /* -6 */ + "effective eccentricity < 0 or >= 1.", /* -6 */ "unknown unit conversion id", /* -7 */ "invalid boolean param argument", /* -8 */ "unknown elliptical parameter name", /* -9 */ -- cgit v1.2.3 From e41b9f143c783651ce8576f0ccc5ca612883c9e6 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Fri, 5 Apr 2019 00:18:16 +1300 Subject: CMake: cache C/C++ warn flags to compile PROJ targets Remove (most) needs to fiddle with CMAKE_C_FLAGS / CMAKE_CXX_FLAGS --- src/bin_cct.cmake | 2 ++ src/bin_cs2cs.cmake | 2 ++ src/bin_geod.cmake | 3 ++- src/bin_geodtest.cmake | 5 ++--- src/bin_gie.cmake | 2 ++ src/bin_proj.cmake | 3 ++- src/bin_projinfo.cmake | 3 ++- src/lib_proj.cmake | 18 ++++++++++++------ 8 files changed, 26 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/bin_cct.cmake b/src/bin_cct.cmake index 9c4b0804..d2d61cf5 100644 --- a/src/bin_cct.cmake +++ b/src/bin_cct.cmake @@ -9,6 +9,8 @@ source_group("Source Files\\Bin" FILES ${CCT_SRC}) add_executable(cct ${CCT_SRC} ${CCT_INCLUDE}) target_link_libraries(cct ${PROJ_LIBRARIES}) +target_compile_options(cct PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS cct RUNTIME DESTINATION ${BINDIR}) diff --git a/src/bin_cs2cs.cmake b/src/bin_cs2cs.cmake index 9b2f2f4f..7ee26673 100644 --- a/src/bin_cs2cs.cmake +++ b/src/bin_cs2cs.cmake @@ -7,6 +7,8 @@ source_group("Source Files\\Bin" FILES ${CS2CS_SRC}) add_executable(cs2cs ${CS2CS_SRC} ${CS2CS_INCLUDE}) target_link_libraries(cs2cs ${PROJ_LIBRARIES}) +target_compile_options(cs2cs PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS cs2cs RUNTIME DESTINATION ${BINDIR}) diff --git a/src/bin_geod.cmake b/src/bin_geod.cmake index 7221958a..84d2cd5b 100644 --- a/src/bin_geod.cmake +++ b/src/bin_geod.cmake @@ -8,9 +8,10 @@ set(GEOD_INCLUDE apps/geod_interface.h) source_group("Source Files\\Bin" FILES ${GEOD_SRC} ${GEOD_INCLUDE}) -#Executable add_executable(geod ${GEOD_SRC} ${GEOD_INCLUDE}) target_link_libraries(geod ${PROJ_LIBRARIES}) +target_compile_options(geod PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS geod RUNTIME DESTINATION ${BINDIR}) diff --git a/src/bin_geodtest.cmake b/src/bin_geodtest.cmake index 4cc98197..c911e95f 100644 --- a/src/bin_geodtest.cmake +++ b/src/bin_geodtest.cmake @@ -3,12 +3,11 @@ set(GEODTEST_INCLUDE) source_group("Source Files\\Bin" FILES ${GEODTEST_SRC} ${GEODTEST_INCLUDE}) -#Executable add_executable(geodtest ${GEODTEST_SRC} ${GEODTEST_INCLUDE}) target_link_libraries(geodtest ${PROJ_LIBRARIES}) -# Do not install +target_compile_options(geodtest PRIVATE ${PROJ_CXX_WARN_FLAGS}) -# Instead run as a test +# Do not install, instead run as a test add_test(NAME geodesic-test COMMAND geodtest) if(MSVC AND BUILD_LIBPROJ_SHARED) diff --git a/src/bin_gie.cmake b/src/bin_gie.cmake index a96c4c1c..49c57483 100644 --- a/src/bin_gie.cmake +++ b/src/bin_gie.cmake @@ -9,6 +9,8 @@ source_group("Source Files\\Bin" FILES ${GIE_SRC}) add_executable(gie ${GIE_SRC} ${GIE_INCLUDE}) target_link_libraries(gie ${PROJ_LIBRARIES}) +target_compile_options(gie PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS gie RUNTIME DESTINATION ${BINDIR}) diff --git a/src/bin_proj.cmake b/src/bin_proj.cmake index c55ccfda..b9ae03e5 100644 --- a/src/bin_proj.cmake +++ b/src/bin_proj.cmake @@ -5,12 +5,13 @@ set(PROJ_SRC source_group("Source Files\\Bin" FILES ${PROJ_SRC}) -#Executable add_executable(binproj ${PROJ_SRC}) set_target_properties(binproj PROPERTIES OUTPUT_NAME proj) target_link_libraries(binproj ${PROJ_LIBRARIES}) +target_compile_options(binproj PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS binproj RUNTIME DESTINATION ${BINDIR}) diff --git a/src/bin_projinfo.cmake b/src/bin_projinfo.cmake index 0691d739..c2447262 100644 --- a/src/bin_projinfo.cmake +++ b/src/bin_projinfo.cmake @@ -2,12 +2,13 @@ set(PROJINFO_SRC apps/projinfo.cpp) source_group("Source Files\\Bin" FILES ${PROJINFO_SRC}) -#Executable add_executable(binprojinfo ${PROJINFO_SRC}) set_target_properties(binprojinfo PROPERTIES OUTPUT_NAME projinfo) target_link_libraries(binprojinfo ${PROJ_LIBRARIES}) +target_compile_options(binprojinfo PRIVATE ${PROJ_CXX_WARN_FLAGS}) + install(TARGETS binprojinfo RUNTIME DESTINATION ${BINDIR}) diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 38bc05d8..635992e4 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -42,15 +42,9 @@ if(ENABLE_LTO) set(CMAKE_REQUIRED_FLAGS "-Wl,-flto") check_cxx_source_compiles("int main(){ return 0; }" COMPILER_SUPPORTS_FLTO_FLAG) - if(COMPILER_SUPPORTS_FLTO_FLAG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") - endif() else() include(CheckCXXCompilerFlag) check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_FLTO_FLAG) - if(COMPILER_SUPPORTS_FLTO_FLAG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") - endif() endif() endif() @@ -351,6 +345,18 @@ add_library( ${ALL_LIBPROJ_HEADERS} ${PROJ_RESOURCES} ) +target_compile_options(${PROJ_CORE_TARGET} + PRIVATE $<$:${PROJ_C_WARN_FLAGS}> + PRIVATE $<$:${PROJ_CXX_WARN_FLAGS}> +) + +if(COMPILER_SUPPORTS_FLTO_FLAG) + # See https://gitlab.kitware.com/cmake/cmake/issues/15245 + # CMake v3.9: + # set_property(TARGET ${PROJ_CORE_TARGET} + # PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + target_compile_options(${PROJ_CORE_TARGET} PRIVATE -flto) +endif() if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) target_include_directories(${PROJ_CORE_TARGET} INTERFACE -- cgit v1.2.3 From 3aed84243a8188b54d19d7e9c26028796eb398b0 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 5 Apr 2019 12:54:56 +0200 Subject: _buildUnit(): avoid later division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14055 Credit to OSS Fuzz --- src/iso19111/io.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 51fda1c1..360d55a2 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6091,6 +6091,9 @@ static UnitOfMeasure _buildUnit(const LinearUnitDesc *unitsMatch) { static UnitOfMeasure _buildUnit(double to_meter_value) { // TODO: look-up in EPSG catalog + if (to_meter_value == 0) { + throw ParsingException("invalid unit value"); + } return UnitOfMeasure("unknown", to_meter_value, UnitOfMeasure::Type::LINEAR); } -- cgit v1.2.3 From 97de772e16281fad460a1469c34cd37ff42bcefb Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 5 Apr 2019 13:25:17 +0200 Subject: lcc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14058 Credit to OSS Fuzz --- src/projections/lcc.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 3e93f98c..8cc743a9 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -125,6 +125,9 @@ PJ *PROJECTION(lcc) { Q->rho0 *= (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) ? 0. : pow(pj_tsfn(P->phi0, sin(P->phi0), P->e), Q->n); } else { + if( fabs(cosphi) < EPS10 || fabs(cos(Q->phi2)) < EPS10 ) { + return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + } if (secant) Q->n = log(cosphi / cos(Q->phi2)) / log(tan(M_FORTPI + .5 * Q->phi2) / -- cgit v1.2.3 From a90a5c0b9ac58c322daa8f339719b2c0e09d3d45 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 5 Apr 2019 13:30:57 +0200 Subject: krovak: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14061 Credit to OSS Fuzz --- src/projections/krovak.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp index c30be411..c3f61f3d 100644 --- a/src/projections/krovak.cpp +++ b/src/projections/krovak.cpp @@ -222,7 +222,11 @@ PJ *PROJECTION(krovak) { Q->alpha = sqrt(1. + (P->es * pow(cos(P->phi0), 4)) / (1. - P->es)); u0 = asin(sin(P->phi0) / Q->alpha); g = pow( (1. + P->e * sin(P->phi0)) / (1. - P->e * sin(P->phi0)) , Q->alpha * P->e / 2. ); - Q->k = tan( u0 / 2. + M_PI_4) / pow (tan(P->phi0 / 2. + M_PI_4) , Q->alpha) * g; + double tan_half_phi0_plus_pi_4 = tan(P->phi0 / 2. + M_PI_4); + if( tan_half_phi0_plus_pi_4 == 0.0 ) { + return pj_default_destructor(P, PJD_ERR_INVALID_ARG); + } + Q->k = tan( u0 / 2. + M_PI_4) / pow (tan_half_phi0_plus_pi_4 , Q->alpha) * g; n0 = sqrt(1. - P->es) / (1. - P->es * pow(sin(P->phi0), 2)); Q->n = sin(S0); Q->rho0 = P->k0 * n0 / tan(S0); -- cgit v1.2.3 From f6ba932a8f1d7f0775d4ebe367b2d5faef57461a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 5 Apr 2019 14:17:58 +0200 Subject: imw_p: avoid division by zero in inverse Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14062 Credit to OSS Fuzz --- src/projections/imw_p.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp index 41882df2..8d675318 100644 --- a/src/projections/imw_p.cpp +++ b/src/projections/imw_p.cpp @@ -117,12 +117,16 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ do { t = loc_for(lp, P, &yc); const double denom = t.y - yc; - if( denom == 0 ) { - proj_errno_set(P, PJD_ERR_NON_CONVERGENT); - return proj_coord_error().lp; + if( denom != 0 || fabs(t.y - xy.y) > TOL ) + { + if( denom == 0 ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().lp; + } + lp.phi = ((lp.phi - Q->phi_1) * (xy.y - yc) / denom) + Q->phi_1; } - lp.phi = ((lp.phi - Q->phi_1) * (xy.y - yc) / denom) + Q->phi_1; - lp.lam = lp.lam * xy.x / t.x; + if( t.x != 0 || fabs(t.x - xy.x) > TOL ) + lp.lam = lp.lam * xy.x / t.x; i ++; } while (i < N_MAX_ITER && (fabs(t.x - xy.x) > TOL || fabs(t.y - xy.y) > TOL)); -- cgit v1.2.3 From 89e5fe47cf695579cfec82907d8ba5abbd22ec86 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 6 Apr 2019 15:00:01 +0200 Subject: pj_open_lib_ex(): avoid false positive Coverity Scan warning abount nullptr dereference. CID 202725 --- src/open_lib.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/open_lib.cpp b/src/open_lib.cpp index 68477996..01f626e8 100644 --- a/src/open_lib.cpp +++ b/src/open_lib.cpp @@ -34,6 +34,7 @@ #define FROM_PROJ_CPP #endif +#include #include #include #include @@ -239,6 +240,7 @@ pj_open_lib_ex(projCtx ctx, const char *name, const char *mode, sysname = name; } + assert(sysname); // to make Coverity Scan happy if ( fid != nullptr || (fid = pj_ctx_fopen(ctx, sysname, mode)) != nullptr) { if( out_full_filename != nullptr && out_full_filename_size > 0 ) -- cgit v1.2.3 From 685ad56156f320760c92f7f71fa4acbf3e00acc9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 10 Apr 2019 23:55:52 +0200 Subject: lsat: avoid division by zero in inverse Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14135 Credit to OSS Fuzz --- src/projections/lsat.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/projections/lsat.cpp b/src/projections/lsat.cpp index 5b7520d3..f9eec1b9 100644 --- a/src/projections/lsat.cpp +++ b/src/projections/lsat.cpp @@ -112,7 +112,6 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ struct pj_opaque *Q = static_cast(P->opaque); int nn; double lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp; - lamdp = xy.x / Q->b; nn = 50; do { @@ -135,10 +134,14 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ lamdp -= TOL; spp = sin(phidp); sppsq = spp * spp; + const double denom = 1. - sppsq * (1. + Q->u); + if( denom == 0.0 ) { + proj_errno_set(P, PJD_ERR_INVALID_X_OR_Y); + return proj_coord_error().lp; + } lamt = atan(((1. - sppsq * P->rone_es) * tan(lamdp) * Q->ca - spp * Q->sa * sqrt((1. + Q->q * dd) * ( - 1. - sppsq) - sppsq * Q->u) / cos(lamdp)) / (1. - sppsq - * (1. + Q->u))); + 1. - sppsq) - sppsq * Q->u) / cos(lamdp)) / denom); sl = lamt >= 0. ? 1. : -1.; scl = cos(lamdp) >= 0. ? 1. : -1; lamt -= M_HALFPI * (1. - scl) * sl; -- cgit v1.2.3 From 00dffd7ace356d7cb39e2c515237d4351f5b5666 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 11 Apr 2019 00:14:26 +0200 Subject: omerc: avoid division by zero when |lat_0|=90 Partially revert e3346bb39c860883ed9a8ada0657139118e21ef0 (#195) Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14136 Credit to OSS Fuzz --- src/projections/omerc.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index c33f6489..4d78fbef 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -191,6 +191,9 @@ PJ *PROJECTION(omerc) { gamma = alpha_c; } else alpha_c = aasin(P->ctx, D*sin(gamma0 = gamma)); + if( fabs(fabs(P->phi0) - M_HALFPI) <= TOL ) { + return pj_default_destructor(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90); + } P->lam0 = lamc - aasin(P->ctx, .5 * (F - 1. / F) * tan(gamma0)) / Q->B; } else { -- cgit v1.2.3 From c1e730312965831e6b9c2093677a67716c198622 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 11 Apr 2019 00:21:24 +0200 Subject: omerc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14138 Credit to OSS Fuzz --- src/projections/omerc.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index 4d78fbef..c0278043 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -209,8 +209,11 @@ PJ *PROJECTION(omerc) { lam2 += M_TWOPI; P->lam0 = adjlon(.5 * (lam1 + lam2) - atan( J * tan(.5 * Q->B * (lam1 - lam2)) / p) / Q->B); - gamma0 = atan(2. * sin(Q->B * adjlon(lam1 - P->lam0)) / - (F - 1. / F)); + const double denom = F - 1. / F; + if( denom == 0 ) { + return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); + } + gamma0 = atan(2. * sin(Q->B * adjlon(lam1 - P->lam0)) / denom); gamma = alpha_c = aasin(P->ctx, D * sin(gamma0)); } Q->singam = sin(gamma0); -- cgit v1.2.3 From 33f81359efd93ccd4bf59cc4f6b68c6363042f97 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 12 Apr 2019 18:21:22 +0200 Subject: Validate lat_0 range in general case, lat_1 and lat_2 for lcc and eqdc Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14211 Credit to OSS Fuzz --- src/init.cpp | 2 ++ src/projections/eqdc.cpp | 10 ++++++++-- src/projections/lcc.cpp | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/init.cpp b/src/init.cpp index 0fd303f5..ba9cddd2 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -736,6 +736,8 @@ pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_i /* Central latitude */ PIN->phi0 = pj_param(ctx, start, "rlat_0").f; + if( fabs(PIN->phi0) > M_HALFPI ) + return pj_default_destructor (PIN, PJD_ERR_LAT_LARGER_THAN_90); /* False easting and northing */ PIN->x0 = pj_param(ctx, start, "dx_0").f; diff --git a/src/projections/eqdc.cpp b/src/projections/eqdc.cpp index d175d4a1..49cfc0ae 100644 --- a/src/projections/eqdc.cpp +++ b/src/projections/eqdc.cpp @@ -84,12 +84,14 @@ PJ *PROJECTION(eqdc) { Q->phi1 = pj_param(P->ctx, P->params, "rlat_1").f; Q->phi2 = pj_param(P->ctx, P->params, "rlat_2").f; + if (fabs(Q->phi1) > M_HALFPI || fabs(Q->phi2) > M_HALFPI) + return destructor(P, PJD_ERR_LAT_LARGER_THAN_90); if (fabs(Q->phi1 + Q->phi2) < EPS10) - return pj_default_destructor (P, PJD_ERR_CONIC_LAT_EQUAL); + return destructor (P, PJD_ERR_CONIC_LAT_EQUAL); if (!(Q->en = pj_enfn(P->es))) - return pj_default_destructor(P, ENOMEM); + return destructor(P, ENOMEM); Q->n = sinphi = sin(Q->phi1); cosphi = cos(Q->phi1); @@ -104,6 +106,10 @@ PJ *PROJECTION(eqdc) { cosphi = cos(Q->phi2); Q->n = (m1 - pj_msfn(sinphi, cosphi, P->es)) / (pj_mlfn(Q->phi2, sinphi, cosphi, Q->en) - ml1); + if (Q->n == 0) { + // Not quite, but es is very close to 1... + return destructor(P, PJD_ERR_INVALID_ECCENTRICITY); + } } Q->c = ml1 + m1 / Q->n; Q->rho0 = Q->c - pj_mlfn(P->phi0, sin(P->phi0), diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 8cc743a9..aca025be 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -94,6 +94,8 @@ PJ *PROJECTION(lcc) { if (!pj_param(P->ctx, P->params, "tlat_0").i) P->phi0 = Q->phi1; } + if (fabs(Q->phi1) > M_HALFPI || fabs(Q->phi2) > M_HALFPI) + return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90); if (fabs(Q->phi1 + Q->phi2) < EPS10) return pj_default_destructor(P, PJD_ERR_CONIC_LAT_EQUAL); -- cgit v1.2.3 From 85b564a5b1096274752c4c50640a509f51fca214 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 14 Apr 2019 19:56:15 +0200 Subject: imw_p: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14248 Credit to OSS Fuzz --- src/projections/imw_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp index 8d675318..5455be33 100644 --- a/src/projections/imw_p.cpp +++ b/src/projections/imw_p.cpp @@ -125,7 +125,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } lp.phi = ((lp.phi - Q->phi_1) * (xy.y - yc) / denom) + Q->phi_1; } - if( t.x != 0 || fabs(t.x - xy.x) > TOL ) + if( t.x != 0 && fabs(t.x - xy.x) > TOL ) lp.lam = lp.lam * xy.x / t.x; i ++; } while (i < N_MAX_ITER && -- cgit v1.2.3 From 47db7804524066e74fd787bdd0d7f2ba8394c220 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 14 Apr 2019 20:11:17 +0200 Subject: lcc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14250 Credit to OSS Fuzz --- src/projections/lcc.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index aca025be..a101009d 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -121,7 +121,12 @@ PJ *PROJECTION(lcc) { if( ml2 == 0 ) { return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); } - Q->n /= log(ml1 / ml2); + const double denom = log(ml1 / ml2); + if( denom == 0 ) { + // Not quite, but es is very close to 1... + return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); + } + Q->n /= denom; } Q->c = (Q->rho0 = m1 * pow(ml1, -Q->n) / Q->n); Q->rho0 *= (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) ? 0. : -- cgit v1.2.3 From 74723a7dff60542af4cadffb9797b5ae60e4a88e Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Tue, 16 Apr 2019 21:29:17 +1200 Subject: Remove `PROJ_COMPILATION=1` definition --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 9858d78f..308b4ca9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,7 @@ check_PROGRAMS = geodtest AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \ -DMUTEX_@MUTEX_SETTING@ @JNI_INCLUDE@ -I$(top_srcdir)/include @SQLITE3_CFLAGS@ -AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@ -DPROJ_COMPILATION +AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@ include_HEADERS = proj.h proj_experimental.h proj_constants.h proj_api.h geodesic.h \ org_proj4_PJ.h proj_symbol_rename.h -- cgit v1.2.3 From 421653b9c61f253e800ca749e9b1a9ba0688d72a Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Tue, 16 Apr 2019 09:38:51 +0000 Subject: CMake: better support for Intel compiler --- src/lib_proj.cmake | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 635992e4..f52f5327 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -37,11 +37,16 @@ endif() option(ENABLE_LTO "Build library with LTO optimization (if available)." OFF) if(ENABLE_LTO) - if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + # TODO: CMake v3.9 use CheckIPOSupported and set property; see + # https://cmake.org/cmake/help/v3.9/module/CheckIPOSupported.html + if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_FLAGS "-Wl,-flto") check_cxx_source_compiles("int main(){ return 0; }" COMPILER_SUPPORTS_FLTO_FLAG) + elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") + # Set INTERPROCEDURAL_OPTIMIZATION property later + set(COMPILER_SUPPORTS_FLTO_FLAG TRUE) else() include(CheckCXXCompilerFlag) check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_FLTO_FLAG) @@ -350,12 +355,31 @@ target_compile_options(${PROJ_CORE_TARGET} PRIVATE $<$:${PROJ_CXX_WARN_FLAGS}> ) +# Tell Intel compiler to do arithmetic accurately. This is needed to stop the +# compiler from ignoring parentheses in expressions like (a + b) + c and from +# simplifying 0.0 + x to x (which is wrong if x = -0.0). +if("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") + if(MSVC) + set(FP_PRECISE "/fp:precise") + else() + set(FP_PRECISE "-fp-model precise") + endif() + # Apply to source files that require this option + set_source_files_properties( + geodesic.c + PROPERTIES COMPILE_FLAGS ${FP_PRECISE}) +endif() + if(COMPILER_SUPPORTS_FLTO_FLAG) - # See https://gitlab.kitware.com/cmake/cmake/issues/15245 - # CMake v3.9: - # set_property(TARGET ${PROJ_CORE_TARGET} - # PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) - target_compile_options(${PROJ_CORE_TARGET} PRIVATE -flto) + if("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") + # Intel supported only, before v3.9 + set_property(TARGET ${PROJ_CORE_TARGET} + PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + else() + # Pre CMake v3.9 needs to set flag for other compilers + # see https://gitlab.kitware.com/cmake/cmake/issues/15245 + target_compile_options(${PROJ_CORE_TARGET} PRIVATE -flto) + endif() endif() if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) -- cgit v1.2.3 From d9e2a15f2e17b6710ccffa3e271595e006ceadf2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 16 Apr 2019 19:26:16 +0200 Subject: createOperations(): do not attempt using a unrelated datum intermediate when doing geog2D<-->geog3D conversions of same datum Seen when testing transformations between "CR 05" (EPSG:5365) and "CR-SIRGAS" (EPSG:8907) which require going through their corresponding 3D GeogCRS to find a Helmert transformation. --- src/iso19111/coordinateoperation.cpp | 326 ++++++++++++++++++++++++++++++----- 1 file changed, 283 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 15532a89..7eab849c 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -56,6 +56,10 @@ #include #include +#ifdef DEBUG +#include +#endif + using namespace NS_PROJ::internal; #if 0 @@ -805,6 +809,14 @@ CoordinateOperation::normalizeForVisualization() const { // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +CoordinateOperationNNPtr CoordinateOperation::shallowClone() const { + return _shallowClone(); +} +//! @endcond + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress struct OperationMethod::Private { util::optional formula_{}; @@ -2342,6 +2354,10 @@ ConversionNNPtr Conversion::shallowClone() const { conv->setCRSs(this, false); return conv; } + +CoordinateOperationNNPtr Conversion::_shallowClone() const { + return util::nn_static_pointer_cast(shallowClone()); +} //! @endcond // --------------------------------------------------------------------------- @@ -4679,6 +4695,16 @@ InverseConversion::create(const ConversionNNPtr &forward) { return conv; } +// --------------------------------------------------------------------------- + +CoordinateOperationNNPtr InverseConversion::_shallowClone() const { + auto op = InverseConversion::nn_make_shared( + inverseAsConversion()->shallowClone()); + op->assignSelf(op); + op->setCRSs(this, false); + return util::nn_static_pointer_cast(op); +} + //! @endcond // --------------------------------------------------------------------------- @@ -5181,6 +5207,7 @@ const char *Conversion::getWKT1GDALMethodName() const { // --------------------------------------------------------------------------- //! @cond Doxygen_Suppress + void Conversion::_exportToWKT(io::WKTFormatter *formatter) const { const auto &l_method = method(); const auto &methodName = l_method->nameStr(); @@ -5210,6 +5237,17 @@ void Conversion::_exportToWKT(io::WKTFormatter *formatter) const { formatter->pushOutputId(false); } +#ifdef DEBUG_CONVERSION_ID + if (sourceCRS() && targetCRS()) { + formatter->startNode("SOURCECRS_ID", false); + sourceCRS()->formatID(formatter); + formatter->endNode(); + formatter->startNode("TARGETCRS_ID", false); + targetCRS()->formatID(formatter); + formatter->endNode(); + } +#endif + bool bAlreadyWritten = false; if (!isWKT2 && formatter->useESRIDialect()) { const ESRIParamMapping *esriParams = nullptr; @@ -6036,10 +6074,14 @@ const crs::CRSNNPtr &Transformation::targetCRS() PROJ_PURE_DEFN { //! @cond Doxygen_Suppress TransformationNNPtr Transformation::shallowClone() const { - auto conv = Transformation::nn_make_shared(*this); - conv->assignSelf(conv); - conv->setCRSs(this, false); - return conv; + auto transf = Transformation::nn_make_shared(*this); + transf->assignSelf(transf); + transf->setCRSs(this, false); + return transf; +} + +CoordinateOperationNNPtr Transformation::_shallowClone() const { + return util::nn_static_pointer_cast(shallowClone()); } //! @endcond @@ -7656,6 +7698,13 @@ InverseTransformation::create(const TransformationNNPtr &forward) { // --------------------------------------------------------------------------- +TransformationNNPtr InverseTransformation::inverseAsTransformation() const { + return NN_NO_CHECK( + util::nn_dynamic_pointer_cast(forwardOperation_)); +} + +// --------------------------------------------------------------------------- + void InverseTransformation::_exportToWKT(io::WKTFormatter *formatter) const { auto approxInverse = createApproximateInverseIfPossible( @@ -7667,6 +7716,16 @@ void InverseTransformation::_exportToWKT(io::WKTFormatter *formatter) const { } } +// --------------------------------------------------------------------------- + +CoordinateOperationNNPtr InverseTransformation::_shallowClone() const { + auto op = InverseTransformation::nn_make_shared( + inverseAsTransformation()->shallowClone()); + op->assignSelf(op); + op->setCRSs(this, false); + return util::nn_static_pointer_cast(op); +} + //! @endcond // --------------------------------------------------------------------------- @@ -9063,6 +9122,7 @@ struct ConcatenatedOperation::Private { explicit Private(const std::vector &operationsIn) : operations_(operationsIn) {} + Private(const Private &) = default; }; //! @endcond @@ -9074,6 +9134,14 @@ ConcatenatedOperation::~ConcatenatedOperation() = default; // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +ConcatenatedOperation::ConcatenatedOperation(const ConcatenatedOperation &other) + : CoordinateOperation(other), + d(internal::make_unique(*(other.d))) {} +//! @endcond + +// --------------------------------------------------------------------------- + ConcatenatedOperation::ConcatenatedOperation( const std::vector &operationsIn) : CoordinateOperation(), d(internal::make_unique(operationsIn)) {} @@ -9136,6 +9204,22 @@ ConcatenatedOperationNNPtr ConcatenatedOperation::create( } if (i >= 1) { if (!compareStepCRS(l_sourceCRS.get(), lastTargetCRS.get())) { +#ifdef DEBUG_CONCATENATED_OPERATION + { + auto f(io::WKTFormatter::create( + io::WKTFormatter::Convention::WKT2_2018)); + std::cerr << "Source CRS of step " << i << ":" << std::endl; + std::cerr << l_sourceCRS->exportToWKT(f.get()) << std::endl; + } + { + auto f(io::WKTFormatter::create( + io::WKTFormatter::Convention::WKT2_2018)); + std::cerr << "Target CRS of step " << i - 1 << ":" + << std::endl; + std::cerr << lastTargetCRS->exportToWKT(f.get()) + << std::endl; + } +#endif throw InvalidOperation( "Inconsistent chaining of CRS in operations"); } @@ -9149,6 +9233,14 @@ ConcatenatedOperationNNPtr ConcatenatedOperation::create( op->setCRSs(NN_NO_CHECK(operationsIn[0]->sourceCRS()), NN_NO_CHECK(operationsIn.back()->targetCRS()), nullptr); op->setAccuracies(accuracies); +#ifdef DEBUG_CONCATENATED_OPERATION + { + auto f( + io::WKTFormatter::create(io::WKTFormatter::Convention::WKT2_2018)); + std::cerr << "ConcatenatedOperation::create()" << std::endl; + std::cerr << op->exportToWKT(f.get()) << std::endl; + } +#endif return op; } @@ -9459,6 +9551,18 @@ void ConcatenatedOperation::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +CoordinateOperationNNPtr ConcatenatedOperation::_shallowClone() const { + auto op = + ConcatenatedOperation::nn_make_shared(*this); + op->assignSelf(op); + op->setCRSs(this, false); + return util::nn_static_pointer_cast(op); +} +//! @endcond + +// --------------------------------------------------------------------------- + void ConcatenatedOperation::_exportToPROJString( io::PROJStringFormatter *formatter) const // throw(FormattingException) { @@ -11359,11 +11463,46 @@ static bool isNullTransformation(const std::string &name) { // --------------------------------------------------------------------------- +#ifdef DEBUG + +static int nCallLevel = 0; + +struct EnterDebugLevel { + EnterDebugLevel() { ++nCallLevel; } + ~EnterDebugLevel() { --nCallLevel; } +}; + +static void debugTrace(const std::string &str) { + for (int i = 1; i < nCallLevel; i++) + std::cerr << " "; + std::cerr << str << std::endl; +} + +static std::string objectAsStr(const common::IdentifiedObject *obj) { + std::string ret(obj->nameStr()); + const auto &ids = obj->identifiers(); + if (!ids.empty()) { + ret += " ("; + ret += (*ids[0]->codeSpace()) + ":" + ids[0]->code(); + ret += ")"; + } + return ret; +} +#endif + +// --------------------------------------------------------------------------- + void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( std::vector &res, const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, const crs::GeodeticCRS *geodSrc, const crs::GeodeticCRS *geodDst, Private::Context &context) { +#ifdef DEBUG + EnterDebugLevel enterFunction; + debugTrace("createOperationsWithDatumPivot(" + + objectAsStr(sourceCRS.get()) + "," + + objectAsStr(targetCRS.get()) + ")"); +#endif const bool allowEmptyIntersection = true; struct CreateOperationsWithDatumPivotAntiRecursion { @@ -11411,20 +11550,73 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( } std::vector subOps; + const bool isNullThird = + isNullTransformation(opsThird[0]->nameStr()); + CoordinateOperationNNPtr opSecondCloned( + (isNullFirst || isNullThird) ? opSecond->shallowClone() + : opSecond); + CoordinateOperation *invCOForward = nullptr; + if (isNullFirst || isNullThird) { + if (opSecondCloned->identifiers().size() == 1 && + (*opSecondCloned->identifiers()[0]->codeSpace()) + .find("DERIVED_FROM") == std::string::npos) { + { + util::PropertyMap map; + addModifiedIdentifier(map, opSecondCloned.get(), false, + true); + opSecondCloned->setProperties(map); + } + auto invCO = dynamic_cast( + opSecondCloned.get()); + if (invCO) { + invCOForward = invCO->forwardOperation().get(); + if (invCOForward->identifiers().size() == 1 && + (*invCOForward->identifiers()[0]->codeSpace()) + .find("DERIVED_FROM") == + std::string::npos) { + util::PropertyMap map; + addModifiedIdentifier(map, invCOForward, false, + true); + invCOForward->setProperties(map); + } + } + } + } if (isNullFirst) { - opSecond->setCRSs( - sourceCRS, NN_CHECK_ASSERT(opSecond->targetCRS()), nullptr); + auto oldTarget(NN_CHECK_ASSERT(opSecondCloned->targetCRS())); + opSecondCloned->setCRSs(sourceCRS, oldTarget, nullptr); + if (invCOForward) { + invCOForward->setCRSs(oldTarget, sourceCRS, nullptr); + } } else { subOps.emplace_back(opFirst); } - if (isNullTransformation(opsThird[0]->nameStr())) { - opSecond->setCRSs(NN_CHECK_ASSERT(opSecond->sourceCRS()), - targetCRS, nullptr); - subOps.emplace_back(opSecond); + if (isNullThird) { + auto oldSource(NN_CHECK_ASSERT(opSecondCloned->sourceCRS())); + opSecondCloned->setCRSs(oldSource, targetCRS, nullptr); + if (invCOForward) { + invCOForward->setCRSs(targetCRS, oldSource, nullptr); + } + subOps.emplace_back(opSecondCloned); } else { - subOps.emplace_back(opSecond); + subOps.emplace_back(opSecondCloned); subOps.emplace_back(opsThird[0]); } +#ifdef DEBUG + std::string debugStr; + for (const auto &op : subOps) { + if (!debugStr.empty()) { + debugStr += " + "; + } + debugStr += objectAsStr(op.get()); + debugStr += " ("; + debugStr += objectAsStr(op->sourceCRS().get()); + debugStr += "->"; + debugStr += objectAsStr(op->targetCRS().get()); + debugStr += ")"; + } + debugTrace("transformation " + debugStr); +#endif res.emplace_back(ConcatenatedOperation::createComputeMetadata( subOps, !allowEmptyIntersection)); } @@ -11436,6 +11628,14 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( if (candidateSrcGeod->nameStr() == sourceCRS->nameStr()) { for (const auto &candidateDstGeod : candidatesDstGeod) { if (candidateDstGeod->nameStr() == targetCRS->nameStr()) { +#ifdef DEBUG + EnterDebugLevel loopLevel; + debugTrace("try " + objectAsStr(sourceCRS.get()) + "->" + + objectAsStr(candidateSrcGeod.get()) + "->" + + objectAsStr(candidateDstGeod.get()) + "->" + + objectAsStr(targetCRS.get()) + ")"); + EnterDebugLevel loopLevel2; +#endif const auto opsFirst = createOperations(sourceCRS, candidateSrcGeod, context); assert(!opsFirst.empty()); @@ -11454,17 +11654,28 @@ void CoordinateOperationFactory::Private::createOperationsWithDatumPivot( } for (const auto &candidateSrcGeod : candidatesSrcGeod) { +#ifdef DEBUG + EnterDebugLevel loopLevel; +#endif const auto opsFirst = createOperations(sourceCRS, candidateSrcGeod, context); assert(!opsFirst.empty()); const bool isNullFirst = isNullTransformation(opsFirst[0]->nameStr()); for (const auto &candidateDstGeod : candidatesDstGeod) { +#ifdef DEBUG + EnterDebugLevel loopLevel2; + debugTrace("try " + objectAsStr(sourceCRS.get()) + "->" + + objectAsStr(candidateSrcGeod.get()) + "->" + + objectAsStr(candidateDstGeod.get()) + "->" + + objectAsStr(targetCRS.get()) + ")"); + EnterDebugLevel loopLevel3; +#endif createTransformations(candidateSrcGeod, candidateDstGeod, opsFirst[0], isNullFirst); - } - if (!res.empty()) { - return; + if (!res.empty()) { + return; + } } } } @@ -11519,6 +11730,13 @@ CoordinateOperationFactory::Private::createOperations( const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, Private::Context &context) { +#ifdef DEBUG + EnterDebugLevel enterFunction; + auto debugStr("createOperations(" + objectAsStr(sourceCRS.get()) + "," + + objectAsStr(targetCRS.get()) + ")"); + debugTrace(debugStr); +#endif + std::vector res; const bool allowEmptyIntersection = true; @@ -11598,15 +11816,48 @@ CoordinateOperationFactory::Private::createOperations( doFilterAndCheckPerfectOp = false; + bool sameGeodeticDatum = false; + if (geodSrc && geodDst) { + const auto &srcDatum = geodSrc->datum(); + const auto &dstDatum = geodDst->datum(); + sameGeodeticDatum = + srcDatum != nullptr && dstDatum != nullptr && + srcDatum->_isEquivalentTo( + dstDatum.get(), + util::IComparable::Criterion::EQUIVALENT); + } + + if (res.empty() && !sameGeodeticDatum && + !context.inCreateOperationsWithDatumPivotAntiRecursion && + geodSrc && geodDst) { + // If we still didn't find a transformation, and that the source + // and target are GeodeticCRS, then go through their underlying + // datum to find potential transformations between other + // GeodeticRSs + // that are made of those datum + // The typical example is if transforming between two + // GeographicCRS, + // but transformations are only available between their + // corresponding geocentric CRS. + const auto &srcDatum = geodSrc->datum(); + const auto &dstDatum = geodDst->datum(); + if (srcDatum != nullptr && dstDatum != nullptr) { + createOperationsWithDatumPivot(res, sourceCRS, targetCRS, + geodSrc, geodDst, context); + doFilterAndCheckPerfectOp = !res.empty(); + } + } + // NAD27 to NAD83 has tens of results already. No need to look // for a pivot - if ((res.empty() && + if (!sameGeodeticDatum && + ((res.empty() && + context.context->getAllowUseIntermediateCRS() == + CoordinateOperationContext::IntermediateCRSUse:: + IF_NO_DIRECT_TRANSFORMATION) || context.context->getAllowUseIntermediateCRS() == - CoordinateOperationContext::IntermediateCRSUse:: - IF_NO_DIRECT_TRANSFORMATION) || - context.context->getAllowUseIntermediateCRS() == - CoordinateOperationContext::IntermediateCRSUse::ALWAYS || - getenv("PROJ_FORCE_SEARCH_PIVOT")) { + CoordinateOperationContext::IntermediateCRSUse::ALWAYS || + getenv("PROJ_FORCE_SEARCH_PIVOT"))) { auto resWithIntermediate = findsOpsInRegistryWithIntermediate( sourceCRS, targetCRS, context.context); res.insert(res.end(), resWithIntermediate.begin(), @@ -11615,27 +11866,6 @@ CoordinateOperationFactory::Private::createOperations( } } - if (res.empty() && - !context.inCreateOperationsWithDatumPivotAntiRecursion && geodSrc && - geodDst) { - // If we still didn't find a transformation, and that the source - // and target are GeodeticCRS, then go through their underlying - // datum to find potential transformations between other GeodeticRSs - // that are made of those datum - // The typical example is if transforming between two GeographicCRS, - // but transformations are only available between their - // corresponding geocentric CRS. - const auto &srcDatum = geodSrc->datum(); - const auto &dstDatum = geodDst->datum(); - if (srcDatum != nullptr && dstDatum != nullptr && - !srcDatum->_isEquivalentTo( - dstDatum.get(), util::IComparable::Criterion::EQUIVALENT)) { - createOperationsWithDatumPivot(res, sourceCRS, targetCRS, - geodSrc, geodDst, context); - doFilterAndCheckPerfectOp = !res.empty(); - } - } - if (doFilterAndCheckPerfectOp) { // If we get at least a result with perfect accuracy, do not bother // generating synthetic transforms. @@ -12459,8 +12689,9 @@ InverseCoordinateOperation::~InverseCoordinateOperation() = default; // --------------------------------------------------------------------------- InverseCoordinateOperation::InverseCoordinateOperation( - const CoordinateOperationNNPtr &forwardOperation, bool wktSupportsInversion) - : forwardOperation_(forwardOperation), + const CoordinateOperationNNPtr &forwardOperationIn, + bool wktSupportsInversion) + : forwardOperation_(forwardOperationIn), wktSupportsInversion_(wktSupportsInversion) {} // --------------------------------------------------------------------------- @@ -12651,6 +12882,15 @@ void PROJBasedOperation::_exportToPROJString( // --------------------------------------------------------------------------- +CoordinateOperationNNPtr PROJBasedOperation::_shallowClone() const { + auto op = PROJBasedOperation::nn_make_shared(*this); + op->assignSelf(op); + op->setCRSs(this, false); + return util::nn_static_pointer_cast(op); +} + +// --------------------------------------------------------------------------- + std::set PROJBasedOperation::gridsNeeded( const io::DatabaseContextPtr &databaseContext) const { std::set res; -- cgit v1.2.3 From 8ae2f83174808ac41324c33a749b9cb7ac7eca51 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 16 Apr 2019 22:02:26 +0200 Subject: omerc: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14279 Credit to OSS Fuzz --- src/projections/omerc.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index c0278043..e07c209e 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -201,6 +201,10 @@ PJ *PROJECTION(omerc) { L = pow(pj_tsfn(phi2, sin(phi2), P->e), Q->B); F = Q->E / H; p = (L - H) / (L + H); + if( p == 0 ) { + // Not quite, but es is very close to 1... + return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); + } J = Q->E * Q->E; J = (J - L * H) / (J + L * H); if ((con = lam1 - lam2) < -M_PI) -- cgit v1.2.3 From 7c543c30ba77b4a722b5b193f99af569b4ade41b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 16 Apr 2019 22:42:25 +0200 Subject: vgridshift: handle longitude wrap-around for grids with 360deg longitude extent Like egm96_15.gtx Fixes #1415 Technically, a similar fix could be done for horizontal grids, but world extent is less common for them. --- src/apply_vgridshift.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/apply_vgridshift.cpp b/src/apply_vgridshift.cpp index e73c6da7..377e36e0 100644 --- a/src/apply_vgridshift.cpp +++ b/src/apply_vgridshift.cpp @@ -28,6 +28,7 @@ #define PJ_LIB__ +#include #include #include @@ -62,9 +63,19 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * ct = gi->ct; - /* skip tables that don't match our point at all. */ - if( ct->ll.phi > input.phi || ct->ll.lam > input.lam - || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi + /* skip tables that don't match our point at all (latitude check). */ + if( ct->ll.phi > input.phi + || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi ) + continue; + + bool fullWorldLongExtent = false; + if( fabs(ct->lim.lam * ct->del.lam - 2 * M_PI) < 1e-10 ) + { + fullWorldLongExtent = true; + } + + /* skip tables that don't match our point at all (longitude check). */ + else if( ct->ll.lam > input.lam || ct->ll.lam + (ct->lim.lam-1) * ct->del.lam < input.lam ) continue; @@ -77,8 +88,17 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * { struct CTABLE *ct1 = child->ct; - if( ct1->ll.phi > input.phi || ct1->ll.lam > input.lam - || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi + fullWorldLongExtent = false; + + if( ct1->ll.phi > input.phi + || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi) + continue; + + if( fabs(ct1->lim.lam * ct1->del.lam - 2 * M_PI) < 1e-10 ) + { + fullWorldLongExtent = true; + } + else if( ct1->ll.lam > input.lam || ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam < input.lam) continue; @@ -109,15 +129,29 @@ static double read_vgrid_value( PJ *defn, PJ_LP input, double vmultiplier, int * /* Interpolation a location within the grid */ grid_x = (input.lam - ct->ll.lam) / ct->del.lam; + if( fullWorldLongExtent ) { + // The first fmod goes to ]-lim, lim[ range + // So we add lim again to be in ]0, 2*lim[ and fmod again + grid_x = fmod( + fmod(grid_x + ct->lim.lam, ct->lim.lam) + ct->lim.lam, + ct->lim.lam); + } grid_y = (input.phi - ct->ll.phi) / ct->del.phi; grid_ix = lround(floor(grid_x)); + assert(grid_ix >= 0 && grid_ix < ct->lim.lam); grid_iy = lround(floor(grid_y)); + assert(grid_iy >= 0 && grid_iy < ct->lim.phi); grid_x -= grid_ix; grid_y -= grid_iy; grid_ix2 = grid_ix + 1; - if( grid_ix2 >= ct->lim.lam ) - grid_ix2 = ct->lim.lam - 1; + if( grid_ix2 >= ct->lim.lam ) { + if( fullWorldLongExtent ) { + grid_ix2 = 0; + } else { + grid_ix2 = ct->lim.lam - 1; + } + } grid_iy2 = grid_iy + 1; if( grid_iy2 >= ct->lim.phi ) grid_iy2 = ct->lim.phi - 1; -- cgit v1.2.3 From adc03895800b192f72dc70213786ee708909b75e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 18 Apr 2019 11:06:34 +0200 Subject: Improve doc of proj_coordoperation_get_towgs84_values() (fixes #1430) --- src/iso19111/c_api.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 970d38d8..8fea51e9 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -5962,7 +5962,10 @@ int proj_coordoperation_get_param( * @param coordoperation Object of type Transformation, that can be represented * as a WKT1 TOWGS84 node (must not be NULL) * @param out_values Pointer to an array of value_count double values. - * @param value_count Size of out_values array. + * @param value_count Size of out_values array. The suggested size is 7 to get + * translation, rotation and scale difference parameters. Rotation and scale + * difference terms might be zero if the transformation only includes translation + * parameters. In that case, value_count could be set to 3. * @param emit_error_if_incompatible Boolean to inicate if an error must be * logged if coordoperation is not compatible with a WKT1 TOWGS84 * representation. -- cgit v1.2.3 From 4c8a5cb8c7f69dd227f03f32eb99b53ea0586aba Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 18 Apr 2019 22:12:55 +0200 Subject: isea: avoid invalid integer shift Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14286 Credit to OSS Fuzz --- src/projections/isea.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index 28510cb0..e8720b27 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -898,6 +898,10 @@ static int isea_hex(struct isea_dgg *g, int tri, quad = isea_ptdi(g, tri, pt, &v); + if( v.x < (INT_MIN >> 4) || v.x > (INT_MAX >> 4) ) + { + throw "Invalid shift"; + } hex->x = ((int)v.x << 4) + quad; hex->y = v.y; -- cgit v1.2.3 From 3f6c53ccee6062df95c595a0ea5b8cbed7e7f199 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 18 Apr 2019 22:19:59 +0200 Subject: tpers: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14342 Credit to OSS Fuzz --- src/projections/nsper.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/projections/nsper.cpp b/src/projections/nsper.cpp index a0bb5686..37938924 100644 --- a/src/projections/nsper.cpp +++ b/src/projections/nsper.cpp @@ -96,7 +96,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); - double rh, cosz, sinz; + double rh; if (Q->tilt) { double bm, bq, yt; @@ -108,16 +108,18 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ xy.y = bq * Q->cg - bm * Q->sg; } rh = hypot(xy.x, xy.y); - if ((sinz = 1. - rh * rh * Q->pfact) < 0.) { - proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); - return lp; - } - sinz = (Q->p - sqrt(sinz)) / (Q->pn1 / rh + rh / Q->pn1); - cosz = sqrt(1. - sinz * sinz); if (fabs(rh) <= EPS10) { lp.lam = 0.; lp.phi = P->phi0; } else { + double cosz, sinz; + sinz = 1. - rh * rh * Q->pfact; + if (sinz < 0.) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return lp; + } + sinz = (Q->p - sqrt(sinz)) / (Q->pn1 / rh + rh / Q->pn1); + cosz = sqrt(1. - sinz * sinz); switch (Q->mode) { case OBLIQ: lp.phi = asin(cosz * Q->sinph0 + xy.y * sinz * Q->cosph0 / rh); -- cgit v1.2.3 From 3ff04e06a2ba9d40ead861be0ebdb22af45eaa0d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 19 Apr 2019 14:21:42 +0200 Subject: Inverse cart: better deal with x,y,z equal of very close to zero In that case, for a non-spherical ellipsoid, a phi = 180deg was returned, which caused a division by zero in the foward path of moll.cpp Fixup the latitude to be 0 when that happens. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14348 Credit to OSS Fuzz --- src/conversions/cart.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/conversions/cart.cpp b/src/conversions/cart.cpp index e6942d65..c1f6f09d 100644 --- a/src/conversions/cart.cpp +++ b/src/conversions/cart.cpp @@ -162,6 +162,12 @@ static PJ_LPZ geodetic (PJ_XYZ cart, PJ *P) { c = cos(theta); s = sin(theta); lpz.phi = atan2 (cart.z + P->e2s*P->b*s*s*s, p - P->es*P->a*c*c*c); + if( fabs(lpz.phi) > M_HALFPI ) { + // this happen on non-sphere ellipsoid when x,y,z is very close to 0 + // there is no single solution to the cart->geodetic conversion in + // that case, so arbitrarily pickup phi = 0. + lpz.phi = 0; + } lpz.lam = atan2 (cart.y, cart.x); N = normal_radius_of_curvature (P->a, P->es, lpz.phi); -- cgit v1.2.3 From 8a31ed4036888ff2039919f8c998a90cb2143bc2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 19 Apr 2019 23:47:39 +0200 Subject: proj/cs2cs: validate value of -f parameter to avoid potential crashes (fixes #124) --- src/Makefile.am | 6 +++--- src/apps/cs2cs.cpp | 8 ++++++++ src/apps/proj.cpp | 9 ++++++++- src/apps/utils.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/apps/utils.h | 29 +++++++++++++++++++++++++++ src/bin_cs2cs.cmake | 1 + src/bin_proj.cmake | 1 + 7 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/apps/utils.cpp create mode 100644 src/apps/utils.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 9858d78f..a01ff2e6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,11 +16,11 @@ include_HEADERS = proj.h proj_experimental.h proj_constants.h proj_api.h geodesi EXTRA_DIST = bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \ bin_geod.cmake bin_proj.cmake bin_projinfo.cmake \ lib_proj.cmake CMakeLists.txt bin_geodtest.cmake tests/geodtest.cpp \ - wkt1_grammar.y wkt2_grammar.y apps/emess.h + wkt1_grammar.y wkt2_grammar.y apps/emess.h apps/utils.h -proj_SOURCES = apps/proj.cpp apps/emess.cpp +proj_SOURCES = apps/proj.cpp apps/emess.cpp apps/utils.cpp projinfo_SOURCES = apps/projinfo.cpp -cs2cs_SOURCES = apps/cs2cs.cpp apps/emess.cpp +cs2cs_SOURCES = apps/cs2cs.cpp apps/emess.cpp apps/utils.cpp cct_SOURCES = apps/cct.cpp apps/proj_strtod.cpp apps/proj_strtod.h apps/optargpm.h geod_SOURCES = apps/geod.cpp apps/geod_set.cpp apps/geod_interface.cpp apps/geod_interface.h apps/emess.cpp diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 877a68ff..40b0d584 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -45,6 +45,7 @@ #include "proj.h" #include "proj_internal.h" #include "emess.h" +#include "utils.h" // clang-format on #define MAX_LINE 1000 @@ -522,6 +523,13 @@ int main(int argc, char **argv) { if (eargc == 0) /* if no specific files force sysin */ eargv[eargc++] = const_cast("-"); + if( oform ) { + if( !validate_form_string_for_numbers(oform) ) { + emess(3, "invalid format string"); + exit(0); + } + } + /* * If the user has requested inverse, then just reverse the * coordinate systems. diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 2af49c34..888d723f 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -7,6 +7,7 @@ #include #include #include "emess.h" +#include "utils.h" #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__WIN32__) # include @@ -461,6 +462,13 @@ int main(int argc, char **argv) { if (eargc == 0) /* if no specific files force sysin */ eargv[eargc++] = const_cast("-"); + if( oform ) { + if( !validate_form_string_for_numbers(oform) ) { + emess(3, "invalid format string"); + exit(0); + } + } + /* done with parameter and control input */ if (inverse && postscale) { prescale = 1; @@ -487,7 +495,6 @@ int main(int argc, char **argv) { proj.inv = pj_inv; } else proj.fwd = pj_fwd; - /* set input formatting control */ if (mon) { pj_pr_list(Proj); diff --git a/src/apps/utils.cpp b/src/apps/utils.cpp new file mode 100644 index 00000000..7dc809c9 --- /dev/null +++ b/src/apps/utils.cpp @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Project: PROJ + * Purpose: Utilities for command line arguments + * Author: Even Rouault + * + ****************************************************************************** + * Copyright (c) 2019, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#include "utils.h" + +#include + +bool validate_form_string_for_numbers(const char* formatString) { + /* Only accepts '%[+]?[number]?[.]?[number]?[e|E|f|F|g|G]' */ + bool valid = true; + if( formatString[0] != '%' ) + valid = false; + else { + auto oformLen = strlen(formatString); + for( int i = 1; i < static_cast(oformLen) - 1; i++ ) { + if( !(formatString[i] == '.' || + formatString[i] == '+' || + (formatString[i] >= '0' && formatString[i] <= '9')) ) { + valid = false; + break; + } + } + if( valid ) { + valid = formatString[oformLen-1] == 'e' || + formatString[oformLen-1] == 'E' || + formatString[oformLen-1] == 'f' || + formatString[oformLen-1] == 'F' || + formatString[oformLen-1] == 'g' || + formatString[oformLen-1] == 'G'; + } + } + return valid; +} diff --git a/src/apps/utils.h b/src/apps/utils.h new file mode 100644 index 00000000..99c14091 --- /dev/null +++ b/src/apps/utils.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * + * Project: PROJ + * Purpose: Utilities for command line arguments + * Author: Even Rouault + * + ****************************************************************************** + * Copyright (c) 2019, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +bool validate_form_string_for_numbers(const char* formatString); diff --git a/src/bin_cs2cs.cmake b/src/bin_cs2cs.cmake index 7ee26673..d2bb3b97 100644 --- a/src/bin_cs2cs.cmake +++ b/src/bin_cs2cs.cmake @@ -1,6 +1,7 @@ set(CS2CS_SRC apps/cs2cs.cpp apps/emess.cpp + apps/utils.cpp ) source_group("Source Files\\Bin" FILES ${CS2CS_SRC}) diff --git a/src/bin_proj.cmake b/src/bin_proj.cmake index b9ae03e5..ce282fc6 100644 --- a/src/bin_proj.cmake +++ b/src/bin_proj.cmake @@ -1,6 +1,7 @@ set(PROJ_SRC apps/proj.cpp apps/emess.cpp + apps/utils.cpp ) source_group("Source Files\\Bin" FILES ${PROJ_SRC}) -- cgit v1.2.3 From 318dab0d074a7bfd9d0724e674777aa10422d4e6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 20 Apr 2019 17:49:37 +0200 Subject: omerc: validate lat_1 and lat_2 to avoid divison by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14384 Credit to OSS Fuzz --- src/projections/omerc.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index e07c209e..0de3aa7d 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -154,6 +154,8 @@ PJ *PROJECTION(omerc) { phi1 = pj_param(P->ctx, P->params, "rlat_1").f; lam2 = pj_param(P->ctx, P->params, "rlon_2").f; phi2 = pj_param(P->ctx, P->params, "rlat_2").f; + if (fabs(phi1) > M_HALFPI || fabs(phi2) > M_HALFPI) + return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90); if (fabs(phi1 - phi2) <= TOL || (con = fabs(phi1)) <= TOL || fabs(con - M_HALFPI) <= TOL || -- cgit v1.2.3 From f54f4556234dda885777343ae9b4594aba36c428 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Sun, 21 Apr 2019 16:46:29 +1200 Subject: CMake: enable LTO using a flag or property method --- src/lib_proj.cmake | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index f52f5327..5a0a8070 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -35,23 +35,36 @@ elseif(USE_THREAD AND NOT Threads_FOUND) "required by USE_THREAD option") endif() -option(ENABLE_LTO "Build library with LTO optimization (if available)." OFF) +option(ENABLE_LTO + "Build library with LTO/IPO optimization (if available)." OFF) if(ENABLE_LTO) - # TODO: CMake v3.9 use CheckIPOSupported and set property; see - # https://cmake.org/cmake/help/v3.9/module/CheckIPOSupported.html - if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") - include(CheckCXXSourceCompiles) - set(CMAKE_REQUIRED_FLAGS "-Wl,-flto") - check_cxx_source_compiles("int main(){ return 0; }" - COMPILER_SUPPORTS_FLTO_FLAG) - elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") - # Set INTERPROCEDURAL_OPTIMIZATION property later - set(COMPILER_SUPPORTS_FLTO_FLAG TRUE) - else() - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_FLTO_FLAG) + # Determine ENABLE_LTO_METHOD to either "flag" or "property" + if(CMAKE_C_COMPILER_ID STREQUAL "Intel" + AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(ENABLE_LTO_METHOD "property") + elseif(CMAKE_VERSION VERSION_LESS 3.9) + # Maual checks required + if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_FLAGS "-Wl,-flto") + check_cxx_source_compiles("int main(){ return 0; }" + COMPILER_SUPPORTS_FLTO_FLAG) + else() + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("-flto" COMPILER_SUPPORTS_FLTO_FLAG) + endif() + set(ENABLE_LTO_METHOD "flag") + if(NOT COMPILER_SUPPORTS_FLTO_FLAG) + set(ENABLE_LTO OFF) + endif() + else() # CMake v3.9 + cmake_policy(SET CMP0069 NEW) + include(CheckIPOSupported) + check_ipo_supported(RESULT ENABLE_LTO) + set(ENABLE_LTO_METHOD "property") endif() endif() +boost_report_value(ENABLE_LTO) ############################################## @@ -370,14 +383,12 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") PROPERTIES COMPILE_FLAGS ${FP_PRECISE}) endif() -if(COMPILER_SUPPORTS_FLTO_FLAG) - if("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") - # Intel supported only, before v3.9 +if(ENABLE_LTO) + if(ENABLE_LTO_METHOD STREQUAL "property") set_property(TARGET ${PROJ_CORE_TARGET} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) - else() - # Pre CMake v3.9 needs to set flag for other compilers - # see https://gitlab.kitware.com/cmake/cmake/issues/15245 + elseif(ENABLE_LTO_METHOD STREQUAL "flag") + # pre-CMake 3.9 workaround target_compile_options(${PROJ_CORE_TARGET} PRIVATE -flto) endif() endif() -- cgit v1.2.3 From e63f206d994658995505ce322d644fba0b807d5b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 21 Apr 2019 21:51:43 +0200 Subject: Database: make conversion & helmert_transformation updatable views - Transform conversion as a view, and when inserting into it, actually insert into 3 tables: conversion_table, conversion_method and conversion_param, so that method and parameter names are not repeated each time. - Similarly for helmert_tranformation, insert into helmert_transformation_tabl and coordinate_operation_method. This reduces the db size from 6 344 704 bytes to 5 853 184 bytes, without significant slowdown for queries. --- src/iso19111/factory.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index f24b3457..0f19c44a 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -614,11 +614,16 @@ void DatabaseContext::Private::setHandle(sqlite3 *sqlite_handle) { // --------------------------------------------------------------------------- std::vector DatabaseContext::Private::getDatabaseStructure() { - auto sqlRes = run("SELECT sql FROM sqlite_master WHERE type " - "IN ('table', 'trigger', 'view') ORDER BY type"); + const char *sqls[] = { + "SELECT sql FROM sqlite_master WHERE type = 'table'", + "SELECT sql FROM sqlite_master WHERE type = 'view'", + "SELECT sql FROM sqlite_master WHERE type = 'trigger'"}; std::vector res; - for (const auto &row : sqlRes) { - res.emplace_back(row[0]); + for (const auto &sql : sqls) { + auto sqlRes = run(sql); + for (const auto &row : sqlRes) { + res.emplace_back(row[0]); + } } return res; } @@ -3929,13 +3934,16 @@ std::list AuthorityFactory::getCRSInfoList() const { sql += "SELECT c.auth_name, c.code, c.name, 'projected', " "c.deprecated, " "a.west_lon, a.south_lat, a.east_lon, a.north_lat, " - "a.name, conv.method_name FROM projected_crs c " + "a.name, cm.name AS conversion_method_name FROM projected_crs c " "JOIN area a ON " "c.area_of_use_auth_name = a.auth_name AND " "c.area_of_use_code = a.code " - "LEFT JOIN conversion conv ON " + "LEFT JOIN conversion_table conv ON " "c.conversion_auth_name = conv.auth_name AND " - "c.conversion_code = conv.code"; + "c.conversion_code = conv.code " + "LEFT JOIN conversion_method cm ON " + "conv.method_auth_name = cm.auth_name AND " + "conv.method_code = cm.code"; if (d->hasAuthorityRestriction()) { sql += " WHERE c.auth_name = ?"; params.emplace_back(d->authority()); @@ -4658,9 +4666,9 @@ AuthorityFactory::createProjectedCRSFromExisting( std::string sql( "SELECT projected_crs.auth_name, projected_crs.code FROM projected_crs " - "JOIN conversion ON " - "projected_crs.conversion_auth_name = conversion.auth_name AND " - "projected_crs.conversion_code = conversion.code WHERE " + "JOIN conversion_table conv ON " + "projected_crs.conversion_auth_name = conv.auth_name AND " + "projected_crs.conversion_code = conv.code WHERE " "projected_crs.deprecated = 0 AND "); ListOfParams params; if (!candidatesGeodCRS.empty()) { @@ -4668,8 +4676,8 @@ AuthorityFactory::createProjectedCRSFromExisting( "projected_crs.geodetic_crs_"); sql += " AND "; } - sql += "conversion.method_auth_name = 'EPSG' AND " - "conversion.method_code = ?"; + sql += "conv.method_auth_name = 'EPSG' AND " + "conv.method_code = ?"; params.emplace_back(toString(methodEPSGCode)); if (d->hasAuthorityRestriction()) { sql += " AND projected_crs.auth_name = ?"; @@ -4696,11 +4704,11 @@ AuthorityFactory::createProjectedCRSFromExisting( if (unit == common::UnitOfMeasure::DEGREE && geogCRS->coordinateSystem()->axisList()[0]->unit() == unit) { const auto iParamAsStr(toString(iParam)); - sql += " AND conversion.param"; + sql += " AND conv.param"; sql += iParamAsStr; - sql += "_code = ? AND conversion.param"; + sql += "_code = ? AND conv.param"; sql += iParamAsStr; - sql += "_auth_name = 'EPSG' AND conversion.param"; + sql += "_auth_name = 'EPSG' AND conv.param"; sql += iParamAsStr; sql += "_value BETWEEN ? AND ?"; // As angles might be expressed with the odd unit EPSG:9110 -- cgit v1.2.3 From d8526d7870e4b91238c9a7b652ed03c21b77e884 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 13:15:02 +0200 Subject: ESRI_WKT: preserve Gauss_Kruger in conversion name for round-tripping --- src/iso19111/c_api.cpp | 3 ++- src/iso19111/coordinateoperation.cpp | 9 +++++---- src/iso19111/io.cpp | 5 ++++- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 8fea51e9..6a2a1ae0 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -5964,7 +5964,8 @@ int proj_coordoperation_get_param( * @param out_values Pointer to an array of value_count double values. * @param value_count Size of out_values array. The suggested size is 7 to get * translation, rotation and scale difference parameters. Rotation and scale - * difference terms might be zero if the transformation only includes translation + * difference terms might be zero if the transformation only includes + * translation * parameters. In that case, value_count could be set to 3. * @param emit_error_if_incompatible Boolean to inicate if an error must be * logged if coordoperation is not compatible with a WKT1 TOWGS84 diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 7eab849c..0b4e7912 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -5120,10 +5120,11 @@ static void getESRIMethodNameAndParams(const Conversion *conv, } } else if (esriMapping->epsg_code == EPSG_CODE_METHOD_TRANSVERSE_MERCATOR) { - if (l_targetCRS && - (ci_find(l_targetCRS->nameStr(), "Gauss") != - std::string::npos || - ci_find(l_targetCRS->nameStr(), "GK_") != std::string::npos)) { + if (ci_find(conv->nameStr(), "Gauss Kruger") != std::string::npos || + (l_targetCRS && (ci_find(l_targetCRS->nameStr(), "Gauss") != + std::string::npos || + ci_find(l_targetCRS->nameStr(), "GK_") != + std::string::npos))) { esriParams = paramsESRI_Gauss_Kruger; esriMethodName = "Gauss_Kruger"; } else { diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 360d55a2..399908eb 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -3257,7 +3257,10 @@ ConversionNNPtr WKTParser::Private::buildProjectionFromESRI( } return Conversion::create( - PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), + PropertyMap().set(IdentifiedObject::NAME_KEY, + esriProjectionName == "Gauss_Kruger" + ? "unnnamed (Gauss Kruger)" + : "unnamed"), propertiesMethod, parameters, values) ->identify(); } -- cgit v1.2.3 From 17b2607deff4e939255ef7747c5887887ad3b7d7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 13:15:33 +0200 Subject: Database: import common projections from ESRI projected CRS in structured form That is Transverse_Mercator/Gauss_Kruger, Lambert_Conformal_Conic and Hotine_Oblique_Mercator_Azimuth_Natural_Origin Decreases proj.db from 5 853 184 bytes to 5 189 632 bytes. --- src/iso19111/factory.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 0f19c44a..e683c485 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2413,6 +2413,11 @@ AuthorityFactory::createProjectedCRS(const std::string &code) const { auto conv = d->createFactory(conversion_auth_name) ->createConversion(conversion_code); + if (conv->nameStr() == "unnamed") { + conv = conv->shallowClone(); + conv->setProperties(util::PropertyMap().set( + common::IdentifiedObject::NAME_KEY, name)); + } auto cartesianCS = util::nn_dynamic_pointer_cast(cs); if (cartesianCS) { -- cgit v1.2.3 From 1c677ed192125ddc0eb4b90b24b80d9820769dd0 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 15:27:33 +0200 Subject: Tweak morphNameToESRI() to reflect current ESRI practice regarding a few '(foo)' suffixes --- src/iso19111/io.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 399908eb..4a38a057 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -757,13 +757,22 @@ const std::string &WKTFormatter::getHDatumExtension() const { // --------------------------------------------------------------------------- std::string WKTFormatter::morphNameToESRI(const std::string &name) { + + for (const auto *suffix : {"(m)", "(ftUS)", "(E-N)", "(N-E)"}) { + if (ends_with(name, suffix)) { + return morphNameToESRI( + name.substr(0, name.size() - strlen(suffix))) + + suffix; + } + } + std::string ret; bool insertUnderscore = false; // Replace any special character by underscore, except at the beginning // and of the name where those characters are removed. for (char ch : name) { - if (ch == '+' || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || - (ch >= 'A' && ch <= 'Z')) { + if (ch == '+' || ch == '-' || (ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { if (insertUnderscore && !ret.empty()) { ret += '_'; } -- cgit v1.2.3 From 1b0c6fbc8b90522983b18772303ff517dec21cd5 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 18:01:09 +0200 Subject: airy: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14410 Credit to OSS Fuzz --- src/projections/airy.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/projections/airy.cpp b/src/projections/airy.cpp index f7068061..ba6a40ff 100644 --- a/src/projections/airy.cpp +++ b/src/projections/airy.cpp @@ -79,6 +79,10 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } if (fabs(s = 1. - cosz) > EPS) { t = 0.5 * (1. + cosz); + if(t == 0) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return xy; + } Krho = -log(t)/s - Q->Cb / t; } else Krho = 0.5 - Q->Cb; -- cgit v1.2.3 From 1ebec58e22cce57310f40fa5a455b0b89c7f19b6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 19:13:45 +0200 Subject: code format fix --- src/iso19111/c_api.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 8fea51e9..6a2a1ae0 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -5964,7 +5964,8 @@ int proj_coordoperation_get_param( * @param out_values Pointer to an array of value_count double values. * @param value_count Size of out_values array. The suggested size is 7 to get * translation, rotation and scale difference parameters. Rotation and scale - * difference terms might be zero if the transformation only includes translation + * difference terms might be zero if the transformation only includes + * translation * parameters. In that case, value_count could be set to 3. * @param emit_error_if_incompatible Boolean to inicate if an error must be * logged if coordoperation is not compatible with a WKT1 TOWGS84 -- cgit v1.2.3 From 292807eee9e1194175b64cb5c0a9f0b432352abc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 20:05:36 +0200 Subject: proj_create(): add support for compoundCRS and concatenatedOperation named from their components Support following syntaxes: - OGC URN combining references for compoundCRS: e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" - its GDAL shortcut: e.g. "EPSG:2393+5717" - OGC URN combining references for concatenated operations: e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618" --- src/iso19111/factory.cpp | 5 +++ src/iso19111/io.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index f24b3457..9f7467a2 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2484,6 +2484,8 @@ crs::CRSNNPtr AuthorityFactory::createCoordinateReferenceSystem( return createCoordinateReferenceSystem(code, true); } +//! @cond Doxygen_Suppress + crs::CRSNNPtr AuthorityFactory::createCoordinateReferenceSystem(const std::string &code, bool allowCompound) const { @@ -2513,6 +2515,9 @@ AuthorityFactory::createCoordinateReferenceSystem(const std::string &code, } throw FactoryException("unhandled CRS type: " + type); } + +//! @endcond + // --------------------------------------------------------------------------- //! @cond Doxygen_Suppress diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 360d55a2..d8282bb0 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4397,15 +4397,97 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, const auto authorities = dbContextNNPtr->getAuthorities(); for (const auto &authCandidate : authorities) { if (ci_equal(authCandidate, authName)) { - return AuthorityFactory::create(dbContextNNPtr, - authCandidate) - ->createCoordinateReferenceSystem(code); + factory = + AuthorityFactory::create(dbContextNNPtr, authCandidate); + try { + return factory->createCoordinateReferenceSystem(code); + } catch (...) { + // EPSG:4326+3855 + auto tokensCode = split(code, '+'); + if (tokensCode.size() == 2) { + auto crs1(factory->createCoordinateReferenceSystem( + tokensCode[0], false)); + auto crs2(factory->createCoordinateReferenceSystem( + tokensCode[1], false)); + return CompoundCRS::create( + util::PropertyMap().set( + IdentifiedObject::NAME_KEY, + crs1->nameStr() + " + " + crs2->nameStr()), + {crs1, crs2}); + } + throw; + } } } throw; } } + // OGC 07-092r2: para 7.5.2 + // URN combined references for compound coordinate reference systems + if (starts_with(text, "urn:ogc:def:crs,")) { + if (!dbContext) { + throw ParsingException("no database context specified"); + } + auto tokensComma = split(text, ','); + std::vector components; + std::string name; + for (size_t i = 1; i < tokensComma.size(); i++) { + tokens = split(tokensComma[i], ':'); + if (tokens.size() != 4) { + throw ParsingException( + concat("invalid crs component: ", tokensComma[i])); + } + const auto &type = tokens[0]; + auto factory = + AuthorityFactory::create(NN_NO_CHECK(dbContext), tokens[1]); + const auto &code = tokens[3]; + if (type == "crs") { + auto crs(factory->createCoordinateReferenceSystem(code, false)); + components.emplace_back(crs); + if (!name.empty()) { + name += " + "; + } + name += crs->nameStr(); + } else { + throw ParsingException( + concat("unexpected object type: ", type)); + } + } + return CompoundCRS::create( + util::PropertyMap().set(IdentifiedObject::NAME_KEY, name), + components); + } + + // OGC 07-092r2: para 7.5.3 + // 7.5.3 URN combined references for concatenated operations + if (starts_with(text, "urn:ogc:def:coordinateOperation,")) { + if (!dbContext) { + throw ParsingException("no database context specified"); + } + auto tokensComma = split(text, ','); + std::vector components; + for (size_t i = 1; i < tokensComma.size(); i++) { + tokens = split(tokensComma[i], ':'); + if (tokens.size() != 4) { + throw ParsingException(concat( + "invalid coordinateOperation component: ", tokensComma[i])); + } + const auto &type = tokens[0]; + auto factory = + AuthorityFactory::create(NN_NO_CHECK(dbContext), tokens[1]); + const auto &code = tokens[3]; + if (type == "coordinateOperation") { + auto op(factory->createCoordinateOperation(code, false)); + components.emplace_back(op); + } else { + throw ParsingException( + concat("unexpected object type: ", type)); + } + } + return ConcatenatedOperation::createComputeMetadata(components, true); + } + // urn:ogc:def:crs:EPSG::4326 if (tokens.size() == 7) { if (!dbContext) { @@ -4510,6 +4592,13 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, * "urn:ogc:def:coordinateOperation:EPSG::1671", * "urn:ogc:def:ellipsoid:EPSG::7001" * or "urn:ogc:def:datum:EPSG::6326" + *
  • OGC URN combining references for compound coordinate reference systems + * e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" + * We also accept a custom abbreviated syntax EPSG:2393+5717 + *
  • + *
  • OGC URN combining references for concatenated operations + * e.g. + * "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618"
  • *
  • an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
  • @@ -4546,6 +4635,13 @@ BaseObjectNNPtr createFromUserInput(const std::string &text, * "urn:ogc:def:coordinateOperation:EPSG::1671", * "urn:ogc:def:ellipsoid:EPSG::7001" * or "urn:ogc:def:datum:EPSG::6326" + *
  • OGC URN combining references for compound coordinate reference systems + * e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" + * We also accept a custom abbreviated syntax EPSG:2393+5717 + *
  • + *
  • OGC URN combining references for concatenated operations + * e.g. + * "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618"
  • *
  • an Object name. e.g "WGS 84", "WGS 84 / UTM zone 31N". In that case as * uniqueness is not guaranteed, the function may apply heuristics to * determine the appropriate best match.
  • -- cgit v1.2.3 From 9215789383f4f56a2d989a07bfcbddcaf7ee4736 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 25 Apr 2019 13:55:46 +0200 Subject: gs50 and other mod_ster projections: avoid divison by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14421 Credit to OSS Fuzz --- src/projections/mod_ster.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/mod_ster.cpp b/src/projections/mod_ster.cpp index b26ea289..50f66839 100644 --- a/src/projections/mod_ster.cpp +++ b/src/projections/mod_ster.cpp @@ -35,7 +35,12 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ pow((1. - esphi) / (1. + esphi), P->e * .5)) - M_HALFPI; schi = sin(chi); cchi = cos(chi); - s = 2. / (1. + Q->schio * schi + Q->cchio * cchi * coslon); + const double denom = 1. + Q->schio * schi + Q->cchio * cchi * coslon; + if( denom == 0 ) { + proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); + return xy; + } + s = 2. / denom; p.r = s * cchi * sinlon; p.i = s * (Q->cchio * schi - Q->schio * cchi * coslon); p = pj_zpoly1(p, Q->zcoeff, Q->n); -- cgit v1.2.3 From c783e556835d2a4be85a20ee62bea8b13de3b841 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 26 Apr 2019 17:52:42 +0200 Subject: aitoff.cpp: fix indentation --- src/projections/aitoff.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp index 127841ff..639eeb87 100644 --- a/src/projections/aitoff.cpp +++ b/src/projections/aitoff.cpp @@ -116,15 +116,15 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ sl = sin(lp.lam * 0.5); cl = cos(lp.lam * 0.5); sp = sin(lp.phi); cp = cos(lp.phi); D = cp * cl; - C = 1. - D * D; + C = 1. - D * D; D = acos(D) / pow(C, 1.5); - f1 = 2. * D * C * cp * sl; - f2 = D * C * sp; - f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl); - f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp; - f2p = sp * sp * cl / C + D * sl * sl * cp; - f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl); - if (Q->mode == WINKEL_TRIPEL) { + f1 = 2. * D * C * cp * sl; + f2 = D * C * sp; + f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl); + f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp; + f2p = sp * sp * cl / C + D * sl * sl * cp; + f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl); + if (Q->mode == WINKEL_TRIPEL) { f1 = 0.5 * (f1 + lp.lam * Q->cosphi1); f2 = 0.5 * (f2 + lp.phi); f1p *= 0.5; @@ -156,10 +156,10 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ } while (((fabs(xy.x-x) > EPSILON) || (fabs(xy.y-y) > EPSILON)) && (round++ < MAXROUND)); if (iter == MAXITER && round == MAXROUND) - { - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); - /* fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); */ - } + { + pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + /* fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); */ + } return lp; } -- cgit v1.2.3 From 210df01d861f4d75b3e4c698b9394d6d48989169 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 26 Apr 2019 18:09:04 +0200 Subject: aitof: fix division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14447 Credit to OSS Fuzz --- src/projections/aitoff.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp index 639eeb87..23554605 100644 --- a/src/projections/aitoff.cpp +++ b/src/projections/aitoff.cpp @@ -117,7 +117,12 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ sp = sin(lp.phi); cp = cos(lp.phi); D = cp * cl; C = 1. - D * D; - D = acos(D) / pow(C, 1.5); + const double denom = pow(C, 1.5); + if( denom == 0 ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return lp; + } + D = acos(D) / denom; f1 = 2. * D * C * cp * sl; f2 = D * C * sp; f1p = 2.* (sl * cl * sp * cp / C - D * sp * sl); -- cgit v1.2.3 From 00980bf63fae6d350f425c44a648f33d7c09a931 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 26 Apr 2019 18:18:30 +0200 Subject: Prefix inverse and forward functions by their projection names This is mostly to have better OSSFuzz report. Currently a lot of bug summaries are like `proj4/standard_fuzzer: Divide-by-zero in s_inverse` By prefixing the projection name, we will get better reports, like `Divide-by-zero in airy_s_inverse` This also makes it slightly easier to set a breakpoint by function name. --- src/projections/aea.cpp | 8 ++++---- src/projections/aeqd.cpp | 16 ++++++++-------- src/projections/airy.cpp | 4 ++-- src/projections/aitoff.cpp | 10 +++++----- src/projections/august.cpp | 4 ++-- src/projections/bacon.cpp | 8 ++++---- src/projections/bertin1953.cpp | 4 ++-- src/projections/bipc.cpp | 8 ++++---- src/projections/boggs.cpp | 4 ++-- src/projections/bonne.cpp | 16 ++++++++-------- src/projections/calcofi.cpp | 16 ++++++++-------- src/projections/cass.cpp | 16 ++++++++-------- src/projections/cc.cpp | 8 ++++---- src/projections/ccon.cpp | 8 ++++---- src/projections/cea.cpp | 16 ++++++++-------- src/projections/chamb.cpp | 4 ++-- src/projections/collg.cpp | 8 ++++---- src/projections/comill.cpp | 8 ++++---- src/projections/crast.cpp | 8 ++++---- src/projections/denoy.cpp | 4 ++-- src/projections/eck1.cpp | 8 ++++---- src/projections/eck2.cpp | 8 ++++---- src/projections/eck3.cpp | 8 ++++---- src/projections/eck4.cpp | 8 ++++---- src/projections/eck5.cpp | 8 ++++---- src/projections/eqc.cpp | 8 ++++---- src/projections/eqdc.cpp | 8 ++++---- src/projections/eqearth.cpp | 8 ++++---- src/projections/fahey.cpp | 8 ++++---- src/projections/fouc_s.cpp | 8 ++++---- src/projections/gall.cpp | 8 ++++---- src/projections/geos.cpp | 16 ++++++++-------- src/projections/gins8.cpp | 4 ++-- src/projections/gn_sinu.cpp | 16 ++++++++-------- src/projections/gnom.cpp | 8 ++++---- src/projections/goode.cpp | 8 ++++---- src/projections/gstmerc.cpp | 8 ++++---- src/projections/hammer.cpp | 8 ++++---- src/projections/hatano.cpp | 8 ++++---- src/projections/healpix.cpp | 10 +++++----- src/projections/igh.cpp | 8 ++++---- src/projections/imw_p.cpp | 8 ++++---- src/projections/isea.cpp | 4 ++-- src/projections/krovak.cpp | 8 ++++---- src/projections/labrd.cpp | 8 ++++---- src/projections/laea.cpp | 16 ++++++++-------- src/projections/lagrng.cpp | 8 ++++---- src/projections/larr.cpp | 4 ++-- src/projections/lask.cpp | 4 ++-- src/projections/lcc.cpp | 8 ++++---- src/projections/lcca.cpp | 8 ++++---- src/projections/loxim.cpp | 8 ++++---- src/projections/lsat.cpp | 8 ++++---- src/projections/mbt_fps.cpp | 8 ++++---- src/projections/mbtfpp.cpp | 8 ++++---- src/projections/mbtfpq.cpp | 8 ++++---- src/projections/merc.cpp | 20 ++++++++++---------- src/projections/mill.cpp | 8 ++++---- src/projections/misrsom.cpp | 8 ++++---- src/projections/mod_ster.cpp | 8 ++++---- src/projections/moll.cpp | 12 ++++++------ src/projections/natearth.cpp | 8 ++++---- src/projections/natearth2.cpp | 8 ++++---- src/projections/nell.cpp | 8 ++++---- src/projections/nell_h.cpp | 8 ++++---- src/projections/nicol.cpp | 4 ++-- src/projections/nsper.cpp | 8 ++++---- src/projections/nzmg.cpp | 8 ++++---- src/projections/ocea.cpp | 8 ++++---- src/projections/oea.cpp | 8 ++++---- src/projections/omerc.cpp | 8 ++++---- src/projections/ortho.cpp | 8 ++++---- src/projections/patterson.cpp | 8 ++++---- src/projections/poly.cpp | 16 ++++++++-------- src/projections/putp2.cpp | 8 ++++---- src/projections/putp3.cpp | 12 ++++++------ src/projections/putp4p.cpp | 12 ++++++------ src/projections/putp5.cpp | 12 ++++++------ src/projections/putp6.cpp | 12 ++++++------ src/projections/qsc.cpp | 8 ++++---- src/projections/robin.cpp | 8 ++++---- src/projections/rouss.cpp | 8 ++++---- src/projections/rpoly.cpp | 4 ++-- src/projections/sch.cpp | 8 ++++---- src/projections/sconics.cpp | 8 ++++---- src/projections/somerc.cpp | 8 ++++---- src/projections/stere.cpp | 16 ++++++++-------- src/projections/sterea.cpp | 8 ++++---- src/projections/sts.cpp | 8 ++++---- src/projections/tcc.cpp | 4 ++-- src/projections/tcea.cpp | 8 ++++---- src/projections/times.cpp | 8 ++++---- src/projections/tobmerc.cpp | 8 ++++---- src/projections/tpeqd.cpp | 8 ++++---- src/projections/urm5.cpp | 4 ++-- src/projections/urmfps.cpp | 8 ++++---- src/projections/vandg.cpp | 8 ++++---- src/projections/vandg2.cpp | 6 +++--- src/projections/vandg4.cpp | 4 ++-- src/projections/wag2.cpp | 8 ++++---- src/projections/wag3.cpp | 8 ++++---- src/projections/wag7.cpp | 4 ++-- src/projections/wink1.cpp | 8 ++++---- src/projections/wink2.cpp | 4 ++-- 104 files changed, 439 insertions(+), 439 deletions(-) (limited to 'src') diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp index e488ddd9..721ea3c9 100644 --- a/src/projections/aea.cpp +++ b/src/projections/aea.cpp @@ -99,7 +99,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoid/spheroid, forward */ +static PJ_XY aea_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoid/spheroid, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); Q->rho = Q->c - (Q->ellips ? Q->n * pj_qsfn(sin(lp.phi), P->e, P->one_es) : Q->n2 * sin(lp.phi));; @@ -114,7 +114,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoid/spheroid, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoid/spheroid, inverse */ +static PJ_LP aea_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoid/spheroid, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); if( (Q->rho = hypot(xy.x, xy.y = Q->rho0 - xy.y)) != 0.0 ) { @@ -152,8 +152,8 @@ static PJ *setup(PJ *P) { int secant; struct pj_opaque *Q = static_cast(P->opaque); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = aea_e_inverse; + P->fwd = aea_e_forward; if (fabs(Q->phi1) > M_HALFPI || fabs(Q->phi2) > M_HALFPI) return destructor(P, PJD_ERR_LAT_LARGER_THAN_90); diff --git a/src/projections/aeqd.cpp b/src/projections/aeqd.cpp index 882d9531..04c3662e 100644 --- a/src/projections/aeqd.cpp +++ b/src/projections/aeqd.cpp @@ -91,7 +91,7 @@ static PJ_XY e_guam_fwd(PJ_LP lp, PJ *P) { /* Guam elliptical */ } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY aeqd_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi, rho; @@ -130,7 +130,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY aeqd_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi; @@ -195,7 +195,7 @@ static PJ_LP e_guam_inv(PJ_XY xy, PJ *P) { /* Guam elliptical */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP aeqd_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c; @@ -227,7 +227,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP aeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cosc, c_rh, sinc; @@ -291,8 +291,8 @@ PJ *PROJECTION(aeqd) { Q->cosph0 = cos(P->phi0); } if (P->es == 0.0) { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = aeqd_s_inverse; + P->fwd = aeqd_s_forward; } else { if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor (P, 0); @@ -315,8 +315,8 @@ PJ *PROJECTION(aeqd) { Q->He *= Q->cosph0; break; } - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = aeqd_e_inverse; + P->fwd = aeqd_e_forward; } } diff --git a/src/projections/airy.cpp b/src/projections/airy.cpp index ba6a40ff..91b4b7a2 100644 --- a/src/projections/airy.cpp +++ b/src/projections/airy.cpp @@ -58,7 +58,7 @@ struct pj_opaque { # define EPS 1.e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY airy_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz; @@ -151,7 +151,7 @@ PJ *PROJECTION(airy) { Q->cosph0 = cos(P->phi0); } } - P->fwd = s_forward; + P->fwd = airy_s_forward; P->es = 0.; return P; } diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp index 23554605..dadae12d 100644 --- a/src/projections/aitoff.cpp +++ b/src/projections/aitoff.cpp @@ -58,11 +58,11 @@ PROJ_HEAD(wintri, "Winkel Tripel") "\n\tMisc Sph\n\tlat_1"; #if 0 -FORWARD(s_forward); /* spheroid */ +FORWARD(aitoff_s_forward); /* spheroid */ #endif -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY aitoff_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c, d; @@ -100,7 +100,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ * ************************************************************************************/ -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP aitoff_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int iter, MAXITER = 10, round = 0, MAXROUND = 20; @@ -171,8 +171,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ static PJ *setup(PJ *P) { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = aitoff_s_inverse; + P->fwd = aitoff_s_forward; P->es = 0.; return P; } diff --git a/src/projections/august.cpp b/src/projections/august.cpp index 3523034e..2104c3cc 100644 --- a/src/projections/august.cpp +++ b/src/projections/august.cpp @@ -9,7 +9,7 @@ PROJ_HEAD(august, "August Epicycloidal") "\n\tMisc Sph, no inv"; #define M 1.333333333333333 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY august_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double t, c1, c, x1, x12, y1, y12; (void) P; @@ -29,7 +29,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(august) { P->inv = nullptr; - P->fwd = s_forward; + P->fwd = august_s_forward; P->es = 0.; return P; } diff --git a/src/projections/bacon.cpp b/src/projections/bacon.cpp index c713a989..5db2d854 100644 --- a/src/projections/bacon.cpp +++ b/src/projections/bacon.cpp @@ -20,7 +20,7 @@ PROJ_HEAD(ortel, "Ortelius Oval") "\n\tMisc Sph, no inv"; PROJ_HEAD(bacon, "Bacon Globular") "\n\tMisc Sph, no inv"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY bacon_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double ax, f; @@ -50,7 +50,7 @@ PJ *PROJECTION(bacon) { Q->bacn = 1; Q->ortl = 0; P->es = 0.; - P->fwd = s_forward; + P->fwd = bacon_s_forward; return P; } @@ -63,7 +63,7 @@ PJ *PROJECTION(apian) { Q->bacn = Q->ortl = 0; P->es = 0.; - P->fwd = s_forward; + P->fwd = bacon_s_forward; return P; } @@ -77,6 +77,6 @@ PJ *PROJECTION(ortel) { Q->bacn = 0; Q->ortl = 1; P->es = 0.; - P->fwd = s_forward; + P->fwd = bacon_s_forward; return P; } diff --git a/src/projections/bertin1953.cpp b/src/projections/bertin1953.cpp index add9f0b3..63154084 100644 --- a/src/projections/bertin1953.cpp +++ b/src/projections/bertin1953.cpp @@ -27,7 +27,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { +static PJ_XY bertin1953_s_forward (PJ_LP lp, PJ *P) { PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -89,7 +89,7 @@ PJ *PROJECTION(bertin1953) { Q->sin_delta_gamma = 0.; P->es = 0.; - P->fwd = s_forward; + P->fwd = bertin1953_s_forward; return P; } diff --git a/src/projections/bipc.cpp b/src/projections/bipc.cpp index 5cfef11f..9fd2fc6f 100644 --- a/src/projections/bipc.cpp +++ b/src/projections/bipc.cpp @@ -36,7 +36,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY bipc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r; @@ -113,7 +113,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP bipc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t, r, rp, rl, al, z = 0.0, fAz, Az, s, c, Av; @@ -169,8 +169,8 @@ PJ *PROJECTION(bipc) { P->opaque = Q; Q->noskew = pj_param(P->ctx, P->params, "bns").i; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = bipc_s_inverse; + P->fwd = bipc_s_forward; P->es = 0.; return P; } diff --git a/src/projections/boggs.cpp b/src/projections/boggs.cpp index 5502d493..e7278904 100644 --- a/src/projections/boggs.cpp +++ b/src/projections/boggs.cpp @@ -12,7 +12,7 @@ PROJ_HEAD(boggs, "Boggs Eumorphic") "\n\tPCyl, no inv, Sph"; # define FYC 0.49931 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY boggs_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double theta, th1, c; int i; @@ -39,6 +39,6 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(boggs) { P->es = 0.; - P->fwd = s_forward; + P->fwd = boggs_s_forward; return P; } diff --git a/src/projections/bonne.cpp b/src/projections/bonne.cpp index 289eb23d..31f90907 100644 --- a/src/projections/bonne.cpp +++ b/src/projections/bonne.cpp @@ -20,7 +20,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY bonne_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rh, E, c; @@ -38,7 +38,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY bonne_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double E, rh; @@ -53,7 +53,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP bonne_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rh; @@ -72,7 +72,7 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP bonne_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double s, rh; @@ -125,15 +125,15 @@ PJ *PROJECTION(bonne) { Q->m1 = pj_mlfn(Q->phi1, Q->am1 = sin(Q->phi1), c = cos(Q->phi1), Q->en); Q->am1 = c / (sqrt(1. - P->es * Q->am1 * Q->am1) * Q->am1); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = bonne_e_inverse; + P->fwd = bonne_e_forward; } else { if (fabs(Q->phi1) + EPS10 >= M_HALFPI) Q->cphi1 = 0.; else Q->cphi1 = 1. / tan(Q->phi1); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = bonne_s_inverse; + P->fwd = bonne_s_forward; } return P; } diff --git a/src/projections/calcofi.cpp b/src/projections/calcofi.cpp index e81843b4..57c12dde 100644 --- a/src/projections/calcofi.cpp +++ b/src/projections/calcofi.cpp @@ -35,7 +35,7 @@ whatever ellipsoid is provided. */ #define ROTATION_ANGLE 0.52359877559829882 /*CalCOFI angle of 30 deg in rad */ -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY calcofi_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; double oy; /* pt O y value in Mercator */ double l1; /* l1 and l2 are distances calculated using trig that sum @@ -67,7 +67,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY calcofi_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double oy; double l1; @@ -93,7 +93,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP calcofi_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; double ry; /* y value of point r */ double oymctr; /* Mercator-transformed y value of point O */ @@ -116,7 +116,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP calcofi_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double ry; double oymctr; @@ -153,11 +153,11 @@ PJ *PROJECTION(calcofi) { P->over = 1; if (P->es != 0.0) { /* ellipsoid */ - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = calcofi_e_inverse; + P->fwd = calcofi_e_forward; } else { /* sphere */ - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = calcofi_s_inverse; + P->fwd = calcofi_s_forward; } return P; } diff --git a/src/projections/cass.cpp b/src/projections/cass.cpp index ee050548..9eea10c5 100644 --- a/src/projections/cass.cpp +++ b/src/projections/cass.cpp @@ -25,7 +25,7 @@ struct pj_opaque { -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY cass_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ double n, t, a1, c, a2, tn; PJ_XY xy = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -47,7 +47,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY cass_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; xy.x = asin (cos (lp.phi) * sin (lp.lam)); xy.y = atan2 (tan (lp.phi), cos (lp.lam)) - P->phi0; @@ -55,7 +55,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP cass_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ double n, t, r, dd, d2, tn, ph1; PJ_LP lp = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -76,7 +76,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP cass_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double dd; lp.phi = asin(sin(dd = xy.y + P->phi0) * cos(xy.x)); @@ -101,8 +101,8 @@ PJ *PROJECTION(cass) { /* Spheroidal? */ if (0==P->es) { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = cass_s_inverse; + P->fwd = cass_s_forward; return P; } @@ -117,8 +117,8 @@ PJ *PROJECTION(cass) { return pj_default_destructor (P, ENOMEM); static_cast(P->opaque)->m0 = pj_mlfn (P->phi0, sin (P->phi0), cos (P->phi0), static_cast(P->opaque)->en); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = cass_e_inverse; + P->fwd = cass_e_forward; return P; } diff --git a/src/projections/cc.cpp b/src/projections/cc.cpp index 559a4f1a..244e185d 100644 --- a/src/projections/cc.cpp +++ b/src/projections/cc.cpp @@ -9,7 +9,7 @@ PROJ_HEAD(cc, "Central Cylindrical") "\n\tCyl, Sph"; #define EPS10 1.e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY cc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; if (fabs (fabs(lp.phi) - M_HALFPI) <= EPS10) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); @@ -21,7 +21,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP cc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; lp.phi = atan(xy.y); @@ -34,8 +34,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(cc) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = cc_s_inverse; + P->fwd = cc_s_forward; return P; } diff --git a/src/projections/ccon.cpp b/src/projections/ccon.cpp index 5f5128cf..e2312c0d 100644 --- a/src/projections/ccon.cpp +++ b/src/projections/ccon.cpp @@ -43,7 +43,7 @@ PROJ_HEAD(ccon, "Central Conic") -static PJ_XY forward (PJ_LP lp, PJ *P) { +static PJ_XY ccon_forward (PJ_LP lp, PJ *P) { PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double r; @@ -56,7 +56,7 @@ static PJ_XY forward (PJ_LP lp, PJ *P) { } -static PJ_LP inverse (PJ_XY xy, PJ *P) { +static PJ_LP ccon_inverse (PJ_XY xy, PJ *P) { PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -100,8 +100,8 @@ PJ *PROJECTION(ccon) { Q->ctgphi1 = Q->cosphi1/Q->sinphi1; - P->inv = inverse; - P->fwd = forward; + P->inv = ccon_inverse; + P->fwd = ccon_forward; return P; } diff --git a/src/projections/cea.cpp b/src/projections/cea.cpp index a1c9c8b5..a7e5fd04 100644 --- a/src/projections/cea.cpp +++ b/src/projections/cea.cpp @@ -17,7 +17,7 @@ PROJ_HEAD(cea, "Equal Area Cylindrical") "\n\tCyl, Sph&Ell\n\tlat_ts="; # define EPS 1e-10 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY cea_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = P->k0 * lp.lam; xy.y = 0.5 * pj_qsfn (sin (lp.phi), P->e, P->one_es) / P->k0; @@ -25,7 +25,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY cea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = P->k0 * lp.lam; xy.y = sin(lp.phi) / P->k0; @@ -33,7 +33,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP cea_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = pj_authlat(asin( 2. * xy.y * P->k0 / static_cast(P->opaque)->qp), static_cast(P->opaque)->apa); lp.lam = xy.x / P->k0; @@ -41,7 +41,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP cea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double t; @@ -92,11 +92,11 @@ PJ *PROJECTION(cea) { return pj_default_destructor(P, ENOMEM); Q->qp = pj_qsfn(1., P->e, P->one_es); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = cea_e_inverse; + P->fwd = cea_e_forward; } else { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = cea_s_inverse; + P->fwd = cea_s_forward; } return P; diff --git a/src/projections/chamb.cpp b/src/projections/chamb.cpp index 33a38781..e6bac22c 100644 --- a/src/projections/chamb.cpp +++ b/src/projections/chamb.cpp @@ -54,7 +54,7 @@ static double lc(projCtx ctx, double b,double c,double a) { } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY chamb_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy; struct pj_opaque *Q = static_cast(P->opaque); double sinphi, cosphi, a; @@ -135,7 +135,7 @@ PJ *PROJECTION(chamb) { Q->p.x = Q->c[2].p.x = Q->c[0].p.x + Q->c[2].v.r * cos(Q->beta_0); P->es = 0.; - P->fwd = s_forward; + P->fwd = chamb_s_forward; return P; } diff --git a/src/projections/collg.cpp b/src/projections/collg.cpp index b22e1bf2..40319a51 100644 --- a/src/projections/collg.cpp +++ b/src/projections/collg.cpp @@ -11,7 +11,7 @@ PROJ_HEAD(collg, "Collignon") "\n\tPCyl, Sph"; #define ONEEPS 1.0000001 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY collg_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; if ((xy.y = 1. - sin(lp.phi)) <= 0.) @@ -24,7 +24,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP collg_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y / FYC - 1.; if (fabs(lp.phi = 1. - lp.phi * lp.phi) < 1.) @@ -46,8 +46,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(collg) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = collg_s_inverse; + P->fwd = collg_s_forward; return P; } diff --git a/src/projections/comill.cpp b/src/projections/comill.cpp index 3af19b42..afcfbf7f 100644 --- a/src/projections/comill.cpp +++ b/src/projections/comill.cpp @@ -26,7 +26,7 @@ PROJ_HEAD(comill, "Compact Miller") "\n\tCyl, Sph"; /* Not sure at all of the appropriate number for MAX_ITER... */ #define MAX_ITER 100 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY comill_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double lat_sq; @@ -39,7 +39,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP comill_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double yc, tol, y2, f, fder; int i; @@ -78,8 +78,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(comill) { P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = comill_s_inverse; + P->fwd = comill_s_forward; return P; } diff --git a/src/projections/crast.cpp b/src/projections/crast.cpp index 35272058..cff35472 100644 --- a/src/projections/crast.cpp +++ b/src/projections/crast.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(crast, "Craster Parabolic (Putnins P4)") "\n\tPCyl, Sph"; #define THIRD 0.333333333333333333 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY crast_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; lp.phi *= THIRD; @@ -23,7 +23,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP crast_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; lp.phi = 3. * asin(xy.y * RYM); @@ -34,8 +34,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(crast) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = crast_s_inverse; + P->fwd = crast_s_forward; return P; } diff --git a/src/projections/denoy.cpp b/src/projections/denoy.cpp index 1560ad6b..5f736a40 100644 --- a/src/projections/denoy.cpp +++ b/src/projections/denoy.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(denoy, "Denoyer Semi-Elliptical") "\n\tPCyl, no inv, Sph"; #define D5 0.03 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY denoy_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; (void) P; xy.y = lp.phi; @@ -27,7 +27,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(denoy) { P->es = 0.0; - P->fwd = s_forward; + P->fwd = denoy_s_forward; return P; } diff --git a/src/projections/eck1.cpp b/src/projections/eck1.cpp index 3a19796e..55944952 100644 --- a/src/projections/eck1.cpp +++ b/src/projections/eck1.cpp @@ -9,7 +9,7 @@ PROJ_HEAD(eck1, "Eckert I") "\n\tPCyl, Sph"; #define RP 0.31830988618379067154 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eck1_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -20,7 +20,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eck1_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; @@ -34,8 +34,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(eck1) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eck1_s_inverse; + P->fwd = eck1_s_forward; return P ; diff --git a/src/projections/eck2.cpp b/src/projections/eck2.cpp index f019fdab..27b94aed 100644 --- a/src/projections/eck2.cpp +++ b/src/projections/eck2.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(eck2, "Eckert II") "\n\tPCyl, Sph"; #define ONEEPS 1.0000001 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eck2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -25,7 +25,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eck2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; @@ -49,8 +49,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(eck2) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eck2_s_inverse; + P->fwd = eck2_s_forward; return P; } diff --git a/src/projections/eck3.cpp b/src/projections/eck3.cpp index 6777c765..dd04fb39 100644 --- a/src/projections/eck3.cpp +++ b/src/projections/eck3.cpp @@ -18,7 +18,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eck3_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -28,7 +28,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eck3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double denominator; @@ -45,8 +45,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ static PJ *setup(PJ *P) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eck3_s_inverse; + P->fwd = eck3_s_forward; return P; } diff --git a/src/projections/eck4.cpp b/src/projections/eck4.cpp index 7f8203b2..df2caf42 100644 --- a/src/projections/eck4.cpp +++ b/src/projections/eck4.cpp @@ -16,7 +16,7 @@ PROJ_HEAD(eck4, "Eckert IV") "\n\tPCyl, Sph"; #define NITER 6 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eck4_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double p, V, s, c; int i; @@ -44,7 +44,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eck4_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double c; @@ -57,8 +57,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(eck4) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eck4_s_inverse; + P->fwd = eck4_s_forward; return P; } diff --git a/src/projections/eck5.cpp b/src/projections/eck5.cpp index 40e9d3bb..bf0e6a42 100644 --- a/src/projections/eck5.cpp +++ b/src/projections/eck5.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(eck5, "Eckert V") "\n\tPCyl, Sph"; #define RYF 1.13375401361911319568 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eck5_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; xy.x = XF * (1. + cos(lp.phi)) * lp.lam; @@ -23,7 +23,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eck5_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; lp.lam = RXF * xy.x / (1. + cos( lp.phi = RYF * xy.y)); @@ -34,8 +34,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(eck5) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eck5_s_inverse; + P->fwd = eck5_s_forward; return P; } diff --git a/src/projections/eqc.cpp b/src/projections/eqc.cpp index eb021eac..194625ef 100644 --- a/src/projections/eqc.cpp +++ b/src/projections/eqc.cpp @@ -16,7 +16,7 @@ PROJ_HEAD(eqc, "Equidistant Cylindrical (Plate Carree)") "\n\tCyl, Sph\n\tlat_ts=[, lat_0=0]"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY eqc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -27,7 +27,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP eqc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -46,8 +46,8 @@ PJ *PROJECTION(eqc) { if ((Q->rc = cos(pj_param(P->ctx, P->params, "rlat_ts").f)) <= 0.) return pj_default_destructor (P, PJD_ERR_LAT_TS_LARGER_THAN_90); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = eqc_s_inverse; + P->fwd = eqc_s_forward; P->es = 0.; return P; diff --git a/src/projections/eqdc.cpp b/src/projections/eqdc.cpp index 49cfc0ae..e050a593 100644 --- a/src/projections/eqdc.cpp +++ b/src/projections/eqdc.cpp @@ -25,7 +25,7 @@ PROJ_HEAD(eqdc, "Equidistant Conic") # define EPS10 1.e-10 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY eqdc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -38,7 +38,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP eqdc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -121,8 +121,8 @@ PJ *PROJECTION(eqdc) { Q->rho0 = Q->c - P->phi0; } - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = eqdc_e_inverse; + P->fwd = eqdc_e_forward; return P; } diff --git a/src/projections/eqearth.cpp b/src/projections/eqearth.cpp index 73499262..832c9444 100644 --- a/src/projections/eqearth.cpp +++ b/src/projections/eqearth.cpp @@ -40,7 +40,7 @@ struct pj_opaque { }; } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal/spheroidal, forward */ +static PJ_XY eqearth_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal/spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double sbeta; @@ -74,7 +74,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal/spheroidal, } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal/spheroidal, inverse */ +static PJ_LP eqearth_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal/spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double yc, y2, y6; @@ -148,8 +148,8 @@ PJ *PROJECTION(eqearth) { return pj_default_destructor (P, ENOMEM); P->opaque = Q; P->destructor = destructor; - P->fwd = e_forward; - P->inv = e_inverse; + P->fwd = eqearth_e_forward; + P->inv = eqearth_e_inverse; Q->rqda = 1.0; /* Ellipsoidal case */ diff --git a/src/projections/fahey.cpp b/src/projections/fahey.cpp index ba8cb8f9..9561217a 100644 --- a/src/projections/fahey.cpp +++ b/src/projections/fahey.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(fahey, "Fahey") "\n\tPcyl, Sph"; #define TOL 1e-6 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY fahey_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -21,7 +21,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP fahey_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; @@ -35,8 +35,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(fahey) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = fahey_s_inverse; + P->fwd = fahey_s_forward; return P; } diff --git a/src/projections/fouc_s.cpp b/src/projections/fouc_s.cpp index e91f41c3..29d6437d 100644 --- a/src/projections/fouc_s.cpp +++ b/src/projections/fouc_s.cpp @@ -18,7 +18,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY fouc_s_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t; @@ -30,7 +30,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP fouc_s_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double V; @@ -66,7 +66,7 @@ PJ *PROJECTION(fouc_s) { Q->n1 = 1. - Q->n; P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = fouc_s_s_inverse; + P->fwd = fouc_s_s_forward; return P; } diff --git a/src/projections/gall.cpp b/src/projections/gall.cpp index 8f1ca1f8..091c75d7 100644 --- a/src/projections/gall.cpp +++ b/src/projections/gall.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(gall, "Gall (Gall Stereographic)") "\n\tCyl, Sph"; #define RXF 1.41421356237309504880 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY gall_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -24,7 +24,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP gall_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; @@ -38,8 +38,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(gall) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = gall_s_inverse; + P->fwd = gall_s_forward; return P; } diff --git a/src/projections/geos.cpp b/src/projections/geos.cpp index cdb0244a..7c15f22a 100644 --- a/src/projections/geos.cpp +++ b/src/projections/geos.cpp @@ -52,7 +52,7 @@ struct pj_opaque { PROJ_HEAD(geos, "Geostationary Satellite View") "\n\tAzi, Sph&Ell\n\th="; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY geos_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double Vx, Vy, Vz, tmp; @@ -82,7 +82,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY geos_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double r, Vx, Vy, Vz, tmp; @@ -118,7 +118,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP geos_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double Vx, Vy, Vz, a, b, det, k; @@ -155,7 +155,7 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP geos_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double Vx, Vy, Vz, a, b, det, k; @@ -226,12 +226,12 @@ PJ *PROJECTION(geos) { Q->radius_p = sqrt (P->one_es); Q->radius_p2 = P->one_es; Q->radius_p_inv2 = P->rone_es; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = geos_e_inverse; + P->fwd = geos_e_forward; } else { Q->radius_p = Q->radius_p2 = Q->radius_p_inv2 = 1.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = geos_s_inverse; + P->fwd = geos_s_forward; } return P; diff --git a/src/projections/gins8.cpp b/src/projections/gins8.cpp index 6f499889..73f00d6f 100644 --- a/src/projections/gins8.cpp +++ b/src/projections/gins8.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(gins8, "Ginsburg VIII (TsNIIGAiK)") "\n\tPCyl, Sph, no inv"; #define C12 0.08333333333333333 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY gins8_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double t = lp.phi * lp.phi; (void) P; @@ -27,7 +27,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(gins8) { P->es = 0.0; P->inv = nullptr; - P->fwd = s_forward; + P->fwd = gins8_s_forward; return P; } diff --git a/src/projections/gn_sinu.cpp b/src/projections/gn_sinu.cpp index 3a591669..84883cbc 100644 --- a/src/projections/gn_sinu.cpp +++ b/src/projections/gn_sinu.cpp @@ -23,7 +23,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY gn_sinu_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; double s, c; @@ -33,7 +33,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP gn_sinu_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; double s; @@ -50,7 +50,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY gn_sinu_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -80,7 +80,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP gn_sinu_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -109,8 +109,8 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor static void setup(PJ *P) { struct pj_opaque *Q = static_cast(P->opaque); P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = gn_sinu_s_inverse; + P->fwd = gn_sinu_s_forward; Q->C_x = (Q->C_y = sqrt((Q->m + 1.) / Q->n))/(Q->m + 1.); } @@ -127,8 +127,8 @@ PJ *PROJECTION(sinu) { return pj_default_destructor (P, ENOMEM); if (P->es != 0.0) { - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = gn_sinu_e_inverse; + P->fwd = gn_sinu_e_forward; } else { Q->n = 1.; Q->m = 0.; diff --git a/src/projections/gnom.cpp b/src/projections/gnom.cpp index bf454ba9..f7cb2635 100644 --- a/src/projections/gnom.cpp +++ b/src/projections/gnom.cpp @@ -29,7 +29,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY gnom_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi; @@ -77,7 +77,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP gnom_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rh, cosz, sinz; @@ -139,8 +139,8 @@ PJ *PROJECTION(gnom) { Q->cosph0 = cos(P->phi0); } - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = gnom_s_inverse; + P->fwd = gnom_s_forward; P->es = 0.; return P; diff --git a/src/projections/goode.cpp b/src/projections/goode.cpp index 802df90c..c716649d 100644 --- a/src/projections/goode.cpp +++ b/src/projections/goode.cpp @@ -21,7 +21,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY goode_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy; struct pj_opaque *Q = static_cast(P->opaque); @@ -35,7 +35,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP goode_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp; struct pj_opaque *Q = static_cast(P->opaque); @@ -77,8 +77,8 @@ PJ *PROJECTION(goode) { if (!(Q->sinu = pj_sinu(Q->sinu)) || !(Q->moll = pj_moll(Q->moll))) return destructor (P, ENOMEM); - P->fwd = s_forward; - P->inv = s_inverse; + P->fwd = goode_s_forward; + P->inv = goode_s_inverse; return P; } diff --git a/src/projections/gstmerc.cpp b/src/projections/gstmerc.cpp index 735d39e5..808d9ef7 100644 --- a/src/projections/gstmerc.cpp +++ b/src/projections/gstmerc.cpp @@ -22,7 +22,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY gstmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double L, Ls, sinLs1, Ls1; @@ -38,7 +38,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP gstmerc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double L, LC, sinC; @@ -68,8 +68,8 @@ PJ *PROJECTION(gstmerc) { Q->XS = 0; Q->YS = -1.0 * Q->n2 * Q->phic; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = gstmerc_s_inverse; + P->fwd = gstmerc_s_forward; return P; } diff --git a/src/projections/hammer.cpp b/src/projections/hammer.cpp index b2e56a2c..56bdf74e 100644 --- a/src/projections/hammer.cpp +++ b/src/projections/hammer.cpp @@ -19,7 +19,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY hammer_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cosphi, d; @@ -38,7 +38,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP hammer_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double z; @@ -77,8 +77,8 @@ PJ *PROJECTION(hammer) { Q->m /= Q->w; P->es = 0.; - P->fwd = s_forward; - P->inv = s_inverse; + P->fwd = hammer_s_forward; + P->inv = hammer_s_inverse; return P; } diff --git a/src/projections/hatano.cpp b/src/projections/hatano.cpp index b2ef6c6f..6c125d2e 100644 --- a/src/projections/hatano.cpp +++ b/src/projections/hatano.cpp @@ -22,7 +22,7 @@ PROJ_HEAD(hatano, "Hatano Asymmetrical Equal Area") "\n\tPCyl, Sph"; #define RXC 1.17647058823529411764 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY hatano_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double th1, c; int i; @@ -40,7 +40,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP hatano_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double th; @@ -76,8 +76,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(hatano) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = hatano_s_inverse; + P->fwd = hatano_s_forward; return P; } diff --git a/src/projections/healpix.cpp b/src/projections/healpix.cpp index e9924e04..515f4f6f 100644 --- a/src/projections/healpix.cpp +++ b/src/projections/healpix.cpp @@ -281,7 +281,7 @@ static PJ_XY healpix_sphere(PJ_LP lp) { /** * Return the inverse of healpix_sphere(). **/ -static PJ_LP healpix_sphere_inverse(PJ_XY xy) { +static PJ_LP healpix_spherhealpix_e_inverse(PJ_XY xy) { PJ_LP lp; double x = xy.x; double y = xy.y; @@ -532,7 +532,7 @@ static PJ_LP s_healpix_inverse(PJ_XY xy, PJ *P) { /* sphere */ pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } - return healpix_sphere_inverse(xy); + return healpix_spherhealpix_e_inverse(xy); } @@ -546,7 +546,7 @@ static PJ_LP e_healpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */ pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } - lp = healpix_sphere_inverse(xy); + lp = healpix_spherhealpix_e_inverse(xy); lp.phi = auth_lat(P, lp.phi, 1); return lp; } @@ -581,7 +581,7 @@ static PJ_LP s_rhealpix_inverse(PJ_XY xy, PJ *P) { /* sphere */ return lp; } xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1); - return healpix_sphere_inverse(xy); + return healpix_spherhealpix_e_inverse(xy); } @@ -597,7 +597,7 @@ static PJ_LP e_rhealpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */ return lp; } xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1); - lp = healpix_sphere_inverse(xy); + lp = healpix_spherhealpix_e_inverse(xy); lp.phi = auth_lat(P, lp.phi, 1); return lp; } diff --git a/src/projections/igh.cpp b/src/projections/igh.cpp index d6b2d38d..8a41cea3 100644 --- a/src/projections/igh.cpp +++ b/src/projections/igh.cpp @@ -41,7 +41,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY igh_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy; struct pj_opaque *Q = static_cast(P->opaque); int z; @@ -74,7 +74,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP igh_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); const double y90 = Q->dy0 + sqrt(2.0); /* lt=90 corresponds to y=y0+sqrt(2) */ @@ -219,8 +219,8 @@ PJ *PROJECTION(igh) { SETUP(11, moll, d20, -Q->dy0, d20); SETUP(12, moll, d140, -Q->dy0, d140); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = igh_s_inverse; + P->fwd = igh_s_forward; P->destructor = destructor; P->es = 0.; diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp index 5455be33..ee206091 100644 --- a/src/projections/imw_p.cpp +++ b/src/projections/imw_p.cpp @@ -97,14 +97,14 @@ static PJ_XY loc_for(PJ_LP lp, PJ *P, double *yc) { } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY imw_p_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ double yc; PJ_XY xy = loc_for(lp, P, &yc); return (xy); } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP imw_p_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); PJ_XY t; @@ -219,8 +219,8 @@ PJ *PROJECTION(imw_p) { Q->Pp = (m2 * x1 - m1 * x2) * t; Q->Qp = (x2 - x1) * t; - P->fwd = e_forward; - P->inv = e_inverse; + P->fwd = imw_p_e_forward; + P->inv = imw_p_e_inverse; P->destructor = destructor; return P; diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index e8720b27..c22e143d 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -1014,7 +1014,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY isea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); struct isea_pt out; @@ -1045,7 +1045,7 @@ PJ *PROJECTION(isea) { P->opaque = Q; - P->fwd = s_forward; + P->fwd = isea_s_forward; isea_grid_init(&Q->dgg); Q->dgg.output = ISEA_PLANE; diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp index c3f61f3d..98f09199 100644 --- a/src/projections/krovak.cpp +++ b/src/projections/krovak.cpp @@ -103,7 +103,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY krovak_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ struct pj_opaque *Q = static_cast(P->opaque); PJ_XY xy = {0.0,0.0}; @@ -137,7 +137,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forwar } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ struct pj_opaque *Q = static_cast(P->opaque); PJ_LP lp = {0.0,0.0}; @@ -232,8 +232,8 @@ PJ *PROJECTION(krovak) { Q->rho0 = P->k0 * n0 / tan(S0); Q->ad = M_PI_2 - UQ; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = krovak_e_inverse; + P->fwd = krovak_e_forward; return P; } diff --git a/src/projections/labrd.cpp b/src/projections/labrd.cpp index 85ab3ddd..21d9099f 100644 --- a/src/projections/labrd.cpp +++ b/src/projections/labrd.cpp @@ -16,7 +16,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY labrd_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double V1, V2, ps, sinps, cosps, sinps2, cosps2; @@ -49,7 +49,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP labrd_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); /* t = 0.0 optimization is to avoid a false positive cppcheck warning */ @@ -130,8 +130,8 @@ PJ *PROJECTION(labrd) { Q->Cc = 3. * (Q->Ca * Q->Ca - Q->Cb * Q->Cb); Q->Cd = 6. * Q->Ca * Q->Cb; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = labrd_e_inverse; + P->fwd = labrd_e_forward; return P; } diff --git a/src/projections/laea.cpp b/src/projections/laea.cpp index 11b89a96..8a23c504 100644 --- a/src/projections/laea.cpp +++ b/src/projections/laea.cpp @@ -32,7 +32,7 @@ struct pj_opaque { #define EPS10 1.e-10 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY laea_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0; @@ -94,7 +94,7 @@ eqcon: } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY laea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi; @@ -136,7 +136,7 @@ oblcon: } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP laea_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cCe, sCe, q, rho, ab=0.0; @@ -185,7 +185,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP laea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cosz=0.0, rh, sinz=0.0; @@ -287,15 +287,15 @@ PJ *PROJECTION(laea) { Q->xmf *= Q->dd; break; } - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = laea_e_inverse; + P->fwd = laea_e_forward; } else { if (Q->mode == OBLIQ) { Q->sinb1 = sin(P->phi0); Q->cosb1 = cos(P->phi0); } - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = laea_s_inverse; + P->fwd = laea_s_forward; } return P; diff --git a/src/projections/lagrng.cpp b/src/projections/lagrng.cpp index 65686584..ac7a37a4 100644 --- a/src/projections/lagrng.cpp +++ b/src/projections/lagrng.cpp @@ -21,7 +21,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY lagrng_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double v, c; @@ -45,7 +45,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP lagrng_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c, x2, y2p, y2m; @@ -93,8 +93,8 @@ PJ *PROJECTION(lagrng) { Q->a2 = Q->a1 * Q->a1; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = lagrng_s_inverse; + P->fwd = lagrng_s_forward; return P; } diff --git a/src/projections/larr.cpp b/src/projections/larr.cpp index bab1dbf4..33fbd94c 100644 --- a/src/projections/larr.cpp +++ b/src/projections/larr.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(larr, "Larrivee") "\n\tMisc Sph, no inv"; #define SIXTH .16666666666666666 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY larr_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -23,7 +23,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(larr) { P->es = 0; - P->fwd = s_forward; + P->fwd = larr_s_forward; return P; } diff --git a/src/projections/lask.cpp b/src/projections/lask.cpp index c4c6734d..80e50522 100644 --- a/src/projections/lask.cpp +++ b/src/projections/lask.cpp @@ -17,7 +17,7 @@ PROJ_HEAD(lask, "Laskowski") "\n\tMisc Sph, no inv"; #define b05 -0.0491032 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY lask_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double l2, p2; (void) P; @@ -33,7 +33,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(lask) { - P->fwd = s_forward; + P->fwd = lask_s_forward; P->es = 0.; return P; diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index a101009d..beb2efd1 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -20,7 +20,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY lcc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0., 0.}; struct pj_opaque *Q = static_cast(P->opaque); double rho; @@ -43,7 +43,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP lcc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0., 0.}; struct pj_opaque *Q = static_cast(P->opaque); double rho; @@ -144,8 +144,8 @@ PJ *PROJECTION(lcc) { Q->c * pow(tan(M_FORTPI + .5 * P->phi0), -Q->n); } - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = lcc_e_inverse; + P->fwd = lcc_e_forward; return P; } diff --git a/src/projections/lcca.cpp b/src/projections/lcca.cpp index d4dc8641..11ecb29c 100644 --- a/src/projections/lcca.cpp +++ b/src/projections/lcca.cpp @@ -80,7 +80,7 @@ static double fSp(double S, double C) { /* deriv of fs */ } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY lcca_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double S, r, dr; @@ -94,7 +94,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP lcca_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double theta, dr, S, dif; @@ -156,8 +156,8 @@ PJ *PROJECTION(lcca) { Q->r0 = N0 / tan0; Q->C = 1. / (6. * R0 * N0); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = lcca_e_inverse; + P->fwd = lcca_e_forward; P->destructor = destructor; return P; diff --git a/src/projections/loxim.cpp b/src/projections/loxim.cpp index 2a780a9e..2ee88037 100644 --- a/src/projections/loxim.cpp +++ b/src/projections/loxim.cpp @@ -19,7 +19,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY loxim_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -37,7 +37,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP loxim_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -69,8 +69,8 @@ PJ *PROJECTION(loxim) { Q->tanphi1 = tan(M_FORTPI + 0.5 * Q->phi1); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = loxim_s_inverse; + P->fwd = loxim_s_forward; P->es = 0.; return P; diff --git a/src/projections/lsat.cpp b/src/projections/lsat.cpp index f9eec1b9..f6114485 100644 --- a/src/projections/lsat.cpp +++ b/src/projections/lsat.cpp @@ -44,7 +44,7 @@ static void seraz0(double lam, double mult, PJ *P) { } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY lsat_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int l, nn; @@ -107,7 +107,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP lsat_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int nn; @@ -208,8 +208,8 @@ PJ *PROJECTION(lsat) { Q->c1 /= 15.; Q->c3 /= 45.; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = lsat_e_inverse; + P->fwd = lsat_e_forward; return P; } diff --git a/src/projections/mbt_fps.cpp b/src/projections/mbt_fps.cpp index beff3314..9ce2aa36 100644 --- a/src/projections/mbt_fps.cpp +++ b/src/projections/mbt_fps.cpp @@ -16,7 +16,7 @@ PROJ_HEAD(mbt_fps, "McBryde-Thomas Flat-Pole Sine (No. 2)") "\n\tCyl, Sph"; #define C_y 1.44492 #define C1_2 0.33333333333333333333333333 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY mbt_fps_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double k, V, t; int i; @@ -37,7 +37,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP mbt_fps_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double t; @@ -51,8 +51,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(mbt_fps) { P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = mbt_fps_s_inverse; + P->fwd = mbt_fps_s_forward; return P; } diff --git a/src/projections/mbtfpp.cpp b/src/projections/mbtfpp.cpp index ebd860ee..a4ab60b9 100644 --- a/src/projections/mbtfpp.cpp +++ b/src/projections/mbtfpp.cpp @@ -15,7 +15,7 @@ PROJ_HEAD(mbtfpp, "McBride-Thomas Flat-Polar Parabolic") "\n\tCyl, Sph"; #define ONEEPS 1.0000001 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY mbtfpp_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -26,7 +26,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP mbtfpp_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y / FYC; @@ -58,8 +58,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(mbtfpp) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = mbtfpp_s_inverse; + P->fwd = mbtfpp_s_forward; return P; } diff --git a/src/projections/mbtfpq.cpp b/src/projections/mbtfpq.cpp index ec49f9ce..9a419790 100644 --- a/src/projections/mbtfpq.cpp +++ b/src/projections/mbtfpq.cpp @@ -18,7 +18,7 @@ PROJ_HEAD(mbtfpq, "McBryde-Thomas Flat-Polar Quartic") "\n\tCyl, Sph"; #define RXC 3.20041258076506210122 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY mbtfpq_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double th1, c; int i; @@ -36,7 +36,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP mbtfpq_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double t; @@ -67,8 +67,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(mbtfpq) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = mbtfpq_s_inverse; + P->fwd = mbtfpq_s_forward; return P; } diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index 4975b6c5..10b8bb90 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -19,7 +19,7 @@ static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */ return log(tan(M_FORTPI + .5 * x)); } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); @@ -31,7 +31,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY merc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); @@ -43,7 +43,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP merc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; if ((lp.phi = pj_phi2(P->ctx, exp(- xy.y / P->k0), P->e)) == HUGE_VAL) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); @@ -54,7 +54,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP merc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = atan(sinh(xy.y / P->k0)); lp.lam = xy.x / P->k0; @@ -75,15 +75,15 @@ PJ *PROJECTION(merc) { if (P->es != 0.0) { /* ellipsoid */ if (is_phits) P->k0 = pj_msfn(sin(phits), cos(phits), P->es); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = merc_e_inverse; + P->fwd = merc_e_forward; } else { /* sphere */ if (is_phits) P->k0 = cos(phits); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = merc_s_inverse; + P->fwd = merc_s_forward; } return P; @@ -94,7 +94,7 @@ PJ *PROJECTION(webmerc) { /* Overriding k_0 with fixed parameter */ P->k0 = 1.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = merc_s_inverse; + P->fwd = merc_s_forward; return P; } diff --git a/src/projections/mill.cpp b/src/projections/mill.cpp index 5d4acd89..e6a97057 100644 --- a/src/projections/mill.cpp +++ b/src/projections/mill.cpp @@ -7,7 +7,7 @@ PROJ_HEAD(mill, "Miller Cylindrical") "\n\tCyl, Sph"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY mill_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -18,7 +18,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP mill_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; (void) P; @@ -31,8 +31,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(mill) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = mill_s_inverse; + P->fwd = mill_s_forward; return P; } diff --git a/src/projections/misrsom.cpp b/src/projections/misrsom.cpp index d16dd62d..09e2d8f3 100644 --- a/src/projections/misrsom.cpp +++ b/src/projections/misrsom.cpp @@ -62,7 +62,7 @@ static void seraz0(double lam, double mult, PJ *P) { } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY misrsom_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int l, nn; @@ -123,7 +123,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP misrsom_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int nn; @@ -216,8 +216,8 @@ PJ *PROJECTION(misrsom) { Q->c1 /= 15.; Q->c3 /= 45.; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = misrsom_e_inverse; + P->fwd = misrsom_e_forward; return P; } diff --git a/src/projections/mod_ster.cpp b/src/projections/mod_ster.cpp index 50f66839..8e02ea72 100644 --- a/src/projections/mod_ster.cpp +++ b/src/projections/mod_ster.cpp @@ -22,7 +22,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY mod_ster_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double sinlon, coslon, esphi, chi, schi, cchi, s; @@ -51,7 +51,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP mod_ster_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); int nn; @@ -119,8 +119,8 @@ static PJ *setup(PJ *P) { /* general initialization */ chio = P->phi0; Q->schio = sin(chio); Q->cchio = cos(chio); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = mod_ster_e_inverse; + P->fwd = mod_ster_e_forward; return P; } diff --git a/src/projections/moll.cpp b/src/projections/moll.cpp index 03393b01..d511c6e0 100644 --- a/src/projections/moll.cpp +++ b/src/projections/moll.cpp @@ -20,7 +20,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY moll_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double k, V; @@ -43,7 +43,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP moll_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); lp.phi = aasin(P->ctx, xy.y / Q->C_y); @@ -70,8 +70,8 @@ static PJ * setup(PJ *P, double p) { Q->C_y = r / sp; Q->C_p = p2 + sin(p2); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = moll_s_inverse; + P->fwd = moll_s_forward; return P; } @@ -106,8 +106,8 @@ PJ *PROJECTION(wag5) { Q->C_y = 1.65014; Q->C_p = 3.00896; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = moll_s_inverse; + P->fwd = moll_s_forward; return P; } diff --git a/src/projections/natearth.cpp b/src/projections/natearth.cpp index d8e52c37..ff8aef6a 100644 --- a/src/projections/natearth.cpp +++ b/src/projections/natearth.cpp @@ -42,7 +42,7 @@ PROJ_HEAD(natearth, "Natural Earth") "\n\tPCyl, Sph"; #define MAX_ITER 100 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY natearth_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double phi2, phi4; (void) P; @@ -55,7 +55,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP natearth_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double yc, tol, y2, y4, f, fder; int i; @@ -94,8 +94,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(natearth) { P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = natearth_s_inverse; + P->fwd = natearth_s_forward; return P; } diff --git a/src/projections/natearth2.cpp b/src/projections/natearth2.cpp index 9849a723..95d73c36 100644 --- a/src/projections/natearth2.cpp +++ b/src/projections/natearth2.cpp @@ -34,7 +34,7 @@ PROJ_HEAD(natearth2, "Natural Earth 2") "\n\tPCyl, Sph"; #define MAX_ITER 100 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY natearth2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double phi2, phi4, phi6; (void) P; @@ -49,7 +49,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP natearth2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double yc, tol, y2, y4, y6, f, fder; int i; @@ -91,8 +91,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(natearth2) { P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = natearth2_s_inverse; + P->fwd = natearth2_s_forward; return P; } diff --git a/src/projections/nell.cpp b/src/projections/nell.cpp index b6e69dd6..63a0eec1 100644 --- a/src/projections/nell.cpp +++ b/src/projections/nell.cpp @@ -11,7 +11,7 @@ PROJ_HEAD(nell, "Nell") "\n\tPCyl, Sph"; #define LOOP_TOL 1e-7 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY nell_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double k, V; int i; @@ -33,7 +33,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP nell_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.lam = 2. * xy.x / (1. + cos(xy.y)); lp.phi = aasin(P->ctx,0.5 * (xy.y + sin(xy.y))); @@ -45,8 +45,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(nell) { P->es = 0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = nell_s_inverse; + P->fwd = nell_s_forward; return P; } diff --git a/src/projections/nell_h.cpp b/src/projections/nell_h.cpp index be28b917..63d12391 100644 --- a/src/projections/nell_h.cpp +++ b/src/projections/nell_h.cpp @@ -11,7 +11,7 @@ PROJ_HEAD(nell_h, "Nell-Hammer") "\n\tPCyl, Sph"; #define EPS 1e-7 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY nell_h_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -22,7 +22,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP nell_h_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double V, c, p; int i; @@ -47,8 +47,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(nell_h) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = nell_h_s_inverse; + P->fwd = nell_h_s_forward; return P; } diff --git a/src/projections/nicol.cpp b/src/projections/nicol.cpp index c4bee261..fb1b93ea 100644 --- a/src/projections/nicol.cpp +++ b/src/projections/nicol.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(nicol, "Nicolosi Globular") "\n\tMisc Sph, no inv"; #define EPS 1e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY nicol_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; (void) P; @@ -49,7 +49,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(nicol) { P->es = 0.; - P->fwd = s_forward; + P->fwd = nicol_s_forward; return P; } diff --git a/src/projections/nsper.cpp b/src/projections/nsper.cpp index 37938924..fbf5317b 100644 --- a/src/projections/nsper.cpp +++ b/src/projections/nsper.cpp @@ -38,7 +38,7 @@ PROJ_HEAD(tpers, "Tilted perspective") "\n\tAzi, Sph\n\ttilt= azi= h="; # define EPS10 1.e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY nsper_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi; @@ -93,7 +93,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP nsper_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rh; @@ -165,8 +165,8 @@ static PJ *setup(PJ *P) { Q->rp = 1. / Q->p; Q->h = 1. / Q->pn1; Q->pfact = (Q->p + 1.) * Q->h; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = nsper_s_inverse; + P->fwd = nsper_s_forward; P->es = 0.; return P; diff --git a/src/projections/nzmg.cpp b/src/projections/nzmg.cpp index 1c2d9fb7..2f1a897e 100644 --- a/src/projections/nzmg.cpp +++ b/src/projections/nzmg.cpp @@ -58,7 +58,7 @@ static const double tpsi[] = { .6399175073, -.1358797613, .063294409, -.02526853 #define Ntphi 8 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY nzmg_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; COMPLEX p; const double *C; @@ -77,7 +77,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP nzmg_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; int nn, i; COMPLEX p, f, fp, dp; @@ -116,8 +116,8 @@ PJ *PROJECTION(nzmg) { P->x0 = 2510000.; P->y0 = 6023150.; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = nzmg_e_inverse; + P->fwd = nzmg_e_forward; return P; diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp index 3141dd11..646b8638 100644 --- a/src/projections/ocea.cpp +++ b/src/projections/ocea.cpp @@ -19,7 +19,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY ocea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t; @@ -34,7 +34,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP ocea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t, s; @@ -106,8 +106,8 @@ PJ *PROJECTION(ocea) { P->lam0 = lam_p + M_HALFPI; Q->cosphi = cos(phi_p); Q->sinphi = sin(phi_p); - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = ocea_s_inverse; + P->fwd = ocea_s_forward; P->es = 0.; return P; diff --git a/src/projections/oea.cpp b/src/projections/oea.cpp index f2fc1053..ac0f643f 100644 --- a/src/projections/oea.cpp +++ b/src/projections/oea.cpp @@ -16,7 +16,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY oea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double Az, M, N, cp, sp, cl, shz; @@ -35,7 +35,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP oea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double N, M, xp, yp, z, Az, cz, sz, cAz; @@ -77,8 +77,8 @@ PJ *PROJECTION(oea) { Q->two_r_m = 2. * Q->rm; Q->hm = 0.5 * Q->m; Q->hn = 0.5 * Q->n; - P->fwd = s_forward; - P->inv = s_inverse; + P->fwd = oea_s_forward; + P->inv = oea_s_inverse; P->es = 0.; } diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index 0de3aa7d..954023df 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -45,7 +45,7 @@ struct pj_opaque { #define EPS 1.e-10 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY omerc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double S, T, U, V, W, temp, u, v; @@ -84,7 +84,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP omerc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double u, v, Qp, Sp, Tp, Vp, Up; @@ -238,8 +238,8 @@ PJ *PROJECTION(omerc) { F = 0.5 * gamma0; Q->v_pole_n = Q->ArB * log(tan(M_FORTPI - F)); Q->v_pole_s = Q->ArB * log(tan(M_FORTPI + F)); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = omerc_e_inverse; + P->fwd = omerc_e_forward; return P; } diff --git a/src/projections/ortho.cpp b/src/projections/ortho.cpp index eda325fe..94764756 100644 --- a/src/projections/ortho.cpp +++ b/src/projections/ortho.cpp @@ -32,7 +32,7 @@ static PJ_XY forward_error(PJ *P, PJ_LP lp, PJ_XY xy) { return xy; } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY ortho_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy; struct pj_opaque *Q = static_cast(P->opaque); double coslam, cosphi, sinphi; @@ -66,7 +66,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP ortho_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp; struct pj_opaque *Q = static_cast(P->opaque); double rh, cosc, sinc; @@ -133,8 +133,8 @@ PJ *PROJECTION(ortho) { Q->cosph0 = cos(P->phi0); } else Q->mode = EQUIT; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = ortho_s_inverse; + P->fwd = ortho_s_forward; P->es = 0.; return P; diff --git a/src/projections/patterson.cpp b/src/projections/patterson.cpp index 7f0ea3a9..16e7b746 100644 --- a/src/projections/patterson.cpp +++ b/src/projections/patterson.cpp @@ -61,7 +61,7 @@ PROJ_HEAD(patterson, "Patterson Cylindrical") "\n\tCyl"; #define MAX_ITER 100 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY patterson_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double phi2; (void) P; @@ -74,7 +74,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP patterson_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double yc, tol, y2, f, fder; int i; @@ -111,8 +111,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(patterson) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = patterson_s_inverse; + P->fwd = patterson_s_forward; return P; } diff --git a/src/projections/poly.cpp b/src/projections/poly.cpp index b4b61b00..08a4aaad 100644 --- a/src/projections/poly.cpp +++ b/src/projections/poly.cpp @@ -23,7 +23,7 @@ struct pj_opaque { #define ITOL 1.e-12 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY poly_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double ms, sp, cp; @@ -42,7 +42,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY poly_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cot, E; @@ -60,7 +60,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP poly_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -104,7 +104,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP poly_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double B, dphi, tp; int i; @@ -159,12 +159,12 @@ PJ *PROJECTION(poly) { if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor (P, ENOMEM); Q->ml0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), Q->en); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = poly_e_inverse; + P->fwd = poly_e_forward; } else { Q->ml0 = -P->phi0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = poly_s_inverse; + P->fwd = poly_s_forward; } return P; diff --git a/src/projections/putp2.cpp b/src/projections/putp2.cpp index d5b3b9f5..a11e479e 100644 --- a/src/projections/putp2.cpp +++ b/src/projections/putp2.cpp @@ -15,7 +15,7 @@ PROJ_HEAD(putp2, "Putnins P2") "\n\tPCyl, Sph"; #define PI_DIV_3 1.0471975511965977 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY putp2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double p, c, s, V; int i; @@ -41,7 +41,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP putp2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double c; @@ -55,8 +55,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(putp2) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp2_s_inverse; + P->fwd = putp2_s_forward; return P; } diff --git a/src/projections/putp3.cpp b/src/projections/putp3.cpp index bc4a02e4..c2df20e8 100644 --- a/src/projections/putp3.cpp +++ b/src/projections/putp3.cpp @@ -17,7 +17,7 @@ PROJ_HEAD(putp3p, "Putnins P3'") "\n\tPCyl, Sph"; #define RPISQ 0.1013211836 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY putp3_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = C * lp.lam * (1. - static_cast(P->opaque)->A * lp.phi * lp.phi); @@ -27,7 +27,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP putp3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y / C; @@ -46,8 +46,8 @@ PJ *PROJECTION(putp3) { Q->A = 4. * RPISQ; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp3_s_inverse; + P->fwd = putp3_s_forward; return P; } @@ -61,8 +61,8 @@ PJ *PROJECTION(putp3p) { Q->A = 2. * RPISQ; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp3_s_inverse; + P->fwd = putp3_s_forward; return P; } diff --git a/src/projections/putp4p.cpp b/src/projections/putp4p.cpp index 462dae81..a5728b74 100644 --- a/src/projections/putp4p.cpp +++ b/src/projections/putp4p.cpp @@ -16,7 +16,7 @@ PROJ_HEAD(putp4p, "Putnins P4'") "\n\tPCyl, Sph"; PROJ_HEAD(weren, "Werenskiold I") "\n\tPCyl, Sph"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY putp4p_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -29,7 +29,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP putp4p_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -53,8 +53,8 @@ PJ *PROJECTION(putp4p) { Q->C_y = 3.883251825; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp4p_s_inverse; + P->fwd = putp4p_s_forward; return P; } @@ -70,8 +70,8 @@ PJ *PROJECTION(weren) { Q->C_y = 4.442882938; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp4p_s_inverse; + P->fwd = putp4p_s_forward; return P; } diff --git a/src/projections/putp5.cpp b/src/projections/putp5.cpp index 62cb2ea9..1847e7a9 100644 --- a/src/projections/putp5.cpp +++ b/src/projections/putp5.cpp @@ -19,7 +19,7 @@ PROJ_HEAD(putp5p, "Putnins P5'") "\n\tPCyl, Sph"; #define D 1.2158542 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY putp5_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -30,7 +30,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP putp5_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); @@ -52,8 +52,8 @@ PJ *PROJECTION(putp5) { Q->B = 1.; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp5_s_inverse; + P->fwd = putp5_s_forward; return P; } @@ -69,8 +69,8 @@ PJ *PROJECTION(putp5p) { Q->B = 0.5; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp5_s_inverse; + P->fwd = putp5_s_forward; return P; } diff --git a/src/projections/putp6.cpp b/src/projections/putp6.cpp index 4bae7ae6..bcf9ad8e 100644 --- a/src/projections/putp6.cpp +++ b/src/projections/putp6.cpp @@ -20,7 +20,7 @@ PROJ_HEAD(putp6p, "Putnins P6'") "\n\tPCyl, Sph"; #define CON_POLE 1.732050807568877 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY putp6_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double p, r, V; @@ -44,7 +44,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP putp6_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double r; @@ -71,8 +71,8 @@ PJ *PROJECTION(putp6) { Q->D = 2.; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp6_s_inverse; + P->fwd = putp6_s_forward; return P; } @@ -91,8 +91,8 @@ PJ *PROJECTION(putp6p) { Q->D = 3.; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = putp6_s_inverse; + P->fwd = putp6_s_forward; return P; } diff --git a/src/projections/qsc.cpp b/src/projections/qsc.cpp index 409afb38..98e3755e 100644 --- a/src/projections/qsc.cpp +++ b/src/projections/qsc.cpp @@ -119,7 +119,7 @@ static double qsc_shift_lon_origin(double lon, double offset) { } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY qsc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double lat, lon; @@ -235,7 +235,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP qsc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double mu, nu, cosmu, tannu; @@ -382,8 +382,8 @@ PJ *PROJECTION(qsc) { return pj_default_destructor (P, ENOMEM); P->opaque = Q; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = qsc_e_inverse; + P->fwd = qsc_e_forward; /* Determine the cube face from the center of projection. */ if (P->phi0 >= M_HALFPI - M_FORTPI / 2.0) { Q->face = FACE_TOP; diff --git a/src/projections/robin.cpp b/src/projections/robin.cpp index dfb750dd..c08ac0e2 100644 --- a/src/projections/robin.cpp +++ b/src/projections/robin.cpp @@ -77,7 +77,7 @@ static const struct COEFS Y[] = { /* Not sure at all of the appropriate number for MAX_ITER... */ #define MAX_ITER 100 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY robin_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; long i; double dphi; @@ -99,7 +99,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP robin_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; long i; double t, t1; @@ -149,8 +149,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(robin) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = robin_s_inverse; + P->fwd = robin_s_forward; return P; } diff --git a/src/projections/rouss.cpp b/src/projections/rouss.cpp index f58277b8..f5a8f12f 100644 --- a/src/projections/rouss.cpp +++ b/src/projections/rouss.cpp @@ -44,7 +44,7 @@ struct pj_opaque { PROJ_HEAD(rouss, "Roussilhe Stereographic") "\n\tAzi, Ell"; -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY rouss_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double s, al, cp, sp, al2, s2; @@ -65,7 +65,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP rouss_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double s, al, x = xy.x / P->k0, y = xy.y / P->k0, x2, y2;; @@ -150,8 +150,8 @@ PJ *PROJECTION(rouss) { Q->D10 = R_R0_4 * t * (29. + t2 * (86. + t2 * 48.))/(96. * N0); Q->D11 = R_R0_4 * t * (37. + t2 * 44.)/(96. * N0); - P->fwd = e_forward; - P->inv = e_inverse; + P->fwd = rouss_e_forward; + P->inv = rouss_e_inverse; P->destructor = destructor; return P; diff --git a/src/projections/rpoly.cpp b/src/projections/rpoly.cpp index 6e883ab2..58decf66 100644 --- a/src/projections/rpoly.cpp +++ b/src/projections/rpoly.cpp @@ -20,7 +20,7 @@ PROJ_HEAD(rpoly, "Rectangular Polyconic") #define EPS 1e-9 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY rpoly_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double fa; @@ -53,7 +53,7 @@ PJ *PROJECTION(rpoly) { Q->fxa = 0.5 / Q->fxb; } P->es = 0.; - P->fwd = s_forward; + P->fwd = rpoly_s_forward; return P; } diff --git a/src/projections/sch.cpp b/src/projections/sch.cpp index c6fb6145..e302c1da 100644 --- a/src/projections/sch.cpp +++ b/src/projections/sch.cpp @@ -55,7 +55,7 @@ struct pj_opaque { PROJ_HEAD(sch, "Spherical Cross-track Height") "\n\tMisc\n\tplat_0= plon_0= phdg_0= [h_0=]"; -static PJ_LPZ inverse3d(PJ_XYZ xyz, PJ *P) { +static PJ_LPZ sch_inverse3d(PJ_XYZ xyz, PJ *P) { PJ_LPZ lpz = {0.0, 0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double temp[3]; @@ -93,7 +93,7 @@ static PJ_LPZ inverse3d(PJ_XYZ xyz, PJ *P) { return lpz; } -static PJ_XYZ forward3d(PJ_LPZ lpz, PJ *P) { +static PJ_XYZ sch_forward3d(PJ_LPZ lpz, PJ *P) { PJ_XYZ xyz = {0.0, 0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double temp[3]; @@ -187,8 +187,8 @@ static PJ *setup(PJ *P) { /* general initialization */ Q->xyzoff[1] = pxyz[1] - (Q->rcurv) * clt * slo; Q->xyzoff[2] = pxyz[2] - (Q->rcurv) * slt; - P->fwd3d = forward3d; - P->inv3d = inverse3d; + P->fwd3d = sch_forward3d; + P->inv3d = sch_inverse3d; return P; } diff --git a/src/projections/sconics.cpp b/src/projections/sconics.cpp index 7bdd2603..1a16fe24 100644 --- a/src/projections/sconics.cpp +++ b/src/projections/sconics.cpp @@ -62,7 +62,7 @@ static int phi12(PJ *P, double *del) { } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY sconics_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rho; @@ -85,7 +85,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, (and ellipsoidal?) inverse */ +static PJ_LP sconics_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, (and ellipsoidal?) inverse */ PJ_LP lp = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rho; @@ -177,8 +177,8 @@ static PJ *setup(PJ *P, enum Type type) { break; } - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = sconics_s_inverse; + P->fwd = sconics_s_forward; P->es = 0; return (P); } diff --git a/src/projections/somerc.cpp b/src/projections/somerc.cpp index ead9090f..be1f660d 100644 --- a/src/projections/somerc.cpp +++ b/src/projections/somerc.cpp @@ -18,7 +18,7 @@ struct pj_opaque { #define NITER 6 -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY somerc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0, 0.0}; double phip, lamp, phipp, lampp, sp, cp; struct pj_opaque *Q = static_cast(P->opaque); @@ -37,7 +37,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP somerc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double phip, lamp, phipp, lampp, cp, esp, con, delp; @@ -88,7 +88,7 @@ PJ *PROJECTION(somerc) { log (tan (M_FORTPI + 0.5 * P->phi0)) - Q->hlf_e * log ((1. + sp) / (1. - sp))); Q->kR = P->k0 * sqrt(P->one_es) / (1. - sp * sp); - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = somerc_e_inverse; + P->fwd = somerc_e_forward; return P; } diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp index fd9f9827..683d484c 100644 --- a/src/projections/stere.cpp +++ b/src/projections/stere.cpp @@ -41,7 +41,7 @@ static double ssfn_ (double phit, double sinphi, double eccen) { } -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY stere_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double coslam, sinlam, sinX = 0.0, cosX = 0.0, X, A = 0.0, sinphi; @@ -95,7 +95,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY stere_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double sinphi, cosphi, coslam, sinlam; @@ -137,7 +137,7 @@ oblcon: } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP stere_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, halfpi=0.0; @@ -188,7 +188,7 @@ static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP stere_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c, rh, sinc, cosc; @@ -265,8 +265,8 @@ static PJ *setup(PJ *P) { /* general initialization */ Q->cosX1 = cos (X); break; } - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = stere_e_inverse; + P->fwd = stere_e_forward; } else { switch (Q->mode) { case OBLIQ: @@ -284,8 +284,8 @@ static PJ *setup(PJ *P) { /* general initialization */ break; } - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = stere_s_inverse; + P->fwd = stere_s_forward; } return P; } diff --git a/src/projections/sterea.cpp b/src/projections/sterea.cpp index 964bb588..ca3bfd06 100644 --- a/src/projections/sterea.cpp +++ b/src/projections/sterea.cpp @@ -44,7 +44,7 @@ PROJ_HEAD(sterea, "Oblique Stereographic Alternative") "\n\tAzimuthal, Sph&Ell"; -static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ +static PJ_XY sterea_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cosc, sinc, cosl, k; @@ -65,7 +65,7 @@ static PJ_XY e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ } -static PJ_LP e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ +static PJ_LP sterea_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double rho, c, sinc, cosc; @@ -114,8 +114,8 @@ PJ *PROJECTION(sterea) { Q->cosc0 = cos (Q->phic0); Q->R2 = 2. * R; - P->inv = e_inverse; - P->fwd = e_forward; + P->inv = sterea_e_inverse; + P->fwd = sterea_e_forward; P->destructor = destructor; return P; diff --git a/src/projections/sts.cpp b/src/projections/sts.cpp index 27dc3eb8..4d682a53 100644 --- a/src/projections/sts.cpp +++ b/src/projections/sts.cpp @@ -20,7 +20,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY sts_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c; @@ -40,7 +40,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP sts_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double c; @@ -59,8 +59,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ static PJ *setup(PJ *P, double p, double q, int mode) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = sts_s_inverse; + P->fwd = sts_s_forward; static_cast(P->opaque)->C_x = q / p; static_cast(P->opaque)->C_y = p; static_cast(P->opaque)->C_p = 1/ q; diff --git a/src/projections/tcc.cpp b/src/projections/tcc.cpp index cfac9974..3dd47940 100644 --- a/src/projections/tcc.cpp +++ b/src/projections/tcc.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(tcc, "Transverse Central Cylindrical") "\n\tCyl, Sph, no inv"; #define EPS10 1.e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY tcc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; double b, bt; @@ -27,7 +27,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(tcc) { P->es = 0.; - P->fwd = s_forward; + P->fwd = tcc_s_forward; P->inv = nullptr; return P; diff --git a/src/projections/tcea.cpp b/src/projections/tcea.cpp index d780718d..a3c771ff 100644 --- a/src/projections/tcea.cpp +++ b/src/projections/tcea.cpp @@ -8,7 +8,7 @@ PROJ_HEAD(tcea, "Transverse Cylindrical Equal Area") "\n\tCyl, Sph"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY tcea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = cos (lp.phi) * sin (lp.lam) / P->k0; xy.y = P->k0 * (atan2 (tan (lp.phi), cos (lp.lam)) - P->phi0); @@ -16,7 +16,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP tcea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0, 0.0}; double t; @@ -30,8 +30,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(tcea) { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = tcea_s_inverse; + P->fwd = tcea_s_forward; P->es = 0.; return P; } diff --git a/src/projections/times.cpp b/src/projections/times.cpp index 4a0d0f59..21c6c19a 100644 --- a/src/projections/times.cpp +++ b/src/projections/times.cpp @@ -38,7 +38,7 @@ PROJ_HEAD(times, "Times") "\n\tCyl, Sph"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY times_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ double T, S, S2; PJ_XY xy = {0.0,0.0}; (void) P; @@ -54,7 +54,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP times_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ double T, S, S2; PJ_LP lp = {0.0,0.0}; (void) P; @@ -73,8 +73,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(times) { P->es = 0.0; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = times_s_inverse; + P->fwd = times_s_forward; return P; } diff --git a/src/projections/tobmerc.cpp b/src/projections/tobmerc.cpp index 126d6be2..7215f0db 100644 --- a/src/projections/tobmerc.cpp +++ b/src/projections/tobmerc.cpp @@ -18,7 +18,7 @@ static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */ return log(tan(M_FORTPI + .5 * x)); } -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY tobmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; double cosphi; @@ -33,7 +33,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ return xy; } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP tobmerc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0, 0.0}; double cosphi; @@ -44,7 +44,7 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ } PJ *PROJECTION(tobmerc) { - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = tobmerc_s_inverse; + P->fwd = tobmerc_s_forward; return P; } diff --git a/src/projections/tpeqd.cpp b/src/projections/tpeqd.cpp index 9904bb8c..b306968c 100644 --- a/src/projections/tpeqd.cpp +++ b/src/projections/tpeqd.cpp @@ -16,7 +16,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY tpeqd_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t, z1, z2, dl1, dl2, sp, cp; @@ -37,7 +37,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP tpeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double cz1, cz2, s, d, cp, sp; @@ -104,8 +104,8 @@ PJ *PROJECTION(tpeqd) { Q->r2z0 = 0.5 / Q->z02; Q->z02 *= Q->z02; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = tpeqd_s_inverse; + P->fwd = tpeqd_s_forward; P->es = 0.; return P; diff --git a/src/projections/urm5.cpp b/src/projections/urm5.cpp index f89bb1d5..499644d2 100644 --- a/src/projections/urm5.cpp +++ b/src/projections/urm5.cpp @@ -15,7 +15,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY urm5_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; struct pj_opaque *Q = static_cast(P->opaque); double t; @@ -54,7 +54,7 @@ PJ *PROJECTION(urm5) { P->es = 0.; P->inv = nullptr; - P->fwd = s_forward; + P->fwd = urm5_s_forward; return P; } diff --git a/src/projections/urmfps.cpp b/src/projections/urmfps.cpp index 3a51798b..3f9fdf23 100644 --- a/src/projections/urmfps.cpp +++ b/src/projections/urmfps.cpp @@ -19,7 +19,7 @@ struct pj_opaque { #define Cy 1.139753528477 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY urmfps_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; lp.phi = aasin (P->ctx,static_cast(P->opaque)->n * sin (lp.phi)); xy.x = C_x * lp.lam * cos (lp.phi); @@ -28,7 +28,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP urmfps_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0, 0.0}; xy.y /= static_cast(P->opaque)->C_y; lp.phi = aasin(P->ctx, sin (xy.y) / static_cast(P->opaque)->n); @@ -40,8 +40,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ static PJ *setup(PJ *P) { static_cast(P->opaque)->C_y = Cy / static_cast(P->opaque)->n; P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = urmfps_s_inverse; + P->fwd = urmfps_s_forward; return P; } diff --git a/src/projections/vandg.cpp b/src/projections/vandg.cpp index c669f8fa..7d485aff 100644 --- a/src/projections/vandg.cpp +++ b/src/projections/vandg.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(vandg, "van der Grinten (I)") "\n\tMisc Sph"; # define HPISQ 4.93480220054467930934 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY vandg_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double al, al2, g, g2, p2; @@ -58,7 +58,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP vandg_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; double t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2; @@ -105,8 +105,8 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(vandg) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = vandg_s_inverse; + P->fwd = vandg_s_forward; return P; } diff --git a/src/projections/vandg2.cpp b/src/projections/vandg2.cpp index de63b085..05314833 100644 --- a/src/projections/vandg2.cpp +++ b/src/projections/vandg2.cpp @@ -18,7 +18,7 @@ PROJ_HEAD(vandg3, "van der Grinten III") "\n\tMisc Sph, no inv"; #define TOL 1e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY vandg2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; struct pj_opaque *Q = static_cast(P->opaque); double x1, at, bt, ct; @@ -58,7 +58,7 @@ PJ *PROJECTION(vandg2) { P->opaque = Q; Q->vdg3 = 0; - P->fwd = s_forward; + P->fwd = vandg2_s_forward; return P; } @@ -71,7 +71,7 @@ PJ *PROJECTION(vandg3) { Q->vdg3 = 1; P->es = 0.; - P->fwd = s_forward; + P->fwd = vandg2_s_forward; return P; } diff --git a/src/projections/vandg4.cpp b/src/projections/vandg4.cpp index 8511431d..a5cfd8e6 100644 --- a/src/projections/vandg4.cpp +++ b/src/projections/vandg4.cpp @@ -10,7 +10,7 @@ PROJ_HEAD(vandg4, "van der Grinten IV") "\n\tMisc Sph, no inv"; #define TOL 1e-10 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY vandg4_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; double x1, t, bt, ct, ft, bt2, ct2, dt, dt2; (void) P; @@ -50,7 +50,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(vandg4) { P->es = 0.; - P->fwd = s_forward; + P->fwd = vandg4_s_forward; return P; } diff --git a/src/projections/wag2.cpp b/src/projections/wag2.cpp index e04cc648..4e7c28ac 100644 --- a/src/projections/wag2.cpp +++ b/src/projections/wag2.cpp @@ -13,7 +13,7 @@ PROJ_HEAD(wag2, "Wagner II") "\n\tPCyl, Sph"; #define C_p2 0.88550 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY wag2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; lp.phi = aasin (P->ctx,C_p1 * sin (C_p2 * lp.phi)); xy.x = C_x * lp.lam * cos (lp.phi); @@ -22,7 +22,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP wag2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y / C_y; lp.lam = xy.x / (C_x * cos(lp.phi)); @@ -33,7 +33,7 @@ static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ *PROJECTION(wag2) { P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = wag2_s_inverse; + P->fwd = wag2_s_forward; return P; } diff --git a/src/projections/wag3.cpp b/src/projections/wag3.cpp index ed695ffd..33313cdb 100644 --- a/src/projections/wag3.cpp +++ b/src/projections/wag3.cpp @@ -17,7 +17,7 @@ struct pj_opaque { } // anonymous namespace -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY wag3_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = static_cast(P->opaque)->C_x * lp.lam * cos(TWOTHIRD * lp.phi); xy.y = lp.phi; @@ -25,7 +25,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP wag3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y; lp.lam = xy.x / (static_cast(P->opaque)->C_x * cos(TWOTHIRD * lp.phi)); @@ -44,8 +44,8 @@ PJ *PROJECTION(wag3) { ts = pj_param (P->ctx, P->params, "rlat_ts").f; static_cast(P->opaque)->C_x = cos (ts) / cos (2.*ts/3.); P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = wag3_s_inverse; + P->fwd = wag3_s_forward; return P; } diff --git a/src/projections/wag7.cpp b/src/projections/wag7.cpp index 45b70ee2..3afb5a03 100644 --- a/src/projections/wag7.cpp +++ b/src/projections/wag7.cpp @@ -9,7 +9,7 @@ PROJ_HEAD(wag7, "Wagner VII") "\n\tMisc Sph, no inv"; -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY wag7_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; double theta, ct, D; @@ -24,7 +24,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ *PROJECTION(wag7) { - P->fwd = s_forward; + P->fwd = wag7_s_forward; P->inv = nullptr; P->es = 0.; return P; diff --git a/src/projections/wink1.cpp b/src/projections/wink1.cpp index 75abbffc..d097978f 100644 --- a/src/projections/wink1.cpp +++ b/src/projections/wink1.cpp @@ -16,7 +16,7 @@ struct pj_opaque { -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY wink1_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = .5 * lp.lam * (static_cast(P->opaque)->cosphi1 + cos(lp.phi)); xy.y = lp.phi; @@ -24,7 +24,7 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ } -static PJ_LP s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ +static PJ_LP wink1_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ PJ_LP lp = {0.0,0.0}; lp.phi = xy.y; lp.lam = 2. * xy.x / (static_cast(P->opaque)->cosphi1 + cos(lp.phi)); @@ -40,8 +40,8 @@ PJ *PROJECTION(wink1) { static_cast(P->opaque)->cosphi1 = cos (pj_param(P->ctx, P->params, "rlat_ts").f); P->es = 0.; - P->inv = s_inverse; - P->fwd = s_forward; + P->inv = wink1_s_inverse; + P->fwd = wink1_s_forward; return P; } diff --git a/src/projections/wink2.cpp b/src/projections/wink2.cpp index 6957bde1..4aaf1972 100644 --- a/src/projections/wink2.cpp +++ b/src/projections/wink2.cpp @@ -18,7 +18,7 @@ struct pj_opaque { #define LOOP_TOL 1e-7 -static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ +static PJ_XY wink2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; double k, V; int i; @@ -51,7 +51,7 @@ PJ *PROJECTION(wink2) { static_cast(P->opaque)->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f); P->es = 0.; P->inv = nullptr; - P->fwd = s_forward; + P->fwd = wink2_s_forward; return P; } -- cgit v1.2.3 From c3c1efedbeae11a09947f2873fe97e50afa87b29 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 28 Apr 2019 13:00:18 +0200 Subject: Fix false-positive -Wnull-dereference GCC 8 warning --- src/iso19111/coordinateoperation.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 7eab849c..6a05c285 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12584,11 +12584,11 @@ getResolvedCRS(const crs::CRSNNPtr &crs, const auto tmpAuthFactory = io::AuthorityFactory::create( authFactory->databaseContext(), *ids.front()->codeSpace()); try { - crs::CRSNNPtr resolvedCrs( + auto resolvedCrs( tmpAuthFactory->createProjectedCRS(ids.front()->code())); - if (resolvedCrs->_isEquivalentTo( + if (resolvedCrs->isEquivalentTo( crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return resolvedCrs; + return util::nn_static_pointer_cast(resolvedCrs); } } catch (const std::exception &) { } @@ -12616,12 +12616,13 @@ getResolvedCRS(const crs::CRSNNPtr &crs, const auto tmpAuthFactory = io::AuthorityFactory::create( authFactory->databaseContext(), *ids.front()->codeSpace()); try { - crs::CRSNNPtr resolvedCrs( + auto resolvedCrs( tmpAuthFactory->createCompoundCRS(ids.front()->code())); - if (resolvedCrs->_isEquivalentTo( + if (resolvedCrs->isEquivalentTo( crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return resolvedCrs; + return util::nn_static_pointer_cast( + resolvedCrs); } } catch (const std::exception &) { } -- cgit v1.2.3 From cca27b1fae234a90df42ff5341121759846dc39b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 14:31:16 +0200 Subject: Propagate ballpark transformation flag to inverse coordinate operations --- src/iso19111/coordinateoperation.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 6a05c285..2cab05bd 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -7484,6 +7484,8 @@ Transformation::Private::registerInv(util::BaseObjectNNPtr thisIn, TransformationNNPtr invTransform) { invTransform->d->forwardOperation_ = util::nn_dynamic_pointer_cast(thisIn); + invTransform->setHasBallparkTransformation( + invTransform->d->forwardOperation_->hasBallparkTransformation()); return invTransform; } //! @endcond @@ -9490,6 +9492,7 @@ CoordinateOperationNNPtr ConcatenatedOperation::inverse() const { auto op = create(properties, inversedOperations, coordinateOperationAccuracies()); op->d->computedName_ = d->computedName_; + op->setHasBallparkTransformation(hasBallparkTransformation()); return op; } @@ -12704,6 +12707,8 @@ void InverseCoordinateOperation::setPropertiesFromForward() { if (forwardOperation_->sourceCRS() && forwardOperation_->targetCRS()) { setCRSs(forwardOperation_.get(), true); } + setHasBallparkTransformation( + forwardOperation_->hasBallparkTransformation()); } // --------------------------------------------------------------------------- -- cgit v1.2.3 From b4a9e65cec051ca3cb16b8cccfa012d70ce10570 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 14:56:32 +0200 Subject: createOperations(): in SourceTargetCRSExtentUse::INTERSECTION mode, early return if the intersection of the areas is empty --- src/iso19111/coordinateoperation.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 2cab05bd..ca882f49 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12669,6 +12669,17 @@ CoordinateOperationFactory::createOperations( auto l_resolvedTargetCRS = getResolvedCRS(l_targetCRS, context); Private::Context contextPrivate(l_resolvedSourceCRS, l_resolvedTargetCRS, context); + + if (context->getSourceAndTargetCRSExtentUse() == + CoordinateOperationContext::SourceTargetCRSExtentUse::INTERSECTION) { + auto sourceCRSExtent(getExtent(l_resolvedSourceCRS)); + auto targetCRSExtent(getExtent(l_resolvedTargetCRS)); + if (sourceCRSExtent && targetCRSExtent && + !sourceCRSExtent->intersects(NN_NO_CHECK(targetCRSExtent))) { + return std::vector(); + } + } + return filterAndSort(Private::createOperations(l_resolvedSourceCRS, l_resolvedTargetCRS, contextPrivate), -- cgit v1.2.3 From 09cbfb85c834d99e5a00f5989dc144613e0cfbf2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 17:25:38 +0200 Subject: WKT importer: accepts PROJ-based COORDINATEOPERATION --- src/iso19111/coordinateoperation.cpp | 2 +- src/iso19111/io.cpp | 36 +++++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index ca882f49..9c393aba 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12802,7 +12802,7 @@ PROJBasedOperationNNPtr PROJBasedOperation::create( auto method = OperationMethod::create( util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, - "PROJ-based operation method (approximate) : " + + "PROJ-based operation method (approximate): " + projString), std::vector{}); auto op = PROJBasedOperation::nn_make_shared(method); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index d8282bb0..0a32bb7c 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -1342,7 +1342,7 @@ struct WKTParser::Private { CRSPtr buildCRS(const WKTNodeNNPtr &node); - CoordinateOperationNNPtr buildCoordinateOperation(const WKTNodeNNPtr &node); + TransformationNNPtr buildCoordinateOperation(const WKTNodeNNPtr &node); ConcatenatedOperationNNPtr buildConcatenatedOperation(const WKTNodeNNPtr &node); @@ -2940,7 +2940,7 @@ WKTParser::Private::buildConversion(const WKTNodeNNPtr &node, // --------------------------------------------------------------------------- -CoordinateOperationNNPtr +TransformationNNPtr WKTParser::Private::buildCoordinateOperation(const WKTNodeNNPtr &node) { const auto *nodeP = node->GP(); auto &methodNode = nodeP->lookForChild(WKTConstants::METHOD); @@ -2991,11 +2991,10 @@ WKTParser::Private::buildCoordinateOperation(const WKTNodeNNPtr &node) { stripQuotes(accuracyNode->GP()->children()[0]))); } - return util::nn_static_pointer_cast( - Transformation::create(buildProperties(node), NN_NO_CHECK(sourceCRS), - NN_NO_CHECK(targetCRS), interpolationCRS, - buildProperties(methodNode), parameters, values, - accuracies)); + return Transformation::create(buildProperties(node), NN_NO_CHECK(sourceCRS), + NN_NO_CHECK(targetCRS), interpolationCRS, + buildProperties(methodNode), parameters, + values, accuracies); } // --------------------------------------------------------------------------- @@ -4307,16 +4306,31 @@ BaseObjectNNPtr WKTParser::Private::build(const WKTNodeNNPtr &node) { } if (ci_equal(name, WKTConstants::COORDINATEOPERATION)) { - return util::nn_static_pointer_cast( - buildCoordinateOperation(node)); + auto transf = buildCoordinateOperation(node); + + const char *prefixes[] = { + "PROJ-based operation method: ", + "PROJ-based operation method (approximate): "}; + for (const char *prefix : prefixes) { + if (starts_with(transf->method()->nameStr(), prefix)) { + auto projString = + transf->method()->nameStr().substr(strlen(prefix)); + return util::nn_static_pointer_cast( + PROJBasedOperation::create( + PropertyMap(), projString, transf->sourceCRS(), + transf->targetCRS(), + transf->coordinateOperationAccuracies())); + } + } + + return util::nn_static_pointer_cast(transf); } if (ci_equal(name, WKTConstants::CONVERSION)) { auto conv = buildConversion(node, UnitOfMeasure::METRE, UnitOfMeasure::DEGREE); - if (conv->nameStr() == "PROJ-based coordinate operation" && - starts_with(conv->method()->nameStr(), + if (starts_with(conv->method()->nameStr(), "PROJ-based operation method: ")) { auto projString = conv->method()->nameStr().substr( strlen("PROJ-based operation method: ")); -- cgit v1.2.3 From f98f6533cda8fe85fa7507ba97a4eb098ea32cba Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 2 May 2019 18:11:44 +0200 Subject: lagrng: avoid division by zero when latitude is very close to 90 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14477 Credit to OSS Fuzz --- src/projections/lagrng.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/projections/lagrng.cpp b/src/projections/lagrng.cpp index ac7a37a4..d37a00e6 100644 --- a/src/projections/lagrng.cpp +++ b/src/projections/lagrng.cpp @@ -26,12 +26,12 @@ static PJ_XY lagrng_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwa struct pj_opaque *Q = static_cast(P->opaque); double v, c; - if (fabs(fabs(lp.phi) - M_HALFPI) < TOL) { + const double sin_phi = sin(lp.phi); + if (fabs(fabs(sin_phi) - 1) < TOL) { xy.x = 0; xy.y = lp.phi < 0 ? -2. : 2.; } else { - lp.phi = sin(lp.phi); - v = Q->a1 * pow((1. + lp.phi)/(1. - lp.phi), Q->hrw); + v = Q->a1 * pow((1. + sin_phi)/(1. - sin_phi), Q->hrw); lp.lam *= Q->rw; c = 0.5 * (v + 1./v) + cos(lp.lam); if (c < TOL) { @@ -70,7 +70,7 @@ static PJ_LP lagrng_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver PJ *PROJECTION(lagrng) { - double phi1; + double sin_phi1; struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); @@ -85,11 +85,11 @@ PJ *PROJECTION(lagrng) { Q->hw = 0.5 * Q->w; Q->rw = 1. / Q->w; Q->hrw = 0.5 * Q->rw; - phi1 = sin(pj_param(P->ctx, P->params, "rlat_1").f); - if (fabs(fabs(phi1) - 1.) < TOL) + sin_phi1 = sin(pj_param(P->ctx, P->params, "rlat_1").f); + if (fabs(fabs(sin_phi1) - 1.) < TOL) return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90); - Q->a1 = pow((1. - phi1)/(1. + phi1), Q->hrw); + Q->a1 = pow((1. - sin_phi1)/(1. + sin_phi1), Q->hrw); Q->a2 = Q->a1 * Q->a1; P->es = 0.; -- cgit v1.2.3 From c5346c7c25ca9fe281df39eaeefebc1aa4009266 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 3 May 2019 20:54:42 +0200 Subject: cs2cs: set time value to HUGE_VAL if not explicitly specified --- src/apps/cs2cs.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 40b0d584..20e5e73c 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -123,6 +123,8 @@ static void process(FILE *fid) /* is forward verbatim from the input. */ char *before_time = s; double t = strtod(s, &s); + if( s == before_time ) + t = HUGE_VAL; s = before_time; if (data.v == HUGE_VAL) -- cgit v1.2.3 From 96af6dbf69dd38421916438702be80f73276d879 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 5 May 2019 20:28:59 +0200 Subject: geos: avoid division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14602 Credit to OSS Fuzz --- src/apps/gie.cpp | 2 +- src/proj_internal.h | 2 +- src/projections/geos.cpp | 5 +++-- src/projections/nsper.cpp | 5 +++-- src/strerrno.cpp | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 5a86ebb7..2f401984 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -1121,7 +1121,7 @@ static const struct errno_vs_err_const lookup[] = { {"pjd_err_w_or_m_zero_or_less" , -27}, {"pjd_err_lsat_not_in_range" , -28}, {"pjd_err_path_not_in_range" , -29}, - {"pjd_err_h_less_than_zero" , -30}, + {"pjd_err_invalid_h" , -30}, {"pjd_err_k_less_than_zero" , -31}, {"pjd_err_lat_1_or_2_zero_or_90" , -32}, {"pjd_err_lat_0_or_alpha_eq_90" , -33}, diff --git a/src/proj_internal.h b/src/proj_internal.h index 66cadb1a..8c365793 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -648,7 +648,7 @@ struct FACTORS { #define PJD_ERR_W_OR_M_ZERO_OR_LESS -27 #define PJD_ERR_LSAT_NOT_IN_RANGE -28 #define PJD_ERR_PATH_NOT_IN_RANGE -29 -#define PJD_ERR_H_LESS_THAN_ZERO -30 +#define PJD_ERR_INVALID_H -30 #define PJD_ERR_K_LESS_THAN_ZERO -31 #define PJD_ERR_LAT_1_OR_2_ZERO_OR_90 -32 #define PJD_ERR_LAT_0_OR_ALPHA_EQ_90 -33 diff --git a/src/projections/geos.cpp b/src/projections/geos.cpp index 7c15f22a..5b3e594c 100644 --- a/src/projections/geos.cpp +++ b/src/projections/geos.cpp @@ -202,8 +202,7 @@ PJ *PROJECTION(geos) { return pj_default_destructor (P, ENOMEM); P->opaque = Q; - if ((Q->h = pj_param(P->ctx, P->params, "dh").f) <= 0.) - return pj_default_destructor (P, PJD_ERR_H_LESS_THAN_ZERO); + Q->h = pj_param(P->ctx, P->params, "dh").f; sweep_axis = pj_param(P->ctx, P->params, "ssweep").s; if (sweep_axis == nullptr) @@ -220,6 +219,8 @@ PJ *PROJECTION(geos) { } Q->radius_g_1 = Q->h / P->a; + if ( Q->radius_g_1 <= 0 || Q->radius_g_1 > 1e10 ) + return pj_default_destructor (P, PJD_ERR_INVALID_H); Q->radius_g = 1. + Q->radius_g_1; Q->C = Q->radius_g * Q->radius_g - 1.0; if (P->es != 0.0) { diff --git a/src/projections/nsper.cpp b/src/projections/nsper.cpp index fbf5317b..d641e1b6 100644 --- a/src/projections/nsper.cpp +++ b/src/projections/nsper.cpp @@ -148,8 +148,7 @@ static PJ_LP nsper_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers static PJ *setup(PJ *P) { struct pj_opaque *Q = static_cast(P->opaque); - if ((Q->height = pj_param(P->ctx, P->params, "dh").f) <= 0.) - return pj_default_destructor(P, PJD_ERR_H_LESS_THAN_ZERO); + Q->height = pj_param(P->ctx, P->params, "dh").f; if (fabs(fabs(P->phi0) - M_HALFPI) < EPS10) Q->mode = P->phi0 < 0. ? S_POLE : N_POLE; @@ -161,6 +160,8 @@ static PJ *setup(PJ *P) { Q->cosph0 = cos(P->phi0); } Q->pn1 = Q->height / P->a; /* normalize by radius */ + if ( Q->pn1 <= 0 || Q->pn1 > 1e10 ) + return pj_default_destructor (P, PJD_ERR_INVALID_H); Q->p = 1. + Q->pn1; Q->rp = 1. / Q->p; Q->h = 1. / Q->pn1; diff --git a/src/strerrno.cpp b/src/strerrno.cpp index c230d226..12546bd0 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -39,7 +39,7 @@ pj_err_list[] = { "W <= 0 or M <= 0", /* -27 */ "lsat not in 1-5 range", /* -28 */ "path not in range", /* -29 */ - "h <= 0", /* -30 */ + "h <= 0 or h > 1e10 * a", /* -30 */ "k <= 0", /* -31 */ "lat_1=lat_2 or lat_1=0 or lat_2=90", /* -32 */ "lat_0 = 0 or 90 or alpha = 90", /* -33 */ -- cgit v1.2.3 From aaddaf6e65cee8443c6e0db7157bee9057d5d420 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 6 May 2019 07:23:53 +0200 Subject: Update ABI version number for 6.1.0 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index aa1787c1..aed5a393 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ geodtest_LDADD = libproj.la lib_LTLIBRARIES = libproj.la -libproj_la_LDFLAGS = -no-undefined -version-info 15:0:0 +libproj_la_LDFLAGS = -no-undefined -version-info 16:0:1 libproj_la_LIBADD = @SQLITE3_LIBS@ libproj_la_SOURCES = \ -- cgit v1.2.3 From 19766318ef918db5a4ef90700db10a9c91281d46 Mon Sep 17 00:00:00 2001 From: Bas Couwenberg Date: Mon, 6 May 2019 08:54:10 +0200 Subject: Fix spelling errors. * unknow -> unknown --- src/strerrno.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 12546bd0..9bf5f45a 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -70,7 +70,7 @@ pj_err_list[] = { "argument not numerical or out of range", /* -58 */ "inconsistent unit type between input and output", /* -59 */ "arguments are mutually exclusive", /* -60 */ - "generic error of unknow origin", /* -61 */ + "generic error of unknown origin", /* -61 */ /* When adding error messages, remember to update ID defines in projects.h, and transient_error array in pj_transform */ -- cgit v1.2.3 From 5e98fed78205605ccb01ab4310d3cba292de73b4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 6 May 2019 12:43:04 +0200 Subject: createOperations(): fix case of ETRS89 3D to proj string with nadgrids and geoidgrids Fixes https://lists.osgeo.org/pipermail/proj/2019-May/008519.html --- src/iso19111/coordinateoperation.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 605004b6..f75f7588 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12135,6 +12135,37 @@ CoordinateOperationFactory::Private::createOperations( } } + auto vertCRSOfBaseOfBoundSrc = + dynamic_cast(boundSrc->baseCRS().get()); + if (vertCRSOfBaseOfBoundSrc && hubSrcGeog && + hubSrcGeog->coordinateSystem()->axisList().size() == 3 && + geogDst->coordinateSystem()->axisList().size() == 3) { + auto opsFirst = createOperations(sourceCRS, hubSrc, context); + auto opsSecond = createOperations(hubSrc, targetCRS, context); + if (!opsFirst.empty() && !opsSecond.empty()) { + for (const auto &opFirst : opsFirst) { + for (const auto &opLast : opsSecond) { + // Exclude artificial transformations from the hub + // to the target CRS + if (!opLast->hasBallparkTransformation()) { + try { + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {opFirst, opLast}, + !allowEmptyIntersection)); + } catch ( + const InvalidOperationEmptyIntersection &) { + } + } + } + } + if (!res.empty()) { + return res; + } + } + } + return createOperations(boundSrc->baseCRS(), targetCRS, context); } -- cgit v1.2.3 From 61cf8c5b29c82ab7e46b207bd125eaad49c03021 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 6 May 2019 19:45:27 +0200 Subject: createOperations(): for 'Amersfoort / RD New + NAP height' (EPSG:7415) to ETRS89 (EPSG:4937), make sure that the vgridshift is applied first (ie on Amersfoort datum) before the hgridshift --- src/iso19111/coordinateoperation.cpp | 111 ++++++++++++++++++++++++++++------- src/iso19111/internal.cpp | 15 +++++ src/iso19111/io.cpp | 20 ++++--- 3 files changed, 117 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index f75f7588..348a776a 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -6958,11 +6958,11 @@ TransformationNNPtr Transformation::createNTv2( static TransformationNNPtr _createGravityRelatedHeightToGeographic3D( const util::PropertyMap &properties, bool inverse, const crs::CRSNNPtr &sourceCRSIn, const crs::CRSNNPtr &targetCRSIn, - const std::string &filename, + const crs::CRSPtr &interpolationCRSIn, const std::string &filename, const std::vector &accuracies) { return Transformation::create( - properties, sourceCRSIn, targetCRSIn, nullptr, + properties, sourceCRSIn, targetCRSIn, interpolationCRSIn, util::PropertyMap().set( common::IdentifiedObject::NAME_KEY, inverse ? INVERSE_OF + PROJ_WKT2_NAME_METHOD_HEIGHT_TO_GEOG3D @@ -6981,17 +6981,20 @@ static TransformationNNPtr _createGravityRelatedHeightToGeographic3D( * At minimum the name should be defined. * @param sourceCRSIn Source CRS. * @param targetCRSIn Target CRS. + * @param interpolationCRSIn Interpolation CRS. (might be null) * @param filename GRID filename. * @param accuracies Vector of positional accuracy (might be empty). * @return new Transformation. */ TransformationNNPtr Transformation::createGravityRelatedHeightToGeographic3D( const util::PropertyMap &properties, const crs::CRSNNPtr &sourceCRSIn, - const crs::CRSNNPtr &targetCRSIn, const std::string &filename, + const crs::CRSNNPtr &targetCRSIn, const crs::CRSPtr &interpolationCRSIn, + const std::string &filename, const std::vector &accuracies) { return _createGravityRelatedHeightToGeographic3D( - properties, false, sourceCRSIn, targetCRSIn, filename, accuracies); + properties, false, sourceCRSIn, targetCRSIn, interpolationCRSIn, + filename, accuracies); } // --------------------------------------------------------------------------- @@ -7302,8 +7305,20 @@ createPropertiesForInverse(const CoordinateOperation *op, bool derivedFrom, auto targetCRS = op->targetCRS(); std::string name; if (!forwardName.empty()) { - if (starts_with(forwardName, INVERSE_OF)) { - name = forwardName.substr(INVERSE_OF.size()); + if (starts_with(forwardName, INVERSE_OF) || + forwardName.find(" + ") != std::string::npos) { + auto tokens = split(forwardName, " + "); + for (size_t i = tokens.size(); i > 0;) { + i--; + if (!name.empty()) { + name += " + "; + } + if (starts_with(tokens[i], INVERSE_OF)) { + name += tokens[i].substr(INVERSE_OF.size()); + } else { + name += INVERSE_OF + tokens[i]; + } + } } else if (!sourceCRS || !targetCRS || forwardName != buildOpName(opType, sourceCRS, targetCRS)) { name = INVERSE_OF + forwardName; @@ -8195,13 +8210,14 @@ TransformationNNPtr Transformation::substitutePROJAlternativeGridNames( return createGravityRelatedHeightToGeographic3D( createPropertiesForInverse(self.as_nullable().get(), true, false), - targetCRS(), sourceCRS(), projFilename, - coordinateOperationAccuracies()) + targetCRS(), sourceCRS(), interpolationCRS(), + projFilename, coordinateOperationAccuracies()) ->inverseAsTransformation(); } else { return createGravityRelatedHeightToGeographic3D( createSimilarPropertiesTransformation(self), sourceCRS(), - targetCRS(), projFilename, coordinateOperationAccuracies()); + targetCRS(), interpolationCRS(), projFilename, + coordinateOperationAccuracies()); } } } @@ -10972,19 +10988,19 @@ struct MyPROJStringExportableHorizVertical final // cppcheck-suppress functionStatic _exportToPROJString(io::PROJStringFormatter *formatter) const override { - formatter->setOmitZUnitConversion(true); + formatter->pushOmitZUnitConversion(); horizTransform->_exportToPROJString(formatter); formatter->startInversion(); geogDst->addAngularUnitConvertAndAxisSwap(formatter); formatter->stopInversion(); - formatter->setOmitZUnitConversion(false); + formatter->popOmitZUnitConversion(); verticalTransform->_exportToPROJString(formatter); - formatter->setOmitZUnitConversion(true); + formatter->pushOmitZUnitConversion(); geogDst->addAngularUnitConvertAndAxisSwap(formatter); - formatter->setOmitZUnitConversion(false); + formatter->popOmitZUnitConversion(); } }; @@ -11016,7 +11032,7 @@ struct MyPROJStringExportableHorizVerticalHorizPROJBased final // cppcheck-suppress functionStatic _exportToPROJString(io::PROJStringFormatter *formatter) const override { - formatter->setOmitZUnitConversion(true); + formatter->pushOmitZUnitConversion(); opSrcCRSToGeogCRS->_exportToPROJString(formatter); @@ -11024,17 +11040,17 @@ struct MyPROJStringExportableHorizVerticalHorizPROJBased final interpolationGeogCRS->addAngularUnitConvertAndAxisSwap(formatter); formatter->stopInversion(); - formatter->setOmitZUnitConversion(false); + formatter->popOmitZUnitConversion(); verticalTransform->_exportToPROJString(formatter); - formatter->setOmitZUnitConversion(true); + formatter->pushOmitZUnitConversion(); interpolationGeogCRS->addAngularUnitConvertAndAxisSwap(formatter); opGeogCRStoDstCRS->_exportToPROJString(formatter); - formatter->setOmitZUnitConversion(false); + formatter->popOmitZUnitConversion(); } }; @@ -12380,7 +12396,8 @@ CoordinateOperationFactory::Private::createOperations( const auto &componentsSrc = compoundSrc->componentReferenceSystems(); if (!componentsSrc.empty()) { std::vector horizTransforms; - if (componentsSrc[0]->extractGeographicCRS()) { + auto srcGeogCRS = componentsSrc[0]->extractGeographicCRS(); + if (srcGeogCRS) { horizTransforms = createOperations(componentsSrc[0], targetCRS, context); } @@ -12394,11 +12411,61 @@ CoordinateOperationFactory::Private::createOperations( for (const auto &horizTransform : horizTransforms) { for (const auto &verticalTransform : verticalTransforms) { - auto op = createHorizVerticalPROJBased( - sourceCRS, targetCRS, horizTransform, - verticalTransform); + crs::GeographicCRSPtr interpolationGeogCRS; + auto transformationVerticalTransform = + dynamic_cast( + verticalTransform.get()); + if (transformationVerticalTransform) { + auto interpTransformCRS = + transformationVerticalTransform + ->interpolationCRS(); + if (interpTransformCRS) { + auto nn_interpTransformCRS = + NN_NO_CHECK(interpTransformCRS); + if (dynamic_cast( + nn_interpTransformCRS.get())) { + interpolationGeogCRS = + util::nn_dynamic_pointer_cast< + crs::GeographicCRS>( + nn_interpTransformCRS); + } + } + } + bool done = false; + if (interpolationGeogCRS && + (interpolationGeogCRS->_isEquivalentTo( + srcGeogCRS.get(), + util::IComparable::Criterion::EQUIVALENT) || + interpolationGeogCRS->is2DPartOf3D( + NN_NO_CHECK(srcGeogCRS.get())))) { + auto srcToInterp = createOperations( + componentsSrc[0], + NN_NO_CHECK(interpolationGeogCRS), context); + auto interpToCompoundHoriz = createOperations( + NN_NO_CHECK(interpolationGeogCRS), + componentsSrc[0], context); + if (!srcToInterp.empty() && + !interpToCompoundHoriz.empty()) { + auto op = createHorizVerticalHorizPROJBased( + sourceCRS, componentsSrc[0], + srcToInterp.front(), verticalTransform, + interpToCompoundHoriz.front(), + interpolationGeogCRS); + done = true; + res.emplace_back( + ConcatenatedOperation:: + createComputeMetadata( + {op, horizTransform}, + !allowEmptyIntersection)); + } + } + if (!done) { + auto op = createHorizVerticalPROJBased( + sourceCRS, targetCRS, horizTransform, + verticalTransform); - res.emplace_back(op); + res.emplace_back(op); + } } } return res; diff --git a/src/iso19111/internal.cpp b/src/iso19111/internal.cpp index 240c98f4..4810202d 100644 --- a/src/iso19111/internal.cpp +++ b/src/iso19111/internal.cpp @@ -298,6 +298,21 @@ std::vector split(const std::string &str, char separator) { // --------------------------------------------------------------------------- +std::vector split(const std::string &str, + const std::string &separator) { + std::vector res; + size_t lastPos = 0; + size_t newPos = 0; + while ((newPos = str.find(separator, lastPos)) != std::string::npos) { + res.push_back(str.substr(lastPos, newPos - lastPos)); + lastPos = newPos + separator.size(); + } + res.push_back(str.substr(lastPos)); + return res; +} + +// --------------------------------------------------------------------------- + #ifdef _WIN32 // For some reason, sqlite3_snprintf() in the sqlite3 builds used on AppVeyor diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index e072a66f..c84ea2f3 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -3818,7 +3818,7 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) { Transformation::createGravityRelatedHeightToGeographic3D( PropertyMap().set(IdentifiedObject::NAME_KEY, transformationName), - crs, GeographicCRS::EPSG_4979, + crs, GeographicCRS::EPSG_4979, nullptr, stripQuotes(extensionChildren[1]), std::vector()); return nn_static_pointer_cast(BoundCRS::create( @@ -4922,7 +4922,7 @@ struct PROJStringFormatter::Private { }; std::vector inversionStack_{InversionStackElt()}; bool omitProjLongLatIfPossible_ = false; - bool omitZUnitConversion_ = false; + std::vector omitZUnitConversion_{false}; DatabaseContextPtr dbContext_{}; bool useApproxTMerc_ = false; bool addNoDefs_ = true; @@ -5939,15 +5939,21 @@ bool PROJStringFormatter::omitProjLongLatIfPossible() const { // --------------------------------------------------------------------------- -void PROJStringFormatter::setOmitZUnitConversion(bool omit) { - assert(d->omitZUnitConversion_ ^ omit); - d->omitZUnitConversion_ = omit; +void PROJStringFormatter::pushOmitZUnitConversion() { + d->omitZUnitConversion_.push_back(true); +} + +// --------------------------------------------------------------------------- + +void PROJStringFormatter::popOmitZUnitConversion() { + assert(d->omitZUnitConversion_.size() > 1); + d->omitZUnitConversion_.pop_back(); } // --------------------------------------------------------------------------- bool PROJStringFormatter::omitZUnitConversion() const { - return d->omitZUnitConversion_; + return d->omitZUnitConversion_.back(); } // --------------------------------------------------------------------------- @@ -6995,7 +7001,7 @@ PROJStringParser::Private::buildBoundOrCompoundCRSIfNeeded(int iStep, Transformation::createGravityRelatedHeightToGeographic3D( PropertyMap().set(IdentifiedObject::NAME_KEY, "unknown to WGS84 ellipsoidal height"), - crs, GeographicCRS::EPSG_4979, geoidgrids, + crs, GeographicCRS::EPSG_4979, nullptr, geoidgrids, std::vector()); auto boundvcrs = BoundCRS::create(vcrs, GeographicCRS::EPSG_4979, transformation); -- cgit v1.2.3 From 4d722565d63d504aab5fb2e403d1dd5c3b649d1a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 8 May 2019 12:00:08 +0200 Subject: proj_normalize_for_visualization(): fix when there are coordinate operation alternatives --- src/iso19111/c_api.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 6a2a1ae0..85421fa0 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -30,6 +30,7 @@ #define FROM_PROJ_CPP #endif +#include #include #include #include @@ -151,6 +152,7 @@ static PJ *pj_obj_create(PJ_CONTEXT *ctx, const IdentifiedObjectNNPtr &objIn) { } auto pj = pj_new(); if (pj) { + pj->ctx = ctx; pj->descr = "ISO-19111 object"; pj->iso_obj = objIn; } @@ -6793,6 +6795,56 @@ int proj_cs_get_axis_info(PJ_CONTEXT *ctx, const PJ *cs, int index, * nullptr in case of error */ PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) { + + if (!obj->alternativeCoordinateOperations.empty()) { + try { + auto pjNew = pj_new(); + pjNew->ctx = ctx; + for (const auto &alt : obj->alternativeCoordinateOperations) { + auto co = dynamic_cast( + alt.pj->iso_obj.get()); + if (co) { + double minxSrc = alt.minxSrc; + double minySrc = alt.minySrc; + double maxxSrc = alt.maxxSrc; + double maxySrc = alt.maxySrc; + double minxDst = alt.minxDst; + double minyDst = alt.minyDst; + double maxxDst = alt.maxxDst; + double maxyDst = alt.maxyDst; + + auto l_sourceCRS = co->sourceCRS(); + auto l_targetCRS = co->targetCRS(); + if (l_sourceCRS && l_targetCRS) { + const bool swapSource = + l_sourceCRS + ->mustAxisOrderBeSwitchedForVisualization(); + if (swapSource) { + std::swap(minxSrc, minySrc); + std::swap(maxxSrc, maxySrc); + } + const bool swapTarget = + l_targetCRS + ->mustAxisOrderBeSwitchedForVisualization(); + if (swapTarget) { + std::swap(minxDst, minyDst); + std::swap(maxxDst, maxyDst); + } + } + pjNew->alternativeCoordinateOperations.emplace_back( + minxSrc, minySrc, maxxSrc, maxySrc, minxDst, minyDst, + maxxDst, maxyDst, + pj_obj_create(ctx, co->normalizeForVisualization()), + co->nameStr()); + } + } + return pjNew; + } catch (const std::exception &e) { + proj_log_debug(ctx, __FUNCTION__, e.what()); + return nullptr; + } + } + auto co = dynamic_cast(obj->iso_obj.get()); if (!co) { proj_log_error(ctx, __FUNCTION__, "Object is not a CoordinateOperation " -- cgit v1.2.3 From 3c99b45f2c34d1bbdd752a51c1704e594f341c31 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 8 May 2019 17:36:39 +0200 Subject: proj_normalize_for_visualization(): fix crash when ctx == nullptr --- src/iso19111/c_api.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 85421fa0..ceb27111 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -6796,9 +6797,12 @@ int proj_cs_get_axis_info(PJ_CONTEXT *ctx, const PJ *cs, int index, */ PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) { + SANITIZE_CTX(ctx); if (!obj->alternativeCoordinateOperations.empty()) { try { - auto pjNew = pj_new(); + auto pjNew = std::unique_ptr(pj_new()); + if (!pjNew) + return nullptr; pjNew->ctx = ctx; for (const auto &alt : obj->alternativeCoordinateOperations) { auto co = dynamic_cast( @@ -6838,7 +6842,7 @@ PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ *obj) { co->nameStr()); } } - return pjNew; + return pjNew.release(); } catch (const std::exception &e) { proj_log_debug(ctx, __FUNCTION__, e.what()); return nullptr; -- cgit v1.2.3 From cd2f5b38046b7775feae08dfc8d8b1e59c1689f2 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 9 May 2019 09:45:46 +0200 Subject: pj_release: Use correct release date for 6.1.0 --- src/release.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/release.cpp b/src/release.cpp index 13ed45f0..822ea4a9 100644 --- a/src/release.cpp +++ b/src/release.cpp @@ -11,7 +11,7 @@ char const pj_release[] = STR(PROJ_VERSION_MAJOR)"." STR(PROJ_VERSION_MINOR)"." STR(PROJ_VERSION_PATCH)", " - "September 1st, 2019"; + "May 15th, 2019"; const char *pj_get_release() { return pj_release; -- cgit v1.2.3 From 004e26293e258a9144e6e1d33049eb1753b82b89 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 12 May 2019 09:03:48 +0200 Subject: Fix identification of GeodeticCRS expressed by PROJ string for EPSG authority --- src/iso19111/io.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index c84ea2f3..7329758a 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6899,6 +6899,7 @@ PROJStringParser::Private::buildGeographicCRS(int iStep, int iUnitConvert, getNumericValue(getParamValue(step, "lon_0")) != 0.0)) { props.set("EXTENSION_PROJ4", projString_); } + props.set("IMPLICIT_CS", true); return GeographicCRS::create(props, datum, cs); } @@ -7389,6 +7390,8 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS( props.set("EXTENSION_PROJ4", projString_); } + props.set("IMPLICIT_CS", true); + CRSNNPtr crs = ProjectedCRS::create(props, geogCRS, NN_NO_CHECK(conv), cs); if (!hasParamValue(step, "geoidgrids") && -- cgit v1.2.3 From 32703ddba9081682b4c39ae7bcedeabeb8c6143d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 12 May 2019 09:07:27 +0200 Subject: Fix doc of proj_identify() --- src/iso19111/c_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index ceb27111..5d2216e8 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1777,7 +1777,7 @@ PJ *proj_get_target_crs(PJ_CONTEXT *ctx, const PJ *obj) { /** \brief Identify the CRS with reference CRSs. * * The candidate CRSs are either hard-coded, or looked in the database when - * authorityFactory is not null. + * it is available. * * The method returns a list of matching reference CRS, and the percentage * (0-100) of confidence in the match. The list is sorted by decreasing -- cgit v1.2.3 From 97d6060e596d1b044f84e7d140b26200ef56f65e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 13 May 2019 09:33:38 -0500 Subject: identify(): take into account the authority passed in (fixes #1465) When identifying an object that has already a code with authority A but the authority of interest passed was B, then it was not checking that A != B, and did not try to search in the objects of B. --- src/iso19111/crs.cpp | 134 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 1ef7dcda..476bc72b 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1387,6 +1387,36 @@ GeodeticCRSNNPtr GeodeticCRS::createEPSG_4978() { // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress + +static bool hasCodeCompatibleOfAuthorityFactory( + const common::IdentifiedObject *obj, + const io::AuthorityFactoryPtr &authorityFactory) { + const auto &ids = obj->identifiers(); + if (!ids.empty() && authorityFactory->getAuthority().empty()) { + return true; + } + for (const auto &id : ids) { + if (*(id->codeSpace()) == authorityFactory->getAuthority()) { + return true; + } + } + return false; +} + +static bool hasCodeCompatibleOfAuthorityFactory( + const metadata::IdentifierNNPtr &id, + const io::AuthorityFactoryPtr &authorityFactory) { + if (authorityFactory->getAuthority().empty()) { + return true; + } + return *(id->codeSpace()) == authorityFactory->getAuthority(); +} + +//! @endcond + +// --------------------------------------------------------------------------- + /** \brief Identify the CRS with reference CRSs. * * The candidate CRSs are either hard-coded, or looked in the database when @@ -1530,19 +1560,22 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { searchByEllipsoid(); } } - } else if (!identifiers().empty()) { + } else if (hasCodeCompatibleOfAuthorityFactory(this, + authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createGeodeticCRS(id->code()); - bool match = _isEquivalentTo(crs.get(), crsCriterion); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createGeodeticCRS(id->code()); + bool match = _isEquivalentTo(crs.get(), crsCriterion); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else { @@ -2299,20 +2332,23 @@ VerticalCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { const bool unsignificantName = thisName.empty() || ci_equal(thisName, "unknown") || ci_equal(thisName, "unnamed"); - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createVerticalCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createVerticalCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion::EQUIVALENT); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { @@ -3100,21 +3136,24 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { ci_equal(thisName, "unnamed"); bool foundEquivalentName = false; - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createProjectedCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion:: - EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createProjectedCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion:: + EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { @@ -3189,8 +3228,8 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { // Sort results res.sort(lambdaSort); - if (identifiers().empty() && !foundEquivalentName && - (res.empty() || res.front().second < 50)) { + if (!hasCodeCompatibleOfAuthorityFactory(this, authorityFactory) && + !foundEquivalentName && (res.empty() || res.front().second < 50)) { std::set> alreadyKnown; for (const auto &pair : res) { const auto &ids = pair.first->identifiers(); @@ -3448,20 +3487,23 @@ CompoundCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { ci_equal(thisName, "unnamed"); bool foundEquivalentName = false; - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createCompoundCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createCompoundCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion::EQUIVALENT); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { -- cgit v1.2.3