ogrfmedatasource.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,716 行 · 第 1/5 页

CPP
1,716
字号
        OGRFMELayer     *poNewLayer = NULL;        if( bUseCaching )            poNewLayer = new OGRFMELayerCached( this );        else            poNewLayer = new OGRFMELayerDB( this, pszReaderName, pszDataset,                                            poUserDirectives );        if( !poNewLayer->Initialize( poFMEFeature, poSRS ) )        {            CPLDebug( kPROVIDERNAME, "%p:Initialize() failed.", this );            delete poNewLayer;            ReleaseSession();            return FALSE;        }        papoLayers = (OGRFMELayer **)            CPLRealloc(papoLayers, sizeof(void*) * ++nLayers );        papoLayers[nLayers-1] = poNewLayer;    }    poSession->destroyStringArray( poParms );    if( poSRS != NULL )        poSRS->Release();    CPLDebug( kPROVIDERNAME, "%p:schema read.", this );/* -------------------------------------------------------------------- *//*      Do we want to build our own index/caches for each layer?        *//* -------------------------------------------------------------------- */    if( bUseCaching )        BuildSpatialIndexes();    CPLDebug( kPROVIDERNAME, "%p:Open() successful.", this );    ReleaseSession();/* -------------------------------------------------------------------- *//*      If we are caching, add this cache to the cache index.           *//* -------------------------------------------------------------------- */#ifdef SUPPORT_PERSISTENT_CACHE    if( bUseCaching && oCacheIndex.Lock() && oCacheIndex.Load() )    {        CPLXMLNode *psXML = SerializeToXML();        oCacheIndex.Add( psXML  ); // cache index takes ownership of tree        oCacheIndex.Reference( psXML );        oCacheIndex.Save();        oCacheIndex.Unlock();    }#endif    return TRUE;}/************************************************************************//*                              GetLayer()                              *//************************************************************************/OGRLayer *OGRFMEDataSource::GetLayer( int iLayer ){    if( iLayer < 0 || iLayer >= nLayers )        return NULL;    else        return papoLayers[iLayer];}/************************************************************************//*                        BuildSpatialIndexes()                         *//*                                                                      *//*      Import all the features, building per-layer spatial             *//*      caches with indexing.                                           *//************************************************************************/void OGRFMEDataSource::BuildSpatialIndexes(){    CacheLayerInfo     *pasCLI;    int                iLayer;    pasCLI = (CacheLayerInfo *) CPLCalloc(sizeof(CacheLayerInfo),nLayers);/* -------------------------------------------------------------------- *//*      Create index files with "temp file" names.                      *//* -------------------------------------------------------------------- */    for( iLayer = 0; iLayer < nLayers; iLayer++ )    {        CacheLayerInfo *psCLI = pasCLI + iLayer;        psCLI->pszCoordSys = NULL;        psCLI->pszIndFile =             BuildTmpNam( papoLayers[iLayer]->GetLayerDefn()->GetName() );        psCLI->poIndex =             poSession->createSpatialIndex( psCLI->pszIndFile, "WRITE", NULL );                if( psCLI->poIndex == NULL || psCLI->poIndex->open() != 0 )        {            CPLDebug( kPROVIDERNAME,                       "Serious error creating or opening spatial index ... bailing." );            return;        }        // our special marker meaning unset.        psCLI->eBestGeomType = (OGRwkbGeometryType) 500;     }/* -------------------------------------------------------------------- *//*      Read all features, and store them into appropriate spatial      *//*      indexes.                                                        *//* -------------------------------------------------------------------- */    while( ReadFMEFeature() )    {        CacheLayerInfo *psCLI = NULL;        poFMEFeature->getFeatureType( *poFMEString );                for( iLayer = 0; iLayer < nLayers; iLayer++ )        {            if( EQUAL(papoLayers[iLayer]->GetLayerDefn()->GetName(),                      poFMEString->data()) )            {                psCLI = pasCLI + iLayer;                break;            }        }                if( psCLI == NULL )        {            CPLDebug( "FME_LOG",                       "Skipping %s feature, doesn't match a layer.",                       poFMEString->data() );            continue;        }        psCLI->poIndex->store( *poFMEFeature );        // Aggregate to extents.        FME_Real64  dfMinX, dfMaxX, dfMinY, dfMaxY;        poFMEFeature->boundingBox( dfMinX, dfMaxX, dfMinY, dfMaxY );                if( psCLI->poIndex->entries() == 1 )        {            psCLI->sExtent.MinX = dfMinX;            psCLI->sExtent.MaxX = dfMaxX;            psCLI->sExtent.MinY = dfMinY;            psCLI->sExtent.MaxY = dfMaxY;        }        else        {            psCLI->sExtent.MinX = MIN(psCLI->sExtent.MinX,dfMinX);            psCLI->sExtent.MaxX = MAX(psCLI->sExtent.MaxX,dfMaxX);            psCLI->sExtent.MinY = MIN(psCLI->sExtent.MinY,dfMinY);            psCLI->sExtent.MaxY = MAX(psCLI->sExtent.MaxY,dfMaxY);        }        // Update best geometry type to use based on this geometry.        ClarifyGeometryClass( poFMEFeature, psCLI->eBestGeomType );        // Check on coordsys.        if( poFMEFeature->getCoordSys() != NULL            && strlen(poFMEFeature->getCoordSys()) > 0 )        {            if( psCLI->pszCoordSys == NULL )                psCLI->pszCoordSys = CPLStrdup(poFMEFeature->getCoordSys());            else            {                if( !EQUAL(psCLI->pszCoordSys,poFMEFeature->getCoordSys()) )                    CPLDebug( "FME_OLEDB",                               "Conflicting coordsys %s (vs. %s) on layer %s.",                              poFMEFeature->getCoordSys(),                               psCLI->pszCoordSys,                               papoLayers[iLayer]->GetLayerDefn()->GetName() );            }        }    }/* -------------------------------------------------------------------- *//*      Close indexes and assign to layers.                             *//* -------------------------------------------------------------------- */    for( iLayer = 0; iLayer < nLayers; iLayer++ )    {        OGRFMELayerCached * poLayer = (OGRFMELayerCached *) papoLayers[iLayer];        CacheLayerInfo *psCLI = pasCLI + iLayer;        // If there are no features, we destroy the layer.        if( psCLI->poIndex->entries() == 0 )        {            CPLDebug( "FME_LOG", "Drop layer %s, there are not features.",                      poLayer->GetLayerDefn()->GetName() );            psCLI->poIndex->close(FME_TRUE);            delete poLayer;            papoLayers[iLayer] = NULL;        }        else        {            OGRSpatialReference *poSpatialRef = NULL;            psCLI->poIndex->close(FME_FALSE);            poSession->destroySpatialIndex( psCLI->poIndex );                        if( psCLI->pszCoordSys != NULL && !bCoordSysOverride )            {                CPLDebug("FME_OLEDB",                          "Applying COORDSYS=%s to layer %s from feature scan.",                         psCLI->pszCoordSys,                          papoLayers[iLayer]->GetLayerDefn()->GetName() );                                       poSpatialRef = FME2OGRSpatialRef( psCLI->pszCoordSys );            }            poLayer->AssignIndex( psCLI->pszIndFile, &(psCLI->sExtent),                                  poSpatialRef );            if( psCLI->eBestGeomType != 500                 && psCLI->eBestGeomType                          != poLayer->GetLayerDefn()->GetGeomType() )            {                CPLDebug( "FME_LOG", "Setting geom type from %d to %d",                           poLayer->GetLayerDefn()->GetGeomType(),                          psCLI->eBestGeomType );                                          poLayer->GetLayerDefn()->SetGeomType( psCLI->eBestGeomType );            }        }                    CPLFree( psCLI->pszIndFile );        CPLFree( psCLI->pszCoordSys );    }    CPLFree( pasCLI );/* -------------------------------------------------------------------- *//*      Compress missing layers from the layer list.                    *//* -------------------------------------------------------------------- */    for( iLayer = 0; iLayer < nLayers; iLayer++ )    {        if( papoLayers[iLayer] == NULL )        {            papoLayers[iLayer] = papoLayers[nLayers-1];            nLayers--;            iLayer--;        }    }}/************************************************************************//*                        ClarifyGeometryClass()                        *//*                                                                      *//*      Examine an FME features geometry, and ensure the wkb            *//*      geometry type we are using will include it.  That is, we        *//*      generally make the geometry type sufficiently general to        *//*      include the type of geometry of this feature.                   *//*                                                                      *//*      Exceptions are when the existing type is unknown, in which      *//*      case we assign it the type of the geometry we find, and if      *//*      it is a mixture of polygon and multipolygon in which case we    *//*      use multipolygon with the understanding that we will force      *//*      the polygons to multipolygon.                                   *//************************************************************************/void OGRFMEDataSource::ClarifyGeometryClass(     IFMEFeature *poFeature,    OGRwkbGeometryType &eBestGeomType ){    FME_GeometryType      eFMEType = poFeature->getGeometryType();    OGRwkbGeometryType    eThisType;/* -------------------------------------------------------------------- *//*      Classify this FME geometry.  The hard case is aggregate.        *//* -------------------------------------------------------------------- */    if( eFMEType == FME_GEOM_POINT )        eThisType = wkbPoint;    else if( eFMEType == FME_GEOM_LINE )        eThisType = wkbLineString;    else if( eFMEType == FME_GEOM_POLYGON || eFMEType == FME_GEOM_DONUT )        eThisType = wkbPolygon;    else if( eFMEType == FME_GEOM_AGGREGATE )    {        // This is the hard case!  Split the aggregate to see if we can        // categorize it more specifically.        OGRwkbGeometryType eComponentType = (OGRwkbGeometryType) 500;        IFMEFeatureVector *poFeatVector;        poFeatVector = poSession->createFeatureVector();                poFeature->splitAggregate( *poFeatVector );                for( int iPart = 0; iPart < (int)poFeatVector->entries(); iPart++ )        {            IFMEFeature      *poFMEPart = (*poFeatVector)(iPart);            if( poFMEPart != NULL )                ClarifyGeometryClass( poFMEPart, eComponentType );        }        poSession->destroyFeatureVector( poFeatVector );        if( wkbFlatten(eComponentType) == wkbPolygon )            eThisType = wkbMultiPolygon;        else if( wkbFlatten(eComponentType) == wkbPoint )            eThisType = wkbMultiPoint;        else if( wkbFlatten(eComponentType) == wkbLineString )            eThisType = wkbMultiLineString;        else            eThisType = wkbGeometryCollection;    }    else         eThisType = wkbUnknown;    // Is this 3D?    if( poFeature->getDimension() == FME_THREE_D )        eThisType = (OGRwkbGeometryType) (eThisType | wkb25DBit);    /* -------------------------------------------------------------------- *//*      Now adjust the working type.                                    *//* -------------------------------------------------------------------- */    OGRwkbGeometryType eNewBestGeomType = eBestGeomType;    if( eBestGeomType == 500 )        eNewBestGeomType = eThisType;    else if( eThisType == wkbNone )        /* do nothing */;    else if( wkbFlatten(eThisType) == wkbFlatten(eBestGeomType) )        /* no change */;    else if( wkbFlatten(eThisType) == wkbPolygon              && wkbFlatten(eBestGeomType) == wkbMultiPolygon )        /* do nothing */;    else if( wkbFlatten(eThisType) == wkbMultiPolygon              && wkbFlatten(eBestGeomType) == wkbPolygon )        eNewBestGeomType = wkbMultiPolygon;    else if( wkbFlatten(eThisType) >= 4 && wkbFlatten(eThisType) <= 7           && wkbFlatten(eBestGeomType) >= 4 && wkbFlatten(eBestGeomType) <= 7 )        /* they are both collections, but not the same ... go to generic coll*/        eNewBestGeomType = wkbGeometryCollection;    else        eNewBestGeomType = wkbUnknown;    if( ((eBestGeomType & wkb25DBit) || (eThisType & wkb25DBit)) 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?