1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // User Interface //
9 // //
10 // Program: SAGA //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // WKSP_Map_DC.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. SAGA is free software; you //
22 // can redistribute it and/or modify it under the terms //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the //
25 // License, or (at your option) any later version. //
26 // //
27 // SAGA is distributed in the hope that it will be //
28 // useful, but WITHOUT ANY WARRANTY; without even the //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
30 // PARTICULAR PURPOSE. See the GNU General Public //
31 // License for more details. //
32 // //
33 // You should have received a copy of the GNU General //
34 // Public License along with this program; if not, see //
35 // <http://www.gnu.org/licenses/>. //
36 // //
37 //-------------------------------------------------------//
38 // //
39 // contact: Olaf Conrad //
40 // Institute of Geography //
41 // University of Goettingen //
42 // Goldschmidtstr. 5 //
43 // 37077 Goettingen //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
48 ///////////////////////////////////////////////////////////
49
50 //---------------------------------------------------------
51 #include <wx/window.h>
52
53 #include "helper.h"
54
55 #include "wksp_map_dc.h"
56
57
58 ///////////////////////////////////////////////////////////
59 // //
60 // //
61 // //
62 ///////////////////////////////////////////////////////////
63
64 //---------------------------------------------------------
CWKSP_Map_DC(const CSG_Rect & rWorld,const wxRect & rDC,double Scale,int Background)65 CWKSP_Map_DC::CWKSP_Map_DC(const CSG_Rect &rWorld, const wxRect &rDC, double Scale, int Background)
66 {
67 m_rWorld = rWorld;
68 m_rDC = rDC;
69 m_Scale = Scale;
70
71 m_img_rgb = NULL;
72 m_img_dc_rgb = NULL;
73
74 m_Background[0] = Background >= 0 ? SG_GET_R(Background) : 254;
75 m_Background[1] = Background >= 0 ? SG_GET_G(Background) : 255;
76 m_Background[2] = Background >= 0 ? SG_GET_B(Background) : 255;
77
78 //-----------------------------------------------------
79 if( m_rWorld.Get_XRange() == 0. || m_rWorld.Get_YRange() == 0. )
80 {
81 m_rWorld.Inflate(m_rWorld.Get_XRange() ? 0. : 1., m_rWorld.Get_YRange() ? 0. : 1., false);
82 }
83
84 //-----------------------------------------------------
85 // ensure cellsize in x-/y-direction are identical...
86 double dxdyDC = (double)m_rDC.GetWidth() / (double)m_rDC.GetHeight();
87 double dxdyWorld = m_rWorld.Get_XRange() / m_rWorld.Get_YRange();
88
89 if( dxdyDC > dxdyWorld )
90 {
91 m_rWorld.Inflate(0.5 * (m_rWorld.Get_YRange() * dxdyDC - m_rWorld.Get_XRange()), 0., false);
92 }
93 else if( dxdyDC < dxdyWorld )
94 {
95 m_rWorld.Inflate(0., 0.5 * (m_rWorld.Get_XRange() / dxdyDC - m_rWorld.Get_YRange()), false);
96 }
97
98 //-----------------------------------------------------
99 m_World2DC = (double)m_rDC.GetWidth() / m_rWorld.Get_XRange();
100 m_DC2World = 1. / m_World2DC;
101
102 //-----------------------------------------------------
103 dc_BMP.Create(m_rDC.GetWidth(), m_rDC.GetHeight());
104 dc.SelectObject(dc_BMP);
105 dc.SetBackground(wxBrush(wxColour(m_Background[0], m_Background[1], m_Background[2]), wxBRUSHSTYLE_SOLID));
106 dc.Clear();
107 }
108
109 //---------------------------------------------------------
~CWKSP_Map_DC(void)110 CWKSP_Map_DC::~CWKSP_Map_DC(void)
111 {}
112
113
114 ///////////////////////////////////////////////////////////
115 // //
116 ///////////////////////////////////////////////////////////
117
118 //---------------------------------------------------------
Draw(wxDC & dc_Target)119 void CWKSP_Map_DC::Draw(wxDC &dc_Target)
120 {
121 dc.SelectObject(wxNullBitmap);
122
123 dc_Target.DrawBitmap(dc_BMP, m_rDC.GetLeft(), m_rDC.GetTop(), false);
124 }
125
126
127 ///////////////////////////////////////////////////////////
128 // //
129 ///////////////////////////////////////////////////////////
130
131 //---------------------------------------------------------
Draw_DC(CWKSP_Map_DC & dc_Source,double Transparency)132 void CWKSP_Map_DC::Draw_DC(CWKSP_Map_DC &dc_Source, double Transparency)
133 {
134 if( IMG_Draw_Begin(Transparency) )
135 {
136 wxImage src_img = dc_Source.dc_BMP.ConvertToImage(); if( !src_img.GetData() ) { return; }
137
138 #pragma omp parallel for
139 for(int y=0; y<m_rDC.GetHeight(); y++)
140 {
141 int i = y * 3 * m_rDC.GetWidth(); BYTE *src_rgb = src_img.GetData() + i;
142
143 for(int x=0; x<m_rDC.GetWidth(); x++, i+=3, src_rgb+=3)
144 {
145 if( src_rgb[0] != dc_Source.m_Background[0]
146 || src_rgb[1] != dc_Source.m_Background[1]
147 || src_rgb[2] != dc_Source.m_Background[2] )
148 {
149 IMG_Set_Pixel_Direct(i, *((int *)src_rgb));
150 }
151 }
152 }
153
154 IMG_Draw_End();
155 }
156 }
157 //{
158 // wxImage dst_img = dc_BMP.ConvertToImage();
159 // wxImage src_img = dc_Source.dc_BMP.ConvertToImage();
160 //
161 // //-----------------------------------------------------
162 // #pragma omp parallel for
163 // for(int y=0; y<m_rDC.GetHeight(); y++)
164 // {
165 // BYTE *src_rgb = src_img.GetData() + y * 3 * m_rDC.GetWidth();
166 // BYTE *dst_rgb = dst_img.GetData() + y * 3 * m_rDC.GetWidth();
167 //
168 // for(int x=0; x<m_rDC.GetWidth(); x++, src_rgb+=3, dst_rgb+=3)
169 // {
170 // if( src_rgb[0] != dc_Source.m_Background[0]
171 // || src_rgb[1] != dc_Source.m_Background[1]
172 // || src_rgb[2] != dc_Source.m_Background[2] )
173 // {
174 // dst_rgb[0] = (int)((1. - Transparency) * src_rgb[0] + Transparency * dst_rgb[0]);
175 // dst_rgb[1] = (int)((1. - Transparency) * src_rgb[1] + Transparency * dst_rgb[1]);
176 // dst_rgb[2] = (int)((1. - Transparency) * src_rgb[2] + Transparency * dst_rgb[2]);
177 // }
178 // }
179 // }
180 //
181 // //-----------------------------------------------------
182 // dc.DrawBitmap(wxBitmap(dst_img), 0, 0, true);
183 //}
184
185
186 ///////////////////////////////////////////////////////////
187 // //
188 ///////////////////////////////////////////////////////////
189
190 //---------------------------------------------------------
Set_Font(wxFont & Font)191 void CWKSP_Map_DC::Set_Font(wxFont &Font)
192 {
193 if( Font.Ok() )
194 {
195 Font.SetPointSize((int)(m_Scale * Font.GetPointSize()));
196
197 dc.SetFont(Font);
198 }
199 }
200
201
202 ///////////////////////////////////////////////////////////
203 // //
204 ///////////////////////////////////////////////////////////
205
206 //---------------------------------------------------------
IMG_Draw_Begin(double Transparency,int Mode)207 bool CWKSP_Map_DC::IMG_Draw_Begin(double Transparency, int Mode)
208 {
209 if( m_DC2World <= 0. || m_rDC.GetWidth() <= 0 || m_rDC.GetHeight() <= 0 )
210 {
211 return( false );
212 }
213
214 m_Opacity = Transparency < 0. ? 1. : Transparency > 1. ? 0. : 1. - Transparency;
215
216 if( m_Opacity <= 0. && (Mode == IMG_MODE_TRANSPARENT || Mode == IMG_MODE_TRANSPARENT_ALPHA) )
217 {
218 return( false );
219 }
220
221 switch( Mode )
222 {
223 case IMG_MODE_OPAQUE: default: m_img_mode = IMG_MODE_OPAQUE ; break;
224 case IMG_MODE_SHADING : m_img_mode = IMG_MODE_SHADING ; break;
225 case IMG_MODE_TRANSPARENT : m_img_mode = m_Opacity < 1. ? IMG_MODE_TRANSPARENT : IMG_MODE_OPAQUE; break;
226 case IMG_MODE_TRANSPARENT_ALPHA: m_img_mode = IMG_MODE_TRANSPARENT_ALPHA ; break;
227 }
228
229 //-----------------------------------------------------
230 m_img.Create(m_rDC.GetWidth(), m_rDC.GetHeight());
231 m_img.SetMask(true);
232 m_img.SetMaskColour(m_Background[0], m_Background[1], m_Background[2]);
233 m_img_rgb = m_img.GetData();
234 m_img_nx = m_rDC.GetWidth();
235 m_img_nBytes = 3 * m_rDC.GetHeight() * m_rDC.GetWidth();
236
237 BYTE *pRGB = m_img_rgb;
238
239 for(int i=0; i<m_img_nBytes; i+=3)
240 {
241 *pRGB++ = m_Background[0];
242 *pRGB++ = m_Background[1];
243 *pRGB++ = m_Background[2];
244 }
245
246 //-----------------------------------------------------
247 if( m_img_mode != IMG_MODE_OPAQUE )
248 {
249 wxBitmap tmp_BMP(m_rDC.GetWidth(), m_rDC.GetHeight());
250 wxMemoryDC tmp_dc;
251
252 tmp_dc.SelectObject(tmp_BMP);
253 tmp_dc.Blit(0, 0, m_rDC.GetWidth(), m_rDC.GetHeight(), &dc, 0, 0);
254 tmp_dc.SelectObject(wxNullBitmap);
255
256 if( !tmp_BMP.IsOk() )
257 {
258 m_img.Destroy();
259 m_img_rgb = NULL;
260 m_img_nx = 0;
261 m_img_nBytes = 0;
262
263 return( false );
264 }
265
266 m_img_dc = tmp_BMP.ConvertToImage();
267 m_img_dc_rgb = m_img_dc.GetData();
268 }
269
270 return( true );
271 }
272
273 //---------------------------------------------------------
IMG_Draw_End(void)274 bool CWKSP_Map_DC::IMG_Draw_End(void)
275 {
276 if( !m_img.Ok() )
277 {
278 return( false );
279 }
280
281 //-----------------------------------------------------
282 dc.DrawBitmap(wxBitmap(m_img), 0, 0, true);
283
284 m_img.Destroy();
285 m_img_rgb = NULL;
286 m_img_nx = 0;
287 m_img_nBytes = 0;
288
289 if( m_img_dc.Ok() )
290 {
291 m_img_dc.Destroy();
292 m_img_dc_rgb = NULL;
293 }
294
295 return( true );
296 }
297
298 //---------------------------------------------------------
IMG_Set_Rect(int x_a,int y_a,int x_b,int y_b,int Color)299 void CWKSP_Map_DC::IMG_Set_Rect(int x_a, int y_a, int x_b, int y_b, int Color)
300 {
301 if( y_a > y_b ) { double y = y_a; y_a = y_b; y_b = y; }
302 if( y_a < 0 ) { y_a = 0; }
303 if( y_b >= m_rDC.GetHeight() ) { y_b = m_rDC.GetHeight(); }
304
305 if( x_a > x_b ) { double x = x_a; x_a = x_b; x_b = x; }
306 if( x_a < 0 ) { x_a = 0; }
307 if( x_b >= m_rDC.GetWidth () ) { x_b = m_rDC.GetWidth (); }
308
309 //-----------------------------------------------------
310 for(int y=y_a; y<y_b; y++)
311 {
312 int i = 3 * (y * m_img_nx + x_a);
313
314 for(int x=x_a; x<x_b; x++, i+=3)
315 {
316 IMG_Set_Pixel_Direct(i, Color);
317 }
318 }
319 }
320
321
322 ///////////////////////////////////////////////////////////
323 // //
324 ///////////////////////////////////////////////////////////
325
326 //---------------------------------------------------------
Draw_Polygon(CSG_Shape_Polygon * pPolygon)327 void CWKSP_Map_DC::Draw_Polygon(CSG_Shape_Polygon *pPolygon)
328 {
329 if( m_World2DC * pPolygon->Get_Extent().Get_XRange() <= 2.
330 && m_World2DC * pPolygon->Get_Extent().Get_YRange() <= 2. )
331 {
332 dc.DrawPoint(
333 (int)xWorld2DC(pPolygon->Get_Extent().Get_XCenter()),
334 (int)yWorld2DC(pPolygon->Get_Extent().Get_YCenter())
335 );
336 }
337
338 //-----------------------------------------------------
339 else if( pPolygon->Get_Part_Count() == 1 && pPolygon->Get_Point_Count(0) > 2 )
340 {
341 wxPoint *Points = new wxPoint[pPolygon->Get_Point_Count()];
342
343 for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(0); iPoint++)
344 {
345 Points[iPoint].x = (int)xWorld2DC(pPolygon->Get_Point(iPoint, 0).x);
346 Points[iPoint].y = (int)yWorld2DC(pPolygon->Get_Point(iPoint, 0).y);
347 }
348
349 dc.DrawPolygon(pPolygon->Get_Point_Count(), Points);
350
351 delete[](Points);
352 }
353
354 //-----------------------------------------------------
355 else if( pPolygon->Get_Part_Count() > 1 )
356 {
357 wxPoint *Points = new wxPoint[pPolygon->Get_Point_Count()];
358 int *nPoints = new int [pPolygon->Get_Part_Count ()];
359
360 for(int iPart=0, jPoint=0; iPart<pPolygon->Get_Part_Count(); iPart++)
361 {
362 nPoints[iPart] = pPolygon->Get_Point_Count(iPart);
363
364 for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(iPart); iPoint++, jPoint++)
365 {
366 Points[jPoint].x = (int)xWorld2DC(pPolygon->Get_Point(iPoint, iPart).x);
367 Points[jPoint].y = (int)yWorld2DC(pPolygon->Get_Point(iPoint, iPart).y);
368 }
369 }
370
371 dc.DrawPolyPolygon(pPolygon->Get_Part_Count(), nPoints, Points, 0, 0, wxODDEVEN_RULE);
372
373 delete[]( Points);
374 delete[](nPoints);
375 }
376 }
377
378
379 ///////////////////////////////////////////////////////////
380 // //
381 // //
382 // //
383 ///////////////////////////////////////////////////////////
384
385 //---------------------------------------------------------
386