Exemple #1
0
int* SHPSearchDiskTreeEx( SHPTreeDiskHandle hDiskTree,
                          double *padfBoundsMin, double *padfBoundsMax,
                          int *pnShapeCount )

{
    int i, bNeedSwap, nBufferMax = 0;
    unsigned char abyBuf[16];
    int *panResultBuffer = NULL;

    *pnShapeCount = 0;

/* -------------------------------------------------------------------- */
/*	Establish the byte order on this machine.	  	        */
/* -------------------------------------------------------------------- */
    i = 1;
    if( *((unsigned char *) &i) == 1 )
        bBigEndian = FALSE;
    else
        bBigEndian = TRUE;

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    hDiskTree->sHooks.FSeek( hDiskTree->fpQIX, 0, SEEK_SET );
    hDiskTree->sHooks.FRead( abyBuf, 16, 1, hDiskTree->fpQIX );

    if( memcmp( abyBuf, "SQT", 3 ) != 0 )
        return NULL;

    if( (abyBuf[3] == 2 && bBigEndian)
        || (abyBuf[3] == 1 && !bBigEndian) )
        bNeedSwap = FALSE;
    else
        bNeedSwap = TRUE;

/* -------------------------------------------------------------------- */
/*      Search through root node and it's descendants.                  */
/* -------------------------------------------------------------------- */
    if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax,
                                &panResultBuffer, &nBufferMax,
                                pnShapeCount, bNeedSwap, 0 ) )
    {
        if( panResultBuffer != NULL )
            free( panResultBuffer );
        *pnShapeCount = 0;
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Sort the id array                                               */
/* -------------------------------------------------------------------- */

    /* To distinguish between empty intersection from error case */
    if( panResultBuffer == NULL )
        panResultBuffer = (int*) calloc(1, sizeof(int));
    else
        qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints);


    return panResultBuffer;
}
Exemple #2
0
SHPSearchDiskTree( FILE *fp, 
                   double *padfBoundsMin, double *padfBoundsMax,
                   int *pnShapeCount )

{
    int i, bNeedSwap, nBufferMax = 0;
    unsigned char abyBuf[16];
    int *panResultBuffer = NULL;

    *pnShapeCount = 0;

/* -------------------------------------------------------------------- */
/*	Establish the byte order on this machine.	  	        */
/* -------------------------------------------------------------------- */
    i = 1;
    if( *((unsigned char *) &i) == 1 )
        bBigEndian = FALSE;
    else
        bBigEndian = TRUE;

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    fseek( fp, 0, SEEK_SET );
    fread( abyBuf, 16, 1, fp );

    if( memcmp( abyBuf, "SQT", 3 ) != 0 )
        return NULL;

    if( (abyBuf[3] == 2 && bBigEndian)
        || (abyBuf[3] == 1 && !bBigEndian) )
        bNeedSwap = FALSE;
    else
        bNeedSwap = TRUE;

/* -------------------------------------------------------------------- */
/*      Search through root node and it's decendents.                   */
/* -------------------------------------------------------------------- */
    if( !SHPSearchDiskTreeNode( fp, padfBoundsMin, padfBoundsMax, 
                                &panResultBuffer, &nBufferMax, 
                                pnShapeCount, bNeedSwap ) )
    {
        if( panResultBuffer != NULL )
            free( panResultBuffer );
        *pnShapeCount = 0;
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Sort the id array                                               */
/* -------------------------------------------------------------------- */
    qsort(panResultBuffer, *pnShapeCount, sizeof(int), compare_ints);
    
    return panResultBuffer;
}
Exemple #3
0
static int
SHPSearchDiskTreeNode( FILE *fp, double *padfBoundsMin, double *padfBoundsMax,
                       int **ppanResultBuffer, int *pnBufferMax, 
                       int *pnResultCount, int bNeedSwap )

{
    int i;
    int offset;
    int numshapes, numsubnodes;
    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];

/* -------------------------------------------------------------------- */
/*      Read and unswap first part of node info.                        */
/* -------------------------------------------------------------------- */
    fread( &offset, 4, 1, fp );
    if ( bNeedSwap ) SwapWord ( 4, &offset );

    fread( adfNodeBoundsMin, sizeof(double), 2, fp );
    fread( adfNodeBoundsMax, sizeof(double), 2, fp );
    if ( bNeedSwap )
    {
        SwapWord( 8, adfNodeBoundsMin + 0 );
        SwapWord( 8, adfNodeBoundsMin + 1 );
        SwapWord( 8, adfNodeBoundsMax + 0 );
        SwapWord( 8, adfNodeBoundsMax + 1 );
    }
      
    fread( &numshapes, 4, 1, fp );
    if ( bNeedSwap ) SwapWord ( 4, &numshapes );

/* -------------------------------------------------------------------- */
/*      If we don't overlap this node at all, we can just fseek()       */
/*      pass this node info and all subnodes.                           */
/* -------------------------------------------------------------------- */
    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
                                padfBoundsMin, padfBoundsMax, 2 ) )
    {
        offset += numshapes*sizeof(int) + sizeof(int);
        fseek(fp, offset, SEEK_CUR);
        return TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add all the shapeids at this node to our list.                  */
/* -------------------------------------------------------------------- */
    if(numshapes > 0) 
    {
        if( *pnResultCount + numshapes > *pnBufferMax )
        {
            *pnBufferMax = (int) ((*pnResultCount + numshapes + 100) * 1.25);
            *ppanResultBuffer = (int *) 
                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );
        }

        fread( *ppanResultBuffer + *pnResultCount, 
               sizeof(int), numshapes, fp );

        if (bNeedSwap )
        {
            for( i=0; i<numshapes; i++ )
                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
        }

        *pnResultCount += numshapes; 
    } 

/* -------------------------------------------------------------------- */
/*      Process the subnodes.                                           */
/* -------------------------------------------------------------------- */
    fread( &numsubnodes, 4, 1, fp );
    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );

    for(i=0; i<numsubnodes; i++)
    {
        if( !SHPSearchDiskTreeNode( fp, padfBoundsMin, padfBoundsMax, 
                                    ppanResultBuffer, pnBufferMax, 
                                    pnResultCount, bNeedSwap ) )
            return FALSE;
    }

    return TRUE;
}
Exemple #4
0
static int
SHPSearchDiskTreeNode( SHPTreeDiskHandle hDiskTree, double *padfBoundsMin, double *padfBoundsMax,
                       int **ppanResultBuffer, int *pnBufferMax, 
                       int *pnResultCount, int bNeedSwap, int nRecLevel )

{
    unsigned int i;
    unsigned int offset;
    unsigned int numshapes, numsubnodes;
    double adfNodeBoundsMin[2], adfNodeBoundsMax[2];
    int nFReadAcc;

/* -------------------------------------------------------------------- */
/*      Read and unswap first part of node info.                        */
/* -------------------------------------------------------------------- */
    nFReadAcc = (int)hDiskTree->sHooks.FRead( &offset, 4, 1, hDiskTree->fpQIX );
    if ( bNeedSwap ) SwapWord ( 4, &offset );

    nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMin, sizeof(double), 2, hDiskTree->fpQIX );
    nFReadAcc += (int)hDiskTree->sHooks.FRead( adfNodeBoundsMax, sizeof(double), 2, hDiskTree->fpQIX );
    if ( bNeedSwap )
    {
        SwapWord( 8, adfNodeBoundsMin + 0 );
        SwapWord( 8, adfNodeBoundsMin + 1 );
        SwapWord( 8, adfNodeBoundsMax + 0 );
        SwapWord( 8, adfNodeBoundsMax + 1 );
    }
      
    nFReadAcc += (int)hDiskTree->sHooks.FRead( &numshapes, 4, 1, hDiskTree->fpQIX );
    if ( bNeedSwap ) SwapWord ( 4, &numshapes );

    /* Check that we could read all previous values */
    if( nFReadAcc != 1 + 2 + 2 + 1 )
    {
        hDiskTree->sHooks.Error("I/O error");
        return FALSE;
    }

    /* Sanity checks to avoid int overflows in later computation */
    if( offset > INT_MAX - sizeof(int) )
    {
        hDiskTree->sHooks.Error("Invalid value for offset");
        return FALSE;
    }

    if( numshapes > (INT_MAX - offset - sizeof(int)) / sizeof(int) ||
        numshapes > INT_MAX / sizeof(int) - *pnResultCount )
    {
        hDiskTree->sHooks.Error("Invalid value for numshapes");
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      If we don't overlap this node at all, we can just fseek()       */
/*      pass this node info and all subnodes.                           */
/* -------------------------------------------------------------------- */
    if( !SHPCheckBoundsOverlap( adfNodeBoundsMin, adfNodeBoundsMax, 
                                padfBoundsMin, padfBoundsMax, 2 ) )
    {
        offset += numshapes*sizeof(int) + sizeof(int);
        hDiskTree->sHooks.FSeek(hDiskTree->fpQIX, offset, SEEK_CUR);
        return TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add all the shapeids at this node to our list.                  */
/* -------------------------------------------------------------------- */
    if(numshapes > 0) 
    {
        if( *pnResultCount + numshapes > *pnBufferMax )
        {
            int* pNewBuffer;

            *pnBufferMax = (*pnResultCount + numshapes + 100) * 5 / 4;

            if( *pnBufferMax > INT_MAX / sizeof(int) )
                *pnBufferMax = *pnResultCount + numshapes;

            pNewBuffer = (int *)
                SfRealloc( *ppanResultBuffer, *pnBufferMax * sizeof(int) );

            if( pNewBuffer == NULL )
            {
                hDiskTree->sHooks.Error("Out of memory error");
                return FALSE;
            }

            *ppanResultBuffer = pNewBuffer;
        }

        if( hDiskTree->sHooks.FRead( *ppanResultBuffer + *pnResultCount,
                    sizeof(int), numshapes, hDiskTree->fpQIX ) != numshapes )
        {
            hDiskTree->sHooks.Error("I/O error");
            return FALSE;
        }

        if (bNeedSwap )
        {
            for( i=0; i<numshapes; i++ )
                SwapWord( 4, *ppanResultBuffer + *pnResultCount + i );
        }

        *pnResultCount += numshapes; 
    } 

/* -------------------------------------------------------------------- */
/*      Process the subnodes.                                           */
/* -------------------------------------------------------------------- */
    if( hDiskTree->sHooks.FRead( &numsubnodes, 4, 1, hDiskTree->fpQIX ) != 1 )
    {
        hDiskTree->sHooks.Error("I/O error");
        return FALSE;
    }
    if ( bNeedSwap  ) SwapWord ( 4, &numsubnodes );
    if( numsubnodes > 0 && nRecLevel == 32 )
    {
        hDiskTree->sHooks.Error("Shape tree is too deep");
        return FALSE;
    }

    for(i=0; i<numsubnodes; i++)
    {
        if( !SHPSearchDiskTreeNode( hDiskTree, padfBoundsMin, padfBoundsMax, 
                                    ppanResultBuffer, pnBufferMax, 
                                    pnResultCount, bNeedSwap, nRecLevel + 1 ) )
            return FALSE;
    }

    return TRUE;
}