コード例 #1
0
ファイル: rasterrenderer.cpp プロジェクト: jacklibj/r5
wxImage wxGISRasterRGBRenderer::Scale(unsigned char* pData, int nOrigX, int nOrigY, double rOrigX, double rOrigY, int nDestX, int nDestY, double rDeltaX, double rDeltaY, wxGISEnumDrawQuality Quality, ITrackCancel* pTrackCancel)
{
 //   //simple way
 //   wxImage ResultImage(nOrigX, nOrigY, pData);
	//ResultImage = ResultImage.Scale(nDestX, nDestY, nQuality);
 //   return ResultImage;

    wxImage ResultImage(nDestX, nDestY, false);
    unsigned char* pDestData = ResultImage.GetData();
    //multithreaded
    int CPUCount(2); //check cpu count
    std::vector<wxRasterDrawThread*> threadarray;
    int nPartSize = nDestY / CPUCount;
    int nBegY(0), nEndY;
    for(int i = 0; i < CPUCount; i++)
    {        
        if(i == CPUCount - 1)
            nEndY = nDestY;
        else
            nEndY = nPartSize * (i + 1);

        unsigned char* pDestInputData = pDestData  + (nDestX * nBegY * 3);
        wxRasterDrawThread *thread = new wxRasterDrawThread(pData, pDestInputData, nOrigX, nOrigY, rOrigX, rOrigY, nDestX, nDestY, rDeltaX, rDeltaY, Quality, pTrackCancel, nBegY, nEndY);
        thread->Create();
        thread->Run();
        threadarray.push_back(thread);
        nBegY = nEndY/* + 1*/;
    }

    for(size_t i = 0; i < threadarray.size(); i++)
    {
        wgDELETE(threadarray[i], Wait());
    }
    return ResultImage;
}
コード例 #2
0
ファイル: rasterrenderer.cpp プロジェクト: jacklibj/r5
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel)
{
	wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset);
	if(!pRaster)
		return;
	IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation();
	OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference();
	OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference();
	bool IsSpaRefSame(true);
	if(pDisplaySpatialReference && pDisplaySpatialReference)
		IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference);
	OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds();
	OGREnvelope* pRasterExtent = pRaster->GetEnvelope();
	OGREnvelope RasterEnvelope, DisplayEnvelope;

	if(!IsSpaRefSame)
	{
		RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference);
	}
	else
	{
		RasterEnvelope = *pRasterExtent;
	}
	bool IsZoomIn(false);
	//IsZoomIn = RasterEnvelope.Contains(VisibleBounds);
	IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY;
	if(IsZoomIn)
	{
		//intersect bounds
		OGREnvelope DrawBounds;
		DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX);
		DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY);
		DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX);
		DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY);

		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = DrawBounds.MinX;
		OGRRawPoints[0].y = DrawBounds.MinY;
		OGRRawPoints[1].x = DrawBounds.MaxX;
		OGRRawPoints[1].y = DrawBounds.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}

		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		wxDELETEA(pDCPoints);

        if(nWidth <= 20 || nHeight <= 20)
			return;

		GDALDataset* pGDALDataset = pRaster->GetRaster();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
        double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
		CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform);
        bool bNoTransform(false);
        if(err != CE_None)
        {
            bNoTransform = true;
        }
        else
        {
            int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform );
        }

		//2. get image data from raster - draw part of the raster
		if(IsSpaRefSame)
		{
			double rMinX, rMinY, rMaxX, rMaxY;

            int nXSize = pGDALDataset->GetRasterXSize();
            int nYSize = pGDALDataset->GetRasterYSize();

            if(bNoTransform)
            {
                rMinX = DrawBounds.MinX;
                rMaxX = DrawBounds.MaxX;
                rMaxY = nYSize - DrawBounds.MinY;
                rMinY = nYSize - DrawBounds.MaxY;
            }
            else
            {
    			GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY );
	    		GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY );
            }
            //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY;
            //rRealMinX = MIN(rMinX, rMaxX);
            //rRealMinY = MIN(rMinY, rMaxY);
            //rRealMaxX = MAX(rMinX, rMaxX);
            //rRealMaxY = MAX(rMinY, rMaxY);

            double rImgWidth = rMaxX - rMinX;
            double rImgHeight = rMaxY - rMinY;
			int nImgWidth = ceil(rImgWidth) + 1;
			int nImgHeight = ceil(rImgHeight) + 1;
            
			//read in buffer
            int nMinX = floor(rMinX);
            int nMinY = floor(rMinY);
			if(nMinX < 0) nMinX = 0;
			if(nMinY < 0) nMinY = 0;

            if(nImgWidth > nXSize - nMinX) nImgWidth -= 1;
            if(nImgHeight > nYSize - nMinY) nImgHeight -= 1;

		    //create buffer
			int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0  /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/;
			int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0  /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/;
			double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth;
			double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight;


		    unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3];

		    err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL);
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }

		    err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }
		    //scale pTempData to data using interpolation methods
		    pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig);

            wxDELETEA(data);
		}
		else
		{
		//void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 );
		//GDALDestroyGenImgProjTransformer( hTransformArg );
	////		//get new envelope - it may rotate
	////		OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference);
	//////		get real envelope
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY);
	////		OCTDestroyCoordinateTransformation(poCT);
		}
	}
	else
	{
		//1. convert newrasterenvelope to DC		
		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = RasterEnvelope.MinX;
		OGRRawPoints[0].y = RasterEnvelope.MinY;
		OGRRawPoints[1].x = RasterEnvelope.MaxX;
		OGRRawPoints[1].y = RasterEnvelope.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		//2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster
		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}
		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		delete[](pDCPoints);

		GDALDataset* pGDALDataset = pRaster->GetRaster();
		int nImgWidth = pGDALDataset->GetRasterXSize();
		int nImgHeight = pGDALDataset->GetRasterYSize();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		//create buffer
		unsigned char* data = new unsigned char[nWidth * nHeight * 3];
		if(IsSpaRefSame)
		{
			//read in buffer
			CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
			if(err != CE_None)
			{
				wxDELETEA(data);
				return;
			}
		}
		else
		{
			//1. calc Width & Height of TempData with same aspect ratio of raster
			//2. create pTempData buffer
			unsigned char* pTempData;
			//3. fill data
			//4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation
			//delete[](data);
		}
		//3. draw //think about transparancy!
		wxImage ResultImage(nWidth, nHeight, data);
		pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig);

		//delete[](data);
	}
}
コード例 #3
0
/**
* @brief CombineMultiImages  Combine the input images to a single big image.
* @param Images         The input images.
* @param NumberOfRows   The number of the rows to put the input images.
* @param NumberOfCols   The number of the cols to put the input images.
* @param Distance       The distance between each image.
* @param ImageWidth     The width of each image in the big image.
* @param ImageHeight    The height of each image in the big image.
* @return      The big image if the operation is successed;
*              otherwise return empty image.
*
* @author sheng
* @date 2015-03-24
* @version 0.1
*
* @history
*     <author>       <date>         <version>        <description>
*      sheng       2015-03-24          0.1           build the function
*
*/
cv::Mat CombineMultiImages(const std::vector<cv::Mat>& Images,
	const int NumberOfRows,
	const int NumberOfCols,
	const int Distance,
	const int ImageWidth,
	const int ImageHeight)
{
	// return empty mat if the Number of rows or cols is smaller than 1.
	assert((NumberOfRows > 0) && (NumberOfCols > 0));
	if ((NumberOfRows < 1) || (NumberOfCols < 1))
	{
		std::cout << "The number of the rows or the cols is smaller than 1."
			<< std::endl;
		return cv::Mat();
	}


	// return empty mat if the distance, the width or the height of image
	// is smaller than 1.
	assert((Distance > 0) && (ImageWidth > 0) && (ImageHeight > 0));
	if ((Distance < 1) || (ImageWidth < 1) || (ImageHeight < 1))
	{
		std::cout << "The distance, the width or the height of the image is smaller than 1."
			<< std::endl;
		return cv::Mat();
	}


	// Get the number of the input images
	const int NUMBEROFINPUTIMAGES = Images.size();


	// return empty mat if the number of the input images is too big.
	assert(NUMBEROFINPUTIMAGES <= NumberOfRows * NumberOfCols);
	if (NUMBEROFINPUTIMAGES > NumberOfRows * NumberOfCols)
	{
		std::cout << "The number of images is too big." << std::endl;
		return cv::Mat();
	}


	// return empty mat if the number of the input images is too low.
	assert(NUMBEROFINPUTIMAGES > 0);
	if (NUMBEROFINPUTIMAGES < 1)
	{
		std::cout << "The number of images is too low." << std::endl;
		return cv::Mat();
	}


	// create the big image
	const int WIDTH = Distance * (NumberOfCols + 1) + ImageWidth * NumberOfCols;
	const int HEIGHT = Distance * (NumberOfRows + 1) + ImageHeight * NumberOfRows;

	cv::Scalar Color(255, 255, 255);
	if (Images[0].channels() == 1)
	{
		Color = cv::Scalar(255);
	}
	cv::Mat ResultImage(HEIGHT, WIDTH, Images[0].type(), Color);



	// copy the input images to the big image
	for (int Index = 0; Index < NUMBEROFINPUTIMAGES; Index++)
	{

		assert(Images[Index].type() == ResultImage.type());
		if (Images[Index].type() != ResultImage.type())
		{
			std::cout << "The No." << Index << "image has the different type."
				<< std::endl;
			return cv::Mat();
		}


		// Get the row and the col of No.Index image
		int Rows = Index / NumberOfCols;
		int Cols = Index % NumberOfCols;

		// The start point of No.Index image.
		int StartRows = Distance * (Rows + 1) + ImageHeight * Rows;
		int StartCols = Distance * (Cols + 1) + ImageWidth * Cols;

		// copy  No.Index image to the big image
		cv::Mat ROI = ResultImage(cv::Rect(StartCols, StartRows,
			ImageWidth, ImageHeight));
		cv::resize(Images[Index], ROI, cv::Size(ImageWidth, ImageHeight));

	}

	return ResultImage;


}