예제 #1
0
파일: crypt.cpp 프로젝트: Mileslee/wxgis
bool CreateRandomData(void)
{
	wxGISAppConfig oConfig = GetConfig();
	if(!oConfig.IsOk())
		return false;

	GByte key[EVP_KEY_SIZE];
	if(!RAND_bytes(key, sizeof(key)))
		return false;
	CPLString pszKey(CPLBinaryToHex(EVP_KEY_SIZE, key));
	if(!oConfig.Write(enumGISHKCU, wxString(wxT("wxGISCommon/crypt/key")), wxString(pszKey, wxConvUTF8)))
 		return false;
	GByte iv[EVP_IV_SIZE];
	if(!RAND_bytes(iv, sizeof(iv)))
		return false;
	CPLString pszIV(CPLBinaryToHex(EVP_IV_SIZE, iv));
	return oConfig.Write(enumGISHKCU, wxString(wxT("wxGISCommon/crypt/iv")), wxString(pszIV, wxConvUTF8));
}
예제 #2
0
int GDALJP2Box::DumpReadable( FILE *fpOut, int nIndentLevel )

{
    if( fpOut == NULL )
        fpOut = stdout;

    int i;
    for(i=0;i<nIndentLevel;i++)
        fprintf( fpOut, "  " );

    fprintf( fpOut, "  Type=%s, Offset=" CPL_FRMT_GIB "/" CPL_FRMT_GIB", Data Size=" CPL_FRMT_GIB,
             szBoxType, nBoxOffset, nDataOffset, 
             GetDataLength() );

    if( IsSuperBox() )
    {
        fprintf( fpOut, " (super)" );
    }

    fprintf( fpOut, "\n" );
    
    if( IsSuperBox() ) 
    {
        GDALJP2Box oSubBox( GetFILE() );

        for( oSubBox.ReadFirstChild( this );
             strlen(oSubBox.GetType()) > 0;
             oSubBox.ReadNextChild( this ) )
        {
            oSubBox.DumpReadable( fpOut, nIndentLevel + 1 );
        }
    }

    if( EQUAL(GetType(),"uuid") )
    {
        char *pszHex = CPLBinaryToHex( 16, GetUUID() );
        for(i=0;i<nIndentLevel;i++)
            fprintf( fpOut, "  " );

        fprintf( fpOut, "    UUID=%s", pszHex );

        if( EQUAL(pszHex,"B14BF8BD083D4B43A5AE8CD7D5A6CE03") )
            fprintf( fpOut, " (GeoTIFF)" );
        if( EQUAL(pszHex,"96A9F1F1DC98402DA7AED68E34451809") )
            fprintf( fpOut, " (MSI Worldfile)" );
        if( EQUAL(pszHex,"BE7ACFCB97A942E89C71999491E3AFAC") )
            fprintf( fpOut, " (XMP)" );
        CPLFree( pszHex );

        fprintf( fpOut, "\n" );
    }

    return 0;
}
예제 #3
0
파일: crypt.cpp 프로젝트: Mileslee/wxgis
wxString GetRandomKey(short nLen)
{
	GByte *key = new GByte[nLen];
	if(!RAND_bytes(key, nLen))
    {
        wxDELETE(key);
		return wxEmptyString;
    }
	CPLString pszKey(CPLBinaryToHex(nLen, key));
    wxDELETE(key);
	return wxString(pszKey, wxConvUTF8);
}
예제 #4
0
int GDALJP2Box::DumpReadable( FILE *fpOut )

{
    if( fpOut == NULL )
        fpOut = stdout;

    fprintf( fpOut, "  Type=%s, Offset=%d/%d, Data Size=%d",
             szBoxType, (int) nBoxOffset, (int) nDataOffset, 
             (int)(nBoxLength - (nDataOffset - nBoxOffset)) );

    if( IsSuperBox() )
    {
        fprintf( fpOut, " (super)" );
    }

    fprintf( fpOut, "\n" );
    
    if( IsSuperBox() ) 
    {
        GDALJP2Box oSubBox( GetFILE() );

        for( oSubBox.ReadFirstChild( this );
             strlen(oSubBox.GetType()) > 0;
             oSubBox.ReadNextChild( this ) )
        {
            oSubBox.DumpReadable( fpOut );
        }

        printf( "  (end of %s subboxes)\n", szBoxType );
    }

    if( EQUAL(GetType(),"uuid") )
    {
        char *pszHex = CPLBinaryToHex( 16, GetUUID() );
        fprintf( fpOut, "    UUID=%s", pszHex );

        if( EQUAL(pszHex,"B14BF8BD083D4B43A5AE8CD7D5A6CE03") )
            fprintf( fpOut, " (GeoTIFF)" );
        if( EQUAL(pszHex,"96A9F1F1DC98402DA7AED68E34451809") )
            fprintf( fpOut, " (MSI Worldfile)" );
        CPLFree( pszHex );

        fprintf( fpOut, "\n" );
    }

    return 0;
}
예제 #5
0
파일: crypt.cpp 프로젝트: Mileslee/wxgis
bool Crypt(const wxString &sText, wxString &sCryptText)
{

	GByte *pabyKey = GetKey();
	GByte *pabyIV = GetIV();

	EVP_CIPHER_CTX* ctx = CreateCTX(pabyKey, pabyIV, false);
	if(!ctx)
	{
		wxLogError(_("Crypt: Failed EVP_EncryptInit!"));
		CPLFree( pabyKey );
		CPLFree( pabyIV );
		return false;
	}

	CPLString pszText(sText.mb_str(wxConvUTF8));
	int outlen;
	unsigned char outbuf[BUFSIZE];

	bool bResult = EVP_EncryptUpdate(ctx, outbuf, &outlen, (const unsigned char*)pszText.data(), pszText.length() * sizeof(pszText[0]) + 1);

	if(!bResult)
	{
		wxLogError(_("Crypt: Failed EVP_EncryptUpdate!"));
		CPLFree( pabyKey );
		CPLFree( pabyIV );
		return bResult;
	}

	int nLen = outlen;
	bResult = EVP_EncryptFinal(ctx, &outbuf[outlen], &outlen);
	nLen += outlen;

	CPLString pszOutput(CPLBinaryToHex(nLen, outbuf));
	sCryptText = wxString(pszOutput, wxConvUTF8);

	CPLFree( pabyKey );
	CPLFree( pabyIV );
	EVP_CIPHER_CTX_cleanup(ctx);
	//EVP_CIPHER_CTX_free(ctx);

	return bResult;
}
예제 #6
0
OGRErr OGRIngresTableLayer::CreateFeature( OGRFeature *poFeature )

{
    CPLString           osCommand;
    int                 i, bNeedComma = FALSE;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO %s (", poFeatureDefn->GetName() );


/* -------------------------------------------------------------------- */
/*      Accumulate fields to be inserted.                               */
/* -------------------------------------------------------------------- */
    if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() )
    {
        osCommand = osCommand + osGeomColumn + " ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() )
    {
        if( bNeedComma )
            osCommand += ", ";
        
        osCommand = osCommand + osFIDColumn + " ";
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand 
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef();
    }

    osCommand += ") VALUES (";

/* -------------------------------------------------------------------- */
/*      Insert the geometry (as a place holder)                         */
/* -------------------------------------------------------------------- */
    CPLString osGeomText;

    // Set the geometry 
    bNeedComma = FALSE;
    if( poFeature->GetGeometryRef() != NULL && osGeomColumn.size() )
    {
        bNeedComma = TRUE;
        OGRErr localErr;

        if( poDS->IsNewIngres() )
        {
        	localErr = PrepareNewStyleGeometry( poFeature->GetGeometryRef(), osGeomText );
        }
        else
        {
        	localErr = PrepareOldStyleGeometry( poFeature->GetGeometryRef(), osGeomText );
        }
        if( localErr == OGRERR_NONE )
        {
            if( CSLTestBoolean( 
                     CPLGetConfigOption( "INGRES_INSERT_SUB", "NO") ) )
            {
                osCommand += " ~V";
            }
            else if( poDS->IsNewIngres() == FALSE )
            {
                osCommand += "'";
                osCommand += osGeomText;
                osCommand += "'";
                osGeomText = "";
            }
            else
            {
            	osCommand += osGeomText;
            	//osGeomText = "";
            }
        }
        else
        {
            osGeomText = "";
            osCommand += "NULL"; /* is this sort of empty geometry legal? */
        }
    }

/* -------------------------------------------------------------------- */
/*      Set the FID                                                     */
/* -------------------------------------------------------------------- */
    if( poFeature->GetFID() != OGRNullFID && osFIDColumn.size() )
    {
        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Copy in the attribute values.                                   */
/* -------------------------------------------------------------------- */
    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            int         iChar;

            //We need to quote and escape string fields. 
            osCommand += "'";

            for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "INGRES",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\'';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }

    }

    osCommand += ")";

/* -------------------------------------------------------------------- */
/*      Execute it.                                                     */
/* -------------------------------------------------------------------- */
    poDS->EstablishActiveLayer( NULL );
    OGRIngresStatement oStmt( poDS->GetConn() );

    oStmt.bDebug = FALSE; 

    if( osGeomText.size() > 0  && poDS->IsNewIngres() == FALSE )
        oStmt.addInputParameter( IIAPI_LVCH_TYPE, osGeomText.size(),
                                 (GByte *) osGeomText.c_str() );
    if( osGeomText.size() > 0 && poDS->IsNewIngres() == TRUE )
    {
    	GByte * pabyWKB;
    	int nSize = poFeature->GetGeometryRef()->WkbSize();
    	pabyWKB = (GByte *) CPLMalloc(nSize);

    	poFeature->GetGeometryRef()->exportToWkb(wkbNDR, pabyWKB);

    	oStmt.addInputParameter( IIAPI_LBYTE_TYPE, nSize, pabyWKB );
    	CPLFree(pabyWKB);
/*
 * Test code
     	char * pszWKT;
    	poFeature->GetGeometryRef()->exportToWkt(&pszWKT);
    	oStmt.addInputParameter(IIAPI_LVCH_TYPE, strlen(pszWKT), (GByte *) pszWKT);*/
    }

    if( !oStmt.ExecuteSQL( osCommand ) )
        return OGRERR_FAILURE;
    
    return OGRERR_NONE;

}
/*****************************************************
 * \brief Write a natural block of raster band data
 *****************************************************/
CPLErr PostGISRasterRasterBand::IWriteBlock(int nBlockXOff,
        int nBlockYOff, void * pImage)
{
    int nPixelSize = GDALGetDataTypeSize(eDataType) / 8;
    int nNaturalBlockXSize = 0;
    int nNaturalBlockYSize = 0;
    int nDataSize = 0;
    int nBandMetaDataSize = 0;
    PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS;
    CPLDebug("PostGIS_Raster",
        "PostGISRasterRasterBand::IWriteBlock(): Table %s.%s (%s), Srid : %d",
        pszSchema, pszTable, pszColumn,poRDS->nSrid);

    // How much data are we going to copy?
    GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize);
    nDataSize = nNaturalBlockXSize * nNaturalBlockYSize * nPixelSize;

    // Allocating space for band metadata
    nBandMetaDataSize = (nPixelSize + 1);
    char * pszBandMetadata = (char*) VSIMalloc2(2 * nBandMetaDataSize, sizeof (char));

    // Allocate memory for all bands data, if needed
    if (!poRDS->pBufferToInsert) {
        CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(); "
            "Allocating memory for buffer to hold insert query data (%d characters)",
            2 * (nDataSize + nBandMetaDataSize) * poRDS->nBandsToCopy);

        poRDS->pBufferToInsert =
            (char *)VSIMalloc3(poRDS->nBandsToCopy, 2 * (nDataSize + nBandMetaDataSize), sizeof(char));

        poRDS->nPosToCopy = 0;
        poRDS->nBandsCopied = 0;
    }

    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IWriteBlock(): Block (%d x %d), Metadata %d. We are "
            "copying %d bytes", nNaturalBlockXSize, nNaturalBlockYSize, nBandMetaDataSize, nDataSize+nBandMetaDataSize);

    /**
     * Copy the band data into the dataset buffer. We will raise the query
     * after we have the data of all bands in the buffer.
     *
     * NOTE: At this point, datatype translation between src and dst has been
     * performed by IRasterIO. So, we can use band datatype for both, origin
     * and destination buffers.
     **/

    // GDALCopyWords(pImage, eDataType, 0,
    //     poRDS->pBufferToInsert + poRDS->nPosToCopy, eDataType, 0, nDataSize);

    char cPostGISQueryWKT = TranslateDataTypeGDALtoPostGIS(&eDataType);
    if(cPostGISQueryWKT == '\0'){
        CPLDebug("PostGIS_Raster",
                "PostGISRasterRasterBand::IWriteBlock(): PostGIS Datatype id : %c",
                cPostGISQueryWKT);
        return CE_Failure;
    }
    CPLDebug("PostGIS_Raster",
            "PostGISRasterRasterBand::IWriteBlock(): HasNoDataValue = %s, NoDataValue = %f",
            bNoDataValueSet? "True" : "False", dfNoDataValue);

    /* Testing bNoDataValueSet :: Hack */
    // bNoDataValueSet = 1;
    // dfNoDataValue = 0;
    if(bNoDataValueSet)
        pszBandMetadata[0] = '4';
    else
        pszBandMetadata[0] = '0';

    pszBandMetadata[1] = cPostGISQueryWKT;
    strcpy(pszBandMetadata + 2, CPLBinaryToHex(nPixelSize,(GByte *)&dfNoDataValue));
    memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, pszBandMetadata, nBandMetaDataSize * 2);
    poRDS->nPosToCopy += nBandMetaDataSize * 2;
    memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, CPLBinaryToHex(nDataSize,(GByte *)pImage), nDataSize * 2);
    poRDS->nPosToCopy += nDataSize * 2;
    poRDS->pBufferToInsert[poRDS->nPosToCopy] = '\0';
    poRDS->nBandsCopied++;

    // Check if we're done, to raise the insert query
    if (poRDS->nBandsToCopy == poRDS->nBandsCopied) {

        PGresult * poResult = NULL;
        CPLString osCommand;
/*
        // hack
        pszSchema = "public";
        pszTable = "newtable";
        pszColumn = "rast";
*/
        // Raise insert query
        // TODO: The table may contain more fields
        // FIXME: For some reason, pszSchema, pszTable and pszColumn are NULL.
        // I think it's related with the fact we overwrote GDALDataset::IRasterIO,
        // and we delegate in default implementation. Here, poDS is a simple
        // GDALDataset *, not a PostGISRasterDataset *

        // FIXME: anyway, even hardcoding schema/table/column names here, we
        // still have an error:
        // ERROR:  rt_raster_from_wkb: WKB version 10091 unsupported
        // This is caused because we're not correctly creating the hex string
        // representing PostGIS Raster. Version should be 0, and number 10091
        // is being read instead. We're not including headers in the hex string,
        // just raster data. Need to fix this.
        osCommand.Printf("insert into %s.%s (%s) values('010000",pszSchema, pszTable, pszColumn);
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&poRDS->nBandsToCopy));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_WE_RES]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_NS_RES]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM1]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM2]));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(4, (GByte*)&poRDS->nSrid));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockXSize));
        osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockYSize));
        osCommand += poRDS->pBufferToInsert;
        osCommand += "'::raster)";

        CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock: Insert "
            "query raised: %s", osCommand.c_str());

        poResult = PQexec(poRDS->poConn, osCommand.c_str());

        if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) {

            CPLError(CE_Failure, CPLE_AppDefined,
                "Error inserting raster data in %s.%s: %s", pszSchema,
                pszTable, PQerrorMessage(poRDS->poConn));

            if (poResult != NULL)
                PQclear(poResult);

            // rollback
            poResult = PQexec(poRDS->poConn, "rollback");
            if (poResult == NULL ||
                PQresultStatus(poResult) != PGRES_COMMAND_OK) {

                CPLError(CE_Failure, CPLE_AppDefined,
                    "Error rolling back transaction: %s",
                PQerrorMessage(poRDS->poConn));
            }

            if (poResult != NULL)
                PQclear(poResult);
        }


        // Release memory
        VSIFree(poRDS->pBufferToInsert);
        poRDS->pBufferToInsert = NULL;
    }

    return CE_None;
}
예제 #8
0
CPLXMLNode *GDALPamRasterBand::SerializeToXML( const char *pszUnused )

{
    if( psPam == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Setup root node and attributes.                                 */
/* -------------------------------------------------------------------- */
    CPLString oFmt;

    CPLXMLNode *psTree;

    psTree = CPLCreateXMLNode( NULL, CXT_Element, "PAMRasterBand" );

    if( GetBand() > 0 )
        CPLSetXMLValue( psTree, "#band", oFmt.Printf( "%d", GetBand() ) );

/* -------------------------------------------------------------------- */
/*      Serialize information of interest.                              */
/* -------------------------------------------------------------------- */
    if( strlen(GetDescription()) > 0 )
        CPLSetXMLValue( psTree, "Description", GetDescription() );

    if( psPam->bNoDataValueSet )
    {
        if (CPLIsNan(psPam->dfNoDataValue))
            CPLSetXMLValue( psTree, "NoDataValue",  "nan" );
        else
            CPLSetXMLValue( psTree, "NoDataValue", 
                            oFmt.Printf( "%.14E", psPam->dfNoDataValue ) );

        /* hex encode real floating point values */
        if( psPam->dfNoDataValue != floor(psPam->dfNoDataValue) 
            || psPam->dfNoDataValue != atof(oFmt) )
        {
            double dfNoDataLittleEndian;

            dfNoDataLittleEndian = psPam->dfNoDataValue;
            CPL_LSBPTR64( &dfNoDataLittleEndian );

            char *pszHexEncoding = 
                CPLBinaryToHex( 8, (GByte *) &dfNoDataLittleEndian );
            CPLSetXMLValue( psTree, "NoDataValue.#le_hex_equiv",pszHexEncoding);
            CPLFree( pszHexEncoding );
        }
    }

    if( psPam->pszUnitType != NULL )
        CPLSetXMLValue( psTree, "UnitType", psPam->pszUnitType );

    if( psPam->dfOffset != 0.0 )
        CPLSetXMLValue( psTree, "Offset", 
                        oFmt.Printf( "%.16g", psPam->dfOffset ) );

    if( psPam->dfScale != 1.0 )
        CPLSetXMLValue( psTree, "Scale", 
                        oFmt.Printf( "%.16g", psPam->dfScale ) );

    if( psPam->eColorInterp != GCI_Undefined )
        CPLSetXMLValue( psTree, "ColorInterp", 
                        GDALGetColorInterpretationName( psPam->eColorInterp ));

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( psPam->papszCategoryNames != NULL )
    {
        CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, 
                                                 "CategoryNames" );

        for( int iEntry=0; psPam->papszCategoryNames[iEntry] != NULL; iEntry++)
        {
            CPLCreateXMLElementAndValue( psCT_XML, "Category", 
                                         psPam->papszCategoryNames[iEntry] );
        }
    }

/* -------------------------------------------------------------------- */
/*      Color Table.                                                    */
/* -------------------------------------------------------------------- */
    if( psPam->poColorTable != NULL )
    {
        CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, 
                                                 "ColorTable" );

        for( int iEntry=0; iEntry < psPam->poColorTable->GetColorEntryCount(); 
             iEntry++ )
        {
            GDALColorEntry sEntry;
            CPLXMLNode *psEntry_XML = CPLCreateXMLNode( psCT_XML, CXT_Element, 
                                                        "Entry" );

            psPam->poColorTable->GetColorEntryAsRGB( iEntry, &sEntry );
            
            CPLSetXMLValue( psEntry_XML, "#c1", oFmt.Printf("%d",sEntry.c1) );
            CPLSetXMLValue( psEntry_XML, "#c2", oFmt.Printf("%d",sEntry.c2) );
            CPLSetXMLValue( psEntry_XML, "#c3", oFmt.Printf("%d",sEntry.c3) );
            CPLSetXMLValue( psEntry_XML, "#c4", oFmt.Printf("%d",sEntry.c4) );
        }
    }

/* -------------------------------------------------------------------- */
/*      Min/max.                                                        */
/* -------------------------------------------------------------------- */
    if( psPam->bHaveMinMax )
    {
        CPLSetXMLValue( psTree, "Minimum", 
                        oFmt.Printf( "%.16g", psPam->dfMin ) );
        CPLSetXMLValue( psTree, "Maximum", 
                        oFmt.Printf( "%.16g", psPam->dfMax ) );
    }

/* -------------------------------------------------------------------- */
/*      Statistics                                                      */
/* -------------------------------------------------------------------- */
    if( psPam->bHaveStats )
    {
        CPLSetXMLValue( psTree, "Mean", 
                        oFmt.Printf( "%.16g", psPam->dfMean ) );
        CPLSetXMLValue( psTree, "StandardDeviation", 
                        oFmt.Printf( "%.16g", psPam->dfStdDev ) );
    }

/* -------------------------------------------------------------------- */
/*      Histograms.                                                     */
/* -------------------------------------------------------------------- */
    if( psPam->psSavedHistograms != NULL )
        CPLAddXMLChild( psTree, CPLCloneXMLTree( psPam->psSavedHistograms ) );

/* -------------------------------------------------------------------- */
/*      Raster Attribute Table                                          */
/* -------------------------------------------------------------------- */
    if( psPam->poDefaultRAT != NULL )
        CPLAddXMLChild( psTree, psPam->poDefaultRAT->Serialize() );

/* -------------------------------------------------------------------- */
/*      Metadata.                                                       */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psMD;

    psMD = oMDMD.Serialize();
    if( psMD != NULL )
    {
        if( psMD->psChild == NULL )
            CPLDestroyXMLNode( psMD );
        else
            CPLAddXMLChild( psTree, psMD );
    }

/* -------------------------------------------------------------------- */
/*      We don't want to return anything if we had no metadata to       */
/*      attach.                                                         */
/* -------------------------------------------------------------------- */
    if( psTree->psChild == NULL || psTree->psChild->psNext == NULL )
    {
        CPLDestroyXMLNode( psTree );
        psTree = NULL;
    }

    return psTree;
}
예제 #9
0
void OGRDWGLayer::TranslateGenericProperties( OGRFeature *poFeature,
                                              OdDbEntityPtr poEntity )

{
    poFeature->SetField( "Layer", TextUnescape(poEntity->layer()) );
    poFeature->SetField( "Linetype", TextUnescape(poEntity->layer()) );

    CPLString osValue;
    osValue.Printf( "%d", (int) poEntity->lineWeight() );
    oStyleProperties["LineWeight"] = osValue;

    OdDbHandle oHandle = poEntity->getDbHandle();
    poFeature->SetField( "EntityHandle", (const char *) oHandle.ascii() );

    if( poEntity->colorIndex() != 256 )
    {
        osValue.Printf( "%d", poEntity->colorIndex() );
        oStyleProperties["Color"] = osValue.c_str();
    }

/* -------------------------------------------------------------------- */
/*      Collect the subclasses.                                         */
/* -------------------------------------------------------------------- */
    CPLString osSubClasses;
    OdRxClass *poClass = poEntity->isA();

    while( poClass != NULL )
    {
        if( !osSubClasses.empty() )
            osSubClasses = ":" + osSubClasses;

        osSubClasses = ((const char *) poClass->name()) + osSubClasses;
        if( EQUAL(poClass->name(),"AcDbEntity") )
            break;

        poClass = poClass->myParent();
    }

    poFeature->SetField( "SubClasses", osSubClasses.c_str() );

/* -------------------------------------------------------------------- */
/*      Collect Xdata.                                                  */
/* -------------------------------------------------------------------- */
    OdResBufPtr poResBufBase = poEntity->xData();
    OdResBuf *poResBuf = poResBufBase;
    CPLString osFullXData;

    for ( ; poResBuf != NULL; poResBuf = poResBuf->next() )
    {
        CPLString osXDataItem;

        switch (OdDxfCode::_getType(poResBuf->restype()))
        {
          case OdDxfCode::Name:
          case OdDxfCode::String:
          case OdDxfCode::LayerName:
            osXDataItem = (const char *) poResBuf->getString();
            break;

          case OdDxfCode::Bool:
            if( poResBuf->getBool() )
                osXDataItem = "true";
            else
                osXDataItem = "false";
            break;

          case OdDxfCode::Integer8:
            osXDataItem.Printf( "%d", (int) poResBuf->getInt8() );
            break;

          case OdDxfCode::Integer16:
            osXDataItem.Printf( "%d", (int) poResBuf->getInt16() );
            break;

          case OdDxfCode::Integer32:
            osXDataItem.Printf( "%d", (int) poResBuf->getInt32() );
            break;

          case OdDxfCode::Double:
          case OdDxfCode::Angle:
            osXDataItem.Printf( "%g", poResBuf->getDouble() );
            break;

          case OdDxfCode::Point:
          {
              OdGePoint3d oPoint = poResBuf->getPoint3d();
              osXDataItem.Printf( "(%g,%g,%g)", oPoint.x, oPoint.y, oPoint.z );
          }
          break;

          case OdDxfCode::BinaryChunk:
          {
              OdBinaryData oBinData = poResBuf->getBinaryChunk();
              char *pszAsHex = CPLBinaryToHex( oBinData.size(),
                                               (GByte*) oBinData.asArrayPtr() );
              osXDataItem = pszAsHex;
              CPLFree( pszAsHex );
          }
          break;

          case OdDxfCode::ObjectId:
          case OdDxfCode::SoftPointerId:
          case OdDxfCode::HardPointerId:
          case OdDxfCode::SoftOwnershipId:
          case OdDxfCode::HardOwnershipId:
          case OdDxfCode::Handle:
            osXDataItem = (const char *) poResBuf->getHandle().ascii();
            break;

          default:
            break;
        }

        if( !osFullXData.empty() )
            osFullXData += " ";
        osFullXData += (const char *) osXDataItem;
    }

    poFeature->SetField( "ExtendedEntity", osFullXData );

#ifdef notdef
      // OCS vector.
      case 210:
        oStyleProperties["210_N.dX"] = pszValue;
        break;

      case 220:
        oStyleProperties["220_N.dY"] = pszValue;
        break;

      case 230:
        oStyleProperties["230_N.dZ"] = pszValue;
        break;

      default:
        break;
    }
예제 #10
0
char *OGRPGDumpLayer::GeometryToHex( OGRGeometry * poGeometry, int nSRSId )
{
    GByte       *pabyWKB;
    char        *pszTextBuf;
    char        *pszTextBufCurrent;
    char        *pszHex;

    int nWkbSize = poGeometry->WkbSize();
    pabyWKB = (GByte *) CPLMalloc(nWkbSize);

    if( poGeometry->exportToWkb( wkbNDR, pabyWKB ) != OGRERR_NONE )
    {
        CPLFree( pabyWKB );
        return CPLStrdup("");
    }

    /* When converting to hex, each byte takes 2 hex characters.  In addition
       we add in 8 characters to represent the SRID integer in hex, and
       one for a null terminator */

    int pszSize = nWkbSize*2 + 8 + 1;
    pszTextBuf = (char *) CPLMalloc(pszSize);
    pszTextBufCurrent = pszTextBuf;

    /* Convert the 1st byte, which is the endianess flag, to hex. */
    pszHex = CPLBinaryToHex( 1, pabyWKB );
    strcpy(pszTextBufCurrent, pszHex );
    CPLFree ( pszHex );
    pszTextBufCurrent += 2;

    /* Next, get the geom type which is bytes 2 through 5 */
    GUInt32 geomType;
    memcpy( &geomType, pabyWKB+1, 4 );

    /* Now add the SRID flag if an SRID is provided */
    if (nSRSId != -1)
    {
        /* Change the flag to wkbNDR (little) endianess */
        GUInt32 nGSrsFlag = CPL_LSBWORD32( WKBSRIDFLAG );
        /* Apply the flag */
        geomType = geomType | nGSrsFlag;
    }

    /* Now write the geom type which is 4 bytes */
    pszHex = CPLBinaryToHex( 4, (GByte*) &geomType );
    strcpy(pszTextBufCurrent, pszHex );
    CPLFree ( pszHex );
    pszTextBufCurrent += 8;

    /* Now include SRID if provided */
    if (nSRSId != -1)
    {
        /* Force the srsid to wkbNDR (little) endianess */
        GUInt32 nGSRSId = CPL_LSBWORD32( nSRSId );
        pszHex = CPLBinaryToHex( sizeof(nGSRSId),(GByte*) &nGSRSId );
        strcpy(pszTextBufCurrent, pszHex );
        CPLFree ( pszHex );
        pszTextBufCurrent += 8;
    }

    /* Copy the rest of the data over - subtract
       5 since we already copied 5 bytes above */
    pszHex = CPLBinaryToHex( nWkbSize - 5, pabyWKB + 5 );
    strcpy(pszTextBufCurrent, pszHex );
    CPLFree ( pszHex );

    CPLFree( pabyWKB );

    return pszTextBuf;
}
OGRErr OGRMySQLTableLayer::CreateFeature( OGRFeature *poFeature )

{
    MYSQL_RES           *hResult=NULL;
    CPLString           osCommand;
    int                 i, bNeedComma = FALSE;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO `%s` (", poFeatureDefn->GetName() );

    if( poFeature->GetGeometryRef() != NULL )
    {
        osCommand = osCommand + "`" + pszGeomColumn + "` ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";
        
        osCommand = osCommand + "`" + pszFIDColumn + "` ";
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand + "`"
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef() + "`";
    }

    osCommand += ") VALUES (";

    // Set the geometry 
    bNeedComma = poFeature->GetGeometryRef() != NULL;
    if( poFeature->GetGeometryRef() != NULL)
    {
        char    *pszWKT = NULL;

        if( poFeature->GetGeometryRef() != NULL )
        {
            OGRGeometry *poGeom = (OGRGeometry *) poFeature->GetGeometryRef();
            
            poGeom->closeRings();
            poGeom->flattenTo2D();
            poGeom->exportToWkt( &pszWKT );
        }

        if( pszWKT != NULL )
        {

            osCommand += 
                CPLString().Printf(
                    "GeometryFromText('%s',%d) ", pszWKT, nSRSId );

            OGRFree( pszWKT );
        }
        else
            osCommand += "''";
    }


    // Set the FID 
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != NULL )
    {
        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( "%ld ", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

    for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            int         iChar;

            //We need to quote and escape string fields. 
            osCommand += "'";

            for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "MYSQL",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\\'
                    || pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\\';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }

    }

    osCommand += ")";
    
    int nQueryResult = mysql_query(poDS->GetConn(), osCommand.c_str() );
    const my_ulonglong nFID = mysql_insert_id( poDS->GetConn() );
    
    if( nQueryResult ){   
        int eErrorCode = mysql_errno(poDS->GetConn());
        if (eErrorCode == 1153) {//ER_NET_PACKET_TOO_LARGE)
            poDS->ReportError("CreateFeature failed because the MySQL server " \
                              "cannot read the entire query statement.  Increase " \
                              "the size of statements your server will allow by " \
                              "altering the 'max_allowed_packet' parameter in "\
                              "your MySQL server configuration.");
        }
        else
        {
        CPLDebug("MYSQL","Error number %d", eErrorCode);
            poDS->ReportError(  osCommand.c_str() );
        }

        // make sure to attempt to free results
        hResult = mysql_store_result( poDS->GetConn() );
        if( hResult != NULL )
            mysql_free_result( hResult );
        hResult = NULL;
            
        return OGRERR_FAILURE;   
    }

    if( nFID > 0 ) {
        poFeature->SetFID( nFID );
    }

    // make sure to attempt to free results of successful queries
    hResult = mysql_store_result( poDS->GetConn() );
    if( hResult != NULL )
        mysql_free_result( hResult );
    hResult = NULL;
    
    return OGRERR_NONE;

}
예제 #12
0
OGRErr OGRPGeoLayer::createFromShapeBin( GByte *pabyShape, 
                                         OGRGeometry **ppoGeom,
                                         int nBytes )

{
    *ppoGeom = NULL;

    if( nBytes < 1 )
        return OGRERR_FAILURE;

    int nSHPType = pabyShape[0];


//    CPLDebug( "PGeo", 
//              "Shape type read from PGeo data is nSHPType = %d", 
//              nSHPType );

/* -------------------------------------------------------------------- */
/*      type 50 appears to just be an alias for normal line             */
/*      strings. (#1484)                                                */
/*      Type 51 appears to just be an alias for normal polygon. (#3100) */
/*      TODO: These types include additional attributes including       */
/*      non-linear segments and such. They should be handled.           */
/* -------------------------------------------------------------------- */
    switch( nSHPType )
    {
      case 50:
        nSHPType = SHPT_ARC;
        break;
      case 51:
        nSHPType = SHPT_POLYGON;
        break;
      case 52:
        nSHPType = SHPT_POINT;
        break;
      case 53:
        nSHPType = SHPT_MULTIPOINT;
        break;
      case 54:
        nSHPType = SHPT_MULTIPATCH;
    }

/* ==================================================================== */
/*  Extract vertices for a Polygon or Arc.				*/
/* ==================================================================== */
    if(    nSHPType == SHPT_ARC
        || nSHPType == SHPT_ARCZ
        || nSHPType == SHPT_ARCM
        || nSHPType == SHPT_ARCZM
        || nSHPType == SHPT_POLYGON 
        || nSHPType == SHPT_POLYGONZ
        || nSHPType == SHPT_POLYGONM
        || nSHPType == SHPT_POLYGONZM
        || nSHPType == SHPT_MULTIPATCH 
        || nSHPType == SHPT_MULTIPATCHM)
    {
        GInt32         nPoints, nParts;
        int            i, nOffset;
        GInt32         *panPartStart;

        if (nBytes < 44)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Extract part/point count, and build vertex and part arrays      */
/*      to proper size.                                                 */
/* -------------------------------------------------------------------- */
	memcpy( &nPoints, pabyShape + 40, 4 );
	memcpy( &nParts, pabyShape + 36, 4 );

	CPL_LSBPTR32( &nPoints );
	CPL_LSBPTR32( &nParts );

        if (nPoints < 0 || nParts < 0 ||
            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d.",
                     nPoints, nParts);
            return OGRERR_FAILURE;
        }

        int bHasZ = (  nSHPType == SHPT_POLYGONZ
                    || nSHPType == SHPT_POLYGONZM
                    || nSHPType == SHPT_ARCZ
                    || nSHPType == SHPT_ARCZM
                    || nSHPType == SHPT_MULTIPATCH 
                    || nSHPType == SHPT_MULTIPATCHM );

        int bIsMultiPatch = ( nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM );

        /* With the previous checks on nPoints and nParts, */
        /* we should not overflow here and after */
        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
        int nRequiredSize = 44 + 4 * nParts + 16 * nPoints;
        if ( bHasZ )
        {
            nRequiredSize += 16 + 8 * nPoints;
        }
        if( bIsMultiPatch )
        {
            nRequiredSize += 4 * nParts;
        }
        if (nRequiredSize > nBytes)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nPoints=%d, nParts=%d, nBytes=%d, nSHPType=%d",
                     nPoints, nParts, nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

        panPartStart = (GInt32 *) VSICalloc(nParts,sizeof(GInt32));
        if (panPartStart == NULL)
        {
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Copy out the part array from the record.                        */
/* -------------------------------------------------------------------- */
	memcpy( panPartStart, pabyShape + 44, 4 * nParts );
	for( i = 0; i < nParts; i++ )
	{
            CPL_LSBPTR32( panPartStart + i );

            /* We check that the offset is inside the vertex array */
            if (panPartStart[i] < 0 ||
                panPartStart[i] >= nPoints)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, nPoints = %d",
                         i, panPartStart[i], nPoints); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
            if (i > 0 && panPartStart[i] <= panPartStart[i-1])
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, panPartStart[%d] = %d",
                         i, panPartStart[i], i - 1, panPartStart[i - 1]); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
	}

	nOffset = 44 + 4*nParts;

/* -------------------------------------------------------------------- */
/*      If this is a multipatch, we will also have parts types.  For    */
/*      now we ignore and skip past them.                               */
/* -------------------------------------------------------------------- */
        if( bIsMultiPatch )
            nOffset += 4*nParts;
        
/* -------------------------------------------------------------------- */
/*      Copy out the vertices from the record.                          */
/* -------------------------------------------------------------------- */
        double *padfX = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfY = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfZ = (double *) VSICalloc(sizeof(double),nPoints);
        if (padfX == NULL || padfY == NULL || padfZ == NULL)
        {
            CPLFree( panPartStart );
            CPLFree( padfX );
            CPLFree( padfY );
            CPLFree( padfZ );
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(padfX + i, pabyShape + nOffset + i * 16, 8 );
	    memcpy(padfY + i, pabyShape + nOffset + i * 16 + 8, 8 );
            CPL_LSBPTR64( padfX + i );
            CPL_LSBPTR64( padfY + i );
	}

        nOffset += 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( bHasZ )
        {
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( padfZ + i, pabyShape + nOffset + 16 + i*8, 8 );
                CPL_LSBPTR64( padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      Build corresponding OGR objects.                                */
/* -------------------------------------------------------------------- */
        if(    nSHPType == SHPT_ARC 
            || nSHPType == SHPT_ARCZ
            || nSHPType == SHPT_ARCM
            || nSHPType == SHPT_ARCZM )
        {
/* -------------------------------------------------------------------- */
/*      Arc - As LineString                                             */
/* -------------------------------------------------------------------- */
            if( nParts == 1 )
            {
                OGRLineString *poLine = new OGRLineString();
                *ppoGeom = poLine;

                poLine->setPoints( nPoints, padfX, padfY, padfZ );
            }

/* -------------------------------------------------------------------- */
/*      Arc - As MultiLineString                                        */
/* -------------------------------------------------------------------- */
            else
            {
                OGRMultiLineString *poMulti = new OGRMultiLineString;
                *ppoGeom = poMulti;

                for( i = 0; i < nParts; i++ )
                {
                    OGRLineString *poLine = new OGRLineString;
                    int nVerticesInThisPart;

                    if( i == nParts-1 )
                        nVerticesInThisPart = nPoints - panPartStart[i];
                    else
                        nVerticesInThisPart = 
                            panPartStart[i+1] - panPartStart[i];

                    poLine->setPoints( nVerticesInThisPart, 
                                       padfX + panPartStart[i], 
                                       padfY + panPartStart[i], 
                                       padfZ + panPartStart[i] );

                    poMulti->addGeometryDirectly( poLine );
                }
            }
        } /* ARC */

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
        else if(    nSHPType == SHPT_POLYGON
                 || nSHPType == SHPT_POLYGONZ
                 || nSHPType == SHPT_POLYGONM
                 || nSHPType == SHPT_POLYGONZM )
        {
            OGRPolygon *poMulti = new OGRPolygon;
            *ppoGeom = poMulti;

            for( i = 0; i < nParts; i++ )
            {
                OGRLinearRing *poRing = new OGRLinearRing;
                int nVerticesInThisPart;

                if( i == nParts-1 )
                    nVerticesInThisPart = nPoints - panPartStart[i];
                else
                    nVerticesInThisPart = 
                        panPartStart[i+1] - panPartStart[i];

                poRing->setPoints( nVerticesInThisPart, 
                                   padfX + panPartStart[i], 
                                   padfY + panPartStart[i], 
                                   padfZ + panPartStart[i] );

                poMulti->addRingDirectly( poRing );
            }
        } /* polygon */

/* -------------------------------------------------------------------- */
/*      Multipatch                                                      */
/* -------------------------------------------------------------------- */
        else if( bIsMultiPatch )
        {
            /* return to this later */
        } 

        CPLFree( panPartStart );
        CPLFree( padfX );
        CPLFree( padfY );
        CPLFree( padfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

/* ==================================================================== */
/*  Extract vertices for a MultiPoint.					*/
/* ==================================================================== */
    else if(    nSHPType == SHPT_MULTIPOINT
             || nSHPType == SHPT_MULTIPOINTM
             || nSHPType == SHPT_MULTIPOINTZ
             || nSHPType == SHPT_MULTIPOINTZM )
    {
#ifdef notdef
	int32		nPoints;
	int    		i, nOffset;

	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
	if( bBigEndian ) SwapWord( 4, &nPoints );

	psShape->nVertices = nPoints;
        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
        psShape->padfM = (double *) calloc(nPoints,sizeof(double));

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );

	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
	}

        nOffset = 48 + 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*	Get the X/Y bounds.						*/
/* -------------------------------------------------------------------- */
        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );

	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );

/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( psShape->nSHPType == SHPT_MULTIPOINTZ || psShape->nSHPType == SHPT_MULTIPOINTZM )
        {
            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfZ + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      If we have a M measure value, then read it now.  We assume      */
/*      that the measure can be present for any shape if the size is    */
/*      big enough, but really it will only occur for the Z shapes      */
/*      (options), and the M shapes.                                    */
/* -------------------------------------------------------------------- */
        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
        {
            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfM + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
            }
        }
#endif
    }

/* ==================================================================== */
/*      Extract vertices for a point.                                   */
/* ==================================================================== */
    else if(    nSHPType == SHPT_POINT
             || nSHPType == SHPT_POINTM
             || nSHPType == SHPT_POINTZ
             || nSHPType == SHPT_POINTZM )
    {
        int	nOffset;
        double  dfX, dfY, dfZ = 0;

        int bHasZ = (nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM);

        if (nBytes < 4 + 8 + 8 + ((nSHPType == SHPT_POINTZ) ? 8 : 0))
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }
        
	memcpy( &dfX, pabyShape + 4, 8 );
	memcpy( &dfY, pabyShape + 4 + 8, 8 );

        CPL_LSBPTR64( &dfX );
        CPL_LSBPTR64( &dfY );
        nOffset = 20 + 8;
        
        if( bHasZ )
        {
            memcpy( &dfZ, pabyShape + 4 + 16, 8 );
            CPL_LSBPTR64( &dfZ );
        }

        *ppoGeom = new OGRPoint( dfX, dfY, dfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

    char* pszHex = CPLBinaryToHex( nBytes, pabyShape );
    CPLDebug( "PGEO", "Unsupported geometry type:%d\nnBytes=%d, hex=%s",
              nSHPType, nBytes, pszHex );
    CPLFree(pszHex);

    return OGRERR_FAILURE;
}
예제 #13
0
OGRErr OGRMySQLTableLayer::ICreateFeature( OGRFeature *poFeature )

{
    int bNeedComma = FALSE;
    CPLString osCommand;

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand.Printf( "INSERT INTO `%s` (", poFeatureDefn->GetName() );

    if( poFeature->GetGeometryRef() != nullptr )
    {
        osCommand = osCommand + "`" + pszGeomColumn + "` ";
        bNeedComma = TRUE;
    }

    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != nullptr )
    {
        if( bNeedComma )
            osCommand += ", ";

        osCommand = osCommand + "`" + pszFIDColumn + "` ";
        bNeedComma = TRUE;
    }

    for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( !bNeedComma )
            bNeedComma = TRUE;
        else
            osCommand += ", ";

        osCommand = osCommand + "`"
             + poFeatureDefn->GetFieldDefn(i)->GetNameRef() + "`";
    }

    osCommand += ") VALUES (";

    // Set the geometry
    bNeedComma = poFeature->GetGeometryRef() != nullptr;
    if( poFeature->GetGeometryRef() != nullptr)
    {
        char    *pszWKT = nullptr;

        if( poFeature->GetGeometryRef() != nullptr )
        {
            OGRGeometry *poGeom = (OGRGeometry *) poFeature->GetGeometryRef();

            poGeom->closeRings();
            poGeom->flattenTo2D();
            poGeom->exportToWkt( &pszWKT );
        }

        if( pszWKT != nullptr )
        {
            const char* pszAxisOrder = "";
            OGRSpatialReference* l_poSRS = GetSpatialRef();
            if( poDS->GetMajorVersion() >= 8 && !poDS->IsMariaDB() &&
                l_poSRS && l_poSRS->IsGeographic() )
            {
                pszAxisOrder = ", 'axis-order=long-lat'";
            }

            osCommand +=
                CPLString().Printf(
                    "%s('%s',%d%s) ",
                    poDS->GetMajorVersion() >= 8 ? "ST_GeomFromText" : "GeometryFromText",
                    pszWKT, nSRSId, pszAxisOrder );

            CPLFree( pszWKT );
        }
        else
            osCommand += "''";
    }

    // Set the FID
    if( poFeature->GetFID() != OGRNullFID && pszFIDColumn != nullptr )
    {
        GIntBig nFID = poFeature->GetFID();
        if( !CPL_INT64_FITS_ON_INT32(nFID) &&
            GetMetadataItem(OLMD_FID64) == nullptr )
        {
            CPLString osCommand2;
            osCommand2.Printf(
                     "ALTER TABLE `%s` MODIFY COLUMN `%s` BIGINT UNIQUE NOT NULL AUTO_INCREMENT",
                     poFeatureDefn->GetName(), pszFIDColumn );

            if( mysql_query(poDS->GetConn(), osCommand2 ) )
            {
                poDS->ReportError( osCommand2 );
                return OGRERR_FAILURE;
            }

            // make sure to attempt to free results of successful queries
            MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
            if( hResult != nullptr )
                mysql_free_result( hResult );
            hResult = nullptr;

            SetMetadataItem(OLMD_FID64, "YES");
        }

        if( bNeedComma )
            osCommand += ", ";
        osCommand += CPLString().Printf( CPL_FRMT_GIB, nFID );
        bNeedComma = TRUE;
    }

    for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
    {
        if( !poFeature->IsFieldSet( i ) )
            continue;

        if( bNeedComma )
            osCommand += ", ";
        else
            bNeedComma = TRUE;

        const char *pszStrValue = poFeature->GetFieldAsString(i);

        if( poFeature->IsFieldNull(i) )
        {
            osCommand += "NULL";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger64
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal
                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTBinary )
        {
            // We need to quote and escape string fields.
            osCommand += "'";

            for( int iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )
            {
                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger64List
                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList
                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0
                    && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )
                {
                    CPLDebug( "MYSQL",
                              "Truncated %s field value, it was too long.",
                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );
                    break;
                }

                if( pszStrValue[iChar] == '\\'
                    || pszStrValue[iChar] == '\'' )
                {
                    osCommand += '\\';
                    osCommand += pszStrValue[iChar];
                }
                else
                    osCommand += pszStrValue[iChar];
            }

            osCommand += "'";
        }
        else if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTBinary )
        {
            int binaryCount = 0;
            GByte* binaryData = poFeature->GetFieldAsBinary(i, &binaryCount);
            char* pszHexValue = CPLBinaryToHex( binaryCount, binaryData );

            osCommand += "x'";
            osCommand += pszHexValue;
            osCommand += "'";

            CPLFree( pszHexValue );
        }
        else
        {
            osCommand += pszStrValue;
        }
    }

    osCommand += ")";

    //CPLDebug("MYSQL", "%s", osCommand.c_str());
    int nQueryResult = mysql_query(poDS->GetConn(), osCommand.c_str() );
    const my_ulonglong nFID = mysql_insert_id( poDS->GetConn() );

    if( nQueryResult ){
        int eErrorCode = mysql_errno(poDS->GetConn());
        if (eErrorCode == 1153) {//ER_NET_PACKET_TOO_LARGE)
            poDS->ReportError("CreateFeature failed because the MySQL server " \
                              "cannot read the entire query statement.  Increase " \
                              "the size of statements your server will allow by " \
                              "altering the 'max_allowed_packet' parameter in "\
                              "your MySQL server configuration.");
        }
        else
        {
        CPLDebug("MYSQL","Error number %d", eErrorCode);
            poDS->ReportError(  osCommand.c_str() );
        }

        // make sure to attempt to free results
        MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
        if( hResult != nullptr )
            mysql_free_result( hResult );
        hResult = nullptr;

        return OGRERR_FAILURE;
    }

    if( nFID > 0 ) {
        poFeature->SetFID( nFID );
    }

    // make sure to attempt to free results of successful queries
    MYSQL_RES *hResult = mysql_store_result( poDS->GetConn() );
    if( hResult != nullptr )
        mysql_free_result( hResult );
    hResult = nullptr;

    return OGRERR_NONE;
}