void OGRILI1Layer::JoinSurfaceLayer( OGRILI1Layer* poSurfaceLineLayer, int nSurfaceFieldIndex ) { CPLDebug( "OGR_ILI", "Joining surface layer %s with geometries", GetLayerDefn()->GetName()); OGRwkbGeometryType geomType = GetLayerDefn()->GetGeomFieldDefn(nSurfaceFieldIndex)->GetType(); poSurfaceLineLayer->ResetReading(); while (OGRFeature *linefeature = poSurfaceLineLayer->GetNextFeatureRef()) { //OBJE entries with same _RefTID are polygon rings of same feature //TODO: non-numeric _RefTID/FID is not supported yet! GIntBig reftid = linefeature->GetFieldAsInteger64(1); //_RefTID OGRFeature *feature = GetFeatureRef((int)reftid); if (feature) { OGRCurvePolygon *poly; if (feature->GetGeomFieldRef(nSurfaceFieldIndex)) { CPLDebug( "OGR_ILI", "Adding ring to FID " CPL_FRMT_GIB, reftid ); poly = (OGRCurvePolygon *)feature->GetGeomFieldRef(nSurfaceFieldIndex); } else { poly = (geomType == wkbPolygon) ? new OGRPolygon() : new OGRCurvePolygon(); feature->SetGeomFieldDirectly(nSurfaceFieldIndex, poly); } OGRMultiCurve *lines = (OGRMultiCurve*)linefeature->GetGeomFieldRef(0); for( int i = 0; i < lines->getNumGeometries(); i++ ) { OGRCurve *line = (OGRCurve*)lines->getGeometryRef(i); OGRCurve *ring = (geomType == wkbPolygon) ? OGRCurve::CastToLinearRing((OGRCurve*)line->clone()) : (OGRCurve*)line->clone(); poly->addRingDirectly(ring); } } else { CPLError(CE_Warning, CPLE_AppDefined, "Couldn't join feature FID " CPL_FRMT_GIB, reftid ); } } ResetReading(); poSurfaceLineLayer = 0; }
static void AppendCoumpoundCurve( OGRCompoundCurve *poCC, OGRILI1DataSource *poDS) { for( int iMember = 0; iMember < poCC->getNumCurves(); iMember++) { OGRCurve *poGeometry = poCC->getCurve( iMember ); int b3D = wkbHasZ(poGeometry->getGeometryType()); int bIsArc = (poGeometry->getGeometryType() == wkbCircularString || poGeometry->getGeometryType() == wkbCircularStringZ ); OGRSimpleCurve *poLine = (OGRSimpleCurve *)poGeometry; for( int iPoint = 0; iPoint < poLine->getNumPoints(); iPoint++ ) { //Skip last point in curve member if (iPoint == poLine->getNumPoints()-1 && iMember < poCC->getNumCurves()-1) continue; if (iMember == 0 && iPoint == 0) VSIFPrintf( poDS->GetTransferFile(), "STPT" ); else if (bIsArc && iPoint == 1) VSIFPrintf( poDS->GetTransferFile(), "ARCP" ); else VSIFPrintf( poDS->GetTransferFile(), "LIPT" ); VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getX(iPoint)) ); VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getY(iPoint)) ); if (b3D) VSIFPrintf( poDS->GetTransferFile(), " %s", d2str(poLine->getZ(iPoint)) ); VSIFPrintf( poDS->GetTransferFile(), "\n" ); } } VSIFPrintf( poDS->GetTransferFile(), "ELIN\n" ); }
// [[Rcpp::export]] Rcpp::List CPL_curve_to_linestring(Rcpp::List sfc) { // need to pass more parameters? #nocov start std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL); std::vector<OGRGeometry *> out(g.size()); for (size_t i = 0; i < g.size(); i++) { OGRCurve *cs = (OGRCurve *) g[i]; out[i] = cs->CastToLineString(cs); } return sfc_from_ogr(out, true); // destroys out; } // #nocov end
// [[Rcpp::export]] Rcpp::NumericVector CPL_length(Rcpp::List sfc) { std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL); Rcpp::NumericVector out(sfc.length()); for (size_t i = 0; i < g.size(); i++) { OGRwkbGeometryType gt = OGR_GT_Flatten(g[i]->getGeometryType()); if (gt == wkbLineString || gt == wkbCircularString || gt == wkbCompoundCurve || gt == wkbCurve) { OGRCurve *a = (OGRCurve *) g[i]; out[i] = a->get_Length(); } else { OGRGeometryCollection *a = (OGRGeometryCollection *) g[i]; out[i] = a->get_Length(); } delete g[i]; } return out; }
OGRGeometry* OGRPolygon::getCurveGeometry(const char* const* papszOptions) const { OGRCurvePolygon* poCC = new OGRCurvePolygon(); poCC->assignSpatialReference( getSpatialReference() ); bool bHasCurveGeometry = false; for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRCurve* poSubGeom = (OGRCurve* )oCC.papoCurves[iRing]->getCurveGeometry(papszOptions); if( wkbFlatten(poSubGeom->getGeometryType()) != wkbLineString ) bHasCurveGeometry = true; poCC->addRingDirectly( poSubGeom ); } if( !bHasCurveGeometry ) { delete poCC; return clone(); } return poCC; }
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(); }