示例#1
0
文件: wmsutils.cpp 项目: OSGeo/gdal
// Terminates an URL base with either ? or &, so extra args can be appended
void URLPrepare(CPLString &url) {
    if (url.find("?") == std::string::npos) {
        url.append("?");
    } else {
        if (*url.rbegin() != '?' && *url.rbegin() != '&')
            url.append("&");
    }
}
CPLString OGRCARTODBEscapeLiteral(const char* pszStr)
{
    CPLString osStr;

    char ch;
    for(int i=0; (ch = pszStr[i]) != '\0'; i++)
    {
        if (ch == '\'')
            osStr.append(1, ch);
        osStr.append(1, ch);
    }

    return osStr;
}
CPLString OGRPGDumpEscapeColumnName(const char* pszColumnName)
{
    CPLString osStr;

    osStr += "\"";

    char ch;
    for(int i=0; (ch = pszColumnName[i]) != '\0'; i++)
    {
        if (ch == '"')
            osStr.append(1, ch);
        osStr.append(1, ch);
    }

    osStr += "\"";

    return osStr;
}
CPLString OGRCARTODBEscapeIdentifier(const char* pszStr)
{
    CPLString osStr;

    osStr += "\"";

    char ch;
    for(int i=0; (ch = pszStr[i]) != '\0'; i++)
    {
        if (ch == '"')
            osStr.append(1, ch);
        osStr.append(1, ch);
    }

    osStr += "\"";

    return osStr;
}
示例#5
0
int OGRDXFWriterLayer::WriteValue( int nCode, const char *pszValue )

{
    CPLString osLinePair;

    osLinePair.Printf( "%3d\n", nCode );

    if( strlen(pszValue) < 255 )
        osLinePair += pszValue;
    else
        osLinePair.append( pszValue, 255 );

    osLinePair += "\n";

    return VSIFWriteL( osLinePair.c_str(),
                       1, osLinePair.size(), fp ) == osLinePair.size();
}
示例#6
0
char* ImagineCitationTranslation(const char* psCitation, geokey_t keyID)
{
    char* ret = NULL;
    if(!psCitation)
        return ret;
    if(EQUALN(psCitation, "IMAGINE GeoTIFF Support", strlen("IMAGINE GeoTIFF Support")))
    {
        CPLString osName;

        // this is a handle IMAGING style citation
        const char* p = NULL;
        p = strchr(psCitation, '$');
        if(p)
            p = strchr(p, '\n');
        if(p)
            p++;
        const char* p1 = NULL;
        if(p)
            p1 = strchr(p, '\n');
        if(p && p1)
        {
            switch (keyID)
            {
              case PCSCitationGeoKey:
                osName = "PCS Name = ";
                break;
              case GTCitationGeoKey:
                osName = "CS Name = ";
                break;
              case GeogCitationGeoKey:
                if(!strstr(p, "Unable to"))
                    osName = "GCS Name = ";
                break;
              default:
                break;
            }
            if(strlen(osName)>0)
            {
                osName.append(p, p1-p);
                osName += "|";
            }
        }
        p = strstr(psCitation, "Projection Name = ");
        if(p)
        {
            p += strlen("Projection Name = ");
            p1 = strchr(p, '\n');
            if(!p1)
                p1 = strchr(p, '\0');
        }
        if(p && p1)
        {
            osName.append(p, p1-p);
            osName += "|";
        }
        p = strstr(psCitation, "Datum = ");
        if(p)
        {
            p += strlen("Datum = ");
            p1 = strchr(p, '\n');
            if(!p1)
                p1 = strchr(p, '\0');
        }
        if(p && p1)
        {
            osName += "Datum = ";
            osName.append(p, p1-p);
            osName += "|";
        }
        p = strstr(psCitation, "Ellipsoid = ");
        if(p)
        {
            p += strlen("Ellipsoid = ");
            p1 = strchr(p, '\n');
            if(!p1)
                p1 = strchr(p, '\0');
        }
        if(p && p1)
        {
            osName += "Ellipsoid = ";
            osName.append(p, p1-p);
            osName += "|";
        }
        p = strstr(psCitation, "Units = ");
        if(p)
        {
            p += strlen("Units = ");
            p1 = strchr(p, '\n');
            if(!p1)
                p1 = strchr(p, '\0');
        }
        if(p && p1)
        {
            osName += "LUnits = ";
            osName.append(p, p1-p);
            osName += "|";
        }
        if(strlen(osName) > 0)
        {
            ret = CPLStrdup(osName);
        }
    }
    return ret;
}
CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT )
{
    GeoRasterDataset* poGDS = (GeoRasterDataset*) poDS;

    if( ! poRAT )
    {
        return CE_Failure;
    }

    if( poDefaultRAT )
    {
        delete poDefaultRAT;
    }

    poDefaultRAT = poRAT->Clone();

    // ----------------------------------------------------------
    // Check if RAT is just colortable and/or histogram
    // ----------------------------------------------------------

    CPLString sColName = "";
    int  iCol = 0;
    int  nColCount = poRAT->GetColumnCount();

    for( iCol = 0; iCol < poRAT->GetColumnCount(); iCol++ )
    {
        sColName = poRAT->GetNameOfCol( iCol );

        if( EQUAL( sColName, "histogram" ) ||
            EQUAL( sColName, "red" ) ||
            EQUAL( sColName, "green" ) ||
            EQUAL( sColName, "blue" ) ||
            EQUAL( sColName, "opacity" ) )
        {
            nColCount--;
        }
    }

    if( nColCount < 2 )
    {
        return CE_None;
    }

    // ----------------------------------------------------------
    // Format Table description
    // ----------------------------------------------------------

    char szName[OWTEXT];
    char szDescription[OWTEXT];

    strcpy( szDescription, "( ID NUMBER" );

    for( iCol = 0; iCol < poRAT->GetColumnCount(); iCol++ )
    {
        strcpy( szName, poRAT->GetNameOfCol( iCol ) );

        strcpy( szDescription, CPLSPrintf( "%s, %s",
            szDescription, szName ) );

        if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer )
        {
            strcpy( szDescription, CPLSPrintf( "%s NUMBER",
                szDescription ) );
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_Real )
        {
            strcpy( szDescription, CPLSPrintf( "%s FLOAT",
                szDescription ) );
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_String )
        {
            strcpy( szDescription, CPLSPrintf( "%s VARCHAR2(%d)",
                szDescription, MAXLEN_VATSTR) );
        }
    }
    strcpy( szDescription, CPLSPrintf( "%s )", szDescription ) );

    // ----------------------------------------------------------
    // Create VAT named based on RDT and RID and Layer (nBand)
    // ----------------------------------------------------------

    if( ! pszVATName )
    {
        pszVATName = CPLStrdup( CPLSPrintf(
            "RAT_%s_%d_%d", 
            poGeoRaster->sDataTable.c_str(),
            poGeoRaster->nRasterId,
            nBand ) );
    }

    // ----------------------------------------------------------
    // Create VAT table
    // ----------------------------------------------------------

    OWStatement* poStmt = poGeoRaster->poConnection->CreateStatement( CPLSPrintf(
        "DECLARE\n"
        "  TAB VARCHAR2(68)  := UPPER(:1);\n"
        "  CNT NUMBER        := 0;\n"
        "BEGIN\n"
        "  EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM USER_TABLES\n"
        "    WHERE TABLE_NAME = :1' INTO CNT USING TAB;\n"
        "\n"
        "  IF NOT CNT = 0 THEN\n"
        "    EXECUTE IMMEDIATE 'DROP TABLE '||TAB||' PURGE';\n"
        "  END IF;\n"
        "\n"
        "  EXECUTE IMMEDIATE 'CREATE TABLE '||TAB||' %s';\n"
        "END;", szDescription ) );

    poStmt->Bind( pszVATName );

    if( ! poStmt->Execute() )
    {
        delete poStmt;
        CPLError( CE_Failure, CPLE_AppDefined, "Create VAT Table Error!" );
        return CE_Failure;
    }

    delete poStmt;

    // ----------------------------------------------------------
    // Insert Data to VAT
    // ----------------------------------------------------------

    int iEntry       = 0;
    int nEntryCount  = poRAT->GetRowCount();
    int nColunsCount = poRAT->GetColumnCount();
    int nVATStrSize  = MAXLEN_VATSTR * poGeoRaster->poConnection->GetCharSize();

    // ---------------------------
    // Allocate array of buffers
    // ---------------------------

    void** papWriteFields = (void**) VSIMalloc2(sizeof(void*), nColunsCount + 1);

    papWriteFields[0] = 
        (void*) VSIMalloc3(sizeof(int), sizeof(int), nEntryCount ); // ID field

    for(iCol = 0; iCol < nColunsCount; iCol++)
    {
        if( poRAT->GetTypeOfCol( iCol ) == GFT_String )
        {
            papWriteFields[iCol + 1] =
                (void*) VSIMalloc3(sizeof(char), nVATStrSize, nEntryCount );
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer )
        {
            papWriteFields[iCol + 1] =
                (void*) VSIMalloc3(sizeof(int), sizeof(int), nEntryCount );
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_Real )
        {
            papWriteFields[iCol + 1] =
                 (void*) VSIMalloc3(sizeof(double), sizeof(double), nEntryCount );
        }
    }
    
    // ---------------------------
    // Load data to buffers
    // ---------------------------

    for( iEntry = 0; iEntry < nEntryCount; iEntry++ )
    {
        ((int *)(papWriteFields[0]))[iEntry] = iEntry; // ID field

        for(iCol = 0; iCol < nColunsCount; iCol++)
        {
            if( poRAT->GetTypeOfCol( iCol ) == GFT_String )
            {

                int nOffset = iEntry * nVATStrSize;
                char* pszTarget = ((char*)papWriteFields[iCol + 1]) + nOffset;
                const char *pszStrValue = poRAT->GetValueAsString(iEntry, iCol);
                int nLen = strlen( pszStrValue );
                nLen = nLen > ( nVATStrSize - 1 ) ? nVATStrSize : ( nVATStrSize - 1 );
                strncpy( pszTarget, pszStrValue, nLen );
                pszTarget[nLen] = '\0';
            }
            if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer )
            {
                ((int *)(papWriteFields[iCol + 1]))[iEntry] =
                    poRAT->GetValueAsInt(iEntry, iCol);
            }
            if( poRAT->GetTypeOfCol( iCol ) == GFT_Real )
            {
                ((double *)(papWriteFields[iCol]))[iEntry + 1] =
                    poRAT->GetValueAsDouble(iEntry, iCol);
            }
        }
    }

    // ---------------------------
    // Prepare insert statement
    // ---------------------------

    CPLString osInsert = CPLSPrintf( "INSERT INTO %s VALUES (", pszVATName );
    
    for( iCol = 0; iCol < ( nColunsCount + 1); iCol++ )
    {
        if( iCol > 0 )
        {
            osInsert.append(", ");
        }
        osInsert.append( CPLSPrintf(":%d", iCol + 1) );
    }
    osInsert.append(")");

    poStmt = poGeoRaster->poConnection->CreateStatement( osInsert.c_str() );

    // ---------------------------
    // Bind buffers to columns
    // ---------------------------

    poStmt->Bind((int*) papWriteFields[0]); // ID field
    
    for(iCol = 0; iCol < nColunsCount; iCol++)
    {
        if( poRAT->GetTypeOfCol( iCol ) == GFT_String )
        {
            poStmt->Bind( (char*) papWriteFields[iCol + 1], nVATStrSize );
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer )
        {
            poStmt->Bind( (int*) papWriteFields[iCol + 1]);
        }
        if( poRAT->GetTypeOfCol( iCol ) == GFT_Real )
        {
            poStmt->Bind( (double*) papWriteFields[iCol + 1]);
        }
    }

    if( poStmt->Execute( iEntry ) )
    {
        poGDS->poGeoRaster->SetVAT( nBand, pszVATName );
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined, "Insert VAT Error!" );
    }

    // ---------------------------
    // Clean up
    // ---------------------------

    for(iCol = 0; iCol < ( nColunsCount + 1); iCol++)
    {
        CPLFree( papWriteFields[iCol] );
    }
    
    CPLFree( papWriteFields );

    delete poStmt;

    return CE_None;
}
void    GMLASXPathMatcher::SetDocumentMapURIToPrefix(
                        const std::map<CPLString,CPLString>& oMapURIToPrefix )
{
    m_aosReferenceXPaths.clear();

    // Split each reference XPath into its components
    for(size_t i = 0; i < m_aosReferenceXPathsUncompiled.size(); ++i )
    {
        const CPLString& osXPath( m_aosReferenceXPathsUncompiled[i] );

        std::vector<XPathComponent> oVector;

        size_t iPos = 0;
        bool bDirectChild = false;
        if( osXPath.size() >= 2 &&
            osXPath[0] == '/' && osXPath[1] == '/' )
        {
            iPos += 2;
        }
        else if( osXPath.size() >= 1 && osXPath[0] == '/' )
        {
            iPos += 1;
            bDirectChild = true;
        }

        while( iPos < osXPath.size() )
        {
            size_t iPosNextSlash = osXPath.find('/', iPos);

            if( iPos == iPosNextSlash )
            {
                bDirectChild = false;
                iPos ++;
                continue;
            }

            CPLString osCurNode;
            if( iPosNextSlash == std::string::npos )
                osCurNode.assign(osXPath, iPos, std::string::npos);
            else
                osCurNode.assign(osXPath, iPos, iPosNextSlash - iPos);

            // Translate the configuration prefix to the equivalent in
            // this current schema
            size_t iPosColumn = osCurNode.find(':');
            if( iPosColumn != std::string::npos )
            {
                bool bIsAttr = ( osCurNode[0] == '@' );
                CPLString osPrefix;
                CPLString osLocalname;
                osPrefix.assign(osCurNode, 
                                bIsAttr ? 1 : 0,
                                iPosColumn - (bIsAttr ? 1 : 0));
                osLocalname.assign(osCurNode, iPosColumn+1,
                                std::string::npos);

                std::map<CPLString, CPLString>::const_iterator oIter =
                    m_oMapPrefixToURIReferenceXPaths.find(osPrefix);
                if( oIter != m_oMapPrefixToURIReferenceXPaths.end() )
                {
                    const CPLString& osURI( oIter->second );
                    oIter = oMapURIToPrefix.find( osURI );
                    if( oIter == oMapURIToPrefix.end() )
                        break;
                    osPrefix.assign(oIter->second);
                }

                osCurNode.clear();
                if( bIsAttr )
                    osCurNode.append(1, '@');
                osCurNode.append(osPrefix);
                osCurNode.append(1, ':');
                osCurNode.append(osLocalname);
            }

            XPathComponent comp;
            comp.m_osValue = osCurNode;
            comp.m_bDirectChild = bDirectChild;
            oVector.push_back(comp);

            if( iPosNextSlash == std::string::npos )
                iPos = osXPath.size();
            else
                iPos = iPosNextSlash + 1;

            bDirectChild = true;
        }

        if ( iPos < osXPath.size() )
            oVector.clear();
        m_aosReferenceXPaths.push_back(oVector);
    }
}
示例#9
0
/**
 *\Brief Create a MRF file from an existing DS
 */
GDALDataset * GDALMRFDataset::CreateCopy( const char *pszFilename, 
            GDALDataset *poSrcDS, int bStrict, char **papszOptions, 
            GDALProgressFunc pfnProgress, void *pProgressData)

{
    // short term temporaryBlock
    const char *pszValue;
    GDALColorTable *poColorTable=NULL;

    // Defaults
    int  nBands = poSrcDS->GetRasterCount();
    int  nXSize = poSrcDS->GetRasterXSize();
    int  nYSize = poSrcDS->GetRasterYSize();

    // Set some defaults
    ILCompression comp=IL_PNG;
    ILOrder ord=IL_Interleaved;
    ILSize ILSPage(512,512,1,1);
    int quality = -1;
    bool nbo=NET_ORDER;

    // Use the info from the input image
    // Use the poSrcDS or the first band to find out info about the dataset
    GDALRasterBand *poPBand=poSrcDS->GetRasterBand(1);

    GDALDataType dt=poPBand->GetRasterDataType();

    // Use the blocking from the input image, if the input uses blocks.
    int srcXBlk,srcYBlk;
    poPBand->GetBlockSize(&srcXBlk,&srcYBlk);
    if ((srcXBlk!=nXSize) && (srcYBlk!=nYSize)) {
        ILSPage.x=srcXBlk;
        ILSPage.y=srcYBlk;
    }

    // Except if the BLOCKSIZE BLOCKXSIZE and BLOCKYSIZE are set
    pszValue = CSLFetchNameValue(papszOptions,"BLOCKSIZE");
    if ( pszValue != NULL ) ILSPage.x = ILSPage.y = atoi( pszValue );
    pszValue = CSLFetchNameValue(papszOptions,"BLOCKXSIZE");
    if ( pszValue != NULL ) ILSPage.x = atoi( pszValue );
    pszValue = CSLFetchNameValue(papszOptions,"BLOCKYSIZE");
    if ( pszValue != NULL ) ILSPage.y = atoi( pszValue );

    // Get the quality setting
    pszValue = CSLFetchNameValue(papszOptions,"QUALITY");
    if ( pszValue != NULL ) quality = atoi( pszValue );
    else quality = 85;
    if ( quality < 0 || quality > 99 ) {
        CPLError(CE_Warning, CPLE_AppDefined, "GDAL MRF: Quality setting should be between 0 and 99, using 85");
        quality = 85;
    }

    // If the source has a NoDataValue, min or max, we keep them
    CPLString NoData;
    {
        int bHasNoData=false; double dfNoData=poPBand->GetNoDataValue( &bHasNoData);
        if (bHasNoData) {
            NoData=CPLString().FormatC(dfNoData);
            // And for the other bands, if they are there
            for (int i=1;i<nBands;i++) {
                double dfNoData=poSrcDS->GetRasterBand(i+1)->GetNoDataValue(&bHasNoData);
                if (bHasNoData)
                    NoData.append(CPLString().Printf(" %s",CPLString().FormatC(dfNoData).c_str()));
            }
        }
    }

    CPLString Min;
    {
        int bHasMin=false; double dfMin=poPBand->GetMinimum( &bHasMin);
        if (bHasMin) {
            Min=CPLString().FormatC(dfMin);
            // And for the other bands, if they are there
            for (int i=1;i<nBands;i++) {
                double dfMin=poSrcDS->GetRasterBand(i+1)->GetMinimum(&bHasMin);
                if (bHasMin)
                    Min.append(CPLString().Printf(" %s",CPLString().FormatC(dfMin).c_str()));
            }
        }
    }

    CPLString Max;
    {
        int bHasMax=false; double dfMax=poPBand->GetMaximum( &bHasMax);
        if (bHasMax) {
            Max=CPLString().FormatC(dfMax);
            // And for the other bands, if they are there
            for (int i=1;i<nBands;i++) {
                double dfMax=poSrcDS->GetRasterBand(i+1)->GetMaximum(&bHasMax);
                if (bHasMax)
                    Max.append(CPLString().Printf(" %s",CPLString().FormatC(dfMax).c_str()));
            }
        }
    }

    // Network byte order requested?
    pszValue = CSLFetchNameValue(papszOptions,"NETBYTEORDER");
    if (( pszValue != 0 ) &&
        (EQUAL(pszValue, "ON") || EQUAL(pszValue, "TRUE") || EQUAL(pszValue, "YES")) )
            nbo=true;

    // Order, leave error checking for later
    pszValue=poPBand->GetMetadataItem("INTERLEAVE","IMAGE_STRUCTURE");
    if ((nBands>1) && (NULL!=pszValue) && EQUAL("PIXEL",pszValue))
        ILSPage.c=nBands;

    // Use the source compression if we understand it
    comp=CompToken(poPBand->GetMetadataItem("COMPRESSION","IMAGE_STRUCTURE"),comp);

    // Input options, overrides
    pszValue=CSLFetchNameValue(papszOptions,"INTERLEAVE");
    if (pszValue) if (IL_ERR_ORD==(ord=OrderToken(pszValue))) {
        CPLError(CE_Warning, CPLE_AppDefined, "GDAL MRF: Interleave model %s is unknown, "
            "using PIXEL",pszValue);
        ord=IL_Interleaved;
    }

    pszValue=CSLFetchNameValue(papszOptions,"COMPRESS");
    if (pszValue) if (IL_ERR_COMP==(comp=CompToken(pszValue))) {
        CPLError(CE_Warning, CPLE_AppDefined, "GDAL MRF: Compression %s is unknown, "
            "using PNG", pszValue);
        comp=IL_PNG;
    }

    // Error checks and synchronizations

    // If interleaved model is requested and no page size is set,
    // use the number of bands
    if ((nBands>1) && (IL_Interleaved==ord) && (1==ILSPage.c))
        ILSPage.c=nBands;

    // Check compression based limitations
    if (1!=ILSPage.c) {
        if ((IL_PNG==comp)||(IL_PPNG==comp)) {
            if (ILSPage.c>4) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDAL MRF: %s "
                    " Compression can't handle %d pixel interleaved bands\n",
                    CompName(IL_PNG),ILSPage.c);
                return NULL;
            }
        }
        if (IL_JPEG==comp) {
            if ((2==ILSPage.c) || (ILSPage.c>4)) {
                CPLError(CE_Failure, CPLE_AppDefined, "GDAL MRF: Compression %s "
                    "can't handle %d pixel interleaved bands\n",
                    CompName(IL_JPEG),ILSPage.c);
                return NULL;
            }
        }
    }

    // Check data type
    if ((IL_JPEG==comp) && (dt!=GDT_Byte)) {
        CPLError(CE_Failure,CPLE_AppDefined, "GDAL MRF: JPEG only supports byte at this time");
        return NULL;
    } else  // PNG supports 8 and 16 bit types
    if ((IL_PNG==comp) && (dt!=GDT_Byte) && (dt!=GDT_Int16) && (dt!=GDT_UInt16)) {
        CPLError(CE_Failure,CPLE_AppDefined, "GDAL MRF: PNG only supports 8 and 16 bits of data, format is %s",GDALGetDataTypeName(dt));
        return NULL;
    }

    CPLString fname_data(getFname(pszFilename,ILComp_Ext[comp]));
    CPLString fname_idx(getFname(pszFilename,".idx"));

    // Get the color palette if we only have one band
    if ( 1==nBands && poPBand->GetColorInterpretation()==GCI_PaletteIndex )
        poColorTable=poPBand->GetColorTable()->Clone();

    // Check for format is PPNG and we don't have a palette
    // TODO: create option to build a palette, using the syntax from VRT LUT
    if (( poColorTable==NULL ) && ( comp==IL_PPNG )) {
        comp=IL_PNG;
        CPLError(CE_Warning,CPLE_AppDefined, "GDAL MRF: PPNG needs a palette based input, switching to PNG");
    }

    // Let's build the XML
    CPLXMLNode *config=CPLCreateXMLNode(NULL,CXT_Element,"MRF_META");
    CPLXMLNode *raster=CPLCreateXMLNode(config,CXT_Element,"Raster");
    XMLSetAttributeVal(raster,"Size",ILSize(nXSize,nYSize,1,nBands),"%.0f");


    // Only one for now
    // CPLCreateXMLElementAndValue(raster,"NumImgs","1");

    //  This one can only be TL when used by GDAL
    //	CPLCreateXMLElementAndValue(raster,"Orientation","TL");
    if (comp!=IL_PNG)
        CPLCreateXMLElementAndValue(raster,"Compression",CompName(comp));

    if (dt!=GDT_Byte)
        CPLCreateXMLElementAndValue(raster,"DataType",GDALGetDataTypeName( dt));

    if (NoData.size()|| Min.size()|| Max.size()) {
        CPLXMLNode *values=CPLCreateXMLNode(raster,CXT_Element,"DataValues");
        if (NoData.size()) {
            CPLCreateXMLNode(values,CXT_Attribute,"NoData");
            CPLSetXMLValue(values,"NoData",NoData.c_str());
        }
        if (Min.size()) {
            CPLCreateXMLNode(values,CXT_Attribute,"min");
            CPLSetXMLValue(values,"min",Min.c_str());
        }
        if (Max.size()) {
            CPLCreateXMLNode(values,CXT_Attribute,"max");
            CPLSetXMLValue(values,"max",Max.c_str());
        }
    }
    // Always dump the palette if we have one
    if (poColorTable!=NULL) {
        CPLXMLNode *pal=CPLCreateXMLNode(raster,CXT_Element,"Palette");
        int sz=poColorTable->GetColorEntryCount();
        if (sz!=256)
            XMLSetAttributeVal(pal,"Size",poColorTable->GetColorEntryCount());
        // Should also check and set the colormodel, RGBA for now
        for (int i=0;i<sz;i++) {
            CPLXMLNode *entry=CPLCreateXMLNode(pal,CXT_Element,"Entry");
            const GDALColorEntry *ent=poColorTable->GetColorEntry(i);
            // No need to set the index, it is always from 0 no size-1
            XMLSetAttributeVal(entry,"c1",ent->c1);
            XMLSetAttributeVal(entry,"c2",ent->c2);
            XMLSetAttributeVal(entry,"c3",ent->c3);
            if (ent->c4!=255)
                XMLSetAttributeVal(entry,"c4",ent->c4);
        }

        // Done with the palette
        delete poColorTable;
    }

    if (is_Endianess_Dependent(dt,comp)) // Need to set the order
        CPLCreateXMLElementAndValue(raster,"NetByteOrder",
            (nbo||NET_ORDER)?"TRUE":"FALSE");

    if (quality>0)
      CPLCreateXMLElementAndValue(raster,"Quality", CPLString().Printf("%d",quality).c_str());

    XMLSetAttributeVal(raster,"PageSize",ILSPage,"%.0f");

    CPLCreateXMLNode(config,CXT_Element,"Rsets");
    CPLXMLNode *gtags=CPLCreateXMLNode(config,CXT_Element,"GeoTags");

    // Do we have a meaningfull affine transform?
    double gt[6];

    if (poSrcDS->GetGeoTransform(gt)==CE_None
        && (gt[0] != 0 || gt[1] != 1 || gt[2] != 0 || 
            gt[3] != 0 || gt[4] != 0 || gt[5] != 1 ))
    {
        double minx=gt[0];
        double maxx=gt[1]*poSrcDS->GetRasterXSize()+minx;
        double maxy=gt[3];
        double miny=gt[5]*poSrcDS->GetRasterYSize()+maxy;
        CPLXMLNode *bbox=CPLCreateXMLNode(gtags,CXT_Element,"BoundingBox");
        XMLSetAttributeVal(bbox,"minx",minx);
        XMLSetAttributeVal(bbox,"miny",miny);
        XMLSetAttributeVal(bbox,"maxx",maxx);
        XMLSetAttributeVal(bbox,"maxy",maxy);
    }

    const char *pszProj=poSrcDS->GetProjectionRef();
    if (pszProj&&(!EQUAL(pszProj,"")))
        CPLCreateXMLElementAndValue(gtags,"Projection",pszProj);

    CPLSerializeXMLTreeToFile(config,pszFilename);

    // Done with the XML
    CPLDestroyXMLNode(config);

    // Create the data and index files, but only if they don't exist, otherwise leave them untouched
    VSILFILE *f_data=VSIFOpenL(fname_data,"r+b");
    if (NULL==f_data)
        f_data=VSIFOpenL(fname_data,"w+b");
    VSILFILE *f_idx=VSIFOpenL(fname_idx,"r+b");
    if (NULL==f_idx)
        f_idx=VSIFOpenL(fname_idx,"w+b");

    if ((NULL==f_data)||(NULL==f_idx)) {
        CPLError(CE_Failure,CPLE_AppDefined,"Can't open data or index files in update mode");
        return NULL;
    }

    // Leave the data empty but build the index file
    int idx_sz=pcount(nXSize,ILSPage.x)*pcount(nYSize,ILSPage.y)*pcount(nBands,ILSPage.c)*sizeof(ILIdx);

    // Write the last tile index if the file seems to small
    if (!CheckFileSize(f_idx,idx_sz,GA_Update)) {
        VSIFCloseL(f_data);
        VSIFCloseL(f_idx);
        CPLError(CE_Failure,CPLE_AppDefined,"Can't extend the index file");
        return NULL;
    }

    // Close these too
    VSIFCloseL(f_data);
    VSIFCloseL(f_idx);

    // Reopen in RW mode and use the standard CopyWholeRaster
    GDALDataset *poDS = (GDALDataset *) GDALOpen(pszFilename, GA_Update);

    // Need to flag the dataset as compressed (COMPRESSED=TRUE) to force block writes
    char **papszCWROptions= CSLDuplicate(0);
    papszCWROptions=CSLAddNameValue(papszCWROptions,"COMPRESSED","TRUE");
    CPLErr err=GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS,
            (GDALDatasetH) poDS, papszCWROptions,pfnProgress,
            pProgressData);
    
    CSLDestroy(papszCWROptions);
    if (CE_Failure==err) {
        delete poDS;
        // Maybe clean up the files that might have been created here?
        return NULL;
    }

    return poDS;
}
示例#10
0
static void CreatePath( HDF5GroupObjects *poH5Object )
{
    // Recurse to the root path.
    CPLString osPath;
    if( poH5Object->poHparent != nullptr )
    {
        CreatePath(poH5Object->poHparent);
        osPath = poH5Object->poHparent->pszPath;
    }

    // Add name to the path.
    if( !EQUAL(poH5Object->pszName, "/") )
    {
        osPath.append("/");
        osPath.append(poH5Object->pszName);
    }

    // Fill up path for each object.
    CPLString osUnderscoreSpaceInName;
    if( poH5Object->pszPath == nullptr )
    {

        if( strlen(poH5Object->pszName) == 1 )
        {
            osPath.append(poH5Object->pszName);
            osUnderscoreSpaceInName = poH5Object->pszName;
        }
        else
        {
            // Change space for underscore.
            char **papszPath =
                CSLTokenizeString2(osPath.c_str(), " ", CSLT_HONOURSTRINGS);

            for( int i = 0; papszPath[i] != nullptr ; i++ )
            {
                if( i > 0 )
                    osUnderscoreSpaceInName.append("_");
                osUnderscoreSpaceInName.append(papszPath[i]);
            }
            CSLDestroy(papszPath);
        }

        // -1 to give room for NUL in C strings.
        constexpr size_t MAX_PATH = 8192 - 1;
        // TODO(schwehr): Is it an issue if the results are longer than 8192?
        // It appears that the output can never be longer than the source.
        if( osUnderscoreSpaceInName.size() > MAX_PATH )
            CPLError(CE_Fatal, CPLE_AppDefined,
                     "osUnderscoreSpaceInName longer than MAX_PATH: "
                     "%u > %u",
                     static_cast<unsigned int>(osUnderscoreSpaceInName.size()),
                     static_cast<unsigned int>(MAX_PATH));
        if( osPath.size() > MAX_PATH )
            CPLError(CE_Fatal, CPLE_AppDefined,
                     "osPath longer than MAX_PATH: %u > %u",
                     static_cast<unsigned int>(osPath.size()),
                     static_cast<unsigned int>(MAX_PATH));

        poH5Object->pszUnderscorePath =
            CPLStrdup(osUnderscoreSpaceInName.c_str());
        poH5Object->pszPath = CPLStrdup(osPath.c_str());
    }
}