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 + -
显示快捷键?