Exemplo n.º 1
0
void wxGISDisplay::InitTransformMatrix(void)
{
	m_dFrameCenterX = m_oDeviceFrameRect.GetWidth() / 2;
	m_dFrameCenterY = m_oDeviceFrameRect.GetHeight() / 2;
	double dWorldCenterX = (m_CurrentBounds.MaxX - m_CurrentBounds.MinX) / 2;
	double dWorldCenterY = (m_CurrentBounds.MaxY - m_CurrentBounds.MinY) / 2;

	//origin (UL corner)
	m_dOrigin_X = m_dCacheCenterX - m_dFrameCenterX;
	m_dOrigin_Y = m_dCacheCenterY - m_dFrameCenterY;
	//get scale
	double dScaleX = fabs(m_dFrameCenterX / dWorldCenterX);
	double dScaleY = fabs(m_dFrameCenterY / dWorldCenterY);
    m_dScale = wxMin(dScaleX, dScaleY);

	double dWorldDeltaX = dWorldCenterX + m_CurrentBounds.MinX;
	double dWorldDeltaY = dWorldCenterY + m_CurrentBounds.MinY;

	double dWorldDeltaXSt = m_dScale * dWorldDeltaX;// + m_dAngleRad * dWorldDeltaY;
	double dWorldDeltaYSt = m_dScale * dWorldDeltaY;//m_dAngleRad * dWorldDeltaX +

	//double dCenterX = m_dCacheCenterX - dWorldDeltaXSt;//(dWorldCenterX + m_CurrentBounds.MinX) * dScale;//
	//double dCenterY = m_dCacheCenterY + dWorldDeltaYSt;//(dWorldCenterY + m_CurrentBounds.MinY) * dScale;//
	m_dFrameXShift = m_dFrameCenterX - dWorldDeltaXSt;//(dWorldCenterX + m_CurrentBounds.MinX) * dScale;//
	m_dFrameYShift = m_dFrameCenterY + dWorldDeltaYSt;//(dWorldCenterY + m_CurrentBounds.MinY) * dScale;//

//	cairo_matrix_init (m_pMatrix, 1, 0, 0, 1, m_dCacheCenterX, m_dCacheCenterY);
	//cairo_matrix_init (m_pMatrix, dScale, 0.0, 0.0, -dScale, dCenterX, dCenterY);
	cairo_matrix_init_translate (m_pMatrix, m_dCacheCenterX, m_dCacheCenterY);
	//rotate
	//cairo_matrix_rotate(m_pMatrix, 45.0 * M_PI / 180.0);
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	//{
		//cairo_matrix_translate(m_pMatrix, dWorldDeltaXSt, dWorldDeltaYSt);
		cairo_matrix_rotate(m_pMatrix, m_dAngleRad);
		//cairo_matrix_translate(m_pMatrix, -dWorldDeltaXSt, dWorldDeltaYSt);
	//}
	//else
	cairo_matrix_translate(m_pMatrix, -dWorldDeltaXSt, dWorldDeltaYSt);

	cairo_matrix_scale(m_pMatrix, m_dScale, -m_dScale);

	//init matrix for Wld2DC & DC2Wld
	cairo_matrix_init_translate (m_pDisplayMatrix, m_dFrameCenterX, m_dFrameCenterY);
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
		cairo_matrix_rotate(m_pDisplayMatrix, m_dAngleRad);
	cairo_matrix_translate(m_pDisplayMatrix, -dWorldDeltaXSt, dWorldDeltaYSt);
	cairo_matrix_scale(m_pDisplayMatrix, m_dScale, -m_dScale);

	//init matrix for TransformRect
	cairo_matrix_init_translate (m_pDisplayMatrixNoRotate, m_dFrameCenterX, m_dFrameCenterY);
	cairo_matrix_translate(m_pDisplayMatrixNoRotate, -dWorldDeltaXSt, dWorldDeltaYSt);
	cairo_matrix_scale(m_pDisplayMatrixNoRotate, m_dScale, -m_dScale);

	//set matrix to all caches
	for(size_t i = 0; i < m_saLayerCaches.size(); ++i)
		cairo_set_matrix (m_saLayerCaches[i].pCairoContext, m_pMatrix);
}
Exemplo n.º 2
0
void wxGISDisplay::SetDeviceFrame(wxRect &rc)
{
	m_oDeviceFrameRect = rc;
	if(m_oDeviceFrameRect.GetWidth() % 2 != 0)
		m_oDeviceFrameRect.SetWidth(m_oDeviceFrameRect.GetWidth() + 1);
	if(m_oDeviceFrameRect.GetHeight() % 2 != 0)
		m_oDeviceFrameRect.SetHeight(m_oDeviceFrameRect.GetHeight() + 1);

	m_dFrameRatio = double(m_oDeviceFrameRect.GetWidth()) / m_oDeviceFrameRect.GetHeight();

	m_CurrentBounds = m_RealBounds;

	SetEnvelopeRatio(m_CurrentBounds, m_dFrameRatio);
	m_dRotatedBoundsCenterX = m_CurrentBounds.MinX + (m_CurrentBounds.MaxX - m_CurrentBounds.MinX) / 2;
	m_dRotatedBoundsCenterY = m_CurrentBounds.MinY + (m_CurrentBounds.MaxY - m_CurrentBounds.MinY) / 2;
	m_CurrentBoundsRotated = m_CurrentBounds;
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	{
		RotateEnvelope(m_CurrentBoundsRotated, m_dAngleRad, m_dRotatedBoundsCenterX, m_dRotatedBoundsCenterY);
		SetEnvelopeRatio(m_CurrentBoundsRotated, m_dFrameRatio);//test
	}
	m_CurrentBoundsX8 = m_CurrentBoundsRotated;
	IncreaseEnvelope(m_CurrentBoundsX8, 8);

    cairo_destroy (m_cr_tmp);
    cairo_surface_destroy (m_surface_tmp);

	m_surface_tmp = cairo_image_surface_create (CAIRO_FORMAT_RGB24, m_oDeviceFrameRect.GetWidth(), m_oDeviceFrameRect.GetHeight());
	m_cr_tmp = cairo_create (m_surface_tmp);


	//compute current transform matrix
	InitTransformMatrix();
}
Exemplo n.º 3
0
bool wxGISDisplay::CanDraw(OGREnvelope &Env)
{
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	{
		RotateEnvelope(Env, -m_dAngleRad, m_dRotatedBoundsCenterX, m_dRotatedBoundsCenterY);
	}

	return Env.Contains(m_CurrentBoundsRotated) || m_CurrentBoundsRotated.Contains(Env) || Env.Intersects(m_CurrentBoundsRotated);
}
Exemplo n.º 4
0
void wxGISDisplay::WheelingDraw(double dZoom, wxDC* pDC)
{
	wxCriticalSectionLocker locker(m_CritSect);

	if(IsDoubleEquil(dZoom, 1)) // no zoom
	{
		cairo_set_source_surface (m_cr_tmp, m_saLayerCaches[m_nCurrentLayer].pCairoSurface, -m_dOrigin_X, -m_dOrigin_Y);
		cairo_set_operator (m_cr_tmp, CAIRO_OPERATOR_SOURCE);

        cairo_paint (m_cr_tmp);

	}
	else if(dZoom > 1) // zoom in
	{
		double dDCXDelta = m_dFrameCenterX / dZoom;
		double dDCYDelta = m_dFrameCenterY / dZoom;
		double dOrigin_X = m_dCacheCenterX - dDCXDelta;
		double dOrigin_Y = m_dCacheCenterY - dDCYDelta;

        cairo_scale(m_cr_tmp, dZoom, dZoom);

        cairo_set_source_rgb(m_cr_tmp, m_BackGroudnColour.GetRed(), m_BackGroudnColour.GetGreen(), m_BackGroudnColour.GetBlue());
	    cairo_paint(m_cr_tmp);

		cairo_set_source_surface (m_cr_tmp, m_saLayerCaches[m_nLastCacheID].pCairoSurface, -dOrigin_X, -dOrigin_Y);

        cairo_paint (m_cr_tmp);
	}
	else //zoom out
	{
		double dDCXDelta = m_dFrameCenterX * dZoom;
		double dDCYDelta = m_dFrameCenterY * dZoom;
		double dOrigin_X = m_dFrameCenterX - dDCXDelta;
		double dOrigin_Y = m_dFrameCenterY - dDCYDelta;

        cairo_set_source_rgb(m_cr_tmp, m_BackGroudnColour.GetRed(), m_BackGroudnColour.GetGreen(), m_BackGroudnColour.GetBlue());
	    cairo_paint(m_cr_tmp);

        cairo_translate (m_cr_tmp, dOrigin_X, dOrigin_Y);
		cairo_scale(m_cr_tmp, dZoom, dZoom);

		cairo_set_source_surface (m_cr_tmp, m_saLayerCaches[m_nLastCacheID].pCairoSurface, -m_dOrigin_X, -m_dOrigin_Y);

        cairo_paint (m_cr_tmp);
	}

    Output(m_surface_tmp, pDC);

    cairo_matrix_t mat = {1, 0, 0, 1, 0, 0};
	cairo_set_matrix (m_cr_tmp, &mat);
}
Exemplo n.º 5
0
OGREnvelope wxGISMapView::GetFullExtent(void)
{
	OGREnvelope OutputEnv;
	if(!IsDoubleEquil(m_dCurrentAngle, 0.0))
	{
		OutputEnv = m_FullExtent;
		double dCenterX = m_FullExtent.MinX + (m_FullExtent.MaxX - m_FullExtent.MinX) / 2;
		double dCenterY = m_FullExtent.MinY + (m_FullExtent.MaxY - m_FullExtent.MinY) / 2;
		RotateEnvelope(OutputEnv, m_dCurrentAngle, dCenterX, dCenterY);
		IncreaseEnvelope(OutputEnv, 0.1);
	}
	else
		OutputEnv = wxGISMap::GetFullExtent();
	return OutputEnv;
}
Exemplo n.º 6
0
bool wxGISDisplay::CheckDrawAsPoint(const OGREnvelope &Envelope, double dfLineWidth, bool bIsRing, double dOffsetX, double dOffsetY, bool bCheckEnvelope)
{
	OGREnvelope TestEnv;
	TestEnv = Envelope;
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	{
		RotateEnvelope(TestEnv, -m_dAngleRad, m_dRotatedBoundsCenterX, m_dRotatedBoundsCenterY);
	}

	if(bCheckEnvelope && !m_CurrentBoundsRotated.Intersects(TestEnv))
		return true;

	double EnvWidth = Envelope.MaxX - Envelope.MinX;
	double EnvHeight = Envelope.MaxY - Envelope.MinY;

	World2DCDist(&EnvWidth, &EnvHeight);
	double dfR = (fabs(EnvWidth) + fabs(EnvHeight)) * .5;
    if (dfR <= MINPOLYDRAWAREA)
	{
	    if(bIsRing)
        {
            SetLineWidth( dfLineWidth + dfLineWidth );
        }
        else
        {
            SetLineWidth( dfLineWidth );
        }

        if (dfR >= MINPOLYAREA)
		{
            wxCriticalSectionLocker locker(m_CritSect);
			cairo_move_to(m_saLayerCaches[m_nCurrentLayer].pCairoContext, Envelope.MinX + dOffsetX, Envelope.MinY + dOffsetY);
			cairo_line_to(m_saLayerCaches[m_nCurrentLayer].pCairoContext, Envelope.MaxX + dOffsetX, Envelope.MaxY + dOffsetY);
		}
        else
        {
			DrawPointFast(Envelope.MinX, Envelope.MinY, dOffsetX, dOffsetY);
        }



        SetLineCap(CAIRO_LINE_CAP_ROUND);
		return true;
	}
	return false;
}
Exemplo n.º 7
0
void wxGISDisplay::SetRotate(double dAngleRad)
{
	m_dAngleRad = dAngleRad;
    //for rotate panning & zooming
	m_CurrentBoundsRotated = m_CurrentBounds;
	m_dRotatedBoundsCenterX = m_CurrentBoundsRotated.MinX + (m_CurrentBoundsRotated.MaxX - m_CurrentBoundsRotated.MinX) / 2;
	m_dRotatedBoundsCenterY = m_CurrentBoundsRotated.MinY + (m_CurrentBoundsRotated.MaxY - m_CurrentBoundsRotated.MinY) / 2;
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	{
		RotateEnvelope(m_CurrentBoundsRotated, m_dAngleRad, m_dRotatedBoundsCenterX, m_dRotatedBoundsCenterY);
		SetEnvelopeRatio(m_CurrentBoundsRotated, m_dFrameRatio);//test
	}
	m_CurrentBoundsX8 = m_CurrentBoundsRotated;
	IncreaseEnvelope(m_CurrentBoundsX8, 8);

	//compute current transform matrix
	InitTransformMatrix();

	SetAllCachesDerty(true);
}
Exemplo n.º 8
0
void wxGISDisplay::SetBounds(const OGREnvelope& Bounds)
{
	//update bounds to frame ratio
	m_RealBounds = Bounds;
	m_CurrentBounds = m_RealBounds;

	SetEnvelopeRatio(m_CurrentBounds, m_dFrameRatio);
	m_dRotatedBoundsCenterX = m_CurrentBounds.MinX + (m_CurrentBounds.MaxX - m_CurrentBounds.MinX) / 2;
	m_dRotatedBoundsCenterY = m_CurrentBounds.MinY + (m_CurrentBounds.MaxY - m_CurrentBounds.MinY) / 2;
	m_CurrentBoundsRotated = m_CurrentBounds;
	if(!IsDoubleEquil(m_dAngleRad, 0.0))
	{
		RotateEnvelope(m_CurrentBoundsRotated, m_dAngleRad, m_dRotatedBoundsCenterX, m_dRotatedBoundsCenterY);
		SetEnvelopeRatio(m_CurrentBoundsRotated, m_dFrameRatio);//test
	}
	m_CurrentBoundsX8 = m_CurrentBoundsRotated;
	IncreaseEnvelope(m_CurrentBoundsX8, 8);

	SetAllCachesDerty(true);
	//compute current transform matrix
	InitTransformMatrix();
}
Exemplo n.º 9
0
bool wxGISDrawingLayer::Draw(wxGISEnumDrawPhase DrawPhase, ITrackCancel* const pTrackCancel)
{
    wxCHECK_MSG(m_pDisplay, false, wxT("Display pointer is NULL"));

    wxCriticalSectionLocker lock(m_CritSect);

    OGREnvelope stDisplayExtentRotated = m_pDisplay->GetBounds(true);
    OGREnvelope stFeatureDatasetExtentRotated = m_oLayerExtent;

    //rotate featureclass extent
    if (!IsDoubleEquil(m_pDisplay->GetRotate(), 0.0))
    {
        wxRealPoint dfCenter = m_pDisplay->GetBoundsCenter();
        RotateEnvelope(stFeatureDatasetExtentRotated, m_pDisplay->GetRotate(), dfCenter.x, dfCenter.y);//dCenterX, dCenterY);
    }

    //if envelopes don't intersect exit
    if (!stDisplayExtentRotated.Intersects(stFeatureDatasetExtentRotated))
        return false;

    //get intersect envelope to fill vector data
    OGREnvelope stDrawBounds = stDisplayExtentRotated;
    stDrawBounds.Intersect(stFeatureDatasetExtentRotated);
    if (!stDrawBounds.IsInit())
        return false;

    IProgressor* pProgress = NULL;
    if (NULL != pTrackCancel)
    {
        pProgress = pTrackCancel->GetProgressor();
    }

    if (NULL != pProgress)
    {
        pProgress->SetRange(m_aoShapes.size());
    }

    //draw shapes
    for (size_t i = 0; i < m_aoShapes.size(); ++i)
    {
        if (NULL != pProgress)
        {
            pProgress->SetValue(i);
        }

        if (pTrackCancel != NULL && !pTrackCancel->Continue())
            return true;
        if (m_aoShapes[i] != NULL)
        {
            m_aoShapes[i]->Draw(m_pDisplay);
        }
    }

    //draw enumGISShapeStateSelected

    //draw enumGISShapeStateRotated

    //draw enumGISShapeStatePoints

    return true;
}
Exemplo n.º 10
0
bool CreateSubRaster( wxGISRasterDatasetSPtr pSrcRasterDataSet, OGREnvelope &Env, const OGRGeometry *pGeom, GDALDriver* pDriver, CPLString &szDstPath, GDALDataType eOutputType, int nBandCount, int *panBandList, double dfOutResX, double dfOutResY, bool bCopyNodata, bool bSkipSourceMetadata, char** papszOptions, ITrackCancel* pTrackCancel )
{
	GDALDataset* pDset = pSrcRasterDataSet->GetRaster();
	if(!pDset)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}

    double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
	CPLErr err = pDset->GetGeoTransform(adfGeoTransform);
	if(err == CE_Fatal)
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr);
		return false;
	}
	if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
	{
		if(pTrackCancel)
			pTrackCancel->PutMessage(_("The geotransform is rotated. This configuration is not supported."), -1, enumGISMessageErr);
		return false;
    }
	int anSrcWin[4] = {0, 0, 0, 0};

    anSrcWin[0] = floor ((Env.MinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
    anSrcWin[1] = floor ((Env.MaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);
	anSrcWin[2] = ceil ((Env.MaxX - Env.MinX) / adfGeoTransform[1]);
	anSrcWin[3] = ceil ((Env.MinY - Env.MaxY) / adfGeoTransform[5]);
	if(pTrackCancel)
		pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window %d %d %d %d from geographic window."), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3] ), -1, enumGISMessageInfo);

	if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > pSrcRasterDataSet->GetWidth() || anSrcWin[1] + anSrcWin[3] > pSrcRasterDataSet->GetHeight() )
    {
		if(pTrackCancel)
			pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window falls outside raster size of %dx%d."), pSrcRasterDataSet->GetWidth(), pSrcRasterDataSet->GetHeight()), -1, enumGISMessageErr);
		return false;
    }

	int nOXSize = 0, nOYSize = 0;

    if(IsDoubleEquil(dfOutResX, -1) && IsDoubleEquil(dfOutResY, -1))
    {
        nOXSize = anSrcWin[2];
        nOYSize = anSrcWin[3];
    }
    else
    {
        nOXSize = ceil ((Env.MaxX - Env.MinX) / dfOutResX);
        nOYSize = ceil ((Env.MinY - Env.MaxY) / (adfGeoTransform[5] < 0 ? dfOutResY * -1 : dfOutResY));
    }

/* ==================================================================== */
/*      Create a virtual dataset.                                       */
/* ==================================================================== */
    VRTDataset *poVDS;
/* -------------------------------------------------------------------- */
/*      Make a virtual clone.                                           */
/* -------------------------------------------------------------------- */
    poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize );

    if( pSrcRasterDataSet->GetSpatialReference() != NULL )
    {
		poVDS->SetProjection( pDset->GetProjectionRef() );
    }

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

    adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
    adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
    adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;

    poVDS->SetGeoTransform( adfGeoTransform );

    int nGCPs = pDset->GetGCPCount();
    if( nGCPs > 0 )
    {
        GDAL_GCP *pasGCPs = GDALDuplicateGCPs( nGCPs, pDset->GetGCPs() );

        for(size_t i = 0; i < nGCPs; ++i )
        {
            pasGCPs[i].dfGCPPixel -= anSrcWin[0];
            pasGCPs[i].dfGCPLine  -= anSrcWin[1];
            pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] );
            pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3] );
        }

        poVDS->SetGCPs( nGCPs, pasGCPs, pDset->GetGCPProjection() );
        GDALDeinitGCPs( nGCPs, pasGCPs );
        CPLFree( pasGCPs );
    }

/* -------------------------------------------------------------------- */
/*      Transfer generally applicable metadata.                         */
/* -------------------------------------------------------------------- */
    if(!bSkipSourceMetadata)
        poVDS->SetMetadata( pDset->GetMetadata() );

/* ==================================================================== */
/*      Process all bands.                                              */
/* ==================================================================== */
    for(size_t i = 0; i < nBandCount; ++i )
    {
        VRTSourcedRasterBand *poVRTBand;
        GDALRasterBand *poSrcBand;
        GDALDataType eBandType;
        int nComponent = 0;

        poSrcBand = pDset->GetRasterBand(panBandList[i]);

/* -------------------------------------------------------------------- */
/*      Select output data type to match source.                        */
/* -------------------------------------------------------------------- */
        if( eOutputType == GDT_Unknown )
            eBandType = poSrcBand->GetRasterDataType();
        else
            eBandType = eOutputType;
/* -------------------------------------------------------------------- */
/*      Create this band.                                               */
/* -------------------------------------------------------------------- */
        poVDS->AddBand( eBandType, NULL );
        poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i + 1 );
/* -------------------------------------------------------------------- */
/*      Create a simple data source depending on the                    */
/*      translation type required.                                      */
/* -------------------------------------------------------------------- */
        //if( bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand) )
        //{
        //    poVRTBand->AddComplexSource( poSrcBand,
        //                                 anSrcWin[0], anSrcWin[1],
        //                                 anSrcWin[2], anSrcWin[3],
        //                                 0, 0, nOXSize, nOYSize,
        //                                 dfOffset, dfScale,
        //                                 VRT_NODATA_UNSET,
        //                                 nComponent );
        //}
        //else
        CPLString pszResampling = CSLFetchNameValueDef(papszOptions, "DEST_RESAMPLING", "near");
        poVRTBand->AddSimpleSource( poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, pszResampling );

/* -------------------------------------------------------------------- */
/*      copy some other information of interest.                        */
/* -------------------------------------------------------------------- */
		CopyBandInfo( poSrcBand, poVRTBand, bCopyNodata );
/* -------------------------------------------------------------------- */
/*      Set a forcable nodata value?                                    */
/* -------------------------------------------------------------------- */
//        if( bSetNoData )
//        {
//            double dfVal = dfNoDataReal;
//            int bClamped = FALSE, bRounded = FALSE;
//
//#define CLAMP(val,type,minval,maxval) \
//    do { if (val < minval) { bClamped = TRUE; val = minval; } \
//    else if (val > maxval) { bClamped = TRUE; val = maxval; } \
//    else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \
//    while(0)
//
//            switch(eBandType)
//            {
//                case GDT_Byte:
//                    CLAMP(dfVal, GByte, 0.0, 255.0);
//                    break;
//                case GDT_Int16:
//                    CLAMP(dfVal, GInt16, -32768.0, 32767.0);
//                    break;
//                case GDT_UInt16:
//                    CLAMP(dfVal, GUInt16, 0.0, 65535.0);
//                    break;
//                case GDT_Int32:
//                    CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0);
//                    break;
//                case GDT_UInt32:
//                    CLAMP(dfVal, GUInt32, 0.0, 4294967295.0);
//                    break;
//                default:
//                    break;
//            }
//
//            if (bClamped)
//            {
//                printf( "for band %d, nodata value has been clamped "
//                       "to %.0f, the original value being out of range.\n",
//                       i + 1, dfVal);
//            }
//            else if(bRounded)
//            {
//                printf("for band %d, nodata value has been rounded "
//                       "to %.0f, %s being an integer datatype.\n",
//                       i + 1, dfVal,
//                       GDALGetDataTypeName(eBandType));
//            }
//
//            poVRTBand->SetNoDataValue( dfVal );
//        }

        //if (eMaskMode == MASK_AUTO &&
        //    (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 &&
        //    (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0)
        //{
        //    if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None)
        //    {
        //        VRTSourcedRasterBand* hMaskVRTBand =
        //            (VRTSourcedRasterBand*)poVRTBand->GetMaskBand();
        //        hMaskVRTBand->AddMaskBandSource(poSrcBand,
        //                                anSrcWin[0], anSrcWin[1],
        //                                anSrcWin[2], anSrcWin[3],
        //                                0, 0, nOXSize, nOYSize );
        //    }
        //}
    }

    //if (eMaskMode == MASK_USER)
    //{
    //    GDALRasterBand *poSrcBand =
    //        (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand));
    //    if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        if (nMaskBand > 0)
    //            hMaskVRTBand->AddSimpleSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //        else
    //            hMaskVRTBand->AddMaskBandSource(poSrcBand,
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}
    //else
    //if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 &&
    //    GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET)
    //{
    //    if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None)
    //    {
    //        VRTSourcedRasterBand* hMaskVRTBand = (VRTSourcedRasterBand*)
    //            GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1));
    //        hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1),
    //                                    anSrcWin[0], anSrcWin[1],
    //                                    anSrcWin[2], anSrcWin[3],
    //                                    0, 0, nOXSize, nOYSize );
    //    }
    //}

/* -------------------------------------------------------------------- */
/*      Write to the output file using CopyCreate().                    */
/* -------------------------------------------------------------------- */
    GDALDataset* pOutDS = pDriver->CreateCopy(szDstPath, poVDS, false, papszOptions, GDALDummyProgress, NULL);

    //hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL );
    if( pOutDS )
    {
        CPLErrorReset();
        GDALFlushCache( pOutDS );
        if (CPLGetLastErrorType() != CE_None)
        {
		    if(pTrackCancel)
			    pTrackCancel->PutMessage(_("GDALFlushCache failed!"), -1, enumGISMessageErr);
        }
        GDALClose( pOutDS );

        GDALClose( poVDS );
        return true;
    }
    else
    {
        GDALClose( poVDS );
        return false;
    }


    //CPLFree( panBandList );
    //
    //CPLFree( pszOutputSRS );

    //if( !bSubCall )
    //{
    //    GDALDumpOpenDatasets( stderr );
    //    GDALDestroyDriverManager();
    //}
    //CSLDestroy( papszCreateOptions );

	return true;
}