Example #1
0
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;
}
Example #2
0
    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);
    }
Example #3
0
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;
}
Example #4
0
/**********************************************************************
 *                          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;
}
Example #5
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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;
}