/////////////////////////////////////////////////////////////////////////////// // 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 #include "DgnImportGeoData.h" #include #include #include "DgKMLPlacemark.h" namespace TD_DGN_IMPORT { //--------------------------------------------------------------------------------------------------- void setDwgGeoDataValues(OdDbDatabase* pDb, OdDbGeoData* pGeoData, const OdGePoint3d& ptGeoRSS, const OdGePoint3d& ptDesign ) { OdString sCSId; OdDbGeoCoordinateSystemPtr pCS; if (eOk == OdDbGeoCoordinateSystem::create(pGeoData->coordinateSystem(), pCS) && !pCS.isNull()) pCS->getId(sCSId); else return; OdDb::UnitsValue eUnits = pGeoData->horizontalUnits(); double dNorthDir = pGeoData->northDirection() + OdaPI2; pGeoData->setCoordinateType(OdDbGeoData::kCoordTypLocal); pGeoData->setHorizontalUnits(eUnits); pGeoData->setVerticalUnits(eUnits); pGeoData->setDesignPoint(ptDesign); pGeoData->setUpDirection(OdGeVector3d::kZAxis); OdGeVector2d vNorthDirection = OdGeVector2d::kXAxis; vNorthDirection.rotateBy(dNorthDir); pGeoData->setNorthDirectionVector(vNorthDirection); OdGePoint3d ptReference; OdDbGeoCoordinateSystemTransformer::transformPoint(L"LL84", sCSId, OdGePoint3d(ptGeoRSS.x, ptGeoRSS.y, ptGeoRSS.z), ptReference); pGeoData->setReferencePoint(ptReference); pGeoData->setDoSeaLevelCorrection(false); pGeoData->setScaleEstimationMethod(OdDbGeoData::kScaleEstMethodUnity); double dEccentricity = 0.08181919092890674; OdDbGeoEllipsoid elipsoid; OdDbGeoCoordinateSystem::create(sCSId, pCS); if (!pCS.isNull() && eOk == pCS->getEllipsoid(elipsoid) && !elipsoid.id.isEmpty()) { dEccentricity = elipsoid.eccentricity; } double dRadius = 6378137.; double dSinLat = sin(ptReference.y); double dCoordinateProjectionRadius = dRadius * (1 - dEccentricity * dEccentricity) / pow(1 - dEccentricity * dEccentricity * dSinLat * dSinLat, 1.5); pGeoData->setCoordinateProjectionRadius(dCoordinateProjectionRadius); pGeoData->setGeoRSSTag(OdString().format(L"%f %f", ptGeoRSS.y, ptGeoRSS.x)); //database fields update: pDb->setLONGITUDE(ptGeoRSS.x); pDb->setLATITUDE(ptGeoRSS.y); //pDb->setELEVATION(ptGeoRSS.z); pDb->setNORTHDIRECTION(dNorthDir); pGeoData->updateTransformationMatrix(); } //--------------------------------------------------------------------------------------------------- void OdDgnGeoDataImportPE::subImportElement(OdDgElement* e, OdDbBlockTableRecord* owner) { OdDgGeoDataInfo* pDgGeoData = (OdDgGeoDataInfo*)e; OdString strWktDesc; ::odrxDynamicLinker()->loadModule(L"DgGeoDataEx"); ::odrxDynamicLinker()->loadModule(OdGeoDataModuleName); if( pDgGeoData->getWktRepresentation(strWktDesc) == eOk ) { OdDbGeoDataPtr pGeoData = OdDbGeoData::createObject(); pGeoData->setBlockTableRecordId(owner->objectId()); OdDbObjectId objId; if( eOk == pGeoData->postToDb(objId) ) { if (pGeoData->setCoordinateSystem(strWktDesc) == eOk) { bool bInitPlacemark = false; OdGePoint3d ptPlaceMarkXYZ = OdGePoint3d::kOrigin; OdGePoint3d ptPlaceMarkLLA = OdGePoint3d::kOrigin; OdDgGeoDataPEPtr pGeoDataPE = pDgGeoData; if( !pGeoDataPE.isNull() ) { // 1. Try to find first placemark. OdDgElementId idModel = pDgGeoData->ownerId(); OdDgModelPtr pModel; if( !idModel.isNull() ) { OdDgElementPtr pModelElm = idModel.openObject(OdDg::kForRead); if( pModelElm->isKindOf(OdDgModel::desc()) ) { pModel = pModelElm; OdDgElementIteratorPtr pIter = pModel->createGraphicsElementsIterator(); for(; !pIter->done(); pIter->step() ) { OdDgElementPtr pItem = pIter->item().openObject(OdDg::kForRead); if (pItem.isNull() || ((pItem->isA() != OdDgKMLPlacemark2d::desc()) && (pItem->isA() != OdDgKMLPlacemark3d::desc()))) continue; if( pItem->isA() == OdDgKMLPlacemark2d::desc() ) { OdDgKMLPlacemark2dPtr pMarker = pItem; OdGePoint2d ptOrigin = pMarker->getOrigin(); ptPlaceMarkXYZ.set(ptOrigin.x, ptOrigin.y, 0.0); ptPlaceMarkLLA.set(pMarker->getLongitude()*180.0 / OdaPI, pMarker->getLatitude()*180.0 / OdaPI, pMarker->getElevation()); bInitPlacemark = true; break; } else { OdDgKMLPlacemark3dPtr pMarker = pItem; ptPlaceMarkXYZ = pMarker->getOrigin(); ptPlaceMarkLLA.set(pMarker->getLongitude()*180.0 / OdaPI, pMarker->getLatitude()*180.0 / OdaPI, pMarker->getElevation()); bInitPlacemark = true; break; } } } } // 2. Get data from dgn geodata. if( !bInitPlacemark ) { OdDgGeoDataCoordinateConverterPtr pGeoDataConvertor = pGeoDataPE->createGeoDataCoordinateConvertor(pDgGeoData, pModel); if( !pGeoDataConvertor.isNull() ) pGeoDataConvertor->transformXYZPointLL(ptPlaceMarkXYZ, ptPlaceMarkLLA); } // 3. Correct db geo data design point and reference point. OdDbDatabase* pDb = owner->database(); setDwgGeoDataValues(pDb, pGeoData, ptPlaceMarkLLA, ptPlaceMarkXYZ); } } else pGeoData->erase(true); } else pGeoData->erase(true); } } //--------------------------------------------------------------------------------------------------- }