OGRPolygon* OGRMSSQLGeometryParser::ReadPolygon(int iShape) { int iFigure, iPoint, iNextPoint, i; int iNextFigure = NextFigureOffset(iShape); OGRPolygon* poPoly = new OGRPolygon(); for (iFigure = FigureOffset(iShape); iFigure < iNextFigure; iFigure++) { OGRLinearRing* poRing = new OGRLinearRing(); iPoint = PointOffset(iFigure); iNextPoint = NextPointOffset(iFigure); poRing->setNumPoints(iNextPoint - iPoint); i = 0; while (iPoint < iNextPoint) { if ( chProps & SP_HASZVALUES ) poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint), ReadZ(iPoint) ); else poRing->setPoint(i, ReadX(iPoint), ReadY(iPoint) ); ++iPoint; ++i; } poPoly->addRingDirectly( poRing ); } return poPoly; }
void addPart( const marching_squares::LineString& ring ) { if ( currentGeometry_ && currentPart_ ) { currentGeometry_->addGeometryDirectly(currentPart_); } OGRLinearRing* poNewRing = new OGRLinearRing(); poNewRing->setNumPoints( int(ring.size()) ); int iPoint = 0; for ( const auto& p : ring ) { poNewRing->setPoint( iPoint, p.x, p.y ); iPoint++; } currentPart_ = new OGRPolygon(); currentPart_->addRingDirectly(poNewRing); }
OGRFeature *OGROGDILayer::GetNextRawFeature() { ecs_Result *psResult; int i; OGRFeature *poFeature; /* -------------------------------------------------------------------- */ /* Retrieve object from OGDI server and create new feature */ /* -------------------------------------------------------------------- */ psResult = cln_GetNextObject(m_nClientID); if (! ECSSUCCESS(psResult)) { // We probably reached EOF... keep track of shape count. m_nTotalShapeCount = m_iNextShapeId - m_nFilteredOutShapes; return NULL; } poFeature = new OGRFeature(m_poFeatureDefn); poFeature->SetFID( m_iNextShapeId++ ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Process geometry */ /* -------------------------------------------------------------------- */ if (m_eFamily == Point) { ecs_Point *psPoint = &(ECSGEOM(psResult).point); OGRPoint *poOGRPoint = new OGRPoint(psPoint->c.x, psPoint->c.y); poOGRPoint->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPoint); } else if (m_eFamily == Line) { ecs_Line *psLine = &(ECSGEOM(psResult).line); OGRLineString *poOGRLine = new OGRLineString(); poOGRLine->setNumPoints( psLine->c.c_len ); for( i=0; i < (int) psLine->c.c_len; i++ ) { poOGRLine->setPoint(i, psLine->c.c_val[i].x, psLine->c.c_val[i].y); } poOGRLine->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRLine); } else if (m_eFamily == Area) { ecs_Area *psArea = &(ECSGEOM(psResult).area); OGRPolygon *poOGRPolygon = new OGRPolygon(); for(int iRing=0; iRing < (int) psArea->ring.ring_len; iRing++) { ecs_FeatureRing *psRing = &(psArea->ring.ring_val[iRing]); OGRLinearRing *poOGRRing = new OGRLinearRing(); poOGRRing->setNumPoints( psRing->c.c_len ); for( i=0; i < (int) psRing->c.c_len; i++ ) { poOGRRing->setPoint(i, psRing->c.c_val[i].x, psRing->c.c_val[i].y); } poOGRPolygon->addRingDirectly(poOGRRing); } // __TODO__ // When OGR supports polygon centroids then we should carry them here poOGRPolygon->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPolygon); } else if (m_eFamily == Text) { // __TODO__ // For now text is treated as a point and string is lost // ecs_Text *psText = &(ECSGEOM(psResult).text); OGRPoint *poOGRPoint = new OGRPoint(psText->c.x, psText->c.y); poOGRPoint->assignSpatialReference(m_poSpatialRef); poFeature->SetGeometryDirectly(poOGRPoint); } else { CPLAssert(FALSE); } /* -------------------------------------------------------------------- */ /* Set attributes */ /* -------------------------------------------------------------------- */ char *pszAttrList = ECSOBJECTATTR(psResult); for( int iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++ ) { char *pszFieldStart; int nNameLen; char chSavedChar; /* parse out the next attribute value */ if( !ecs_FindElement( pszAttrList, &pszFieldStart, &pszAttrList, &nNameLen, NULL ) ) { nNameLen = 0; pszFieldStart = pszAttrList; } /* Skip any trailing white space (for string constants). */ if( nNameLen > 0 && pszFieldStart[nNameLen-1] == ' ' ) nNameLen--; /* skip leading white space */ while( pszFieldStart[0] == ' ' && nNameLen > 0 ) { pszFieldStart++; nNameLen--; } /* zero terminate the single field value, but save the */ /* character we overwrote, so we can restore it when done. */ chSavedChar = pszFieldStart[nNameLen]; pszFieldStart[nNameLen] = '\0'; /* OGR takes care of all field type conversions for us! */ poFeature->SetField(iField, pszFieldStart); pszFieldStart[nNameLen] = chSavedChar; } /* -------------------------------------------------------------------- */ /* Apply the text associated with text features if appropriate. */ /* -------------------------------------------------------------------- */ if( m_eFamily == Text ) { poFeature->SetField( "text", ECSGEOM(psResult).text.desc ); } return poFeature; }
/********************************************************************** * DumpViaSpatialIndex() * * Open a .TAB file and print all the geogr. objects that match the * specified filter. Scanes the file via the spatial index. **********************************************************************/ static int DumpViaSpatialIndex(const char *pszFname, double dXMin, double dYMin, double dXMax, double dYMax) { IMapInfoFile *poFile; TABFeature *poFeature; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poFile = IMapInfoFile::SmartOpen(pszFname)) == NULL) { printf("Failed to open %s\n", pszFname); return -1; } poFile->Dump(); /*--------------------------------------------------------------------- * Check for indexed fields *--------------------------------------------------------------------*/ for(int iField=0; iField<poFile->GetLayerDefn()->GetFieldCount(); iField++) { if (poFile->IsFieldIndexed(iField)) printf(" Field %d is indexed\n", iField); } /*--------------------------------------------------------------------- * Set spatial filter *--------------------------------------------------------------------*/ OGRLinearRing oSpatialFilter; oSpatialFilter.setNumPoints(5); oSpatialFilter.setPoint(0, dXMin, dYMin); oSpatialFilter.setPoint(1, dXMax, dYMin); oSpatialFilter.setPoint(2, dXMax, dYMax); oSpatialFilter.setPoint(3, dXMin, dYMax); oSpatialFilter.setPoint(4, dXMin, dYMin); poFile->SetSpatialFilter( &oSpatialFilter ); /*--------------------------------------------------------------------- * Read/Dump objects until EOF is reached *--------------------------------------------------------------------*/ while ( (poFeature = (TABFeature*)poFile->GetNextFeature()) != NULL ) { // poFeature->DumpReadable(stdout); printf("\nFeature %ld:\n", poFeature->GetFID()); poFeature->DumpMID(); poFeature->DumpMIF(); } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poFile->Close(); delete poFile; return 0; }
OGRFeature *OGRPCIDSKLayer::GetFeature( GIntBig nFID ) { /* -------------------------------------------------------------------- */ /* Create the OGR feature. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature; poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( (int) nFID ); /* -------------------------------------------------------------------- */ /* Set attributes for any indicated attribute records. */ /* -------------------------------------------------------------------- */ try { std::vector<PCIDSK::ShapeField> aoFields; unsigned int i; poVecSeg->GetFields( (int) nFID, aoFields ); for( i=0; i < aoFields.size(); i++ ) { if( (int) i == iRingStartField ) continue; switch( aoFields[i].GetType() ) { case PCIDSK::FieldTypeNone: // null field value. break; case PCIDSK::FieldTypeInteger: poFeature->SetField( i, aoFields[i].GetValueInteger() ); break; case PCIDSK::FieldTypeFloat: poFeature->SetField( i, aoFields[i].GetValueFloat() ); break; case PCIDSK::FieldTypeDouble: poFeature->SetField( i, aoFields[i].GetValueDouble() ); break; case PCIDSK::FieldTypeString: poFeature->SetField( i, aoFields[i].GetValueString().c_str() ); break; case PCIDSK::FieldTypeCountedInt: std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt(); poFeature->SetField( i, list.size(), &(list[0]) ); break; } } /* -------------------------------------------------------------------- */ /* Translate the geometry. */ /* -------------------------------------------------------------------- */ std::vector<PCIDSK::ShapeVertex> aoVertices; poVecSeg->GetVertices( (int) nFID, aoVertices ); /* -------------------------------------------------------------------- */ /* Point */ /* -------------------------------------------------------------------- */ if( poFeatureDefn->GetGeomType() == wkbPoint25D || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown && aoVertices.size() == 1) ) { if( aoVertices.size() == 1 ) { OGRPoint* poPoint = new OGRPoint( aoVertices[0].x, aoVertices[0].y, aoVertices[0].z ); if (poSRS) poPoint->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly(poPoint); } else { // report issue? } } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ else if( poFeatureDefn->GetGeomType() == wkbLineString25D || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown && aoVertices.size() > 1) ) { // We should likely be applying ringstart to break things into // a multilinestring in some cases. if( aoVertices.size() > 1 ) { OGRLineString *poLS = new OGRLineString(); poLS->setNumPoints( aoVertices.size() ); for( i = 0; i < aoVertices.size(); i++ ) poLS->setPoint( i, aoVertices[i].x, aoVertices[i].y, aoVertices[i].z ); if (poSRS) poLS->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poLS ); } else { // report issue? } } /* -------------------------------------------------------------------- */ /* Polygon - Currently we have no way to recognise if we are */ /* dealing with a multipolygon when we have more than one */ /* ring. Also, PCIDSK allows the rings to be in arbitrary */ /* order, not necessarily outside first which we are not yet */ /* ready to address in the following code. */ /* -------------------------------------------------------------------- */ else if( poFeatureDefn->GetGeomType() == wkbPolygon25D ) { std::vector<PCIDSK::int32> anRingStart; OGRPolygon *poPoly = new OGRPolygon(); unsigned int iRing; if( iRingStartField != -1 ) anRingStart = aoFields[iRingStartField].GetValueCountedInt(); for( iRing = 0; iRing < anRingStart.size()+1; iRing++ ) { int iStartVertex, iEndVertex, iVertex; OGRLinearRing *poRing = new OGRLinearRing(); if( iRing == 0 ) iStartVertex = 0; else iStartVertex = anRingStart[iRing-1]; if( iRing == anRingStart.size() ) iEndVertex = aoVertices.size() - 1; else iEndVertex = anRingStart[iRing] - 1; poRing->setNumPoints( iEndVertex - iStartVertex + 1 ); for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ ) { poRing->setPoint( iVertex - iStartVertex, aoVertices[iVertex].x, aoVertices[iVertex].y, aoVertices[iVertex].z ); } poPoly->addRingDirectly( poRing ); } if (poSRS) poPoly->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poPoly ); } } /* -------------------------------------------------------------------- */ /* Trap exceptions and report as CPL errors. */ /* -------------------------------------------------------------------- */ catch( PCIDSK::PCIDSKException ex ) { delete poFeature; CPLError( CE_Failure, CPLE_AppDefined, "%s", ex.what() ); return NULL; } catch(...) { delete poFeature; CPLError( CE_Failure, CPLE_AppDefined, "Non-PCIDSK exception trapped." ); return NULL; } m_nFeaturesRead++; return poFeature; }
OGRErr OGRCreateFromGeomedia( GByte *pabyGeom, OGRGeometry **ppoGeom, int nBytes ) { *ppoGeom = NULL; if( nBytes < 16 ) return OGRERR_FAILURE; if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) ) return OGRERR_FAILURE; int nGeomType = pabyGeom[0]; pabyGeom += 16; nBytes -= 16; if( nGeomType == GEOMEDIA_POINT || nGeomType == GEOMEDIA_ORIENTED_POINT ) { if (nBytes < 3 * 8) return OGRERR_FAILURE; double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); *ppoGeom = new OGRPoint( dfX, dfY, dfZ ); return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_POLYLINE ) { if (nBytes < 4) return OGRERR_FAILURE; int nPoints; memcpy(&nPoints, pabyGeom, 4); CPL_LSBPTR32(&nPoints); pabyGeom += 4; nBytes -= 4; if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24) return OGRERR_FAILURE; OGRLineString* poLS = new OGRLineString(); poLS->setNumPoints(nPoints); int i; for(i=0;i<nPoints;i++) { double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); poLS->setPoint(i, dfX, dfY, dfZ); pabyGeom += 24; } *ppoGeom = poLS; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_POLYGON ) { if (nBytes < 4) return OGRERR_FAILURE; int nPoints; memcpy(&nPoints, pabyGeom, 4); CPL_LSBPTR32(&nPoints); pabyGeom += 4; nBytes -= 4; if (nPoints < 0 || nPoints > INT_MAX / 24 || nBytes < nPoints * 24) return OGRERR_FAILURE; OGRLinearRing* poRing = new OGRLinearRing(); poRing->setNumPoints(nPoints); int i; for(i=0;i<nPoints;i++) { double dfX, dfY, dfZ; memcpy(&dfX, pabyGeom, 8); CPL_LSBPTR64(&dfX); memcpy(&dfY, pabyGeom + 8, 8); CPL_LSBPTR64(&dfY); memcpy(&dfZ, pabyGeom + 16, 8); CPL_LSBPTR64(&dfZ); poRing->setPoint(i, dfX, dfY, dfZ); pabyGeom += 24; } OGRPolygon* poPoly = new OGRPolygon(); poPoly->addRingDirectly(poRing); *ppoGeom = poPoly; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_BOUNDARY ) { if (nBytes < 4) return OGRERR_FAILURE; int nExteriorSize; memcpy(&nExteriorSize, pabyGeom, 4); CPL_LSBPTR32(&nExteriorSize); pabyGeom += 4; nBytes -= 4; if (nBytes < nExteriorSize) return OGRERR_FAILURE; OGRGeometry* poExteriorGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poExteriorGeom, nExteriorSize ) != OGRERR_NONE) return OGRERR_FAILURE; if ( wkbFlatten( poExteriorGeom->getGeometryType() ) != wkbPolygon ) { delete poExteriorGeom; return OGRERR_FAILURE; } pabyGeom += nExteriorSize; nBytes -= nExteriorSize; if (nBytes < 4) { delete poExteriorGeom; return OGRERR_FAILURE; } int nInteriorSize; memcpy(&nInteriorSize, pabyGeom, 4); CPL_LSBPTR32(&nInteriorSize); pabyGeom += 4; nBytes -= 4; if (nBytes < nInteriorSize) { delete poExteriorGeom; return OGRERR_FAILURE; } OGRGeometry* poInteriorGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poInteriorGeom, nInteriorSize ) != OGRERR_NONE) { delete poExteriorGeom; return OGRERR_FAILURE; } OGRwkbGeometryType interiorGeomType = wkbFlatten( poInteriorGeom->getGeometryType() ); if ( interiorGeomType == wkbPolygon ) { ((OGRPolygon*)poExteriorGeom)->addRing(((OGRPolygon*)poInteriorGeom)->getExteriorRing()); } else if ( interiorGeomType == wkbMultiPolygon ) { int numGeom = ((OGRMultiPolygon*)poInteriorGeom)->getNumGeometries(); for ( int i = 0; i < numGeom; ++i ) { OGRPolygon* poInteriorPolygon = (OGRPolygon*)((OGRMultiPolygon*)poInteriorGeom)->getGeometryRef(i); ((OGRPolygon*)poExteriorGeom)->addRing( poInteriorPolygon->getExteriorRing() ); } } else { delete poExteriorGeom; delete poInteriorGeom; return OGRERR_FAILURE; } delete poInteriorGeom; *ppoGeom = poExteriorGeom; return OGRERR_NONE; } else if ( nGeomType == GEOMEDIA_COLLECTION || nGeomType == GEOMEDIA_MULTILINE || nGeomType == GEOMEDIA_MULTIPOLYGON ) { if (nBytes < 4) return OGRERR_FAILURE; int i; int nParts; memcpy(&nParts, pabyGeom, 4); CPL_LSBPTR32(&nParts); pabyGeom += 4; nBytes -= 4; if (nParts < 0 || nParts > INT_MAX / (4 + 16) || nBytes < nParts * (4 + 16)) return OGRERR_FAILURE; /* Can this collection be considered as a multipolyline or multipolygon ? */ if ( nGeomType == GEOMEDIA_COLLECTION ) { GByte* pabyGeomBackup = pabyGeom; int nBytesBackup = nBytes; int bAllPolyline = TRUE; int bAllPolygon = TRUE; for(i=0;i<nParts;i++) { if (nBytes < 4) return OGRERR_FAILURE; int nSubBytes; memcpy(&nSubBytes, pabyGeom, 4); CPL_LSBPTR32(&nSubBytes); if (nSubBytes < 0) { return OGRERR_FAILURE; } pabyGeom += 4; nBytes -= 4; if (nBytes < nSubBytes) { return OGRERR_FAILURE; } if( nSubBytes < 16 ) return OGRERR_FAILURE; if( !(pabyGeom[1] == 0xFF && pabyGeom[2] == 0xD2 && pabyGeom[3] == 0x0F) ) return OGRERR_FAILURE; int nSubGeomType = pabyGeom[0]; if ( nSubGeomType != GEOMEDIA_POLYLINE ) bAllPolyline = FALSE; if ( nSubGeomType != GEOMEDIA_POLYGON ) bAllPolygon = FALSE; pabyGeom += nSubBytes; nBytes -= nSubBytes; } pabyGeom = pabyGeomBackup; nBytes = nBytesBackup; if (bAllPolyline) nGeomType = GEOMEDIA_MULTILINE; else if (bAllPolygon) nGeomType = GEOMEDIA_MULTIPOLYGON; } OGRGeometryCollection* poColl = (nGeomType == GEOMEDIA_MULTILINE) ? new OGRMultiLineString() : (nGeomType == GEOMEDIA_MULTIPOLYGON) ? new OGRMultiPolygon() : new OGRGeometryCollection(); for(i=0;i<nParts;i++) { if (nBytes < 4) return OGRERR_FAILURE; int nSubBytes; memcpy(&nSubBytes, pabyGeom, 4); CPL_LSBPTR32(&nSubBytes); if (nSubBytes < 0) { delete poColl; return OGRERR_FAILURE; } pabyGeom += 4; nBytes -= 4; if (nBytes < nSubBytes) { delete poColl; return OGRERR_FAILURE; } OGRGeometry* poSubGeom = NULL; if (OGRCreateFromGeomedia( pabyGeom, &poSubGeom, nSubBytes ) == OGRERR_NONE) { if (wkbFlatten(poColl->getGeometryType()) == wkbMultiPolygon && wkbFlatten(poSubGeom->getGeometryType()) == wkbLineString) { OGRPolygon* poPoly = new OGRPolygon(); OGRLinearRing* poRing = new OGRLinearRing(); poRing->addSubLineString((OGRLineString*)poSubGeom); poPoly->addRingDirectly(poRing); delete poSubGeom; poSubGeom = poPoly; } if (poColl->addGeometryDirectly(poSubGeom) != OGRERR_NONE) { //printf("%d %d\n", poColl->getGeometryType() & ~wkb25DBit, poSubGeom->getGeometryType() & ~wkb25DBit); delete poSubGeom; } } pabyGeom += nSubBytes; nBytes -= nSubBytes; } *ppoGeom = poColl; return OGRERR_NONE; } else { CPLDebug("GEOMEDIA", "Unhandled type %d", nGeomType); } return OGRERR_FAILURE; }
OGRGeometry *OGRIngresLayer::TranslateGeometry( const char *pszGeom ) { OGRGeometry *poGeom = NULL; /* -------------------------------------------------------------------- */ /* Parse the tuple list into an array of x/y vertices. The */ /* input may look like "(2,3)" or "((2,3),(4,5),...)". Extra */ /* spaces may occur between tokens. */ /* -------------------------------------------------------------------- */ double *padfXY = NULL; int nVertMax = 0; int nVertCount = 0; int nDepth = 0; const char *pszNext = pszGeom; while( *pszNext != '\0' ) { while( *pszNext == ' ' ) pszNext++; if( *pszNext == '(' ) { pszNext++; nDepth++; continue; } if( *pszNext == ')' ) { pszNext++; CPLAssert( nDepth == 1 ); nDepth--; break; } if( *pszNext == ',' ) { pszNext++; CPLAssert( nDepth == 1 ); continue; } if( nVertCount == nVertMax ) { nVertMax = nVertMax * 2 + 1; padfXY = (double *) CPLRealloc(padfXY, sizeof(double) * nVertMax * 2 ); } if( !ParseXY( &pszNext, padfXY + nVertCount*2 ) ) { CPLDebug( "INGRES", "Error parsing geometry: %s", pszGeom ); CPLFree( padfXY ); return NULL; } CPLAssert( *pszNext == ')' ); nVertCount++; pszNext++; nDepth--; while( *pszNext == ' ' ) pszNext++; } CPLAssert( nDepth == 0 ); /* -------------------------------------------------------------------- */ /* Handle Box/IBox. */ /* -------------------------------------------------------------------- */ if( EQUAL(osIngresGeomType,"BOX") || EQUAL(osIngresGeomType,"IBOX") ) { CPLAssert( nVertCount == 2 ); OGRLinearRing *poRing = new OGRLinearRing(); poRing->addPoint( padfXY[0], padfXY[1] ); poRing->addPoint( padfXY[2], padfXY[1] ); poRing->addPoint( padfXY[2], padfXY[3] ); poRing->addPoint( padfXY[0], padfXY[3] ); poRing->addPoint( padfXY[0], padfXY[1] ); OGRPolygon *poPolygon = new OGRPolygon(); poPolygon->addRingDirectly( poRing ); poGeom = poPolygon; } /* -------------------------------------------------------------------- */ /* Handle Point/IPoint */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"POINT") || EQUAL(osIngresGeomType,"IPOINT") ) { CPLAssert( nVertCount == 1 ); poGeom = new OGRPoint( padfXY[0], padfXY[1] ); } /* -------------------------------------------------------------------- */ /* Handle various linestring types. */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"LSEG") || EQUAL(osIngresGeomType,"ILSEG") || EQUAL(osIngresGeomType,"LINE") || EQUAL(osIngresGeomType,"LONG LINE") || EQUAL(osIngresGeomType,"ILINE") ) { OGRLineString *poLine = new OGRLineString(); int iVert; poLine->setNumPoints( nVertCount ); for( iVert = 0; iVert < nVertCount; iVert++ ) poLine->setPoint( iVert, padfXY[iVert*2+0], padfXY[iVert*2+1] ); poGeom = poLine; } /* -------------------------------------------------------------------- */ /* Handle Polygon/IPolygon/LongPolygon. */ /* -------------------------------------------------------------------- */ else if( EQUAL(osIngresGeomType,"POLYGON") || EQUAL(osIngresGeomType,"IPOLYGON") || EQUAL(osIngresGeomType,"LONG POLYGON") ) { OGRLinearRing *poLine = new OGRLinearRing(); int iVert; poLine->setNumPoints( nVertCount ); for( iVert = 0; iVert < nVertCount; iVert++ ) poLine->setPoint( iVert, padfXY[iVert*2+0], padfXY[iVert*2+1] ); // INGRES polygons are implicitly closed, but OGR expects explicit if( poLine->getX(nVertCount-1) != poLine->getX(0) || poLine->getY(nVertCount-1) != poLine->getY(0) ) poLine->addPoint( poLine->getX(0), poLine->getY(0) ); OGRPolygon *poPolygon = new OGRPolygon(); poPolygon->addRingDirectly( poLine ); poGeom = poPolygon; } return poGeom; }
static OGRGeometry *GML2OGRGeometry_XMLNode( CPLXMLNode *psNode ) { const char *pszBaseGeometry = BareGMLElement( psNode->pszValue ); /* -------------------------------------------------------------------- */ /* Polygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"Polygon") ) { CPLXMLNode *psChild; OGRPolygon *poPolygon = new OGRPolygon(); OGRLinearRing *poRing; // Find outer ring. psChild = FindBareXMLChild( psNode, "outerBoundaryIs" ); if( psChild == NULL || psChild->psChild == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing outerBoundaryIs property on Polygon." ); delete poPolygon; return NULL; } // Translate outer ring and add to polygon. poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poRing == NULL ) { delete poPolygon; return NULL; } if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as outerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"innerBoundaryIs") ) { poRing = (OGRLinearRing *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( !EQUAL(poRing->getGeometryName(),"LINEARRING") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as innerBoundaryIs instead of LINEARRING.", poRing->getGeometryName() ); delete poPolygon; delete poRing; return NULL; } poPolygon->addRingDirectly( poRing ); } } return poPolygon; } /* -------------------------------------------------------------------- */ /* LinearRing */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LinearRing") ) { OGRLinearRing *poLinearRing = new OGRLinearRing(); if( !ParseGMLCoordinates( psNode, poLinearRing ) ) { delete poLinearRing; return NULL; } return poLinearRing; } /* -------------------------------------------------------------------- */ /* LineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"LineString") ) { OGRLineString *poLine = new OGRLineString(); if( !ParseGMLCoordinates( psNode, poLine ) ) { delete poLine; return NULL; } return poLine; } /* -------------------------------------------------------------------- */ /* PointType */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"PointType") || EQUAL(pszBaseGeometry,"Point") ) { OGRPoint *poPoint = new OGRPoint(); if( !ParseGMLCoordinates( psNode, poPoint ) ) { delete poPoint; return NULL; } return poPoint; } /* -------------------------------------------------------------------- */ /* Box */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"BoxType") || EQUAL(pszBaseGeometry,"Box") ) { OGRLineString oPoints; if( !ParseGMLCoordinates( psNode, &oPoints ) ) return NULL; if( oPoints.getNumPoints() < 2 ) return NULL; OGRLinearRing *poBoxRing = new OGRLinearRing(); OGRPolygon *poBoxPoly = new OGRPolygon(); poBoxRing->setNumPoints( 5 ); poBoxRing->setPoint( 0, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 1, oPoints.getX(1), oPoints.getY(0), oPoints.getZ(0) ); poBoxRing->setPoint( 2, oPoints.getX(1), oPoints.getY(1), oPoints.getZ(1) ); poBoxRing->setPoint( 3, oPoints.getX(0), oPoints.getY(1), oPoints.getZ(0) ); poBoxRing->setPoint( 4, oPoints.getX(0), oPoints.getY(0), oPoints.getZ(0) ); poBoxPoly->addRingDirectly( poBoxRing ); return poBoxPoly; } /* -------------------------------------------------------------------- */ /* MultiPolygon */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPolygon") ) { CPLXMLNode *psChild; OGRMultiPolygon *poMPoly = new OGRMultiPolygon(); // Find all inner rings for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"polygonMember") ) { OGRPolygon *poPolygon; poPolygon = (OGRPolygon *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPolygon == NULL ) { delete poMPoly; return NULL; } if( !EQUAL(poPolygon->getGeometryName(),"POLYGON") ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as polygonMember instead of MULTIPOLYGON.", poPolygon->getGeometryName() ); delete poPolygon; delete poMPoly; return NULL; } poMPoly->addGeometryDirectly( poPolygon ); } } return poMPoly; } /* -------------------------------------------------------------------- */ /* MultiPoint */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiPoint") ) { CPLXMLNode *psChild; OGRMultiPoint *poMP = new OGRMultiPoint(); // collect points. for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"pointMember") ) { OGRPoint *poPoint; poPoint = (OGRPoint *) GML2OGRGeometry_XMLNode( psChild->psChild ); if( poPoint == NULL || wkbFlatten(poPoint->getGeometryType()) != wkbPoint ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as pointMember instead of MULTIPOINT", poPoint ? poPoint->getGeometryName() : "NULL" ); delete poPoint; delete poMP; return NULL; } poMP->addGeometryDirectly( poPoint ); } } return poMP; } /* -------------------------------------------------------------------- */ /* MultiLineString */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"MultiLineString") ) { CPLXMLNode *psChild; OGRMultiLineString *poMP = new OGRMultiLineString(); // collect lines for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"lineStringMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL || wkbFlatten(poGeom->getGeometryType()) != wkbLineString ) { CPLError( CE_Failure, CPLE_AppDefined, "Got %.500s geometry as Member instead of LINESTRING.", poGeom ? poGeom->getGeometryName() : "NULL" ); delete poGeom; delete poMP; return NULL; } poMP->addGeometryDirectly( poGeom ); } } return poMP; } /* -------------------------------------------------------------------- */ /* GeometryCollection */ /* -------------------------------------------------------------------- */ if( EQUAL(pszBaseGeometry,"GeometryCollection") ) { CPLXMLNode *psChild; OGRGeometryCollection *poGC = new OGRGeometryCollection(); // collect geoms for( psChild = psNode->psChild; psChild != NULL; psChild = psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(BareGMLElement(psChild->pszValue),"geometryMember") ) { OGRGeometry *poGeom; poGeom = GML2OGRGeometry_XMLNode( psChild->psChild ); if( poGeom == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to get geometry in geometryMember" ); delete poGeom; delete poGC; return NULL; } poGC->addGeometryDirectly( poGeom ); } } return poGC; } CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised geometry type <%.500s>.", pszBaseGeometry ); return NULL; }
OGRFeature *OGRDGNLayer::ElementToFeature( DGNElemCore *psElement ) { OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); poFeature->SetFID( psElement->element_id ); poFeature->SetField( "Type", psElement->type ); poFeature->SetField( "Level", psElement->level ); poFeature->SetField( "GraphicGroup", psElement->graphic_group ); poFeature->SetField( "ColorIndex", psElement->color ); poFeature->SetField( "Weight", psElement->weight ); poFeature->SetField( "Style", psElement->style ); m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Collect linkage information */ /* -------------------------------------------------------------------- */ #define MAX_LINK 100 int anEntityNum[MAX_LINK], anMSLink[MAX_LINK]; unsigned char *pabyData; int iLink=0, nLinkCount=0; anEntityNum[0] = 0; anMSLink[0] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+iLink, anMSLink+iLink, NULL ); while( pabyData && nLinkCount < MAX_LINK ) { iLink++; if( anEntityNum[nLinkCount] != 0 || anMSLink[nLinkCount] != 0 ) nLinkCount++; anEntityNum[nLinkCount] = 0; anMSLink[nLinkCount] = 0; pabyData = DGNGetLinkage( hDGN, psElement, iLink, NULL, anEntityNum+nLinkCount, anMSLink+nLinkCount, NULL ); } /* -------------------------------------------------------------------- */ /* Apply attribute linkage to feature. */ /* -------------------------------------------------------------------- */ if( nLinkCount > 0 ) { if( EQUAL(pszLinkFormat,"FIRST") ) { poFeature->SetField( "EntityNum", anEntityNum[0] ); poFeature->SetField( "MSLink", anMSLink[0] ); } else if( EQUAL(pszLinkFormat,"LIST") ) { poFeature->SetField( "EntityNum", nLinkCount, anEntityNum ); poFeature->SetField( "MSLink", nLinkCount, anMSLink ); } else if( EQUAL(pszLinkFormat,"STRING") ) { char szEntityList[MAX_LINK*9], szMSLinkList[MAX_LINK*9]; int nEntityLen = 0, nMSLinkLen = 0; for( iLink = 0; iLink < nLinkCount; iLink++ ) { if( iLink != 0 ) { szEntityList[nEntityLen++] = ','; szMSLinkList[nMSLinkLen++] = ','; } sprintf( szEntityList + nEntityLen, "%d", anEntityNum[iLink]); sprintf( szMSLinkList + nMSLinkLen, "%d", anMSLink[iLink] ); nEntityLen += strlen(szEntityList + nEntityLen ); nMSLinkLen += strlen(szMSLinkList + nMSLinkLen ); } poFeature->SetField( "EntityNum", szEntityList ); poFeature->SetField( "MSLink", szMSLinkList ); } } /* -------------------------------------------------------------------- */ /* Lookup color. */ /* -------------------------------------------------------------------- */ char gv_color[128]; int gv_red, gv_green, gv_blue; char szFSColor[128], szPen[256]; szFSColor[0] = '\0'; if( DGNLookupColor( hDGN, psElement->color, &gv_red, &gv_green, &gv_blue ) ) { sprintf( gv_color, "%f %f %f 1.0", gv_red / 255.0, gv_green / 255.0, gv_blue / 255.0 ); sprintf( szFSColor, "c:#%02x%02x%02x", gv_red, gv_green, gv_blue ); } /* -------------------------------------------------------------------- */ /* Generate corresponding PEN style. */ /* -------------------------------------------------------------------- */ if( psElement->style == DGNS_SOLID ) sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); else if( psElement->style == DGNS_DOTTED ) sprintf( szPen, "PEN(id:\"ogr-pen-5\"" ); else if( psElement->style == DGNS_MEDIUM_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-2\"" ); else if( psElement->style == DGNS_LONG_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-4\"" ); else if( psElement->style == DGNS_DOT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-6\"" ); else if( psElement->style == DGNS_SHORT_DASH ) sprintf( szPen, "PEN(id:\"ogr-pen-3\"" ); else if( psElement->style == DGNS_DASH_DOUBLE_DOT ) sprintf( szPen, "PEN(id:\"ogr-pen-7\"" ); else if( psElement->style == DGNS_LONG_DASH_SHORT_DASH ) sprintf( szPen, "PEN(p:\"10px 5px 4px 5px\"" ); else sprintf( szPen, "PEN(id:\"ogr-pen-0\"" ); if( strlen(szFSColor) > 0 ) sprintf( szPen+strlen(szPen), ",%s", szFSColor ); if( psElement->weight > 1 ) sprintf( szPen+strlen(szPen), ",w:%dpx", psElement->weight ); strcat( szPen, ")" ); switch( psElement->stype ) { case DGNST_MULTIPOINT: if( psElement->type == DGNT_SHAPE ) { OGRLinearRing *poLine = new OGRLinearRing(); OGRPolygon *poPolygon = new OGRPolygon(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poPolygon->addRingDirectly( poLine ); poFeature->SetGeometryDirectly( poPolygon ); ConsiderBrush( psElement, szPen, poFeature ); } else if( psElement->type == DGNT_CURVE ) { DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; OGRLineString *poLine = new OGRLineString(); DGNPoint *pasPoints; int nPoints; nPoints = 5 * psEMP->num_vertices; pasPoints = (DGNPoint *) CPLMalloc(sizeof(DGNPoint) * nPoints); DGNStrokeCurve( hDGN, psEMP, nPoints, pasPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, pasPoints[i].x, pasPoints[i].y, pasPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); CPLFree( pasPoints ); poFeature->SetStyleString( szPen ); } else { OGRLineString *poLine = new OGRLineString(); DGNElemMultiPoint *psEMP = (DGNElemMultiPoint *) psElement; if( psEMP->num_vertices > 0 ) { poLine->setNumPoints( psEMP->num_vertices ); for( int i = 0; i < psEMP->num_vertices; i++ ) { poLine->setPoint( i, psEMP->vertices[i].x, psEMP->vertices[i].y, psEMP->vertices[i].z ); } poFeature->SetGeometryDirectly( poLine ); } poFeature->SetStyleString( szPen ); } break; case DGNST_ARC: { OGRLineString *poLine = new OGRLineString(); DGNElemArc *psArc = (DGNElemArc *) psElement; DGNPoint asPoints[90]; int nPoints; nPoints = (int) (MAX(1,ABS(psArc->sweepang) / 5) + 1); DGNStrokeArc( hDGN, psArc, nPoints, asPoints ); poLine->setNumPoints( nPoints ); for( int i = 0; i < nPoints; i++ ) { poLine->setPoint( i, asPoints[i].x, asPoints[i].y, asPoints[i].z ); } poFeature->SetGeometryDirectly( poLine ); poFeature->SetStyleString( szPen ); } break; case DGNST_TEXT: { OGRPoint *poPoint = new OGRPoint(); DGNElemText *psText = (DGNElemText *) psElement; char *pszOgrFS; poPoint->setX( psText->origin.x ); poPoint->setY( psText->origin.y ); poPoint->setZ( psText->origin.z ); poFeature->SetGeometryDirectly( poPoint ); pszOgrFS = (char *) CPLMalloc(strlen(psText->string) + 150); // setup the basic label. sprintf( pszOgrFS, "LABEL(t:\"%s\"", psText->string ); // set the color if we have it. if( strlen(szFSColor) > 0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",%s", szFSColor ); // Add the size info in ground units. if( ABS(psText->height_mult) >= 6.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%dg", (int) psText->height_mult ); else if( ABS(psText->height_mult) > 0.1 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.3fg", psText->height_mult ); else sprintf( pszOgrFS+strlen(pszOgrFS), ",s:%.12fg", psText->height_mult ); // Add the font name. Name it MstnFont<FONTNUMBER> if not available // in the font list. #3392 static const char *papszFontList[] = { "STANDARD", "WORKING", "FANCY", "ENGINEERING", "NEWZERO", "STENCEL", //0-5 "USTN_FANCY", "COMPRESSED", "STENCEQ", NULL, "hand", "ARCH", //6-11 "ARCHB", NULL, NULL, "IGES1001", "IGES1002", "IGES1003", //12-17 "CENTB", "MICROS", NULL, NULL, "ISOFRACTIONS", "ITALICS", //18-23 "ISO30", NULL, "GREEK", "ISOREC", "Isoeq", NULL, //24-29 "ISO_FONTLEFT", "ISO_FONTRIGHT", "INTL_ENGINEERING", "INTL_WORKING", "ISOITEQ", NULL, //30-35 "USTN FONT 26", NULL, NULL, NULL, NULL, "ARCHITECTURAL", //36-41 "BLOCK_OUTLINE", "LOW_RES_FILLED", NULL, NULL, NULL, NULL, //42-47 NULL, NULL, "UPPERCASE", NULL, NULL, NULL, //48-53 NULL, NULL, NULL, NULL, NULL, NULL, //54-49 "FONT060", "din", "dinit", "helvl", "HELVLIT", "helv", //60-65 "HELVIT", "cent", "CENTIT", "SCRIPT", NULL, NULL, //66-71 NULL, NULL, NULL, NULL, "MICROQ", "dotfont", //72-77 "DOTIT", NULL, NULL, NULL, NULL, NULL, //78-83 NULL, NULL, NULL, NULL, NULL, NULL, //84-89 NULL, NULL, "FONT092", NULL, "FONT094", NULL, //90-95 NULL, NULL, NULL, NULL, "ANSI_SYMBOLS", "FEATURE_CONTROL_SYSMBOLS", //96-101 "SYMB_FAST", NULL, NULL, "INTL_ISO", "INTL_ISO_EQUAL", "INTL_ISO_ITALIC", //102-107 "INTL_ISO_ITALIC_EQUAL" }; //108 if(psText->font_id <= 108 && papszFontList[psText->font_id] != NULL ) { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:%s", papszFontList[psText->font_id] ); } else { sprintf( pszOgrFS+strlen(pszOgrFS), ",f:MstnFont%d", psText->font_id ); } // Add the angle, if not horizontal if( psText->rotation != 0.0 ) sprintf( pszOgrFS+strlen(pszOgrFS), ",a:%d", (int) (psText->rotation+0.5) ); strcat( pszOgrFS, ")" ); poFeature->SetStyleString( pszOgrFS ); CPLFree( pszOgrFS ); poFeature->SetField( "Text", psText->string ); } break; case DGNST_COMPLEX_HEADER: { DGNElemComplexHeader *psHdr = (DGNElemComplexHeader *) psElement; int iChild; OGRMultiLineString oChildren; /* collect subsequent child geometries. */ // we should disable the spatial filter ... add later. for( iChild = 0; iChild < psHdr->numelems; iChild++ ) { OGRFeature *poChildFeature = NULL; DGNElemCore *psChildElement; psChildElement = DGNReadElement( hDGN ); // should verify complex bit set, not another header. if( psChildElement != NULL ) { poChildFeature = ElementToFeature( psChildElement ); DGNFreeElement( hDGN, psChildElement ); } if( poChildFeature != NULL && poChildFeature->GetGeometryRef() != NULL ) { OGRGeometry *poGeom; poGeom = poChildFeature->GetGeometryRef(); if( wkbFlatten(poGeom->getGeometryType()) == wkbLineString ) oChildren.addGeometry( poGeom ); } if( poChildFeature != NULL ) delete poChildFeature; } // Try to assemble into polygon geometry. OGRGeometry *poGeom; if( psElement->type == DGNT_COMPLEX_SHAPE_HEADER ) poGeom = (OGRPolygon *) OGRBuildPolygonFromEdges( (OGRGeometryH) &oChildren, TRUE, TRUE, 100000, NULL ); else poGeom = oChildren.clone(); if( poGeom != NULL ) poFeature->SetGeometryDirectly( poGeom ); ConsiderBrush( psElement, szPen, poFeature ); } break; default: break; } /* -------------------------------------------------------------------- */ /* Fixup geometry dimension. */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL ) poFeature->GetGeometryRef()->setCoordinateDimension( DGNGetDimension( hDGN ) ); return poFeature; }