// This is the main DLL file.
#include "stdafx.h"
#include "GdalImage.h"
#using <System.dll>
#using <System.Drawing.DLL>
#include <gdal_priv.h>
//#using <System.Runtime.InteropServices.dll>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
#include <algorithm>
namespace GdalImage
{
struct IpRGB
{
public:
unsigned char r;
unsigned char g;
unsigned char b;
};
bool GeoImage::Open(String* fname)
{
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(fname);
GDALAllRegister();
m_poDataset = (GDALDataset *) GDALOpen( str2, GA_ReadOnly );
Marshal::FreeHGlobal(str2);
if( m_poDataset == NULL )
{
return false;
}
double adfGeoTransform[6];
if( m_poDataset->GetProjectionRef() != NULL )
{
}
if( m_poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
{
}
m_width = m_poDataset->GetRasterXSize();
m_height = m_poDataset->GetRasterYSize();
m_trans = new System::Drawing::Drawing2D::Matrix((float)adfGeoTransform[1],
(float)adfGeoTransform[2],
(float)adfGeoTransform[4],
(float)adfGeoTransform[5],
(float)adfGeoTransform[0],
(float)adfGeoTransform[3]);
return true;
}
bool GeoImage::Draw(System::Drawing::Graphics* graph,System::Drawing::Drawing2D::Matrix* m)
{
if(m_poDataset == NULL)
return false;
System::Drawing::PointF src_rect_points __gc[] = new System::Drawing::PointF __gc[2];
src_rect_points[0] = System::Drawing::PointF(graph->ClipBounds.X,graph->ClipBounds.Y);
src_rect_points[1] = System::Drawing::PointF(graph->ClipBounds.Right,graph->ClipBounds.Bottom);
// get inverse transformation of geo coordinates to GUI client :
System::Drawing::Drawing2D::Matrix* graph_inv_trans = m->Clone();
graph_inv_trans->Invert();
// get inverse transformation image coordinates to geo coordinates:
System::Drawing::Drawing2D::Matrix* inv_trans = m_trans->Clone();
inv_trans->Invert();
graph_inv_trans->Multiply(inv_trans,
System::Drawing::Drawing2D::MatrixOrder::Append);
System::Drawing::Drawing2D::Matrix* img2client_trans = graph_inv_trans->Clone();
img2client_trans->Invert();
//System::Drawing::RectangleF* src_rect = new System::Drawing::RectangleF();
System::Drawing::RectangleF rect = System::Drawing::RectangleF(graph->ClipBounds.X,graph->ClipBounds.Y,
graph->ClipBounds.Width,graph->ClipBounds.Height);
System::Drawing::PointF points __gc[] = new System::Drawing::PointF __gc[2];
points[0] = System::Drawing::PointF(rect.Left,rect.Top);
points[1] = System::Drawing::PointF(rect.Right,rect.Bottom);
graph_inv_trans->TransformPoints(points);
double r_x1 = points[0].X;
double r_y1 = points[0].Y;
double r_x2 = points[1].X;
double r_y2 = points[1].Y;
if(r_x1>r_x2)
std::swap(r_x1,r_x2);
bool up_north = false;
if(r_y1>r_y2)
{
up_north = true;
std::swap(r_y1,r_y2);
}
if(r_x1<0)
r_x1 = 0;
if(r_x2 - r_x1 > m_width)
r_x2 = r_x1 + m_width;
if(r_y1 < 0)
r_y1 = 0;
if(r_y2 - r_y1 > m_height)
r_y2 = r_y1 + m_height;
if(r_y2 - r_y1 < 2 || r_x2-r_x1 < 2)
return false;
System::Drawing::PointF client_points __gc[] = new System::Drawing::PointF __gc[2];
client_points[0] = System::Drawing::PointF(r_x1,r_y1);
client_points[1] = System::Drawing::PointF(r_x2,r_y2);
img2client_trans->TransformPoints(client_points);
int draw_x_size = (int)Math::Abs(client_points[1].X-client_points[0].X);
int draw_y_size = (int)Math::Abs(client_points[1].Y-client_points[0].Y);
if( draw_x_size < 4 || draw_y_size < 4 )
return false;
System::Drawing::Bitmap* bmp = new System::Drawing::Bitmap(draw_x_size,draw_y_size);
GDALRasterBand* poBands[3];
for(int i=0; i<3; i++) {
GDALRasterBand *poBand;
int nBlockXSize, nBlockYSize;
int bGotMin, bGotMax;
double adfMinMax[2];
poBand = m_poDataset->GetRasterBand( i+1 );
poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
adfMinMax[0] = poBand->GetMinimum( &bGotMin );
adfMinMax[1] = poBand->GetMaximum( &bGotMax );
if( ! (bGotMin && bGotMax) )
GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
poBands[i] = poBand;
}
float *pafScanline;
int nXSize = poBands[0]->GetXSize();
int x_size = poBands[0]->GetXSize();
int y_size = poBands[0]->GetYSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*draw_x_size*draw_y_size);
std::fill(pafScanline,pafScanline+draw_x_size*draw_y_size,100);
IpRGB* img_buff_rgb = new IpRGB [draw_x_size*draw_y_size];
for(int ch=0; ch<3; ch++)
{
unsigned char* ch_buff = (unsigned char*)img_buff_rgb + ch;
poBands[ch]->RasterIO( GF_Read,r_x1, r_y1,
r_x2-r_x1, r_y2-r_y1,
pafScanline,
draw_x_size,
draw_y_size,
GDT_Float32,
0, 0);
for(int p=0; p<draw_x_size*draw_y_size; p++, ch_buff+=3)
*ch_buff = (unsigned char)(pafScanline[p]);
}
int p_indx = 0;
if(up_north)
{
for(int y=draw_y_size-1; y>=0; y--)
for(int x=0; x<draw_x_size; x++,p_indx++)
{
System::Drawing::Color col = System::Drawing::Color::FromArgb(img_buff_rgb[p_indx].r,img_buff_rgb[p_indx].g,img_buff_rgb[p_indx].b);
bmp->SetPixel(x,y,col);
}
}
else
{
for(int y=0; y<draw_y_size; y++)
for(int x=0; x<draw_x_size; x++,p_indx++)
{
System::Drawing::Color col = System::Drawing::Color::FromArgb(img_buff_rgb[p_indx].r,img_buff_rgb[p_indx].g,img_buff_rgb[p_indx].b);
bmp->SetPixel(x,y,col);
}
}
graph->DrawImageUnscaled(bmp,(int)client_points[0].X,(int)client_points[0].Y,
draw_x_size,draw_y_size);
delete [] img_buff_rgb;
bmp->Dispose();
CPLFree(pafScanline);
return true;
}
}