Esempio n. 1
0
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )

{
    char *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        if (CPLStrlcat( pszStaticResult, SEP_STRING, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
            goto error;
    }

    if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    return pszStaticResult;
error:
    return CPLStaticBufferTooSmall(pszStaticResult);
}
Esempio n. 2
0
const char *CPLProjectRelativeFilename( const char *pszProjectDir,
                                        const char *pszSecondaryFilename )

{
    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    strncpy( szStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE );
    szStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/'
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        CPLAssert( strlen(SEP_STRING) + 1 < CPL_PATH_BUF_SIZE );

        strcat( szStaticResult, SEP_STRING );
    }

    CPLAssert( strlen(pszSecondaryFilename) + 1 < CPL_PATH_BUF_SIZE );

    strcat( szStaticResult, pszSecondaryFilename );

    return szStaticResult;
}
Esempio n. 3
0
bool GMLRegistryFeatureType::Parse(const char *pszRegistryFilename,
                                   CPLXMLNode *psNode)
{
    const char *pszElementName = CPLGetXMLValue(psNode, "elementName", NULL);
    const char *pszSchemaLocation =
        CPLGetXMLValue(psNode, "schemaLocation", NULL);
    const char *pszGFSSchemaLocation =
        CPLGetXMLValue(psNode, "gfsSchemaLocation", NULL);
    if( pszElementName == NULL ||
        (pszSchemaLocation == NULL && pszGFSSchemaLocation == NULL) )
        return false;

    const char *pszElementValue = CPLGetXMLValue(psNode, "elementValue", NULL);
    osElementName = pszElementName;

    if( pszSchemaLocation != NULL )
    {
        if( !STARTS_WITH(pszSchemaLocation, "http://") &&
            !STARTS_WITH(pszSchemaLocation, "https://") &&
            CPLIsFilenameRelative(pszSchemaLocation) )
        {
            pszSchemaLocation = CPLFormFilename(
                CPLGetPath(pszRegistryFilename), pszSchemaLocation, NULL );
        }
        osSchemaLocation = pszSchemaLocation;
    }
    else if( pszGFSSchemaLocation != NULL )
    {
        if( !STARTS_WITH(pszGFSSchemaLocation, "http://") &&
            !STARTS_WITH(pszGFSSchemaLocation, "https://") &&
            CPLIsFilenameRelative(pszGFSSchemaLocation) )
        {
            pszGFSSchemaLocation = CPLFormFilename(
                CPLGetPath(pszRegistryFilename), pszGFSSchemaLocation, NULL);
        }
        osGFSSchemaLocation = pszGFSSchemaLocation;
    }

    if ( pszElementValue != NULL )
    {
        osElementValue = pszElementValue;
    }

    return true;
}
Esempio n. 4
0
int GMLRegistryFeatureType::Parse(const char* pszRegistryFilename, CPLXMLNode* psNode)
{
    const char* pszElementName = CPLGetXMLValue(psNode, "elementName", NULL);
    const char* pszElementValue = CPLGetXMLValue(psNode, "elementValue", NULL);
    const char* pszSchemaLocation = CPLGetXMLValue(psNode, "schemaLocation", NULL);
    const char* pszGFSSchemaLocation = CPLGetXMLValue(psNode, "gfsSchemaLocation", NULL);
    if( pszElementName == NULL || (pszSchemaLocation == NULL && pszGFSSchemaLocation == NULL) )
        return FALSE;
    osElementName = pszElementName;

    if( pszSchemaLocation != NULL )
    {
        if( strncmp(pszSchemaLocation, "http://", 7) != 0 &&
            strncmp(pszSchemaLocation, "https://", 8) != 0 &&
            CPLIsFilenameRelative(pszSchemaLocation ) )
        {
            pszSchemaLocation = CPLFormFilename(
                CPLGetPath(pszRegistryFilename), pszSchemaLocation, NULL );
        }
        osSchemaLocation = pszSchemaLocation;
    }
    else if( pszGFSSchemaLocation != NULL )
    {
        if( strncmp(pszGFSSchemaLocation, "http://", 7) != 0 &&
            strncmp(pszGFSSchemaLocation, "https://", 8) != 0 &&
            CPLIsFilenameRelative(pszGFSSchemaLocation ) )
        {
            pszGFSSchemaLocation = CPLFormFilename(
                CPLGetPath(pszRegistryFilename), pszGFSSchemaLocation, NULL );
        }
        osGFSSchemaLocation = pszGFSSchemaLocation;
    }

    if ( pszElementValue != NULL )
    {
        osElementValue = pszElementValue; 
    }

    return TRUE;
}
Esempio n. 5
0
const char *CPLProjectRelativeFilename( const char *pszProjectDir, 
                                        const char *pszSecondaryFilename )

{
    char *pszStaticResult = CPLGetStaticResult();

    CPLAssert( ! (pszProjectDir >= pszStaticResult && pszProjectDir < pszStaticResult + CPL_PATH_BUF_SIZE) );
    CPLAssert( ! (pszSecondaryFilename >= pszStaticResult && pszSecondaryFilename < pszStaticResult + CPL_PATH_BUF_SIZE) );

    if( !CPLIsFilenameRelative( pszSecondaryFilename ) )
        return pszSecondaryFilename;

    if( pszProjectDir == NULL || strlen(pszProjectDir) == 0 )
        return pszSecondaryFilename;

    if (CPLStrlcpy( pszStaticResult, pszProjectDir, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    if( pszProjectDir[strlen(pszProjectDir)-1] != '/' 
        && pszProjectDir[strlen(pszProjectDir)-1] != '\\' )
    {
        /* FIXME? would be better to ask the filesystems what they */
        /* prefer as directory separator */
        const char* pszAddedPathSep;
        if (strncmp(pszStaticResult, "/vsicurl/", 9) == 0)
            pszAddedPathSep = "/";
        else
            pszAddedPathSep = SEP_STRING;
        if (CPLStrlcat( pszStaticResult, pszAddedPathSep, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
            goto error;
    }

    if (CPLStrlcat( pszStaticResult, pszSecondaryFilename, CPL_PATH_BUF_SIZE ) >= CPL_PATH_BUF_SIZE)
        goto error;

    return pszStaticResult;
error:
    return CPLStaticBufferTooSmall(pszStaticResult);
}
Esempio n. 6
0
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, FILE* fp, const char* tocHeader)
{
    int i, j;
    unsigned int locationSectionPhysicalLocation;
    
    unsigned short nSections;
    unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0, boundaryRectangleSectionSubHeaderLength = 0;
    unsigned int boundaryRectangleTablePhysIndex = 0, boundaryRectangleTableLength = 0;
    unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0, frameFileIndexSectionSubHeaderLength = 0;
    unsigned int frameFileIndexSubsectionPhysIndex = 0, frameFileIndexSubsectionLength = 0;
    
    unsigned int boundaryRectangleTableOffset;
    unsigned short boundaryRectangleCount;
    
    unsigned int frameIndexTableOffset;
    unsigned int nFrameFileIndexRecords;
    unsigned short nFrameFilePathnameRecords;
    unsigned short frameFileIndexRecordLength;

    int newBoundaryId = 0;

    RPFToc* toc;
    
    tocHeader += 1; /* skip endian */
    tocHeader += 2; /* skip header length */
    tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
    tocHeader += 1; /* skip new  */
    tocHeader += 15; /* skip standard_num  */
    tocHeader += 8; /* skip standard_date  */
    tocHeader += 1; /* skip classification  */
    tocHeader += 2; /* skip country  */
    tocHeader += 2; /* skip release  */
    
    memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
    CPL_MSBPTR32(&locationSectionPhysicalLocation);
    
    if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
                   locationSectionPhysicalLocation );
        return NULL;
    }
    
    /* Skip location section length (4) and component location table offset (2)*/
    VSIFSeekL( fp, 4 + 2, SEEK_CUR);
    
    /* How many sections: # of section location records */
    VSIFReadL( &nSections, 1, sizeof(nSections), fp);
    CPL_MSBPTR16( &nSections );
    
    /* Skip location record length(2) + component aggregate length(4) */
    VSIFSeekL( fp, 2 + 4, SEEK_CUR);
    
    for (i = 0; i < nSections; i++)
    {
        unsigned short id;
        unsigned int sectionLength, physIndex;
        VSIFReadL( &id, 1, sizeof(id), fp);
        CPL_MSBPTR16( &id );
        
        VSIFReadL( &sectionLength, 1, sizeof(sectionLength), fp);
        CPL_MSBPTR32( &sectionLength );
        
        VSIFReadL( &physIndex, 1, sizeof(physIndex), fp);
        CPL_MSBPTR32( &physIndex );
        
        if (id == LID_BoundaryRectangleSectionSubheader)
        {
            boundaryRectangleSectionSubHeaderPhysIndex = physIndex;
            boundaryRectangleSectionSubHeaderLength = sectionLength;
        }
        else if (id == LID_BoundaryRectangleTable)
        {
            boundaryRectangleTablePhysIndex = physIndex;
            boundaryRectangleTableLength = sectionLength;
        }
        else if (id == LID_FrameFileIndexSectionSubHeader)
        {
            frameFileIndexSectionSubHeaderPhysIndex = physIndex;
            frameFileIndexSectionSubHeaderLength = sectionLength;
        }
        else if (id == LID_FrameFileIndexSubsection)
        {
            frameFileIndexSubsectionPhysIndex = physIndex;
            frameFileIndexSubsectionLength = sectionLength;
        }
    }
    
    if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
        return NULL;
    }
    if (boundaryRectangleTablePhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
        return NULL;
    }
    if (frameFileIndexSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
        return NULL;
    }
    if (frameFileIndexSubsectionPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
        return NULL;
    }
    
    if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
                   boundaryRectangleSectionSubHeaderPhysIndex );
        return NULL;
    }
    
    VSIFReadL( &boundaryRectangleTableOffset, 1, sizeof(boundaryRectangleTableOffset), fp);
    CPL_MSBPTR32( &boundaryRectangleTableOffset );
    
    VSIFReadL( &boundaryRectangleCount, 1, sizeof(boundaryRectangleCount), fp);
    CPL_MSBPTR16( &boundaryRectangleCount );
    
    if( VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
                   boundaryRectangleTablePhysIndex );
        return NULL;
    }
    
    toc = (RPFToc*)CPLMalloc(sizeof(RPFToc));
    toc->nEntries = boundaryRectangleCount;
    toc->entries = (RPFTocEntry*)CPLMalloc(boundaryRectangleCount * sizeof(RPFTocEntry));
    memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));
    
    for(i=0;i<toc->nEntries;i++)
    {
        toc->entries[i].isOverviewOrLegend = 0;
        
        VSIFReadL( toc->entries[i].type, 1, 5, fp);
        toc->entries[i].type[5] = 0;
        RPFTOCTrim(toc->entries[i].type);
        
        VSIFReadL( toc->entries[i].compression, 1, 5, fp);
        toc->entries[i].compression[5] = 0;
        RPFTOCTrim(toc->entries[i].compression);
        
        VSIFReadL( toc->entries[i].scale, 1, 12, fp);
        toc->entries[i].scale[12] = 0;
        RPFTOCTrim(toc->entries[i].scale);
        if (toc->entries[i].scale[0] == '1' &&
            toc->entries[i].scale[1] == ':')
        {
            memmove(toc->entries[i].scale,
                    toc->entries[i].scale+2,
                    strlen(toc->entries[i].scale+2)+1);
        }
        
        VSIFReadL( toc->entries[i].zone, 1, 1, fp);
        toc->entries[i].zone[1] = 0;
        RPFTOCTrim(toc->entries[i].zone);
        
        VSIFReadL( toc->entries[i].producer, 1, 5, fp);
        toc->entries[i].producer[5] = 0;
        RPFTOCTrim(toc->entries[i].producer);

        VSIFReadL( &toc->entries[i].nwLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].nwLat);

        VSIFReadL( &toc->entries[i].nwLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].nwLong);

        VSIFReadL( &toc->entries[i].swLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].swLat);

        VSIFReadL( &toc->entries[i].swLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].swLong);

        VSIFReadL( &toc->entries[i].neLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].neLat);

        VSIFReadL( &toc->entries[i].neLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].neLong);

        VSIFReadL( &toc->entries[i].seLat, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].seLat);
        
        VSIFReadL( &toc->entries[i].seLong, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].seLong);
        
        VSIFReadL( &toc->entries[i].vertResolution, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].vertResolution);
        
        VSIFReadL( &toc->entries[i].horizResolution, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].horizResolution);
        
        VSIFReadL( &toc->entries[i].vertInterval, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].vertInterval);

        VSIFReadL( &toc->entries[i].horizInterval, 1, sizeof(double), fp);
        CPL_MSBPTR64( &toc->entries[i].horizInterval);
        
        VSIFReadL( &toc->entries[i].nVertFrames, 1, sizeof(int), fp);
        CPL_MSBPTR32( &toc->entries[i].nVertFrames );
        
        VSIFReadL( &toc->entries[i].nHorizFrames, 1, sizeof(int), fp);
        CPL_MSBPTR32( &toc->entries[i].nHorizFrames );
        
        toc->entries[i].frameEntries = (RPFTocFrameEntry*)
                VSIMalloc3(toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames, sizeof(RPFTocFrameEntry));
        if (toc->entries[i].frameEntries == NULL)
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                      "RPFTOCReadFromBuffer : Out of memory. Probably due to corrupted TOC file.");
            RPFTOCFree(toc);
            return NULL;
        }
        memset(toc->entries[i].frameEntries, 0,
               toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames * sizeof(RPFTocFrameEntry));
        
        CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
                 i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
                 toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
    }
    
    if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
                   frameFileIndexSectionSubHeaderPhysIndex );
        RPFTOCFree(toc);
        return NULL;
    }
    
    /* Skip 1 byte security classification */
    VSIFSeekL( fp, 1, SEEK_CUR );
    
    VSIFReadL( &frameIndexTableOffset, 1, sizeof(frameIndexTableOffset), fp);
    CPL_MSBPTR32( &frameIndexTableOffset );
    
    VSIFReadL( &nFrameFileIndexRecords, 1, sizeof(nFrameFileIndexRecords), fp);
    CPL_MSBPTR32( &nFrameFileIndexRecords );
    
    VSIFReadL( &nFrameFilePathnameRecords, 1, sizeof(nFrameFilePathnameRecords), fp);
    CPL_MSBPTR16( &nFrameFilePathnameRecords );
    
    VSIFReadL( &frameFileIndexRecordLength, 1, sizeof(frameFileIndexRecordLength), fp);
    CPL_MSBPTR16( &frameFileIndexRecordLength );
    
    for (i=0;i<(int)nFrameFileIndexRecords;i++)
    {
        RPFTocEntry* entry;
        RPFTocFrameEntry* frameEntry;
        unsigned short boundaryId, frameRow, frameCol;
        unsigned int offsetFrameFilePathName;
        unsigned short pathLength;
        
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
            RPFTOCFree(toc);
            return NULL;
        }

        VSIFReadL( &boundaryId, 1, sizeof(boundaryId), fp);
        CPL_MSBPTR16( &boundaryId );
        
        if (i == 0 && boundaryId == 0)
            newBoundaryId = 1;
        if (newBoundaryId == 0)
            boundaryId--;
        
        if (boundaryId >= toc->nEntries)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
                     boundaryId, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        entry = &toc->entries[boundaryId];
        entry->boundaryId = boundaryId;
        
        VSIFReadL( &frameRow, 1, sizeof(frameRow), fp);
        CPL_MSBPTR16( &frameRow );
        
        VSIFReadL( &frameCol, 1, sizeof(frameCol), fp);
        CPL_MSBPTR16( &frameCol );


        if (newBoundaryId == 0)
        {
            frameRow--;
            frameCol--;
        }
        else
        {
            /* Trick so that frames are numbered north to south */
            frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
        }
   
        if (frameRow >= entry->nVertFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                        "Invalid TOC file. Bad row num (%d) for frame file index %d.",
                        frameRow, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        if (frameCol >= entry->nHorizFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                        "Invalid TOC file. Bad col num (%d) for frame file index %d.",
                        frameCol, i);
            RPFTOCFree(toc);
            return NULL;
        }

        frameEntry = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
        frameEntry->frameRow = frameRow;
        frameEntry->frameCol = frameCol;

        if (frameEntry->exists)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                      "Invalid TOC file. Frame entry(%d,%d) for frame file index %d is a duplicate.",
                      frameRow, frameCol, i);
            RPFTOCFree(toc);
            return NULL;
        }
        
        VSIFReadL( &offsetFrameFilePathName, 1, sizeof(offsetFrameFilePathName), fp);
        CPL_MSBPTR32( &offsetFrameFilePathName );
        

        VSIFReadL( frameEntry->filename, 1, 12, fp);
        frameEntry->filename[12] = '\0';

        /* Check if the filename is an overview or legend */
        for (j=0;j<12;j++)
        {
            if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
                strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
                strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
                strcmp(&(frameEntry->filename[j]),".lgd") == 0)
            {
                entry->isOverviewOrLegend = TRUE;
                break;
            }
        }
        
        /* Extract series code */
        if (entry->seriesAbbreviation == NULL)
        {
            const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
            if (series)
            {
                entry->seriesAbbreviation = series->abbreviation;
                entry->seriesName = series->name;
            }
        }

        /* Get file geo reference */
        VSIFReadL( frameEntry->georef, 1, 6, fp);
        frameEntry->georef[6] = '\0';

        /* Go to start of pathname record */
        /* New path_off offset from start of frame file index section of TOC?? */
        /* Add pathoffset wrt frame file index table subsection (loc[3]) */
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported, 
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
            RPFTOCFree(toc);
            return NULL;
        }

        VSIFReadL( &pathLength, 1, sizeof(pathLength), fp);
        CPL_MSBPTR16( &pathLength );
        
        /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
           this leads to 4 GB allocation... Protect against this case */
        if (pathLength > 256)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Path length is big : %d. Probably corrupted TOC file.", (int)pathLength);
            RPFTOCFree(toc);
            return NULL;
        }
        
        frameEntry->directory = (char *)CPLMalloc(pathLength+1);
        VSIFReadL( frameEntry->directory, 1, pathLength, fp);
        frameEntry->directory[pathLength] = 0;
        if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
            frameEntry->directory[pathLength-1] = 0;
        
        if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
            memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);
        
        {
            char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
            VSIStatBufL sStatBuf;
            char* subdir;
            if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
                subdir = CPLStrdup(frameEntry->directory);
            else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
                subdir = CPLStrdup(baseDir);
            else
                subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, NULL));
#if !defined(_WIN32) && !defined(_WIN32_CE)
            if( VSIStatL( subdir, &sStatBuf ) != 0 && subdir[strlen(baseDir)] != 0)
            {
                char* c = subdir + strlen(baseDir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
            }
#endif
            frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
                    subdir,
                    frameEntry->filename, NULL));
            if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
            {
#if !defined(_WIN32) && !defined(_WIN32_CE)
                char* c = frameEntry->fullFilePath + strlen(subdir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
                if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
#endif
                {
                    frameEntry->fileExists = 0;
                    CPLError( CE_Warning, CPLE_AppDefined, 
                        "File %s does not exist.", frameEntry->fullFilePath );
                }
#if !defined(_WIN32) && !defined(_WIN32_CE)
                else
                {
                    frameEntry->fileExists = 1;
                }
#endif
            }
            else
            {
                frameEntry->fileExists = 1;
            }
            CPLFree(subdir);
            CPLFree(baseDir);
        }

        CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);

        frameEntry->exists = 1;
    }
    
    return toc;
}
Esempio n. 7
0
MAIN_START(argc, argv)
{
    // Check that we are running against at least GDAL 1.4.
    // Note to developers: if we use newer API, please change the requirement.
    if( atoi(GDALVersionInfo("VERSION_NUM")) < 1400 )
    {
        fprintf(stderr,
                "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n",
                argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

    GDALAllRegister();
    OGRRegisterAll();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Get commandline arguments other than the GDAL raster filenames. */
/* -------------------------------------------------------------------- */
    const char* pszIndexLayerName = nullptr;
    const char *index_filename = nullptr;
    const char *tile_index = "location";
    const char* pszDriverName = nullptr;
    size_t nMaxFieldSize = 254;
    bool write_absolute_path = false;
    char* current_path = nullptr;
    bool skip_different_projection = false;
    const char *pszTargetSRS = "";
    bool bSetTargetSRS = false;
    const char* pszSrcSRSName = nullptr;
    int i_SrcSRSName = -1;
    bool bSrcSRSFormatSpecified = false;
    SrcSRSFormat eSrcSRSFormat = FORMAT_AUTO;

    int iArg = 1;  // Used after for.
    for( ; iArg < argc; iArg++ )
    {
        if( EQUAL(argv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against "
                   "GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            CSLDestroy( argv );
            return 0;
        }
        else if( EQUAL(argv[iArg],"--help") )
            Usage(nullptr);
        else if( (strcmp(argv[iArg],"-f") == 0 || strcmp(argv[iArg],"-of") == 0) )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszDriverName = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-lyr_name") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszIndexLayerName = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-tileindex") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            tile_index = argv[++iArg];
        }
        else if( strcmp(argv[iArg],"-t_srs") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszTargetSRS = argv[++iArg];
            bSetTargetSRS = true;
        }
        else if ( strcmp(argv[iArg],"-write_absolute_path") == 0 )
        {
            write_absolute_path = true;
        }
        else if ( strcmp(argv[iArg],"-skip_different_projection") == 0 )
        {
            skip_different_projection = true;
        }
        else if( strcmp(argv[iArg], "-src_srs_name") == 0 )
        {
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszSrcSRSName = argv[++iArg];
        }
        else if( strcmp(argv[iArg], "-src_srs_format") == 0 )
        {
            const char* pszFormat;
            bSrcSRSFormatSpecified = true;
            CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
            pszFormat = argv[++iArg];
            if( EQUAL(pszFormat, "AUTO") )
                eSrcSRSFormat = FORMAT_AUTO;
            else if( EQUAL(pszFormat, "WKT") )
                eSrcSRSFormat = FORMAT_WKT;
            else if( EQUAL(pszFormat, "EPSG") )
                eSrcSRSFormat = FORMAT_EPSG;
            else if( EQUAL(pszFormat, "PROJ") )
                eSrcSRSFormat = FORMAT_PROJ;
        }
        else if( argv[iArg][0] == '-' )
            Usage(CPLSPrintf("Unknown option name '%s'", argv[iArg]));
        else if( index_filename == nullptr )
        {
            index_filename = argv[iArg];
            iArg++;
            break;
        }
    }

    if( index_filename == nullptr )
        Usage("No index filename specified.");
    if( iArg == argc )
        Usage("No file to index specified.");
    if( bSrcSRSFormatSpecified && pszSrcSRSName == nullptr )
        Usage("-src_srs_name must be specified when -src_srs_format is "
              "specified.");

/* -------------------------------------------------------------------- */
/*      Create and validate target SRS if given.                        */
/* -------------------------------------------------------------------- */
    OGRSpatialReferenceH hTargetSRS = nullptr;
    if( bSetTargetSRS )
    {
        if( skip_different_projection )
        {
            fprintf( stderr,
                     "Warning : -skip_different_projection does not apply "
                     "when -t_srs is requested.\n" );
        }
        hTargetSRS = OSRNewSpatialReference("");
        OSRSetAxisMappingStrategy(hTargetSRS, OAMS_TRADITIONAL_GIS_ORDER);
        // coverity[tainted_data]
        if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None )
        {
            OSRDestroySpatialReference( hTargetSRS );
            fprintf( stderr, "Invalid target SRS `%s'.\n",
                     pszTargetSRS );
            exit(1);
        }
    }

/* -------------------------------------------------------------------- */
/*      Open or create the target datasource                            */
/* -------------------------------------------------------------------- */
    GDALDatasetH hTileIndexDS = GDALOpenEx(
        index_filename, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr );
    OGRLayerH hLayer = nullptr;
    CPLString osFormat;
    if( hTileIndexDS != nullptr )
    {
        GDALDriverH hDriver = GDALGetDatasetDriver(hTileIndexDS);
        if( hDriver )
            osFormat = GDALGetDriverShortName(hDriver);

        if( GDALDatasetGetLayerCount(hTileIndexDS) == 1 )
        {
            hLayer = GDALDatasetGetLayer(hTileIndexDS, 0);
        }
        else
        {
            if( pszIndexLayerName == nullptr )
            {
                printf( "-lyr_name must be specified.\n" );
                exit( 1 );
            }
            CPLPushErrorHandler(CPLQuietErrorHandler);
            hLayer = GDALDatasetGetLayerByName(hTileIndexDS, pszIndexLayerName);
            CPLPopErrorHandler();
        }
    }
    else
    {
        printf( "Creating new index file...\n" );
        if( pszDriverName == nullptr )
        {
            std::vector<CPLString> aoDrivers =
                GetOutputDriversFor(index_filename, GDAL_OF_VECTOR);
            if( aoDrivers.empty() )
            {
                CPLError( CE_Failure, CPLE_AppDefined,
                        "Cannot guess driver for %s", index_filename);
                exit( 10 );
            }
            else
            {
                if( aoDrivers.size() > 1 )
                {
                    CPLError( CE_Warning, CPLE_AppDefined,
                            "Several drivers matching %s extension. Using %s",
                            CPLGetExtension(index_filename), aoDrivers[0].c_str() );
                }
                osFormat = aoDrivers[0];
            }
        }
        else
        {
            osFormat = pszDriverName;
        }
        if( !EQUAL(osFormat, "ESRI Shapefile") )
            nMaxFieldSize = 0;


        GDALDriverH hDriver = GDALGetDriverByName( osFormat.c_str() );
        if( hDriver == nullptr )
        {
            printf( "%s driver not available.\n", osFormat.c_str() );
            exit( 1 );
        }

        hTileIndexDS = 
            GDALCreate( hDriver, index_filename, 0, 0, 0, GDT_Unknown, nullptr );
    }

    if( hTileIndexDS != nullptr && hLayer == nullptr )
    {
        OGRSpatialReferenceH hSpatialRef = nullptr;
        char* pszLayerName = nullptr;
        if( pszIndexLayerName == nullptr )
        {
            VSIStatBuf sStat;
            if( EQUAL(osFormat, "ESRI Shapefile") ||
                VSIStat(index_filename, &sStat) == 0 )
            {
                pszLayerName = CPLStrdup(CPLGetBasename(index_filename));
            }
            else
            {
                printf( "-lyr_name must be specified.\n" );
                exit( 1 );
            }
        }
        else
        {
            pszLayerName = CPLStrdup(pszIndexLayerName);
        }

        /* get spatial reference for output file from target SRS (if set) */
        /* or from first input file */
        if( bSetTargetSRS )
        {
            hSpatialRef = OSRClone( hTargetSRS );
        }
        else
        {
            GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly );
            if( hDS )
            {
                const char* pszWKT = GDALGetProjectionRef(hDS);
                if (pszWKT != nullptr && pszWKT[0] != '\0')
                {
                    hSpatialRef = OSRNewSpatialReference(pszWKT);
                    OSRSetAxisMappingStrategy(hSpatialRef, OAMS_TRADITIONAL_GIS_ORDER);
                }
                GDALClose(hDS);
            }
        }

        hLayer =
            GDALDatasetCreateLayer( hTileIndexDS, pszLayerName, hSpatialRef,
                                wkbPolygon, nullptr );
        CPLFree(pszLayerName);
        if( hSpatialRef )
            OSRRelease(hSpatialRef);

        if( hLayer )
        {
            OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString );
            if( nMaxFieldSize )
                OGR_Fld_SetWidth( hFieldDefn, static_cast<int>(nMaxFieldSize));
            OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
            OGR_Fld_Destroy(hFieldDefn);
            if( pszSrcSRSName != nullptr )
            {
                hFieldDefn = OGR_Fld_Create( pszSrcSRSName, OFTString );
                if( nMaxFieldSize )
                    OGR_Fld_SetWidth(hFieldDefn,
                                     static_cast<int>(nMaxFieldSize));
                OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
                OGR_Fld_Destroy(hFieldDefn);
            }
        }
    }

    if( hTileIndexDS == nullptr || hLayer == nullptr )
    {
        fprintf( stderr, "Unable to open/create shapefile `%s'.\n",
                 index_filename );
        exit(2);
    }

    OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer);

    const int ti_field = OGR_FD_GetFieldIndex( hFDefn, tile_index );
    if( ti_field < 0 )
    {
        fprintf( stderr, "Unable to find field `%s' in file `%s'.\n",
                 tile_index, index_filename );
        exit(2);
    }

    if( pszSrcSRSName != nullptr )
        i_SrcSRSName = OGR_FD_GetFieldIndex( hFDefn, pszSrcSRSName );

    // Load in memory existing file names in SHP.
    int nExistingFiles = static_cast<int>(OGR_L_GetFeatureCount(hLayer, FALSE));
    if( nExistingFiles < 0)
        nExistingFiles = 0;

    char** existingFilesTab = nullptr;
    bool alreadyExistingProjectionRefValid = false;
    char* alreadyExistingProjectionRef = nullptr;
    if( nExistingFiles > 0 )
    {
        OGRFeatureH hFeature = nullptr;
        existingFilesTab = static_cast<char **>(
            CPLMalloc(nExistingFiles * sizeof(char*)));
        for( int i = 0; i < nExistingFiles; i++ )
        {
            hFeature = OGR_L_GetNextFeature(hLayer);
            existingFilesTab[i] =
                CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field ));
            if( i == 0 )
            {
                GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly );
                if( hDS )
                {
                    alreadyExistingProjectionRefValid = true;
                    alreadyExistingProjectionRef =
                        CPLStrdup(GDALGetProjectionRef(hDS));
                    GDALClose(hDS);
                }
            }
            OGR_F_Destroy( hFeature );
        }
    }

    if( write_absolute_path )
    {
        current_path = CPLGetCurrentDir();
        if (current_path == nullptr)
        {
            fprintf( stderr,
                     "This system does not support the CPLGetCurrentDir call. "
                     "The option -write_absolute_path will have no effect\n" );
            write_absolute_path = FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      loop over GDAL files, processing.                               */
/* -------------------------------------------------------------------- */
    for( ; iArg < argc; iArg++ )
    {
        char *fileNameToWrite = nullptr;
        VSIStatBuf sStatBuf;

        // Make sure it is a file before building absolute path name.
        if( write_absolute_path && CPLIsFilenameRelative( argv[iArg] ) &&
            VSIStat( argv[iArg], &sStatBuf ) == 0 )
        {
            fileNameToWrite =
                CPLStrdup(CPLProjectRelativeFilename(current_path, argv[iArg]));
        }
        else
        {
            fileNameToWrite = CPLStrdup(argv[iArg]);
        }

        // Checks that file is not already in tileindex.
        {
            int i = 0;  // Used after for.
            for( ; i < nExistingFiles; i++ )
            {
                if (EQUAL(fileNameToWrite, existingFilesTab[i]))
                {
                    fprintf(stderr,
                            "File %s is already in tileindex. Skipping it.\n",
                            fileNameToWrite);
                    break;
                }
            }
            if (i != nExistingFiles)
            {
                CPLFree(fileNameToWrite);
                continue;
            }
        }

        GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly );
        if( hDS == nullptr )
        {
            fprintf( stderr, "Unable to open %s, skipping.\n",
                     argv[iArg] );
            CPLFree(fileNameToWrite);
            continue;
        }

        double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
        GDALGetGeoTransform( hDS, adfGeoTransform );
        if( adfGeoTransform[0] == 0.0
            && adfGeoTransform[1] == 1.0
            && adfGeoTransform[3] == 0.0
            && std::abs(adfGeoTransform[5]) == 1.0 )
        {
            fprintf( stderr,
                     "It appears no georeferencing is available for\n"
                     "`%s', skipping.\n",
                     argv[iArg] );
            GDALClose( hDS );
            CPLFree(fileNameToWrite);
            continue;
        }

        const char *projectionRef = GDALGetProjectionRef(hDS);

        // If not set target srs, test that the current file uses same
        // projection as others.
        if( !bSetTargetSRS )
        {
            if( alreadyExistingProjectionRefValid )
            {
                int projectionRefNotNull, alreadyExistingProjectionRefNotNull;
                projectionRefNotNull = projectionRef && projectionRef[0];
                alreadyExistingProjectionRefNotNull =
                    alreadyExistingProjectionRef &&
                    alreadyExistingProjectionRef[0];
                if ((projectionRefNotNull &&
                     alreadyExistingProjectionRefNotNull &&
                     EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) ||
                    (projectionRefNotNull != alreadyExistingProjectionRefNotNull))
                {
                    fprintf(
                        stderr,
                        "Warning : %s is not using the same projection system "
                        "as other files in the tileindex.\n"
                        "This may cause problems when using it in MapServer "
                        "for example.\n"
                        "Use -t_srs option to set target projection system "
                        "(not supported by MapServer).\n"
                        "%s\n", argv[iArg],
                        skip_different_projection ? "Skipping this file." : "");
                    if( skip_different_projection )
                    {
                        CPLFree(fileNameToWrite);
                        GDALClose( hDS );
                        continue;
                    }
                }
            }
            else
            {
                alreadyExistingProjectionRefValid = true;
                alreadyExistingProjectionRef = CPLStrdup(projectionRef);
            }
        }

        const int nXSize = GDALGetRasterXSize( hDS );
        const int nYSize = GDALGetRasterYSize( hDS );

        double adfX[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
        double adfY[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
        adfX[0] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[0] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        adfX[1] = adfGeoTransform[0]
            + nXSize * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[1] = adfGeoTransform[3]
            + nXSize * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        adfX[2] = adfGeoTransform[0]
            + nXSize * adfGeoTransform[1]
            + nYSize * adfGeoTransform[2];
        adfY[2] = adfGeoTransform[3]
            + nXSize * adfGeoTransform[4]
            + nYSize * adfGeoTransform[5];

        adfX[3] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + nYSize * adfGeoTransform[2];
        adfY[3] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + nYSize * adfGeoTransform[5];

        adfX[4] = adfGeoTransform[0]
            + 0 * adfGeoTransform[1]
            + 0 * adfGeoTransform[2];
        adfY[4] = adfGeoTransform[3]
            + 0 * adfGeoTransform[4]
            + 0 * adfGeoTransform[5];

        OGRSpatialReferenceH hSourceSRS = nullptr;
        if( (bSetTargetSRS || i_SrcSRSName >= 0) &&
            projectionRef != nullptr &&
            projectionRef[0] != '\0' )
        {
            hSourceSRS = OSRNewSpatialReference( projectionRef );
            OSRSetAxisMappingStrategy(hSourceSRS, OAMS_TRADITIONAL_GIS_ORDER);
        }

        // If set target srs, do the forward transformation of all points.
        if( bSetTargetSRS && projectionRef != nullptr && projectionRef[0] != '\0' )
        {
            OGRCoordinateTransformationH hCT = nullptr;
            if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) )
            {
                hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS );
                if( hCT == nullptr || !OCTTransform( hCT, 5, adfX, adfY, nullptr ) )
                {
                    fprintf(
                        stderr,
                        "Warning : unable to transform points from source "
                        "SRS `%s' to target SRS `%s'\n"
                        "for file `%s' - file skipped\n",
                        projectionRef, pszTargetSRS, fileNameToWrite );
                    if( hCT )
                        OCTDestroyCoordinateTransformation( hCT );
                    if( hSourceSRS )
                        OSRDestroySpatialReference( hSourceSRS );
                    continue;
                }
                if( hCT )
                    OCTDestroyCoordinateTransformation( hCT );
            }
        }

        OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
        OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite );

        if( i_SrcSRSName >= 0 && hSourceSRS != nullptr )
        {
            const char* pszAuthorityCode =
                OSRGetAuthorityCode(hSourceSRS, nullptr);
            const char* pszAuthorityName =
                OSRGetAuthorityName(hSourceSRS, nullptr);
            if( eSrcSRSFormat == FORMAT_AUTO )
            {
                if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr )
                {
                    OGR_F_SetFieldString(
                        hFeature, i_SrcSRSName,
                        CPLSPrintf("%s:%s",
                                   pszAuthorityName, pszAuthorityCode) );
                }
                else if( nMaxFieldSize == 0 ||
                         strlen(projectionRef) <= nMaxFieldSize )
                {
                    OGR_F_SetFieldString(hFeature, i_SrcSRSName, projectionRef);
                }
                else
                {
                    char* pszProj4 = nullptr;
                    if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE )
                    {
                        OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                              pszProj4 );
                        CPLFree(pszProj4);
                    }
                    else
                    {
                        OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                              projectionRef );
                    }
                }
            }
            else if( eSrcSRSFormat == FORMAT_WKT )
            {
                if( nMaxFieldSize == 0 ||
                    strlen(projectionRef) <= nMaxFieldSize )
                {
                    OGR_F_SetFieldString( hFeature, i_SrcSRSName,
                                          projectionRef );
                }
                else
                {
                    fprintf(stderr,
                            "Cannot write WKT for file %s as it is too long!\n",
                            fileNameToWrite);
                }
            }
            else if( eSrcSRSFormat == FORMAT_PROJ )
            {
                char* pszProj4 = nullptr;
                if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE )
                {
                    OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 );
                    CPLFree(pszProj4);
                }
            }
            else if( eSrcSRSFormat == FORMAT_EPSG )
            {
                if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr )
                    OGR_F_SetFieldString(
                        hFeature, i_SrcSRSName,
                        CPLSPrintf("%s:%s",
                                   pszAuthorityName, pszAuthorityCode) );
            }
        }
        if( hSourceSRS )
            OSRDestroySpatialReference( hSourceSRS );

        OGRGeometryH hPoly = OGR_G_CreateGeometry(wkbPolygon);
        OGRGeometryH hRing = OGR_G_CreateGeometry(wkbLinearRing);
        for( int k = 0; k < 5; k++ )
            OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]);
        OGR_G_AddGeometryDirectly( hPoly, hRing );
        OGR_F_SetGeometryDirectly( hFeature, hPoly );

        if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
        {
           printf( "Failed to create feature in shapefile.\n" );
           break;
        }

        OGR_F_Destroy( hFeature );

        CPLFree(fileNameToWrite);

        GDALClose( hDS );
    }

    CPLFree(current_path);

    if (nExistingFiles)
    {
        for( int i = 0; i < nExistingFiles; i++ )
        {
            CPLFree(existingFilesTab[i]);
        }
        CPLFree(existingFilesTab);
    }
    CPLFree(alreadyExistingProjectionRef);

    if ( hTargetSRS )
        OSRDestroySpatialReference( hTargetSRS );

    GDALClose( hTileIndexDS );

    GDALDestroyDriverManager();
    OGRCleanupAll();
    CSLDestroy(argv);

    exit( 0 );
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
    const char *index_filename = NULL;
    const char *tile_index = "location";
    int		i_arg, ti_field;
    OGRDataSourceH hTileIndexDS;
    OGRLayerH hLayer = NULL;
    OGRFeatureDefnH hFDefn;
    int write_absolute_path = FALSE;
    char* current_path = NULL;
    int i;
    int nExistingFiles;
    int skip_different_projection = FALSE;
    char** existingFilesTab = NULL;
    int alreadyExistingProjectionRefValid = FALSE;
    char* alreadyExistingProjectionRef = NULL;
    char* index_filename_mod;
    int bExists;
    VSIStatBuf sStatBuf;
    const char *pszTargetSRS = "";
    int bSetTargetSRS = FALSE;
    OGRSpatialReferenceH hTargetSRS = NULL;

    /* Check that we are running against at least GDAL 1.4 */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
    {
        fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

    GDALAllRegister();
    OGRRegisterAll();

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );

/* -------------------------------------------------------------------- */
/*      Get commandline arguments other than the GDAL raster filenames. */
/* -------------------------------------------------------------------- */
    for( i_arg = 1; i_arg < argc; i_arg++ )
    {
        if( EQUAL(argv[i_arg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( strcmp(argv[i_arg],"-tileindex") == 0 )
        {
            tile_index = argv[++i_arg];
        }
        else if( strcmp(argv[i_arg],"-t_srs") == 0 )
        {
            pszTargetSRS = argv[++i_arg];
            bSetTargetSRS = TRUE;
        }
        else if ( strcmp(argv[i_arg],"-write_absolute_path") == 0 )
        {
            write_absolute_path = TRUE;
        }
        else if ( strcmp(argv[i_arg],"-skip_different_projection") == 0 )
        {
            skip_different_projection = TRUE;
        }
        else if( argv[i_arg][0] == '-' )
            Usage();
        else if( index_filename == NULL )
        {
            index_filename = argv[i_arg];
            i_arg++;
            break;
        }
    }
 
    if( index_filename == NULL || i_arg == argc )
        Usage();

/* -------------------------------------------------------------------- */
/*      Create and validate target SRS if given.                        */
/* -------------------------------------------------------------------- */
   if( bSetTargetSRS )
   {  
       if ( skip_different_projection )
       {
           fprintf( stderr, 
                    "Warning : -skip_different_projection does not apply "
                    "when -t_srs is requested.\n" );
       }
       hTargetSRS = OSRNewSpatialReference("");
       if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None )
       {
           OSRDestroySpatialReference( hTargetSRS );
           fprintf( stderr, "Invalid target SRS `%s'.\n", 
                    pszTargetSRS );
           exit(1);
       }
   }

/* -------------------------------------------------------------------- */
/*      Open or create the target shapefile and DBF file.               */
/* -------------------------------------------------------------------- */
    index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp"));

    bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0);
    if (!bExists)
    {
        CPLFree(index_filename_mod);
        index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP"));
        bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0);
    }
    CPLFree(index_filename_mod);

    if (bExists)
    {
        hTileIndexDS = OGROpen( index_filename, TRUE, NULL );
        if (hTileIndexDS != NULL)
        {
            hLayer = OGR_DS_GetLayer(hTileIndexDS, 0);
        }
    }
    else
    {
        OGRSFDriverH hDriver;
        const char* pszDriverName = "ESRI Shapefile";

        printf( "Creating new index file...\n" );
        hDriver = OGRGetDriverByName( pszDriverName );
        if( hDriver == NULL )
        {
            printf( "%s driver not available.\n", pszDriverName );
            exit( 1 );
        }

        hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL );
        if (hTileIndexDS)
        {
            char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename));

            /* get spatial reference for output file from target SRS (if set) */
            /* or from first input file */
            OGRSpatialReferenceH hSpatialRef = NULL;
            if( bSetTargetSRS )
            {
                hSpatialRef = OSRClone( hTargetSRS );
            }
            else
            {
                GDALDatasetH hDS = GDALOpen( argv[i_arg], GA_ReadOnly );
                if (hDS)
                {
                    const char* pszWKT = GDALGetProjectionRef(hDS);
                    if (pszWKT != NULL && pszWKT[0] != '\0')
                    {
                        hSpatialRef = OSRNewSpatialReference(pszWKT);
                    }
                    GDALClose(hDS);
                }
            }

            hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL );
            CPLFree(pszLayerName);
            if (hSpatialRef)
                OSRRelease(hSpatialRef);

            if (hLayer)
            {
                OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString );
                OGR_Fld_SetWidth( hFieldDefn, 255);
                OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
                OGR_Fld_Destroy(hFieldDefn);
            }
        }
    }

    if( hTileIndexDS == NULL || hLayer == NULL )
    {
        fprintf( stderr, "Unable to open/create shapefile `%s'.\n", 
                 index_filename );
        exit(2);
    }

    hFDefn = OGR_L_GetLayerDefn(hLayer);

    for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ )
    {
        OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field );
        if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 )
            break;
    }

    if( ti_field == OGR_FD_GetFieldCount(hFDefn) )
    {
        fprintf( stderr, "Unable to find field `%s' in DBF file `%s'.\n", 
                 tile_index, index_filename );
        exit(2);
    }

    /* Load in memory existing file names in SHP */
    nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE);
    if (nExistingFiles)
    {
        OGRFeatureH hFeature;
        existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*));
        for(i=0;i<nExistingFiles;i++)
        {
            hFeature = OGR_L_GetNextFeature(hLayer);
            existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field ));
            if (i == 0)
            {
                GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly );
                if (hDS)
                {
                    alreadyExistingProjectionRefValid = TRUE;
                    alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS));
                    GDALClose(hDS);
                }
            }
            OGR_F_Destroy( hFeature );
        }
    }

    if (write_absolute_path)
    {
        current_path = CPLGetCurrentDir();
        if (current_path == NULL)
        {
            fprintf( stderr, "This system does not support the CPLGetCurrentDir call. "
                             "The option -write_absolute_path will have no effect\n");
            write_absolute_path = FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      loop over GDAL files, processing.                               */
/* -------------------------------------------------------------------- */
    for( ; i_arg < argc; i_arg++ )
    {
        GDALDatasetH	hDS;
        double	        adfGeoTransform[6];
        double		adfX[5], adfY[5];
        int		nXSize, nYSize;
        char* fileNameToWrite;
        const char* projectionRef;
        VSIStatBuf sStatBuf;
        int k;
        OGRFeatureH hFeature;
        OGRGeometryH hPoly, hRing;

        /* Make sure it is a file before building absolute path name */
        if (write_absolute_path && CPLIsFilenameRelative( argv[i_arg] ) &&
            VSIStat( argv[i_arg], &sStatBuf ) == 0)
        {
            fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[i_arg]));
        }
        else
        {
            fileNameToWrite = CPLStrdup(argv[i_arg]);
        }

        /* Checks that file is not already in tileindex */
        for(i=0;i<nExistingFiles;i++)
        {
            if (EQUAL(fileNameToWrite, existingFilesTab[i]))
            {
                fprintf(stderr, "File %s is already in tileindex. Skipping it.\n",
                        fileNameToWrite);
                break;
            }
        }
        if (i != nExistingFiles)
        {
            CPLFree(fileNameToWrite);
            continue;
        }

        hDS = GDALOpen( argv[i_arg], GA_ReadOnly );
        if( hDS == NULL )
        {
            fprintf( stderr, "Unable to open %s, skipping.\n", 
                     argv[i_arg] );
            CPLFree(fileNameToWrite);
            continue;
        }

        GDALGetGeoTransform( hDS, adfGeoTransform );
        if( adfGeoTransform[0] == 0.0 
            && adfGeoTransform[1] == 1.0
            && adfGeoTransform[3] == 0.0
            && ABS(adfGeoTransform[5]) == 1.0 )
        {
            fprintf( stderr, 
                     "It appears no georeferencing is available for\n"
                     "`%s', skipping.\n", 
                     argv[i_arg] );
            GDALClose( hDS );
            CPLFree(fileNameToWrite);
            continue;
        }

        projectionRef = GDALGetProjectionRef(hDS);

        /* if not set target srs, test that the current file uses same projection as others */
        if( !bSetTargetSRS )
        { 
            if (alreadyExistingProjectionRefValid)
            {
                int projectionRefNotNull, alreadyExistingProjectionRefNotNull;
                projectionRefNotNull = projectionRef && projectionRef[0];
                alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0];
                if ((projectionRefNotNull &&
                     alreadyExistingProjectionRefNotNull &&
                     EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) ||
                    (projectionRefNotNull != alreadyExistingProjectionRefNotNull))
                {
                    fprintf(stderr, "Warning : %s is not using the same projection system as "
                            "other files in the tileindex.\n"
			    "This may cause problems when using it in MapServer for example.\n"
                            "Use -t_srs option to set target projection system (not supported by MapServer).\n"
                            "%s\n", argv[i_arg],
                            (skip_different_projection) ? "Skipping this file." : "");
                    if (skip_different_projection)
                    {
                        CPLFree(fileNameToWrite);
                        GDALClose( hDS );
                        continue;
                    }
                }
            }
            else
            {
                alreadyExistingProjectionRefValid = TRUE;
                alreadyExistingProjectionRef = CPLStrdup(projectionRef);
            }
        }

        nXSize = GDALGetRasterXSize( hDS );
        nYSize = GDALGetRasterYSize( hDS );
        
        adfX[0] = adfGeoTransform[0] 
            + 0 * adfGeoTransform[1] 
            + 0 * adfGeoTransform[2];
        adfY[0] = adfGeoTransform[3] 
            + 0 * adfGeoTransform[4] 
            + 0 * adfGeoTransform[5];
        
        adfX[1] = adfGeoTransform[0] 
            + nXSize * adfGeoTransform[1] 
            + 0 * adfGeoTransform[2];
        adfY[1] = adfGeoTransform[3] 
            + nXSize * adfGeoTransform[4] 
            + 0 * adfGeoTransform[5];
        
        adfX[2] = adfGeoTransform[0] 
            + nXSize * adfGeoTransform[1] 
            + nYSize * adfGeoTransform[2];
        adfY[2] = adfGeoTransform[3] 
            + nXSize * adfGeoTransform[4] 
            + nYSize * adfGeoTransform[5];
        
        adfX[3] = adfGeoTransform[0] 
            + 0 * adfGeoTransform[1] 
            + nYSize * adfGeoTransform[2];
        adfY[3] = adfGeoTransform[3] 
            + 0 * adfGeoTransform[4] 
            + nYSize * adfGeoTransform[5];
        
        adfX[4] = adfGeoTransform[0] 
            + 0 * adfGeoTransform[1] 
            + 0 * adfGeoTransform[2];
        adfY[4] = adfGeoTransform[3] 
            + 0 * adfGeoTransform[4] 
            + 0 * adfGeoTransform[5];

        /* if set target srs, do the forward transformation of all points */
        if( bSetTargetSRS )
        {
            OGRSpatialReferenceH hSourceSRS = NULL;
            OGRCoordinateTransformationH hCT = NULL;
            hSourceSRS = OSRNewSpatialReference( projectionRef );
            if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) )
            {
                hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS );
                if( hCT == NULL || !OCTTransform( hCT, 5, adfX, adfY, NULL ) )
                {
                    fprintf( stderr, 
                             "Warning : unable to transform points from source SRS `%s' to target SRS `%s'\n"
                             "for file `%s' - file skipped\n", 
                             projectionRef, pszTargetSRS, fileNameToWrite );
                    if ( hCT ) 
                        OCTDestroyCoordinateTransformation( hCT );
                    if ( hSourceSRS )
                        OSRDestroySpatialReference( hSourceSRS );
                    continue;
                }
                if ( hCT ) 
                    OCTDestroyCoordinateTransformation( hCT );
            }
            if ( hSourceSRS )
                OSRDestroySpatialReference( hSourceSRS );
        }

        hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
        OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite );

        hPoly = OGR_G_CreateGeometry(wkbPolygon);
        hRing = OGR_G_CreateGeometry(wkbLinearRing);
        for(k=0;k<5;k++)
            OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]);
        OGR_G_AddGeometryDirectly( hPoly, hRing );
        OGR_F_SetGeometryDirectly( hFeature, hPoly );

        if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
        {
           printf( "Failed to create feature in shapefile.\n" );
           break;
        }

        OGR_F_Destroy( hFeature );

        
        CPLFree(fileNameToWrite);

        GDALClose( hDS );
    }
    
    CPLFree(current_path);
    
    if (nExistingFiles)
    {
        for(i=0;i<nExistingFiles;i++)
        {
            CPLFree(existingFilesTab[i]);
        }
        CPLFree(existingFilesTab);
    }
    CPLFree(alreadyExistingProjectionRef);

    if ( hTargetSRS )
        OSRDestroySpatialReference( hTargetSRS );

    OGR_DS_Destroy( hTileIndexDS );
    
    GDALDestroyDriverManager();
    OGRCleanupAll();
    CSLDestroy(argv);
    
    exit( 0 );
} 
Esempio n. 9
0
const char *CPLExtractRelativePath( const char *pszBaseDir, 
                                    const char *pszTarget,
                                    int *pbGotRelative )

{
    size_t nBasePathLen;

/* -------------------------------------------------------------------- */
/*      If we don't have a basedir, then we can't relativize the path.  */
/* -------------------------------------------------------------------- */
    if( pszBaseDir == NULL )
    {
        if( pbGotRelative != NULL )
            *pbGotRelative = FALSE;

        return pszTarget;
    }

    nBasePathLen = strlen(pszBaseDir);

/* -------------------------------------------------------------------- */
/*      One simple case is when the base dir is '.' and the target      */
/*      filename is relative.                                           */
/* -------------------------------------------------------------------- */
    if( (nBasePathLen == 0 || EQUAL(pszBaseDir,"."))
        && CPLIsFilenameRelative(pszTarget) )
    {
        if( pbGotRelative != NULL )
            *pbGotRelative = TRUE;

        return pszTarget;
    }

/* -------------------------------------------------------------------- */
/*      By this point, if we don't have a base path, we can't have a    */
/*      meaningful common prefix.                                       */
/* -------------------------------------------------------------------- */
    if( nBasePathLen == 0 )
    {
        if( pbGotRelative != NULL )
            *pbGotRelative = FALSE;

        return pszTarget;
    }

/* -------------------------------------------------------------------- */
/*      If we don't have a common path prefix, then we can't get a      */
/*      relative path.                                                  */
/* -------------------------------------------------------------------- */
    if( !EQUALN(pszBaseDir,pszTarget,nBasePathLen) 
        || (pszTarget[nBasePathLen] != '\\' 
            && pszTarget[nBasePathLen] != '/') )
    {
        if( pbGotRelative != NULL )
            *pbGotRelative = FALSE;

        return pszTarget;
    }

/* -------------------------------------------------------------------- */
/*      We have a relative path.  Strip it off to get a string to       */
/*      return.                                                         */
/* -------------------------------------------------------------------- */
    if( pbGotRelative != NULL )
        *pbGotRelative = TRUE;

    return pszTarget + nBasePathLen + 1;
}
Esempio n. 10
0
  int tindex(maps*& conf, maps*& inputs,maps*& outputs)
  {
    char *index_filename = NULL;
    const char *tile_index = "location";
    int		i_arg, ti_field;
    OGRDataSourceH hTileIndexDS;
    OGRLayerH hLayer = NULL;
    OGRFeatureDefnH hFDefn;
    int write_absolute_path = FALSE;
    char* current_path = NULL;
    int i;
    int nExistingFiles;
    int skip_different_projection = FALSE;
    char** existingFilesTab = NULL;
    int alreadyExistingProjectionRefValid = FALSE;
    char* alreadyExistingProjectionRef = NULL;
    char* index_filename_mod;
    int bExists;
    VSIStatBuf sStatBuf;

    /* Check that we are running against at least GDAL 1.4 */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
      {
	char tmp[1024];
        sprintf(tmp, "At least, GDAL >= 1.4.0 is required for this version of"
		"tindex, which was compiled against GDAL %s\n", GDAL_RELEASE_NAME);
        return SERVICE_FAILED;
      }

    GDALAllRegister();
    OGRRegisterAll();


    /* -------------------------------------------------------------------- */
    /*      Get the directory name to search for raster file to index.      */
    /* -------------------------------------------------------------------- */
    char *tmpDataDir;
    char *pszDataDir;
    map* tmpMap=getMapFromMaps(conf,"main","isTrial");      
    map* tmpMap1=getMapFromMaps(conf,"main","dataPath");
    map* tmpInputMap=getMapFromMaps(inputs,"dir","value");
    if(tmpMap!=NULL && strcasecmp(tmpMap->value,"true")==0){
      pszDataDir=(char*) malloc((strlen(tmpInputMap->value)+strlen(tmpMap1->value)+5+1)*sizeof(char));
      sprintf(pszDataDir,"%s/ftp/%s",tmpMap1->value,tmpInputMap->value);
    }else{
      pszDataDir=(char*) malloc(((strlen(tmpInputMap->value)+1)*sizeof(char)));
      sprintf(pszDataDir,"%s",tmpInputMap->value);
    }
    
    tmpMap=getMapFromMaps(inputs,"iname","value");
    tmpMap1=getMapFromMaps(inputs,"idir","value");
    map* tmpMap2=getMapFromMaps(conf,"main","dataPath");
    if(tmpMap!=NULL && tmpMap1!=NULL && tmpMap2!=NULL){
      index_filename = (char*) malloc((strlen(tmpMap->value)+strlen(tmpMap1->value)+strlen(tmpMap2->value)+12)*sizeof(char));
      sprintf(index_filename,"%s/dirs/%s/%s.shp",tmpMap2->value,tmpMap1->value,tmpMap->value);
    }
    fprintf(stderr,"Filename %s\n",index_filename);
    /* -------------------------------------------------------------------- */
    /*      Open or create the target shapefile and DBF file.               */
    /* -------------------------------------------------------------------- */
    index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp"));

    bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0);
    if (!bExists)
      {
        CPLFree(index_filename_mod);
        index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP"));
        bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0);
      }
    CPLFree(index_filename_mod);

    if (bExists)
      {
        hTileIndexDS = OGROpen( index_filename, TRUE, NULL );
        if (hTileIndexDS != NULL)
	  {
            hLayer = OGR_DS_GetLayer(hTileIndexDS, 0);
	  }
      }
    else
      {
        OGRSFDriverH hDriver;
        const char* pszDriverName = "ESRI Shapefile";

        fprintf( stderr,"Creating new index file...\n" );
        hDriver = OGRGetDriverByName( pszDriverName );
        if( hDriver == NULL )
	  {
	    char msg[1024];
            sprintf( msg, "%s driver not available.", pszDriverName );
	    setMapInMaps(conf,"lenv","message",msg);
	    return SERVICE_FAILED;
	  }

        hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL );
        if (hTileIndexDS)
	  {
            char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename));
            OGRSpatialReferenceH hSpatialRef = NULL;
            GDALDatasetH hDS = GDALOpen( index_filename, GA_ReadOnly );
            if (hDS)
	      {
                const char* pszWKT = GDALGetProjectionRef(hDS);
                if (pszWKT != NULL && pszWKT[0] != '\0')
		  {
                    hSpatialRef = OSRNewSpatialReference(pszWKT);
		  }
                GDALClose(hDS);
	      }

	    DIR *dirp = opendir(pszDataDir);
	    if(dirp==NULL){
	      char tmp1[1024];
	      sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir);
	      setMapInMaps(conf,"lenv","message",tmp1);
	      return SERVICE_FAILED;
	    }
	    char *res=NULL;
	    struct dirent *dp;
	    tmpMap=getMapFromMaps(inputs,"ext","value");
	    char *ext;
	    if(tmpMap!=NULL)
	      ext=tmpMap->value;
	    while ((dp = readdir(dirp)) != NULL){
	      if(strncmp(dp->d_name,".",1)!=0&&strncmp(dp->d_name,"..",2)!=0){
		char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char));
		sprintf(argv,"%s/%s",pszDataDir,dp->d_name);
		GDALDatasetH hDS0 = GDALOpen( argv, GA_ReadOnly );
		if (hDS0)
		  {
		    const char* pszWKT = GDALGetProjectionRef(hDS0);
		    fprintf(stderr,"SRS %s \n",pszWKT);
		    if (pszWKT != NULL && pszWKT[0] != '\0')
		      {
			if (hSpatialRef)
			  OSRRelease(hSpatialRef);
			hSpatialRef = OSRNewSpatialReference(pszWKT);
		      }
		    GDALClose(hDS);
		  }
		break;
	      }
	    }
	    closedir(dirp);
            hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL );
            CPLFree(pszLayerName);
            if (hSpatialRef)
	      OSRRelease(hSpatialRef);

            if (hLayer)
	      {
                OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString );
                OGR_Fld_SetWidth( hFieldDefn, 255);
                OGR_L_CreateField( hLayer, hFieldDefn, TRUE );
                OGR_Fld_Destroy(hFieldDefn);
	      }
	  }
      }

    if( hTileIndexDS == NULL || hLayer == NULL )
      {
	char msg[1024];
        sprintf( msg, "Unable to open/create shapefile `%s'.", 
                 index_filename );
	setMapInMaps(conf,"lenv","message",msg);
      }

    hFDefn = OGR_L_GetLayerDefn(hLayer);

    for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ )
      {
        OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field );
        if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 )
	  break;
      }

    if( ti_field == OGR_FD_GetFieldCount(hFDefn) )
      {
	char msg[1024];
        sprintf( msg, "Unable to find field `%s' in DBF file `%s'.\n", 
                 tile_index, index_filename );
	setMapInMaps(conf,"lenv","message",msg);
	return SERVICE_FAILED;
      }

    /* Load in memory existing file names in SHP */
    nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE);
    if (nExistingFiles)
      {
        OGRFeatureH hFeature;
        existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*));
        for(i=0;i<nExistingFiles;i++)
	  {
            hFeature = OGR_L_GetNextFeature(hLayer);
            existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field ));
            if (i == 0)
	      {
                GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly );
                if (hDS)
		  {
                    alreadyExistingProjectionRefValid = TRUE;
                    alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS));
                    GDALClose(hDS);
		  }
	      }
            OGR_F_Destroy( hFeature );
	  }
      }

    if (write_absolute_path)
      {
        current_path = CPLGetCurrentDir();
        if (current_path == NULL)
	  {
            fprintf( stderr, "This system does not support the CPLGetCurrentDir call. "
		     "The option -write_absolute_path will have no effect\n");
            write_absolute_path = FALSE;
	  }
      }

      
    /* -------------------------------------------------------------------- */
    /*      loop over GDAL files, processing.                               */
    /* -------------------------------------------------------------------- */
    DIR *dirp = opendir(pszDataDir);
    if(dirp==NULL){
      char tmp1[1024];
      sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir);
      setMapInMaps(conf,"lenv","message",tmp1);
      return SERVICE_FAILED;
    }
    char *res=NULL;
    struct dirent *dp;
    tmpMap=getMapFromMaps(inputs,"ext","value");
    char *ext;
    if(tmpMap!=NULL)
      ext=tmpMap->value;
    while ((dp = readdir(dirp)) != NULL){
      
      if(strlen(dp->d_name)>2 && strstr(dp->d_name,".")!=0 && strstr(dp->d_name,ext)>0){
	char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char));
	sprintf(argv,"%s/%s",pszDataDir,dp->d_name);


        GDALDatasetH	hDS;
        double	        adfGeoTransform[6];
        double		adfX[5], adfY[5];
        int		nXSize, nYSize;
        char* fileNameToWrite;
        const char* projectionRef;
        VSIStatBuf sStatBuf;
        int k;
        OGRFeatureH hFeature;
        OGRGeometryH hPoly, hRing;

        /* Make sure it is a file before building absolute path name */
        if (write_absolute_path && CPLIsFilenameRelative( argv ) &&
            VSIStat( argv, &sStatBuf ) == 0)
	  {
            fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv));
	  }
        else
	  {
            fileNameToWrite = CPLStrdup(argv);
	  }

        /* Checks that file is not already in tileindex */
        for(i=0;i<nExistingFiles;i++)
	  {
            if (EQUAL(fileNameToWrite, existingFilesTab[i]))
	      {
                fprintf(stderr, "File %s is already in tileindex. Skipping it.\n",
                        fileNameToWrite);
                break;
	      }
	  }
        if (i != nExistingFiles)
	  {
            CPLFree(fileNameToWrite);
            continue;
	  }

        hDS = GDALOpen( argv, GA_ReadOnly );
        if( hDS == NULL )
	  {
            fprintf( stderr, "Unable to open %s, skipping.\n", 
                     argv );
            CPLFree(fileNameToWrite);
	    continue;
	  }

        GDALGetGeoTransform( hDS, adfGeoTransform );
        if( adfGeoTransform[0] == 0.0 
            && adfGeoTransform[1] == 1.0
            && adfGeoTransform[3] == 0.0
            && ABS(adfGeoTransform[5]) == 1.0 )
	  {
            fprintf( stderr, 
                     "It appears no georeferencing is available for\n"
                     "`%s', skipping.\n", 
                     argv );
            GDALClose( hDS );
            CPLFree(fileNameToWrite);
            continue;
	  }

        projectionRef = GDALGetProjectionRef(hDS);
        if (alreadyExistingProjectionRefValid)
	  {
            int projectionRefNotNull, alreadyExistingProjectionRefNotNull;
            projectionRefNotNull = projectionRef && projectionRef[0];
            alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0];
            if ((projectionRefNotNull &&
                 alreadyExistingProjectionRefNotNull &&
                 EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) ||
                (projectionRefNotNull != alreadyExistingProjectionRefNotNull))
	      {
                fprintf(stderr, "Warning : %s is not using the same projection system as "
			"other files in the tileindex. This may cause problems when "
			"using it in MapServer for example.%s\n", argv,
			(skip_different_projection) ? " Skipping it" : "");
                if (skip_different_projection)
		  {
                    CPLFree(fileNameToWrite);
                    GDALClose( hDS );
                    continue;
		  }
	      }
	  }
        else
	  {
            alreadyExistingProjectionRefValid = TRUE;
            alreadyExistingProjectionRef = CPLStrdup(projectionRef);
	  }

        nXSize = GDALGetRasterXSize( hDS );
        nYSize = GDALGetRasterYSize( hDS );
        
        adfX[0] = adfGeoTransform[0] 
	  + 0 * adfGeoTransform[1] 
	  + 0 * adfGeoTransform[2];
        adfY[0] = adfGeoTransform[3] 
	  + 0 * adfGeoTransform[4] 
	  + 0 * adfGeoTransform[5];
        
        adfX[1] = adfGeoTransform[0] 
	  + nXSize * adfGeoTransform[1] 
	  + 0 * adfGeoTransform[2];
        adfY[1] = adfGeoTransform[3] 
	  + nXSize * adfGeoTransform[4] 
	  + 0 * adfGeoTransform[5];
        
        adfX[2] = adfGeoTransform[0] 
	  + nXSize * adfGeoTransform[1] 
	  + nYSize * adfGeoTransform[2];
        adfY[2] = adfGeoTransform[3] 
	  + nXSize * adfGeoTransform[4] 
	  + nYSize * adfGeoTransform[5];
        
        adfX[3] = adfGeoTransform[0] 
	  + 0 * adfGeoTransform[1] 
	  + nYSize * adfGeoTransform[2];
        adfY[3] = adfGeoTransform[3] 
	  + 0 * adfGeoTransform[4] 
	  + nYSize * adfGeoTransform[5];
        
        adfX[4] = adfGeoTransform[0] 
	  + 0 * adfGeoTransform[1] 
	  + 0 * adfGeoTransform[2];
        adfY[4] = adfGeoTransform[3] 
	  + 0 * adfGeoTransform[4] 
	  + 0 * adfGeoTransform[5];

        hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) );
        OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite );

        hPoly = OGR_G_CreateGeometry(wkbPolygon);
        hRing = OGR_G_CreateGeometry(wkbLinearRing);
        for(k=0;k<5;k++)
	  OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]);
        OGR_G_AddGeometryDirectly( hPoly, hRing );
        OGR_F_SetGeometryDirectly( hFeature, hPoly );

        if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE )
	  {
	    fprintf( stderr, "Failed to create feature in shapefile.\n" );
	    break;
	  }

        OGR_F_Destroy( hFeature );

        
        CPLFree(fileNameToWrite);

        GDALClose( hDS );
      }
    }
    
    CPLFree(current_path);
    
    if (nExistingFiles)
      {
        for(i=0;i<nExistingFiles;i++)
	  {
            CPLFree(existingFilesTab[i]);
	  }
        CPLFree(existingFilesTab);
      }
    CPLFree(alreadyExistingProjectionRef);

    OGR_DS_Destroy( hTileIndexDS );
    
    GDALDestroyDriverManager();
    OGRCleanupAll();
    setMapInMaps(outputs,"Result","value","Tile index successfully created.");
    //CSLDestroy(argv);
    
    return SERVICE_SUCCEEDED;
  } 
Esempio n. 11
0
GDALDataset *OZIDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if (!Identify(poOpenInfo))
        return NULL;

    GByte abyHeader[14];
    CPLString osImgFilename = poOpenInfo->pszFilename;
    int bIsMap = FALSE;
    if (EQUALN((const char*)poOpenInfo->pabyHeader,
        "OziExplorer Map Data File Version ", 34) )
    {
        char** papszLines = CSLLoad2( poOpenInfo->pszFilename, 1000, 200, NULL );
        if ( !papszLines || CSLCount(papszLines) < 5)
        {
            CSLDestroy(papszLines);
            return FALSE;
        }

        bIsMap = TRUE;

        osImgFilename = papszLines[2];
        VSIStatBufL sStat;
        if (VSIStatL(osImgFilename, &sStat) != 0)
        {
            if (CPLIsFilenameRelative(osImgFilename))
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
            else
            {
                CPLString osPath = CPLGetPath(poOpenInfo->pszFilename);
                osImgFilename = CPLGetFilename(osImgFilename);
                osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL);
            }
        }

        CSLDestroy(papszLines);

        GDALOpenInfo oOpenInfo(osImgFilename, GA_ReadOnly);
        if (!Identify(&oOpenInfo))
            return NULL;
        memcpy(abyHeader, oOpenInfo.pabyHeader, 14);
    }
    else
        memcpy(abyHeader, poOpenInfo->pabyHeader, 14);

    int bOzi3 = (abyHeader[0] == 0x80 &&
                 abyHeader[1] == 0x77);

    VSILFILE* fp = VSIFOpenL(osImgFilename.c_str(), "rb");
    if (fp == NULL)
        return NULL;

    OZIDataset* poDS = new OZIDataset();
    poDS->fp = fp;

    if (bIsMap)
    {
        poDS->bReadMapFileSuccess =
            GDALLoadOziMapFile( poOpenInfo->pszFilename,
                                poDS->adfGeoTransform,
                                &poDS->pszWKT,
                                &poDS->nGCPCount,
                                &poDS->pasGCPs );
    }

    GByte nRandomNumber = 0;
    GByte nKeyInit = 0;
    if (bOzi3)
    {
        VSIFSeekL(fp, 14, SEEK_SET);
        VSIFReadL(&nRandomNumber, 1, 1, fp);
        //printf("nRandomNumber = %d\n", nRandomNumber);
        if (nRandomNumber < 0x94)
        {
            delete poDS;
            return NULL;
        }
        VSIFSeekL(fp, 0x93, SEEK_CUR);
        VSIFReadL(&nKeyInit, 1, 1, fp);

        VSIFSeekL(fp, 0, SEEK_SET);
        VSIFReadL(abyHeader, 1, 14, fp);
        OZIDecrypt(abyHeader, 14, nKeyInit);
        if (!(abyHeader[6] == 0x40 &&
           abyHeader[7] == 0x00 &&
           abyHeader[8] == 0x01 &&
           abyHeader[9] == 0x00 &&
           abyHeader[10] == 0x36 &&
           abyHeader[11] == 0x04 &&
           abyHeader[12] == 0x00 &&
           abyHeader[13] == 0x00))
        {
            delete poDS;
            return NULL;
        }

        VSIFSeekL(fp, 14 + 1 + nRandomNumber, SEEK_SET);
        int nMagic = ReadInt(fp, bOzi3, nKeyInit);
        CPLDebug("OZI", "OZI version code : 0x%08X", nMagic);

        poDS->bOzi3 = bOzi3;
    }
    else
    {
        VSIFSeekL(fp, 14, SEEK_SET);
    }

    GByte abyHeader2[40], abyHeader2_Backup[40];
    VSIFReadL(abyHeader2, 40, 1, fp);
    memcpy(abyHeader2_Backup, abyHeader2, 40);

    /* There's apparently a relationship between the nMagic number */
    /* and the nKeyInit, but I'm too lazy to add switch/cases that might */
    /* be not exhaustive, so let's try the 'brute force' attack !!! */
    /* It is much so funny to be able to run one in a few microseconds :-) */
    for(nKeyInit = 0; nKeyInit < 256; nKeyInit ++)
    {
        GByte* pabyHeader2 = abyHeader2;
        if (bOzi3)
            OZIDecrypt(abyHeader2, 40, nKeyInit);

        int nHeaderSize = ReadInt(&pabyHeader2); /* should be 40 */
        poDS->nRasterXSize = ReadInt(&pabyHeader2);
        poDS->nRasterYSize = ReadInt(&pabyHeader2);
        int nDepth = ReadShort(&pabyHeader2); /* should be 1 */
        int nBPP = ReadShort(&pabyHeader2); /* should be 8 */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* pixel number (height * width) : unused */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* reserved */
        ReadInt(&pabyHeader2); /* ?? 0x100 */
        ReadInt(&pabyHeader2); /* ?? 0x100 */

        if (nHeaderSize != 40 || nDepth != 1 || nBPP != 8)
        {
            if (bOzi3)
            {
                if (nKeyInit != 255)
                {
                    memcpy(abyHeader2, abyHeader2_Backup,40);
                    continue;
                }
                else
                {
                    CPLDebug("OZI", "Cannot decypher 2nd header. Sorry...");
                    delete poDS;
                    return NULL;
                }
            }
            else
            {
                CPLDebug("OZI", "nHeaderSize = %d, nDepth = %d, nBPP = %d",
                        nHeaderSize, nDepth, nBPP);
                delete poDS;
                return NULL;
            }
        }
        else
            break;
    }
    poDS->nKeyInit = nKeyInit;

    int nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        CPLDebug("OZI", "didn't get end of header2 marker");
        delete poDS;
        return NULL;
    }

    poDS->nZoomLevelCount = ReadShort(fp);
    //CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
    if (poDS->nZoomLevelCount < 0 || poDS->nZoomLevelCount >= 256)
    {
        CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount);
        delete poDS;
        return NULL;
    }

    /* Skip array of zoom level percentage. We don't need it for GDAL */
    VSIFSeekL(fp, sizeof(float) * poDS->nZoomLevelCount, SEEK_CUR);

    nSeparator = ReadInt(fp);
    if (!bOzi3 && nSeparator != 0x77777777)
    {
        /* Some files have 8 extra bytes before the marker. I'm not sure */
        /* what they are used for. So just skeep them and hope that */
        /* we'll find the marker */
        nSeparator = ReadInt(fp);
        nSeparator = ReadInt(fp);
        if (nSeparator != 0x77777777)
        {
            CPLDebug("OZI", "didn't get end of zoom levels marker");
            delete poDS;
            return NULL;
        }
    }

    VSIFSeekL(fp, 0, SEEK_END);
    vsi_l_offset nFileSize = VSIFTellL(fp);
    poDS->nFileSize = nFileSize;
    VSIFSeekL(fp, nFileSize - 4, SEEK_SET);
    int nZoomLevelTableOffset = ReadInt(fp, bOzi3, nKeyInit);
    if (nZoomLevelTableOffset < 0 ||
        (vsi_l_offset)nZoomLevelTableOffset >= nFileSize)
    {
        CPLDebug("OZI", "nZoomLevelTableOffset = %d",
                 nZoomLevelTableOffset);
        delete poDS;
        return NULL;
    }

    VSIFSeekL(fp, nZoomLevelTableOffset, SEEK_SET);

    poDS->panZoomLevelOffsets =
        (int*)CPLMalloc(sizeof(int) * poDS->nZoomLevelCount);
    int i;
    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        poDS->panZoomLevelOffsets[i] = ReadInt(fp, bOzi3, nKeyInit);
        if (poDS->panZoomLevelOffsets[i] < 0 ||
            (vsi_l_offset)poDS->panZoomLevelOffsets[i] >= nFileSize)
        {
            CPLDebug("OZI", "panZoomLevelOffsets[%d] = %d",
                     i, poDS->panZoomLevelOffsets[i]);
            delete poDS;
            return NULL;
        }
    }

    poDS->papoBands =
        (OZIRasterBand**)CPLCalloc(sizeof(OZIRasterBand*), poDS->nZoomLevelCount);

    for(i=0;i<poDS->nZoomLevelCount;i++)
    {
        VSIFSeekL(fp, poDS->panZoomLevelOffsets[i], SEEK_SET);
        int nW = ReadInt(fp, bOzi3, nKeyInit);
        int nH = ReadInt(fp, bOzi3, nKeyInit);
        short nTileX = ReadShort(fp, bOzi3, nKeyInit);
        short nTileY = ReadShort(fp, bOzi3, nKeyInit);
        if (i == 0 && (nW != poDS->nRasterXSize || nH != poDS->nRasterYSize))
        {
            CPLDebug("OZI", "zoom[%d] inconsistant dimensions for zoom level 0 : nW=%d, nH=%d, nTileX=%d, nTileY=%d, nRasterXSize=%d, nRasterYSize=%d",
                     i, nW, nH, nTileX, nTileY, poDS->nRasterXSize, poDS->nRasterYSize);
            delete poDS;
            return NULL;
        }
        /* Note (#3895): some files such as world.ozf2 provided with OziExplorer */
        /* expose nTileY=33, but have nH=2048, so only require 32 tiles in vertical dimension. */
        /* So there's apparently one extra and useless tile that will be ignored */
        /* without causing apparent issues */
        /* Some other files have more tile in horizontal direction than needed, so let's */
        /* accept that. But in that case we really need to keep the nTileX value for IReadBlock() */
        /* to work properly */
        if ((nW + 63) / 64 > nTileX || (nH + 63) / 64 > nTileY)
        {
            CPLDebug("OZI", "zoom[%d] unexpected number of tiles : nW=%d, nH=%d, nTileX=%d, nTileY=%d",
                     i, nW, nH, nTileX, nTileY);
            delete poDS;
            return NULL;
        }

        GDALColorTable* poColorTable = new GDALColorTable();
        GByte abyColorTable[256*4];
        VSIFReadL(abyColorTable, 1, 1024, fp);
        if (bOzi3)
            OZIDecrypt(abyColorTable, 1024, nKeyInit);
        int j;
        for(j=0;j<256;j++)
        {
            GDALColorEntry sEntry;
            sEntry.c1 = abyColorTable[4*j + 2];
            sEntry.c2 = abyColorTable[4*j + 1];
            sEntry.c3 = abyColorTable[4*j + 0];
            sEntry.c4 = 255;
            poColorTable->SetColorEntry(j, &sEntry);
        }

        poDS->papoBands[i] = new OZIRasterBand(poDS, i, nW, nH, nTileX, poColorTable);

        if (i > 0)
        {
            GByte* pabyTranslationTable =
                poDS->papoBands[i]->GetIndexColorTranslationTo(poDS->papoBands[0], NULL, NULL);

            delete poDS->papoBands[i]->poColorTable;
            poDS->papoBands[i]->poColorTable = poDS->papoBands[0]->poColorTable->Clone();
            poDS->papoBands[i]->pabyTranslationTable = pabyTranslationTable;
        }

    }

    poDS->SetBand(1, poDS->papoBands[0]);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Support overviews.                                              */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
    return( poDS );
}
Esempio n. 12
0
static
void CPLXMLSchemaResolveInclude( const char* pszMainSchemaLocation,
                                 CPLXMLNode *psSchemaNode )
{
    std::set<CPLString> osAlreadyIncluded;

    bool bTryAgain;
    do
    {
        CPLXMLNode *psLast = NULL;
        bTryAgain = false;

        CPLXMLNode *psThis = psSchemaNode->psChild;
        for( ; psThis != NULL; psThis = psThis->psNext )
        {
            if( psThis->eType == CXT_Element &&
                EQUAL(psThis->pszValue,"include") )
            {
                const char* pszSchemaLocation =
                        CPLGetXMLValue(psThis, "schemaLocation", NULL);
                if( pszSchemaLocation != NULL &&
                    osAlreadyIncluded.count( pszSchemaLocation) == 0 )
                {
                    osAlreadyIncluded.insert( pszSchemaLocation );

                    if( !STARTS_WITH(pszSchemaLocation, "http://") &&
                        !STARTS_WITH(pszSchemaLocation, "https://") &&
                        CPLIsFilenameRelative(pszSchemaLocation ) )
                    {
                        pszSchemaLocation = CPLFormFilename(
                            CPLGetPath(pszMainSchemaLocation), pszSchemaLocation, NULL );
                    }

                    CPLXMLNode *psIncludedXSDTree =
                                GMLParseXMLFile( pszSchemaLocation );
                    if( psIncludedXSDTree != NULL )
                    {
                        CPLStripXMLNamespace( psIncludedXSDTree, NULL, TRUE );
                        CPLXMLNode *psIncludedSchemaNode =
                                CPLGetXMLNode( psIncludedXSDTree, "=schema" );
                        if( psIncludedSchemaNode != NULL )
                        {
                            /* Substitute de <include> node by its content */
                            CPLXMLNode* psFirstChildElement =
                                CPLGetFirstChildNode(psIncludedSchemaNode);
                            if( psFirstChildElement != NULL )
                            {
                                CPLXMLNode* psCopy = CPLCloneXMLTree(psFirstChildElement);
                                if( psLast != NULL )
                                    psLast->psNext = psCopy;
                                else
                                    psSchemaNode->psChild = psCopy;
                                CPLXMLNode* psNext = psThis->psNext;
                                psThis->psNext = NULL;
                                CPLDestroyXMLNode(psThis);
                                psThis = CPLGetLastNode(psCopy);
                                psThis->psNext = psNext;

                                /* In case the included schema also contains */
                                /* includes */
                                bTryAgain = true;
                            }

                        }
                        CPLDestroyXMLNode( psIncludedXSDTree );
                    }
                }
            }

            psLast = psThis;
        }
    } while( bTryAgain );

    const char* pszSchemaOutputName =
        CPLGetConfigOption("GML_SCHEMA_OUTPUT_NAME", NULL);
    if( pszSchemaOutputName != NULL )
    {
        CPLSerializeXMLTreeToFile( psSchemaNode, pszSchemaOutputName );
    }
}
Esempio n. 13
0
OGRErr FGdbDriver::StartTransaction(OGRDataSource*& poDSInOut, int& bOutHasReopenedDS)
{
    CPLMutexHolderOptionalLockD(hMutex);

    bOutHasReopenedDS = FALSE;

    OGRMutexedDataSource* poMutexedDS = (OGRMutexedDataSource*)poDSInOut;
    FGdbDataSource* poDS = (FGdbDataSource* )poMutexedDS->GetBaseDataSource();
    if( !poDS->GetUpdate() )
        return OGRERR_FAILURE;
    FGdbDatabaseConnection* pConnection = poDS->GetConnection();
    if( pConnection->GetRefCount() != 1 )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Cannot start transaction as database is opened in another connection");
        return OGRERR_FAILURE;
    }
    if( pConnection->IsLocked() )
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "Transaction is already in progress");
        return OGRERR_FAILURE;
    }

    bOutHasReopenedDS = TRUE;

    CPLString osName(poMutexedDS->GetName());
    CPLString osNameOri(osName);
    if( osName[osName.size()-1] == '/' || osName[osName.size()-1] == '\\' )
        osName.resize(osName.size()-1);

#ifndef WIN32
    int bPerLayerCopyingForTransaction = poDS->HasPerLayerCopyingForTransaction();
#endif

    pConnection->m_nRefCount ++;
    delete poDSInOut;
    poDSInOut = NULL;
    poMutexedDS = NULL;
    poDS = NULL;

    pConnection->CloseGeodatabase();

    CPLString osEditedName(osName);
    osEditedName += ".ogredited";

    CPLPushErrorHandler(CPLQuietErrorHandler);
    CPL_IGNORE_RET_VAL(CPLUnlinkTree(osEditedName));
    CPLPopErrorHandler();

    OGRErr eErr = OGRERR_NONE;
    
    CPLString osDatabaseToReopen;
#ifndef WIN32
    if( bPerLayerCopyingForTransaction )
    {
        int bError = FALSE;
        
        if( VSIMkdir( osEditedName, 0755 ) != 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "Cannot create directory '%s'.",
                      osEditedName.c_str() );
            bError = TRUE;
        }

        // Only copy a0000000X.Y files with X >= 1 && X <= 8, gdb and timestamps
        // and symlink others
        char** papszFiles = VSIReadDir(osName);
        for(char** papszIter = papszFiles; !bError && *papszIter; ++papszIter)
        {
            if( strcmp(*papszIter, ".") == 0 || strcmp(*papszIter, "..") == 0 )
                continue;
            if( ((*papszIter)[0] == 'a' && atoi((*papszIter)+1) >= 1 &&
                 atoi((*papszIter)+1) <= 8) || EQUAL(*papszIter, "gdb") ||
                 EQUAL(*papszIter, "timestamps") )
            {
                if( CPLCopyFile(CPLFormFilename(osEditedName, *papszIter, NULL),
                                CPLFormFilename(osName, *papszIter, NULL)) != 0 )
                {
                    bError = TRUE;
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Cannot copy %s", *papszIter);
                }
            }
            else
            {
                CPLString osSourceFile;
                if( CPLIsFilenameRelative(osName) )
                    osSourceFile = CPLFormFilename(CPLSPrintf("../%s", CPLGetFilename(osName.c_str())), *papszIter, NULL);
                else
                    osSourceFile = osName;
                if( EQUAL(CPLGetConfigOption("FGDB_SIMUL_FAIL", ""), "CASE1") ||
                    CPLSymlink( osSourceFile,
                                CPLFormFilename(osEditedName.c_str(), *papszIter, NULL),
                                NULL ) != 0 )
                {
                    bError = TRUE;
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Cannot symlink %s", *papszIter);
                }
            }
        }
        CSLDestroy(papszFiles);

        if( bError )
        {
            eErr = OGRERR_FAILURE;
            osDatabaseToReopen = osName;
        }
        else
            osDatabaseToReopen = osEditedName;
    }
    else
#endif
    {
        if( EQUAL(CPLGetConfigOption("FGDB_SIMUL_FAIL", ""), "CASE1") ||
            CPLCopyTree( osEditedName, osName ) != 0 )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                    "Cannot backup geodatabase");
            eErr = OGRERR_FAILURE;
            osDatabaseToReopen = osName;
        }
        else
            osDatabaseToReopen = osEditedName;
    }

    pConnection->m_pGeodatabase = new Geodatabase;
    long hr = ::OpenGeodatabase(StringToWString(osDatabaseToReopen), *(pConnection->m_pGeodatabase));
    if( EQUAL(CPLGetConfigOption("FGDB_SIMUL_FAIL", ""), "CASE2") || FAILED(hr))
    {
        delete pConnection->m_pGeodatabase;
        pConnection->m_pGeodatabase = NULL;
        Release(osName);
        GDBErr(hr, CPLSPrintf("Failed to open %s. Dataset should be closed",
                              osDatabaseToReopen.c_str()));

        return OGRERR_FAILURE;
    }

    FGdbDataSource* pDS = new FGdbDataSource(this, pConnection);
    pDS->Open(osDatabaseToReopen, TRUE, osNameOri);

#ifndef WIN32
    if( eErr == OGRERR_NONE && bPerLayerCopyingForTransaction )
    {
        pDS->SetPerLayerCopyingForTransaction(bPerLayerCopyingForTransaction);
        pDS->SetSymlinkFlagOnAllLayers();
    }
#endif

    poDSInOut = new OGRMutexedDataSource(pDS, TRUE, hMutex, TRUE);

    if( eErr == OGRERR_NONE )
        pConnection->SetLocked(TRUE);
    return eErr;
}
Esempio n. 14
0
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, VSILFILE* fp, const char* tocHeader)
{
    tocHeader += 1; /* skip endian */
    tocHeader += 2; /* skip header length */
    tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
    tocHeader += 1; /* skip new  */
    tocHeader += 15; /* skip standard_num  */
    tocHeader += 8; /* skip standard_date  */
    tocHeader += 1; /* skip classification  */
    tocHeader += 2; /* skip country  */
    tocHeader += 2; /* skip release  */

    unsigned int locationSectionPhysicalLocation;
    memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
    CPL_MSBPTR32(&locationSectionPhysicalLocation);

    if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
                   locationSectionPhysicalLocation );
        return nullptr;
    }

    int nSections;
    NITFLocation* pasLocations = NITFReadRPFLocationTable(fp, &nSections);

    unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0;
    unsigned int boundaryRectangleTablePhysIndex = 0;
    unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0;
    unsigned int frameFileIndexSubsectionPhysIndex = 0;

    for( int i = 0; i < nSections; i++ )
    {
        if (pasLocations[i].nLocId == LID_BoundaryRectangleSectionSubheader)
        {
            boundaryRectangleSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_BoundaryRectangleTable)
        {
            boundaryRectangleTablePhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSectionSubHeader)
        {
            frameFileIndexSectionSubHeaderPhysIndex = pasLocations[i].nLocOffset;
        }
        else if (pasLocations[i].nLocId == LID_FrameFileIndexSubsection)
        {
            frameFileIndexSubsectionPhysIndex = pasLocations[i].nLocOffset;
        }
    }

    CPLFree(pasLocations);

    if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
        return nullptr;
    }
    if (boundaryRectangleTablePhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
        return nullptr;
    }
    if (frameFileIndexSectionSubHeaderPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
        return nullptr;
    }
    if (frameFileIndexSubsectionPhysIndex == 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
        return nullptr;
    }

    if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
                   boundaryRectangleSectionSubHeaderPhysIndex );
        return nullptr;
    }

    unsigned int boundaryRectangleTableOffset;
    bool bOK = VSIFReadL( &boundaryRectangleTableOffset, sizeof(boundaryRectangleTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &boundaryRectangleTableOffset );

    unsigned short boundaryRectangleCount;
    bOK &= VSIFReadL( &boundaryRectangleCount, sizeof(boundaryRectangleCount), 1, fp) == 1;
    CPL_MSBPTR16( &boundaryRectangleCount );

    if( !bOK || VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
                   boundaryRectangleTablePhysIndex );
        return nullptr;
    }

    RPFToc* toc = reinterpret_cast<RPFToc *>( CPLMalloc( sizeof( RPFToc ) ) );
    toc->nEntries = boundaryRectangleCount;
    toc->entries = reinterpret_cast<RPFTocEntry *>(
        CPLMalloc( boundaryRectangleCount * sizeof(RPFTocEntry) ) );
    memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));

    for( int i = 0; i < toc->nEntries; i++ )
    {
        toc->entries[i].isOverviewOrLegend = 0;

        bOK &= VSIFReadL( toc->entries[i].type, 1, 5, fp) == 5;
        toc->entries[i].type[5] = 0;
        RPFTOCTrim(toc->entries[i].type);

        bOK &= VSIFReadL( toc->entries[i].compression, 1, 5, fp) == 5;
        toc->entries[i].compression[5] = 0;
        RPFTOCTrim(toc->entries[i].compression);

        bOK &= VSIFReadL( toc->entries[i].scale, 1, 12, fp) == 12;
        toc->entries[i].scale[12] = 0;
        RPFTOCTrim(toc->entries[i].scale);
        if (toc->entries[i].scale[0] == '1' &&
            toc->entries[i].scale[1] == ':')
        {
            memmove(toc->entries[i].scale,
                    toc->entries[i].scale+2,
                    strlen(toc->entries[i].scale+2)+1);
        }

        bOK &= VSIFReadL( toc->entries[i].zone, 1, 1, fp) == 1;
        toc->entries[i].zone[1] = 0;
        RPFTOCTrim(toc->entries[i].zone);

        bOK &= VSIFReadL( toc->entries[i].producer, 1, 5, fp) == 5;
        toc->entries[i].producer[5] = 0;
        RPFTOCTrim(toc->entries[i].producer);

        bOK &= VSIFReadL( &toc->entries[i].nwLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLat);

        bOK &= VSIFReadL( &toc->entries[i].nwLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].nwLong);

        bOK &= VSIFReadL( &toc->entries[i].swLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLat);

        bOK &= VSIFReadL( &toc->entries[i].swLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].swLong);

        bOK &= VSIFReadL( &toc->entries[i].neLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLat);

        bOK &= VSIFReadL( &toc->entries[i].neLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].neLong);

        bOK &= VSIFReadL( &toc->entries[i].seLat, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLat);

        bOK &= VSIFReadL( &toc->entries[i].seLong, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].seLong);

        bOK &= VSIFReadL( &toc->entries[i].vertResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertResolution);

        bOK &= VSIFReadL( &toc->entries[i].horizResolution, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizResolution);

        bOK &= VSIFReadL( &toc->entries[i].vertInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].vertInterval);

        bOK &= VSIFReadL( &toc->entries[i].horizInterval, sizeof(double), 1, fp) == 1;
        CPL_MSBPTR64( &toc->entries[i].horizInterval);

        bOK &= VSIFReadL( &toc->entries[i].nVertFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nVertFrames );

        bOK &= VSIFReadL( &toc->entries[i].nHorizFrames, sizeof(int), 1, fp) == 1;
        CPL_MSBPTR32( &toc->entries[i].nHorizFrames );

        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        if( toc->entries[i].vertInterval <= 1e-10 ||
            !CPLIsFinite(toc->entries[i].vertInterval) ||
            toc->entries[i].horizInterval <= 1e-10 ||
            !CPLIsFinite(toc->entries[i].horizInterval) ||
            !(fabs(toc->entries[i].seLong) <= 360.0) ||
            !(fabs(toc->entries[i].nwLong) <= 360.0) ||
            !(fabs(toc->entries[i].nwLat) <= 90.0) ||
            !(fabs(toc->entries[i].seLat) <= 90.0) ||
            toc->entries[i].seLong < toc->entries[i].nwLong ||
            toc->entries[i].nwLat < toc->entries[i].seLat ||
            toc->entries[i].nHorizFrames == 0 ||
            toc->entries[i].nVertFrames == 0 ||
            toc->entries[i].nHorizFrames > INT_MAX / toc->entries[i].nVertFrames )
        {
            CPLError(CE_Failure, CPLE_FileIO, "Invalid TOC entry");
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        // TODO: We could probably use another data structure, like a list,
        // instead of an array referenced by the frame coordinate...
        if( static_cast<int>(toc->entries[i].nHorizFrames *
                                  toc->entries[i].nVertFrames) >
                 atoi(CPLGetConfigOption("RPFTOC_MAX_FRAME_COUNT", "1000000")) )
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "nHorizFrames=%d x nVertFrames=%d > %d. Please raise "
                     "the value of the RPFTOC_MAX_FRAME_COUNT configuration "
                     "option to more than %d if this dataset is legitimate.",
                     toc->entries[i].nHorizFrames, toc->entries[i].nVertFrames,
                     atoi(CPLGetConfigOption("RPFTOC_MAX_FRAME_COUNT", "1000000")),
                     toc->entries[i].nHorizFrames * toc->entries[i].nVertFrames );
            toc->entries[i].frameEntries = nullptr;
        }
        else
        {
            toc->entries[i].frameEntries = reinterpret_cast<RPFTocFrameEntry*>(
                VSI_CALLOC_VERBOSE( toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames,
                                    sizeof(RPFTocFrameEntry) ) );
        }
        if (toc->entries[i].frameEntries == nullptr)
        {
            toc->entries[i].nVertFrames = 0;
            toc->entries[i].nHorizFrames = 0;
            RPFTOCFree(toc);
            return nullptr;
        }

        CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
                 i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
                 toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
    }

    if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
                   frameFileIndexSectionSubHeaderPhysIndex );
        RPFTOCFree(toc);
        return nullptr;
    }

    /* Skip 1 byte security classification */
    bOK &= VSIFSeekL( fp, 1, SEEK_CUR ) == 0;

    unsigned int frameIndexTableOffset;
    bOK &= VSIFReadL( &frameIndexTableOffset, sizeof(frameIndexTableOffset), 1, fp) == 1;
    CPL_MSBPTR32( &frameIndexTableOffset );

    unsigned int nFrameFileIndexRecords;
    bOK &= VSIFReadL( &nFrameFileIndexRecords, sizeof(nFrameFileIndexRecords), 1, fp) == 1;
    CPL_MSBPTR32( &nFrameFileIndexRecords );

    unsigned short nFrameFilePathnameRecords;
    bOK &= VSIFReadL( &nFrameFilePathnameRecords, sizeof(nFrameFilePathnameRecords), 1, fp) == 1;
    CPL_MSBPTR16( &nFrameFilePathnameRecords );

    unsigned short frameFileIndexRecordLength;
    bOK &= VSIFReadL( &frameFileIndexRecordLength, sizeof(frameFileIndexRecordLength), 1, fp) == 1;
    CPL_MSBPTR16( &frameFileIndexRecordLength );
    if( frameFileIndexRecordLength < 3 * sizeof(short) )
    {
        CPLError(CE_Failure, CPLE_FileIO, "Invalid file");
        RPFTOCFree(toc);
        return nullptr;
    }

    if( !bOK )
    {
        CPLError(CE_Failure, CPLE_FileIO, "I/O error");
        RPFTOCFree(toc);
        return nullptr;
    }

    int newBoundaryId = 0;

    for( int i = 0; i < static_cast<int>( nFrameFileIndexRecords ); i++ )
    {
        if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
            RPFTOCFree(toc);
            return nullptr;
        }

        unsigned short boundaryId;
        if( VSIFReadL( &boundaryId, sizeof(boundaryId), 1, fp) != 1 )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        CPL_MSBPTR16( &boundaryId );

        if (i == 0 && boundaryId == 0)
            newBoundaryId = 1;
        if (newBoundaryId == 0)
            boundaryId--;

        if (boundaryId >= toc->nEntries)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                    "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
                     boundaryId, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        RPFTocEntry* entry = &toc->entries[boundaryId];
        entry->boundaryId = boundaryId;

        unsigned short frameRow;
        bOK &= VSIFReadL( &frameRow, sizeof(frameRow), 1, fp) == 1;
        CPL_MSBPTR16( &frameRow );

        unsigned short frameCol;
        bOK &= VSIFReadL( &frameCol, sizeof(frameCol), 1, fp) == 1;
        CPL_MSBPTR16( &frameCol );
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }

        if (newBoundaryId == 0)
        {
            frameRow--;
            frameCol--;
        }
        else
        {
            /* Trick so that frames are numbered north to south */
            frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
        }

        if (frameRow >= entry->nVertFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad row num (%d) for frame file index %d.",
                        frameRow, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        if (frameCol >= entry->nHorizFrames)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                        "Invalid TOC file. Bad col num (%d) for frame file index %d.",
                        frameCol, i);
            RPFTOCFree(toc);
            return nullptr;
        }

        RPFTocFrameEntry* frameEntry
            = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
        frameEntry->frameRow = frameRow;
        frameEntry->frameCol = frameCol;

        if (frameEntry->exists)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Frame entry(%d,%d) for frame file index %d was already found.",
                      frameRow, frameCol, i);
            CPLFree(frameEntry->directory);
            frameEntry->directory = nullptr;
            CPLFree(frameEntry->fullFilePath);
            frameEntry->fullFilePath = nullptr;
            frameEntry->exists = 0;
        }

        unsigned int offsetFrameFilePathName;
        bOK &= VSIFReadL( &offsetFrameFilePathName, sizeof(offsetFrameFilePathName), 1, fp) == 1;
        CPL_MSBPTR32( &offsetFrameFilePathName );

        bOK &= VSIFReadL( frameEntry->filename, 1, 12, fp) == 12;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        frameEntry->filename[12] = '\0';
        bOK &= strlen(frameEntry->filename) > 0;

        /* Check if the filename is an overview or legend */
        for( int j = 0; j < 12; j++ )
        {
            if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
                strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
                strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
                strcmp(&(frameEntry->filename[j]),".lgd") == 0)
            {
                entry->isOverviewOrLegend = TRUE;
                break;
            }
        }

        /* Extract series code */
        if (entry->seriesAbbreviation == nullptr)
        {
            const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
            if (series)
            {
                entry->seriesAbbreviation = series->abbreviation;
                entry->seriesName = series->name;
            }
        }

        /* Get file geo reference */
        bOK &= VSIFReadL( frameEntry->georef, 1, 6, fp) == 6;
        frameEntry->georef[6] = '\0';

        /* Go to start of pathname record */
        /* New path_off offset from start of frame file index section of TOC?? */
        /* Add pathoffset wrt frame file index table subsection (loc[3]) */
        if( !bOK || VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Invalid TOC file. Unable to seek to "
                      "frameFileIndexSubsectionPhysIndex + "
                      "offsetFrameFilePathName(%d) at offset %d.",
                     i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
            RPFTOCFree(toc);
            return nullptr;
        }

        unsigned short pathLength;
        bOK &= VSIFReadL( &pathLength, sizeof(pathLength), 1, fp) == 1;
        CPL_MSBPTR16( &pathLength );

        /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
           this leads to 4 GB allocation... Protect against this case */
        if (!bOK || pathLength == 0 || pathLength > 256)
        {
            CPLError( CE_Failure, CPLE_NotSupported,
                      "Path length is invalid : %d. Probably corrupted TOC file.",
                      static_cast<int>( pathLength ) );
            RPFTOCFree(toc);
            return nullptr;
        }

        frameEntry->directory = reinterpret_cast<char *>( CPLMalloc(pathLength+1) );
        bOK &= VSIFReadL( frameEntry->directory, 1, pathLength, fp) == pathLength;
        if( !bOK )
        {
            CPLError(CE_Failure, CPLE_FileIO, "I/O error");
            RPFTOCFree(toc);
            return nullptr;
        }
        frameEntry->directory[pathLength] = 0;
        if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
            frameEntry->directory[pathLength-1] = 0;

        if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
        {
            memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);

            // Some A.TOC have subdirectory names like ".//X/" ... (#5979)
            // Check if it was not intended to be "./X/" instead.
            VSIStatBufL sStatBuf;
            if( frameEntry->directory[0] == '/' &&
                VSIStatL(CPLFormFilename(CPLGetDirname(pszFilename), frameEntry->directory+1, nullptr), &sStatBuf) == 0 &&
                VSI_ISDIR(sStatBuf.st_mode) )
            {
                memmove(frameEntry->directory, frameEntry->directory+1, strlen(frameEntry->directory+1)+1);
            }
        }

        {
            char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
            VSIStatBufL sStatBuf;
            char* subdir = nullptr;
            if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
                subdir = CPLStrdup(frameEntry->directory);
            else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
                subdir = CPLStrdup(baseDir);
            else
                subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, nullptr));
#if !defined(_WIN32) && !defined(_WIN32_CE)
            if( VSIStatL( subdir, &sStatBuf ) != 0 && strlen(subdir) > strlen(baseDir) && subdir[strlen(baseDir)] != 0)
            {
                char* c = subdir + strlen(baseDir)+1;
                while(*c)
                {
                    if (*c >= 'A' && *c <= 'Z')
                        *c += 'a' - 'A';
                    c++;
                }
            }
#endif
            frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
                    subdir,
                    frameEntry->filename, nullptr));
            if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
            {
#if !defined(_WIN32) && !defined(_WIN32_CE)
                if( strlen(frameEntry->fullFilePath) > strlen(subdir) )
                {
                    char* c = frameEntry->fullFilePath + strlen(subdir)+1;
                    while(*c)
                    {
                        if (*c >= 'A' && *c <= 'Z')
                            *c += 'a' - 'A';
                        c++;
                    }
                }
                if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
#endif
                {
                    frameEntry->fileExists = 0;
                    CPLError( CE_Warning, CPLE_AppDefined,
                        "File %s does not exist.", frameEntry->fullFilePath );
                }
#if !defined(_WIN32) && !defined(_WIN32_CE)
                else
                {
                    frameEntry->fileExists = 1;
                }
#endif
            }
            else
            {
                frameEntry->fileExists = 1;
            }
            CPLFree(subdir);
            CPLFree(baseDir);
        }

        CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);

        frameEntry->exists = 1;
    }

    return toc;
}
static void CorrectURLs( CPLXMLNode * psRoot, const char *pszURL )

{
    if( psRoot == NULL || pszURL == NULL )
        return;
    if( pszURL[0] == '\0' )
        return;

    CPLXMLNode *psChild = psRoot->psChild;

// check for xlink:href attribute
    while( psChild != NULL && !( ( psChild->eType == CXT_Attribute ) &&
                                 ( EQUAL(psChild->pszValue, "xlink:href") )) )
        psChild = psChild->psNext;

    if( psChild != NULL &&
        !( strstr( psChild->psChild->pszValue, pszURL ) == psChild->psChild->pszValue
        && psChild->psChild->pszValue[strlen(pszURL)] == '#' ) )
    {
    //href has a different url
        size_t nLen;
        char *pszNew;
        if( psChild->psChild->pszValue[0] == '#' )
        {
        //empty URL: prepend the given URL
            nLen = CPLStrnlen( pszURL, 1024 ) +
                   CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1;
            pszNew = (char *)CPLMalloc( nLen * sizeof(char));
            CPLStrlcpy( pszNew, pszURL, nLen );
            CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen );
            CPLSetXMLValue( psRoot, "#xlink:href", pszNew );
            CPLFree( pszNew );
        }
        else
        {
            size_t nPathLen;
            for( nPathLen = strlen(pszURL);
                 nPathLen > 0 && pszURL[nPathLen - 1] != '/'
                              && pszURL[nPathLen - 1] != '\\';
                 nPathLen--);

            if( strncmp( pszURL, psChild->psChild->pszValue, nPathLen ) != 0 )
            {
            //different path
                int nURLLen = strchr( psChild->psChild->pszValue, '#' ) -
                              psChild->psChild->pszValue;
                char *pszURLWithoutID = (char *)CPLMalloc( (nURLLen+1) * sizeof(char));
                strncpy( pszURLWithoutID, psChild->psChild->pszValue, nURLLen );
                pszURLWithoutID[nURLLen] = '\0';

                if( CPLIsFilenameRelative( pszURLWithoutID ) &&
                    strstr( pszURLWithoutID, ":" ) == NULL )
                {
                    //relative URL: prepend the path of pszURL
                    nLen = nPathLen +
                           CPLStrnlen( psChild->psChild->pszValue, 1024 ) + 1;
                    pszNew = (char *)CPLMalloc( nLen * sizeof(char));
                    size_t i;
                    for( i = 0; i < nPathLen; i++ )
                        pszNew[i] = pszURL[i];
                    pszNew[nPathLen] = '\0';
                    CPLStrlcat( pszNew, psChild->psChild->pszValue, nLen );
                    CPLSetXMLValue( psRoot, "#xlink:href", pszNew );
                    CPLFree( pszNew );
                }
                CPLFree( pszURLWithoutID );
            }
        }
    }

// search the child elements of psRoot
    for( psChild = psRoot->psChild; psChild != NULL; psChild = psChild->psNext)
        if( psChild->eType == CXT_Element )
            CorrectURLs( psChild, pszURL );
}
Esempio n. 16
0
int main( int nArgc, char ** papszArgv )

{
    int   nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg;
    const char *pszFormat = "ESRI Shapefile";
    const char *pszTileIndexField = "LOCATION";
    const char *pszOutputName = NULL;
    int write_absolute_path = FALSE;
    int skip_different_projection = FALSE;
    char* current_path = NULL;
    int accept_different_schemas = FALSE;
    int bFirstWarningForNonMatchingAttributes = TRUE;
    
    /* Check strict compilation and runtime library version as we use C++ API */
    if (! GDAL_CHECK_VERSION(papszArgv[0]))
        exit(1);
/* -------------------------------------------------------------------- */
/*      Register format(s).                                             */
/* -------------------------------------------------------------------- */
    OGRRegisterAll();
    
/* -------------------------------------------------------------------- */
/*      Processing command line arguments.                              */
/* -------------------------------------------------------------------- */
    for( iArg = 1; iArg < nArgc; iArg++ )
    {
        if( EQUAL(papszArgv[iArg], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 )
        {
            pszFormat = papszArgv[++iArg];
        }
        else if( EQUAL(papszArgv[iArg],"-write_absolute_path"))
        {
            write_absolute_path = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-skip_different_projection"))
        {
            skip_different_projection = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-accept_different_schemas"))
        {
            accept_different_schemas = TRUE;
        }
        else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 )
        {
            pszTileIndexField = papszArgv[++iArg];
        }
        else if( EQUAL(papszArgv[iArg],"-lnum") 
                 || EQUAL(papszArgv[iArg],"-lname") )
        {
            iArg++;
            bLayersWildcarded = FALSE;
        }
        else if( papszArgv[iArg][0] == '-' )
            Usage();
        else if( pszOutputName == NULL )
            pszOutputName = papszArgv[iArg];
        else if( nFirstSourceDataset == -1 )
            nFirstSourceDataset = iArg;
    }

    if( pszOutputName == NULL || nFirstSourceDataset == -1 )
        Usage();

/* -------------------------------------------------------------------- */
/*      Try to open as an existing dataset for update access.           */
/* -------------------------------------------------------------------- */
    OGRDataSource *poDstDS;
    OGRLayer *poDstLayer = NULL;

    poDstDS = OGRSFDriverRegistrar::Open( pszOutputName, TRUE );

/* -------------------------------------------------------------------- */
/*      If that failed, find the driver so we can create the tile index.*/
/* -------------------------------------------------------------------- */
    if( poDstDS == NULL )
    {
        OGRSFDriverRegistrar     *poR = OGRSFDriverRegistrar::GetRegistrar();
        OGRSFDriver              *poDriver = NULL;
        int                      iDriver;

        for( iDriver = 0;
             iDriver < poR->GetDriverCount() && poDriver == NULL;
             iDriver++ )
        {
            if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) )
            {
                poDriver = poR->GetDriver(iDriver);
            }
        }

        if( poDriver == NULL )
        {
            fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
            fprintf( stderr, "The following drivers are available:\n" );
        
            for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
            {
                fprintf( stderr, "  -> `%s'\n", poR->GetDriver(iDriver)->GetName() );
            }
            exit( 1 );
        }

        if( !poDriver->TestCapability( ODrCCreateDataSource ) )
        {
            fprintf( stderr, "%s driver does not support data source creation.\n",
                    pszFormat );
            exit( 1 );
        }

/* -------------------------------------------------------------------- */
/*      Now create it.                                                  */
/* -------------------------------------------------------------------- */
        
        poDstDS = poDriver->CreateDataSource( pszOutputName, NULL );
        if( poDstDS == NULL )
        {
            fprintf( stderr, "%s driver failed to create %s\n", 
                    pszFormat, pszOutputName );
            exit( 1 );
        }

        if( poDstDS->GetLayerCount() == 0 )
        {
            OGRFieldDefn oLocation( pszTileIndexField, OFTString );
            
            oLocation.SetWidth( 200 );
            
            if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' )
            {
                nFirstSourceDataset++;
            }
            
            OGRSpatialReference* poSrcSpatialRef = NULL;
            
            /* Fetches the SRS of the first layer and use it when creating the tileindex layer */
            if (nFirstSourceDataset < nArgc)
            {
                OGRDataSource* poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], 
                                           FALSE );
                                           
                if (poDS)
                {
                    int iLayer;

                    for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
                    {
                        int bRequested = bLayersWildcarded;
                        OGRLayer *poLayer = poDS->GetLayer(iLayer);

                        for( iArg = 1; iArg < nArgc && !bRequested; iArg++ )
                        {
                            if( EQUAL(papszArgv[iArg],"-lnum") 
                                && atoi(papszArgv[iArg+1]) == iLayer )
                                bRequested = TRUE;
                            else if( EQUAL(papszArgv[iArg],"-lname") 
                                     && EQUAL(papszArgv[iArg+1],
                                              poLayer->GetLayerDefn()->GetName()) )
                                bRequested = TRUE;
                        }

                        if( !bRequested )
                            continue;
                            
                        if ( poLayer->GetSpatialRef() )
                            poSrcSpatialRef = poLayer->GetSpatialRef()->Clone();
                        break;
                    }
                }
                
                OGRDataSource::DestroyDataSource( poDS );
            }

            poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef );
            poDstLayer->CreateField( &oLocation, OFTString );
            
            OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef );
        }
    }

/* -------------------------------------------------------------------- */
/*      Identify target layer and field.                                */
/* -------------------------------------------------------------------- */
    int   iTileIndexField;

    poDstLayer = poDstDS->GetLayer(0);
    if( poDstLayer == NULL )
    {
        fprintf( stderr, "Can't find any layer in output tileindex!\n" );
        exit( 1 );
    }

    iTileIndexField = 
        poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField );
    if( iTileIndexField == -1 )
    {
        fprintf( stderr, "Can't find %s field in tile index dataset.\n", 
                pszTileIndexField );
        exit( 1 );
    }

    OGRFeatureDefn* poFeatureDefn = NULL;

    /* Load in memory existing file names in SHP */
    int nExistingLayers = 0;
    char** existingLayersTab = NULL;
    OGRSpatialReference* alreadyExistingSpatialRef = NULL;
    int alreadyExistingSpatialRefValid = FALSE;
    nExistingLayers = poDstLayer->GetFeatureCount();
    if (nExistingLayers)
    {
        int i;
        existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*));
        for(i=0;i<nExistingLayers;i++)
        {
            OGRFeature* feature = poDstLayer->GetNextFeature();
            existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField));
            if (i == 0)
            {
                OGRDataSource       *poDS;
                char* filename = CPLStrdup(existingLayersTab[i]);
                int j;
                for(j=strlen(filename)-1;j>=0;j--)
                {
                    if (filename[j] == ',')
                        break;
                }
                if (j >= 0)
                {
                    int iLayer = atoi(filename + j + 1);
                    filename[j] = 0;
                    poDS = OGRSFDriverRegistrar::Open(filename, 
                                                    FALSE );
                    if (poDS)
                    {
                        OGRLayer *poLayer = poDS->GetLayer(iLayer);
                        if (poLayer)
                        {
                            alreadyExistingSpatialRefValid = TRUE;
                            alreadyExistingSpatialRef =
                                    (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL;
                                    
                            if (poFeatureDefn == NULL)
                                poFeatureDefn = poLayer->GetLayerDefn()->Clone();
                        }
                        OGRDataSource::DestroyDataSource( poDS );
                    }
                }
            }
        }
    }


    if (write_absolute_path)
    {
        current_path = CPLGetCurrentDir();
        if (current_path == NULL)
        {
            fprintf( stderr, "This system does not support the CPLGetCurrentDir call. "
                             "The option -write_absolute_path will have no effect\n");
            write_absolute_path = FALSE;
        }
    }
/* ==================================================================== */
/*      Process each input datasource in turn.                          */
/* ==================================================================== */

	for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ )
    {
        int i;
        OGRDataSource       *poDS;

        if( papszArgv[nFirstSourceDataset][0] == '-' )
        {
            nFirstSourceDataset++;
            continue;
        }
        
        char* fileNameToWrite;
        VSIStatBuf sStatBuf;

        if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) &&
            VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0)
        {
            fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset]));
        }
        else
        {
            fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]);
        }

        poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], 
                                           FALSE );

        if( poDS == NULL )
        {
            fprintf( stderr, "Failed to open dataset %s, skipping.\n", 
                    papszArgv[nFirstSourceDataset] );
            CPLFree(fileNameToWrite);
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Check all layers, and see if they match requests.               */
/* -------------------------------------------------------------------- */
        int iLayer;

        for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
        {
            int bRequested = bLayersWildcarded;
            OGRLayer *poLayer = poDS->GetLayer(iLayer);

            for( iArg = 1; iArg < nArgc && !bRequested; iArg++ )
            {
                if( EQUAL(papszArgv[iArg],"-lnum") 
                    && atoi(papszArgv[iArg+1]) == iLayer )
                    bRequested = TRUE;
                else if( EQUAL(papszArgv[iArg],"-lname") 
                         && EQUAL(papszArgv[iArg+1],
                                  poLayer->GetLayerDefn()->GetName()) )
                    bRequested = TRUE;
            }

            if( !bRequested )
                continue;

            /* Checks that the layer is not already in tileindex */
            for(i=0;i<nExistingLayers;i++)
            {
                char        szLocation[5000];
                sprintf( szLocation, "%s,%d", 
                        fileNameToWrite, iLayer );
                if (EQUAL(szLocation, existingLayersTab[i]))
                {
                    fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n",
                            iLayer, papszArgv[nFirstSourceDataset]);
                    break;
                }
            }
            if (i != nExistingLayers)
            {
                continue;
            }

            OGRSpatialReference* spatialRef = poLayer->GetSpatialRef();
            if (alreadyExistingSpatialRefValid)
            {
                if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL &&
                     spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) ||
                    ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL)))
                {
                    fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as "
                                "other files in the tileindex. This may cause problems when "
                                "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset],
                                (skip_different_projection) ? " Skipping it" : "");
                    if (skip_different_projection)
                    {
                        continue;
                    }
                }
            }
            else
            {
                alreadyExistingSpatialRefValid = TRUE;
                alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL;
            }

/* -------------------------------------------------------------------- */
/*		Check if all layers in dataset have the same attributes	schema. */
/* -------------------------------------------------------------------- */
			if( poFeatureDefn == NULL )
			{
				poFeatureDefn = poLayer->GetLayerDefn()->Clone();
			}
			else if ( !accept_different_schemas )
			{
				OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn();
				assert(NULL != poFeatureDefnCur);

				int fieldCount = poFeatureDefnCur->GetFieldCount();

				if( fieldCount != poFeatureDefn->GetFieldCount())
				{
					fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n",
                             poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]);
                    if (bFirstWarningForNonMatchingAttributes)
                    {
                        fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n"
                                         "but this may result in a tileindex incompatible with MapServer\n");
                        bFirstWarningForNonMatchingAttributes = FALSE;
                    }
					continue;
				}
				
                int bSkip = FALSE;
				for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ )
				{
 					OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn);
 					OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn);

					/* XXX - Should those pointers be checked against NULL? */ 
					assert(NULL != poField);
					assert(NULL != poFieldCur);

					if( poField->GetType() != poFieldCur->GetType() 
						|| poField->GetWidth() != poFieldCur->GetWidth() 
						|| poField->GetPrecision() != poFieldCur->GetPrecision() 
						|| !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) )
					{
						fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n",
                                 poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]);
                        if (bFirstWarningForNonMatchingAttributes)
                        {
                            fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n"
                                             "but this may result in a tileindex incompatible with MapServer\n");
                            bFirstWarningForNonMatchingAttributes = FALSE;
                        }
                        bSkip = TRUE; 
                        break;
					}
				}
                
                if (bSkip)
                    continue;
			}


/* -------------------------------------------------------------------- */
/*      Get layer extents, and create a corresponding polygon           */
/*      geometry.                                                       */
/* -------------------------------------------------------------------- */
            OGREnvelope sExtents;
            OGRPolygon oRegion;
            OGRLinearRing oRing;

            if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE )
            {
                fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", 
                        poLayer->GetLayerDefn()->GetName(), 
                        papszArgv[nFirstSourceDataset] );
                continue;
            }
            
            oRing.addPoint( sExtents.MinX, sExtents.MinY );
            oRing.addPoint( sExtents.MinX, sExtents.MaxY );
            oRing.addPoint( sExtents.MaxX, sExtents.MaxY );
            oRing.addPoint( sExtents.MaxX, sExtents.MinY );
            oRing.addPoint( sExtents.MinX, sExtents.MinY );

            oRegion.addRing( &oRing );

/* -------------------------------------------------------------------- */
/*      Add layer to tileindex.                                         */
/* -------------------------------------------------------------------- */
            char        szLocation[5000];
            OGRFeature  oTileFeat( poDstLayer->GetLayerDefn() );

            sprintf( szLocation, "%s,%d", 
                     fileNameToWrite, iLayer );
            oTileFeat.SetGeometry( &oRegion );
            oTileFeat.SetField( iTileIndexField, szLocation );

            if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE )
            {
                fprintf( stderr, "Failed to create feature on tile index ... terminating." );
                OGRDataSource::DestroyDataSource( poDstDS );
                exit( 1 );
            }
        }

/* -------------------------------------------------------------------- */
/*      Cleanup this data source.                                       */
/* -------------------------------------------------------------------- */
        CPLFree(fileNameToWrite);
        OGRDataSource::DestroyDataSource( poDS );
    }

/* -------------------------------------------------------------------- */
/*      Close tile index and clear buffers.                             */
/* -------------------------------------------------------------------- */
    OGRDataSource::DestroyDataSource( poDstDS );
	OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn );
  
    if (alreadyExistingSpatialRef != NULL)
        OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef );
  
    CPLFree(current_path);
    
    if (nExistingLayers)
    {
        int i;
        for(i=0;i<nExistingLayers;i++)
        {
            CPLFree(existingLayersTab[i]);
        }
        CPLFree(existingLayersTab);
    }

    return 0;
}
Esempio n. 17
0
static CPLString GetProj4Filename(const char* pszFilename)
{
    CPLString osFilename;

    /* or fixed path: /name, ./name or ../name */
    if ( !CPLIsFilenameRelative(pszFilename) || *pszFilename == '.' )
    {
        return pszFilename;
    }

#if defined(PROJ_STATIC) && PROJ_VERSION >= 5
    PJ_GRID_INFO info = proj_grid_info(pszFilename);
    if( info.filename[0] )
    {
        osFilename = info.filename;
    }
#elif defined(PROJ_STATIC) && PJ_VERSION > 493
    osFilename.resize(2048);
    projCtx ctx = pj_ctx_alloc();
    if( pj_find_file(ctx, pszFilename, &osFilename[0], osFilename.size()) )
    {
        osFilename.resize( strlen(osFilename) );
    }
    else
    {
        osFilename.clear();
    }
    pj_ctx_free(ctx);
#else
    // Transpose some of the proj.4 pj_open_lib() logic...

    /* check if ~/name */
    char* pszSysname;
    if (*pszFilename == '~' &&
        (pszFilename[1] == '/' || pszFilename[1] == '\\') )
    {
        if ((pszSysname = getenv("HOME")) != nullptr)
        {
            osFilename = CPLFormFilename(pszSysname, pszFilename + 1, nullptr);
        }
        return osFilename;
    }

    /* or is environment PROJ_LIB defined */
    else if ((pszSysname = getenv("PROJ_LIB")) != nullptr)
    {
        osFilename = CPLFormFilename(pszSysname, pszFilename, nullptr);
        VSIStatBufL sStat;
        if( VSIStatL(osFilename, &sStat) == 0 )
            return osFilename;
        osFilename.clear();
    }


#if defined(PROJ_STATIC) && PJ_VERSION >= 490
    // Super messy. proj.4 up to 4.9.3 had no public API to return the full
    // path to a resource file, so we rely on the fact that it emits a log
    // message with it...
    // Basically this is needed in the case where the file is in the
    // resource installation directory of proj.4, which we have no way to
    // know otherwise.
    CPLString osMsg;
    projCtx ctx = pj_ctx_alloc();
    pj_ctx_set_app_data(ctx, &osMsg);
    pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR);
    pj_ctx_set_logger(ctx, my_proj4_logger);
    PAFile f = pj_open_lib(ctx, pszFilename, "rb");
    if( f )
    {
        pj_ctx_fclose(ctx, f);
        size_t nPos = osMsg.find("fopen(");
        if( nPos != std::string::npos )
        {
            osFilename = osMsg.substr(nPos + strlen("fopen("));
            nPos = osFilename.find(")");
            if( nPos != std::string::npos )
                osFilename = osFilename.substr(0, nPos);
        }
    }
    pj_ctx_free(ctx);
#endif
#endif
    return osFilename;
}