/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #include "OdDbGeoCoordinateSystemImpl.h" #include "Ge/GeBoundBlock2d.h" #include "SpatialReference/OdCsdFormatter.h" #include "SpatialReference/OdFormatConverter.h" #include "SpatialReference/OdHelper.h" #include "SpatialReference/OdCoordinateReferenceSystemOperation.h" ODRX_CONS_DEFINE_MEMBERS(OdDbGeoCoordinateSystemCategoryImpl, OdDbGeoCoordinateSystemCategory, RXIMPL_CONSTR); ODRX_CONS_DEFINE_MEMBERS(OdDbGeoCoordinateSystemImpl, OdDbGeoCoordinateSystem, RXIMPL_CONSTR); ODRX_CONS_DEFINE_MEMBERS(OdDbGeoVerticalCoordinateSystemImpl, OdDbGeoVerticalCoordinateSystem, RXIMPL_CONSTR); ODRX_CONS_DEFINE_MEMBERS(OdDbGeoCompoundCoordinateSystemImpl, OdDbGeoCompoundCoordinateSystem, RXIMPL_CONSTR); ODRX_CONS_DEFINE_MEMBERS(OdDbGeoCoordinateSystemTransformerImpl, OdDbGeoCoordinateSystemTransformer, RXIMPL_CONSTR); OdDb::UnitsValue geoCsUnits2UnitsValue(OdDbGeoCoordinateSystem::Unit eUnit) { switch (eUnit) { case OdDbGeoCoordinateSystem::kUnitMeter: return OdDb::kUnitsMeters; case OdDbGeoCoordinateSystem::kUnitFoot: return OdDb::kUnitsFeet; case OdDbGeoCoordinateSystem::kUnitMile: return OdDb::kUnitsMiles; case OdDbGeoCoordinateSystem::kUnitCentimeter: return OdDb::kUnitsCentimeters; case OdDbGeoCoordinateSystem::kUnitDekameter: return OdDb::kUnitsDekameters; case OdDbGeoCoordinateSystem::kUnitDecimeter: return OdDb::kUnitsDecimeters; case OdDbGeoCoordinateSystem::kUnitHectometer: return OdDb::kUnitsHectometers; case OdDbGeoCoordinateSystem::kUnitInch: return OdDb::kUnitsInches; case OdDbGeoCoordinateSystem::kUnitKilometer: return OdDb::kUnitsKilometers; case OdDbGeoCoordinateSystem::kUnitMil: return OdDb::kUnitsMils; case OdDbGeoCoordinateSystem::kUnitMillimeter: return OdDb::kUnitsMillimeters; case OdDbGeoCoordinateSystem::kUnitYard: return OdDb::kUnitsYards; } return OdDb::kUnitsUndefined; } //OdDbGeoCoordinateSystemCategoryImpl OdResult OdDbGeoCoordinateSystemCategoryImpl::getId(OdString& sCategoryId) const { if (m_pCategory.isNull()) { return eNullPtr; } return m_pCategory->getCode(sCategoryId); } OdResult OdDbGeoCoordinateSystemCategoryImpl::getNumOfCoordinateSystem(int& nNum) const { if (m_pCategory.isNull()) { return eNullPtr; } OdUInt32 uCount = 0; OdResult status = m_pCategory->getCount(uCount); nNum = uCount; return status; } OdResult OdDbGeoCoordinateSystemCategoryImpl::getCoordinateSystemAt(int nIndex, OdDbGeoCoordinateSystemPtr& pCoordSys) const { if (m_pCategory.isNull()) { return eNullPtr; } OdString sName; OdResult status = m_pCategory->getAt(nIndex, sName); if (eOk != status) { return status; } return OdDbGeoCoordinateSystem::create(sName, pCoordSys); } OdResult OdDbGeoCoordinateSystemCategoryImpl::getCoordinateSystemIds(OdStringArray& arrIds) const { arrIds.clear(); if (m_pCategory.isNull()) { return eNullPtr; } OdUInt32 uCount = 0; OdResult status = m_pCategory->getCount(uCount); if (eOk != status) { return status; } arrIds.resize(uCount); for (OdUInt32 i = 0; i < uCount; ++i) { m_pCategory->getAt(i, arrIds[i]); } return eOk; } OdResult OdDbGeoCoordinateSystemCategoryImpl::getNumOfVerticalCoordinateSystem(int& nNum) const { if (m_pCategory.isNull()) { return eNullPtr; } OdUInt32 uCount = 0; OdResult status = m_pCategory->getVerticalCount(uCount); nNum = uCount; return status; } OdResult OdDbGeoCoordinateSystemCategoryImpl::getVerticalCoordinateSystemAt(int nIndex, OdDbGeoVerticalCoordinateSystemPtr& pCoordSys) const { if (m_pCategory.isNull()) { return eNullPtr; } OdString sName; OdResult status = m_pCategory->getVerticalAt(nIndex, sName); if (eOk != status) { return status; } return OdDbGeoVerticalCoordinateSystem::create(sName, pCoordSys); } OdResult OdDbGeoCoordinateSystemCategoryImpl::getVerticalCoordinateSystemIds(OdStringArray& arrIds) const { arrIds.clear(); if (m_pCategory.isNull()) { return eNullPtr; } OdUInt32 uCount = 0; OdResult status = m_pCategory->getVerticalCount(uCount); if (eOk != status) { return status; } arrIds.resize(uCount); for (OdUInt32 i = 0; i < uCount; ++i) { m_pCategory->getVerticalAt(i, arrIds[i]); } return eOk; } OdResult OdDbGeoCoordinateSystemCategoryImpl::createAll(OdArray& arrCategories) { arrCategories.clear(); OdCategoryDefinitionArray arrCD; OdResult status = OdCategoryDefinition::loadAll(arrCD); if (eOk != status) { return eNotApplicable; } arrCategories.reserve(arrCD.size()); for (OdUInt32 i = 0; i < arrCD.size(); ++i) { OdDbGeoCoordinateSystemCategoryImplPtr pCategory = createObject(); pCategory->m_pCategory = arrCD[i]; arrCategories.append(pCategory); } return eOk; } //OdDbGeoCoordinateSystemImpl OdResult OdDbGeoCoordinateSystemImpl::getId(OdString& sCoordSysId) const { sCoordSysId.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } return m_pCRSD->getCode(sCoordSysId); } OdResult OdDbGeoCoordinateSystemImpl::getEpsgCode(int& nEpsgCode) const { nEpsgCode = 0; if (m_pCRSD.isNull()) { return eNullPtr; } OdInt32 nEpsg = 0; OdResult status = m_pCRSD->getEpsgCode(nEpsg); if (eOk != status) { return status; } nEpsgCode = nEpsg; return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getType(OdDbGeoCoordinateSystem::Type& eType) const { eType = OdDbGeoCoordinateSystem::kTypeUnknown; if (m_pCRSD.isNull()) { return eNullPtr; } CoordinateReferenceSystemType eCoordinateReferenceSystemType = OdSpatialReference::kTypeUnknown; OdResult status = m_pCRSD->getType(eCoordinateReferenceSystemType); if (eOk != status) { return status; } eType = OdDbGeoCoordinateSystem::Type(eCoordinateReferenceSystemType); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getDescription(OdString& sDescription) const { sDescription.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } return m_pCRSD->getDescription(sDescription); } OdResult OdDbGeoCoordinateSystemImpl::getSource(OdString& sSource) const { sSource.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } return m_pCRSD->getSource(sSource); } OdResult OdDbGeoCoordinateSystemImpl::getUnit(OdDb::UnitsValue& eUnitsValue) const { eUnitsValue = OdDb::kUnitsUndefined; OdDbGeoCoordinateSystem::Unit eUnit = OdDbGeoCoordinateSystem::kUnitUnknown; OdResult status = getUnit(eUnit); if (eOk != status) { return status; } eUnitsValue = geoCsUnits2UnitsValue(eUnit); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getUnit(OdDbGeoCoordinateSystem::Unit& eUnit) const { eUnit = OdDbGeoCoordinateSystem::kUnitUnknown; if (m_pCRSD.isNull()) { return eNullPtr; } OdSpatialReference::UnitCode eUnitCode = OdSpatialReference::kUnitUnknown; OdResult status = m_pCRSD->getUnitCode(eUnitCode); if (eOk != status) { return status; } eUnit = OdDbGeoCoordinateSystem::Unit(eUnitCode); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getUnit(OdString& sUnit) const { sUnit.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } OdSpatialReference::UnitCode eUnitCode = OdSpatialReference::kUnitUnknown; OdResult status = m_pCRSD->getUnitCode(eUnitCode); if (eOk != status) { return status; } return Helper::getUnitCodeName(eUnitCode, sUnit); } OdResult OdDbGeoCoordinateSystemImpl::getUnitScale(double& dUnitScale) const { dUnitScale = 1.; if (m_pCRSD.isNull()) { return eNullPtr; } OdCoordinateReferenceSystemOperationPtr pOperation; if (eOk != OdCoordinateReferenceSystemOperation::load(m_pCRSD, pOperation)) { return eNotApplicable; } return pOperation->getUnitScale(dUnitScale); } OdResult OdDbGeoCoordinateSystemImpl::getProjectionCode(OdDbGeoCoordinateSystem::ProjectionCode& ePrjCode) const { ePrjCode = OdDbGeoCoordinateSystem::kProjectionCodeUnknown; if (m_pCRSD.isNull()) { return eNullPtr; } OdSpatialReference::ProjectionCode eProjectionCode = OdSpatialReference::kProjectionCodeUnknown; OdResult status = m_pCRSD->getProjectionCode(eProjectionCode); if (eOk != status) { return status; } ePrjCode = OdDbGeoCoordinateSystem::ProjectionCode(eProjectionCode); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getProjectionParameters(OdArray& arrPrjParams, bool bIncludeSpecialParams) const { arrPrjParams.clear(); if (m_pCRSD.isNull()) { return eNullPtr; } OdSpatialReference::ProjectionCode eProjectionCode = OdSpatialReference::kProjectionCodeUnknown; OdResult status = m_pCRSD->getProjectionCode(eProjectionCode); if (eOk != status) { return status; } OdUInt32 uCount = 0; status = m_pCRSD->getProjectionParameterCount(uCount); if (eOk != status) { return status; } OdDbGeoProjectionParameter projectionParameter; for (OdUInt32 i = 0; i < uCount; ++i) { m_pCRSD->getProjectionParameter(i, projectionParameter.value); projectionParameter.name = Helper::getParameterDescription(Helper::getParameterCode(eProjectionCode, i)); arrPrjParams.append(projectionParameter); } if (bIncludeSpecialParams) { if (eOk == m_pCRSD->getOriginLongitude(projectionParameter.value)) { projectionParameter.name = "Origin Longitude"; arrPrjParams.append(projectionParameter); } if (eOk == m_pCRSD->getOriginLatitude(projectionParameter.value)) { projectionParameter.name = "Origin Latitude"; arrPrjParams.append(projectionParameter); } if (eOk == m_pCRSD->getScaleReduction(projectionParameter.value)) { projectionParameter.name = "Scale Reduction"; arrPrjParams.append(projectionParameter); } if (eOk == m_pCRSD->getOffsetX(projectionParameter.value)) { projectionParameter.name = "False Easting"; arrPrjParams.append(projectionParameter); } if (eOk == m_pCRSD->getOffsetY(projectionParameter.value)) { projectionParameter.name = "False Northing"; arrPrjParams.append(projectionParameter); } } return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getDatum(OdDbGeoDatum& datum) const { datum.id.empty(); datum.desc.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } OdDatumDefinitionPtr pDatum; if (eOk != m_pCRSD->getDatumDefinition(pDatum)) { return eNotApplicable; } pDatum->getCode(datum.id); pDatum->getDescription(datum.desc); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getDatumId(OdString& sDatumId) const { sDatumId.empty(); if (m_pCRSD.isNull()) { return eNullPtr; } return m_pCRSD->getDatum(sDatumId); } OdResult OdDbGeoCoordinateSystemImpl::getEllipsoid(OdDbGeoEllipsoid& ellipsoid) const { ellipsoid.id.empty(); ellipsoid.desc.empty(); ellipsoid.polarRadius = -1.; ellipsoid.eccentricity = -1.; if (m_pCRSD.isNull()) { return eNullPtr; } OdEllipsoidDefinitionPtr pEllipsoid; if (eOk != m_pCRSD->getEllipsoidDefinition(pEllipsoid)) { return eNotApplicable; } pEllipsoid->getCode(ellipsoid.id); pEllipsoid->getDescription(ellipsoid.desc); pEllipsoid->getPolarRadius(ellipsoid.polarRadius); pEllipsoid->getEccentricity(ellipsoid.eccentricity); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getOffset(OdGeVector2d& vOffset) const { vOffset = OdGeVector2d::kIdentity; if (m_pCRSD.isNull()) { return eNullPtr; } if (eOk != m_pCRSD->getOffsetX(vOffset.x) || eOk != m_pCRSD->getOffsetY(vOffset.y)) { return eNotApplicable; } return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getCartesianExtents(OdGeExtents2d& exts) const { exts = OdGeExtents2d(); if (m_pCRSD.isNull()) { return eNullPtr; } OdGePoint2d ptMin, ptMax; OdCoordinateReferenceSystemOperationPtr pCRSOperation; if (eOk != OdCoordinateReferenceSystemOperation::load(m_pCRSD, pCRSOperation) || eOk != pCRSOperation->getMinX(ptMin.x) || eOk != pCRSOperation->getMinY(ptMin.y) || eOk != pCRSOperation->getMaxX(ptMax.x) || eOk != pCRSOperation->getMaxY(ptMax.y)) { return eNotApplicable; } exts.set(ptMin, ptMax); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getGeodeticExtents(OdGeExtents2d& exts) const { exts = OdGeExtents2d(); if (m_pCRSD.isNull()) { return eNullPtr; } OdGePoint2d ptMin, ptMax; OdCoordinateReferenceSystemOperationPtr pCRSOperation; if (eOk != OdCoordinateReferenceSystemOperation::load(m_pCRSD, pCRSOperation) || eOk != pCRSOperation->getLonMin(ptMin.x) || eOk != pCRSOperation->getLatMin(ptMin.y) || eOk != pCRSOperation->getLonMax(ptMax.x) || eOk != pCRSOperation->getLatMax(ptMax.y)) { return eNotApplicable; } exts.set(ptMin, ptMax); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::getXmlRepresentation(OdString& sXml) const { return OdCsdFormatter::createXml(m_pCRSD, nullptr, sXml); } OdResult OdDbGeoCoordinateSystemImpl::getWktRepresentation(OdString& sWkt) const { return FormatConverter::definitionToWkt(m_pCRSD, kWktFlvrOgc, sWkt); } OdResult OdDbGeoCoordinateSystemImpl::getStatus(OdDbGeoCoordinateSystem::StatusType& eStatusType) const { if (m_pCRSD.isNull()) { return eNullPtr; } bool bIsProtected = false; OdString sGroup; if (eOk != m_pCRSD->isProtected(bIsProtected) || eOk != m_pCRSD->getGroup(sGroup)) { return eNotApplicable; } if (!bIsProtected) { eStatusType = kStatusTypeUserDefined; } else if (0 == sGroup.iCompare(L"legacy")) { eStatusType = kStatusTypeOutOfDate; } else { eStatusType = kStatusTypeUpToDate; } return eOk; } //OdDbGeoCoordinateSystemImpl static methods OdResult OdDbGeoCoordinateSystemImpl::create(const OdString& sCoordSysIdOrFullDef, OdDbGeoCoordinateSystemPtr& pCS) { OdCoordinateReferenceSystemDefinitionPtr pCRSD; if (eOk == OdCsdFormatter::parseXml(sCoordSysIdOrFullDef, pCRSD)) { OdString sCode; if (eOk != pCRSD->getCode(sCode) || eOk != OdCoordinateReferenceSystemDefinition::load(sCode, pCRSD)) { return eNotApplicable; } } else if (eOk != FormatConverter::getCoordinateReferenceSystemDefinition(sCoordSysIdOrFullDef, pCRSD)) { return eNotApplicable; } OdDbGeoCoordinateSystemImplPtr pCSImpl = createObject(); pCSImpl->m_pCRSD = pCRSD; pCS = pCSImpl; return eOk; } class OdDbGeoCoordinateSystemGeoPointSort { OdGePoint2d m_ptGeo; public: OdDbGeoCoordinateSystemGeoPointSort(const OdGePoint2d & ptGeo) : m_ptGeo(ptGeo) { } bool operator()(OdDbGeoCoordinateSystemPtr pFirst, OdDbGeoCoordinateSystemPtr pSecond) { OdGeExtents2d extFirst, extSecond; pFirst->getGeodeticExtents(extFirst); pSecond->getGeodeticExtents(extSecond); double dFirst = extFirst.center().distanceTo(m_ptGeo); double dSecond = extSecond.center().distanceTo(m_ptGeo); if (dFirst == dSecond) { OdString sIdFirst, sIdSecond; pFirst->getId(sIdFirst); pSecond->getId(sIdSecond); return sIdFirst.compare(sIdSecond) < 0; } return dFirst < dSecond; } }; OdResult OdDbGeoCoordinateSystemImpl::createAll(const OdGePoint3d& ptGeo, OdArray& arrCoordSys) { arrCoordSys.clear(); OdGePoint2d ptGeo2d = ptGeo.convert2d(); OdCoordinateReferenceSystemDefinitionArray arrCRSD; OdResult status = OdCoordinateReferenceSystemDefinition::loadAll(arrCRSD); if (eOk != status) { return status; } arrCoordSys.reserve(arrCRSD.size()); for (OdUInt32 i = 0; i < arrCRSD.size(); ++i) { OdCoordinateReferenceSystemDefinitionPtr pCRSD = arrCRSD[i]; CoordinateReferenceSystemType eType = OdSpatialReference::kTypeUnknown; if (eOk == pCRSD->getType(eType) && eType == OdSpatialReference::kTypeProjected) { OdGePoint2d ptMin, ptMax; OdCoordinateReferenceSystemOperationPtr pCRSOperation; if (eOk == OdCoordinateReferenceSystemOperation::load(pCRSD, pCRSOperation) && eOk == pCRSOperation->getLonMin(ptMin.x) && eOk == pCRSOperation->getLatMin(ptMin.y) && eOk == pCRSOperation->getLonMax(ptMax.x) && eOk == pCRSOperation->getLatMax(ptMax.y)) { if (OdGeBoundBlock2d(ptMin, ptMax).contains(ptGeo2d, 0.)) { OdDbGeoCoordinateSystemImplPtr pCS = createObject(); pCS->m_pCRSD = pCRSD; arrCoordSys.push_back(pCS); } } } } std::sort(arrCoordSys.begin(), arrCoordSys.end(), OdDbGeoCoordinateSystemGeoPointSort(ptGeo2d)); return eOk; } OdResult OdDbGeoCoordinateSystemImpl::createAll(OdArray& arrCoordSys, const OdDbGeoCoordinateSystemCategory* pCategory) { arrCoordSys.clear(); if (pCategory == NULL) { OdCoordinateReferenceSystemDefinitionArray arrCRSD; OdResult status = OdCoordinateReferenceSystemDefinition::loadAll(arrCRSD); if (eOk != status) { return status; } arrCoordSys.reserve(arrCRSD.size()); for (OdUInt32 i = 0; i < arrCRSD.size(); ++i) { OdDbGeoCoordinateSystemImplPtr pCS = createObject(); pCS->m_pCRSD = arrCRSD[i]; arrCoordSys.push_back(pCS); } } else { int nCount = 0; pCategory->getNumOfCoordinateSystem(nCount); arrCoordSys.reserve(nCount); for(int i = 0; i < nCount; ++i) { OdDbGeoCoordinateSystemPtr pCS; pCategory->getCoordinateSystemAt(i, pCS); arrCoordSys.append(pCS); } } return eOk; } void OdDbGeoCoordinateSystemImpl::init(OdCoordinateReferenceSystemDefinition* pCRSD) { m_pCRSD = pCRSD; } //OdDbGeoVerticalCoordinateSystemImpl OdResult OdDbGeoVerticalCoordinateSystemImpl::getId(OdString& sCoordSysId) const { sCoordSysId.empty(); if (m_pVCRSD.isNull()) { return eNullPtr; } return m_pVCRSD->getCode(sCoordSysId); } OdResult OdDbGeoVerticalCoordinateSystemImpl::getEpsgCode(int& nEpsgCode) const { nEpsgCode = 0; if (m_pVCRSD.isNull()) { return eNullPtr; } OdInt32 nEpsg = 0; OdResult status = m_pVCRSD->getEpsgCode(nEpsg); if (eOk != status) { return status; } nEpsgCode = nEpsg; return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getType(OdDbGeoVerticalCoordinateSystem::Type& eType) const { eType = kTypeUnknown; if (m_pVCRSD.isNull()) { return eNullPtr; } OdVerticalCoordinateReferenceSystemDefinition::Type eVerticalType = OdVerticalCoordinateReferenceSystemDefinition::kTypeUnknown; OdResult status = m_pVCRSD->getType(eVerticalType); if (eOk != status) { return status; } eType = OdDbGeoVerticalCoordinateSystem::Type(eVerticalType); return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getDescription(OdString& sDescription) const { sDescription.empty(); if (m_pVCRSD.isNull()) { return eNullPtr; } return m_pVCRSD->getDescription(sDescription); } OdResult OdDbGeoVerticalCoordinateSystemImpl::getAxisDirection(OdDbGeoVerticalCoordinateSystem::AxisDirection& eAxisDirection) const { eAxisDirection = kAxisDirectionUnknown; if (m_pVCRSD.isNull()) { return eNullPtr; } OdVerticalCoordinateReferenceSystemDefinition::AxisDirection eVerticalAxisDirection = OdVerticalCoordinateReferenceSystemDefinition::kAxisDirectionUnknown; OdResult status = m_pVCRSD->getAxisDirection(eVerticalAxisDirection); if (eOk != status) { return status; } eAxisDirection = OdDbGeoVerticalCoordinateSystem::AxisDirection(eVerticalAxisDirection); return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getUnit(OdDb::UnitsValue& eUnitsValue) const { eUnitsValue = OdDb::kUnitsUndefined; OdDbGeoCoordinateSystem::Unit eUnit = OdDbGeoCoordinateSystem::kUnitUnknown; OdResult status = getUnit(eUnit); if (eOk != status) { return status; } eUnitsValue = geoCsUnits2UnitsValue(eUnit); return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getUnit(OdDbGeoCoordinateSystem::Unit& eUnit) const { eUnit = OdDbGeoCoordinateSystem::kUnitUnknown; if (m_pVCRSD.isNull()) { return eNullPtr; } OdSpatialReference::UnitCode eUnitCode = OdSpatialReference::kUnitUnknown; OdResult status = m_pVCRSD->getUnitCode(eUnitCode); if (eOk != status) { return status; } eUnit = OdDbGeoCoordinateSystem::Unit(eUnitCode); return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getUnitScale(double& dUnitScale) const { dUnitScale = 1.; if (m_pVCRSD.isNull()) { return eNullPtr; } return m_pVCRSD->getUnitScale(dUnitScale); } OdResult OdDbGeoVerticalCoordinateSystemImpl::getDatum(OdDbGeoDatum& datum) const { datum.id.empty(); datum.desc.empty(); OdDbGeoVerticalCoordinateSystem::Type eType = kTypeUnknown; OdResult status = getType(eType); if (eOk != status) { return status; } if (kTypeEllipsoidal == eType) { OdDatumDefinitionPtr pDatum; if (eOk != m_pVCRSD->getDatumDefinition(pDatum)) { return eNotApplicable; } pDatum->getCode(datum.id); pDatum->getDescription(datum.desc); return eOk; } if (kTypeGeoidModelDerived == eType) { OdVerticalDatumDefinitionPtr pVerticalDatum; if (eOk != m_pVCRSD->getVerticalDatumDefinition(pVerticalDatum)) { return eNotApplicable; } pVerticalDatum->getCode(datum.id); pVerticalDatum->getDescription(datum.desc); return eOk; } return eNotApplicable; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getDatumId(OdString& sDatumId) const { sDatumId.empty(); if (m_pVCRSD.isNull()) { return eNullPtr; } return m_pVCRSD->getDatum(sDatumId); } OdResult OdDbGeoVerticalCoordinateSystemImpl::getGeodeticExtents(OdGeExtents2d& exts) const { exts = OdGeExtents2d(); if (m_pVCRSD.isNull()) { return eNullPtr; } OdGePoint2d ptMin, ptMax; if (eOk != m_pVCRSD->getLonMin(ptMin.x) || eOk != m_pVCRSD->getLatMin(ptMin.y) || eOk != m_pVCRSD->getLonMax(ptMax.x) || eOk != m_pVCRSD->getLatMax(ptMax.y)) { return eNotApplicable; } exts.set(ptMin, ptMax); if (!exts.isValidExtents()) { exts = OdGeExtents2d(); } return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::getXmlRepresentation(OdString& sXml) const { return OdCsdFormatter::createXml(nullptr, m_pVCRSD, sXml); } OdResult OdDbGeoVerticalCoordinateSystemImpl::getStatus(OdDbGeoCoordinateSystem::StatusType& eStatusType) const { if (m_pVCRSD.isNull()) { return eNullPtr; } bool bIsProtected = false; OdString sGroup; if (eOk != m_pVCRSD->isProtected(bIsProtected) || eOk != m_pVCRSD->getGroup(sGroup)) { return eNotApplicable; } if (!bIsProtected) { eStatusType = OdDbGeoCoordinateSystem::kStatusTypeUserDefined; } else if (0 == sGroup.iCompare(L"legacy")) { eStatusType = OdDbGeoCoordinateSystem::kStatusTypeOutOfDate; } else { eStatusType = OdDbGeoCoordinateSystem::kStatusTypeUpToDate; } return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::create(const OdString& sCoordSysIdOrFullDef, OdDbGeoVerticalCoordinateSystemPtr& pCS) { OdVerticalCoordinateReferenceSystemDefinitionPtr pVCRSD; if (eOk == OdCsdFormatter::parseXml(sCoordSysIdOrFullDef, pVCRSD)) { OdString sCode; if (eOk != pVCRSD->getCode(sCode) || eOk != OdVerticalCoordinateReferenceSystemDefinition::load(sCode, pVCRSD)) { return eNotApplicable; } } else if (eOk != FormatConverter::getVerticalCoordinateReferenceSystemDefinition(sCoordSysIdOrFullDef, pVCRSD)) { return eNotApplicable; } OdDbGeoVerticalCoordinateSystemImplPtr pCSImpl = createObject(); pCSImpl->m_pVCRSD = pVCRSD; pCS = pCSImpl; return eOk; } OdResult OdDbGeoVerticalCoordinateSystemImpl::createAll(OdArray& arrCoordSys, const OdDbGeoCoordinateSystemCategory* pCategory) { arrCoordSys.clear(); if (pCategory == NULL) { OdVerticalCoordinateReferenceSystemDefinitionArray arrVCRSD; OdResult status = OdVerticalCoordinateReferenceSystemDefinition::loadAll(arrVCRSD); if (eOk != status) { return status; } arrCoordSys.reserve(arrVCRSD.size()); for (OdUInt32 i = 0; i < arrVCRSD.size(); ++i) { OdDbGeoVerticalCoordinateSystemImplPtr pCS = createObject(); pCS->m_pVCRSD = arrVCRSD[i]; arrCoordSys.push_back(pCS); } } else { int nCount = 0; pCategory->getNumOfVerticalCoordinateSystem(nCount); arrCoordSys.reserve(nCount); for (int i = 0; i < nCount; ++i) { OdDbGeoVerticalCoordinateSystemPtr pCS; pCategory->getVerticalCoordinateSystemAt(i, pCS); arrCoordSys.append(pCS); } } return eOk; } void OdDbGeoVerticalCoordinateSystemImpl::init(OdVerticalCoordinateReferenceSystemDefinition* pVCRSD) { m_pVCRSD = pVCRSD; } //OdDbGeoCompoundCoordinateSystemImpl OdResult OdDbGeoCompoundCoordinateSystemImpl::getGeodeticCoordinateSystem(OdDbGeoCoordinateSystemPtr& pCS) const { if (m_pCRSD.isNull()) { return eNotApplicable; } OdCoordinateReferenceSystemDefinitionPtr pCRSD = OdCoordinateReferenceSystemDefinition::cast(m_pCRSD->clone()); if (pCRSD.isNull()) { return eNotApplicable; } OdDbGeoCoordinateSystemImplPtr pCSImpl = OdDbGeoCoordinateSystemImpl::createObject(); pCSImpl->init(pCRSD); pCS = pCSImpl; return eOk; } OdResult OdDbGeoCompoundCoordinateSystemImpl::getVerticalCoordinateSystem(OdDbGeoVerticalCoordinateSystemPtr& pCS) const { if (m_pVCRSD.isNull()) { return eNotApplicable; } OdVerticalCoordinateReferenceSystemDefinitionPtr pVCRSD = OdVerticalCoordinateReferenceSystemDefinition::cast(m_pVCRSD->clone()); if (pVCRSD.isNull()) { return eNotApplicable; } OdDbGeoVerticalCoordinateSystemImplPtr pCSImpl = OdDbGeoVerticalCoordinateSystemImpl::createObject(); pCSImpl->init(pVCRSD); pCS = pCSImpl; return eOk; } OdResult OdDbGeoCompoundCoordinateSystemImpl::getXmlRepresentation(OdString& sXml) const { return OdCsdFormatter::createXml(m_pCRSD, m_pVCRSD, sXml); } OdResult OdDbGeoCompoundCoordinateSystemImpl::getWktRepresentation(OdString& /*sWkt*/) const { //same as arx return eNotImplementedYet; } OdResult OdDbGeoCompoundCoordinateSystemImpl::create(const OdString& sCoordSysIdOrFullDef, OdDbGeoCompoundCoordinateSystemPtr& pCS) { OdCoordinateReferenceSystemDefinitionPtr pCRSD; OdVerticalCoordinateReferenceSystemDefinitionPtr pVCRSD; if (eOk == OdCsdFormatter::parseXml(sCoordSysIdOrFullDef, pCRSD, pVCRSD)) { OdString sCode; if (eOk != pCRSD->getCode(sCode) || eOk != OdCoordinateReferenceSystemDefinition::load(sCode, pCRSD) || pVCRSD && (eOk != pVCRSD->getCode(sCode) || eOk != OdVerticalCoordinateReferenceSystemDefinition::load(sCode, pVCRSD))) { return eNotApplicable; } } else { OdString sCRSD; OdString sVCRSD; int nPos = sCoordSysIdOrFullDef.find(L"+"); if (-1 == nPos) // no vertical CS { sCRSD = sCoordSysIdOrFullDef; } else { sCRSD = sCoordSysIdOrFullDef.left(nPos); sVCRSD = sCoordSysIdOrFullDef.mid(nPos + 1); } if (eOk != FormatConverter::getCoordinateReferenceSystemDefinition(sCRSD, pCRSD) || !sVCRSD.isEmpty() && eOk != FormatConverter::getVerticalCoordinateReferenceSystemDefinition(sVCRSD, pVCRSD)) { return eNotApplicable; } } if (pCRSD.get() && pVCRSD.get()) { OdResult status = OdCompoundCoordinateReferenceSystemDefinition::verify(pCRSD, pVCRSD); if (eOk != status) { return status; } } OdDbGeoCompoundCoordinateSystemImplPtr pCSImpl = createObject(); pCSImpl->m_pCRSD = pCRSD; pCSImpl->m_pVCRSD = pVCRSD; pCS = pCSImpl; return eOk; } OdResult OdDbGeoCompoundCoordinateSystemImpl::verify(const OdString& sCoordSysId, const OdString& sVerticalCoordSysId) { return OdCompoundCoordinateReferenceSystemDefinition::verify(sCoordSysId, sVerticalCoordSysId); } //OdDbGeoCoordinateSystemTransformerImpl OdResult OdDbGeoCoordinateSystemTransformerImpl::getSourceCoordinateSystemId(OdString& sSourceCoordSysId) const { sSourceCoordSysId.empty(); if (m_pTransformation.isNull()) { return eNullPtr; } OdCoordinateReferenceSystemDefinitionPtr pSource; if (eOk != m_pTransformation->getSource(pSource) || eOk != pSource->getCode(sSourceCoordSysId)) { return eNotApplicable; } return eOk; } OdResult OdDbGeoCoordinateSystemTransformerImpl::getTargetCoordinateSystemId(OdString& sTargetCoordSysId) const { sTargetCoordSysId.empty(); if (m_pTransformation.isNull()) { return eNullPtr; } OdCoordinateReferenceSystemDefinitionPtr pTarget; if (eOk != m_pTransformation->getTarget(pTarget) || eOk != pTarget->getCode(sTargetCoordSysId)) { return eNotApplicable; } return eOk; } OdResult OdDbGeoCoordinateSystemTransformerImpl::transformPoint(const OdGePoint3d& ptIn, OdGePoint3d& ptOut) const { if (m_pTransformation.isNull()) { return eNullPtr; } ptOut = ptIn; return m_pTransformation->transform(ptOut.x, ptOut.y, ptOut.z); } OdResult OdDbGeoCoordinateSystemTransformerImpl::transformPoints(const OdGePoint3dArray& arrPtIn, OdGePoint3dArray& arrPtOut) const { if (m_pTransformation.isNull()) { return eNullPtr; } OdResult status = eOk; arrPtOut = arrPtIn; for (OdUInt32 i = 0; i < arrPtIn.size(); ++i) { OdGePoint3d & ptOut = arrPtOut[i]; OdResult statusLocal = m_pTransformation->transform(ptOut.x, ptOut.y, ptOut.z); if (eOk == status && eOk != statusLocal) { status = statusLocal; } } return status; } //OdDbGeoCoordinateSystemTransformerImpl static methods OdResult OdDbGeoCoordinateSystemTransformerImpl::transformPoint(const OdString& sSourceCoordSysId, const OdString& sTargetCoordSysId, const OdGePoint3d& ptIn, OdGePoint3d& ptOut) { OdDbGeoCoordinateSystemTransformerPtr pObj; OdResult status = OdDbGeoCoordinateSystemTransformer::create(sSourceCoordSysId, sTargetCoordSysId, pObj); if (status != eOk) { return status; } return pObj->transformPoint(ptIn, ptOut); } OdResult OdDbGeoCoordinateSystemTransformerImpl::transformPoints(const OdString& sSourceCoordSysId, const OdString& sTargetCoordSysId, const OdGePoint3dArray& arrPtIn, OdGePoint3dArray& arrPtOut) { OdDbGeoCoordinateSystemTransformerPtr pObj; OdResult status = OdDbGeoCoordinateSystemTransformer::create(sSourceCoordSysId, sTargetCoordSysId, pObj); if (status != eOk) { return status; } return pObj->transformPoints(arrPtIn, arrPtOut); } OdResult OdDbGeoCoordinateSystemTransformerImpl::create(const OdString& sSourceCoordSysId, const OdString& sTargetCoordSysId, OdDbGeoCoordinateSystemTransformerPtr& pCoordSysTransformer) { OdCoordinateReferenceSystemDefinitionPtr pCRSDSource; if (eOk != OdCsdFormatter::parseXml(sSourceCoordSysId, pCRSDSource) && eOk != FormatConverter::getCoordinateReferenceSystemDefinition(sSourceCoordSysId, pCRSDSource)) { return eNotApplicable; } OdCoordinateReferenceSystemDefinitionPtr pCRSDTarget; if (eOk != OdCsdFormatter::parseXml(sTargetCoordSysId, pCRSDTarget) && eOk != FormatConverter::getCoordinateReferenceSystemDefinition(sTargetCoordSysId, pCRSDTarget)) { return eNotApplicable; } OdString sResSourceCoordSysId; OdString sResTargetCoordSysId; if (eOk != pCRSDSource->getCode(sResSourceCoordSysId) || eOk != pCRSDTarget->getCode(sResTargetCoordSysId)) { return eNotApplicable; } OdCoordinateReferenceSystemTransformationPtr pTransformation; if (eOk != OdCoordinateReferenceSystemTransformation::load(sResSourceCoordSysId, sResTargetCoordSysId, pTransformation)) { return eNotApplicable; } OdDbGeoCoordinateSystemTransformerImplPtr pCoordSysTransformerImpl = createObject(); pCoordSysTransformerImpl->m_pTransformation = pTransformation; pCoordSysTransformer = pCoordSysTransformerImpl; return eOk; }