예제 #1
0
OGRGeometry *OGRGeometryFactory::forceToMultiPolygon( OGRGeometry *poGeom )

{
    if( poGeom == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Check for the case of a geometrycollection that can be          */
/*      promoted to MultiPolygon.                                       */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) == wkbGeometryCollection )
    {
        int iGeom;
        int bAllPoly = TRUE;
        OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeom;

        for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ )
        {
            if( wkbFlatten(poGC->getGeometryRef(iGeom)->getGeometryType())
                != wkbPolygon )
                bAllPoly = FALSE;
        }

        if( !bAllPoly )
            return poGeom;
        
        OGRMultiPolygon *poMP = new OGRMultiPolygon();

        while( poGC->getNumGeometries() > 0 )
        {
            poMP->addGeometryDirectly( poGC->getGeometryRef(0) );
            poGC->removeGeometry( 0, FALSE );
        }

        delete poGC;

        return poMP;
    }

/* -------------------------------------------------------------------- */
/*      Eventually we should try to split the polygon into component    */
/*      island polygons.  But thats alot of work and can be put off.    */
/* -------------------------------------------------------------------- */
    if( wkbFlatten(poGeom->getGeometryType()) != wkbPolygon )
        return poGeom;

    OGRMultiPolygon *poMP = new OGRMultiPolygon();
    poMP->addGeometryDirectly( poGeom );

    return poMP;
}
예제 #2
0
 OGRMultiPolygon* make()
 {
     OGRMultiPolygon* poCollection = new OGRMultiPolygon();
     
     poCollection->addGeometryDirectly(make<OGRPolygon>());
     
     return poCollection;
 }
예제 #3
0
OGRMultiPolygon* OGRMSSQLGeometryParser::ReadMultiPolygon(int iShape)
{
    int i;
    OGRMultiPolygon* poMultiPolygon = new OGRMultiPolygon();
    OGRGeometry* poGeom;

    for (i = iShape + 1; i < nNumShapes; i++)
    {
        poGeom = NULL;
        if (ParentOffset(i) == (unsigned int)iShape)
        {
            if ( ShapeType(i) == ST_POLYGON )
                poGeom = ReadPolygon(i);
        }
        if ( poGeom )
            poMultiPolygon->addGeometryDirectly( poGeom );
    }

    return poMultiPolygon;
}
예제 #4
0
OGRFeature *    OGRBNALayer::BuildFeatureFromBNARecord (BNARecord* record, long fid)
{
    OGRFeature  *poFeature;
    int i;

    poFeature = new OGRFeature( poFeatureDefn );
    for(i=0;i<nIDs;i++)
    {
        poFeature->SetField( i, record->ids[i] ? record->ids[i] : "");
    }
    poFeature->SetFID( fid );
    if (bnaFeatureType == BNA_POINT)
    {
        poFeature->SetGeometryDirectly( new OGRPoint( record->tabCoords[0][0], record->tabCoords[0][1] ) );
    }
    else if (bnaFeatureType == BNA_POLYLINE)
    {
        OGRLineString* lineString = new OGRLineString ();
        lineString->setCoordinateDimension(2);
        lineString->setNumPoints(record->nCoords);
        for(i=0;i<record->nCoords;i++)
        {
            lineString->setPoint(i, record->tabCoords[i][0], record->tabCoords[i][1] );
        }
        poFeature->SetGeometryDirectly(lineString);
    }
    else if (bnaFeatureType == BNA_POLYGON)
    {
        double firstX = record->tabCoords[0][0];
        double firstY = record->tabCoords[0][1];
        int isFirstPolygon = 1;
        double secondaryFirstX = 0, secondaryFirstY = 0;
  
        OGRLinearRing* ring = new OGRLinearRing ();
        ring->setCoordinateDimension(2);
        ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] );
  
        /* record->nCoords is really a safe upper bound */
        int nbPolygons = 0;
        OGRPolygon** tabPolygons =
            (OGRPolygon**)CPLMalloc(record->nCoords * sizeof(OGRPolygon*));

        for(i=1;i<record->nCoords;i++)
        {
            ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] );
            if (isFirstPolygon == 1 &&
                record->tabCoords[i][0] == firstX &&
                record->tabCoords[i][1] == firstY)
            {
                OGRPolygon* polygon = new OGRPolygon ();
                polygon->addRingDirectly(ring);
                tabPolygons[nbPolygons] = polygon;
                nbPolygons++;
    
                if (i == record->nCoords - 1)
                {
                    break;
                }
    
                isFirstPolygon = 0;
    
                i ++;
                secondaryFirstX = record->tabCoords[i][0];
                secondaryFirstY = record->tabCoords[i][1];
                ring = new OGRLinearRing ();
                ring->setCoordinateDimension(2);
                ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] );
            }
            else if (isFirstPolygon == 0 &&
                    record->tabCoords[i][0] == secondaryFirstX &&
                    record->tabCoords[i][1] == secondaryFirstY)
            {

                OGRPolygon* polygon = new OGRPolygon ();
                polygon->addRingDirectly(ring);
                tabPolygons[nbPolygons] = polygon;
                nbPolygons++;

                if (i < record->nCoords - 1)
                {
                    /* After the closing of a subpolygon, the first coordinates of the first polygon */
                    /* should be recalled... in theory */
                    if (record->tabCoords[i+1][0] == firstX &&  record->tabCoords[i+1][1] == firstY)
                    {
                        if (i + 1 == record->nCoords - 1)
                            break;
                        i ++;
                    }
                    else
                    {
#if 0
                        CPLError(CE_Warning, CPLE_AppDefined, 
                                 "Geometry of polygon of fid %d starting at line %d is not strictly conformant. "
                                 "Trying to go on...\n",
                                 fid,
                                 offsetAndLineFeaturesTable[fid].line + 1);
#endif
                    }

                    i ++;
                    secondaryFirstX = record->tabCoords[i][0];
                    secondaryFirstY = record->tabCoords[i][1];
                    ring = new OGRLinearRing ();
                    ring->setCoordinateDimension(2);
                    ring->addPoint(record->tabCoords[i][0], record->tabCoords[i][1] );
                }
                else
                {
#if 0
                    CPLError(CE_Warning, CPLE_AppDefined, 
                        "Geometry of polygon of fid %d starting at line %d is not strictly conformant. Trying to go on...\n",
                        fid,
                        offsetAndLineFeaturesTable[fid].line + 1);
#endif
                }
            }
        }
        if (i == record->nCoords)
        {
            /* Let's be a bit tolerant abount non closing polygons */
            if (isFirstPolygon)
            {
                ring->addPoint(record->tabCoords[0][0], record->tabCoords[0][1] );

                OGRPolygon* polygon = new OGRPolygon ();
                polygon->addRingDirectly(ring);
                tabPolygons[nbPolygons] = polygon;
                nbPolygons++;
            }
        }
        
        if (nbPolygons == 1)
        {
            /* Special optimization here : we directly put the polygon into the multipolygon. */
            /* This should save quite a few useless copies */
            OGRMultiPolygon* multipolygon = new OGRMultiPolygon();
            multipolygon->addGeometryDirectly(tabPolygons[0]);
            poFeature->SetGeometryDirectly(multipolygon);
        }
        else
        {
            int isValidGeometry;
            poFeature->SetGeometryDirectly(
                OGRGeometryFactory::organizePolygons((OGRGeometry**)tabPolygons, nbPolygons, &isValidGeometry, NULL));
            
            if (!isValidGeometry)
            {
                CPLError(CE_Warning, CPLE_AppDefined, 
                        "Geometry of polygon of fid %ld starting at line %d cannot be translated to Simple Geometry. "
                        "All polygons will be contained in a multipolygon.\n",
                        fid,
                        offsetAndLineFeaturesTable[fid].line + 1);
            }
        }

        CPLFree(tabPolygons);
    }
    else
    {
        /* Circle or ellipses are not part of the OGR Simple Geometry, so we discretize them
           into polygons by 1 degree step */
        OGRPolygon* polygon = new OGRPolygon ();
        OGRLinearRing* ring = new OGRLinearRing ();
        ring->setCoordinateDimension(2);
        double center_x = record->tabCoords[0][0];
        double center_y = record->tabCoords[0][1];
        double major_radius = record->tabCoords[1][0];
        double minor_radius = record->tabCoords[1][1];
        if (minor_radius == 0)
            minor_radius = major_radius;
        for(i=0;i<360;i++)
        {
            ring->addPoint(center_x + major_radius * cos(i * (M_PI / 180)),
                           center_y + minor_radius * sin(i * (M_PI / 180)) );
        }
        ring->addPoint(center_x + major_radius, center_y);
        polygon->addRingDirectly  (  ring );
        poFeature->SetGeometryDirectly(polygon);

        poFeature->SetField( nIDs, major_radius);
        poFeature->SetField( nIDs+1, minor_radius);
    }
    
    return poFeature;
}
예제 #5
0
OGRFeature* OGRPLScenesLayer::GetNextRawFeature()
{
    if( bEOF ||
        (!bFilterMustBeClientSideEvaluated && nFeatureCount >= 0 && nNextFID > nFeatureCount) )
        return NULL;

    if( poGeoJSONLayer == NULL )
    {
        if( !GetNextPage() )
            return NULL;
    }

#ifdef notdef
    if( CSLTestBoolean(CPLGetConfigOption("OGR_LIMIT_TOO_MANY_FEATURES", "FALSE")) &&
        nFeatureCount > nPageSize )
    {
        bEOF = TRUE;
        OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
        OGRGeometry* poGeom;
        const char* pszWKT = "MULTIPOLYGON(((-180 90,180 90,180 -90,-180 -90,-180 90)))";
        OGRGeometryFactory::createFromWkt((char**)&pszWKT, poSRS, &poGeom);
        poFeature->SetGeometryDirectly(poGeom);
        return poFeature;
    }
#endif

    OGRFeature* poGeoJSONFeature = poGeoJSONLayer->GetNextFeature();
    if( poGeoJSONFeature == NULL )
    {
        osRequestURL = osNextURL;
        bStillInFirstPage = FALSE;
        if( !GetNextPage() )
            return NULL;
        poGeoJSONFeature = poGeoJSONLayer->GetNextFeature();
        if( poGeoJSONFeature == NULL )
        {
            bEOF = TRUE;
            return NULL;
        }
    }
    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    poFeature->SetFID(nNextFID++);

    OGRGeometry* poGeom = poGeoJSONFeature->StealGeometry();
    if( poGeom != NULL )
    {
        if( poGeom->getGeometryType() == wkbPolygon )
        {
            OGRMultiPolygon* poMP = new OGRMultiPolygon();
            poMP->addGeometryDirectly(poGeom);
            poGeom = poMP;
        }
        poGeom->assignSpatialReference(poSRS);
        poFeature->SetGeometryDirectly(poGeom);
    }
    
    for(int i=0;i<poFeatureDefn->GetFieldCount();i++)
    {
        OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
        OGRFieldType eType = poFieldDefn->GetType();
        int iSrcField = poGeoJSONFeature->GetFieldIndex(poFieldDefn->GetNameRef());
        if( iSrcField >= 0 && poGeoJSONFeature->IsFieldSet(iSrcField) )
        {
            if( eType == OFTInteger )
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsInteger(iSrcField));
            else if( eType == OFTReal )
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsDouble(iSrcField));
            else
                poFeature->SetField(i,
                    poGeoJSONFeature->GetFieldAsString(iSrcField));
        }
    }

    delete poGeoJSONFeature;

    return poFeature;
}
예제 #6
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;
}
예제 #7
0
OGRFeature *OGRGmtLayer::GetNextRawFeature()

{
#if 0
    int bMultiVertex =
        poFeatureDefn->GetGeomType() != wkbPoint
        && poFeatureDefn->GetGeomType() != wkbUnknown;
#endif
    CPLString osFieldData;
    OGRGeometry *poGeom = NULL;

/* -------------------------------------------------------------------- */
/*      Read lines associated with this feature.                        */
/* -------------------------------------------------------------------- */
    for( ; true; ReadLine() )
    {
        if( osLine.length() == 0 )
            break;

        if( osLine[0] == '>' )
        {
            if( poGeom != NULL
                && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon )
            {
                OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                if( ScanAheadForHole() )
                {
                    // Add a hole to the current polygon.
                    ((OGRPolygon *) poMP->getGeometryRef(
                        poMP->getNumGeometries()-1 ))->
                        addRingDirectly( new OGRLinearRing() );
                }
                else if( !NextIsFeature() )
                {
                    OGRPolygon *poPoly = new OGRPolygon();

                    poPoly->addRingDirectly( new OGRLinearRing() );

                    poMP->addGeometryDirectly( poPoly );
                }
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon)
            {
                if( ScanAheadForHole() )
                    ((OGRPolygon *)poGeom)->
                        addRingDirectly( new OGRLinearRing() );
                else
                    break; /* done geometry */
            }
            else if( poGeom != NULL
                     && (wkbFlatten(poGeom->getGeometryType())
                         == wkbMultiLineString)
                     && !NextIsFeature() )
            {
                ((OGRMultiLineString *) poGeom)->
                    addGeometryDirectly( new OGRLineString() );
            }
            else if( poGeom != NULL )
            {
                break;
            }
            else if( poFeatureDefn->GetGeomType() == wkbUnknown )
            {
                poFeatureDefn->SetGeomType( wkbLineString );
                /* bMultiVertex = TRUE; */
            }
        }
        else if( osLine[0] == '#' )
        {
            for( int i = 0;
                 papszKeyedValues != NULL && papszKeyedValues[i] != NULL;
                 i++ )
            {
                if( papszKeyedValues[i][0] == 'D' )
                    osFieldData = papszKeyedValues[i] + 1;
            }
        }
        else
        {
            // Parse point line.
            double dfX;
            double dfY;
            double dfZ = 0.0;
            const int nDim
                = CPLsscanf( osLine, "%lf %lf %lf", &dfX, &dfY, &dfZ );

            if( nDim >= 2 )
            {
                if( poGeom == NULL )
                {
                    switch( poFeatureDefn->GetGeomType() )
                    {
                      case wkbLineString:
                        poGeom = new OGRLineString();
                        break;

                      case wkbPolygon:
                        poGeom = new OGRPolygon();
                        reinterpret_cast<OGRPolygon *>(poGeom)->addRingDirectly(
                            new OGRLinearRing() );
                        break;

                      case wkbMultiPolygon:
                      {
                          OGRPolygon *poPoly = new OGRPolygon();
                          poPoly->addRingDirectly( new OGRLinearRing() );

                          poGeom = new OGRMultiPolygon();
                          reinterpret_cast<OGRMultiPolygon *>(poGeom)->
                              addGeometryDirectly( poPoly );
                      }
                      break;

                      case wkbMultiPoint:
                        poGeom = new OGRMultiPoint();
                        break;

                      case wkbMultiLineString:
                        poGeom = new OGRMultiLineString();
                        reinterpret_cast<OGRMultiLineString *>(poGeom)->
                            addGeometryDirectly(new OGRLineString() );
                        break;

                      case wkbPoint:
                      case wkbUnknown:
                      default:
                        poGeom = new OGRPoint();
                        break;
                    }

                }

                switch( wkbFlatten(poGeom->getGeometryType()) )
                {
                  case wkbPoint:
                    reinterpret_cast<OGRPoint *>(poGeom)->setX( dfX );
                    reinterpret_cast<OGRPoint *>(poGeom)->setY( dfY );
                    if( nDim == 3 )
                        reinterpret_cast<OGRPoint *>(poGeom)->setZ( dfZ );
                    break;

                  case wkbLineString:
                    if( nDim == 3 )
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY, dfZ);
                    else
                        reinterpret_cast<OGRLineString *>(poGeom)->
                            addPoint( dfX, dfY );
                    break;

                  case wkbPolygon:
                  case wkbMultiPolygon:
                  {
                      OGRPolygon *poPoly = NULL;

                      if( wkbFlatten(poGeom->getGeometryType())
                          == wkbMultiPolygon )
                      {
                          OGRMultiPolygon *poMP = (OGRMultiPolygon *) poGeom;
                          poPoly = (OGRPolygon*) poMP->getGeometryRef(
                              poMP->getNumGeometries() - 1 );
                      }
                      else
                          poPoly = reinterpret_cast<OGRPolygon *>(poGeom);

                      OGRLinearRing *poRing = NULL;
                      if( poPoly->getNumInteriorRings() == 0 )
                          poRing = poPoly->getExteriorRing();
                      else
                          poRing = poPoly->getInteriorRing(
                              poPoly->getNumInteriorRings()-1 );

                      if( nDim == 3 )
                          poRing->addPoint( dfX, dfY, dfZ );
                      else
                          poRing->addPoint( dfX, dfY );
                  }
                  break;

                  case wkbMultiLineString:
                  {
                      OGRMultiLineString *poML = (OGRMultiLineString *) poGeom;
                      OGRLineString *poLine = reinterpret_cast<OGRLineString *>(
                          poML->getGeometryRef( poML->getNumGeometries() -1 ) );

                      if( nDim == 3 )
                          poLine->addPoint( dfX, dfY, dfZ );
                      else
                          poLine->addPoint( dfX, dfY );
                  }
                  break;

                  default:
                    CPLAssert( FALSE );
                }
            }
        }

        if( poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )
        {
            ReadLine();
            break;
        }
    }

    if( poGeom == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create feature.                                                 */
/* -------------------------------------------------------------------- */
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
    poGeom->assignSpatialReference(poSRS);
    poFeature->SetGeometryDirectly( poGeom );
    poFeature->SetFID( iNextFID++ );

/* -------------------------------------------------------------------- */
/*      Process field values.                                           */
/* -------------------------------------------------------------------- */
    char **papszFD = CSLTokenizeStringComplex( osFieldData, "|", TRUE, TRUE );

    for( int iField = 0; papszFD != NULL && papszFD[iField] != NULL; iField++ )
    {
        if( iField >= poFeatureDefn->GetFieldCount() )
            break;

        poFeature->SetField( iField, papszFD[iField] );
    }

    CSLDestroy( papszFD );

    m_nFeaturesRead++;

    return poFeature;
}