📄 shpopen.c
字号:
/* -------------------------------------------------------------------- *//* Compute the extents. *//* -------------------------------------------------------------------- */ psObject->nVertices = nVertices; SHPComputeExtents( psObject ); return( psObject );}/************************************************************************//* SHPCreateSimpleObject() *//* *//* Create a simple (common) shape object. Destroy with *//* SHPDestroyObject(). *//************************************************************************/SHPObject *SHPCreateSimpleObject( int nSHPType, int nVertices, double * padfX, double * padfY, double * padfZ ){ return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL, nVertices, padfX, padfY, padfZ, NULL ) );} /************************************************************************//* SHPWriteObject() *//* *//* Write out the vertices of a new structure. Note that it is *//* only possible to write vertices at the end of the file. *//************************************************************************/int SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) { int nRecordOffset, i, nRecordSize; uchar *pabyRec; int32 i32; psSHP->bUpdated = TRUE;/* -------------------------------------------------------------------- *//* Ensure that shape object matches the type of the file it is *//* being written to. *//* -------------------------------------------------------------------- */ assert( psObject->nSHPType == psSHP->nShapeType );/* -------------------------------------------------------------------- *//* Add the new entity to the in memory index. *//* -------------------------------------------------------------------- */ if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords ) { psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100); psSHP->panRecOffset = (int *) SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords ); psSHP->panRecSize = (int *) SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords ); }/* -------------------------------------------------------------------- *//* Initialize record. *//* -------------------------------------------------------------------- */ pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) + psObject->nParts * 8 + 128); /* -------------------------------------------------------------------- *//* Extract vertices for a Polygon or Arc. *//* -------------------------------------------------------------------- */ if( psSHP->nShapeType == SHPT_POLYGON || psSHP->nShapeType == SHPT_POLYGONZ || psSHP->nShapeType == SHPT_POLYGONM || psSHP->nShapeType == SHPT_ARC || psSHP->nShapeType == SHPT_ARCZ || psSHP->nShapeType == SHPT_ARCM || psSHP->nShapeType == SHPT_MULTIPATCH ) { int32 nPoints, nParts; int i; nPoints = psObject->nVertices; nParts = psObject->nParts; _SHPSetBounds( pabyRec + 12, psObject ); if( bBigEndian ) SwapWord( 4, &nPoints ); if( bBigEndian ) SwapWord( 4, &nParts ); ByteCopy( &nPoints, pabyRec + 40 + 8, 4 ); ByteCopy( &nParts, pabyRec + 36 + 8, 4 ); nRecordSize = 52; /* * Write part start positions. */ ByteCopy( psObject->panPartStart, pabyRec + 44 + 8, 4 * psObject->nParts ); for( i = 0; i < psObject->nParts; i++ ) { if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i ); nRecordSize += 4; } /* * Write multipatch part types if needed. */ if( psSHP->nShapeType == SHPT_MULTIPATCH ) { memcpy( pabyRec + nRecordSize, psObject->panPartType, 4*psObject->nParts ); for( i = 0; i < psObject->nParts; i++ ) { if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize ); nRecordSize += 4; } } /* * Write the (x,y) vertex values. */ for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 ); ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize + 8 ); nRecordSize += 2 * 8; } /* * Write the Z coordinates (if any). */ if( psSHP->nShapeType == SHPT_POLYGONZ || psSHP->nShapeType == SHPT_ARCZ || psSHP->nShapeType == SHPT_MULTIPATCH ) { ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } /* * Write the M values, if any. */ if( psSHP->nShapeType == SHPT_POLYGONM || psSHP->nShapeType == SHPT_ARCM#ifndef DISABLE_MULTIPATCH_MEASURE || psSHP->nShapeType == SHPT_MULTIPATCH#endif || psSHP->nShapeType == SHPT_POLYGONZ || psSHP->nShapeType == SHPT_ARCZ ) { ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } }/* -------------------------------------------------------------------- *//* Extract vertices for a MultiPoint. *//* -------------------------------------------------------------------- */ else if( psSHP->nShapeType == SHPT_MULTIPOINT || psSHP->nShapeType == SHPT_MULTIPOINTZ || psSHP->nShapeType == SHPT_MULTIPOINTM ) { int32 nPoints; int i; nPoints = psObject->nVertices; _SHPSetBounds( pabyRec + 12, psObject ); if( bBigEndian ) SwapWord( 4, &nPoints ); ByteCopy( &nPoints, pabyRec + 44, 4 ); for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 ); ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 ); if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 ); } nRecordSize = 48 + 16 * psObject->nVertices; if( psSHP->nShapeType == SHPT_MULTIPOINTZ ) { ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } if( psSHP->nShapeType == SHPT_MULTIPOINTZ || psSHP->nShapeType == SHPT_MULTIPOINTM ) { ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } }/* -------------------------------------------------------------------- *//* Extract vertices for a point. *//* -------------------------------------------------------------------- */ else if( psSHP->nShapeType == SHPT_POINT || psSHP->nShapeType == SHPT_POINTZ || psSHP->nShapeType == SHPT_POINTM ) { ByteCopy( psObject->padfX, pabyRec + 12, 8 ); ByteCopy( psObject->padfY, pabyRec + 20, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + 12 ); if( bBigEndian ) SwapWord( 8, pabyRec + 20 ); nRecordSize = 28; if( psSHP->nShapeType == SHPT_POINTZ ) { ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } if( psSHP->nShapeType == SHPT_POINTZ || psSHP->nShapeType == SHPT_POINTM ) { ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } else { /* unknown type */ assert( FALSE ); }/* -------------------------------------------------------------------- *//* Establish where we are going to put this record. If we are *//* rewriting and existing record, and it will fit, then put it *//* back where the original came from. Otherwise write at the end. *//* -------------------------------------------------------------------- */ if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 ) { if( nShapeId == -1 ) nShapeId = psSHP->nRecords++; psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize; psSHP->panRecSize[nShapeId] = nRecordSize-8; psSHP->nFileSize += nRecordSize; } else { nRecordOffset = psSHP->panRecOffset[nShapeId]; } /* -------------------------------------------------------------------- *//* Set the shape type, record number, and record size. *//* -------------------------------------------------------------------- */ i32 = nShapeId+1; /* record # */ if( !bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec, 4 ); i32 = (nRecordSize-8)/2; /* record size */ if( !bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec + 4, 4 ); i32 = psSHP->nShapeType; /* shape type */ if( bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec + 8, 4 );/* -------------------------------------------------------------------- *//* Write out record. *//* -------------------------------------------------------------------- */ if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) { printf( "Error in fseek() or fwrite().\n" ); free( pabyRec ); return -1; } free( pabyRec );/* -------------------------------------------------------------------- *//* Expand file wide bounds based on this shape. *//* -------------------------------------------------------------------- */ if( psSHP->nRecords == 1 ) { psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; } for( i = 0; i < psObject->nVertices; i++ ) { 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 *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 > nBufSize ) { nBufSize = psSHP->panRecSize[hEntity]+8; pabyRec = (uchar *) SfRealloc(pabyRec,nBufSize); }/* -------------------------------------------------------------------- *//* Read the record. *//* -------------------------------------------------------------------- */ fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); fread( pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP );/* -------------------------------------------------------------------- *//* Allocate and minimally initialize the object. *//* -------------------------------------------------------------------- */ psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); psShape->nShapeId = hEntity; memcpy( &psShape->nSHPType, pabyRec + 8, 4 ); if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -