/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2019, 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-2019 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 "OdaCommon.h" #include "DbGeoMap.h" #include "Gi/GiWorldDraw.h" #include "Gi/GiViewportDraw.h" #include "DbRasterVariables.h" #include "DbFiler.h" #include "DbProxyEntity.h" #include "DbProxyObject.h" #include "RxObject.h" #include "DbText.h" #include "DbSortentsTable.h" #include "DbBlockTableRecord.h" #include "DbGeoMapPE.h" ODRX_NO_CONS_DEFINE_MEMBERS(OdDbGeoMapPE, OdRxObject); class OdGiRasterImageRGBA32 : public OdGiRasterImageBGRA32 { public: OdGiRasterImage::PixelFormatInfo pixelFormat() const { OdGiRasterImage::PixelFormatInfo pf; pf.setRGBA(); return pf; } static OdGiRasterImagePtr createObject(OdGiImageBGRA32 *pImage, OdGiRasterImage::TransparencyMode transparencyMode = OdGiRasterImage::kTransparency8Bit) { ODA_ASSERT(pImage); OdSmartPtr pIw = OdRxObjectImpl::createObject(); pIw->m_pBGRAImage = pImage; pIw->m_transparencyMode = transparencyMode; return pIw; } }; ODRX_DEFINE_MEMBERS_EX(OdDbGeoMap, OdDbRasterImage, DBOBJECT_CONSTR, OdDb::vAC27, 81, OdDbProxyEntity::kEraseAllowed, L"AcDbGeoMap", L"GEOMAPIMAGE", L"AcGeolocationObj", OdRx::kMTLoading|OdRx::kMTRender|OdRx::kMTRenderInBlock | OdRx::kHistoryAware); OdDbGeoMap::OdDbGeoMap() : OdDbRasterImage() , m_myBrightness(50) , m_myContrast(50) , m_myFade(0) , m_nWidth(0) , m_nHeight(0) , m_bOutOfDate(true) , m_LOD(14) , m_Resolution(kOptimal) , m_MapType(kAerial) , m_nInt32_1(4) // not sure about three fields below, it's for disabling asserts while coping newly created geomap , m_nInt32_2(4) , m_nInt32_3(8) , m_dragStatus(OdDb::kDragEnd) { m_ptClipBnd.resize(5); } OdDbGeoMap::~OdDbGeoMap() { } #if !defined(__sun) inline double quad(double x) { return x * x; } #else inline double sun_quad(double x) { return x * x; } #endif OdResult OdDbGeoMap::dwgInFields(OdDbDwgFiler* pFiler) { assertWriteEnabled(); OdResult res = OdDbRasterImage::dwgInFields(pFiler); if (res != eOk) return res; int nI16 = pFiler->rdInt16(); // Version ? if (nI16 != 0) { ODA_FAIL_ONCE(); return eMakeMeProxy; } m_UnkId = pFiler->rdSoftPointerId(); ODA_ASSERT_ONCE(m_UnkId.isNull()); m_ptImageBottomLeft = pFiler->rdPoint3d(); m_ptTextPosition = pFiler->rdPoint3d(); m_dImageWidth = pFiler->rdDouble(); m_dImageHeight = pFiler->rdDouble(); m_LOD = pFiler->rdInt8(); m_Resolution = pFiler->rdUInt8(); ODA_ASSERT_ONCE(m_Resolution <= kFiner); m_MapType = pFiler->rdUInt8(); ODA_ASSERT_ONCE(m_MapType <= kHybrid); m_vU = pFiler->rdVector3d(); m_vV = pFiler->rdVector3d(); m_myBrightness = pFiler->rdInt8(); m_myContrast = pFiler->rdInt8(); m_myFade = pFiler->rdInt8(); m_bOutOfDate = pFiler->rdBool(); m_nWidth = pFiler->rdInt32(); m_nHeight = pFiler->rdInt32(); if (pFiler->filerType() != OdDbFiler::kCopyFiler) { OdUInt32 nBytes = m_nWidth * m_nHeight * 4; m_PixelData.resize(nBytes); if (nBytes) { pFiler->rdBytes(m_PixelData.asArrayPtr(), nBytes); } } m_nInt32_1 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_1 == 4); m_nInt32_2 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_2 == 4 || m_nInt32_2 == 8); m_nInt32_3 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_3 == 8); m_ptBottomLeft = pFiler->rdPoint3d(); m_ptBottomRight = pFiler->rdPoint3d(); m_ptUpperRight = pFiler->rdPoint3d(); m_ptUpperLeft = pFiler->rdPoint3d(); OdInt32 nStrings = pFiler->rdInt32(); m_strings.resize(nStrings); for (OdInt32 i = 0; i < nStrings; ++i) { m_strings[i] = pFiler->rdString(); } m_textColor.dwgIn(pFiler); m_dTextHeight = pFiler->rdDouble(); OdInt16 eClipBoundaryType = pFiler->rdInt16(); OdInt32 nClipPts = pFiler->rdInt32(); m_ptClipBnd.resize(nClipPts); for (OdInt32 i = 0; i < nClipPts; ++i) { m_ptClipBnd[i] = pFiler->rdPoint2d(); } if (eClipBoundaryType == kRect) { m_ptClipBnd.resize(2); } else { if(m_ptClipBnd.size() > 0 && !m_ptClipBnd.first().isEqualTo(m_ptClipBnd.last())) { m_ptClipBnd.append(m_ptClipBnd.first()); } } m_idGeoMapDef = pFiler->rdHardOwnershipId(); if (pFiler->filerType() == OdDbFiler::kCopyFiler) { m_dragStatus = (OdDb::DragStat)pFiler->rdUInt8(); } return eOk; } void OdDbGeoMap::dwgOutFields(OdDbDwgFiler* pFiler) const { assertReadEnabled(); OdDbRasterImage::dwgOutFields(pFiler); pFiler->wrInt16(0); // Version ? pFiler->wrSoftPointerId(m_UnkId); pFiler->wrPoint3d(m_ptImageBottomLeft); pFiler->wrPoint3d(m_ptTextPosition); pFiler->wrDouble(m_dImageWidth); pFiler->wrDouble(m_dImageHeight); pFiler->wrInt8(m_LOD); pFiler->wrUInt8(m_Resolution); pFiler->wrUInt8(m_MapType); pFiler->wrVector3d(m_vU); pFiler->wrVector3d(m_vV); pFiler->wrInt8(m_myBrightness); pFiler->wrInt8(m_myContrast); pFiler->wrInt8(m_myFade); pFiler->wrBool(m_bOutOfDate); pFiler->wrInt32(m_nWidth); pFiler->wrInt32(m_nHeight); if (pFiler->filerType() != OdDbFiler::kCopyFiler) { OdUInt32 nBytes = m_nWidth * m_nHeight * 4; if (nBytes) { pFiler->wrBytes(m_PixelData.asArrayPtr(), nBytes); } } pFiler->wrInt32(m_nInt32_1); pFiler->wrInt32(m_nInt32_2); pFiler->wrInt32(m_nInt32_3); pFiler->wrPoint3d(m_ptBottomLeft); pFiler->wrPoint3d(m_ptBottomRight); pFiler->wrPoint3d(m_ptUpperRight); pFiler->wrPoint3d(m_ptUpperLeft); OdInt32 nStrings = m_strings.size(); pFiler->wrInt32(nStrings); for (OdInt32 i = 0; i < nStrings; ++i) { pFiler->wrString(m_strings[i]); } m_textColor.dwgOut(pFiler); pFiler->wrDouble(m_dTextHeight); OdInt32 nClipPts = m_ptClipBnd.size(); pFiler->wrInt16(nClipPts == 2 ? kRect : kPoly); if (nClipPts == 2) // kRect { pFiler->wrInt32(2); pFiler->wrPoint2d(m_ptClipBnd[0]); pFiler->wrPoint2d(m_ptClipBnd[1]); } else { --nClipPts; pFiler->wrInt32(nClipPts); for (OdInt32 i = 0; i < nClipPts; ++i) { pFiler->wrPoint2d(m_ptClipBnd[i]); } } pFiler->wrHardOwnershipId(m_idGeoMapDef); if (pFiler->filerType() == OdDbFiler::kCopyFiler) { pFiler->wrUInt8((OdUInt8)m_dragStatus); } } OdGeoMapResolution OdDbGeoMap::resolution() const { assertReadEnabled(); return (OdGeoMapResolution)m_Resolution; } OdResult OdDbGeoMap::setResolution(OdGeoMapResolution resolution) { assertWriteEnabled(); // just in case (no check in acad) if (resolution < kCoarse) { resolution = kCoarse; } else if (resolution > kFiner) { resolution = kFiner; } if (m_Resolution != resolution) { m_Resolution = resolution; m_bOutOfDate = true; } return eOk; } OdInt8 OdDbGeoMap::LOD() const { assertReadEnabled(); return m_LOD; } OdGeoMapType OdDbGeoMap::mapType() const { assertReadEnabled(); return (OdGeoMapType)m_MapType; } OdResult OdDbGeoMap::setMapType(OdGeoMapType mapType) { assertWriteEnabled(); if (mapType == kNoMap) { return eInvalidInput; } if (m_MapType != mapType) { m_MapType = mapType; m_bOutOfDate = true; } return eOk; } OdGePoint3d OdDbGeoMap::imageBottomLeftPt() const { assertReadEnabled(); return m_ptImageBottomLeft; } double OdDbGeoMap::imageHeight() const { assertReadEnabled(); return m_dImageHeight; } double OdDbGeoMap::imageWidth() const { assertReadEnabled(); return m_dImageWidth; } OdGeVector2d OdDbGeoMap::imageSize(bool /*bGetCachedValue = false*/) const { assertReadEnabled(); return OdGeVector2d(m_nWidth, m_nHeight); } OdDbObjectId OdDbGeoMap::imageDefId() const { assertReadEnabled(); return m_idGeoMapDef; } OdResult OdDbGeoMap::getVertices(OdGePoint3dArray& vertices) const { assertReadEnabled(); vertices.append(m_ptBottomLeft); vertices.append(m_ptBottomRight); vertices.append(m_ptUpperRight); vertices.append(m_ptUpperLeft); vertices.append(m_ptBottomLeft); return eOk; //TODO return eNotInitializedYet; depends on 4 4 8 } const OdGePoint2dArray& OdDbGeoMap::clipBoundary() const { assertReadEnabled(); return m_ptClipBnd; } bool OdDbGeoMap::isOutOfDate() const { assertReadEnabled(); return m_bOutOfDate; } #define NEXT_CODE(code) \ if (pFiler->nextItem() != code) \ { \ ODA_FAIL_ONCE(); \ return eMakeMeProxy; \ } OdResult OdDbGeoMap::dxfInFields(OdDbDxfFiler* pFiler) { OdResult res = OdDbEntity::dxfInFields(pFiler); if (res != eOk) { ODA_FAIL_ONCE(); return res; } if (!pFiler->atSubclassData(desc()->name())) { ODA_FAIL_ONCE(); return eMakeMeProxy; } setDisplayOpt(OdDbRasterImage::kShow, true); // Because RasterImage data is not saved to DXF NEXT_CODE(70); int nI16 = pFiler->rdInt16(); // Version ? if (nI16 != 0) { ODA_FAIL_ONCE(); return eMakeMeProxy; } NEXT_CODE(330); m_UnkId = pFiler->rdObjectId(); ODA_ASSERT_ONCE(m_UnkId.isNull()); NEXT_CODE(10); pFiler->rdPoint3d(m_ptImageBottomLeft); NEXT_CODE(10); pFiler->rdPoint3d(m_ptTextPosition); NEXT_CODE(40); m_dImageWidth = pFiler->rdDouble(); NEXT_CODE(40); m_dImageHeight = pFiler->rdDouble(); NEXT_CODE(280); m_LOD = pFiler->rdInt8(); NEXT_CODE(280); m_Resolution = pFiler->rdUInt8(); ODA_ASSERT_ONCE(m_Resolution <= kFiner); NEXT_CODE(280); m_MapType = pFiler->rdUInt8(); ODA_ASSERT_ONCE(m_MapType <= kHybrid); NEXT_CODE(10); pFiler->rdVector3d(m_vU); NEXT_CODE(10); pFiler->rdVector3d(m_vV); NEXT_CODE(280); m_myBrightness = pFiler->rdInt8(); NEXT_CODE(280); m_myContrast = pFiler->rdInt8(); NEXT_CODE(280); m_myFade = pFiler->rdInt8(); NEXT_CODE(290); m_bOutOfDate = pFiler->rdBool(); NEXT_CODE(90); m_nWidth = pFiler->rdInt32(); NEXT_CODE(90); m_nHeight = pFiler->rdInt32(); OdUInt32 nBytes = m_nWidth * m_nHeight * 4; m_PixelData.resize(0); if (nBytes) { m_PixelData.reserve(nBytes); OdBinaryData chunk; while (m_PixelData.size() < nBytes) { NEXT_CODE(310); pFiler->rdBinaryChunk(chunk); m_PixelData.append(chunk); } } NEXT_CODE(90); m_nInt32_1 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_1 == 4); NEXT_CODE(90); m_nInt32_2 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_2 == 4); NEXT_CODE(90); m_nInt32_3 = pFiler->rdInt32(); ODA_ASSERT_ONCE(m_nInt32_3 == 8); NEXT_CODE(10); pFiler->rdPoint3d(m_ptBottomLeft); NEXT_CODE(10); pFiler->rdPoint3d(m_ptBottomRight); NEXT_CODE(10); pFiler->rdPoint3d(m_ptUpperRight); NEXT_CODE(10); pFiler->rdPoint3d(m_ptUpperLeft); NEXT_CODE(90); OdInt32 nStrings = pFiler->rdInt32(); m_strings.resize(nStrings); for (OdInt32 i = 0; i < nStrings; ++i) { NEXT_CODE(1); m_strings[i] = pFiler->rdString(); } m_textColor.dxfIn(pFiler, 1); NEXT_CODE(40); m_dTextHeight = pFiler->rdDouble(); NEXT_CODE(71); OdInt16 eClipBoundaryType = pFiler->rdInt16(); NEXT_CODE(91); OdInt32 nClipPts = pFiler->rdInt32(); m_ptClipBnd.resize(nClipPts); for (OdInt32 i = 0; i < nClipPts; ++i) { NEXT_CODE(14); pFiler->rdPoint2d(m_ptClipBnd[i]); } if (eClipBoundaryType == kRect) { m_ptClipBnd.resize(2); } else { if(m_ptClipBnd.size() > 0 && !m_ptClipBnd.first().isEqualTo(m_ptClipBnd.last())) { m_ptClipBnd.append(m_ptClipBnd.first()); } } // m_idGeoMapDef - not saved to DXF return eOk; } void OdDbGeoMap::dxfOutFields(OdDbDxfFiler* pFiler) const { OdDbEntity::dxfOutFields(pFiler); pFiler->wrSubclassMarker(desc()->name()); pFiler->wrInt16(70, 0); // Version ? pFiler->wrObjectId(330, m_UnkId); pFiler->wrPoint3d(10, m_ptImageBottomLeft); pFiler->wrPoint3d(10, m_ptTextPosition); pFiler->wrDouble(40, m_dImageWidth); pFiler->wrDouble(40, m_dImageHeight); pFiler->wrInt8(280, m_LOD); pFiler->wrUInt8(280, m_Resolution); pFiler->wrUInt8(280, m_MapType); pFiler->wrVector3d(10, m_vU); pFiler->wrVector3d(10, m_vV); pFiler->wrInt8(280, m_myBrightness); pFiler->wrInt8(280, m_myContrast); pFiler->wrInt8(280, m_myFade); pFiler->wrBool(290, m_bOutOfDate); pFiler->wrInt32(90, m_nWidth); pFiler->wrInt32(90, m_nHeight); pFiler->wrBinaryChunk(310, m_PixelData.getPtr(), m_PixelData.size()); pFiler->wrInt32(90, m_nInt32_1); pFiler->wrInt32(90, m_nInt32_2); pFiler->wrInt32(90, m_nInt32_3); pFiler->wrPoint3d(10, m_ptBottomLeft); pFiler->wrPoint3d(10, m_ptBottomRight); pFiler->wrPoint3d(10, m_ptUpperRight); pFiler->wrPoint3d(10, m_ptUpperLeft); OdInt32 nStrings = m_strings.size(); pFiler->wrInt32(90, nStrings); for (OdInt32 i = 0; i < nStrings; ++i) { pFiler->wrString(1, m_strings[i]); } m_textColor.dxfOut(pFiler, 1); pFiler->wrDouble(40, m_dTextHeight); OdInt32 nClipPts = m_ptClipBnd.size(); pFiler->wrInt16(71, nClipPts == 2 ? kRect : kPoly); if (nClipPts == 2) { pFiler->wrInt32(91, 2); pFiler->wrPoint2d(14, m_ptClipBnd[0]); pFiler->wrPoint2d(14, m_ptClipBnd[1]); } else { pFiler->wrInt32(91, nClipPts); for (OdInt32 i = 0; i < nClipPts; ++i) { pFiler->wrPoint2d(14, m_ptClipBnd[i]); } } // m_idGeoMapDef - not saved to DXF } void OdDbGeoMap::composeForLoad(OdDb::SaveType format, OdDb::DwgVersion version, OdDbAuditInfo* pAuditInfo) { // Def object is not saved to DXF and is recreated each time DXF is loaded. if (m_idGeoMapDef.isNull()) { OdDbGeoMapDefPtr pDef = OdDbGeoMapDef::createObject(); m_idGeoMapDef = database()->addOdDbObject(pDef, objectId()); } } OdDbObjectPtr OdDbGeoMap::decomposeForSave(OdDb::DwgVersion ver, OdDbObjectId& replaceId, bool& exchangeXData) { OdDbObjectPtr pObj = OdDbRasterImage::decomposeForSave(ver, replaceId, exchangeXData); if (m_idGeoMapDef.isNull()) { OdDbGeoMapDefPtr pDef = OdDbGeoMapDef::createObject(); m_idGeoMapDef = database()->addOdDbObject(pDef, objectId()); } return pObj; } OdInt8 OdDbGeoMap::brightness() const { assertReadEnabled(); return m_myBrightness; } OdResult OdDbGeoMap::setBrightness(OdInt8 brightness) { if (brightness < 0 || brightness > 100) return eInvalidInput; assertWriteEnabled(); m_myBrightness = brightness; return eOk; } OdInt8 OdDbGeoMap::contrast() const { assertReadEnabled(); return m_myContrast; } OdResult OdDbGeoMap::setContrast(OdInt8 contrast) { if (contrast < 0 || contrast > 100) return eInvalidInput; assertWriteEnabled(); m_myContrast = contrast; return eOk; } OdInt8 OdDbGeoMap::fade() const { assertReadEnabled(); return m_myFade; } OdResult OdDbGeoMap::setFade(OdInt8 fade) { if (fade < 0 || fade > 100) return eInvalidInput; assertWriteEnabled(); m_myFade = fade; return eOk; } OdResult OdDbGeoMap::updateMapImage(bool bReset) { assertWriteEnabled(); OdDbGeoMapPEPtr ext = desc()->getX(OdDbGeoMapPE::desc()); if (ext.isNull()) { m_bOutOfDate = true; return eNoInterface; } return ext->updateMapImage(this, bReset); } //#include "RxRasterServices.h" OdGiRasterImagePtr OdDbGeoMap::image(bool /*load*/) const { assertReadEnabled(); updateMapImageIfNeeded(); OdGiImageBGRA32 * pImg = (OdGiImageBGRA32 *) &m_image; pImg->setImage(m_nWidth, m_nHeight, (OdGiPixelBGRA32 *)m_PixelData.asArrayPtr()); OdGiRasterImagePtr pImage = OdGiRasterImageRGBA32::createObject(pImg); // Flip it OdSmartPtr pRet = OdRxObjectImpl::createObject(); pRet->setOriginal(pImage); // OdRxRasterServicesPtr pRasSvcs = odrxDynamicLinker()->loadApp(RX_RASTER_SERVICES_APPNAME); // pRasSvcs->saveRasterImage(pRet, L"d:/0/##GeoMap/background.bmp"); // pRasSvcs->saveRasterImage(pRet, L"d:/0/##GeoMap/background.png"); return pRet; } bool OdDbGeoMap::subWorldDraw(OdGiWorldDraw* pWd) const { OdGiRegenType regenType = pWd->regenType(); if ( regenType == kOdGiForExtents || regenType == kOdGiSaveWorldDrawForProxy || !isSetDisplayOpt(kShow) || m_dragStatus == OdDb::kDragStart ) { OdGePoint3dArray framePoints; getVertices(framePoints); pWd->geometry().polyline(framePoints.size(), framePoints.getPtr()); return true; } return false; // go to viewportDraw, and paint image } //void IO_TRACE(const char* lpszFormat, ...) //{ // // va_list args; // va_start(args, lpszFormat); // // int nBuf; // static char szBuffer[512]; // nBuf = vsnprintf(szBuffer, sizeof(szBuffer), lpszFormat, args); // OutputDebugStringA(szBuffer); // va_end(args); //} void OdDbGeoMap::subViewportDraw(OdGiViewportDraw* pVd) const { assertReadEnabled(); if (m_dragStatus != OdDb::kDragStart) { //Draw Image updateMapImageIfNeeded(); if (!m_bOutOfDate) { OdGiRasterImagePtr pRaster = image(); pVd->geometry().rasterImageDc( m_ptImageBottomLeft, m_vU, m_vV, pRaster, m_ptClipBnd.asArrayPtr(), m_ptClipBnd.size(), isSetDisplayOpt(kTransparent), brightness(), contrast(), fade() ); } } // Draw Frame { OdGePoint3dArray frame; getImageVertices(frame); pVd->geometry().polyline(frame.size(), frame.getPtr()); } //Draw Text if(m_bOutOfDate) { return; } OdString strText; for (unsigned int i = 0; i < m_strings.size(); i++) { if (!m_strings[i].isEmpty()) { strText += m_strings[i]; strText += L' '; // Last (terminating) space is required because of right alignment } } if (!strText.isEmpty()) { OdDbTextPtr pText = OdDbText::createObject(); pText->setTextString(strText); pText->setColor(m_textColor); pText->setHorizontalMode(OdDb::kTextRight); pText->setVerticalMode(OdDb::kTextTop); // pText->setVerticalMode(OdDb::kTextVertMid); //IO_TRACE("m_dTextHeight=%f\n", m_dTextHeight); pText->setHeight(m_dTextHeight); pText->setTextStyle(database()->getTEXTSTYLE()); // TODO #ifdef ___444 if (!(m_ptBottomRight - m_ptBottomLeft).isCodirectionalTo(OdGeVector3d::kXAxis) || !(m_ptUpperLeft - m_ptBottomLeft).isCodirectionalTo(OdGeVector3d::kYAxis)) { OdGeVector3d vNormal = (m_ptBottomRight - m_ptBottomLeft).crossProduct(m_ptUpperLeft - m_ptBottomLeft); if (vNormal.isZeroLength()) { return; } pText->setNormal(vNormal); OdGePlane plane; OdDb::Planarity type; pText->getPlane(plane, type); double dRotation = (m_ptBottomRight - m_ptBottomLeft).angleOnPlane(plane); pText->setRotation(dRotation); } OdGeVector3d vDisplacement = m_vV.normal() * (m_dTextHeight * 2. / 3.); OdGePoint3d ptAlignment(m_ptTextPosition - vDisplacement); pText->setAlignmentPoint(ptAlignment); pText->adjustAlignment(); OdGePoint3d ptPos = pText->position(); // Check if text fits into image boundaries OdGeVector3d vRightToLeft(m_ptBottomLeft - m_ptBottomRight); OdGeVector3d vCornerToText(m_ptTextPosition - m_ptBottomRight); double dBoxWidth = vRightToLeft.length(); double dRightOffset = vCornerToText.dotProduct(vRightToLeft) / dBoxWidth; double dDistToBoxBorder = dBoxWidth - dRightOffset; OdGeVector3d vAlignToPos = ptPos - ptAlignment; double dTextLength = vAlignToPos.length(); if (dTextLength > dDistToBoxBorder) { ptPos = ptAlignment + vAlignToPos * (dDistToBoxBorder / dTextLength); pText->setHorizontalMode(OdDb::kTextAlign); pText->setPosition(ptPos); pText->adjustAlignment(); } pVd->geometry().draw(pText); #else OdGePoint3dArray pp; pText->getBoundingPoints(pp); // Check if text fits into image boundaries double w = (pp[1] - pp[0]).length(); double h = (pp[2] - pp[0]).length(); bool inw = w < (m_ptTextPosition - m_ptBottomLeft).length(); bool inh = h < (m_ptUpperRight - m_ptBottomRight).length(); pText->setRotation(OD_ATAN2((m_ptBottomRight.y - m_ptBottomLeft.y), (m_ptBottomRight.x - m_ptBottomLeft.x))); pText->setPosition(m_ptTextPosition); OdGePoint3d ptAlignment(m_ptTextPosition); pText->setAlignmentPoint(m_ptTextPosition); pText->adjustAlignment(); if(inw && inh) pVd->geometry().draw(pText); #endif } } OdResult OdDbGeoMap::subGetGeomExtents(OdGeExtents3d& ext) const { assertReadEnabled(); ext = OdGeExtents3d(); OdGePoint3dArray framePoints; getVertices(framePoints); for(OdUInt32 f=0; fx - le) < eps; bri = fabs(arr[i]->x - ri) < eps; bto = fabs(arr[i]->y - to) < eps; bbo = fabs(arr[i]->y - bo) < eps; if (ble || bri || bto || bbo) break; } ODA_ASSERT_ONCE(i != 5|| ble || bri || bto || bbo); if (bto) { double dx = arr[i]->x - le; double dy = dx * tan(alfa); i = (1 + i) & 3; arr[i]->x = le; arr[i]->y = to - dy; i = (1 + i) & 3; arr[i]->x = ri - dx; arr[i]->y = bo; i = (1 + i) & 3; arr[i]->x = ri; arr[i]->y = bo + dy; } else if (ble) { double dy = to - arr[i]->y; double dx = dy / tan(alfa); i = (1 + i) & 3; arr[i]->x = ri - dx; arr[i]->y = bo; i = (1 + i) & 3; arr[i]->x = ri; arr[i]->y = bo + dy; i = (1 + i) & 3; arr[i]->x = le + dx; arr[i]->y = to; } else if (bbo) { double dx = ri - arr[i]->x; double dy = dx * tan(alfa); i = (1 + i) & 3; arr[i]->x = ri; arr[i]->y = bo+dy; i = (1 + i) & 3; arr[i]->x = le + dx; arr[i]->y = to; i = (1 + i) & 3; arr[i]->x = le; arr[i]->y = to-dy ; } else if (bri) { double dy = arr[i]->y-bo; double dx = dy / tan(alfa); i = (1 + i) & 3; arr[i]->x = le + dx; arr[i]->y = to; i = (1 + i) & 3; arr[i]->x = le; arr[i]->y = to - dy; i = (1 + i) & 3; arr[i]->x = ri-dx; arr[i]->y = bo; } //IO_TRACE("after %10.0f:%10.0f\n %10.0f:%10.0f\n %10.0f:%10.0f\n %10.0f:%10.0f\n \n", m_ptBottomLeft.x, m_ptBottomLeft.y, m_ptBottomRight.x, m_ptBottomRight.y, m_ptUpperRight.x, m_ptUpperRight.y, m_ptUpperLeft.x, m_ptUpperLeft.y); if (fabs(s) > 1e-9 && fabs(c) > 1e-9)/// rotate { double d1 = ((*arr)[3] - (*arr)[1]).length(); double d0 = ((*arr)[2] - (*arr)[0]).length(); //if (fabs(d1 - d0) > 1e-6) // __debugbreak(); // second variant //ODA_ASSERT_ONCE( abs(s) != abs(c) ); //double d = 1.0 / (quad(c) - quad(s)); //double w3 = (w2*abs(c) - h2 * abs(s))*d; //ODA_ASSERT_ONCE(w3 >= 0); //double h3 = (h2*abs(c) - w2 * abs(s))*d; //ODA_ASSERT_ONCE(h3 >= 0); //m_ptBottomLeft = OdGePoint3d(ce.x + w3 * 0.5 * c - h3 * 0.5 * s, ce.y + h3 * 0.5 * c + w3 * 0.5 * s, 0); //m_ptBottomRight = OdGePoint3d(ce.x - w3 * 0.5 * c - h3 * 0.5 * s, ce.y + h3 * 0.5 * c - w3 * 0.5 * s, 0); //m_ptUpperRight = OdGePoint3d(ce.x - w3 * 0.5 * c + h3 * 0.5 * s, ce.y - h3 * 0.5 * c - w3 * 0.5 * s, 0); //m_ptUpperLeft = OdGePoint3d(ce.x + w3 * 0.5 * c + h3 * 0.5 * s, ce.y - h3 * 0.5 * c + w3 * 0.5 * s, 0); } else { m_ptBottomLeft = OdGePoint3d(le, bo, z); m_ptBottomRight = OdGePoint3d(ri, bo, z); m_ptUpperRight = OdGePoint3d(ri, to, z); m_ptUpperLeft = OdGePoint3d(le, to, z); } // What if image resolution is not set yet? m_vU = u; if (m_nWidth) m_vU /= m_nWidth; m_vV = v; if (m_nHeight) m_vV /= m_nHeight; m_ptClipBnd.resize(5); OdGeMatrix3d mat = pixelToModelTransform(m_ptImageBottomLeft, m_vU, m_vV, m_nHeight).inverse(); m_ptClipBnd[0] = (mat * m_ptBottomLeft).convert2d(); m_ptClipBnd[1] = (mat * m_ptBottomRight).convert2d(); m_ptClipBnd[2] = (mat * m_ptUpperRight).convert2d(); m_ptClipBnd[3] = (mat * m_ptUpperLeft).convert2d(); m_ptClipBnd[4] = m_ptClipBnd[0]; m_ptTextPosition = m_ptBottomRight - (m_ptBottomRight - m_ptBottomLeft).normalize() * 9.0 * m_dTextHeight + (m_ptUpperRight - m_ptBottomRight).normalize() * 2.0 * m_dTextHeight; m_bOutOfDate = true; return eOk; } OdResult OdDbGeoMap::subErase(bool bErasing) { OdDbBlockTableRecordPtr pModelSpace = database()->getModelSpaceId().safeOpenObject(); OdDbSortentsTablePtr pSortentsTable = pModelSpace->getSortentsTable(false); if(pSortentsTable.get()) { pSortentsTable->removeField(id()); } return OdDbRasterImage::subErase(bErasing); } void OdDbGeoMap::updateMapImageIfNeeded(bool bReset) const { //trying to update image if needed if (m_bOutOfDate && m_dragStatus != OdDb::kDragStart) { OdDbGeoMap * pGeoMap = const_cast(this); pGeoMap->upgradeOpen(); pGeoMap->updateMapImage(bReset); pGeoMap->downgradeOpen(); } } void OdDbGeoMap::subClose() { if (m_bOutOfDate && isModified() && !database()->isDatabaseLoading() // Load file as is && !isUndoing() && !isOdDbObjectIdsInFlux()) // Cloning { updateMapImage(); } } void OdDbGeoMap::dragStatus( const OdDb::DragStat status ) { m_dragStatus = status; } //////////////////////////////////////////////////////////////////////////////////// // // OdDbGeoMapDef // //////////////////////////////////////////////////////////////////////////////////// ODRX_DEFINE_MEMBERS_EX(OdDbGeoMapDef, OdDbRasterImageDef, DBOBJECT_CONSTR, OdDb::vAC27, 81, OdDbProxyObject::kDisableProxyWarning, L"AcDbGeoMapDef", L"AcDbGeoMapDef", L"AcGeolocationObj", OdRx::kMTLoading | OdRx::kHistoryAware); OdDbGeoMapDef::OdDbGeoMapDef() : OdDbRasterImageDef() {} OdDbGeoMapDef::~OdDbGeoMapDef() { } OdResult OdDbGeoMapDef::dwgInFields(OdDbDwgFiler* pFiler) { assertWriteEnabled(); OdResult res = OdDbObject::dwgInFields(pFiler); if (res != eOk) return res; int nI16 = pFiler->rdInt16(); // Version ? if (nI16 != 0) { ODA_FAIL_ONCE(); return eMakeMeProxy; } OdDbObjectId id = pFiler->rdSoftPointerId(); if (id != ownerId()) { ODA_FAIL_ONCE(); return eMakeMeProxy; } return eOk; } void OdDbGeoMapDef::dwgOutFields(OdDbDwgFiler* pFiler) const { assertReadEnabled(); OdDbObject::dwgOutFields(pFiler); pFiler->wrInt16(0); pFiler->wrSoftPointerId(ownerId()); } OdGiRasterImagePtr OdDbGeoMapDef::image(bool bReset) { assertReadEnabled(); OdDbGeoMapPtr pEnt = ownerId().safeOpenObject(); return pEnt->image(bReset); }