SAGA API Version 9.14
Loading...
Searching...
No Matches
map_grids.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_grids.cpp //
15// //
16// Copyright (C) 2026 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// e-mail: oconrad@saga-gis.org //
41// //
42// contact: Olaf Conrad //
43// Institute of Geography //
44// University of Hamburg //
45// Germany //
46// //
48
49//---------------------------------------------------------
50#include "../dc_helper.h"
51
52#include "map_symbology.h"
53#include "map_legend.h"
54
55#include "map_layer.h"
56
57
59// //
60// //
61// //
63
64//---------------------------------------------------------
72
73
75// //
77
78//---------------------------------------------------------
80{
82
83 //-----------------------------------------------------
84 // Display...
85
86 Parameters.Add_Grid_Resampling("NODE_DISPLAY", "STRETCH_RESAMPLING", _TL("Resampling"), _TL(""), CSG_Grid_Resampling::Interpolations, CSG_Grid_Resampling::NearestNeighbour);
87
88 //-----------------------------------------------------
89 // Transparency...
90
91 Parameters.Add_Grid("TRANSPARENCY", "TRANSPARENCY_GRID", _TL("Transparency Band"),
92 _TL("Band values used to define transparency. Transparency will be linearly scaled from full transparency to full opacity value range. Can be combined with overall transparency."),
94 );
95
96 Parameters.Add_Double("TRANSPARENCY_GRID", "TRANSPARENCY_GRID_STRETCH.MIN", _TL("Full Transparency"), _TL(""), 0.);
97 Parameters.Add_Double("TRANSPARENCY_GRID", "TRANSPARENCY_GRID_STRETCH.MAX", _TL("Full Opacity" ), _TL(""), 0.);
98
99 //-----------------------------------------------------
100 // Classification...
101
102 Parameters.Add_Grid("COMPOSITE_R", "COMPOSITE_R_GRID", _TL("External Grid"), _TL(""), PARAMETER_INPUT);
103 Parameters.Add_Grid("COMPOSITE_G", "COMPOSITE_G_GRID", _TL("External Grid"), _TL(""), PARAMETER_INPUT);
104 Parameters.Add_Grid("COMPOSITE_B", "COMPOSITE_B_GRID", _TL("External Grid"), _TL(""), PARAMETER_INPUT);
105
106 Set_Grid_Choices(Parameters);
107
108 //-----------------------------------------------------
109 if( m_pObject )
110 {
111 Parameters["TRANSPARENCY_GRID"].Get_Parent()->Set_Value((void *)&m_pObject->asGrids()->Get_System());
112 }
113
114 return( true );
115}
116
117
119// //
121
122//---------------------------------------------------------
123bool CSG_Map_Grids::Parameter_Changed(CSG_Parameters &Parameters, CSG_Parameter &Parameter, int Flags)
124{
125 int Classify = Parameters["COLOR_SYMBOLS"].asInt();
126
127 //-----------------------------------------------------
128 if( Flags & PARAMETER_CHECK_VALUES )
129 {
130 if( Classify == CSG_Map_Symbology::COMPOSITE && Parameters["COMPOSITE_FIT"].asInt() == 1
131 && (Parameter.Cmp_Identifier("STRETCH")
132 || Parameter.Cmp_Identifier("STRETCH_LINEAR")
133 || Parameter.Cmp_Identifier("STRETCH_STDDEV")
134 || Parameter.Cmp_Identifier("STRETCH_STDDEV_RANGE")
135 || Parameter.Cmp_Identifier("STRETCH_PERCENT")
136 || Parameter.Cmp_Identifier("COMPOSITE_FIT")
137 || Parameter.Cmp_Identifier("COMPOSITE_R") || Parameter.Cmp_Identifier("COMPOSITE_R_GRID")
138 || Parameter.Cmp_Identifier("COMPOSITE_G") || Parameter.Cmp_Identifier("COMPOSITE_G_GRID")
139 || Parameter.Cmp_Identifier("COMPOSITE_B") || Parameter.Cmp_Identifier("COMPOSITE_B_GRID")) )
140 {
141 CSG_Grid *pGrid = NULL;
142
143 if( (pGrid = _Get_Grid(0, Parameters)) != NULL ) { Set_Stretch(Parameters, pGrid, "_R"); }
144 if( (pGrid = _Get_Grid(1, Parameters)) != NULL ) { Set_Stretch(Parameters, pGrid, "_G"); }
145 if( (pGrid = _Get_Grid(2, Parameters)) != NULL ) { Set_Stretch(Parameters, pGrid, "_B"); }
146 }
147
148 if( Parameter.Cmp_Identifier("TRANSPARENCY_GRID") )
149 {
150 if( Parameter.asGrid() )
151 {
152 Parameters.Set_Parameter("TRANSPARENCY_GRID_STRETCH.MIN", Parameter.asGrid()->Get_Min());
153 Parameters.Set_Parameter("TRANSPARENCY_GRID_STRETCH.MAX", Parameter.asGrid()->Get_Max());
154 }
155 }
156 }
157
158 //-----------------------------------------------------
159 if( Flags & PARAMETER_CHECK_ENABLE )
160 {
161 if( Parameter.Cmp_Identifier("COLOR_SYMBOLS")
162 || Parameter.Cmp_Identifier("COMPOSITE_FIT")
163 || Parameter.Cmp_Identifier("TRANSPARENCY") )
164 {
166
168
169 Parameters.Set_Enabled("STRETCH_RANGE" , Classify == CSG_Map_Symbology::DISCRETE || Classify == CSG_Map_Symbology::GRADUATED || (Classify == CSG_Map_Symbology::COMPOSITE && Parameters["COMPOSITE_FIT"].asInt() == 0));
171
172 Parameters.Set_Enabled("COMPOSITE_R" , Classify == CSG_Map_Symbology::COMPOSITE);
173 Parameters.Set_Enabled("COMPOSITE_G" , Classify == CSG_Map_Symbology::COMPOSITE);
174 Parameters.Set_Enabled("COMPOSITE_B" , Classify == CSG_Map_Symbology::COMPOSITE);
175 Parameters.Set_Enabled("COMPOSITE_FIT" , Classify == CSG_Map_Symbology::COMPOSITE);
176 Parameters.Set_Enabled("STRETCH_RANGE_R" , Classify == CSG_Map_Symbology::COMPOSITE && Parameters["COMPOSITE_FIT"].asInt() == 1);
177 Parameters.Set_Enabled("STRETCH_RANGE_G" , Classify == CSG_Map_Symbology::COMPOSITE && Parameters["COMPOSITE_FIT"].asInt() == 1);
178 Parameters.Set_Enabled("STRETCH_RANGE_B" , Classify == CSG_Map_Symbology::COMPOSITE && Parameters["COMPOSITE_FIT"].asInt() == 1);
179 }
180
181 if( m_pObject && Parameter.Cmp_Identifier("COMPOSITE_R") ) { Parameter.Set_Children_Enabled(Parameter.asInt() >= m_pObject->asGrids()->Get_NZ()); }
182 if( m_pObject && Parameter.Cmp_Identifier("COMPOSITE_G") ) { Parameter.Set_Children_Enabled(Parameter.asInt() >= m_pObject->asGrids()->Get_NZ()); }
183 if( m_pObject && Parameter.Cmp_Identifier("COMPOSITE_B") ) { Parameter.Set_Children_Enabled(Parameter.asInt() >= m_pObject->asGrids()->Get_NZ()); }
184
185 if( Parameter.Cmp_Identifier("TRANSPARENCY_GRID") )
186 {
187 Parameter.Set_Children_Enabled(Parameter.asGrid() != NULL);
188 }
189 }
190
191 //-----------------------------------------------------
192 return( CSG_Map_Layer::Parameter_Changed(Parameters, Parameter, Flags) );
193}
194
195
197// //
199
200//---------------------------------------------------------
202{
204
205 //-----------------------------------------------------
207
208 if( m_Parameters["COMPOSITE_R"].asInt() == 0
209 && m_Parameters["COMPOSITE_G"].asInt() == 0
210 && m_Parameters["COMPOSITE_B"].asInt() == 0 )
211 {
212 m_Parameters["COMPOSITE_G"].Set_Value(1);
213 m_Parameters["COMPOSITE_B"].Set_Value(2);
214 }
215
220
221 //-----------------------------------------------------
222 return( true );
223}
224
225
227// //
229
230//---------------------------------------------------------
232{
234
235 //-----------------------------------------------------
237
238 //-----------------------------------------------------
239 if( m_Parameters("COLOR_SYMBOLS")->asInt() == CSG_Map_Symbology::COMPOSITE && m_Parameters("COMPOSITE_FIT")->asInt() != 0 )
240 {
241 m_Stretch[0].Create(
242 m_Parameters["STRETCH_RANGE_R.MIN" ].asDouble(),
243 m_Parameters["STRETCH_RANGE_R.MAX" ].asDouble(),
244 m_Parameters["STRETCH_INTERVALS" ].asInt (),
245 m_Parameters["STRETCH_INTERVALS_LOG"].asDouble()
246 );
247
248 m_Stretch[1].Create(
249 m_Parameters["STRETCH_RANGE_G.MIN" ].asDouble(),
250 m_Parameters["STRETCH_RANGE_G.MAX" ].asDouble(),
251 m_Parameters["STRETCH_INTERVALS" ].asInt (),
252 m_Parameters["STRETCH_INTERVALS_LOG"].asDouble()
253 );
254
255 m_Stretch[2].Create(
256 m_Parameters["STRETCH_RANGE_B.MIN" ].asDouble(),
257 m_Parameters["STRETCH_RANGE_B.MAX" ].asDouble(),
258 m_Parameters["STRETCH_INTERVALS" ].asInt (),
259 m_Parameters["STRETCH_INTERVALS_LOG"].asDouble()
260 );
261
262 m_Stretch[0].Set_Histogram(Get_Grid(0));
263 m_Stretch[1].Set_Histogram(Get_Grid(1));
264 m_Stretch[2].Set_Histogram(Get_Grid(2));
265 }
266
267 //-----------------------------------------------------
268 return( true );
269}
270
271
273// //
275
276//---------------------------------------------------------
277bool CSG_Map_Grids::Set_Grid_Choices(CSG_Parameters &Parameters, int NameField)
278{
279 if( m_pObject )
280 {
281 if( NameField < 0 ) { NameField = m_pObject->asGrids()->Get_Z_Name_Field(); }
282
283 CSG_String List(_Get_List_Bands(NameField));
284
285 bool bReset = Parameters["BAND"].asChoice()->Get_Count() != m_pObject->asGrids()->Get_NZ();
286
287 if( Parameters("BAND") ) { Parameters["BAND"].asChoice()->Set_Items(List); }
288
289 List += CSG_String::Format("<%s>", _TL("external grid"));
290
291 if( Parameters("COMPOSITE_R") ) { Parameters["COMPOSITE_R"].asChoice()->Set_Items(List); if( bReset ) { Parameters["COMPOSITE_R"].Set_Value(2); } }
292 if( Parameters("COMPOSITE_G") ) { Parameters["COMPOSITE_G"].asChoice()->Set_Items(List); if( bReset ) { Parameters["COMPOSITE_G"].Set_Value(1); } }
293 if( Parameters("COMPOSITE_B") ) { Parameters["COMPOSITE_B"].asChoice()->Set_Items(List); if( bReset ) { Parameters["COMPOSITE_B"].Set_Value(0); } }
294
295 return( true );
296 }
297
298 return( false );
299}
300
301//---------------------------------------------------------
303{
304 int i = m_Parameters("BAND")->asInt();
305
306 return( m_pObject && i >= 0 && i < m_pObject->asGrids()->Get_NZ() ? m_pObject->asGrids()->Get_Grid_Ptr(i) : NULL );
307}
308
309//---------------------------------------------------------
311{
312 return( _Get_Grid(Band, m_Parameters) );
313}
314
315//---------------------------------------------------------
317{
318 int Choice = -1;
319
320 switch( Band )
321 {
322 case 0: Choice = m_Parameters["COMPOSITE_R"].asInt(); break;
323 case 1: Choice = m_Parameters["COMPOSITE_G"].asInt(); break;
324 case 2: Choice = m_Parameters["COMPOSITE_B"].asInt(); break;
325 }
326
327 if( Choice >= 0 )
328 {
329 if( m_pObject && Choice < m_pObject->asGrids()->Get_NZ() )
330 {
331 return( m_pObject->asGrids()->Get_Grid_Name(Choice, Style) );
332 }
333
334 CSG_Grid *pGrid = NULL;
335
336 switch( Band )
337 {
338 case 0: pGrid = m_Parameters["COMPOSITE_R_GRID"].asGrid(); break;
339 case 1: pGrid = m_Parameters["COMPOSITE_G_GRID"].asGrid(); break;
340 case 2: pGrid = m_Parameters["COMPOSITE_B_GRID"].asGrid(); break;
341 }
342
343 if( pGrid )
344 {
345 return( pGrid->Get_Name() );
346 }
347 }
348
349 return( "" );
350}
351
352//---------------------------------------------------------
353CSG_Grid * CSG_Map_Grids::_Get_Grid(int Band, const CSG_Parameters &Parameters)
354{
355 int Choice = -1;
356
357 switch( Band )
358 {
359 case 0: Choice = Parameters["COMPOSITE_R"].asInt(); break;
360 case 1: Choice = Parameters["COMPOSITE_G"].asInt(); break;
361 case 2: Choice = Parameters["COMPOSITE_B"].asInt(); break;
362 }
363
364 if( Choice >= 0 )
365 {
366 if( m_pObject && Choice < m_pObject->asGrids()->Get_NZ() )
367 {
368 return( m_pObject->asGrids()->Get_Grid_Ptr(Choice) );
369 }
370
371 switch( Band )
372 {
373 case 0: return( Parameters["COMPOSITE_R_GRID"].asGrid() );
374 case 1: return( Parameters["COMPOSITE_G_GRID"].asGrid() );
375 case 2: return( Parameters["COMPOSITE_B_GRID"].asGrid() );
376 }
377 }
378
379 return( NULL );
380}
381
382
384// //
386
387//---------------------------------------------------------
388CSG_String CSG_Map_Grids::_Get_List_Attributes(void)
389{
390 CSG_String List;
391
392 for(int i=0; m_pObject && i<m_pObject->asGrids()->Get_Attributes().Get_Field_Count(); i++)
393 {
394 List += m_pObject->asGrids()->Get_Attributes().Get_Field_Name(i); List += "|";
395 }
396
397 return( List );
398}
399
400//---------------------------------------------------------
401CSG_String CSG_Map_Grids::_Get_List_Bands(int Attribute)
402{
403 CSG_String List;
404
405 if( m_pObject )
406 {
407 if( Attribute < 0 || Attribute >= m_pObject->asGrids()->Get_Attributes().Get_Field_Count() )
408 {
409 Attribute = m_pObject->asGrids()->Get_Z_Name_Field();
410 }
411
412 for(int i=0; i<m_pObject->asGrids()->Get_NZ(); i++)
413 {
414 List += m_pObject->asGrids()->Get_Attributes()[i].asString(Attribute); List += "|";
415 }
416 }
417
418 return( List );
419}
420
421
423// //
425
426//---------------------------------------------------------
428{
429 if( m_Parameters["COLOR_SYMBOLS"].asInt() == CSG_Map_Symbology::DISCRETE
430 || m_Parameters["COLOR_SYMBOLS"].asInt() == CSG_Map_Symbology::GRADUATED
431 || m_Parameters["COLOR_SYMBOLS"].asInt() == CSG_Map_Symbology::COMPOSITE )
432 {
433 if( m_Parameters["STRETCH"].asInt() < 3 ) // not 'manual'
434 {
435 m_Stretch_Extent = m_Parameters["STRETCH"].asInt();
436 }
437
438 //-------------------------------------------------
439 double Minimum, Maximum;
440
441 if( m_Parameters("COLOR_SYMBOLS")->asInt() == CSG_Map_Symbology::DISCRETE
442 || m_Parameters("COLOR_SYMBOLS")->asInt() == CSG_Map_Symbology::GRADUATED )
443 {
444 return( _Get_Stretch_Extent(Extent, Get_Grid(), Minimum, Maximum) && Set_Stretch_Range(Minimum, Maximum) );
445 }
446
447 //-------------------------------------------------
448 if( m_Parameters("COMPOSITE_FIT")->asInt() == 0 && m_pObject ) // overall band statistics
449 {
450 return( _Get_Stretch_Extent(Extent, m_pObject->asGrids(), Minimum, Maximum) && Set_Stretch_Range(Minimum, Maximum) );
451 }
452
453 //-------------------------------------------------
454 if( _Get_Stretch_Extent(Extent, Get_Grid(), Minimum, Maximum) )
455 {
456 m_Parameters.Set_Parameter("STRETCH_RANGE.MIN", Minimum < Maximum ? Minimum : Maximum);
457 m_Parameters.Set_Parameter("STRETCH_RANGE.MAX", Minimum < Maximum ? Maximum : Minimum);
458 }
459
460 const CSG_String Band[3] = { "R", "G", "B" };
461
462 for(int i=0; i<3; i++)
463 {
464 if( _Get_Stretch_Extent(Extent, Get_Grid(i), Minimum, Maximum) )
465 {
466 m_Parameters.Set_Parameter("STRETCH_RANGE_" + Band[i] + ".MIN", Minimum);
467 m_Parameters.Set_Parameter("STRETCH_RANGE_" + Band[i] + ".MAX", Maximum);
468 }
469 }
470
471 m_Parameters["STRETCH"].Set_Value(3); // 'manual'
472
473 return( true );
474 }
475
476 return( false );
477}
478
479//---------------------------------------------------------
480bool CSG_Map_Grids::_Get_Stretch_Extent(const CSG_Rect &Extent, CSG_Data_Object *pObject, double &Minimum, double &Maximum) const
481{
482 if( pObject )
483 {
484 switch( m_Stretch_Extent )
485 {
486 default:
487 {
489
490 if( pObject->asGrid() ? pObject->asGrid()->Get_Statistics(Extent, s) : pObject->asGrids() && pObject->asGrids()->Get_Statistics(Extent, s) )
491 {
492 Minimum = s.Get_Minimum() + s.Get_Range() * m_Parameters("STRETCH_LINEAR.MIN")->asDouble() / 100.;
493 Maximum = s.Get_Minimum() + s.Get_Range() * m_Parameters("STRETCH_LINEAR.MAX")->asDouble() / 100.;
494
495 return( true );
496 }
497 }
498 break;
499
500 case 1:
501 {
502 CSG_Simple_Statistics s;
503
504 if( pObject->asGrid() ? pObject->asGrid()->Get_Statistics(Extent, s) : pObject->asGrids() && pObject->asGrids()->Get_Statistics(Extent, s) )
505 {
506 double d = m_Parameters("STRETCH_STDDEV")->asDouble() * s.Get_StdDev();
507
508 Minimum = s.Get_Mean() - d; if( m_Parameters("STRETCH_STDDEV_RANGE")->asBool() && Minimum < s.Get_Minimum() ) { Minimum = s.Get_Minimum(); }
509 Maximum = s.Get_Mean() + d; if( m_Parameters("STRETCH_STDDEV_RANGE")->asBool() && Maximum > s.Get_Maximum() ) { Maximum = s.Get_Maximum(); }
510
511 return( true );
512 }
513 }
514 break;
515
516 case 2:
517 {
518 CSG_Histogram h;
519
520 if( pObject->asGrid() ? pObject->asGrid()->Get_Histogram (Extent, h) : pObject->asGrids() && pObject->asGrids()->Get_Histogram (Extent, h) )
521 {
522 Minimum = h.Get_Quantile(m_Parameters("STRETCH_PERCENT.MIN")->asDouble() / 100.);
523 Maximum = h.Get_Quantile(m_Parameters("STRETCH_PERCENT.MAX")->asDouble() / 100.);
524
525 return( true );
526 }
527 }
528 break;
529 }
530 }
531
532 Minimum = Maximum = 0.;
533
534 return( false );
535}
536
537
539// //
541
542//---------------------------------------------------------
544{
545 wxImage Image;
546
547 if( m_pObject && pImage && Get_Image(Image) )
548 {
549 pImage->Create(m_pObject->asGrids()->Get_System(), SG_DATATYPE_Int);
550
551 #pragma omp parallel for
552 for(int y=0; y<pImage->Get_NY(); y++) for(int x=0; x<pImage->Get_NX(); x++)
553 {
554 if( Image.HasAlpha() )
555 {
556 pImage->Set_Value(x, y, SG_GET_RGBA(Image.GetRed(x, y), Image.GetGreen(x, y), Image.GetBlue(x, y), Image.GetAlpha(x, y)));
557 }
558 else
559 {
560 pImage->Set_Value(x, y, SG_GET_RGB (Image.GetRed(x, y), Image.GetGreen(x, y), Image.GetBlue(x, y)));
561 }
562 }
563
564 return( true );
565 }
566
567 return( false );
568}
569
570//---------------------------------------------------------
571bool CSG_Map_Grids::Get_Image(wxImage &Image, bool bFitSize, int Width, int Height)
572{
573 if( bFitSize || Width < 1 ) { Width = Get_Grid()->Get_NX(); }
574 if( bFitSize || Height < 1 ) { Height = Get_Grid()->Get_NY(); }
575
576 if( Width > 0 && Height > 0 && Image.Create(Width, Height) )
577 {
579
580 CSG_Map_DC dc_Map(Get_Extent(), Image.GetSize(), 1., -1, true);
581
582 On_Draw(dc_Map, false);
583
584 dc_Map.Get_Image(Image);
585
587
588 return( true );
589 }
590
591 return( false );
592}
593
594//---------------------------------------------------------
595bool CSG_Map_Grids::Get_Bitmap(wxBitmap &Bitmap, bool bFitSize, int Width, int Height)
596{
597 if( bFitSize || Width < 1 ) { Width = bFitSize ? Get_Grid()->Get_NX() : Bitmap.GetWidth (); }
598 if( bFitSize || Height < 1 ) { Height = bFitSize ? Get_Grid()->Get_NY() : Bitmap.GetHeight(); }
599
600 if( Width > 0 && Height > 0 && Bitmap.Create(Width, Height) )
601 {
603
604 CSG_Map_DC dc_Map(Get_Extent(), Bitmap.GetSize(), 1., -1, true);
605
606 On_Draw(dc_Map, false);
607
608 dc_Map.Get_Bitmap(Bitmap);
609
611
612 return( true );
613 }
614
615 return( false );
616}
617
618//---------------------------------------------------------
619bool CSG_Map_Grids::Get_Bitmap_Legend(wxBitmap &Bitmap, double Zoom)
620{
621 if( Zoom > 0. )
622 {
623 wxMemoryDC dc; wxSize s(Get_Legend()->Get_Size(Zoom, 1.));
624
625 Bitmap.Create(s.GetWidth(), s.GetHeight());
626
627 dc.SelectObject(Bitmap);
628 dc.SetBackground(*wxWHITE_BRUSH);
629 dc.Clear();
630
631 Get_Legend()->Draw(dc, Zoom, 1., wxPoint(0, 0));
632
633 dc.SelectObject(wxNullBitmap);
634
635 return( true );
636 }
637
638 return( false );
639}
640
641
643// //
645
646//---------------------------------------------------------
647void CSG_Map_Grids::On_Draw(CSG_Map_DC &dc_Map, int Flags)
648{
649 if( m_pObject == NULL || Get_Grid() == NULL || m_pObject->asGrids()->Get_NZ() < 1 || Get_Extent().Intersects(dc_Map.rWorld()) == INTERSECTION_None )
650 {
651 return;
652 }
653
654 //-----------------------------------------------------
655 m_Alpha.Create(m_Parameters("TRANSPARENCY_GRID")->asGrid(),
656 m_Parameters("TRANSPARENCY_GRID_STRETCH.MIN")->asDouble(),
657 m_Parameters("TRANSPARENCY_GRID_STRETCH.MAX")->asDouble()
658 );
659
661
662 if( !dc_Map.Draw_Image_Begin(m_Parameters("TRANSPARENCY")->asDouble() / 100., Mode) )
663 {
664 return;
665 }
666
667 //-----------------------------------------------------
668 switch( m_Parameters("COLOR_SYMBOLS")->asInt() )
669 {
675 }
676
677 //-----------------------------------------------------
678 if( m_pSymbology->Get_Mode() == CSG_Map_Symbology::SINGLE )
679 {
680 m_Bands.Resampling = CSG_Grid_Resampling::NearestNeighbour;
681 }
682 else
683 {
684 m_Bands.Resampling = m_Parameters(m_pSymbology->Get_Mode() == CSG_Map_Symbology::CLASSIFIED ? "CLASSIFIED_RESAMPLING" : "STRETCH_RESAMPLING")->asGrid_Resampling();
685 }
686
687 m_Bands.bOverlay = m_pSymbology->Get_Mode() == CSG_Map_Symbology::COMPOSITE;
688 m_Bands.bBandStatistics = m_Parameters("COMPOSITE_FIT")->asInt() != 0;
689
690 m_Bands.Set_Bands(m_pSymbology->Get_Mode() != CSG_Map_Symbology::COMPOSITE ? Get_Grid() : Get_Grid(0), Get_Grid(1), Get_Grid(2));
691
692 //-----------------------------------------------------
693 if( dc_Map.DC2World() >= m_pObject->asGrids()->Get_Cellsize() || m_Bands.Resampling != CSG_Grid_Resampling::NearestNeighbour )
694 {
695 _Draw_Points(dc_Map);
696 }
697 else
698 {
699 _Draw_Cells (dc_Map);
700 }
701
702 //-----------------------------------------------------
703 dc_Map.Draw_Image_End();
704}
705
706//---------------------------------------------------------
707void CSG_Map_Grids::_Draw_Cells(CSG_Map_DC &dc_Map)
708{
709 int xa = m_pObject->asGrids()->Get_System().Get_xWorld_to_Grid(dc_Map.rWorld().Get_XMin()); if( xa < 0 ) { xa = 0; }
710 int xb = m_pObject->asGrids()->Get_System().Get_xWorld_to_Grid(dc_Map.rWorld().Get_XMax()); if( xb >= m_pObject->asGrids()->Get_NX() ) { xb = m_pObject->asGrids()->Get_NX() - 1; }
711 int ya = m_pObject->asGrids()->Get_System().Get_yWorld_to_Grid(dc_Map.rWorld().Get_YMin()); if( ya < 0 ) { ya = 0; }
712 int yb = m_pObject->asGrids()->Get_System().Get_yWorld_to_Grid(dc_Map.rWorld().Get_YMax()); if( yb >= m_pObject->asGrids()->Get_NY() ) { yb = m_pObject->asGrids()->Get_NY() - 1; }
713
714 double dDC = m_pObject->asGrids()->Get_Cellsize() * dc_Map.World2DC();
715
716 double axDC = dc_Map.xWorld2DC(m_pObject->asGrids()->Get_System().Get_xGrid_to_World(xa)) + dDC / 2.;
717 double ayDC = dc_Map.yWorld2DC(m_pObject->asGrids()->Get_System().Get_yGrid_to_World(ya)) - dDC / 2.;
718
719 //-----------------------------------------------------
720 double yDC = ayDC;
721
722 for(int y=ya, yaDC=(int)(ayDC), ybDC=(int)(ayDC+dDC); y<=yb; y++, ybDC=yaDC, yaDC=(int)(yDC-=dDC))
723 {
724 double xDC = axDC; int Color;
725
726 for(int x=xa, xaDC=(int)(axDC-dDC), xbDC=(int)(axDC); x<=xb; x++, xaDC=xbDC, xbDC=(int)(xDC+=dDC))
727 {
728 if( _Draw_Get_Color(Color, x, y) )
729 {
730 if( m_Alpha.is_Okay() )
731 {
732 m_Alpha.Set_Alpha(Color, m_pObject->asGrids()->Get_System(), x, y);
733 }
734
735 dc_Map.Draw_Image_Pixels(xaDC, yaDC, xbDC, ybDC, Color);
736 }
737 }
738 }
739}
740
741//---------------------------------------------------------
742void CSG_Map_Grids::_Draw_Points(CSG_Map_DC &dc_Map)
743{
744 CSG_Rect rMap(dc_Map.rWorld()); rMap.Intersect(m_pObject->asGrids()->Get_Extent(true));
745
746 int axDC = (int)dc_Map.xWorld2DC(rMap.Get_XMin()); if( axDC < 0 ) { axDC = 0; }
747 int bxDC = (int)dc_Map.xWorld2DC(rMap.Get_XMax()); if( bxDC >= dc_Map.rDC().GetWidth () ) { bxDC = dc_Map.rDC().GetWidth () - 1; }
748 int byDC = (int)dc_Map.yWorld2DC(rMap.Get_YMax()); if( byDC < 0 ) { byDC = 0; }
749 int ayDC = (int)dc_Map.yWorld2DC(rMap.Get_YMin()); if( ayDC >= dc_Map.rDC().GetHeight() ) { ayDC = dc_Map.rDC().GetHeight() - 1; }
750
751 int nyDC = abs(ayDC - byDC);
752
753 #pragma omp parallel for
754 for(int iyDC=0; iyDC<=nyDC; iyDC++)
755 {
756 int Color, yDC = ayDC - iyDC; CSG_Point Point(dc_Map.xDC2World(axDC), dc_Map.yDC2World(yDC));
757
758 for(int xDC=axDC; xDC<=bxDC; Point.x+=dc_Map.DC2World(), xDC++)
759 {
760 if( _Draw_Get_Color(Color, Point) )
761 {
762 if( m_Alpha.is_Okay() )
763 {
764 m_Alpha.Set_Alpha(Color, Point.x, Point.y);
765 }
766
767 dc_Map.Draw_Image_Pixel(xDC, yDC, Color);
768 }
769 }
770 }
771}
772
773//---------------------------------------------------------
774inline bool CSG_Map_Grids::_Draw_Get_Color(int &Color, int x, int y)
775{
776 if( !m_Bands.bOverlay )
777 {
778 return( m_Bands[0]->is_InGrid(x, y) && m_pSymbology->Get_Class_Color_byValue(m_Bands[0]->asDouble(x, y), Color) );
779 }
780
781 for(int i=0; i<3; i++)
782 {
783 if( m_Bands[i] == NULL )
784 {
785 ((BYTE *)&Color)[i] = 0;
786 }
787 else
788 {
789 double Value;
790
791 if( m_Bands[i]->Get_System() == m_pObject->asGrids()->Get_System() )
792 {
793 if( !m_Bands[i]->is_InGrid(x, y) )
794 {
795 return( false );
796 }
797
798 Value = m_Bands[i]->asDouble(x, y);
799 }
800 else if( !m_Bands[i]->Get_Value(m_pObject->asGrids()->Get_System().Get_Grid_to_World(x, y), Value, m_Bands.Resampling))
801 {
802 return( false );
803 }
804
805 Value = 255. * (m_Bands.bBandStatistics ? m_Stretch[i].to_Relative(Value) : m_pSymbology->Get_Stretch_to_Relative(Value));
806
807 ((BYTE *)&Color)[i] = Value <= 0. ? 0 : Value >= 255. ? 255 : (BYTE)Value;
808 }
809 }
810
811 return( true );
812}
813
814//---------------------------------------------------------
815inline bool CSG_Map_Grids::_Draw_Get_Color(int &Color, const CSG_Point &Point)
816{
817 double Value;
818
819 if( !m_Bands.bOverlay )
820 {
821 return( m_Bands.pBands[0]->Get_Value(Point, Value, m_Bands.Resampling, false) && m_pSymbology->Get_Class_Color_byValue(Value, Color) );
822 }
823
824 for(int i=0; i<3; i++)
825 {
826 if( m_Bands[i] == NULL )
827 {
828 ((BYTE *)&Color)[i] = 0;
829 }
830 else
831 {
832 if( !m_Bands[i]->Get_Value(Point, Value, m_Bands.Resampling, false) )
833 {
834 return( false );
835 }
836
837 Value = 255. * (m_Bands.bBandStatistics ? m_Stretch[i].to_Relative(Value) : m_pSymbology->Get_Stretch_to_Relative(Value));
838
839 ((BYTE *)&Color)[i] = Value <= 0. ? 0 : Value >= 255. ? 255 : (BYTE)Value;
840 }
841 }
842
843 return( true );
844}
845
846
848// //
849// //
850// //
852
853//---------------------------------------------------------
bool SG_UI_Process_Set_Busy(bool bOn, const CSG_String &Message)
#define SG_GET_RGBA(r, g, b, a)
Definition api_core.h:1346
@ SG_DATATYPE_Int
Definition api_core.h:1050
#define SG_GET_RGB(r, g, b)
Definition api_core.h:1345
#define _TL(s)
Definition api_core.h:1619
const SG_Char * Get_Name(void) const
class CSG_Grids * asGrids(bool bPolymorph=false) const
class CSG_Grid * asGrid(bool bPolymorph=false) const
int Get_xWorld_to_Grid(double xWorld) const
Definition grid.h:318
int Get_NY(void) const
Definition grid.h:564
double Get_Max(void)
Definition grid.cpp:1027
const CSG_Simple_Statistics & Get_Statistics(void)
Definition grid.cpp:1099
const CSG_Histogram & Get_Histogram(size_t nClasses=0)
Definition grid.cpp:1175
double Get_Min(void)
Definition grid.cpp:1022
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
const CSG_Grid_System & Get_System(void) const
Definition grids.h:184
const CSG_Simple_Statistics & Get_Statistics(void)
Definition grids.cpp:1544
const CSG_Histogram & Get_Histogram(size_t nClasses=0)
Definition grids.cpp:1644
double Get_Quantile(double Quantile) const
bool Get_Image(wxImage &Image)
Definition map_dc.cpp:208
double yDC2World(double y)
Definition map_dc.h:161
bool Draw_Image_Begin(double Transparency, Mode Mode=Mode::Transparent)
Definition map_dc.cpp:374
double yWorld2DC(double y, bool bRound=true)
Definition map_dc.h:147
double xDC2World(double x)
Definition map_dc.h:156
const CSG_Rect & rWorld(void) const
Definition map_dc.h:124
double xWorld2DC(double x, bool bRound=true)
Definition map_dc.h:140
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
void Draw_Image_Pixel(int x, int y, int Color)
Definition map_dc.h:186
wxBitmap Get_Bitmap(void)
Definition map_dc.cpp:171
bool Draw_Image_End(void)
Definition map_dc.cpp:418
const double & DC2World(void) const
Definition map_dc.h:154
const double & World2DC(void) const
Definition map_dc.h:131
virtual bool Parameter_Changed(CSG_Parameters &Parameters, CSG_Parameter &Parameter, int Flags)
virtual bool Set_Stretch_Extent(const CSG_Rect &Extent)
CSG_String Get_Grid_Name(int Band, int Style=SG_GRIDS_NAME_GRID)
virtual bool Get_Bitmap_Legend(wxBitmap &Bitmap, double Zoom)
virtual bool Add_Parameters(CSG_Parameters &Parameters)
Definition map_grids.cpp:79
virtual bool Get_Bitmap(wxBitmap &Bitmap, bool bFitSize=true, int Width=0, int Height=0)
CSG_Map_Grids(CSG_Grids *pGrids=NULL)
Definition map_grids.cpp:65
virtual bool Parameters_Changed(void)
bool Set_Grid_Choices(CSG_Parameters &Parameters, int NameField=-1)
CSG_Grid * Get_Grid(void)
virtual bool DataObject_Changed(void)
virtual bool Get_Image(wxImage &Image, bool bFitSize=true, int Width=0, int Height=0)
virtual void On_Draw(CSG_Map_DC &dc_Map, int Flags)
virtual bool asImage(CSG_Grid *pImage)
class CSG_Map_Legend * Get_Legend(void)
Definition map_layer.h:137
virtual bool Parameters_Changed(void)
bool Classify(const CSG_MetaData &Options)
virtual bool DataObject_Changed(void)
virtual bool Parameter_Changed(CSG_Parameters &Parameters, CSG_Parameter &Parameter, int Flags)
CSG_Data_Object * m_pObject
Definition map_layer.h:151
bool Set_Stretch(CSG_Parameters &Parameters, CSG_Data_Object *pObject=NULL, const CSG_String &Suffix="")
bool Set_Stretch_Range(double Minimum, double Maximum)
bool Set_Object(CSG_Data_Object *pObject)
CSG_Rect Get_Extent(void) const
CSG_Parameters m_Parameters
Definition map_layer.h:149
class CSG_Map_Symbology * m_pSymbology
Definition map_layer.h:153
virtual bool Add_Parameters(CSG_Parameters &Parameters)
CSG_Map_Layer(void)
Definition map_layer.h:90
void Draw(wxDC &dc, double Zoom, double Zoom_Map, wxPoint Position, wxSize *pSize=NULL)
bool Set_Children_Enabled(bool bEnabled=true)
CSG_Grid * asGrid(void) const
bool Cmp_Identifier(const CSG_String &Identifier) const
int asInt(void) const
Definition parameters.h:287
CSG_Parameter * Add_Grid_Resampling(const CSG_String &ParentID, const CSG_String &ID, const CSG_String &Name, const CSG_String &Description, CSG_Grid_Resampling Methods=CSG_Grid_Resampling::Interpolations, CSG_Grid_Resampling Default=CSG_Grid_Resampling::Bicubic_2)
int Get_Count(void) const
void Set_Enabled(bool bEnabled=true)
CSG_Parameter * Add_Double(const CSG_String &ParentID, const CSG_String &ID, const CSG_String &Name, const CSG_String &Description, double Value=0.0, double Minimum=0.0, bool bMinimum=false, double Maximum=0.0, bool bMaximum=false)
bool Set_Parameter(const CSG_String &ID, CSG_Parameter *pValue)
CSG_Parameter * Add_Grid(const CSG_String &ParentID, const CSG_String &ID, const CSG_String &Name, const CSG_String &Description, int Constraint, bool bSystem_Dependent=true, TSG_Data_Type Preferred_Type=SG_DATATYPE_Undefined)
double Get_XMax(void) const
Definition geo_tools.h:506
double Get_XMin(void) const
Definition geo_tools.h:505
double Get_YMin(void) const
Definition geo_tools.h:507
double Get_YMax(void) const
Definition geo_tools.h:508
double Get_Maximum(void)
Definition mat_tools.h:749
double Get_Mean(void)
Definition mat_tools.h:753
double Get_StdDev(void)
Definition mat_tools.h:755
double Get_Minimum(void)
Definition mat_tools.h:748
double Get_Range(void)
Definition mat_tools.h:750
static CSG_String Format(const char *Format,...)
bool Create(const class wxString *pString)
@ SG_DATAOBJECT_TYPE_Grids
Definition dataobject.h:119
@ INTERSECTION_None
Definition geo_tools.h:102
#define asDouble(i)
#define PARAMETER_CHECK_ENABLE
Definition parameters.h:191
#define PARAMETER_CHECK_VALUES
Definition parameters.h:190
#define PARAMETER_INPUT_OPTIONAL
Definition parameters.h:103
#define PARAMETER_INPUT
Definition parameters.h:94