📄 shpopen.c
字号:
{ psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]); psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]); psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]); psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]); psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]); psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]); psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]); psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]); } return( nShapeId );}/************************************************************************//* SHPReadObject() *//* *//* Read the vertices, parts, and other non-attribute information *//* for one shape. *//************************************************************************/SHPObject SHPAPI_CALL1(*)SHPReadObject( SHPHandle psSHP, int hEntity ){ SHPObject *psShape;/* -------------------------------------------------------------------- *//* Validate the record/entity number. *//* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psSHP->nRecords ) return( NULL );/* -------------------------------------------------------------------- *//* Ensure our record buffer is large enough. *//* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) { psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); }/* -------------------------------------------------------------------- *//* Read the record. *//* -------------------------------------------------------------------- */ if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 || fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ) != 1 ) { /* * TODO - mloskot: Consider detailed diagnostics of shape file, * for example to detect if file is truncated. */#ifdef USE_CPL CPLDebug( "Shape", "Error in fseek() or fread() reading object from .shp file." );#endif return NULL; }/* -------------------------------------------------------------------- *//* Allocate and minimally initialize the object. *//* -------------------------------------------------------------------- */ psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); psShape->nShapeId = hEntity; psShape->bMeasureIsUsed = FALSE; memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );/* ==================================================================== *//* Extract vertices for a Polygon or Arc. *//* ==================================================================== */ if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC || psShape->nSHPType == SHPT_POLYGONZ || psShape->nSHPType == SHPT_POLYGONM || psShape->nSHPType == SHPT_ARCZ || psShape->nSHPType == SHPT_ARCM || psShape->nSHPType == SHPT_MULTIPATCH ) { int32 nPoints, nParts; int i, nOffset;/* -------------------------------------------------------------------- *//* Get the X/Y bounds. *//* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );/* -------------------------------------------------------------------- *//* Extract part/point count, and build vertex and part arrays *//* to proper size. *//* -------------------------------------------------------------------- */ memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 ); memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); if( bBigEndian ) SwapWord( 4, &nParts ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); psShape->nParts = nParts; psShape->panPartStart = (int *) calloc(nParts,sizeof(int)); psShape->panPartType = (int *) calloc(nParts,sizeof(int)); for( i = 0; i < nParts; i++ ) psShape->panPartType[i] = SHPP_RING;/* -------------------------------------------------------------------- *//* Copy out the part array from the record. *//* -------------------------------------------------------------------- */ memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); for( i = 0; i < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); } nOffset = 44 + 8 + 4*nParts;/* -------------------------------------------------------------------- *//* If this is a multipatch, we will also have parts types. *//* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPATCH ) { memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); for( i = 0; i < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); } nOffset += 4*nParts; } /* -------------------------------------------------------------------- *//* Copy out the vertices from the record. *//* -------------------------------------------------------------------- */ for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, 8 ); memcpy(psShape->padfY + i, psSHP->pabyRec + nOffset + i * 16 + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset += 16*nPoints; /* -------------------------------------------------------------------- *//* If we have a Z coordinate, collect that now. *//* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_POLYGONZ || psShape->nSHPType == SHPT_ARCZ || psShape->nSHPType == SHPT_MULTIPATCH ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; }/* -------------------------------------------------------------------- *//* If we have a M measure value, then read it now. We assume *//* that the measure can be present for any shape if the size is *//* big enough, but really it will only occur for the Z shapes *//* (options), and the M shapes. *//* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } psShape->bMeasureIsUsed = TRUE; } }/* ==================================================================== *//* Extract vertices for a MultiPoint. *//* ==================================================================== */ else if( psShape->nSHPType == SHPT_MULTIPOINT || psShape->nSHPType == SHPT_MULTIPOINTM || psShape->nSHPType == SHPT_MULTIPOINTZ ) { int32 nPoints; int i, nOffset; memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset = 48 + 16*nPoints; /* -------------------------------------------------------------------- *//* Get the X/Y bounds. *//* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );/* -------------------------------------------------------------------- *//* If we have a Z coordinate, collect that now. *//* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPOINTZ ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; }/* -------------------------------------------------------------------- *//* If we have a M measure value, then read it now. We assume *//* that the measure can be present for any shape if the size is *//* big enough, but really it will only occur for the Z shapes *//* (options), and the M shapes. *//* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } psShape->bMeasureIsUsed = TRUE; } }/* ==================================================================== *//* Extract vertices for a point. *//* ==================================================================== */ else if( psShape->nSHPType == SHPT_POINT || psShape->nSHPType == SHPT_POINTM || psShape->nSHPType == SHPT_POINTZ ) { int nOffset; psShape->nVertices = 1; psShape->padfX = (double *) calloc(1,sizeof(double)); psShape->padfY = (double *) calloc(1,sizeof(double)); psShape->padfZ = (double *) calloc(1,sizeof(double)); psShape->padfM = (double *) calloc(1,sizeof(double)); memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX ); if( bBigEndian ) SwapWord( 8, psShape->padfY ); nOffset = 20 + 8; /* -------------------------------------------------------------------- *//* If we have a Z coordinate, collect that now. *//* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_POINTZ ) { memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ ); nOffset += 8; }/* -------------------------------------------------------------------- *//* If we have a M measure value, then read it now. We assume *//* that the measure can be present for any shape if the size is *//* big enough, but really it will only occur for the Z shapes *//* (options), and the M shapes. *//* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) { memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM ); psShape->bMeasureIsUsed = TRUE; }/* -------------------------------------------------------------------- *//* Since no extents are supplied in the record, we will apply *//* them from the single vertex. *//* -------------------------------------------------------------------- */ psShape->dfXMin = psShape->dfXMax = psShape->padfX[0]; psShape->dfYMin = psShape->dfYMax = psSh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -