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; }
OGRCurvePolygon* make() { OGRCurvePolygon* poCurvePolygon = new OGRCurvePolygon(); poCurvePolygon->addRingDirectly(make<OGRCompoundCurve>()); poCurvePolygon->addRingDirectly(make<OGRCompoundCurve>()); return poCurvePolygon; }
void OGRGeometryCollection::closeRings() { for( auto&& poSubGeom: *this ) { if( OGR_GT_IsSubClassOf( wkbFlatten(poSubGeom->getGeometryType()), wkbCurvePolygon ) ) { OGRCurvePolygon *poPoly = poSubGeom->toCurvePolygon(); poPoly->closeRings(); } } }
static OGRCurvePolygon *getPolygon(DOMElement *elem) { OGRCurvePolygon *pg = new OGRCurvePolygon(); DOMElement *boundaryElem = (DOMElement *)elem->getFirstChild(); // outer boundary while (boundaryElem != NULL) { char* pszTagName = XMLString::transcode(boundaryElem->getTagName()); if (cmpStr(ILI2_BOUNDARY, pszTagName) == 0) pg->addRingDirectly(getBoundary(boundaryElem)); XMLString::release(&pszTagName); boundaryElem = (DOMElement *)boundaryElem->getNextSibling(); // inner boundaries } return pg; }
OGRGeometry *OGRCurvePolygon::clone() const { OGRCurvePolygon *poNewPolygon; poNewPolygon = (OGRCurvePolygon*) OGRGeometryFactory::createGeometry(getGeometryType()); poNewPolygon->assignSpatialReference( getSpatialReference() ); for( int i = 0; i < oCC.nCurveCount; i++ ) { poNewPolygon->addRing( oCC.papoCurves[i] ); } return poNewPolygon; }
OGRCurvePolygon* OGRPolygon::CastToCurvePolygon( OGRPolygon* poPoly ) { OGRCurvePolygon* poCP = new OGRCurvePolygon(); poCP->set3D(poPoly->Is3D()); poCP->setMeasured(poPoly->IsMeasured()); poCP->assignSpatialReference(poPoly->getSpatialReference()); poCP->oCC.nCurveCount = poPoly->oCC.nCurveCount; poCP->oCC.papoCurves = poPoly->oCC.papoCurves; poPoly->oCC.nCurveCount = 0; poPoly->oCC.papoCurves = nullptr; for( auto&& poRing: *poCP ) { poRing = OGRLinearRing::CastToLineString(poRing->toLinearRing()); } delete poPoly; return poCP; }
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; }
OGRCurvePolygon* OGRPolygon::CastToCurvePolygon(OGRPolygon* poPoly) { OGRCurvePolygon* poCP = new OGRCurvePolygon(); poCP->set3D(poPoly->Is3D()); poCP->setMeasured(poPoly->IsMeasured()); poCP->assignSpatialReference(poPoly->getSpatialReference()); poCP->oCC.nCurveCount = poPoly->oCC.nCurveCount; poCP->oCC.papoCurves = poPoly->oCC.papoCurves; poPoly->oCC.nCurveCount = 0; poPoly->oCC.papoCurves = NULL; for( int iRing = 0; iRing < poCP->oCC.nCurveCount; iRing++ ) { poCP->oCC.papoCurves[iRing] = OGRLinearRing::CastToLineString( (OGRLinearRing*)poCP->oCC.papoCurves[iRing] ); } delete poPoly; return poCP; }
OGRGeometry * OGRPolygon::getCurveGeometry( const char* const* papszOptions ) const { OGRCurvePolygon* poCC = new OGRCurvePolygon(); poCC->assignSpatialReference( getSpatialReference() ); bool bHasCurveGeometry = false; for( auto&& poRing: *this ) { auto poSubGeom = poRing->getCurveGeometry(papszOptions); if( wkbFlatten(poSubGeom->getGeometryType()) != wkbLineString ) bHasCurveGeometry = true; poCC->addRingDirectly( poSubGeom->toCurve() ); } if( !bHasCurveGeometry ) { delete poCC; return clone(); } 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); } }
static int OGR2GML3GeometryAppend( const OGRGeometry *poGeometry, const OGRSpatialReference* poParentSRS, char **ppszText, int *pnLength, int *pnMaxLength, int bIsSubGeometry, int bLongSRS, int bLineStringAsCurve, const char* pszGMLId, int nSRSDimensionLocFlags, int bForceLineStringAsLinearRing ) { /* -------------------------------------------------------------------- */ /* Check for Spatial Reference System attached to given geometry */ /* -------------------------------------------------------------------- */ // Buffer for srsName, srsDimension and gml:id attributes (srsName="..." gml:id="...") char szAttributes[256]; int nAttrsLength = 0; szAttributes[0] = 0; const OGRSpatialReference* poSRS = NULL; if (poParentSRS) poSRS = poParentSRS; else poParentSRS = poSRS = poGeometry->getSpatialReference(); int bCoordSwap = FALSE; if( NULL != poSRS ) { const char* pszAuthName = NULL; const char* pszAuthCode = NULL; const char* pszTarget = NULL; if (poSRS->IsProjected()) pszTarget = "PROJCS"; else pszTarget = "GEOGCS"; pszAuthName = poSRS->GetAuthorityName( pszTarget ); if( NULL != pszAuthName ) { if( EQUAL( pszAuthName, "EPSG" ) ) { pszAuthCode = poSRS->GetAuthorityCode( pszTarget ); if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 ) { if (bLongSRS && !(((OGRSpatialReference*)poSRS)->EPSGTreatsAsLatLong() || ((OGRSpatialReference*)poSRS)->EPSGTreatsAsNorthingEasting())) { OGRSpatialReference oSRS; if (oSRS.importFromEPSGA(atoi(pszAuthCode)) == OGRERR_NONE) { if (oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting()) bCoordSwap = TRUE; } } if (!bIsSubGeometry) { if (bLongSRS) { snprintf( szAttributes, sizeof(szAttributes), " srsName=\"urn:ogc:def:crs:%s::%s\"", pszAuthName, pszAuthCode ); } else { snprintf( szAttributes, sizeof(szAttributes), " srsName=\"%s:%s\"", pszAuthName, pszAuthCode ); } nAttrsLength = strlen(szAttributes); } } } } } if( (nSRSDimensionLocFlags & SRSDIM_LOC_GEOMETRY) != 0 && wkbHasZ(poGeometry->getGeometryType()) ) { strcat(szAttributes, " srsDimension=\"3\""); nAttrsLength = strlen(szAttributes); nSRSDimensionLocFlags &= ~SRSDIM_LOC_GEOMETRY; } if (pszGMLId != NULL && nAttrsLength + 9 + strlen(pszGMLId) + 1 < sizeof(szAttributes)) { strcat(szAttributes, " gml:id=\""); strcat(szAttributes, pszGMLId); strcat(szAttributes, "\""); nAttrsLength = strlen(szAttributes); } OGRwkbGeometryType eType = poGeometry->getGeometryType(); OGRwkbGeometryType eFType = wkbFlatten(eType); /* -------------------------------------------------------------------- */ /* 2D Point */ /* -------------------------------------------------------------------- */ if( eType == wkbPoint ) { char szCoordinate[256]; OGRPoint *poPoint = (OGRPoint *) poGeometry; if (bCoordSwap) OGRMakeWktCoordinate( szCoordinate, poPoint->getY(), poPoint->getX(), 0.0, 2 ); else OGRMakeWktCoordinate( szCoordinate, poPoint->getX(), poPoint->getY(), 0.0, 2 ); _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nAttrsLength, ppszText, pnMaxLength ); sprintf( *ppszText + *pnLength, "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>", szAttributes, szCoordinate ); *pnLength += strlen( *ppszText + *pnLength ); } /* -------------------------------------------------------------------- */ /* 3D Point */ /* -------------------------------------------------------------------- */ else if( eType == wkbPoint25D ) { char szCoordinate[256]; OGRPoint *poPoint = (OGRPoint *) poGeometry; if (bCoordSwap) OGRMakeWktCoordinate( szCoordinate, poPoint->getY(), poPoint->getX(), poPoint->getZ(), 3 ); else OGRMakeWktCoordinate( szCoordinate, poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3 ); _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nAttrsLength, ppszText, pnMaxLength ); sprintf( *ppszText + *pnLength, "<gml:Point%s><gml:pos>%s</gml:pos></gml:Point>", szAttributes, szCoordinate ); *pnLength += strlen( *ppszText + *pnLength ); } /* -------------------------------------------------------------------- */ /* LineString and LinearRing */ /* -------------------------------------------------------------------- */ else if( eFType == wkbLineString ) { int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING") || bForceLineStringAsLinearRing; if (!bRing && bLineStringAsCurve) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:Curve" ); AppendString( ppszText, pnLength, pnMaxLength, szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, "><gml:segments><gml:LineStringSegment>" ); AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); AppendString( ppszText, pnLength, pnMaxLength, "</gml:LineStringSegment></gml:segments></gml:Curve>" ); } else { // Buffer for tag name + srsName attribute if set const size_t nLineTagLength = 16; char* pszLineTagName = NULL; pszLineTagName = (char *) CPLMalloc( nLineTagLength + nAttrsLength + 1 ); if( bRing ) { /* LinearRing isn't supposed to have srsName attribute according to GML3 SF-0 */ AppendString( ppszText, pnLength, pnMaxLength, "<gml:LinearRing>" ); } else { sprintf( pszLineTagName, "<gml:LineString%s>", szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, pszLineTagName ); } // FREE TAG BUFFER CPLFree( pszLineTagName ); AppendGML3CoordinateList( (OGRLineString *) poGeometry, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); if( bRing ) AppendString( ppszText, pnLength, pnMaxLength, "</gml:LinearRing>" ); else AppendString( ppszText, pnLength, pnMaxLength, "</gml:LineString>" ); } } /* -------------------------------------------------------------------- */ /* ArcString or Circle */ /* -------------------------------------------------------------------- */ else if( eFType == wkbCircularString ) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:Curve" ); AppendString( ppszText, pnLength, pnMaxLength, szAttributes ); OGRSimpleCurve* poSC = (OGRSimpleCurve *) poGeometry; /* SQL MM has a unique type for arc and circle, GML not */ if( poSC->getNumPoints() == 3 && poSC->getX(0) == poSC->getX(2) && poSC->getY(0) == poSC->getY(2) ) { double dfMidX = (poSC->getX(0) + poSC->getX(1)) / 2; double dfMidY = (poSC->getY(0) + poSC->getY(1)) / 2; double dfDirX = (poSC->getX(1) - poSC->getX(0)) / 2; double dfDirY = (poSC->getY(1) - poSC->getY(0)) / 2; double dfNormX = -dfDirY; double dfNormY = dfDirX; double dfNewX = dfMidX + dfNormX; double dfNewY = dfMidY + dfNormY; OGRLineString* poLS = new OGRLineString(); OGRPoint p; poSC->getPoint(0, &p); poLS->addPoint(&p); poSC->getPoint(1, &p); if( poSC->getCoordinateDimension() == 3 ) poLS->addPoint(dfNewX, dfNewY, p.getZ()); else poLS->addPoint(dfNewX, dfNewY); poLS->addPoint(&p); AppendString( ppszText, pnLength, pnMaxLength, "><gml:segments><gml:Circle>" ); AppendGML3CoordinateList( poLS, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); AppendString( ppszText, pnLength, pnMaxLength, "</gml:Circle></gml:segments></gml:Curve>" ); delete poLS; } else { AppendString( ppszText, pnLength, pnMaxLength, "><gml:segments><gml:ArcString>" ); AppendGML3CoordinateList( poSC, bCoordSwap, ppszText, pnLength, pnMaxLength, nSRSDimensionLocFlags ); AppendString( ppszText, pnLength, pnMaxLength, "</gml:ArcString></gml:segments></gml:Curve>" ); } } /* -------------------------------------------------------------------- */ /* CompositeCurve */ /* -------------------------------------------------------------------- */ else if( eFType == wkbCompoundCurve ) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:CompositeCurve" ); AppendString( ppszText, pnLength, pnMaxLength, szAttributes ); AppendString( ppszText, pnLength, pnMaxLength,">"); OGRCompoundCurve* poCC = (OGRCompoundCurve*)poGeometry; for(int i=0;i<poCC->getNumCurves();i++) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:curveMember>" ); if( !OGR2GML3GeometryAppend( poCC->getCurve(i), poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, NULL, nSRSDimensionLocFlags, FALSE) ) return FALSE; AppendString( ppszText, pnLength, pnMaxLength, "</gml:curveMember>" ); } AppendString( ppszText, pnLength, pnMaxLength, "</gml:CompositeCurve>" ); } /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ else if( eFType == wkbPolygon || eFType == wkbCurvePolygon ) { OGRCurvePolygon *poCP = (OGRCurvePolygon *) poGeometry; // Buffer for polygon tag name + srsName attribute if set const size_t nPolyTagLength = 13; char* pszPolyTagName = NULL; pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nAttrsLength + 1 ); // Compose Polygon tag with or without srsName attribute sprintf( pszPolyTagName, "<gml:Polygon%s>", szAttributes ); AppendString( ppszText, pnLength, pnMaxLength, pszPolyTagName ); // FREE TAG BUFFER CPLFree( pszPolyTagName ); // Don't add srsName to polygon rings if( poCP->getExteriorRingCurve() != NULL ) { AppendString( ppszText, pnLength, pnMaxLength, "<gml:exterior>" ); if( !OGR2GML3GeometryAppend( poCP->getExteriorRingCurve(), poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, NULL, nSRSDimensionLocFlags, TRUE) ) { return FALSE; } AppendString( ppszText, pnLength, pnMaxLength, "</gml:exterior>" ); } for( int iRing = 0; iRing < poCP->getNumInteriorRings(); iRing++ ) { OGRCurve *poRing = poCP->getInteriorRingCurve(iRing); AppendString( ppszText, pnLength, pnMaxLength, "<gml:interior>" ); if( !OGR2GML3GeometryAppend( poRing, poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, NULL, nSRSDimensionLocFlags, TRUE) ) return FALSE; AppendString( ppszText, pnLength, pnMaxLength, "</gml:interior>" ); } AppendString( ppszText, pnLength, pnMaxLength, "</gml:Polygon>" ); } /* -------------------------------------------------------------------- */ /* MultiSurface, MultiCurve, MultiPoint, MultiGeometry */ /* -------------------------------------------------------------------- */ else if( eFType == wkbMultiPolygon || eFType == wkbMultiSurface || eFType == wkbMultiLineString || eFType == wkbMultiCurve || eFType == wkbMultiPoint || eFType == wkbGeometryCollection ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry; int iMember; const char *pszElemClose = NULL; const char *pszMemberElem = NULL; // Buffer for opening tag + srsName attribute char* pszElemOpen = NULL; if( eFType == wkbMultiPolygon || eFType == wkbMultiSurface ) { pszElemOpen = (char *) CPLMalloc( 13 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiSurface%s>", szAttributes ); pszElemClose = "MultiSurface>"; pszMemberElem = "surfaceMember>"; } else if( eFType == wkbMultiLineString || eFType == wkbMultiCurve ) { pszElemOpen = (char *) CPLMalloc( 16 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiCurve%s>", szAttributes ); pszElemClose = "MultiCurve>"; pszMemberElem = "curveMember>"; } else if( eFType == wkbMultiPoint ) { pszElemOpen = (char *) CPLMalloc( 11 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiPoint%s>", szAttributes ); pszElemClose = "MultiPoint>"; pszMemberElem = "pointMember>"; } else { pszElemOpen = (char *) CPLMalloc( 19 + nAttrsLength + 1 ); sprintf( pszElemOpen, "MultiGeometry%s>", szAttributes ); pszElemClose = "MultiGeometry>"; pszMemberElem = "geometryMember>"; } AppendString( ppszText, pnLength, pnMaxLength, "<gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen ); for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++) { OGRGeometry *poMember = poGC->getGeometryRef( iMember ); AppendString( ppszText, pnLength, pnMaxLength, "<gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem ); char* pszGMLIdSub = NULL; if (pszGMLId != NULL) pszGMLIdSub = CPLStrdup(CPLSPrintf("%s.%d", pszGMLId, iMember)); if( !OGR2GML3GeometryAppend( poMember, poSRS, ppszText, pnLength, pnMaxLength, TRUE, bLongSRS, bLineStringAsCurve, pszGMLIdSub, nSRSDimensionLocFlags, FALSE ) ) { CPLFree(pszGMLIdSub); return FALSE; } CPLFree(pszGMLIdSub); AppendString( ppszText, pnLength, pnMaxLength, "</gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem ); } AppendString( ppszText, pnLength, pnMaxLength, "</gml:" ); AppendString( ppszText, pnLength, pnMaxLength, pszElemClose ); // FREE TAG BUFFER CPLFree( pszElemOpen ); } else { CPLError(CE_Failure, CPLE_NotSupported, "Unsupported geometry type %s", OGRGeometryTypeToName(eType)); return FALSE; } return TRUE; }
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); } }
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(); }
OGRErr OGRCurvePolygon::addCurveDirectlyFromWkb( OGRGeometry* poSelf, OGRCurve* poCurve ) { OGRCurvePolygon* poCP = (OGRCurvePolygon*)poSelf; return poCP->addRingDirectlyInternal( poCurve, FALSE ); }