OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize, OGRwkbVariant eWkbVariant ) { OGRwkbByteOrder eByteOrder; OGRBoolean bIs3D = FALSE; OGRErr eErr = importPreambuleFromWkb( pabyData, nSize, eByteOrder, bIs3D, eWkbVariant ); if( eErr != OGRERR_NONE ) return eErr; if ( nSize < ((bIs3D) ? 29 : 21) && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData + 5, 8 ); memcpy( &y, pabyData + 5 + 8, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( bIs3D ) { memcpy( &z, pabyData + 5 + 16, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &z ); } nCoordDimension = 3; } else { z = 0; nCoordDimension = 2; } /* Detect NaN coordinates --> EMPTY */ if( x != x && y != y ) nCoordDimension = -nCoordDimension; return OGRERR_NONE; }
OGRErr OGRPoint::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if ( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if ( IsEmpty() && eWkbVariant == wkbVariantIso ) { double dNan = std::numeric_limits<double>::quiet_NaN(); memcpy( pabyData+5, &dNan, 8 ); memcpy( pabyData+5+8, &dNan, 8 ); if( getCoordinateDimension() == 3 ) memcpy( pabyData+5+16, &dNan, 8 ); } else { memcpy( pabyData+5, &x, 16 ); if( getCoordinateDimension() == 3 ) { memcpy( pabyData + 5 + 16, &z, 8 ); } } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( pabyData + 5 ); CPL_SWAPDOUBLE( pabyData + 5 + 8 ); if( getCoordinateDimension() == 3 ) CPL_SWAPDOUBLE( pabyData + 5 + 16 ); } return OGRERR_NONE; }
OGRErr OGRLineString::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the data count. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int i; if( getCoordinateDimension() == 3 ) { for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 ); memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 ); } } else memcpy( pabyData+9, paoPoints, 16 * nPointCount ); /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData+5, &nCount, 4 ); for( i = getCoordinateDimension() * nPointCount - 1; i >= 0; i-- ) { CPL_SWAP64PTR( pabyData + 9 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = wkbPolygon; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = wkbPolygon; } /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(); } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { int nOffset; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = getGeometryType(); pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = getGeometryType(); } /* -------------------------------------------------------------------- */ /* 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; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { int nOffset; int b3D = getCoordinateDimension() == 3; /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ 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( nRingCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nRingCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { papoRings[iRing]->_exportToWkb( eByteOrder, b3D, pabyData + nOffset ); nOffset += papoRings[iRing]->_WkbSize(b3D); } return OGRERR_NONE; }
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; }
OGRErr OGRLinearRing::_exportToWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData ) const { int i, nWords; /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( b3D ) { nWords = 3 * nPointCount; for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfZ == NULL ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfZ + i, 8 ); } } else { nWords = 2 * nPointCount; memcpy( pabyData+4, paoPoints, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData, &nCount, 4 ); for( i = 0; i < nWords; i++ ) { CPL_SWAPDOUBLE( pabyData + 4 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRPoint::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER((unsigned char) eByteOrder); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ 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. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nQual, 4 ); memcpy( pabyData+9, &x, 16 ); if( z != 0 ) { memcpy( pabyData + 9 + 16, &z, 8 ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { CPL_SWAP32PTR( pabyData + 5 ); CPL_SWAPDOUBLE( pabyData + 9 ); CPL_SWAPDOUBLE( pabyData + 9 + 8 ); if( z != 0 ) CPL_SWAPDOUBLE( pabyData + 9 + 16 ); } return OGRERR_NONE; }
OGRErr OGRLineString::importFromWkb( unsigned char * pabyData, int nBytesAvailable ) { OGRwkbByteOrder eByteOrder; if( nBytesAvailable < 21 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = (OGRwkbByteOrder) *pabyData; assert( 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. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; int bIs3D; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; bIs3D = (pabyData[2] & 0x80); } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; bIs3D = (pabyData[3] & 0x80); } assert( eGeometryType == wkbLineString ); /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); setNumPoints( nNewNumPoints ); if( bIs3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ int i; if( bIs3D ) { for( i = 0; i < nPointCount; i++ ) { memcpy( paoPoints + i, pabyData + 9 + i*24, 16 ); memcpy( padfZ + i, pabyData + 9 + 16 + i*24, 8 ); } } else { memcpy( paoPoints, pabyData + 9, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); } if( bIs3D ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }
OGRErr OGRLineString::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData ) { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = (unsigned char) eByteOrder; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ if( eByteOrder == wkbNDR ) { pabyData[1] = wkbLineString; if( getCoordinateDimension() == 3 ) pabyData[2] = 0x80; else pabyData[2] = 0; pabyData[3] = 0; pabyData[4] = 0; } else { pabyData[1] = 0; pabyData[2] = 0; if( getCoordinateDimension() == 3 ) pabyData[3] = 0x80; else pabyData[3] = 0; pabyData[4] = wkbLineString; } /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData+5, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int i; if( getCoordinateDimension() == 3 ) { for( i = 0; i < nPointCount; i++ ) { memcpy( pabyData + 9 + 24*i, paoPoints+i, 16 ); memcpy( pabyData + 9 + 16 + 24*i, padfZ+i, 8 ); } } else memcpy( pabyData+9, paoPoints, 16 * nPointCount ); /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount; nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData+5, &nCount, 4 ); for( i = getCoordinateDimension() * 3 - 1; i >= 0; i-- ) { CPL_SWAPDOUBLE( pabyData + 9 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData, int nBytesAvailable ) { if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); /* Check if the wkb stream buffer is big enough to store * fetched number of points. * 16 or 24 - size of point structure */ int nPointSize = (b3D ? 24 : 16); if (nNewNumPoints < 0 || nNewNumPoints > INT_MAX / nPointSize) return OGRERR_CORRUPT_DATA; int nBufferMinSize = nPointSize * nNewNumPoints; if( nBytesAvailable != -1 && nBufferMinSize > nBytesAvailable - 4 ) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); return OGRERR_NOT_ENOUGH_DATA; } /* (Re)Allocation of paoPoints buffer. */ setNumPoints( nNewNumPoints ); if( b3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ int i = 0; if( !b3D ) { memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); } else { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( b3D ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }
OGRErr GPkgHeaderFromWKB(const GByte *pabyGpkg, GPkgHeader *poHeader) { CPLAssert( pabyGpkg != NULL ); CPLAssert( poHeader != NULL ); /* Magic (match required) */ if ( pabyGpkg[0] != 0x47 || pabyGpkg[1] != 0x50 || pabyGpkg[2] != 0 ) /* Version (only 0 supported at this time)*/ { return OGRERR_FAILURE; } /* Flags */ GByte byFlags = pabyGpkg[3]; poHeader->bEmpty = (byFlags & (0x01 << 4)) >> 4; poHeader->bExtended = (byFlags & (0x01 << 5)) >> 5; poHeader->eByteOrder = (OGRwkbByteOrder)(byFlags & 0x01); OGRBoolean bSwap = OGR_SWAP(poHeader->eByteOrder); /* Envelope */ int iEnvelope = (byFlags & (0x07 << 1)) >> 1; if ( iEnvelope == 1 ) poHeader->iDims = 2; /* 2D envelope */ else if ( iEnvelope == 2 ) poHeader->iDims = 3; /* 3D envelope */ else poHeader->iDims = 0; /* No envelope */ /* SrsId */ int iSrsId; memcpy(&iSrsId, pabyGpkg+4, 4); if ( bSwap ) { iSrsId = CPL_SWAP32(iSrsId); } poHeader->iSrsId = iSrsId; /* Envelope */ double *padPtr = (double*)(pabyGpkg+8); if ( poHeader->iDims >= 2 ) { poHeader->MinX = padPtr[0]; poHeader->MaxX = padPtr[1]; poHeader->MinY = padPtr[2]; poHeader->MaxY = padPtr[3]; if ( bSwap ) { CPL_SWAPDOUBLE(&(poHeader->MinX)); CPL_SWAPDOUBLE(&(poHeader->MaxX)); CPL_SWAPDOUBLE(&(poHeader->MinY)); CPL_SWAPDOUBLE(&(poHeader->MaxY)); } } if ( poHeader->iDims == 3 ) { poHeader->MinZ = padPtr[4]; poHeader->MaxZ = padPtr[5]; if ( bSwap ) { CPL_SWAPDOUBLE(&(poHeader->MinZ)); CPL_SWAPDOUBLE(&(poHeader->MaxZ)); } } /* Header size in byte stream */ poHeader->szHeader = 8 + 8*2*(poHeader->iDims); return OGRERR_NONE; }
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; }
OGRErr OGRGeometryCollection::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { if( eWkbVariant == wkbVariantOldOgc && (wkbFlatten(getGeometryType()) == wkbMultiCurve || wkbFlatten(getGeometryType()) == wkbMultiSurface) ) { // Does not make sense for new geometries, so patch it. eWkbVariant = wkbVariantIso; } /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); /* -------------------------------------------------------------------- */ /* Set the geometry feature type, ensuring that 3D flag is */ /* preserved. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); else if( eWkbVariant == wkbVariantPostGIS1 ) { const bool bIs3D = wkbHasZ(static_cast<OGRwkbGeometryType>(nGType)); nGType = wkbFlatten(nGType); if( nGType == wkbMultiCurve ) nGType = POSTGIS15_MULTICURVE; else if( nGType == wkbMultiSurface ) nGType = POSTGIS15_MULTISURFACE; if( bIs3D ) // Yes, explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); } if( OGR_SWAP( eByteOrder ) ) { nGType = CPL_SWAP32(nGType); } memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount = CPL_SWAP32( nGeomCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nGeomCount, 4 ); } int nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ int iGeom = 0; for( auto&& poSubGeom: *this ) { poSubGeom->exportToWkb( eByteOrder, pabyData + nOffset, eWkbVariant ); // Should normally not happen if everyone else does its job, // but has happened sometimes. (#6332) if( poSubGeom->getCoordinateDimension() != getCoordinateDimension() ) { CPLError(CE_Warning, CPLE_AppDefined, "Sub-geometry %d has coordinate dimension %d, " "but container has %d", iGeom, poSubGeom->getCoordinateDimension(), getCoordinateDimension() ); } nOffset += poSubGeom->WkbSize(); iGeom ++; } return OGRERR_NONE; }
OGRErr OGRLinearRing::_exportToWkb( OGRwkbByteOrder eByteOrder, int _flags, unsigned char * pabyData ) const { /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ memcpy( pabyData, &nPointCount, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ int nWords = 0; if( (_flags & OGR_G_3D) && (_flags & OGR_G_MEASURED) ) { nWords = 4 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*32, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*32+8, &(paoPoints[i].y), 8 ); if( padfZ == nullptr ) memset( pabyData+4+i*32+16, 0, 8 ); else memcpy( pabyData+4+i*32+16, padfZ + i, 8 ); if( padfM == nullptr ) memset( pabyData+4+i*32+24, 0, 8 ); else memcpy( pabyData+4+i*32+24, padfM + i, 8 ); } } else if( _flags & OGR_G_MEASURED ) { nWords = 3 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfM == nullptr ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfM + i, 8 ); } } else if( _flags & OGR_G_3D ) { nWords = 3 * nPointCount; for( int i = 0; i < nPointCount; i++ ) { memcpy( pabyData+4+i*24, &(paoPoints[i].x), 8 ); memcpy( pabyData+4+i*24+8, &(paoPoints[i].y), 8 ); if( padfZ == nullptr ) memset( pabyData+4+i*24+16, 0, 8 ); else memcpy( pabyData+4+i*24+16, padfZ + i, 8 ); } } else { nWords = 2 * nPointCount; memcpy( pabyData+4, paoPoints, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { int nCount = CPL_SWAP32( nPointCount ); memcpy( pabyData, &nCount, 4 ); for( int i = 0; i < nWords; i++ ) { CPL_SWAPDOUBLE( pabyData + 4 + 8 * i ); } } return OGRERR_NONE; }
OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nBytesAvailable ) { OGRwkbByteOrder eByteOrder; int nDataOffset; if( nBytesAvailable < 21 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = (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 == wkbPolygon ); #endif /* -------------------------------------------------------------------- */ /* Do we already have some rings? */ /* -------------------------------------------------------------------- */ if( nRingCount != 0 ) { for( int iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; OGRFree( papoRings ); papoRings = NULL; } /* -------------------------------------------------------------------- */ /* Get the ring count. */ /* -------------------------------------------------------------------- */ memcpy( &nRingCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nRingCount = CPL_SWAP32(nRingCount); papoRings = (OGRLinearRing **) OGRMalloc(sizeof(void*) * nRingCount); nDataOffset = 9; if( nBytesAvailable != -1 ) nBytesAvailable -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the rings. */ /* -------------------------------------------------------------------- */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { OGRErr eErr; papoRings[iRing] = new OGRLinearRing(); eErr = papoRings[iRing]->_importFromWkb( eByteOrder, pabyData + nDataOffset, nBytesAvailable ); if( eErr != OGRERR_NONE ) { nRingCount = iRing; return eErr; } if( nBytesAvailable != -1 ) nBytesAvailable -= papoRings[iRing]->_WkbSize(); nDataOffset += papoRings[iRing]->_WkbSize(); } return OGRERR_NONE; }
OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int b3D, unsigned char * pabyData, int nBytesAvailable ) { if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); setNumPoints( nNewNumPoints ); if( b3D ) Make3D(); else Make2D(); /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ int i; if( !b3D ) memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); else { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( b3D ) { CPL_SWAPDOUBLE( padfZ + i ); } } } return OGRERR_NONE; }
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); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* 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. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } if ( eGeometryType != wkbFlatten(getGeometryType()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Get the geometry count. */ /* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); if (nGeomCount < 0 || nGeomCount > INT_MAX / 9) { nGeomCount = 0; return OGRERR_CORRUPT_DATA; } /* Each geometry has a minimum of 9 bytes */ if (nSize != -1 && nSize - 9 < nGeomCount * 9) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nGeomCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoGeoms = (OGRGeometry **) VSIMalloc2(sizeof(void*), nGeomCount); if (nGeomCount != 0 && papoGeoms == NULL) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; OGRGeometry* poSubGeom = NULL; eErr = OGRGeometryFactory:: createFromWkb( pabyData + nDataOffset, NULL, &poSubGeom, nSize ); if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; return eErr; } OGRwkbGeometryType eSubGeomType = wkbFlatten(poSubGeom->getGeometryType()); if( (eGeometryType == wkbMultiPoint && eSubGeomType != wkbPoint) || (eGeometryType == wkbMultiLineString && eSubGeomType != wkbLineString) || (eGeometryType == wkbMultiPolygon && eSubGeomType != wkbPolygon) ) { nGeomCount = iGeom; CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, eGeometryType); delete poSubGeom; return OGRERR_CORRUPT_DATA; } papoGeoms[iGeom] = poSubGeom; if (papoGeoms[iGeom]->getCoordinateDimension() == 3) nCoordDimension = 3; int nSubGeomWkbSize = papoGeoms[iGeom]->WkbSize(); if( nSize != -1 ) nSize -= nSubGeomWkbSize; nDataOffset += nSubGeomWkbSize; } return OGRERR_NONE; }
OGRErr OGRCurveCollection::exportToWkb( const OGRGeometry* poGeom, OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) 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 = poGeom->getIsoGeometryType(); if( eWkbVariant == wkbVariantPostGIS1 ) { int bIs3D = wkbHasZ((OGRwkbGeometryType)nGType); nGType = wkbFlatten(nGType); if( nGType == wkbCurvePolygon ) nGType = POSTGIS15_CURVEPOLYGON; if( bIs3D ) nGType = (OGRwkbGeometryType)(nGType | wkb25DBitInternalUse); /* yes we explicitly set wkb25DBit */ } 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( nCurveCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &nCurveCount, 4 ); } nOffset = 9; /* ==================================================================== */ /* Serialize each of the Geoms. */ /* ==================================================================== */ for( int iGeom = 0; iGeom < nCurveCount; iGeom++ ) { papoCurves[iGeom]->exportToWkb( eByteOrder, pabyData + nOffset, eWkbVariant ); nOffset += papoCurves[iGeom]->WkbSize(); } return OGRERR_NONE; }
OGRErr OGRGeometryCollection::importFromWkbInternal( unsigned char * pabyData, int nSize, int nRecLevel ) { OGRwkbByteOrder eByteOrder; int nDataOffset; /* Arbitrary value, but certainly large enough for reasonable usages ! */ if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursiong level (%d) while parsing WKB geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* 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. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; } if ( eGeometryType != wkbFlatten(getGeometryType()) ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Clear existing Geoms. */ /* -------------------------------------------------------------------- */ empty(); /* -------------------------------------------------------------------- */ /* Get the geometry count. */ /* -------------------------------------------------------------------- */ memcpy( &nGeomCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nGeomCount = CPL_SWAP32(nGeomCount); if (nGeomCount < 0 || nGeomCount > INT_MAX / 9) { nGeomCount = 0; return OGRERR_CORRUPT_DATA; } /* Each geometry has a minimum of 9 bytes */ if (nSize != -1 && nSize - 9 < nGeomCount * 9) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nGeomCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoGeoms = (OGRGeometry **) VSIMalloc2(sizeof(void*), nGeomCount); if (nGeomCount != 0 && papoGeoms == NULL) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRErr eErr; OGRGeometry* poSubGeom = NULL; /* Parses sub-geometry */ unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbByteOrder eSubGeomByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabySubData); if( eSubGeomByteOrder != wkbXDR && eSubGeomByteOrder != wkbNDR ) return OGRERR_CORRUPT_DATA; OGRwkbGeometryType eSubGeomType; if( eSubGeomByteOrder == wkbNDR ) eSubGeomType = (OGRwkbGeometryType) pabySubData[1]; else eSubGeomType = (OGRwkbGeometryType) pabySubData[4]; if( eSubGeomType == wkbPoint || eSubGeomType == wkbLineString || eSubGeomType == wkbPolygon) { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, NULL, &poSubGeom, nSize ); } else if (eSubGeomType == wkbGeometryCollection || eSubGeomType == wkbMultiPolygon || eSubGeomType == wkbMultiPoint || eSubGeomType == wkbMultiLineString) { poSubGeom = OGRGeometryFactory::createGeometry( eSubGeomType ); eErr = ((OGRGeometryCollection*)poSubGeom)-> importFromWkbInternal( pabySubData, nSize, nRecLevel + 1 ); } else return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; delete poSubGeom; return eErr; } if( (eGeometryType == wkbMultiPoint && eSubGeomType != wkbPoint) || (eGeometryType == wkbMultiLineString && eSubGeomType != wkbLineString) || (eGeometryType == wkbMultiPolygon && eSubGeomType != wkbPolygon) ) { nGeomCount = iGeom; CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, eGeometryType); delete poSubGeom; return OGRERR_CORRUPT_DATA; } papoGeoms[iGeom] = poSubGeom; if (papoGeoms[iGeom]->getCoordinateDimension() == 3) nCoordDimension = 3; int nSubGeomWkbSize = papoGeoms[iGeom]->WkbSize(); if( nSize != -1 ) nSize -= nSubGeomWkbSize; nDataOffset += nSubGeomWkbSize; } return OGRERR_NONE; }
OGRErr OGRPolygon::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; int nDataOffset, b3D; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* 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]; if( eGeometryType != wkbPolygon ) return OGRERR_CORRUPT_DATA; #endif if( eByteOrder == wkbNDR ) b3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; else b3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; if( b3D ) nCoordDimension = 3; else nCoordDimension = 2; /* -------------------------------------------------------------------- */ /* Do we already have some rings? */ /* -------------------------------------------------------------------- */ if( nRingCount != 0 ) { for( int iRing = 0; iRing < nRingCount; iRing++ ) delete papoRings[iRing]; OGRFree( papoRings ); papoRings = NULL; } /* -------------------------------------------------------------------- */ /* Get the ring count. */ /* -------------------------------------------------------------------- */ memcpy( &nRingCount, pabyData + 5, 4 ); if( OGR_SWAP( eByteOrder ) ) nRingCount = CPL_SWAP32(nRingCount); if (nRingCount < 0 || nRingCount > INT_MAX / 4) { nRingCount = 0; return OGRERR_CORRUPT_DATA; } /* Each ring has a minimum of 4 bytes (point count) */ if (nSize != -1 && nSize - 9 < nRingCount * 4) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); nRingCount = 0; return OGRERR_NOT_ENOUGH_DATA; } papoRings = (OGRLinearRing **) VSIMalloc2(sizeof(void*), nRingCount); if (nRingCount != 0 && papoRings == NULL) { nRingCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } nDataOffset = 9; if( nSize != -1 ) nSize -= nDataOffset; /* -------------------------------------------------------------------- */ /* Get the rings. */ /* -------------------------------------------------------------------- */ for( int iRing = 0; iRing < nRingCount; iRing++ ) { OGRErr eErr; papoRings[iRing] = new OGRLinearRing(); eErr = papoRings[iRing]->_importFromWkb( eByteOrder, b3D, pabyData + nDataOffset, nSize ); if( eErr != OGRERR_NONE ) { delete papoRings[iRing]; nRingCount = iRing; return eErr; } if( nSize != -1 ) nSize -= papoRings[iRing]->_WkbSize( b3D ); nDataOffset += papoRings[iRing]->_WkbSize( b3D ); } return OGRERR_NONE; }
OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize, OGRwkbVariant eWkbVariant ) { OGRwkbByteOrder eByteOrder = wkbNDR; flags = 0; OGRErr eErr = importPreambuleFromWkb( pabyData, nSize, eByteOrder, eWkbVariant ); pabyData += 5; if( eErr != OGRERR_NONE ) return eErr; if( nSize != -1 ) { if( (nSize < 37) && ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) ) return OGRERR_NOT_ENOUGH_DATA; else if( (nSize < 29) && ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED)) ) return OGRERR_NOT_ENOUGH_DATA; else if( nSize < 21 ) return OGRERR_NOT_ENOUGH_DATA; } /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData, 8 ); pabyData += 8; memcpy( &y, pabyData, 8 ); pabyData += 8; if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( flags & OGR_G_3D ) { memcpy( &z, pabyData, 8 ); pabyData += 8; if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( &z ); } else { z = 0; } if( flags & OGR_G_MEASURED ) { memcpy( &m, pabyData, 8 ); /*pabyData += 8; */ if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &m ); } } else { m = 0; } // Detect coordinates are not NaN --> NOT EMPTY. if( !(CPLIsNan(x) && CPLIsNan(y)) ) flags |= OGR_G_NOT_EMPTY_POINT; return OGRERR_NONE; }
OGRErr OGRPoint::importFromWkb( unsigned char * pabyData, int nSize ) { OGRwkbByteOrder eByteOrder; if( nSize < 21 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the byte order byte. */ /* -------------------------------------------------------------------- */ eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData); if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR )) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* 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. */ /* -------------------------------------------------------------------- */ OGRwkbGeometryType eGeometryType; int bIs3D; if( eByteOrder == wkbNDR ) { eGeometryType = (OGRwkbGeometryType) pabyData[1]; bIs3D = pabyData[4] & 0x80 || pabyData[2] & 0x80; } else { eGeometryType = (OGRwkbGeometryType) pabyData[4]; bIs3D = pabyData[1] & 0x80 || pabyData[3] & 0x80; } if( eGeometryType != wkbPoint ) return OGRERR_CORRUPT_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex. */ /* -------------------------------------------------------------------- */ memcpy( &x, pabyData + 5, 16 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &x ); CPL_SWAPDOUBLE( &y ); } if( bIs3D ) { memcpy( &z, pabyData + 5 + 16, 8 ); if( OGR_SWAP( eByteOrder ) ) { CPL_SWAPDOUBLE( &z ); } nCoordDimension = 3; } else { z = 0; nCoordDimension = 2; } return OGRERR_NONE; }
//! @cond Doxygen_Suppress OGRErr OGRLinearRing::_importFromWkb( OGRwkbByteOrder eByteOrder, int _flags, const unsigned char * pabyData, int nBytesAvailable, int& nBytesConsumedOut ) { nBytesConsumedOut = -1; if( nBytesAvailable < 4 && nBytesAvailable != -1 ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Get the vertex count. */ /* -------------------------------------------------------------------- */ int nNewNumPoints = 0; memcpy( &nNewNumPoints, pabyData, 4 ); if( OGR_SWAP( eByteOrder ) ) nNewNumPoints = CPL_SWAP32(nNewNumPoints); // Check if the wkb stream buffer is big enough to store // fetched number of points. // 16, 24, or 32 - size of point structure. int nPointSize = 0; if( (_flags & OGR_G_3D) && (_flags & OGR_G_MEASURED) ) nPointSize = 32; else if( (_flags & OGR_G_3D) || (_flags & OGR_G_MEASURED) ) nPointSize = 24; else nPointSize = 16; if( nNewNumPoints < 0 || nNewNumPoints > INT_MAX / nPointSize ) return OGRERR_CORRUPT_DATA; int nBufferMinSize = nPointSize * nNewNumPoints; if( nBytesAvailable != -1 && nBufferMinSize > nBytesAvailable - 4 ) { CPLError( CE_Failure, CPLE_AppDefined, "Length of input WKB is too small" ); return OGRERR_NOT_ENOUGH_DATA; } // (Re)Allocation of paoPoints buffer. setNumPoints( nNewNumPoints, FALSE ); if( _flags & OGR_G_3D ) Make3D(); else Make2D(); if( _flags & OGR_G_MEASURED ) AddM(); else RemoveM(); nBytesConsumedOut = 4 + nPointCount * nPointSize; /* -------------------------------------------------------------------- */ /* Get the vertices */ /* -------------------------------------------------------------------- */ if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 32 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 32 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 32 * i + 16, 8 ); memcpy( padfM + i, pabyData + 4 + 32 * i + 24, 8 ); } } else if( flags & OGR_G_MEASURED ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfM + i, pabyData + 4 + 24 * i + 16, 8 ); } } else if( flags & OGR_G_3D ) { for( int i = 0; i < nPointCount; i++ ) { memcpy( &(paoPoints[i].x), pabyData + 4 + 24 * i, 8 ); memcpy( &(paoPoints[i].y), pabyData + 4 + 24 * i + 8, 8 ); memcpy( padfZ + i, pabyData + 4 + 24 * i + 16, 8 ); } } else { memcpy( paoPoints, pabyData + 4, 16 * nPointCount ); } /* -------------------------------------------------------------------- */ /* Byte swap if needed. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { for( int i = 0; i < nPointCount; i++ ) { CPL_SWAPDOUBLE( &(paoPoints[i].x) ); CPL_SWAPDOUBLE( &(paoPoints[i].y) ); if( flags & OGR_G_3D ) { CPL_SWAPDOUBLE( padfZ + i ); } if( flags & OGR_G_MEASURED ) { CPL_SWAPDOUBLE( padfM + i ); } } } return OGRERR_NONE; }
OGRErr OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantPostGIS1 ) { nGType = wkbFlatten(nGType); if( Is3D() ) // Explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); if( IsMeasured() ) nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000); } else if( eWkbVariant == wkbVariantIso ) nGType = getIsoGeometryType(); if( OGR_SWAP( eByteOrder ) ) { nGType = CPL_SWAP32(nGType); } memcpy( pabyData + 1, &nGType, 4 ); /* -------------------------------------------------------------------- */ /* Copy in the raw data. */ /* -------------------------------------------------------------------- */ if( OGR_SWAP( eByteOrder ) ) { const int nCount = CPL_SWAP32( oCC.nCurveCount ); memcpy( pabyData+5, &nCount, 4 ); } else { memcpy( pabyData+5, &oCC.nCurveCount, 4 ); } /* ==================================================================== */ /* Serialize each of the rings. */ /* ==================================================================== */ int nOffset = 9; for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing]; poLR->_exportToWkb( eByteOrder, flags, pabyData + nOffset ); nOffset += poLR->_WkbSize( flags ); } return OGRERR_NONE; }
OGRErr OGRPoint::exportToWkb( OGRwkbByteOrder eByteOrder, unsigned char * pabyData, OGRwkbVariant eWkbVariant ) const { /* -------------------------------------------------------------------- */ /* Set the byte order. */ /* -------------------------------------------------------------------- */ pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(static_cast<unsigned char>(eByteOrder)); pabyData += 1; /* -------------------------------------------------------------------- */ /* Set the geometry feature type. */ /* -------------------------------------------------------------------- */ GUInt32 nGType = getGeometryType(); if( eWkbVariant == wkbVariantPostGIS1 ) { nGType = wkbFlatten(nGType); if( Is3D() ) // Explicitly set wkb25DBit. nGType = static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); if( IsMeasured() ) nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000); } else if( eWkbVariant == wkbVariantIso ) { nGType = getIsoGeometryType(); } if( eByteOrder == wkbNDR ) nGType = CPL_LSBWORD32( nGType ); else nGType = CPL_MSBWORD32( nGType ); memcpy( pabyData, &nGType, 4 ); pabyData += 4; /* -------------------------------------------------------------------- */ /* Copy in the raw data. Swap if needed. */ /* -------------------------------------------------------------------- */ if( IsEmpty() && eWkbVariant == wkbVariantIso ) { const double dNan = std::numeric_limits<double>::quiet_NaN(); memcpy( pabyData, &dNan, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; memcpy( pabyData, &dNan, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; if( flags & OGR_G_3D ) { memcpy( pabyData, &dNan, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; } if( flags & OGR_G_MEASURED ) { memcpy( pabyData, &dNan, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); } } else { memcpy( pabyData, &x, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; memcpy( pabyData, &y, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; if( flags & OGR_G_3D ) { memcpy( pabyData, &z, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); pabyData += 8; } if( flags & OGR_G_MEASURED ) { memcpy( pabyData, &m, 8 ); if( OGR_SWAP( eByteOrder ) ) CPL_SWAPDOUBLE( pabyData ); } } return OGRERR_NONE; }