/////////////////////////////////////////////////////////////////////////////// // 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 "OdDbGeoDataChunksPEImpl.h" #include "OdDbGeoMapHelper.h" #include "OdGeoMapTilesCache.h" #include "Ge/GeRay3d.h" ODRX_CONS_DEFINE_MEMBERS(OdDbGeoDataChunksPEImpl, OdDbGeoDataChunksPE, RXIMPL_CONSTR); OdDbGeoDataChunksPEImpl::OdDbGeoDataChunksPEImpl() : m_bActiveStatus(true) { } OdDbGeoDataChunksPEImpl::~OdDbGeoDataChunksPEImpl() { } OdResult OdDbGeoDataChunksPEImpl::drawGeoDataChunks(OdGiViewportDraw* pVd) const { OdGiDrawFlagsHelper autoFlags(pVd->subEntityTraits(), OdGiSubEntityTraits::kExcludeFromViewExt); OdDbDatabasePtr pDb = pVd->context()->database(); // determine OdDbGeoData: OdDbGeoDataPtr pGeoData; OdResult res = OdDbGeoMapHelper::getGeoData(pDb, pGeoData); if (eOk != res) { return res; } // determine OdGeoMapType: OdGeoMapType eGeoMapType = OdDbGeoMapHelper::getGeoMapType(pVd->viewportObjectId()); if (OdGeoMapType::kNoMap == eGeoMapType) { return eOk; } //get tile info: OdUInt32 uTileSize = 0; OdUInt8 uMinLOD = 0; OdUInt8 uMaxLOD = 0; res = g_OdGeoMapTilesCache->getTileInfo(eGeoMapType, uTileSize, uMinLOD, uMaxLOD); if (eOk != res) { return res; } // get viewport DC corners OdGePoint2d lowerLeft, upperRight; pVd->viewport().getViewportDcCorners(lowerLeft, upperRight); //get scale OdGePoint2d ptScale; pVd->viewport().getNumPixelsInUnitSquare(OdGePoint3d::kOrigin, ptScale, false); // get map extents OdGePoint2dArray arrMapExtents; OdGePoint3dArray arrMapExtents3d; OdGePoint3dArray arrViewPt3d; { OdGeMatrix3d mat = pVd->viewport().getEyeToWorldTransform(); arrViewPt3d.resize(4); arrViewPt3d[0].set(lowerLeft.x, lowerLeft.y, 0.); arrViewPt3d[1].set(upperRight.x, lowerLeft.y, 0.); arrViewPt3d[2].set(upperRight.x, upperRight.y, 0.); arrViewPt3d[3].set(lowerLeft.x, upperRight.y, 0.); arrMapExtents3d.resize(4); arrMapExtents.resize(4); OdGePlane plane(pGeoData->designPoint(), pGeoData->upDirection()); OdGeTol tol = 1.e-6; for (OdUInt32 i = 0; i < 4; ++i) { arrViewPt3d[i].transformBy(mat); plane.intersectWith(OdGeRay3d(arrViewPt3d[i], pVd->viewport().viewDir()), arrMapExtents3d[i], tol); arrMapExtents[i] = arrMapExtents3d[i].convert2d(); } } // get level of detail for result map image (for current viewport) OdUInt8 uLOD = uMinLOD; { OdGeExtents2d extents2d; extents2d.addPoints(arrMapExtents); double dWidth = (upperRight.x - lowerLeft.x) * ptScale.x; double dHeight = (upperRight.y - lowerLeft.y) * ptScale.y; double dViewportDiagLengthInPixels = OdGeVector2d(dWidth, dHeight).length(); double dMapDiagLength = extents2d.diagonal().length(); uLOD = OdDbGeoMapHelper::getOptimalLOD(pGeoData, uMinLOD, uMaxLOD, uTileSize, dViewportDiagLengthInPixels, dMapDiagLength); } // create global map extents OdGePoint2dArray arrGlobalMapExtents; if (eOk != OdDbGeoMapHelper::getGlobalMapExtents(pGeoData, arrGlobalMapExtents)) { return eInvalidInput; } // get all needed tiles std::set arrTiles; res = OdDbGeoMapHelper::getGeoMapTiles(arrTiles, pGeoData, eGeoMapType, uLOD, uTileSize, arrMapExtents, arrGlobalMapExtents); if (eOk != res) { return res; } // get all tiles images OdArray arrTilesImages; res = g_OdGeoMapTilesCache->getTiles(arrTiles, arrTilesImages); if (eOk != res) { return res; } //draw tiles OdDbGeoMapHelper::drawTiles(pVd, pGeoData, arrGlobalMapExtents, arrTiles, arrTilesImages, uTileSize); return eOk; } OdResult OdDbGeoDataChunksPEImpl::drawGeoDataProvidersString(OdGiViewportDraw* pVd) const { OdGiDrawFlagsHelper autoFlags(pVd->subEntityTraits(), OdGiSubEntityTraits::kExcludeFromViewExt); OdDbDatabasePtr pDb = pVd->context()->database(); // determine OdDbGeoData: OdDbGeoDataPtr pGeoData; OdResult res = OdDbGeoMapHelper::getGeoData(pDb, pGeoData); if (eOk != res) { return res; } // determine OdGeoMapType: OdGeoMapType eGeoMapType = OdDbGeoMapHelper::getGeoMapType(pVd->viewportObjectId()); if (OdGeoMapType::kNoMap == eGeoMapType) { return eOk; } //get tile info: OdUInt32 uTileSize = 0; OdUInt8 uMinLOD = 0; OdUInt8 uMaxLOD = 0; res = g_OdGeoMapTilesCache->getTileInfo(eGeoMapType, uTileSize, uMinLOD, uMaxLOD); if (eOk != res) { return res; } // get viewport DC corners OdGePoint2d lowerLeft, upperRight; pVd->viewport().getViewportDcCorners(lowerLeft, upperRight); //get scale OdGePoint2d ptScale; pVd->viewport().getNumPixelsInUnitSquare(OdGePoint3d::kOrigin, ptScale, false); // get map extents OdGePoint2dArray arrMapExtents; OdGePoint3dArray arrMapExtents3d; OdGePoint3dArray arrViewPt3d; { OdGeMatrix3d mat = pVd->viewport().getEyeToWorldTransform(); arrViewPt3d.resize(4); arrViewPt3d[0].set(lowerLeft.x, lowerLeft.y, 0.); arrViewPt3d[1].set(upperRight.x, lowerLeft.y, 0.); arrViewPt3d[2].set(upperRight.x, upperRight.y, 0.); arrViewPt3d[3].set(lowerLeft.x, upperRight.y, 0.); arrMapExtents3d.resize(4); arrMapExtents.resize(4); OdGePlane plane(pGeoData->designPoint(), pGeoData->upDirection()); OdGeTol tol = 1.e-6; for (OdUInt32 i = 0; i < 4; ++i) { arrViewPt3d[i].transformBy(mat); plane.intersectWith(OdGeRay3d(arrViewPt3d[i], pVd->viewport().viewDir()), arrMapExtents3d[i], tol); arrMapExtents[i] = arrMapExtents3d[i].convert2d(); } } // get level of detail for result map image (for current viewport) OdUInt8 uLOD = uMinLOD; { OdGeExtents2d extents2d; extents2d.addPoints(arrMapExtents); double dWidth = (upperRight.x - lowerLeft.x) * ptScale.x; double dHeight = (upperRight.y - lowerLeft.y) * ptScale.y; double dViewportDiagLengthInPixels = OdGeVector2d(dWidth, dHeight).length(); double dMapDiagLength = extents2d.diagonal().length(); uLOD = OdDbGeoMapHelper::getOptimalLOD(pGeoData, uMinLOD, uMaxLOD, uTileSize, dViewportDiagLengthInPixels, dMapDiagLength); } { // loading logo OdUInt32 uBrandLogoWidth = 0; OdUInt32 uBrandLogoHeight = 20; OdGiRasterImagePtr pRasterLogo; g_OdGeoMapTilesCache->getBrandLogo(eGeoMapType, pRasterLogo); if (pRasterLogo.get()) { uBrandLogoWidth = pRasterLogo->pixelWidth(); uBrandLogoHeight = pRasterLogo->pixelHeight(); } OdGePoint3d ptOrigin(upperRight.x - uBrandLogoWidth / ptScale.x, lowerLeft.y, 0.); OdGeVector3d vU(1. / ptScale.x, 0., 0.); OdGeVector3d vV(0., 1. / ptScale.y, 0.); OdGeMatrix3d mat = pVd->viewport().getEyeToWorldTransform(); ptOrigin.transformBy(mat); vU.transformBy(mat); vV.transformBy(mat); if (pRasterLogo.get()) { OdGePoint2dArray arrLogoClipBoundary; arrLogoClipBoundary.resize(5); arrLogoClipBoundary[0].set(0., 0.); arrLogoClipBoundary[1].set(uBrandLogoWidth, 0.); arrLogoClipBoundary[2].set(uBrandLogoWidth, uBrandLogoHeight); arrLogoClipBoundary[3].set(0., uBrandLogoHeight); arrLogoClipBoundary[4] = arrLogoClipBoundary[0]; pVd->geometry().rasterImageDc(ptOrigin, vU, vV, pRasterLogo, arrLogoClipBoundary.asArrayPtr(), arrLogoClipBoundary.size(), true); } // drawing copyright strings { OdStringArray arrCopyrightStrings; g_OdGeoMapTilesCache->getCopyrightStrings(eGeoMapType, pGeoData, uLOD, arrMapExtents, arrCopyrightStrings); OdCmColor textColor; OdDbGeoMapHelper::getTextColor(eGeoMapType, textColor); double dTextHeight = 0.25 * uBrandLogoHeight / ptScale.y; OdGePoint3d ptTextPosition(upperRight.x - uBrandLogoWidth / ptScale.x, lowerLeft.y + uBrandLogoHeight / ptScale.y / 2., 0.); ptTextPosition.transformBy(mat); OdDbGeoMapHelper::drawProvidersStrings(pVd, pDb, arrCopyrightStrings, arrViewPt3d, ptTextPosition, dTextHeight, textColor); } } return eOk; } void OdDbGeoDataChunksPEImpl::setMode(bool bEnable) { TD_AUTOLOCK(m_mutex); m_bActiveStatus = bEnable; } bool OdDbGeoDataChunksPEImpl::getMode() const { TD_AUTOLOCK(m_mutex); return m_bActiveStatus; }