From 6cb4d68f5be1321764911a6b80e81d3bcf12cfed Mon Sep 17 00:00:00 2001 From: Michael Wildman Date: Wed, 13 Sep 2023 09:42:38 -0600 Subject: [PATCH] Support symbology by layer, take global origin into account, ensure last and first point of a closed geometry fit exactly. --- ogr/ogrsf_frmts/dwg/dgnv8_headers.h | 1 + ogr/ogrsf_frmts/dwg/ogrdgnv8datasource.cpp | 1 + ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp | 49 +++++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/ogr/ogrsf_frmts/dwg/dgnv8_headers.h b/ogr/ogrsf_frmts/dwg/dgnv8_headers.h index df1d951e0b7d..364c1564245b 100644 --- a/ogr/ogrsf_frmts/dwg/dgnv8_headers.h +++ b/ogr/ogrsf_frmts/dwg/dgnv8_headers.h @@ -75,5 +75,6 @@ #include "DgSharedCellReference.h" #include "DgText.h" #include "DgTextNode.h" +#include "DgLevelTableRecord.h" #endif // DGNV8_HEADERS_H diff --git a/ogr/ogrsf_frmts/dwg/ogrdgnv8datasource.cpp b/ogr/ogrsf_frmts/dwg/ogrdgnv8datasource.cpp index cca7ee82f2d0..528e2e9e3e31 100644 --- a/ogr/ogrsf_frmts/dwg/ogrdgnv8datasource.cpp +++ b/ogr/ogrsf_frmts/dwg/ogrdgnv8datasource.cpp @@ -145,6 +145,7 @@ int OGRDGNV8DataSource::Open(const char *pszFilename, bool bUpdate) bUpdate ? OdDg::kForWrite : OdDg::kForRead)); if (!pModel.isNull()) { + pModel->enableGlobalOriginUsage(true); OGRDGNV8Layer *poLayer = new OGRDGNV8Layer(this, pModel); m_papoLayers = static_cast(CPLRealloc( m_papoLayers, sizeof(OGRDGNV8Layer *) * (m_nLayers + 1))); diff --git a/ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp b/ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp index 28ba995a0078..11a97c20ea25 100644 --- a/ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp +++ b/ogr/ogrsf_frmts/dwg/ogrdgnv8layer.cpp @@ -705,6 +705,17 @@ IsContiguous(const std::vector &oVectorSubElts, AlmostEqual(oFirstPoint.getX(), oLastPoint.getX()) && AlmostEqual(oFirstPoint.getY(), oLastPoint.getY()) && AlmostEqual(oFirstPoint.getZ(), oLastPoint.getZ()); + if (bIsClosed) + { + // Make sure that the last point and the first point of the closed geometry fit exactly + // otherwise we get into errors in the processing chain + + // Get the last subelement + OGRGeometry* poGeom = oVectorSubElts[oVectorSubElts.size()-1].first->GetGeometryRef(); + OGRSimpleCurve* poCurve = static_cast(poGeom); + // Set the last point of the last subelement to be idetical to the first point of the geometry + poCurve->setPoint(poCurve->getNumPoints() - 1, &oFirstPoint); + } } return bIsContiguous; } @@ -745,7 +756,7 @@ OGRDGNV8Layer::ProcessElement(OdDgGraphicsElementPtr element, int level) poFeature->SetField("Level", nLevel); poFeature->SetField("GraphicGroup", static_cast(element->getGraphicsGroupEntryId())); - const OdUInt32 uColorIndex = element->getColorIndex(); + OdUInt32 uColorIndex = element->getColorIndex(); CPLString osColor; if (uColorIndex != OdDg::kColorByLevel && uColorIndex != OdDg::kColorByCell) { @@ -755,13 +766,33 @@ OGRDGNV8Layer::ProcessElement(OdDgGraphicsElementPtr element, int level) osColor = CPLSPrintf(",c:#%02x%02x%02x", ODGETRED(color), ODGETGREEN(color), ODGETBLUE(color)); } - const OdInt32 nLineStyle = element->getLineStyleEntryId(); + if (uColorIndex == OdDg::kColorByLevel) + { + OdDgLevelTableRecordPtr myLevel = OdDgLevelTableRecord::cast(element->getLevelId().openObject()); + uColorIndex = myLevel->getElementColorIndex(); + OdDgCmEntityColor myColor = OdDgColorTable::lookupTrueColor(element->database(), uColorIndex); + poFeature->SetField("ColorIndex", + static_cast(uColorIndex)); + + osColor = CPLSPrintf(",c:#%02x%02x%02x", + myColor.red(), + myColor.green(), + myColor.blue()); + } + OdInt32 nLineStyle = element->getLineStyleEntryId(); if (nLineStyle != OdDg::kLineStyleByLevel && nLineStyle != OdDg::kLineStyleByCell) { poFeature->SetField("Style", nLineStyle); } + if (nLineStyle == OdDg::kLineStyleByLevel) + { + OdDgLevelTableRecordPtr myLevel = OdDgLevelTableRecord::cast(element->getLevelId().openObject()); + nLineStyle = myLevel->getElementLineStyleEntryId(); + poFeature->SetField("Style", nLineStyle); + } + const OdUInt32 uLineWeight = element->getLineWeight(); int nLineWeight = 0; if (uLineWeight != OdDg::kLineWeightByLevel && @@ -771,6 +802,13 @@ OGRDGNV8Layer::ProcessElement(OdDgGraphicsElementPtr element, int level) poFeature->SetField("Weight", nLineWeight); } + if (uLineWeight == OdDg::kLineWeightByLevel) + { + OdDgLevelTableRecordPtr myLevel = OdDgLevelTableRecord::cast(element->getLevelId().openObject()); + nLineWeight = static_cast(myLevel->getElementLineWeight()); + poFeature->SetField("Weight", nLineWeight); + } + CPLJSONObject uLinkData; CPLJSONArray previousValues; @@ -1604,6 +1642,7 @@ OGRErr OGRDGNV8Layer::DeleteFeature(GIntBig nFID) OGRErr OGRDGNV8Layer::GetExtent(OGREnvelope *psExtent, int bForce) { OdDgModel::StorageUnitDescription description; + OdGePoint3d globalOrigin = m_pModel->getGlobalOrigin (); m_pModel->getStorageUnit(description); OdDgElementIteratorPtr iterator = m_pModel->createGraphicsElementsIterator(); @@ -1648,7 +1687,13 @@ OGRErr OGRDGNV8Layer::GetExtent(OGREnvelope *psExtent, int bForce) } } if (bValid) + { + psExtent->MinX -= globalOrigin.x; + psExtent->MinY -= globalOrigin.y; + psExtent->MaxX -= globalOrigin.x; + psExtent->MaxY -= globalOrigin.y; return OGRERR_NONE; + } return OGRLayer::GetExtent(psExtent, bForce); }