📄 ogrshapelayer.cpp
字号:
&& eRequestedGeomType == wkbUnknown && poFeature->GetGeometryRef() != NULL ) { OGRGeometry *poGeom = poFeature->GetGeometryRef(); int nShapeType; switch( poGeom->getGeometryType() ) { case wkbPoint: nShapeType = SHPT_POINT; eRequestedGeomType = wkbPoint; break; case wkbPoint25D: nShapeType = SHPT_POINTZ; eRequestedGeomType = wkbPoint25D; break; case wkbMultiPoint: nShapeType = SHPT_MULTIPOINT; eRequestedGeomType = wkbMultiPoint; break; case wkbMultiPoint25D: nShapeType = SHPT_MULTIPOINTZ; eRequestedGeomType = wkbMultiPoint25D; break; case wkbLineString: nShapeType = SHPT_ARC; eRequestedGeomType = wkbLineString; break; case wkbLineString25D: nShapeType = SHPT_ARCZ; eRequestedGeomType = wkbLineString25D; break; case wkbPolygon: case wkbMultiPolygon: nShapeType = SHPT_POLYGON; eRequestedGeomType = wkbPolygon; break; case wkbPolygon25D: case wkbMultiPolygon25D: nShapeType = SHPT_POLYGONZ; eRequestedGeomType = wkbPolygon25D; break; default: nShapeType = -1; break; } if( nShapeType != -1 ) { ResetGeomType( nShapeType ); } } eErr = SHPWriteOGRFeature( hSHP, hDBF, poFeatureDefn, poFeature ); if( hSHP != NULL ) nTotalShapeCount = hSHP->nRecords; else nTotalShapeCount = hDBF->nRecords; return eErr;}/************************************************************************//* GetFeatureCount() *//* *//* If a spatial filter is in effect, we turn control over to *//* the generic counter. Otherwise we return the total count. *//* Eventually we should consider implementing a more efficient *//* way of counting features matching a spatial query. *//************************************************************************/int OGRShapeLayer::GetFeatureCount( int bForce ){ if( m_poFilterGeom != NULL || m_poAttrQuery != NULL ) return OGRLayer::GetFeatureCount( bForce ); else return nTotalShapeCount;}/************************************************************************//* GetExtent() *//* *//* Fetch extent of the data currently stored in the dataset. *//* The bForce flag has no effect on SHO files since that value *//* is always in the header. *//* *//* Returns OGRERR_NONE/OGRRERR_FAILURE. *//************************************************************************/OGRErr OGRShapeLayer::GetExtent (OGREnvelope *psExtent, int bForce){ double adMin[4], adMax[4]; if( hSHP == NULL ) return OGRERR_FAILURE; SHPGetInfo(hSHP, NULL, NULL, adMin, adMax); psExtent->MinX = adMin[0]; psExtent->MinY = adMin[1]; psExtent->MaxX = adMax[0]; psExtent->MaxY = adMax[1]; return OGRERR_NONE;}/************************************************************************//* TestCapability() *//************************************************************************/int OGRShapeLayer::TestCapability( const char * pszCap ){ if( EQUAL(pszCap,OLCRandomRead) ) return TRUE; else if( EQUAL(pszCap,OLCSequentialWrite) || EQUAL(pszCap,OLCRandomWrite) ) return bUpdateAccess; else if( EQUAL(pszCap,OLCFastFeatureCount) ) return m_poFilterGeom == NULL; else if( EQUAL(pszCap,OLCFastSpatialFilter) ) return FALSE; else if( EQUAL(pszCap,OLCFastGetExtent) ) return TRUE; else if( EQUAL(pszCap,OLCFastSetNextByIndex) ) return m_poFilterGeom == NULL && m_poAttrQuery == NULL; else if( EQUAL(pszCap,OLCCreateField) ) return TRUE; else return FALSE;}/************************************************************************//* CreateField() *//************************************************************************/OGRErr OGRShapeLayer::CreateField( OGRFieldDefn *poField, int bApproxOK ){ int iNewField; if( GetFeatureCount(TRUE) != 0 ) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields on a Shapefile layer with features.\n"); return OGRERR_FAILURE; } if( !bUpdateAccess ) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields on a read-only shapefile layer.\n"); return OGRERR_FAILURE; } if( poField->GetType() == OFTInteger ) { if( poField->GetWidth() == 0 ) iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTInteger, 11, 0 ); else iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTInteger, poField->GetWidth(), 0 ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( poField ); } else if( poField->GetType() == OFTReal ) { if( poField->GetWidth() == 0 ) iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTDouble, 24, 15 ); else iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTDouble, poField->GetWidth(), poField->GetPrecision() ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( poField ); } else if( poField->GetType() == OFTString ) { if( poField->GetWidth() < 1 ) iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTString, 80, 0 ); else iNewField = DBFAddField( hDBF, poField->GetNameRef(), FTString, poField->GetWidth(), 0 ); if( iNewField != -1 ) poFeatureDefn->AddFieldDefn( poField ); } else { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields of type %s on shapefile layers.\n", OGRFieldDefn::GetFieldTypeName(poField->GetType()) ); return OGRERR_FAILURE; } if( iNewField != -1 ) return OGRERR_NONE; else { CPLError( CE_Failure, CPLE_AppDefined, "Can't create field %s in Shape DBF file, reason unknown.\n", poField->GetNameRef() ); return OGRERR_FAILURE; }}/************************************************************************//* GetSpatialRef() *//************************************************************************/OGRSpatialReference *OGRShapeLayer::GetSpatialRef(){ return poSRS;}/************************************************************************//* ResetGeomType() *//* *//* Modify the geometry type for this file. Used to convert to *//* a different geometry type when a layer was created with a *//* type of unknown, and we get to the first feature to *//* establish the type. *//************************************************************************/int OGRShapeLayer::ResetGeomType( int nNewGeomType ){ char abyHeader[100]; int nStartPos; if( nTotalShapeCount > 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update .shp header. *//* -------------------------------------------------------------------- */ nStartPos = ftell( hSHP->fpSHP ); if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 || fread( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) return FALSE; *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); if( fseek( hSHP->fpSHP, 0, SEEK_SET ) != 0 || fwrite( abyHeader, 100, 1, hSHP->fpSHP ) != 1 ) return FALSE; if( fseek( hSHP->fpSHP, nStartPos, SEEK_SET ) != 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update .shx header. *//* -------------------------------------------------------------------- */ nStartPos = ftell( hSHP->fpSHX ); if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 || fread( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) return FALSE; *((GInt32 *) (abyHeader + 32)) = CPL_LSBWORD32( nNewGeomType ); if( fseek( hSHP->fpSHX, 0, SEEK_SET ) != 0 || fwrite( abyHeader, 100, 1, hSHP->fpSHX ) != 1 ) return FALSE; if( fseek( hSHP->fpSHX, nStartPos, SEEK_SET ) != 0 ) return FALSE;/* -------------------------------------------------------------------- *//* Update other information. *//* -------------------------------------------------------------------- */ hSHP->nShapeType = nNewGeomType; return TRUE;}/************************************************************************//* SyncToDisk() *//************************************************************************/OGRErr OGRShapeLayer::SyncToDisk(){ if( bHeaderDirty ) { if( hSHP != NULL ) SHPWriteHeader( hSHP ); if( hDBF != NULL ) DBFUpdateHeader( hDBF ); bHeaderDirty = FALSE; } if( hSHP != NULL ) { fflush( hSHP->fpSHP ); fflush( hSHP->fpSHX ); } if( hDBF != NULL ) fflush( hDBF->fp ); return OGRERR_NONE;}/************************************************************************//* DropSpatialIndex() *//************************************************************************/OGRErr OGRShapeLayer::DropSpatialIndex(){ if( !CheckForQIX() ) { CPLError( CE_Warning, CPLE_AppDefined, "Layer %s has no spatial index, DROP SPATIAL INDEX failed.", poFeatureDefn->GetName() ); return OGRERR_FAILURE; } VSIFClose( fpQIX ); fpQIX = NULL; bCheckedForQIX = FALSE; const char *pszQIXFilename; pszQIXFilename = CPLResetExtension( pszFullName, "qix" ); CPLDebug( "SHAPE", "Unlinking index file %s", pszQIXFilename ); if( VSIUnlink( pszQIXFilename ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to delete file %s.\n%s", pszQIXFilename, VSIStrerror( errno ) ); return OGRERR_FAILURE; } else return OGRERR_NONE;}/************************************************************************//* CreateSpatialIndex() *//************************************************************************/OGRErr OGRShapeLayer::CreateSpatialIndex( int nMaxDepth ){/* -------------------------------------------------------------------- *//* If we have an existing spatial index, blow it away first. *//* -------------------------------------------------------------------- */ if( CheckForQIX() ) DropSpatialIndex(); bCheckedForQIX = FALSE;/* -------------------------------------------------------------------- *//* Build a quadtree structure for this file. *//* -------------------------------------------------------------------- */ SHPTree *psTree; SyncToDisk(); psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL );/* -------------------------------------------------------------------- *//* Trim unused nodes from the tree. *//* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree );/* -------------------------------------------------------------------- *//* Dump tree to .qix file. *//* -------------------------------------------------------------------- */ char *pszQIXFilename; pszQIXFilename = CPLStrdup(CPLResetExtension( pszFullName, "qix" )); CPLDebug( "SHAPE", "Creating index file %s", pszQIXFilename ); SHPWriteTree( psTree, pszQIXFilename ); CPLFree( pszQIXFilename );/* -------------------------------------------------------------------- *//* cleanup *//* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); CheckForQIX(); return OGRERR_NONE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -