OGRCompoundCurve* make() { OGRCompoundCurve* poCompoundCurve = new OGRCompoundCurve(); poCompoundCurve->addCurveDirectly(make<OGRLineString>()); OGRCircularString* poCircularString = make<OGRCircularString>(); poCircularString->reversePoints(); poCompoundCurve->addCurveDirectly(poCircularString); return poCompoundCurve; }
OGRCompoundCurve* OGRCurve::CastToCompoundCurve(OGRCurve* poCurve) { OGRCompoundCurve* poCC = new OGRCompoundCurve(); if( poCurve->getGeometryType() == wkbLineString ) poCurve = CastToLineString(poCurve); if( !poCurve->IsEmpty() && poCC->addCurveDirectly(poCurve) != OGRERR_NONE ) { delete poCC; delete poCurve; return NULL; } poCC->assignSpatialReference(poCurve->getSpatialReference()); return poCC; }
void ILI1Reader::ReadGeom( char **stgeom, int geomIdx, OGRwkbGeometryType eType, OGRFeature *feature ) { #ifdef DEBUG_VERBOSE CPLDebug( "OGR_ILI", "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s", geomIdx, OGRGeometryTypeToName(eType) ); #endif if (eType == wkbNone) { CPLError( CE_Warning, CPLE_AppDefined, "Calling ILI1Reader::ReadGeom with wkbNone" ); } // Initialize geometry. OGRCompoundCurve *ogrCurve = new OGRCompoundCurve(); OGRCurvePolygon *ogrPoly = NULL; //current polygon OGRMultiCurve *ogrMultiLine = NULL; //current multi line if (eType == wkbMultiCurve || eType == wkbMultiLineString) { ogrMultiLine = new OGRMultiCurve(); } else if (eType == wkbPolygon || eType == wkbCurvePolygon) { ogrPoly = new OGRCurvePolygon(); } OGRPoint ogrPoint; // Current point. ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2])); OGRLineString *ogrLine = new OGRLineString(); ogrLine->addPoint(&ogrPoint); // Parse geometry. char **tokens = NULL; bool end = false; OGRCircularString *arc = NULL; //current arc while (!end && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if( firsttok == NULL ) { // do nothing } else if (EQUAL(firsttok, "LIPT") && CSLCount(tokens) >= 3) { ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); if (arc) { arc->addPoint(&ogrPoint); OGRErr error = ogrCurve->addCurveDirectly(arc); if (error != OGRERR_NONE) { char* pszJSon = arc->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s", pszJSon ? pszJSon : "(null)" ); CPLFree(pszJSon); delete arc; } arc = NULL; } ogrLine->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ARCP") && CSLCount(tokens) >= 3) { //Finish line and start arc if (ogrLine->getNumPoints() > 1) { OGRErr error = ogrCurve->addCurveDirectly(ogrLine); if (error != OGRERR_NONE) { char* pszJSon = ogrLine->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s", pszJSon ? pszJSon : "(null)" ); CPLFree(pszJSon); delete ogrLine; } ogrLine = new OGRLineString(); } else { ogrLine->empty(); } delete arc; arc = new OGRCircularString(); arc->addPoint(&ogrPoint); ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); arc->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ELIN")) { if (ogrLine->getNumPoints() > 1) { // Ignore single LIPT after ARCP OGRErr error = ogrCurve->addCurveDirectly(ogrLine); if (error != OGRERR_NONE) { char* pszJSon = ogrLine->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s", pszJSon ? pszJSon : "(null)" ); CPLFree(pszJSon); delete ogrLine; } ogrLine = NULL; } if (!ogrCurve->IsEmpty()) { if (ogrMultiLine) { OGRErr error = ogrMultiLine->addGeometryDirectly(ogrCurve); if (error != OGRERR_NONE) { char* pszJSon = ogrCurve->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s", pszJSon ? pszJSon : "(null)" ); CPLFree(pszJSon); delete ogrCurve; } ogrCurve = NULL; } if (ogrPoly) { OGRErr error = ogrPoly->addRingDirectly(ogrCurve); if (error != OGRERR_NONE) { char* pszJSon = ogrCurve->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Could not add geometry: %s", pszJSon ? pszJSon : "(null)" ); CPLFree(pszJSon); delete ogrCurve; } ogrCurve = NULL; } } end = true; } else if (EQUAL(firsttok, "EEDG")) { end = true; } else if (EQUAL(firsttok, "LATT")) { //Line Attributes (ignored) } else if (EQUAL(firsttok, "EFLA")) { end = true; } else if (EQUAL(firsttok, "ETAB")) { end = true; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } delete arc; delete ogrLine; //Set feature geometry if (eType == wkbMultiCurve) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine); delete ogrCurve; } else if (eType == wkbMultiLineString) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry()); delete ogrMultiLine; delete ogrCurve; } else if (eType == wkbCurvePolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly); delete ogrCurve; } else if (eType == wkbPolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry()); delete ogrPoly; delete ogrCurve; } else { feature->SetGeomFieldDirectly(geomIdx, ogrCurve); } }
void ILI1Reader::ReadGeom(char **stgeom, int geomIdx, OGRwkbGeometryType eType, OGRFeature *feature) { char **tokens = NULL; const char *firsttok = NULL; int end = FALSE; OGRCompoundCurve *ogrCurve = NULL; //current compound curve OGRLineString *ogrLine = NULL; //current line OGRCircularString *arc = NULL; //current arc OGRCurvePolygon *ogrPoly = NULL; //current polygon OGRPoint ogrPoint; //current point OGRMultiCurve *ogrMultiLine = NULL; //current multi line //CPLDebug( "OGR_ILI", "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s", geomIdx, OGRGeometryTypeToName(eType)); if (eType == wkbNone) { CPLError(CE_Warning, CPLE_AppDefined, "Calling ILI1Reader::ReadGeom with wkbNone" ); } //Initialize geometry ogrCurve = new OGRCompoundCurve(); if (eType == wkbMultiCurve || eType == wkbMultiLineString) { ogrMultiLine = new OGRMultiCurve(); } else if (eType == wkbPolygon || eType == wkbCurvePolygon) { ogrPoly = new OGRCurvePolygon(); } //tokens = ["STPT", "1111", "22222"] ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2])); ogrLine = new OGRLineString(); ogrLine->addPoint(&ogrPoint); //Parse geometry while (!end && (tokens = ReadParseLine())) { firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "LIPT")) { ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); if (arc) { arc->addPoint(&ogrPoint); ogrCurve->addCurveDirectly(arc); arc = NULL; } ogrLine->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ARCP")) { //Finish line and start arc if (ogrLine->getNumPoints() > 1) { ogrCurve->addCurveDirectly(ogrLine); ogrLine = new OGRLineString(); } else { ogrLine->empty(); } arc = new OGRCircularString(); arc->addPoint(&ogrPoint); ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); arc->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ELIN")) { if (!ogrLine->IsEmpty()) { ogrCurve->addCurveDirectly(ogrLine); } if (!ogrCurve->IsEmpty()) { if (ogrMultiLine) { ogrMultiLine->addGeometryDirectly(ogrCurve); } if (ogrPoly) { ogrPoly->addRingDirectly(ogrCurve); } } end = TRUE; } else if (EQUAL(firsttok, "EEDG")) { end = TRUE; } else if (EQUAL(firsttok, "LATT")) { //Line Attributes (ignored) } else if (EQUAL(firsttok, "EFLA")) { end = TRUE; } else if (EQUAL(firsttok, "ETAB")) { end = TRUE; } else { CPLError(CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } //Set feature geometry if (eType == wkbMultiCurve) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine); } else if (eType == wkbMultiLineString) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry()); delete ogrMultiLine; } else if (eType == wkbCurvePolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly); } else if (eType == wkbPolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry()); delete ogrPoly; } else { feature->SetGeomFieldDirectly(geomIdx, ogrCurve); } }
static OGRCompoundCurve *getPolyline(DOMElement *elem) { // elem -> POLYLINE OGRCompoundCurve *ogrCurve = new OGRCompoundCurve(); OGRLineString *ls = new OGRLineString(); DOMElement *lineElem = (DOMElement *)elem->getFirstChild(); while (lineElem != NULL) { char* pszTagName = XMLString::transcode(lineElem->getTagName()); if (cmpStr(ILI2_COORD, pszTagName) == 0) { OGRPoint* poPoint = getPoint(lineElem); ls->addPoint(poPoint); delete poPoint; } else if (cmpStr(ILI2_ARC, pszTagName) == 0) { //Finish line and start arc if (ls->getNumPoints() > 1) { ogrCurve->addCurveDirectly(ls); ls = new OGRLineString(); } else { ls->empty(); } OGRCircularString *arc = new OGRCircularString(); // end point OGRPoint *ptEnd = new OGRPoint(); // point on the arc OGRPoint *ptOnArc = new OGRPoint(); // radius // double radius = 0; DOMElement *arcElem = (DOMElement *)lineElem->getFirstChild(); while (arcElem != NULL) { char* pszTagName2 = XMLString::transcode(arcElem->getTagName()); char* pszObjValue = getObjValue(arcElem); if (cmpStr("C1", pszTagName2) == 0) ptEnd->setX(CPLAtof(pszObjValue)); else if (cmpStr("C2", pszTagName2) == 0) ptEnd->setY(CPLAtof(pszObjValue)); else if (cmpStr("C3", pszTagName2) == 0) ptEnd->setZ(CPLAtof(pszObjValue)); else if (cmpStr("A1", pszTagName2) == 0) ptOnArc->setX(CPLAtof(pszObjValue)); else if (cmpStr("A2", pszTagName2) == 0) ptOnArc->setY(CPLAtof(pszObjValue)); else if (cmpStr("A3", pszTagName2) == 0) ptOnArc->setZ(CPLAtof(pszObjValue)); else if (cmpStr("R", pszTagName2) == 0) { // radius = CPLAtof(pszObjValue); } CPLFree(pszObjValue); XMLString::release(&pszTagName2); arcElem = (DOMElement *)arcElem->getNextSibling(); } OGRPoint *ptStart = getPoint((DOMElement *)lineElem->getPreviousSibling()); // COORD or ARC arc->addPoint(ptStart); arc->addPoint(ptOnArc); arc->addPoint(ptEnd); ogrCurve->addCurveDirectly(arc); delete ptStart; delete ptEnd; delete ptOnArc; } /* else { // TODO: StructureValue in Polyline not yet supported } */ XMLString::release(&pszTagName); lineElem = (DOMElement *)lineElem->getNextSibling(); } if (ls->getNumPoints() > 1) { ogrCurve->addCurveDirectly(ls); } else { delete ls; } return ogrCurve; }
void OGRILI1Layer::JoinSurfaceLayer( OGRILI1Layer* poSurfaceLineLayer, int nSurfaceFieldIndex ) { CPLDebug( "OGR_ILI", "Joining surface layer %s with geometries", GetLayerDefn()->GetName()); OGRwkbGeometryType geomType = GetLayerDefn()->GetGeomFieldDefn(nSurfaceFieldIndex)->GetType(); std::map<OGRFeature*, std::vector<OGRCurve*> > oMapFeatureToGeomSet; poSurfaceLineLayer->ResetReading(); // First map: for each target curvepolygon, find all belonging curves while (OGRFeature *linefeature = poSurfaceLineLayer->GetNextFeatureRef()) { //OBJE entries with same _RefTID are polygon rings of same feature OGRFeature *feature = nullptr; if (poFeatureDefn->GetFieldDefn(0)->GetType() == OFTString) { feature = GetFeatureRef(linefeature->GetFieldAsString(1)); } else { GIntBig reftid = linefeature->GetFieldAsInteger64(1); feature = GetFeatureRef(reftid); } if (feature) { OGRGeometry* poGeom = linefeature->GetGeomFieldRef(0); OGRMultiCurve *curves = dynamic_cast<OGRMultiCurve *>(poGeom); if( curves ) { for (auto&& curve: curves ) { if( !curve->IsEmpty() ) oMapFeatureToGeomSet[feature].push_back(curve); } } } else { CPLError( CE_Warning, CPLE_AppDefined, "Couldn't join feature FID " CPL_FRMT_GIB, linefeature->GetFieldAsInteger64(1) ); } } // Now for each target polygon, assemble the curves together. std::map<OGRFeature*, std::vector<OGRCurve*> >::const_iterator oIter = oMapFeatureToGeomSet.begin(); for( ; oIter != oMapFeatureToGeomSet.end(); ++oIter ) { OGRFeature* feature = oIter->first; std::vector<OGRCurve*> oCurves = oIter->second; std::vector<OGRCurve*> oSetDestCurves; double dfLargestArea = 0.0; OGRCurve* poLargestCurve = nullptr; while( true ) { std::vector<OGRCurve*>::iterator oIterCurves = oCurves.begin(); if( oIterCurves == oCurves.end() ) break; OGRPoint endPointCC; OGRCompoundCurve* poCC = new OGRCompoundCurve(); bool bFirst = true; while( true ) { bool bNewCurveAdded = false; const double dfEps = 1e-14; for(oIterCurves = oCurves.begin(); oIterCurves != oCurves.end(); ++oIterCurves ) { OGRCurve* curve = *oIterCurves; OGRPoint startPoint; OGRPoint endPoint; curve->StartPoint(&startPoint); curve->EndPoint(&endPoint); if( bFirst || (fabs(startPoint.getX() - endPointCC.getX()) < dfEps && fabs(startPoint.getY() - endPointCC.getY()) < dfEps) ) { bFirst = false; curve->EndPoint(&endPointCC); const OGRwkbGeometryType eCurveType = wkbFlatten(curve->getGeometryType()); if( eCurveType == wkbCompoundCurve ) { OGRCompoundCurve* poCCSub = curve->toCompoundCurve(); for( auto&& subCurve: poCCSub ) { poCC->addCurve(subCurve); } } else { poCC->addCurve( curve ); } oCurves.erase( oIterCurves ); bNewCurveAdded = true; break; } else if( fabs(endPoint.getX() - endPointCC.getX()) < dfEps && fabs(endPoint.getY() - endPointCC.getY()) < dfEps ) { curve->StartPoint(&endPointCC); const OGRwkbGeometryType eCurveType = wkbFlatten(curve->getGeometryType()); if( eCurveType == wkbLineString || eCurveType == wkbCircularString ) { OGRSimpleCurve* poSC = curve->clone()->toSimpleCurve(); poSC->reversePoints(); poCC->addCurveDirectly( poSC ); } else if( eCurveType == wkbCompoundCurve ) { // Reverse the order of the elements of the // compound curve OGRCompoundCurve* poCCSub = curve->toCompoundCurve(); for( int i=poCCSub->getNumCurves()-1; i >= 0; --i ) { OGRSimpleCurve* poSC = poCCSub->getCurve(i)-> clone()->toSimpleCurve(); poSC->reversePoints(); poCC->addCurveDirectly(poSC); } } oCurves.erase( oIterCurves ); bNewCurveAdded = true; break; } } if( !bNewCurveAdded || oCurves.empty() || poCC->get_IsClosed() ) break; } if( !poCC->get_IsClosed() ) { char* pszJSon = poCC->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "A ring %s for feature " CPL_FRMT_GIB " in layer %s " "was not closed. Dropping it", pszJSon, feature->GetFID(), GetName()); delete poCC; CPLFree(pszJSon); } else { double dfArea = poCC->get_Area(); if( dfArea >= dfLargestArea ) { dfLargestArea = dfArea; poLargestCurve = poCC; } oSetDestCurves.push_back(poCC); } } // Now build the final polygon by first inserting the largest ring. OGRCurvePolygon *poPoly = (geomType == wkbPolygon) ? new OGRPolygon() : new OGRCurvePolygon(); if( poLargestCurve ) { std::vector<OGRCurve*>::iterator oIterCurves = oSetDestCurves.begin(); for( ; oIterCurves != oSetDestCurves.end(); ++oIterCurves ) { OGRCurve* poCurve = *oIterCurves; if( poCurve == poLargestCurve ) { oSetDestCurves.erase( oIterCurves ); break; } } if (geomType == wkbPolygon) { poLargestCurve = OGRCurve::CastToLinearRing(poLargestCurve); } OGRErr error = poPoly->addRingDirectly(poLargestCurve); if (error != OGRERR_NONE) { char* pszJSon = poLargestCurve->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Cannot add ring %s to feature " CPL_FRMT_GIB " in layer %s", pszJSon, feature->GetFID(), GetName() ); CPLFree(pszJSon); } oIterCurves = oSetDestCurves.begin(); for( ; oIterCurves != oSetDestCurves.end(); ++oIterCurves ) { OGRCurve* poCurve = *oIterCurves; if (geomType == wkbPolygon) { poCurve = OGRCurve::CastToLinearRing(poCurve); } error = poPoly->addRingDirectly(poCurve); if (error != OGRERR_NONE) { char* pszJSon = poCurve->exportToJson(); CPLError(CE_Warning, CPLE_AppDefined, "Cannot add ring %s to feature " CPL_FRMT_GIB " in layer %s", pszJSon, feature->GetFID(), GetName() ); CPLFree(pszJSon); } } } feature->SetGeomFieldDirectly(nSurfaceFieldIndex, poPoly); } ResetReading(); }