SAGA API Version 9.14
Loading...
Searching...
No Matches
map_dc.cpp
Go to the documentation of this file.
1
3// //
4// SAGA //
5// //
6// System for Automated Geoscientific Analyses //
7// //
8// Application Programming Interface //
9// //
10// Library: SAGA_API //
11// //
12//-------------------------------------------------------//
13// //
14// map_dc.cpp //
15// //
16// Copyright (C) 2024 by //
17// Olaf Conrad //
18// //
19//-------------------------------------------------------//
20// //
21// This file is part of 'SAGA - System for Automated //
22// Geoscientific Analyses'. SAGA is free software; you //
23// can redistribute it and/or modify it under the terms //
24// of the GNU General Public License as published by the //
25// Free Software Foundation, either version 2 of the //
26// License, or (at your option) any later version. //
27// //
28// SAGA is distributed in the hope that it will be //
29// useful, but WITHOUT ANY WARRANTY; without even the //
30// implied warranty of MERCHANTABILITY or FITNESS FOR A //
31// PARTICULAR PURPOSE. See the GNU General Public //
32// License for more details. //
33// //
34// You should have received a copy of the GNU General //
35// Public License along with this program; if not, see //
36// <http://www.gnu.org/licenses/>. //
37// //
38//-------------------------------------------------------//
39// //
40// contact: Olaf Conrad //
41// Institute of Geography //
42// University of Hamburg //
43// Germany //
44// //
45// e-mail: oconrad@saga-gis.org //
46// //
48
49//---------------------------------------------------------
50#include "../dc_helper.h"
51
52#include "map_dc.h"
53
54
56// //
57// //
58// //
60
61//---------------------------------------------------------
63{
64 // nop
65}
66
67//---------------------------------------------------------
68CSG_Map_DC::CSG_Map_DC(const CSG_Rect &rWorld, const wxRect &rDC, double Scale, int Background, bool bAlpha)
69{
70 Create(rWorld, rDC, Scale, Background, bAlpha);
71}
72
73//---------------------------------------------------------
74CSG_Map_DC::CSG_Map_DC(const CSG_Rect &rWorld, const CSG_Rect_Int &rDC, double Scale, int Background, bool bAlpha)
75{
76 Create(rWorld, rDC, Scale, Background, bAlpha);
77}
78
79//---------------------------------------------------------
81{
82 Destroy();
83}
84
85
87// //
89
90//---------------------------------------------------------
91bool CSG_Map_DC::Create(const CSG_Rect &rWorld, const CSG_Rect_Int &rDC, double Scale, int Background, bool bAlpha)
92{
93 return( Create(rWorld, wxRect(rDC.xMin, rDC.yMin, rDC.Get_XRange(), rDC.Get_YRange()), Scale, Background, bAlpha) );
94}
95
96//---------------------------------------------------------
97bool CSG_Map_DC::Create(const CSG_Rect &rWorld, const wxRect &rDC, double Scale, int Background, bool bAlpha)
98{
99 m_rWorld = rWorld;
100 m_rDC = rDC;
101 m_Scale = Scale;
102
103 m_img_nx = m_rDC.GetWidth ();
104 m_img_ny = m_rDC.GetHeight(); m_img_nPixels = m_img_nx * m_img_ny;
105
106 if( m_img_nx < 1 || m_img_ny < 1 )
107 {
108 Destroy();
109
110 return( false );
111 }
112
113 //-----------------------------------------------------
114 if( m_rWorld.Get_XRange() == 0. || m_rWorld.Get_YRange() == 0. )
115 {
116 m_rWorld.Inflate(m_rWorld.Get_XRange() ? 0. : 1., m_rWorld.Get_YRange() ? 0. : 1., false);
117 }
118
119 // ensure cellsize in x-/y-direction are identical...
120 double dxdyDC = (double)m_img_nx / (double)m_img_ny;
121 double dxdyWorld = m_rWorld.Get_XRange() / m_rWorld.Get_YRange();
122
123 if( dxdyDC > dxdyWorld )
124 {
125 m_rWorld.Inflate(0.5 * (m_rWorld.Get_YRange() * dxdyDC - m_rWorld.Get_XRange()), 0., false);
126 }
127 else if( dxdyDC < dxdyWorld )
128 {
129 m_rWorld.Inflate(0., 0.5 * (m_rWorld.Get_XRange() / dxdyDC - m_rWorld.Get_YRange()), false);
130 }
131
132 m_World2DC = m_img_nx / m_rWorld.Get_XRange();
133 m_DC2World = m_rWorld.Get_XRange() / m_img_nx;
134
135 //-----------------------------------------------------
136 m_bmp.Create(m_img_nx, m_img_ny);
137 m_dc.SelectObject(m_bmp);
138 m_dc.SetBackground(wxBrush(Background < 0 ? *wxWHITE : wxColour(SG_GET_R(Background), SG_GET_G(Background), SG_GET_B(Background))));
139 m_dc.Clear();
140
141 if( (m_img_alpha = bAlpha ? (BYTE *)m_Alpha.Create(sizeof(BYTE), m_img_nPixels) : NULL) != NULL )
142 {
143 memset(m_img_alpha, 0, m_img_nPixels);
144 }
145
146 return( true );
147}
148
149//---------------------------------------------------------
151{
152 m_img.Destroy(); m_img_rgb = NULL; m_img_alpha = NULL; m_img_nx = 0; m_img_nPixels = 0;
153
154 m_Alpha.Destroy();
155
156 return( true );
157}
158
159
161// //
163
164//---------------------------------------------------------
166{
167 return( SG_Get_Color(m_dc.GetBackground().GetColour()) );
168}
169
170//---------------------------------------------------------
172{
173 wxBitmap Bitmap; Get_Bitmap(Bitmap); return( Bitmap );
174}
175
176//---------------------------------------------------------
177bool CSG_Map_DC::Get_Bitmap(wxBitmap &Bitmap)
178{
179 if( m_bmp.IsOk() )
180 {
181 if( m_img_alpha )
182 {
183 wxImage Image;
184
185 if( Get_Image(Image) )
186 {
187 Bitmap = wxBitmap(Image);
188
189 return( true );
190 }
191 }
192 else
193 {
194 m_dc.SelectObject(wxNullBitmap);
195
196 Bitmap = m_bmp;
197
198 m_dc.SelectObject(m_bmp);
199
200 return( true );
201 }
202 }
203
204 return( false );
205}
206
207//---------------------------------------------------------
208bool CSG_Map_DC::Get_Image(wxImage &Image)
209{
210 if( m_bmp.IsOk() )
211 {
212 m_dc.SelectObject(wxNullBitmap);
213
214 Image = m_bmp.ConvertToImage();
215
216 if( m_img_alpha )
217 {
218 if( Image.HasAlpha() == false )
219 {
220 Image.SetAlpha();
221 }
222
223 #pragma omp parallel for
224 for(int y=0; y<m_img_ny; y++)
225 {
226 for(int x=0, i=y*m_img_nx; x<m_img_nx; x++, i++)
227 {
228 Image.SetAlpha(x, y, m_img_alpha[i]);
229 }
230 }
231 }
232
233 m_dc.SelectObject(m_bmp);
234
235 return( true );
236 }
237
238 return( false );
239}
240
241//---------------------------------------------------------
243{
244 wxImage Image;
245
246 if( Get_Image(Image) && Map.Create(SG_DATATYPE_Int, Image.GetWidth(), Image.GetHeight(), m_DC2World, m_rWorld.xMin, m_rWorld.yMin) )
247 {
248 #pragma omp parallel for
249 for(int y=0; y<Map.Get_NY(); y++)
250 {
251 for(int x=0, yy=Map.Get_NY()-1-y; x<Map.Get_NX(); x++)
252 {
253 BYTE rgb[4] = { Image.GetRed(x, yy), Image.GetGreen(x, yy), Image.GetBlue(x, yy), Image.GetAlpha(x, yy) };
254
255 Map.Set_Value(x, y, *(int *)rgb);
256 }
257 }
258
259 return( true );
260 }
261
262 return( false );
263}
264
265
267// //
269
270//---------------------------------------------------------
272{
273 m_bmp_layer.Create(m_img_nx, m_img_ny);
274 m_dc .SelectObject(m_bmp_layer);
275 m_dc .SetBackground (*wxWHITE_BRUSH);
276 m_dc .Clear();
277
278 m_bmp_alpha.Create(m_img_nx, m_img_ny);
279 m_dc_alpha .SelectObject(m_bmp_alpha);
280 m_dc_alpha .SetBrush (*wxWHITE_BRUSH);
281 m_dc_alpha .SetPen (*wxWHITE_PEN);
282 m_dc_alpha .SetTextForeground(*wxWHITE);
283 m_dc_alpha .SetBackground (*wxBLACK_BRUSH);
284 m_dc_alpha .Clear();
285
286 return( true );
287}
288
289//---------------------------------------------------------
290bool CSG_Map_DC::Draw_Layer_End(double Transparency)
291{
292 m_dc.SelectObject(m_bmp); m_dc_alpha.SelectObject(wxNullBitmap);
293
294 if( Draw_Image_Begin(Transparency) )
295 {
296 wxImage img_layer = m_bmp_layer.ConvertToImage(); BYTE *rgb = img_layer.GetData();
297 wxImage img_alpha = m_bmp_alpha.ConvertToImage(); BYTE *alpha = img_alpha.GetData();
298
299 #pragma omp parallel for
300 for(int i=0; i<m_img_nPixels; i++)
301 {
302 if( alpha[i * 3] )
303 {
304 _Draw_Image_Pixel(i, *((int *)(rgb + i * 3)));
305 }
306 }
307
309
310 return( true );
311 }
312
313 return( false );
314}
315
316//---------------------------------------------------------
318{
319 if( m_World2DC * pPolygon->Get_Extent().Get_XRange() <= 2.
320 && m_World2DC * pPolygon->Get_Extent().Get_YRange() <= 2. )
321 {
322 DrawPoint(
323 (int)xWorld2DC(pPolygon->Get_Extent().Get_XCenter()),
324 (int)yWorld2DC(pPolygon->Get_Extent().Get_YCenter())
325 );
326 }
327
328 //-----------------------------------------------------
329 else if( pPolygon->Get_Part_Count() == 1 && pPolygon->Get_Point_Count(0) > 2 )
330 {
331 wxPoint *Points = new wxPoint[pPolygon->Get_Point_Count()];
332
333 for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(0); iPoint++)
334 {
335 Points[iPoint].x = (int)xWorld2DC(pPolygon->Get_Point(iPoint, 0).x);
336 Points[iPoint].y = (int)yWorld2DC(pPolygon->Get_Point(iPoint, 0).y);
337 }
338
339 DrawPolygon(pPolygon->Get_Point_Count(), Points);
340
341 delete[](Points);
342 }
343
344 //-----------------------------------------------------
345 else if( pPolygon->Get_Part_Count() > 1 )
346 {
347 wxPoint *Points = new wxPoint[pPolygon->Get_Point_Count()];
348 int *nPoints = new int [pPolygon->Get_Part_Count ()];
349
350 for(int iPart=0, jPoint=0; iPart<pPolygon->Get_Part_Count(); iPart++)
351 {
352 nPoints[iPart] = pPolygon->Get_Point_Count(iPart);
353
354 for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(iPart); iPoint++, jPoint++)
355 {
356 Points[jPoint].x = (int)xWorld2DC(pPolygon->Get_Point(iPoint, iPart).x);
357 Points[jPoint].y = (int)yWorld2DC(pPolygon->Get_Point(iPoint, iPart).y);
358 }
359 }
360
361 DrawPolyPolygon(pPolygon->Get_Part_Count(), nPoints, Points, 0, 0, wxODDEVEN_RULE);
362
363 delete[]( Points);
364 delete[](nPoints);
365 }
366}
367
368
370// //
372
373//---------------------------------------------------------
374bool CSG_Map_DC::Draw_Image_Begin(double Transparency, Mode Mode)
375{
376 if( m_DC2World <= 0. || m_img_nx < 1 || m_img_ny < 1 )
377 {
378 return( false );
379 }
380
381 m_Opacity = Transparency < 0. ? 1. : Transparency > 1. ? 0. : 1. - Transparency;
382
383 if( m_Opacity <= 0. && (Mode == Mode::Transparent || Mode == Mode::Alpha) )
384 {
385 return( false );
386 }
387
388 if( Mode == Mode::Transparent && m_Opacity >= 1. )
389 {
391 }
392
393 m_img_mode = Mode;
394
395 //-----------------------------------------------------
396 wxMemoryDC copy_dc; wxBitmap copy_bmp(m_img_nx, m_img_ny);
397
398 copy_dc.SelectObject(copy_bmp);
399 copy_dc.Blit(0, 0, m_img_nx, m_img_ny, &m_dc, 0, 0);
400 copy_dc.SelectObject(wxNullBitmap);
401
402 if( copy_bmp.IsOk() )
403 {
404 m_img = copy_bmp.ConvertToImage();
405
406 if( m_img.IsOk() )
407 {
408 m_img_rgb = m_img.GetData();
409
410 return( true );
411 }
412 }
413
414 return( false );
415}
416
417//---------------------------------------------------------
419{
420 if( m_img.Ok() )
421 {
422 m_dc.DrawBitmap(wxBitmap(m_img), 0, 0, true);
423
424 m_img.Destroy(); m_img_rgb = NULL;
425
426 return( true );
427 }
428
429 return( false );
430}
431
432//---------------------------------------------------------
433void CSG_Map_DC::Draw_Image_Pixels(int x1, int y1, int x2, int y2, int Color)
434{
435 if( x1 > x2 ) { double x = x1; x1 = x2; x2 = x; }
436 if( y1 > y2 ) { double y = y1; y1 = y2; y2 = y; }
437
438 if( y1 < 0 ) { y1 = 0; }
439 if( y2 > m_img_ny ) { y2 = m_img_ny; }
440
441 if( x1 < 0 ) { x1 = 0; }
442 if( x2 > m_img_nx ) { x2 = m_img_nx; }
443
444 //-----------------------------------------------------
445 for(int y=y1; y<y2; y++)
446 {
447 for(int x=x1, i=y*m_img_nx+x1; x<x2; x++, i++)
448 {
449 _Draw_Image_Pixel(i, Color);
450 }
451 }
452}
453
454
456// //
458
459//---------------------------------------------------------
460void CSG_Map_DC::Set_Font(wxFont &Font)
461{
462 if( Font.Ok() )
463 {
464 Font.SetPointSize((int)(m_Scale * Font.GetPointSize()));
465
466 SetFont(Font);
467 }
468}
469
470//---------------------------------------------------------
471void CSG_Map_DC::SetFont(const wxFont &Font)
472{
473 m_dc.SetFont(Font);
474
475 if( m_dc_alpha.IsOk() )
476 {
477 m_dc_alpha.SetFont(Font);
478 }
479}
480
481//---------------------------------------------------------
482void CSG_Map_DC::SetPen(const wxPen &Pen)
483{
484 m_dc.SetPen(Pen);
485
486 if( m_dc_alpha.IsOk() )
487 {
488 wxPen _Pen(Pen); _Pen.SetColour(*wxWHITE);
489
490 m_dc_alpha.SetPen(_Pen);
491 }
492}
493
494//---------------------------------------------------------
495void CSG_Map_DC::SetBrush(const wxBrush &Brush)
496{
497 m_dc.SetBrush(Brush);
498
499 if( m_dc_alpha.IsOk() )
500 {
501 wxBrush _Brush(Brush); _Brush.SetColour(*wxWHITE);
502
503 m_dc_alpha.SetBrush(_Brush);
504 }
505}
506
507
509// //
511
512//---------------------------------------------------------
513void CSG_Map_DC::DrawPoint(int x, int y)
514{
515 m_dc.DrawPoint(x, y);
516
517 if( m_dc_alpha.IsOk() )
518 {
519 m_dc_alpha.DrawPoint(x, y);
520 }
521}
522
523//---------------------------------------------------------
524void CSG_Map_DC::DrawLine(int x1, int y1, int x2, int y2)
525{
526 m_dc.DrawLine(x1, y1, x2, y2);
527
528 if( m_dc_alpha.IsOk() )
529 {
530 m_dc_alpha.DrawLine(x1, y1, x2, y2);
531 }
532}
533
534//---------------------------------------------------------
535void CSG_Map_DC::DrawRectangle(int x, int y, int width, int height)
536{
537 m_dc.DrawRectangle(x, y, width, height);
538
539 if( m_dc_alpha.IsOk() )
540 {
541 m_dc_alpha.DrawRectangle(x, y, width, height);
542 }
543}
544
545void CSG_Map_DC::DrawRectangle(const wxRect &r)
546{
547 m_dc.DrawRectangle(r);
548
549 if( m_dc_alpha.IsOk() )
550 {
551 m_dc_alpha.DrawRectangle(r);
552 }
553}
554
555//---------------------------------------------------------
556void CSG_Map_DC::DrawCircle(int x, int y, int radius)
557{
558 m_dc.DrawCircle(x, y, radius);
559
560 if( m_dc_alpha.IsOk() )
561 {
562 m_dc_alpha.DrawCircle(x, y, radius);
563 }
564}
565
566//---------------------------------------------------------
567void CSG_Map_DC::DrawArc(int xStart, int yStart, int xEnd, int yEnd, int xc, int yc)
568{
569 m_dc.DrawArc(xStart, yStart, xEnd, yEnd, xc, yc);
570
571 if( m_dc_alpha.IsOk() )
572 {
573 m_dc_alpha.DrawArc(xStart, yStart, xEnd, yEnd, xc, yc);
574 }
575}
576
577//---------------------------------------------------------
578void CSG_Map_DC::DrawPolygon(int n, const wxPoint points[], int xoffset, int yoffset, wxPolygonFillMode fill_style)
579{
580 m_dc.DrawPolygon(n, points, xoffset, yoffset, fill_style);
581
582 if( m_dc_alpha.IsOk() )
583 {
584 m_dc_alpha.DrawPolygon(n, points, xoffset, yoffset, fill_style);
585 }
586}
587
588//---------------------------------------------------------
589void CSG_Map_DC::DrawPolyPolygon(int n, const int count[], const wxPoint points[], int xoffset, int yoffset, wxPolygonFillMode fill_style)
590{
591 m_dc.DrawPolyPolygon(n, count, points, xoffset, yoffset, fill_style);
592
593 if( m_dc_alpha.IsOk() )
594 {
595 m_dc_alpha.DrawPolyPolygon(n, count, points, xoffset, yoffset, fill_style);
596 }
597}
598
599//---------------------------------------------------------
600void CSG_Map_DC::DrawBitmap(const wxBitmap &bitmap, int x, int y, bool useAlpha)
601{
602 m_dc.DrawBitmap(bitmap, x, y, useAlpha);
603
604 if( m_dc_alpha.IsOk() )
605 {
606 m_dc_alpha.DrawBitmap(bitmap, x, y, useAlpha);
607 }
608}
609
610
612// //
614
615//---------------------------------------------------------
616void CSG_Map_DC::DrawText(int Align, int x, int y, const wxString &Text)
617{
618 SG_DC_Draw_Text(m_dc, Align, x, y, Text);
619
620 if( m_dc_alpha.IsOk() )
621 {
622 SG_DC_Draw_Text(m_dc_alpha, Align, x, y, Text);
623 }
624}
625
626//---------------------------------------------------------
627void CSG_Map_DC::DrawText(int Align, int x, int y, double Angle, const wxString &Text)
628{
629 SG_DC_Draw_Text(m_dc, Align, x, y, Angle, Text);
630
631 if( m_dc_alpha.IsOk() )
632 {
633 SG_DC_Draw_Text(m_dc_alpha, Align, x, y, Angle, Text);
634 }
635}
636
637//---------------------------------------------------------
638void CSG_Map_DC::DrawText(int Align, int x, int y, const wxString &Text, int Effect, wxColour Effect_Color, int Effect_Size)
639{
640 SG_DC_Draw_Text(m_dc, Align, x, y, Text, Effect, Effect_Color, Effect_Size);
641
642 if( m_dc_alpha.IsOk() )
643 {
644 SG_DC_Draw_Text(m_dc_alpha, Align, x, y, Text, Effect, Effect_Color, Effect_Size);
645 }
646}
647
648//---------------------------------------------------------
649void CSG_Map_DC::DrawText(int Align, int x, int y, double Angle, const wxString &Text, int Effect, wxColour Effect_Color, int Effect_Size)
650{
651 SG_DC_Draw_Text(m_dc, Align, x, y, Angle, Text, Effect, Effect_Color, Effect_Size);
652
653 if( m_dc_alpha.IsOk() )
654 {
655 SG_DC_Draw_Text(m_dc_alpha, Align, x, y, Angle, Text, Effect, Effect_Color, Effect_Size);
656 }
657}
658
659
661// //
662// //
663// //
665
666//---------------------------------------------------------
#define SG_GET_B(rgb)
Definition api_core.h:1350
#define SG_GET_G(rgb)
Definition api_core.h:1349
#define SG_GET_R(rgb)
Definition api_core.h:1348
@ SG_DATATYPE_Int
Definition api_core.h:1050
int Get_NY(void) const
Definition grid.h:564
virtual void Set_Value(sLong i, BYTE Value, bool bScaled=true)
Definition grid.h:846
bool Create(const CSG_Grid &Grid)
Definition grid.cpp:235
int Get_NX(void) const
Definition grid.h:563
bool Get_Image(wxImage &Image)
Definition map_dc.cpp:208
bool Destroy(void)
Definition map_dc.cpp:150
void SetBrush(const wxBrush &Brush)
Definition map_dc.cpp:495
void DrawPoint(int x, int y)
Definition map_dc.cpp:513
bool Draw_Layer_Begin(void)
Definition map_dc.cpp:271
bool Draw_Image_Begin(double Transparency, Mode Mode=Mode::Transparent)
Definition map_dc.cpp:374
void SetPen(const wxPen &Pen)
Definition map_dc.cpp:482
void DrawPolygon(int n, const wxPoint points[], int xoffset=0, int yoffset=0, wxPolygonFillMode fill_style=wxODDEVEN_RULE)
Definition map_dc.cpp:578
virtual ~CSG_Map_DC(void)
Definition map_dc.cpp:80
CSG_Map_DC(void)
Definition map_dc.cpp:62
void DrawArc(int xStart, int yStart, int xEnd, int yEnd, int xc, int yc)
Definition map_dc.cpp:567
double yWorld2DC(double y, bool bRound=true)
Definition map_dc.h:147
void DrawCircle(int x, int y, int radius)
Definition map_dc.cpp:556
const CSG_Rect & rWorld(void) const
Definition map_dc.h:124
double xWorld2DC(double x, bool bRound=true)
Definition map_dc.h:140
void DrawBitmap(const wxBitmap &bitmap, int x, int y, bool useAlpha=false)
Definition map_dc.cpp:600
bool Create(const CSG_Rect &rWorld, const CSG_Rect_Int &rDC, double Scale=1., int Background=-1, bool bAlpha=false)
Definition map_dc.cpp:91
bool Draw_Layer_End(double Transparency=0.)
Definition map_dc.cpp:290
void DrawLine(int x1, int y1, int x2, int y2)
Definition map_dc.cpp:524
const wxRect & rDC(void) const
Definition map_dc.h:129
void Draw_Image_Pixels(int x1, int y1, int x2, int y2, int Color)
Definition map_dc.cpp:433
wxBitmap Get_Bitmap(void)
Definition map_dc.cpp:171
const double & Scale(void) const
Definition map_dc.h:122
void Draw_Polygon(CSG_Shape_Polygon *pPolygon)
Definition map_dc.cpp:317
bool Draw_Image_End(void)
Definition map_dc.cpp:418
int Get_Background(void) const
Definition map_dc.cpp:165
void SetFont(const wxFont &Font)
Definition map_dc.cpp:471
void DrawPolyPolygon(int n, const int count[], const wxPoint points[], int xoffset=0, int yoffset=0, wxPolygonFillMode fill_style=wxODDEVEN_RULE)
Definition map_dc.cpp:589
void DrawText(int Align, int x, int y, const wxString &Text)
Definition map_dc.cpp:616
void Set_Font(wxFont &Font)
Definition map_dc.cpp:460
void DrawRectangle(int x1, int y1, int width, int height)
Definition map_dc.cpp:535
double Get_YRange(void) const
Definition geo_tools.h:511
double Get_YCenter(void) const
Definition geo_tools.h:521
double Get_XRange(void) const
Definition geo_tools.h:510
double Get_XCenter(void) const
Definition geo_tools.h:520
virtual TSG_Point Get_Point(int iPoint=0) const
virtual int Get_Part_Count(void) const
Definition shapes.h:503
virtual int Get_Point_Count(void) const
Definition shapes.h:501
virtual const CSG_Rect & Get_Extent(void)
Definition shapes.h:548
void SG_DC_Draw_Text(wxDC &dc, int Align, int x, int y, const wxString &Text)
int SG_Get_Color(const wxColour &Color)
Definition dc_helper.cpp:64
double x
Definition geo_tools.h:129
double y
Definition geo_tools.h:129