⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shpopen.c

📁 ESRI SHAPE文件读/写源代码。SHAPE是GIS中的重要文件格式
💻 C
📖 第 1 页 / 共 4 页
字号:
	return( NULL );    }    psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256      + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;    psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;    psSHP->nShapeType = pabyBuf[32];/* -------------------------------------------------------------------- *//*      Read the bounds.                                                *//* -------------------------------------------------------------------- */    if( bBigEndian ) SwapWord( 8, pabyBuf+36 );    memcpy( &dValue, pabyBuf+36, 8 );    psSHP->adBoundsMin[0] = dValue;    if( bBigEndian ) SwapWord( 8, pabyBuf+44 );    memcpy( &dValue, pabyBuf+44, 8 );    psSHP->adBoundsMin[1] = dValue;    if( bBigEndian ) SwapWord( 8, pabyBuf+52 );    memcpy( &dValue, pabyBuf+52, 8 );    psSHP->adBoundsMax[0] = dValue;    if( bBigEndian ) SwapWord( 8, pabyBuf+60 );    memcpy( &dValue, pabyBuf+60, 8 );    psSHP->adBoundsMax[1] = dValue;    if( bBigEndian ) SwapWord( 8, pabyBuf+68 );		/* z */    memcpy( &dValue, pabyBuf+68, 8 );    psSHP->adBoundsMin[2] = dValue;        if( bBigEndian ) SwapWord( 8, pabyBuf+76 );    memcpy( &dValue, pabyBuf+76, 8 );    psSHP->adBoundsMax[2] = dValue;        if( bBigEndian ) SwapWord( 8, pabyBuf+84 );		/* z */    memcpy( &dValue, pabyBuf+84, 8 );    psSHP->adBoundsMin[3] = dValue;    if( bBigEndian ) SwapWord( 8, pabyBuf+92 );    memcpy( &dValue, pabyBuf+92, 8 );    psSHP->adBoundsMax[3] = dValue;    free( pabyBuf );/* -------------------------------------------------------------------- *//*	Read the .shx file to get the offsets to each record in 	*//*	the .shp file.							*//* -------------------------------------------------------------------- */    psSHP->nMaxRecords = psSHP->nRecords;    psSHP->panRecOffset =        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );    psSHP->panRecSize =        (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) );    pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );    fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX );    for( i = 0; i < psSHP->nRecords; i++ )    {	int32		nOffset, nLength;	memcpy( &nOffset, pabyBuf + i * 8, 4 );	if( !bBigEndian ) SwapWord( 4, &nOffset );	memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );	if( !bBigEndian ) SwapWord( 4, &nLength );	psSHP->panRecOffset[i] = nOffset*2;	psSHP->panRecSize[i] = nLength*2;    }    free( pabyBuf );    return( psSHP );}/************************************************************************//*                              SHPClose()                              *//*								       	*//*	Close the .shp and .shx files.					*//************************************************************************/void	SHPClose(SHPHandle psSHP ){/* -------------------------------------------------------------------- *//*	Update the header if we have modified anything.			*//* -------------------------------------------------------------------- */    if( psSHP->bUpdated )    {	SHPWriteHeader( psSHP );    }/* -------------------------------------------------------------------- *//*      Free all resources, and close files.                            *//* -------------------------------------------------------------------- */    free( psSHP->panRecOffset );    free( psSHP->panRecSize );    fclose( psSHP->fpSHX );    fclose( psSHP->fpSHP );    free( psSHP );    if( pabyRec != NULL )    {        free( pabyRec );        pabyRec = NULL;        nBufSize = 0;    }}/************************************************************************//*                             SHPGetInfo()                             *//*                                                                      *//*      Fetch general information about the shape file.                 *//************************************************************************/void SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,                double * padfMinBound, double * padfMaxBound ){    int		i;        if( pnEntities != NULL )        *pnEntities = psSHP->nRecords;    if( pnShapeType != NULL )        *pnShapeType = psSHP->nShapeType;    for( i = 0; i < 4; i++ )    {        if( padfMinBound != NULL )            padfMinBound[i] = psSHP->adBoundsMin[i];        if( padfMaxBound != NULL )            padfMaxBound[i] = psSHP->adBoundsMax[i];    }}/************************************************************************//*                             SHPCreate()                              *//*                                                                      *//*      Create a new shape file and return a handle to the open         *//*      shape file with read/write access.                              *//************************************************************************/SHPHandle SHPCreate( const char * pszLayer, int nShapeType ){    char	*pszBasename, *pszFullname;    int		i;    FILE	*fpSHP, *fpSHX;    uchar     	abyHeader[100];    int32	i32;    double	dValue;    /* -------------------------------------------------------------------- *//*      Establish the byte order on this system.                        *//* -------------------------------------------------------------------- */    i = 1;    if( *((uchar *) &i) == 1 )        bBigEndian = FALSE;    else        bBigEndian = TRUE;/* -------------------------------------------------------------------- *//*	Compute the base (layer) name.  If there is any extension	*//*	on the passed in filename we will strip it off.			*//* -------------------------------------------------------------------- */    pszBasename = (char *) malloc(strlen(pszLayer)+5);    strcpy( pszBasename, pszLayer );    for( i = strlen(pszBasename)-1; 	 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'	       && pszBasename[i] != '\\';	 i-- ) {}    if( pszBasename[i] == '.' )        pszBasename[i] = '\0';/* -------------------------------------------------------------------- *//*      Open the two files so we can write their headers.               *//* -------------------------------------------------------------------- */    pszFullname = (char *) malloc(strlen(pszBasename) + 5);    sprintf( pszFullname, "%s.shp", pszBasename );    fpSHP = fopen(pszFullname, "wb" );    if( fpSHP == NULL )        return( NULL );    sprintf( pszFullname, "%s.shx", pszBasename );    fpSHX = fopen(pszFullname, "wb" );    if( fpSHX == NULL )        return( NULL );    free( pszFullname );    free( pszBasename );/* -------------------------------------------------------------------- *//*      Prepare header block for .shp file.                             *//* -------------------------------------------------------------------- */    for( i = 0; i < 100; i++ )      abyHeader[i] = 0;    abyHeader[2] = 0x27;				/* magic cookie */    abyHeader[3] = 0x0a;    i32 = 50;						/* file size */    ByteCopy( &i32, abyHeader+24, 4 );    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );        i32 = 1000;						/* version */    ByteCopy( &i32, abyHeader+28, 4 );    if( bBigEndian ) SwapWord( 4, abyHeader+28 );        i32 = nShapeType;					/* shape type */    ByteCopy( &i32, abyHeader+32, 4 );    if( bBigEndian ) SwapWord( 4, abyHeader+32 );    dValue = 0.0;					/* set bounds */    ByteCopy( &dValue, abyHeader+36, 8 );    ByteCopy( &dValue, abyHeader+44, 8 );    ByteCopy( &dValue, abyHeader+52, 8 );    ByteCopy( &dValue, abyHeader+60, 8 );/* -------------------------------------------------------------------- *//*      Write .shp file header.                                         *//* -------------------------------------------------------------------- */    fwrite( abyHeader, 100, 1, fpSHP );/* -------------------------------------------------------------------- *//*      Prepare, and write .shx file header.                            *//* -------------------------------------------------------------------- */    i32 = 50;						/* file size */    ByteCopy( &i32, abyHeader+24, 4 );    if( !bBigEndian ) SwapWord( 4, abyHeader+24 );        fwrite( abyHeader, 100, 1, fpSHX );/* -------------------------------------------------------------------- *//*      Close the files, and then open them as regular existing files.  *//* -------------------------------------------------------------------- */    fclose( fpSHP );    fclose( fpSHX );    return( SHPOpen( pszLayer, "r+b" ) );}/************************************************************************//*                           _SHPSetBounds()                            *//*                                                                      *//*      Compute a bounds rectangle for a shape, and set it into the     *//*      indicated location in the record.                               *//************************************************************************/static void	_SHPSetBounds( uchar * pabyRec, SHPObject * psShape ){    ByteCopy( &(psShape->dfXMin), pabyRec +  0, 8 );    ByteCopy( &(psShape->dfYMin), pabyRec +  8, 8 );    ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 );    ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 );    if( bBigEndian )    {        SwapWord( 8, pabyRec + 0 );        SwapWord( 8, pabyRec + 8 );        SwapWord( 8, pabyRec + 16 );        SwapWord( 8, pabyRec + 24 );    }}/************************************************************************//*                         SHPComputeExtents()                          *//*                                                                      *//*      Recompute the extents of a shape.  Automatically done by        *//*      SHPCreateObject().                                              *//************************************************************************/void SHPComputeExtents( SHPObject * psObject ){    int		i;    /* -------------------------------------------------------------------- *//*      Build extents for this object.                                  *//* -------------------------------------------------------------------- */    if( psObject->nVertices > 0 )    {        psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];        psObject->dfYMin = psObject->dfYMax = psObject->padfY[0];        psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0];        psObject->dfMMin = psObject->dfMMax = psObject->padfM[0];    }        for( i = 0; i < psObject->nVertices; i++ )    {        psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]);        psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]);        psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]);        psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]);        psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]);        psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]);        psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]);        psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]);    }}/************************************************************************//*                          SHPCreateObject()                           *//*                                                                      *//*      Create a shape object.  It should be freed with                 *//*      SHPDestroyObject().                                             *//************************************************************************/SHPObject *SHPCreateObject( int nSHPType, int nShapeId, int nParts,                            int * panPartStart, int * panPartType,                            int nVertices, double * padfX, double * padfY,                            double * padfZ, double * padfM ){    SHPObject	*psObject;    int		i, bHasM, bHasZ;    psObject = (SHPObject *) calloc(1,sizeof(SHPObject));    psObject->nSHPType = nSHPType;    psObject->nShapeId = nShapeId;/* -------------------------------------------------------------------- *//*	Establish whether this shape type has M, and Z values.		*//* -------------------------------------------------------------------- */    if( nSHPType == SHPT_ARCM        || nSHPType == SHPT_POINTM        || nSHPType == SHPT_POLYGONM        || nSHPType == SHPT_MULTIPOINTM )    {        bHasM = TRUE;        bHasZ = FALSE;    }    else if( nSHPType == SHPT_ARCZ             || nSHPType == SHPT_POINTZ             || nSHPType == SHPT_POLYGONZ             || nSHPType == SHPT_MULTIPOINTZ             || nSHPType == SHPT_MULTIPATCH )    {        bHasM = TRUE;        bHasZ = TRUE;    }    else    {        bHasM = FALSE;        bHasZ = FALSE;    }/* -------------------------------------------------------------------- *//*      Capture parts.  Note that part type is optional, and            *//*      defaults to ring.                                               *//* -------------------------------------------------------------------- */    if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON        || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM        || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ        || nSHPType == SHPT_MULTIPATCH )    {        psObject->nParts = MAX(1,nParts);        psObject->panPartStart = (int *)            malloc(sizeof(int) * psObject->nParts);        psObject->panPartType = (int *)            malloc(sizeof(int) * psObject->nParts);        psObject->panPartStart[0] = 0;        psObject->panPartType[0] = SHPP_RING;                for( i = 0; i < nParts; i++ )        {            psObject->panPartStart[i] = panPartStart[i];            if( panPartType != NULL )                psObject->panPartType[i] = panPartType[i];            else                psObject->panPartType[i] = SHPP_RING;        }    }/* -------------------------------------------------------------------- *//*      Capture vertices.  Note that Z and M are optional, but X and    *//*      Y are not.                                                      *//* -------------------------------------------------------------------- */    psObject->padfX = (double *) calloc(sizeof(double),nVertices);    psObject->padfY = (double *) calloc(sizeof(double),nVertices);    psObject->padfZ = (double *) calloc(sizeof(double),nVertices);    psObject->padfM = (double *) calloc(sizeof(double),nVertices);    assert( padfX != NULL );    assert( padfY != NULL );        for( i = 0; i < nVertices; i++ )    {        psObject->padfX[i] = padfX[i];        psObject->padfY[i] = padfY[i];        if( padfZ != NULL && bHasZ )            psObject->padfZ[i] = padfZ[i];        if( padfM != NULL && bHasM )            psObject->padfM[i] = padfM[i];    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -