📄 ogrgeometrycollection.cpp
字号:
}/************************************************************************//* importFromWkb() *//* *//* Initialize from serialized stream in well known binary *//* format. *//************************************************************************/OGRErr OGRGeometryCollection::importFromWkb( unsigned char * pabyData, int nSize ){ OGRwkbByteOrder eByteOrder; int nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA;/* -------------------------------------------------------------------- *//* Get the byte order byte. *//* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); CPLAssert( eByteOrder == wkbXDR || eByteOrder == wkbNDR );/* -------------------------------------------------------------------- *//* Get the geometry feature type. For now we assume that *//* geometry type is between 0 and 255 so we only have to fetch *//* one byte. *//* -------------------------------------------------------------------- */#ifdef DEBUG OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } CPLAssert( eGeometryType == wkbGeometryCollection || eGeometryType == wkbMultiPolygon || eGeometryType == wkbMultiLineString || eGeometryType == wkbMultiPoint );#endif /* -------------------------------------------------------------------- *//* Do we already have some existing geometry objects? *//* -------------------------------------------------------------------- */ if( nGeomCount != 0 ) { for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) delete papoGeoms[iGeom]; OGRFree( papoGeoms ); papoGeoms = NULL; } /* -------------------------------------------------------------------- *//* Get the geometry count. *//* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); papoGeoms = (OGRGeometry **) OGRMalloc(sizeof(void*) * nGeomCount); nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; nCoordinateDimension = 0; // unknown/* -------------------------------------------------------------------- *//* Get the Geoms. *//* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; eErr = OGRGeometryFactory:: createFromWkb( pabyData + nDataOffset, NULL, papoGeoms + iGeom, nSize ); if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; return eErr; } if( nSize != -1 ) nSize -= papoGeoms[iGeom]->WkbSize(); nDataOffset += papoGeoms[iGeom]->WkbSize(); } return OGRERR_NONE;}/************************************************************************//* exportToWkb() *//* *//* Build a well known binary representation of this object. *//************************************************************************/OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const{ int nOffset; /* -------------------------------------------------------------------- *//* Set the byte order. *//* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder);/* -------------------------------------------------------------------- *//* Set the geometry feature type, ensuring that 3D flag is *//* preserved. *//* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- *//* Copy in the raw data. *//* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } nOffset = 9; /* ==================================================================== *//* Serialize each of the Geoms. *//* ==================================================================== */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->exportToWkb( eByteOrder, pabyData + nOffset ); nOffset += papoGeoms[iGeom]->WkbSize(); } return OGRERR_NONE;}/************************************************************************//* importFromWkt() *//************************************************************************/OGRErr OGRGeometryCollection::importFromWkt( char ** ppszInput ){ char szToken[OGR_WKT_TOKEN_MAX]; const char *pszInput = *ppszInput; int iGeom;/* -------------------------------------------------------------------- *//* Clear existing Geoms. *//* -------------------------------------------------------------------- */ if( nGeomCount > 0 ) { for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) delete papoGeoms[iGeom]; nGeomCount = 0; CPLFree( papoGeoms ); }/* -------------------------------------------------------------------- *//* Read and verify the type keyword, and ensure it matches the *//* actual type of this container. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( !EQUAL(szToken,getGeometryName()) ) return OGRERR_CORRUPT_DATA;/* -------------------------------------------------------------------- *//* The next character should be a ( indicating the start of the *//* list of objects. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { *ppszInput = (char *) pszInput; return OGRERR_NONE; } if( szToken[0] != '(' ) return OGRERR_CORRUPT_DATA;/* -------------------------------------------------------------------- *//* If the next token is EMPTY, then verify that we have proper *//* EMPTY format will a trailing closing bracket. *//* -------------------------------------------------------------------- */ OGRWktReadToken( pszInput, szToken ); if( EQUAL(szToken,"EMPTY") ) { pszInput = OGRWktReadToken( pszInput, szToken ); pszInput = OGRWktReadToken( pszInput, szToken ); *ppszInput = (char *) pszInput; if( !EQUAL(szToken,")") ) return OGRERR_CORRUPT_DATA; else return OGRERR_NONE; }/* ==================================================================== *//* Read each subgeometry in turn. *//* ==================================================================== */ do { OGRGeometry *poGeom = NULL; OGRErr eErr; eErr = OGRGeometryFactory::createFromWkt( (char **) &pszInput, NULL, &poGeom ); if( eErr != OGRERR_NONE ) return eErr; addGeometryDirectly( poGeom );/* -------------------------------------------------------------------- *//* Read the delimeter following the ring. *//* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szToken ); } while( szToken[0] == ',' );/* -------------------------------------------------------------------- *//* freak if we don't get a closing bracket. *//* -------------------------------------------------------------------- */ if( szToken[0] != ')' ) return OGRERR_CORRUPT_DATA; *ppszInput = (char *) pszInput; return OGRERR_NONE;}/************************************************************************//* exportToWkt() *//* *//* Translate this structure into it's well known text format *//* equivelent. This could be made alot more CPU efficient! *//************************************************************************/OGRErr OGRGeometryCollection::exportToWkt( char ** ppszDstText ) const{ char **papszGeoms; int iGeom, nCumulativeLength = 0; OGRErr eErr; if( getNumGeometries() == 0 ) { *ppszDstText = CPLStrdup("GEOMETRYCOLLECTION EMPTY"); return OGRERR_NONE; }/* -------------------------------------------------------------------- *//* Build a list of strings containing the stuff for each Geom. *//* -------------------------------------------------------------------- */ papszGeoms = (char **) CPLCalloc(sizeof(char *),nGeomCount); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt( &(papszGeoms[iGeom]) ); if( eErr != OGRERR_NONE ) return eErr; nCumulativeLength += strlen(papszGeoms[iGeom]); } /* -------------------------------------------------------------------- *//* Allocate the right amount of space for the aggregated string *//* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nGeomCount + 23); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY;/* -------------------------------------------------------------------- *//* Build up the string, freeing temporary strings as we go. *//* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); strcat( *ppszDstText, " (" ); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( iGeom > 0 ) strcat( *ppszDstText, "," ); strcat( *ppszDstText, papszGeoms[iGeom] ); VSIFree( papszGeoms[iGeom] ); } strcat( *ppszDstText, ")" ); CPLFree( papszGeoms ); return OGRERR_NONE;}/************************************************************************//* getEnvelope() *//************************************************************************/void OGRGeometryCollection::getEnvelope( OGREnvelope * psEnvelope ) const{ OGREnvelope oGeomEnv; if( nGeomCount == 0 ) return; papoGeoms[0]->getEnvelope( psEnvelope ); for( int iGeom = 1; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->getEnvelope( &oGeomEnv ); if( psEnvelope->MinX > oGeomEnv.MinX ) psEnvelope->MinX = oGeomEnv.MinX; if( psEnvelope->MinY > oGeomEnv.MinY ) psEnvelope->MinY = oGeomEnv.MinY; if( psEnvelope->MaxX < oGeomEnv.MaxX ) psEnvelope->MaxX = oGeomEnv.MaxX; if( psEnvelope->MaxY < oGeomEnv.MaxY ) psEnvelope->MaxY = oGeomEnv.MaxY; }}/************************************************************************//* Equals() *//************************************************************************/OGRBoolean OGRGeometryCollection::Equals( OGRGeometry * poOther ) const{ OGRGeometryCollection *poOGC = (OGRGeometryCollection *) poOther; if( poOGC == this ) return TRUE; if( poOther->getGeometryType() != getGeometryType() ) return FALSE; if( getNumGeometries() != poOGC->getNumGeometries() ) return FALSE; // we should eventually test the SRS. for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( !getGeometryRef(iGeom)->Equals(poOGC->getGeometryRef(iGeom)) ) return FALSE; } return TRUE;}/************************************************************************//* transform() *//************************************************************************/OGRErr OGRGeometryCollection::transform( OGRCoordinateTransformation *poCT ){#ifdef DISABLE_OGRGEOM_TRANSFORM return OGRERR_FAILURE;#else for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; eErr = papoGeoms[iGeom]->transform( poCT ); if( eErr != OGRERR_NONE ) { if( iGeom != 0 ) { CPLDebug("OGR", "OGRGeometryCollection::transform() failed for a geometry other\n" "than the first, meaning some geometries are transformed\n" "and some are not!\n" ); return OGRERR_FAILURE; } return eErr; } } assignSpatialReference( poCT->GetTargetCS() ); return OGRERR_NONE;#endif}/************************************************************************//* closeRings() *//************************************************************************/void OGRGeometryCollection::closeRings(){ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( wkbFlatten(papoGeoms[iGeom]->getGeometryType()) == wkbPolygon ) ((OGRPolygon *) papoGeoms[iGeom])->closeRings(); }}/************************************************************************//* setCoordinateDimension() *//************************************************************************/void OGRGeometryCollection::setCoordinateDimension( int nNewDimension ){ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { papoGeoms[iGeom]->setCoordinateDimension( nNewDimension ); } OGRGeometry::setCoordinateDimension( nNewDimension );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -