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_Grid.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/dc.h>
52 #include <wx/dcmemory.h>
53 #include <wx/image.h>
54 #include <wx/filename.h>
55 #include <wx/clipbrd.h>
56
57 #include <saga_gdi/sgdi_helper.h>
58
59 #include "res_commands.h"
60 #include "res_dialogs.h"
61
62 #include "helper.h"
63
64 #include "active.h"
65 #include "active_attributes.h"
66
67 #include "wksp_map_control.h"
68
69 #include "wksp_layer_classify.h"
70 #include "wksp_layer_legend.h"
71
72 #include "wksp_data_manager.h"
73 #include "wksp_grid_manager.h"
74 #include "wksp_grid.h"
75 #include "wksp_grids.h"
76
77 #include "data_source_pgsql.h"
78
79
80 ///////////////////////////////////////////////////////////
81 // //
82 // //
83 // //
84 ///////////////////////////////////////////////////////////
85
86 //---------------------------------------------------------
CWKSP_Grid(CSG_Grid * pGrid)87 CWKSP_Grid::CWKSP_Grid(CSG_Grid *pGrid)
88 : CWKSP_Layer(pGrid)
89 {
90 m_Edit_Attributes.Add_Field("ROW", SG_DATATYPE_Int);
91
92 On_Create_Parameters();
93
94 DataObject_Changed();
95 }
96
97
98 ///////////////////////////////////////////////////////////
99 // //
100 ///////////////////////////////////////////////////////////
101
102 //---------------------------------------------------------
Get_Description(void)103 wxString CWKSP_Grid::Get_Description(void)
104 {
105 wxString s;
106
107 //-----------------------------------------------------
108 s += wxString::Format("<h4>%s</h4>", _TL("Grid"));
109
110 s += "<table border=\"0\">";
111
112 DESC_ADD_STR (_TL("Name" ), m_pObject->Get_Name());
113 DESC_ADD_STR (_TL("Description" ), m_pObject->Get_Description());
114
115 if( SG_File_Exists(m_pObject->Get_File_Name(false)) )
116 {
117 DESC_ADD_STR (_TL("File" ), m_pObject->Get_File_Name(false));
118
119 if( m_pObject->Get_MetaData()("GDAL_DRIVER") )
120 DESC_ADD_STR (_TL("Driver" ), m_pObject->Get_MetaData()["GDAL_DRIVER"].Get_Content().c_str());
121
122 if( m_pObject->Get_MetaData()("SURFER_GRID") )
123 DESC_ADD_STR (_TL("Driver" ), m_pObject->Get_MetaData()["SURFER_GRID"].Get_Content().c_str());
124 }
125 else if( m_pObject->Get_MetaData_DB().Get_Children_Count() )
126 {
127 DESC_ADD_STR(_TL("File" ), m_pObject->Get_File_Name(false));
128 //const CSG_MetaData &DB = m_pObject->Get_MetaData_DB();
129 //if( DB("DBMS") ) DESC_ADD_STR (_TL("DBMS" ), DB["DBMS"].Get_Content().c_str());
130 //if( DB("HOST") ) DESC_ADD_STR (_TL("Host" ), DB["DBMS"].Get_Content().c_str());
131 //if( DB("PORT") ) DESC_ADD_STR (_TL("Port" ), DB["DBMS"].Get_Content().c_str());
132 //if( DB("NAME") ) DESC_ADD_STR (_TL("Database"), DB["NAME"].Get_Content().c_str());
133 }
134 else
135 {
136 DESC_ADD_STR (_TL("File" ), _TL("memory"));
137 }
138
139 DESC_ADD_STR (_TL("Modified" ), m_pObject->is_Modified() ? _TL("yes") : _TL("no"));
140 DESC_ADD_STR (_TL("Projection" ), m_pObject->Get_Projection().Get_Description().c_str());
141 DESC_ADD_STR (_TL("West" ), SG_Get_String(Get_Grid()->Get_XMin (), -CSG_Grid_System::Get_Precision()).c_str());
142 DESC_ADD_STR (_TL("East" ), SG_Get_String(Get_Grid()->Get_XMax (), -CSG_Grid_System::Get_Precision()).c_str());
143 DESC_ADD_STR (_TL("West-East" ), SG_Get_String(Get_Grid()->Get_XRange (), -CSG_Grid_System::Get_Precision()).c_str());
144 DESC_ADD_STR (_TL("South" ), SG_Get_String(Get_Grid()->Get_YMin (), -CSG_Grid_System::Get_Precision()).c_str());
145 DESC_ADD_STR (_TL("North" ), SG_Get_String(Get_Grid()->Get_YMax (), -CSG_Grid_System::Get_Precision()).c_str());
146 DESC_ADD_STR (_TL("South-North" ), SG_Get_String(Get_Grid()->Get_YRange (), -CSG_Grid_System::Get_Precision()).c_str());
147 DESC_ADD_STR (_TL("Cell Size" ), SG_Get_String(Get_Grid()->Get_Cellsize (), -CSG_Grid_System::Get_Precision()).c_str());
148 DESC_ADD_INT (_TL("Number of Columns" ), Get_Grid()->Get_NX ());
149 DESC_ADD_INT (_TL("Number of Rows" ), Get_Grid()->Get_NY ());
150 DESC_ADD_LONG(_TL("Number of Cells" ), Get_Grid()->Get_NCells ());
151 DESC_ADD_LONG(_TL("No Data Cells" ), Get_Grid()->Get_NoData_Count());
152 DESC_ADD_STR (_TL("Value Type" ), SG_Data_Type_Get_Name(Get_Grid()->Get_Type()).c_str());
153 DESC_ADD_FLT (_TL("Value Minimum" ), Get_Grid()->Get_Min ());
154 DESC_ADD_FLT (_TL("Value Maximum" ), Get_Grid()->Get_Max ());
155 DESC_ADD_FLT (_TL("Value Range" ), Get_Grid()->Get_Range ());
156 DESC_ADD_STR (_TL("No Data Value" ), Get_Grid()->Get_NoData_Value() < Get_Grid()->Get_NoData_Value(true) ? CSG_String::Format("%f - %f", Get_Grid()->Get_NoData_Value(), Get_Grid()->Get_NoData_Value(true)).c_str() : SG_Get_String(Get_Grid()->Get_NoData_Value(), -2).c_str());
157 DESC_ADD_FLT (_TL("Arithmetic Mean" ), Get_Grid()->Get_Mean ());
158 DESC_ADD_FLT (_TL("Standard Deviation"), Get_Grid()->Get_StdDev ());
159 DESC_ADD_STR (_TL("Memory Size" ), Get_nBytes_asString(Get_Grid()->Get_Memory_Size(), 2).c_str());
160
161 if( Get_Grid()->is_Cached() )
162 {
163 DESC_ADD_STR(_TL("File Cache" ), _TL("activated"));
164 }
165
166 s += "</table>";
167
168 //-----------------------------------------------------
169 // s.Append(wxString::Format(wxT("<hr><b>%s</b><font size=\"-1\">"), _TL("Data History")));
170 // s.Append(Get_Grid()->Get_History().Get_HTML());
171 // s.Append(wxString::Format(wxT("</font")));
172
173 return( s );
174 }
175
176 //---------------------------------------------------------
Get_Menu(void)177 wxMenu * CWKSP_Grid::Get_Menu(void)
178 {
179 wxMenu *pMenu = new wxMenu(m_pObject->Get_Name());
180
181 CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_CLOSE);
182 CMD_Menu_Add_Item(pMenu, false, ID_CMD_GRID_SHOW);
183
184 pMenu->AppendSeparator();
185 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVE);
186 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVEAS);
187
188 if( PGSQL_has_Connections() )
189 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVETODB);
190
191 CMD_Menu_Add_Item(pMenu, false, ID_CMD_GRID_SAVEAS_IMAGE);
192 CMD_Menu_Add_Item(pMenu, false, ID_CMD_GRID_CLIPBOARD_IMAGE);
193
194 if( m_pObject->is_File_Native() && m_pObject->is_Modified() )
195 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_RELOAD);
196
197 if( m_pObject->is_File_Native() )
198 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_DEL_FILES);
199
200 pMenu->AppendSeparator();
201 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECTION);
202
203 if( m_pObject->Get_MetaData().Get_Children_Count() > 0 )
204 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_METADATA);
205
206 pMenu->AppendSeparator();
207 CMD_Menu_Add_Item(pMenu, true , ID_CMD_GRID_HISTOGRAM);
208 CMD_Menu_Add_Item(pMenu, false, ID_CMD_GRID_SCATTERPLOT);
209 CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_FORCE_UPDATE);
210
211 pMenu->AppendSeparator();
212 CMD_Menu_Add_Item(pMenu, false, ID_CMD_GRID_SET_LUT);
213 CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SETTINGS_COPY);
214
215 return( pMenu );
216 }
217
218
219 ///////////////////////////////////////////////////////////
220 // //
221 ///////////////////////////////////////////////////////////
222
223 //---------------------------------------------------------
On_Command(int Cmd_ID)224 bool CWKSP_Grid::On_Command(int Cmd_ID)
225 {
226 switch( Cmd_ID )
227 {
228 default:
229 return( CWKSP_Layer::On_Command(Cmd_ID) );
230
231 case ID_CMD_GRID_SAVEAS_IMAGE:
232 _Save_Image();
233 break;
234
235 case ID_CMD_GRID_CLIPBOARD_IMAGE:
236 _Save_Image_Clipboard();
237 break;
238
239 case ID_CMD_GRID_HISTOGRAM:
240 Histogram_Toggle();
241 break;
242
243 case ID_CMD_GRID_SCATTERPLOT:
244 Add_ScatterPlot();
245 break;
246
247 case ID_CMD_GRID_SET_LUT:
248 _LUT_Create();
249 break;
250
251 case ID_CMD_GRID_SEL_CLEAR:
252 _Edit_Clr_Selection();
253 break;
254
255 case ID_CMD_GRID_SEL_DELETE:
256 _Edit_Del_Selection();
257 break;
258 }
259
260 return( true );
261 }
262
263 //---------------------------------------------------------
On_Command_UI(wxUpdateUIEvent & event)264 bool CWKSP_Grid::On_Command_UI(wxUpdateUIEvent &event)
265 {
266 switch( event.GetId() )
267 {
268 default:
269 return( CWKSP_Layer::On_Command_UI(event) );
270
271 case ID_CMD_GRID_SEL_CLEAR:
272 event.Enable(m_Edit_Attributes.Get_Count() > 0);
273 break;
274
275 case ID_CMD_GRID_SEL_DELETE:
276 event.Enable(m_Edit_Attributes.Get_Count() > 0);
277 break;
278
279 case ID_CMD_GRID_HISTOGRAM:
280 event.Check(m_pHistogram != NULL);
281 break;
282 }
283
284 return( true );
285 }
286
287
288 ///////////////////////////////////////////////////////////
289 // //
290 ///////////////////////////////////////////////////////////
291
292 //---------------------------------------------------------
On_Create_Parameters(void)293 void CWKSP_Grid::On_Create_Parameters(void)
294 {
295 CWKSP_Layer::On_Create_Parameters();
296
297 //-----------------------------------------------------
298 // General...
299
300 m_Parameters.Add_String("NODE_GENERAL", "OBJECT_Z_UNIT" , _TL("Unit" ), _TL(""), Get_Grid()->Get_Unit ());
301 m_Parameters.Add_Double("NODE_GENERAL", "OBJECT_Z_FACTOR", _TL("Z-Scale" ), _TL(""), Get_Grid()->Get_Scaling());
302 m_Parameters.Add_Double("NODE_GENERAL", "OBJECT_Z_OFFSET", _TL("Z-Offset"), _TL(""), Get_Grid()->Get_Offset ());
303
304 //-----------------------------------------------------
305 // Resampling...
306
307 m_Parameters.Add_Choice("NODE_DISPLAY", "DISPLAY_RESAMPLING", _TL("Resampling"),
308 _TL(""),
309 CSG_String::Format("%s|%s|%s|%s",
310 _TL("Nearest Neighbour"),
311 _TL("Bilinear Interpolation"),
312 _TL("Bicubic Spline Interpolation"),
313 _TL("B-Spline Interpolation")
314 ), 0
315 );
316
317 //-----------------------------------------------------
318 // Transparency...
319
320 m_Parameters.Add_Grid("DISPLAY_TRANSPARENCY", "DISPLAY_ALPHA", _TL("Alpha Channel"),
321 _TL("Alpha channel values are adjusted to the specified range minimum (full transparency) and maximum (full opacity)"),
322 PARAMETER_INPUT_OPTIONAL, false
323 )->Get_Parent()->Set_Value((void *)&Get_Grid()->Get_System());
324
325 m_Parameters.Add_Range("DISPLAY_ALPHA", "ALPHA_RANGE", _TL("Adjustment"),
326 _TL(""),
327 0., 255.
328 );
329
330 //-----------------------------------------------------
331 // Shading...
332
333 m_Parameters.Add_Choice("NODE_DISPLAY", "DISPLAY_SHADING" , _TL("Shading"),
334 _TL(""),
335 CSG_String::Format("%s|%s|%s",
336 _TL("none"), _TL("normal"), _TL("inverse")
337 ), 0
338 );
339
340 m_Parameters.Add_Double("DISPLAY_SHADING", "SHADING_AZIMUTH", _TL("Azimuth"),
341 _TL("Direction of the light source, measured in degree clockwise from the North direction."),
342 315., 0., true, 360., true
343 );
344
345 m_Parameters.Add_Double("DISPLAY_SHADING", "SHADING_HEIGHT" , _TL("Height"),
346 _TL("Height of the light source, measured in degree above the horizon."),
347 45., 0., true, 90., true
348 );
349
350 m_Parameters.Add_Double("DISPLAY_SHADING", "SHADING_EXAGG" , _TL("Exaggeration"),
351 _TL(""),
352 1.
353 );
354
355 m_Parameters.Add_Double("DISPLAY_SHADING", "SHADING_MIN" , _TL("Minimum"),
356 _TL(""),
357 0.
358 );
359
360 m_Parameters.Add_Double("DISPLAY_SHADING", "SHADING_MAX" , _TL("Maximum"),
361 _TL(""),
362 1.5
363 );
364
365 //-----------------------------------------------------
366 // Classification...
367
368 m_Parameters.Add_Node("NODE_COLORS" , "NODE_SHADE" , _TL("Shade"),
369 _TL("")
370 );
371
372 m_Parameters.Add_Choice("NODE_SHADE", "SHADE_MODE" , _TL("Coloring"),
373 _TL(""),
374 CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s",
375 _TL("bright - dark" ),
376 _TL("dark - bright" ),
377 _TL("white - cyan" ),
378 _TL("cyan - white" ),
379 _TL("white - magenta"),
380 _TL("magenta - white"),
381 _TL("white - yellow" ),
382 _TL("yellow - white" )
383 ), 0
384 );
385
386 //-----------------------------------------------------
387 m_Parameters.Add_Bool("NODE_COLORS" , "RGB_ALPHA" , _TL("Alpha Channel"),
388 _TL(""),
389 false
390 );
391
392 //-----------------------------------------------------
393 m_Parameters.Add_Node("NODE_COLORS" , "NODE_OVERLAY" , _TL("RGB Composite"),
394 _TL("")
395 );
396
397 m_Parameters.Add_Choice("NODE_OVERLAY", "OVERLAY_MODE" , _TL("This Color"),
398 _TL(""),
399 CSG_String::Format("%s|%s|%s",
400 _TL("Red"), _TL("Green"), _TL("Blue")
401 ), 0
402 );
403
404 m_Parameters.Add_Grid("NODE_OVERLAY", "OVERLAY_R", _TL("Red" ), _TL(""), PARAMETER_INPUT_OPTIONAL, false)->Get_Parent()->Set_Value(
405 (void *)&Get_Grid()->Get_System()
406 );
407
408 m_Parameters.Add_Grid("NODE_OVERLAY", "OVERLAY_G", _TL("Green"), _TL(""), PARAMETER_INPUT_OPTIONAL, false)->Get_Parent()->Set_Value(
409 (void *)&Get_Grid()->Get_System()
410 );
411
412 m_Parameters.Add_Grid("NODE_OVERLAY", "OVERLAY_B", _TL("Blue" ), _TL(""), PARAMETER_INPUT_OPTIONAL, false)->Get_Parent()->Set_Value(
413 (void *)&Get_Grid()->Get_System()
414 );
415
416 //-----------------------------------------------------
417 // Cell Values...
418
419 m_Parameters.Add_Bool("NODE_GENERAL", "VALUES_SHOW" , _TL("Show Cell Values"),
420 _TL("shows cell values when zoomed"),
421 false
422 );
423
424 m_Parameters.Add_Font("VALUES_SHOW", "VALUES_FONT" , _TL("Font"),
425 _TL("")
426 );
427
428 m_Parameters.Add_Double("VALUES_SHOW", "VALUES_SIZE" , _TL("Size"),
429 _TL(""),
430 15, 0, true , 100., true
431 );
432
433 m_Parameters.Add_Int("VALUES_SHOW", "VALUES_DECIMALS" , _TL("Decimals"),
434 _TL(""),
435 2
436 );
437
438 m_Parameters.Add_Choice("VALUES_SHOW", "VALUES_EFFECT" , _TL("Boundary Effect"),
439 _TL(""),
440 CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
441 _TL("none" ),
442 _TL("full frame" ),
443 _TL("top" ),
444 _TL("top left" ),
445 _TL("left" ),
446 _TL("bottom left" ),
447 _TL("bottom" ),
448 _TL("bottom right"),
449 _TL("right" ),
450 _TL("top right" )
451 ), 1
452 );
453
454 m_Parameters.Add_Color("VALUES_EFFECT", "VALUES_EFFECT_COLOR", _TL("Color"),
455 _TL(""),
456 SG_GET_RGB(255, 255, 255)
457 );
458
459 //-----------------------------------------------------
460 // Memory...
461
462 m_Parameters.Add_Double("NODE_GENERAL",
463 "MAX_SAMPLES" , _TL("Maximum Samples"),
464 _TL("Maximum number of samples used to build statistics and histograms expressed as percent of the total number of cells."),
465 100. * (double)Get_Grid()->Get_Max_Samples() / (double)Get_Grid()->Get_NCells(), 0., true, 100., true
466 );
467
468 m_Parameters.Add_Bool("NODE_GENERAL",
469 "FILE_CACHE" , _TL("File Cache"),
470 _TL(""),
471 Get_Grid()->is_Cached()
472 );
473
474 //-----------------------------------------------------
475 m_Fit_Colors = g_pData->Get_Parameter("GRID_STRETCH_DEFAULT")->asInt();
476 }
477
478
479 ///////////////////////////////////////////////////////////
480 // //
481 ///////////////////////////////////////////////////////////
482
483 //---------------------------------------------------------
On_DataObject_Changed(void)484 void CWKSP_Grid::On_DataObject_Changed(void)
485 {
486 //-----------------------------------------------------
487 m_Parameters.Set_Parameter("OBJECT_Z_UNIT" , Get_Grid()->Get_Unit ());
488 m_Parameters.Set_Parameter("OBJECT_Z_FACTOR", Get_Grid()->Get_Scaling());
489 m_Parameters.Set_Parameter("OBJECT_Z_OFFSET", Get_Grid()->Get_Offset ());
490
491 m_Parameters.Set_Parameter("MAX_SAMPLES" , 100. * Get_Grid()->Get_Max_Samples() / (double)Get_Grid()->Get_NCells());
492
493 m_Parameters.Set_Parameter("FILE_CACHE" , Get_Grid()->is_Cached ());
494
495 //-----------------------------------------------------
496 if( m_Parameters("STRETCH_UPDATE")->asBool() == false ) // internal update flag, set by CSG_Tool::DataObject_Update()
497 {
498 m_Parameters.Set_Parameter("STRETCH_UPDATE", true);
499 }
500 else if( m_Parameters("STRETCH_DEFAULT")->asInt() >= 3 ) // manual
501 {
502 m_Parameters.Set_Parameter("STRETCH_DEFAULT", m_Fit_Colors);
503 }
504
505 //-----------------------------------------------------
506 CWKSP_Layer::On_DataObject_Changed();
507 }
508
509 //---------------------------------------------------------
On_Parameters_Changed(void)510 void CWKSP_Grid::On_Parameters_Changed(void)
511 {
512 CWKSP_Layer::On_Parameters_Changed();
513
514 //-----------------------------------------------------
515 Get_Grid()->Set_Unit (m_Parameters("OBJECT_Z_UNIT" )->asString());
516 Get_Grid()->Set_Scaling(m_Parameters("OBJECT_Z_FACTOR")->asDouble(),
517 m_Parameters("OBJECT_Z_OFFSET")->asDouble());
518
519 Get_Grid()->Set_Max_Samples(Get_Grid()->Get_NCells() * (m_Parameters("MAX_SAMPLES")->asDouble() / 100.) );
520
521 Get_Grid()->Set_Cache(m_Parameters("FILE_CACHE")->asBool());
522
523 m_pClassify->Set_Shade_Mode(m_Parameters("SHADE_MODE")->asInt());
524
525 //-----------------------------------------------------
526 if( m_Parameters("STRETCH_DEFAULT")->asInt() < 3 ) // not manual, remember last state...
527 {
528 m_Fit_Colors = m_Parameters("STRETCH_DEFAULT")->asInt();
529 }
530 }
531
532 //---------------------------------------------------------
Update(CWKSP_Layer * pChanged)533 bool CWKSP_Grid::Update(CWKSP_Layer *pChanged)
534 {
535 if( pChanged )
536 {
537 if( pChanged == this )
538 {
539 return( true );
540 }
541
542 if( pChanged->Get_Type() == WKSP_ITEM_Grid )
543 {
544 CSG_Grid *pGrid = ((CWKSP_Grid *)pChanged)->Get_Grid();
545
546 return( (m_Parameters("OVERLAY_R")->is_Enabled() && pGrid == m_Parameters("OVERLAY_R")->asGrid())
547 || (m_Parameters("OVERLAY_G")->is_Enabled() && pGrid == m_Parameters("OVERLAY_G")->asGrid())
548 || (m_Parameters("OVERLAY_B")->is_Enabled() && pGrid == m_Parameters("OVERLAY_B")->asGrid())
549 );
550 }
551
552 if( pChanged->Get_Type() == WKSP_ITEM_Grids )
553 {
554 CSG_Grids *pGrids = ((CWKSP_Grids *)pChanged)->Get_Grids();
555
556 return( (m_Parameters("OVERLAY_R")->is_Enabled() && m_Parameters("OVERLAY_R")->asGrid() && pGrids == m_Parameters("OVERLAY_R")->asGrid()->Get_Owner())
557 || (m_Parameters("OVERLAY_G")->is_Enabled() && m_Parameters("OVERLAY_G")->asGrid() && pGrids == m_Parameters("OVERLAY_G")->asGrid()->Get_Owner())
558 || (m_Parameters("OVERLAY_B")->is_Enabled() && m_Parameters("OVERLAY_B")->asGrid() && pGrids == m_Parameters("OVERLAY_B")->asGrid()->Get_Owner())
559 );
560 }
561 }
562
563 return( false );
564 }
565
566
567 ///////////////////////////////////////////////////////////
568 // //
569 ///////////////////////////////////////////////////////////
570
571 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)572 int CWKSP_Grid::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
573 {
574 //-----------------------------------------------------
575 if( pParameters->Cmp_Identifier("CLASSIFY") )
576 {
577 if( Flags & PARAMETER_CHECK_ENABLE )
578 {
579 if( pParameter->Cmp_Identifier("METHOD") )
580 {
581 pParameters->Set_Enabled("COUNT" , pParameter->asInt() != 0);
582 pParameters->Set_Enabled("COUNTMAX", pParameter->asInt() == 0);
583 }
584 }
585
586 return( CWKSP_Layer::On_Parameter_Changed(pParameters, pParameter, Flags) );
587 }
588
589 //-----------------------------------------------------
590 if( Flags & PARAMETER_CHECK_VALUES )
591 {
592 if( pParameter->Cmp_Identifier("OBJECT_Z_FACTOR")
593 || pParameter->Cmp_Identifier("OBJECT_Z_OFFSET") )
594 {
595 double newFactor = (*pParameters)("OBJECT_Z_FACTOR")->asDouble(), oldFactor = m_Parameters("OBJECT_Z_FACTOR")->asDouble();
596 double newOffset = (*pParameters)("OBJECT_Z_OFFSET")->asDouble(), oldOffset = m_Parameters("OBJECT_Z_OFFSET")->asDouble();
597
598 if( newFactor != 0. && oldFactor != 0. )
599 {
600 CSG_Parameter_Range *newRange = (*pParameters)("METRIC_ZRANGE")->asRange();
601 CSG_Parameter_Range *oldRange = m_Parameters ("METRIC_ZRANGE")->asRange();
602
603 newRange->Set_Min(((oldRange->Get_Min() - oldOffset) / oldFactor) * newFactor + newOffset);
604 newRange->Set_Max(((oldRange->Get_Max() - oldOffset) / oldFactor) * newFactor + newOffset);
605 }
606 }
607 }
608
609 //-----------------------------------------------------
610 if( Flags & PARAMETER_CHECK_ENABLE )
611 {
612 if( pParameter->Cmp_Identifier("DISPLAY_SHADING") )
613 {
614 pParameters->Set_Enabled("SHADING_AZIMUTH" , pParameter->asInt() != 0);
615 pParameters->Set_Enabled("SHADING_HEIGHT" , pParameter->asInt() != 0);
616 pParameters->Set_Enabled("SHADING_EXAGG" , pParameter->asInt() != 0);
617 pParameters->Set_Enabled("SHADING_MIN" , pParameter->asInt() != 0);
618 pParameters->Set_Enabled("SHADING_MAX" , pParameter->asInt() != 0);
619 }
620
621 if( pParameter->Cmp_Identifier("COLORS_TYPE") )
622 {
623 int Value = pParameter->asInt();
624
625 pParameters->Set_Enabled("NODE_SINGLE" , Value == CLASSIFY_SINGLE );
626 pParameters->Set_Enabled("NODE_LUT" , Value == CLASSIFY_LUT );
627 pParameters->Set_Enabled("NODE_METRIC" , Value != CLASSIFY_SINGLE && Value != CLASSIFY_LUT);
628 pParameters->Set_Enabled("NODE_SHADE" , Value == CLASSIFY_SHADE );
629 pParameters->Set_Enabled("NODE_OVERLAY" , Value == CLASSIFY_OVERLAY);
630 pParameters->Set_Enabled("RGB_ALPHA" , Value == CLASSIFY_RGB );
631
632 pParameters->Set_Enabled("DISPLAY_RESAMPLING" , Value != CLASSIFY_LUT );
633 pParameters->Set_Enabled("DISPLAY_SHADING" , Value != CLASSIFY_SHADE );
634
635 pParameters->Set_Enabled("DISPLAY_ALPHA" , Value != CLASSIFY_RGB );
636 }
637
638 if( pParameter->Cmp_Identifier("DISPLAY_ALPHA") )
639 {
640 pParameters->Set_Enabled("ALPHA_RANGE" , pParameter->asGrid() != NULL);
641 }
642
643 if( pParameter->Cmp_Identifier("VALUES_SHOW") )
644 {
645 pParameters->Set_Enabled("VALUES_FONT" , pParameter->asBool());
646 pParameters->Set_Enabled("VALUES_SIZE" , pParameter->asBool());
647 pParameters->Set_Enabled("VALUES_DECIMALS" , pParameter->asBool());
648 pParameters->Set_Enabled("VALUES_EFFECT" , pParameter->asBool());
649 }
650
651 if( pParameter->Cmp_Identifier("VALUES_EFFECT") )
652 {
653 pParameters->Set_Enabled("VALUES_EFFECT_COLOR", pParameter->asInt() > 0);
654 }
655
656 if( pParameter->Cmp_Identifier("OVERLAY_MODE") )
657 {
658 (*pParameters)("OVERLAY_R")->Get_Parent()->Set_Enabled(pParameter->asInt() != 0);
659 (*pParameters)("OVERLAY_G")->Get_Parent()->Set_Enabled(pParameter->asInt() != 1);
660 (*pParameters)("OVERLAY_B")->Get_Parent()->Set_Enabled(pParameter->asInt() != 2);
661 }
662 }
663
664 return( CWKSP_Layer::On_Parameter_Changed(pParameters, pParameter, Flags) );
665 }
666
667
668 ///////////////////////////////////////////////////////////
669 // //
670 ///////////////////////////////////////////////////////////
671
672 //---------------------------------------------------------
_LUT_Create(void)673 void CWKSP_Grid::_LUT_Create(void)
674 {
675 //-----------------------------------------------------
676 static CSG_Parameters PStatic;
677
678 if( PStatic.Get_Count() == 0 )
679 {
680 PStatic.Create(_TL("Classify"));
681 PStatic.Add_Colors("", "COLORS" , _TL("Colors" ), _TL(""));
682 PStatic.Add_Int ("", "COUNT" , _TL("Number of Classes" ), _TL(""), 10, 1, true);
683 PStatic.Add_Int ("", "COUNTMAX", _TL("Maximum Number of Classes"), _TL(""), 1000, 1, true);
684 PStatic.Add_Choice("", "METHOD" , _TL("Classification" ), _TL(""),
685 CSG_String::Format("%s|%s|%s|%s",
686 _TL("unique values"),
687 _TL("equal intervals"),
688 _TL("quantiles"),
689 _TL("natural breaks")
690 ), 1
691 );
692 }
693
694 CSG_Parameters Parameters(_TL("Classify"), _TL(""), SG_T("CLASSIFY"));
695
696 Parameters.Assign_Parameters(&PStatic);
697
698 Parameters("COLORS")->asColors()->Assign(Get_Colors());
699
700 Parameters.Set_Callback_On_Parameter_Changed(&Parameter_Callback);
701
702 if( !DLG_Parameters(&Parameters) )
703 {
704 return;
705 }
706
707 PStatic.Assign_Values(&Parameters);
708
709 //-----------------------------------------------------
710 CSG_Colors Colors(*Parameters("COLORS")->asColors());
711
712 if( Parameters("METHOD")->asInt() != 0 )
713 {
714 Colors.Set_Count(Parameters("COUNT")->asInt());
715 }
716
717 CSG_Table Classes(m_Parameters("LUT")->asTable());
718
719 switch( Parameters("METHOD")->asInt() )
720 {
721 //-----------------------------------------------------
722 case 0: // unique values
723 {
724 CSG_Unique_Number_Statistics s;
725
726 int maxClasses = Parameters("COUNTMAX")->asInt();
727
728 for(sLong iCell = 0; iCell<Get_Grid()->Get_NCells() && s.Get_Count()<maxClasses && PROGRESSBAR_Set_Position(iCell, Get_Grid()->Get_NCells()); iCell++)
729 {
730 if( !Get_Grid()->is_NoData(iCell) )
731 {
732 s += Get_Grid()->asDouble(iCell);
733 }
734 }
735
736 Colors.Set_Count(s.Get_Count());
737
738 for(int iClass=0; iClass<s.Get_Count(); iClass++)
739 {
740 double Value = s.Get_Value(iClass);
741
742 CSG_String Name = SG_Get_String(Value, -2);
743
744 CSG_Table_Record *pClass = Classes.Add_Record();
745
746 pClass->Set_Value(0, Colors[iClass]); // Color
747 pClass->Set_Value(1, Name ); // Name
748 pClass->Set_Value(2, Name ); // Description
749 pClass->Set_Value(3, Value ); // Minimum
750 pClass->Set_Value(4, Value ); // Maximum
751 }
752
753 break;
754 }
755
756 //-----------------------------------------------------
757 case 1: // equal intervals
758 if( Get_Grid()->Get_Range() && Colors.Get_Count() > 0 )
759 {
760 double Minimum, Maximum, Interval;
761
762 Interval = Get_Grid()->Get_Range() / (double)Colors.Get_Count();
763 Minimum = Get_Grid()->Get_Min ();
764
765 for(int iClass=0; iClass<Colors.Get_Count(); iClass++, Minimum+=Interval)
766 {
767 Maximum = iClass < Colors.Get_Count() - 1 ? Minimum + Interval : Get_Grid()->Get_Max() + 1.;
768
769 CSG_String Name = SG_Get_String(Minimum, -2)
770 + " - " + SG_Get_String(Maximum, -2);
771
772 CSG_Table_Record *pClass = Classes.Add_Record();
773
774 pClass->Set_Value(0, Colors[iClass]); // Color
775 pClass->Set_Value(1, Name ); // Name
776 pClass->Set_Value(2, Name ); // Description
777 pClass->Set_Value(3, Minimum ); // Minimum
778 pClass->Set_Value(4, Maximum ); // Maximum
779 }
780 }
781 break;
782
783 //-----------------------------------------------------
784 case 2: // quantiles
785 {
786 if( Get_Grid()->Get_NCells() < Colors.Get_Count() )
787 {
788 Colors.Set_Count(Get_Grid()->Get_NCells());
789 }
790
791 double Minimum, Maximum = Get_Grid()->Get_Histogram().Get_Quantile(0.);
792
793 double Step = 1. / Colors.Get_Count();
794
795 for(int iClass=0; iClass<Colors.Get_Count(); iClass++)
796 {
797 Minimum = Maximum;
798 Maximum = Get_Grid()->Get_Histogram().Get_Quantile((1. + iClass) / Colors.Get_Count());
799
800 CSG_String Name = SG_Get_String(Minimum, -2)
801 + " - " + SG_Get_String(Maximum, -2);
802
803 CSG_Table_Record *pClass = Classes.Add_Record();
804
805 pClass->Set_Value(0, Colors[iClass]); // Color
806 pClass->Set_Value(1, Name ); // Name
807 pClass->Set_Value(2, Name ); // Description
808 pClass->Set_Value(3, Minimum ); // Minimum
809 pClass->Set_Value(4, Maximum ); // Maximum
810 }
811 }
812 break;
813
814 //-----------------------------------------------------
815 case 3: // natural breaks
816 {
817 CSG_Natural_Breaks Breaks(Get_Grid(), Colors.Get_Count(), 255);
818
819 if( Breaks.Get_Count() <= Colors.Get_Count() ) return;
820
821 for(int iClass=0; iClass<Colors.Get_Count(); iClass++)
822 {
823 CSG_Table_Record *pClass = Classes.Add_Record();
824
825 double Minimum = Breaks[iClass ];
826 double Maximum = Breaks[iClass + 1];
827
828 CSG_String Name = SG_Get_String(Minimum, -2)
829 + " - " + SG_Get_String(Maximum, -2);
830
831 pClass->Set_Value(0, Colors[iClass]); // Color
832 pClass->Set_Value(1, Name ); // Name
833 pClass->Set_Value(2, Name ); // Description
834 pClass->Set_Value(3, Minimum ); // Minimum
835 pClass->Set_Value(4, Maximum ); // Maximum
836 }
837 }
838 break;
839 }
840
841 //-----------------------------------------------------
842 PROGRESSBAR_Set_Position(0);
843
844 if( Classes.Get_Count() > 0 )
845 {
846 m_Parameters("LUT")->asTable()->Assign_Values(&Classes);
847
848 m_Parameters("COLORS_TYPE")->Set_Value(CLASSIFY_LUT); // Lookup Table
849
850 Parameters_Changed();
851 }
852 }
853
854
855 ///////////////////////////////////////////////////////////
856 // //
857 ///////////////////////////////////////////////////////////
858
859 //---------------------------------------------------------
Get_Value(CSG_Point ptWorld,double Epsilon)860 wxString CWKSP_Grid::Get_Value(CSG_Point ptWorld, double Epsilon)
861 {
862 wxString s; double Value;
863
864 if( Get_Grid()->Get_Value(ptWorld, Value, GRID_RESAMPLING_NearestNeighbour) )
865 {
866 switch( m_pClassify->Get_Mode() )
867 {
868 default:
869 s = SG_Get_String(Value, -12).c_str();
870
871 if( !Get_Grid()->Get_Unit().is_Empty() )
872 {
873 s += " "; s += Get_Grid()->Get_Unit().c_str();
874 }
875 break;
876
877 case CLASSIFY_RGB:
878 s.Printf("R%03d G%03d B%03d", SG_GET_R((int)Value), SG_GET_G((int)Value), SG_GET_B((int)Value));
879 break;
880
881 case CLASSIFY_LUT:
882 s = m_pClassify->Get_Class_Name_byValue(Value);
883 break;
884 }
885 }
886
887 return( s );
888 }
889
890
891 ///////////////////////////////////////////////////////////
892 // //
893 ///////////////////////////////////////////////////////////
894
895 //---------------------------------------------------------
Get_Value_Minimum(void)896 double CWKSP_Grid::Get_Value_Minimum(void) { return( ((CSG_Grid *)m_pObject)->Get_Min () ); }
Get_Value_Maximum(void)897 double CWKSP_Grid::Get_Value_Maximum(void) { return( ((CSG_Grid *)m_pObject)->Get_Max () ); }
Get_Value_Range(void)898 double CWKSP_Grid::Get_Value_Range (void) { return( ((CSG_Grid *)m_pObject)->Get_Range () ); }
Get_Value_Mean(void)899 double CWKSP_Grid::Get_Value_Mean (void) { return( ((CSG_Grid *)m_pObject)->Get_Mean () ); }
Get_Value_StdDev(void)900 double CWKSP_Grid::Get_Value_StdDev (void) { return( ((CSG_Grid *)m_pObject)->Get_StdDev() ); }
901
902
903 ///////////////////////////////////////////////////////////
904 // //
905 ///////////////////////////////////////////////////////////
906
907 //---------------------------------------------------------
Edit_Get_Menu(void)908 wxMenu * CWKSP_Grid::Edit_Get_Menu(void)
909 {
910 if( m_Edit_Attributes.Get_Count() < 1 )
911 {
912 return( NULL );
913 }
914
915 wxMenu *pMenu = new wxMenu;
916
917 CMD_Menu_Add_Item(pMenu, true , ID_CMD_GRID_SEL_CLEAR);
918 CMD_Menu_Add_Item(pMenu, true , ID_CMD_GRID_SEL_DELETE);
919
920 return( pMenu );
921 }
922
923 //---------------------------------------------------------
Edit_Get_Extent(void)924 TSG_Rect CWKSP_Grid::Edit_Get_Extent(void)
925 {
926 if( m_Edit_Attributes.Get_Count() > 0 )
927 {
928 return( CSG_Rect(
929 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_xGrid_to_World(m_xSel),
930 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_yGrid_to_World(m_ySel),
931 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_xGrid_to_World(m_xSel + m_Edit_Attributes.Get_Field_Count() - 1),
932 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_yGrid_to_World(m_ySel + m_Edit_Attributes.Get_Count()))
933 );
934 }
935
936 return( Get_Grid()->Get_Extent().m_rect );
937 }
938
939 //---------------------------------------------------------
Edit_On_Key_Down(int KeyCode)940 bool CWKSP_Grid::Edit_On_Key_Down(int KeyCode)
941 {
942 switch( KeyCode )
943 {
944 default:
945 return( false );
946
947 case WXK_DELETE:
948 return( _Edit_Del_Selection() );
949 }
950 }
951
952 //---------------------------------------------------------
Edit_On_Mouse_Up(CSG_Point Point,double ClientToWorld,int Key)953 bool CWKSP_Grid::Edit_On_Mouse_Up(CSG_Point Point, double ClientToWorld, int Key)
954 {
955 if( Key & TOOL_INTERACTIVE_KEY_LEFT )
956 {
957 g_pActive->Update_Attributes();
958
959 m_Edit_Attributes.Destroy();
960 m_Edit_Attributes.Add_Field("ROW", SG_DATATYPE_Int);
961
962 CSG_Rect rWorld(m_Edit_Mouse_Down, Point);
963
964 if( rWorld.Intersects(Get_Grid()->Get_Extent(true)) )
965 {
966 m_xSel = Get_Grid()->Get_System().Get_xWorld_to_Grid(rWorld.Get_XMin()); if( m_xSel < 0 ) m_xSel = 0;
967 int nx = Get_Grid()->Get_System().Get_xWorld_to_Grid(rWorld.Get_XMax()); if( nx >= Get_Grid()->Get_NX() ) nx = Get_Grid()->Get_NX() - 1;
968 nx = 1 + nx - m_xSel;
969
970 m_ySel = Get_Grid()->Get_System().Get_yWorld_to_Grid(rWorld.Get_YMin()); if( m_ySel < 0 ) m_ySel = 0;
971 int ny = Get_Grid()->Get_System().Get_yWorld_to_Grid(rWorld.Get_YMax()); if( ny >= Get_Grid()->Get_NY() ) ny = Get_Grid()->Get_NY() - 1;
972 ny = 1 + ny - m_ySel;
973
974 if( nx > 0 && ny > 0 )
975 {
976 int Maximum = g_pData->Get_Parameter("GRID_SELECT_MAX")->asInt();
977
978 if( nx > Maximum )
979 {
980 m_xSel += (nx - Maximum) / 2;
981 nx = Maximum;
982 }
983
984 if( ny > Maximum )
985 {
986 m_ySel += (ny - Maximum) / 2;
987 ny = Maximum;
988 }
989
990 for(int x=0; x<nx; x++)
991 {
992 m_Edit_Attributes.Add_Field(CSG_String::Format("%d", m_xSel + 1 + x), Get_Grid()->Get_Type());
993 }
994
995 for(int y=0; y<ny; y++)
996 {
997 CSG_Table_Record *pRecord = m_Edit_Attributes.Add_Record();
998
999 for(int x=0; x<nx; x++)
1000 {
1001 pRecord->Set_Value(0, m_ySel + ny - y);
1002
1003 if( !Get_Grid()->is_NoData(m_xSel + x, m_ySel + ny - 1 - y) )
1004 {
1005 pRecord->Set_Value(1 + x, Get_Grid()->asDouble(m_xSel + x, m_ySel + ny - 1 - y));
1006 }
1007 else
1008 {
1009 pRecord->Set_NoData(1 + x);
1010 }
1011 }
1012 }
1013 }
1014 }
1015
1016 g_pActive->Update_Attributes();
1017
1018 Update_Views();
1019
1020 return( true );
1021 }
1022
1023 return( false );
1024 }
1025
1026 //---------------------------------------------------------
Edit_Set_Attributes(void)1027 bool CWKSP_Grid::Edit_Set_Attributes(void)
1028 {
1029 if( m_Edit_Attributes.Get_Count() > 0 )
1030 {
1031 for(int y=0; y<m_Edit_Attributes.Get_Count(); y++)
1032 {
1033 CSG_Table_Record *pRecord = m_Edit_Attributes.Get_Record(m_Edit_Attributes.Get_Count() - 1 - y);
1034
1035 for(int x=0, xx=1; xx<m_Edit_Attributes.Get_Field_Count(); x++, xx++)
1036 {
1037 if( !pRecord->is_NoData(xx) )
1038 {
1039 Get_Grid()->Set_Value(m_xSel + x, m_ySel + y, pRecord->asDouble(xx));
1040 }
1041 else
1042 {
1043 Get_Grid()->Set_NoData(m_xSel + x, m_ySel + y);
1044 }
1045 }
1046 }
1047
1048 Update_Views();
1049
1050 return( true );
1051 }
1052
1053 return( false );
1054 }
1055
1056
1057 ///////////////////////////////////////////////////////////
1058 // //
1059 ///////////////////////////////////////////////////////////
1060
1061 //---------------------------------------------------------
_Edit_Clr_Selection(void)1062 bool CWKSP_Grid::_Edit_Clr_Selection(void)
1063 {
1064 if( m_Edit_Attributes.Get_Count() > 0 )
1065 {
1066 m_Edit_Attributes.Destroy();
1067
1068 g_pActive->Update_Attributes();
1069
1070 Update_Views();
1071
1072 return( true );
1073 }
1074
1075 return( false );
1076 }
1077
1078 //---------------------------------------------------------
_Edit_Del_Selection(void)1079 bool CWKSP_Grid::_Edit_Del_Selection(void)
1080 {
1081 if( m_Edit_Attributes.Get_Count() > 0 && DLG_Message_Confirm(_TL("Set selected values to no data."), _TL("Delete")) )
1082 {
1083 for(int y=0; y<m_Edit_Attributes.Get_Count(); y++)
1084 {
1085 for(int x=0, xx=1; xx<m_Edit_Attributes.Get_Field_Count(); x++, xx++)
1086 {
1087 m_Edit_Attributes[y].Set_NoData(xx);
1088
1089 Get_Grid()->Set_NoData(m_xSel + x, m_ySel + y);
1090 }
1091 }
1092
1093 g_pActive->Update_Attributes();
1094
1095 Update_Views();
1096
1097 return( true );
1098 }
1099
1100 return( false );
1101 }
1102
1103
1104 ///////////////////////////////////////////////////////////
1105 // //
1106 ///////////////////////////////////////////////////////////
1107
1108 //---------------------------------------------------------
Fit_Colors(const CSG_Rect & rWorld)1109 bool CWKSP_Grid::Fit_Colors(const CSG_Rect &rWorld)
1110 {
1111 double Minimum, Maximum;
1112
1113 switch( m_Fit_Colors )
1114 {
1115 default: { CSG_Simple_Statistics s; if( !Get_Grid()->Get_Statistics(rWorld, s) ) { return( false ); }
1116 Minimum = s.Get_Minimum() + s.Get_Range() * m_Parameters("STRETCH_LINEAR.MIN")->asDouble() / 100.;
1117 Maximum = s.Get_Minimum() + s.Get_Range() * m_Parameters("STRETCH_LINEAR.MAX")->asDouble() / 100.;
1118 break; }
1119
1120 case 1: { CSG_Simple_Statistics s; if( !Get_Grid()->Get_Statistics(rWorld, s) ) { return( false ); }
1121 double d = m_Parameters("STRETCH_STDDEV")->asDouble() * s.Get_StdDev();
1122 Minimum = s.Get_Mean() - d; if( m_Parameters("STRETCH_INRANGE")->asBool() && Minimum < Get_Grid()->Get_Min() ) Minimum = Get_Grid()->Get_Min();
1123 Maximum = s.Get_Mean() + d; if( m_Parameters("STRETCH_INRANGE")->asBool() && Maximum > Get_Grid()->Get_Max() ) Maximum = Get_Grid()->Get_Max();
1124 break; }
1125
1126 case 2: { CSG_Histogram h; if( !Get_Grid()->Get_Histogram (rWorld, h) ) { return( false ); }
1127 Minimum = h.Get_Quantile(m_Parameters("STRETCH_PCTL.MIN")->asDouble() / 100.);
1128 Maximum = h.Get_Quantile(m_Parameters("STRETCH_PCTL.MAX")->asDouble() / 100.);
1129 break; }
1130 }
1131
1132 return( Set_Color_Range(Minimum, Maximum) );
1133 }
1134
1135
1136 ///////////////////////////////////////////////////////////
1137 // //
1138 ///////////////////////////////////////////////////////////
1139
1140 //---------------------------------------------------------
asImage(CSG_Grid * pImage)1141 bool CWKSP_Grid::asImage(CSG_Grid *pImage)
1142 {
1143 wxBitmap BMP;
1144
1145 if( pImage && Get_Image_Grid(BMP) )
1146 {
1147 wxImage IMG(BMP.ConvertToImage());
1148
1149 pImage->Create(Get_Grid(), SG_DATATYPE_Int);
1150
1151 #pragma omp parallel for
1152 for(int y=0; y<pImage->Get_NY(); y++)
1153 {
1154 for(int x=0; x<pImage->Get_NX(); x++)
1155 {
1156 pImage->Set_Value(x, y, SG_GET_RGB(IMG.GetRed(x, y), IMG.GetGreen(x, y), IMG.GetBlue(x, y)));
1157 }
1158 }
1159
1160 return( true );
1161 }
1162
1163 return( false );
1164 }
1165
1166 //---------------------------------------------------------
_Save_Image(void)1167 bool CWKSP_Grid::_Save_Image(void)
1168 {
1169 static CSG_Parameters P(NULL, _TL("Save Grid as Image..."), _TL(""), SG_T(""));
1170
1171 if( P.Get_Count() == 0 )
1172 {
1173 P.Add_Bool ("", "WORLD", _TL("Save Georeference"), _TL(""), true);
1174 P.Add_Bool ("", "LG" , _TL("Legend: Save" ), _TL(""), true);
1175 P.Add_Double("", "LZ" , _TL("Legend: Zoom" ), _TL(""), 1., 0., true);
1176 }
1177
1178 //-----------------------------------------------------
1179 int Type;
1180 wxString File;
1181 wxBitmap Bitmap;
1182
1183 if( !DLG_Image_Save(File, Type) || !DLG_Parameters(&P) || !Get_Image_Grid(Bitmap) )
1184 {
1185 return( false );
1186 }
1187
1188 Bitmap.SaveFile(File, (wxBitmapType)Type);
1189
1190 //-----------------------------------------------------
1191 if( P("LG")->asBool() && Get_Image_Legend(Bitmap, P("LZ")->asDouble()) )
1192 {
1193 wxFileName fn(File); fn.SetName(wxString::Format("%s_legend", fn.GetName().c_str()));
1194
1195 Bitmap.SaveFile(fn.GetFullPath(), (wxBitmapType)Type);
1196 }
1197
1198 if( P("WORLD")->asBool() )
1199 {
1200 wxFileName fn(File);
1201
1202 switch( Type )
1203 {
1204 default : fn.SetExt("world"); break;
1205 case wxBITMAP_TYPE_BMP : fn.SetExt("bpw" ); break;
1206 case wxBITMAP_TYPE_GIF : fn.SetExt("gfw" ); break;
1207 case wxBITMAP_TYPE_JPEG: fn.SetExt("jgw" ); break;
1208 case wxBITMAP_TYPE_PNG : fn.SetExt("pgw" ); break;
1209 case wxBITMAP_TYPE_PCX : fn.SetExt("pxw" ); break;
1210 case wxBITMAP_TYPE_TIF : fn.SetExt("tfw" ); break;
1211 }
1212
1213 CSG_File Stream;
1214
1215 if( Stream.Open(fn.GetFullPath().wx_str(), SG_FILE_W, false) )
1216 {
1217 Stream.Printf("%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n",
1218 Get_Grid()->Get_Cellsize(), 0., 0.,
1219 -Get_Grid()->Get_Cellsize(),
1220 Get_Grid()->Get_XMin(),
1221 Get_Grid()->Get_YMax()
1222 );
1223 }
1224 }
1225
1226 return( true );
1227 }
1228
1229 //---------------------------------------------------------
_Save_Image_Clipboard(void)1230 bool CWKSP_Grid::_Save_Image_Clipboard(void)
1231 {
1232 wxBitmap Bitmap;
1233
1234 if( Get_Image_Grid(Bitmap) && wxTheClipboard->Open() )
1235 {
1236 wxBitmapDataObject *pBitmap = new wxBitmapDataObject;
1237 pBitmap->SetBitmap(Bitmap);
1238 wxTheClipboard->SetData(pBitmap);
1239 wxTheClipboard->Close();
1240
1241 return( true );
1242 }
1243
1244 return( false );
1245 }
1246
1247 //---------------------------------------------------------
Get_Image_Grid(wxBitmap & BMP,bool bFitSize)1248 bool CWKSP_Grid::Get_Image_Grid(wxBitmap &BMP, bool bFitSize)
1249 {
1250 if( bFitSize || (BMP.GetWidth() > 0 && BMP.GetHeight() > 0) )
1251 {
1252 Set_Buisy_Cursor(true);
1253
1254 if( bFitSize )
1255 {
1256 BMP.Create(Get_Grid()->Get_NX(), Get_Grid()->Get_NY());
1257 }
1258
1259 wxMemoryDC dc;
1260 wxRect r(0, 0, BMP.GetWidth(), BMP.GetHeight());
1261 CWKSP_Map_DC dc_Map(Get_Extent(), r, 1., SG_GET_RGB(255, 255, 255));
1262
1263 On_Draw(dc_Map, false);
1264
1265 dc.SelectObject(BMP);
1266 dc.SetBackground(*wxWHITE_BRUSH);
1267 dc.Clear();
1268
1269 dc_Map.Draw(dc);
1270
1271 dc.SelectObject(wxNullBitmap);
1272
1273 Set_Buisy_Cursor(false);
1274
1275 return( true );
1276 }
1277
1278 return( false );
1279 }
1280
1281 //---------------------------------------------------------
Get_Image_Legend(wxBitmap & BMP,double Zoom)1282 bool CWKSP_Grid::Get_Image_Legend(wxBitmap &BMP, double Zoom)
1283 {
1284 if( Zoom > 0. )
1285 {
1286 wxMemoryDC dc;
1287 wxSize s(Get_Legend()->Get_Size(Zoom, 1.));
1288
1289 BMP.Create(s.GetWidth(), s.GetHeight());
1290
1291 dc.SelectObject(BMP);
1292 dc.SetBackground(*wxWHITE_BRUSH);
1293 dc.Clear();
1294
1295 Get_Legend()->Draw(dc, Zoom, 1., wxPoint(0, 0));
1296
1297 dc.SelectObject(wxNullBitmap);
1298
1299 return( true );
1300 }
1301
1302 return( false );
1303 }
1304
1305
1306 ///////////////////////////////////////////////////////////
1307 // //
1308 ///////////////////////////////////////////////////////////
1309
1310 //---------------------------------------------------------
On_Draw(CWKSP_Map_DC & dc_Map,int Flags)1311 void CWKSP_Grid::On_Draw(CWKSP_Map_DC &dc_Map, int Flags)
1312 {
1313 if( Get_Extent().Intersects(dc_Map.m_rWorld) == INTERSECTION_None )
1314 {
1315 return;
1316 }
1317
1318 //-----------------------------------------------------
1319 int Mode = m_pClassify->Get_Mode() == CLASSIFY_SHADE ? IMG_MODE_SHADING
1320 : m_pClassify->Get_Mode() == CLASSIFY_RGB && m_Parameters("RGB_ALPHA" )->asBool() ? IMG_MODE_TRANSPARENT_ALPHA
1321 : m_pClassify->Get_Mode() != CLASSIFY_RGB && m_Parameters("DISPLAY_ALPHA")->asGrid() ? IMG_MODE_TRANSPARENT_ALPHA
1322 : IMG_MODE_TRANSPARENT;
1323
1324 if( !dc_Map.IMG_Draw_Begin(m_Parameters("DISPLAY_TRANSPARENCY")->asDouble() / 100., Mode) )
1325 {
1326 return;
1327 }
1328
1329 //-----------------------------------------------------
1330 m_pAlpha = m_Parameters("DISPLAY_ALPHA" )->asGrid ();
1331 m_Alpha[0] = m_Parameters("ALPHA_RANGE.MIN")->asDouble();
1332 m_Alpha[1] = m_Parameters("ALPHA_RANGE.MAX")->asDouble() - m_Alpha[0]; m_Alpha[1] = m_Alpha[1] ? 255. / m_Alpha[1] : 1.;
1333
1334 //-----------------------------------------------------
1335 TSG_Grid_Resampling Resampling;
1336
1337 if( m_pClassify->Get_Mode() == CLASSIFY_LUT )
1338 {
1339 Resampling = GRID_RESAMPLING_NearestNeighbour;
1340 }
1341 else switch( m_Parameters("DISPLAY_RESAMPLING")->asInt() )
1342 {
1343 default: Resampling = GRID_RESAMPLING_NearestNeighbour; break;
1344 case 1: Resampling = GRID_RESAMPLING_Bilinear ; break;
1345 case 2: Resampling = GRID_RESAMPLING_BicubicSpline ; break;
1346 case 3: Resampling = GRID_RESAMPLING_BSpline ; break;
1347 }
1348
1349 //-----------------------------------------------------
1350 m_Shade_Mode = m_Parameters("COLORS_TYPE" )->asInt() != CLASSIFY_SHADE
1351 ? m_Parameters("DISPLAY_SHADING")->asInt() : 0;
1352
1353 if( m_Shade_Mode && Get_Grid()->Get_Range() > 0. )
1354 {
1355 // m_Shade_Parms[0] = m_Parameters("SHADING_EXAGG")->asDouble() * Get_Grid()->Get_Cellsize() / Get_Grid()->Get_StdDev();
1356 m_Shade_Parms[0] = m_Parameters("SHADING_EXAGG")->asDouble() * Get_Grid()->Get_Cellsize() / 25.;
1357 m_Shade_Parms[1] = sin(M_DEG_TO_RAD * m_Parameters("SHADING_HEIGHT")->asDouble());
1358 m_Shade_Parms[2] = cos(M_DEG_TO_RAD * m_Parameters("SHADING_HEIGHT")->asDouble());
1359 m_Shade_Parms[3] = M_DEG_TO_RAD * m_Parameters("SHADING_AZIMUTH")->asDouble();
1360 m_Shade_Parms[4] = m_Parameters("SHADING_MIN")->asDouble();
1361 m_Shade_Parms[5] = m_Parameters("SHADING_MAX")->asDouble() - m_Shade_Parms[4];
1362 }
1363
1364 //-----------------------------------------------------
1365 m_pClassify->Set_Shade_Mode(m_Parameters("SHADE_MODE")->asInt());
1366
1367 if( dc_Map.m_DC2World >= Get_Grid()->Get_Cellsize()
1368 || Resampling != GRID_RESAMPLING_NearestNeighbour
1369 || m_Parameters("COLORS_TYPE")->asInt() == CLASSIFY_OVERLAY )
1370 {
1371 _Draw_Grid_Nodes(dc_Map, Resampling);
1372 }
1373 else
1374 {
1375 _Draw_Grid_Cells(dc_Map);
1376 }
1377
1378 //-----------------------------------------------------
1379 dc_Map.IMG_Draw_End();
1380
1381 if( (Flags & LAYER_DRAW_FLAG_NOLABELS) == 0 )
1382 {
1383 _Draw_Values(dc_Map);
1384 }
1385
1386 if( (Flags & LAYER_DRAW_FLAG_NOEDITS) == 0 )
1387 {
1388 _Draw_Edit(dc_Map);
1389 }
1390 }
1391
1392 //---------------------------------------------------------
_Draw_Grid_Nodes(CWKSP_Map_DC & dc_Map,TSG_Grid_Resampling Resampling)1393 void CWKSP_Grid::_Draw_Grid_Nodes(CWKSP_Map_DC &dc_Map, TSG_Grid_Resampling Resampling)
1394 {
1395 CSG_Grid *pOverlay[2]; CSG_Scaler Scaler[2];
1396
1397 _Get_Overlay(pOverlay, Scaler);
1398
1399 CSG_Rect rMap(dc_Map.m_rWorld); rMap.Intersect(Get_Grid()->Get_Extent(true));
1400
1401 int axDC = (int)dc_Map.xWorld2DC(rMap.Get_XMin()); if( axDC < 0 ) axDC = 0;
1402 int bxDC = (int)dc_Map.xWorld2DC(rMap.Get_XMax()); if( bxDC >= dc_Map.m_rDC.GetWidth () ) bxDC = dc_Map.m_rDC.GetWidth () - 1;
1403 int ayDC = (int)dc_Map.yWorld2DC(rMap.Get_YMin()); if( ayDC >= dc_Map.m_rDC.GetHeight() ) ayDC = dc_Map.m_rDC.GetHeight() - 1;
1404 int byDC = (int)dc_Map.yWorld2DC(rMap.Get_YMax()); if( byDC < 0 ) byDC = 0;
1405 int nyDC = abs(ayDC - byDC);
1406
1407 if( Get_Grid()->is_Cached() )
1408 {
1409 for(int iyDC=0; iyDC<=nyDC; iyDC++)
1410 {
1411 _Draw_Grid_Nodes(dc_Map, Resampling, ayDC - iyDC, axDC, bxDC, pOverlay, Scaler);
1412 }
1413 }
1414 else
1415 {
1416 #pragma omp parallel for
1417 for(int iyDC=0; iyDC<=nyDC; iyDC++)
1418 {
1419 _Draw_Grid_Nodes(dc_Map, Resampling, ayDC - iyDC, axDC, bxDC, pOverlay, Scaler);
1420 }
1421 }
1422 }
1423
1424 //---------------------------------------------------------
_Get_Overlay(CSG_Grid * pOverlay[2],CSG_Scaler Scaler[2])1425 void CWKSP_Grid::_Get_Overlay(CSG_Grid *pOverlay[2], CSG_Scaler Scaler[2])
1426 {
1427 if( m_pClassify->Get_Mode() != CLASSIFY_OVERLAY )
1428 {
1429 pOverlay [0] = pOverlay [1] = NULL;
1430 }
1431 else
1432 {
1433 switch( m_Parameters("OVERLAY_MODE")->asInt() )
1434 {
1435 default: // this = red
1436 pOverlay[0] = m_Parameters("OVERLAY_G")->asGrid();
1437 pOverlay[1] = m_Parameters("OVERLAY_B")->asGrid();
1438 break;
1439
1440 case 1: // this = green
1441 pOverlay[0] = m_Parameters("OVERLAY_R")->asGrid();
1442 pOverlay[1] = m_Parameters("OVERLAY_B")->asGrid();
1443 break;
1444
1445 case 2: // this = blue
1446 pOverlay[0] = m_Parameters("OVERLAY_R")->asGrid();
1447 pOverlay[1] = m_Parameters("OVERLAY_G")->asGrid();
1448 break;
1449 }
1450
1451 for(int i=0; i<2; i++)
1452 {
1453 if( !SG_Get_Data_Manager().Exists(pOverlay[i]) )
1454 {
1455 pOverlay[i] = NULL;
1456 }
1457 else if( pOverlay[i]->Get_Owner() )
1458 {
1459 double Interval =
1460 m_pClassify->Get_Metric_Mode() == METRIC_MODE_LOGUP ? m_pClassify->Get_Metric_LogFactor() :
1461 m_pClassify->Get_Metric_Mode() == METRIC_MODE_LOGDOWN ? -m_pClassify->Get_Metric_LogFactor() : 0.;
1462
1463 switch( m_Fit_Colors )
1464 {
1465 default: Scaler[i].Set_Linear (pOverlay[i], Interval, m_Parameters("STRETCH_LINEAR.MIN")->asDouble(), m_Parameters("STRETCH_LINEAR.MAX")->asDouble()); break;
1466 case 1: Scaler[i].Set_StdDev (pOverlay[i], Interval, m_Parameters("STRETCH_STDDEV" )->asDouble(), m_Parameters("STRETCH_INRANGE" )->asBool ()); break;
1467 case 2: Scaler[i].Set_Percentile(pOverlay[i], Interval, m_Parameters("STRETCH_PCTL.MIN" )->asDouble(), m_Parameters("STRETCH_PCTL.MAX" )->asDouble()); break;
1468 }
1469 }
1470 else if( g_pData->Get(pOverlay[i]) )
1471 {
1472 CWKSP_Layer_Classify *pClassify = ((CWKSP_Layer *)g_pData->Get(pOverlay[i]))->Get_Classifier();
1473
1474 Scaler[i].Create(pClassify->Get_Metric_Minimum(), pClassify->Get_Metric_Maximum(),
1475 pClassify->Get_Metric_Mode() == METRIC_MODE_LOGUP ? pClassify->Get_Metric_LogFactor() :
1476 pClassify->Get_Metric_Mode() == METRIC_MODE_LOGDOWN ? -pClassify->Get_Metric_LogFactor() : 0.
1477 );
1478 }
1479 }
1480 }
1481 }
1482
1483 //---------------------------------------------------------
_Draw_Grid_Nodes(CWKSP_Map_DC & dc_Map,TSG_Grid_Resampling Resampling,int yDC,int axDC,int bxDC,CSG_Grid * pOverlay[2],CSG_Scaler Scaler[2])1484 void CWKSP_Grid::_Draw_Grid_Nodes(CWKSP_Map_DC &dc_Map, TSG_Grid_Resampling Resampling, int yDC, int axDC, int bxDC, CSG_Grid *pOverlay[2], CSG_Scaler Scaler[2])
1485 {
1486 int Overlay[3];
1487
1488 switch( m_Parameters("OVERLAY_MODE")->asInt() )
1489 {
1490 default: Overlay[0] = 0; Overlay[1] = 1; Overlay[2] = 2; break; // this = r, pOverlay[0] = g, pOverlay[1] = r
1491 case 1: Overlay[0] = 1; Overlay[1] = 0; Overlay[2] = 2; break; // this = g, pOverlay[0] = r, pOverlay[1] = b
1492 case 2: Overlay[0] = 2; Overlay[1] = 0; Overlay[2] = 1; break; // this = b, pOverlay[0] = r, pOverlay[1] = g
1493 }
1494
1495 double xMap = dc_Map.xDC2World(axDC);
1496 double yMap = dc_Map.yDC2World( yDC);
1497
1498 for(int xDC=axDC; xDC<=bxDC; xMap+=dc_Map.m_DC2World, xDC++)
1499 {
1500 double Value;
1501
1502 if( Get_Grid()->Get_Value(xMap, yMap, Value, Resampling, false, m_pClassify->Get_Mode() == CLASSIFY_RGB) )
1503 {
1504 if( m_pClassify->Get_Mode() != CLASSIFY_OVERLAY )
1505 {
1506 int Color;
1507
1508 if( m_pClassify->Get_Class_Color_byValue(Value, Color) )
1509 {
1510 dc_Map.IMG_Set_Pixel(xDC, yDC, _Get_Shading(xMap, yMap, Color, Resampling));
1511 }
1512 }
1513 else
1514 {
1515 BYTE Color[4]; Color[3] = 0;
1516
1517 Value = m_pClassify->Get_MetricToRelative(Value);
1518 Color[Overlay[0]] = Value <= 0. ? 0 : Value >= 1. ? 255 : (BYTE)(255. * Value);
1519
1520 Value = pOverlay[0] && pOverlay[0]->Get_Value(xMap, yMap, Value, Resampling) ? Scaler[0].to_Relative(Value) : 1.;
1521 Color[Overlay[1]] = Value <= 0. ? 0 : Value >= 1. ? 255 : (BYTE)(255. * Value);
1522
1523 Value = pOverlay[1] && pOverlay[1]->Get_Value(xMap, yMap, Value, Resampling) ? Scaler[1].to_Relative(Value) : 1.;
1524 Color[Overlay[2]] = Value <= 0. ? 0 : Value >= 1. ? 255 : (BYTE)(255. * Value);
1525
1526 dc_Map.IMG_Set_Pixel(xDC, yDC, _Get_Shading(xMap, yMap, *(int *)Color, Resampling));
1527 }
1528 }
1529 }
1530 }
1531
1532 //---------------------------------------------------------
_Draw_Grid_Cells(CWKSP_Map_DC & dc_Map)1533 void CWKSP_Grid::_Draw_Grid_Cells(CWKSP_Map_DC &dc_Map)
1534 {
1535 int xa = Get_Grid()->Get_System().Get_xWorld_to_Grid(dc_Map.m_rWorld.Get_XMin()); if( xa < 0 ) xa = 0;
1536 int ya = Get_Grid()->Get_System().Get_yWorld_to_Grid(dc_Map.m_rWorld.Get_YMin()); if( ya < 0 ) ya = 0;
1537 int xb = Get_Grid()->Get_System().Get_xWorld_to_Grid(dc_Map.m_rWorld.Get_XMax()); if( xb >= Get_Grid()->Get_NX() ) xb = Get_Grid()->Get_NX() - 1;
1538 int yb = Get_Grid()->Get_System().Get_yWorld_to_Grid(dc_Map.m_rWorld.Get_YMax()); if( yb >= Get_Grid()->Get_NY() ) yb = Get_Grid()->Get_NY() - 1;
1539
1540 double dDC = Get_Grid()->Get_Cellsize() * dc_Map.m_World2DC;
1541
1542 double axDC = dc_Map.xWorld2DC(Get_Grid()->Get_System().Get_xGrid_to_World(xa)) + dDC / 2.;
1543 double ayDC = dc_Map.yWorld2DC(Get_Grid()->Get_System().Get_yGrid_to_World(ya)) - dDC / 2.;
1544
1545 //-----------------------------------------------------
1546 double yDC = ayDC;
1547
1548 for(int y=ya, yaDC=(int)(ayDC), ybDC=(int)(ayDC+dDC); y<=yb; y++, ybDC=yaDC, yaDC=(int)(yDC-=dDC))
1549 {
1550 double xDC = axDC;
1551
1552 for(int x=xa, xaDC=(int)(axDC-dDC), xbDC=(int)(axDC); x<=xb; x++, xaDC=xbDC, xbDC=(int)(xDC+=dDC))
1553 {
1554 int Color;
1555
1556 if( Get_Grid()->is_InGrid(x, y) && m_pClassify->Get_Class_Color_byValue(Get_Grid()->asDouble(x, y), Color) )
1557 {
1558 dc_Map.IMG_Set_Rect(xaDC, yaDC, xbDC, ybDC, _Get_Shading(x, y, Color));
1559 }
1560 }
1561 }
1562 }
1563
1564 //---------------------------------------------------------
_Set_Shading(double Shade,int & Color)1565 inline void CWKSP_Grid::_Set_Shading(double Shade, int &Color)
1566 {
1567 switch( m_Shade_Mode )
1568 {
1569 default: Shade = Shade / M_PI_090; break;
1570 case 1: Shade = 1. - Shade / M_PI_090; break;
1571 }
1572
1573 Shade = m_Shade_Parms[5] * (Shade - m_Shade_Parms[4]);
1574
1575 int r = (int)(Shade * SG_GET_R(Color)); if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
1576 int g = (int)(Shade * SG_GET_G(Color)); if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
1577 int b = (int)(Shade * SG_GET_B(Color)); if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
1578
1579 Color = SG_GET_RGB(r, g, b);
1580 }
1581
1582 //---------------------------------------------------------
_Get_Shading(int x,int y,int Color)1583 inline int CWKSP_Grid::_Get_Shading(int x, int y, int Color)
1584 {
1585 if( m_Shade_Mode )
1586 {
1587 double s, a;
1588
1589 if( Get_Grid()->Get_Gradient(x, y, s, a) )
1590 {
1591 s = M_PI_090 - atan(m_Shade_Parms[0] * tan(s));
1592
1593 _Set_Shading(acos(sin(s) * m_Shade_Parms[1] + cos(s) * m_Shade_Parms[2] * cos(a - m_Shade_Parms[3])), Color);
1594 }
1595 }
1596
1597 if( m_pAlpha )
1598 {
1599 double Alpha; TSG_Point p = Get_Grid()->Get_System().Get_Grid_to_World(x, y);
1600
1601 Alpha = m_pAlpha->Get_Value(p, Alpha) ? (Alpha - m_Alpha[0]) * m_Alpha[1] : 1.;
1602
1603 ((BYTE *)&Color)[3] = Alpha <= 0. ? 0 : Alpha >= 255. ? 255 : (BYTE)Alpha;
1604 }
1605
1606 return( Color );
1607 }
1608
1609 //---------------------------------------------------------
_Get_Shading(double x,double y,int Color,TSG_Grid_Resampling Resampling)1610 inline int CWKSP_Grid::_Get_Shading(double x, double y, int Color, TSG_Grid_Resampling Resampling)
1611 {
1612 if( m_Shade_Mode )
1613 {
1614 double s, a;
1615
1616 if( Get_Grid()->Get_Gradient(x, y, s, a, Resampling) )
1617 {
1618 s = M_PI_090 - atan(m_Shade_Parms[0] * tan(s));
1619
1620 _Set_Shading(acos(sin(s) * m_Shade_Parms[1] + cos(s) * m_Shade_Parms[2] * cos(a - m_Shade_Parms[3])), Color);
1621 }
1622 }
1623
1624 if( m_pAlpha )
1625 {
1626 double Alpha;
1627
1628 Alpha = m_pAlpha->Get_Value(x, y, Alpha, Resampling) ? (Alpha - m_Alpha[0]) * m_Alpha[1] : 1.;
1629
1630 ((BYTE *)&Color)[3] = Alpha <= 0. ? 0 : Alpha >= 255. ? 255 : (BYTE)Alpha;
1631 }
1632
1633 return( Color );
1634 }
1635
1636 //---------------------------------------------------------
_Draw_Values(CWKSP_Map_DC & dc_Map)1637 void CWKSP_Grid::_Draw_Values(CWKSP_Map_DC &dc_Map)
1638 {
1639 if( !m_Parameters("VALUES_SHOW")->asBool() || Get_Grid()->Get_Cellsize() * dc_Map.m_World2DC <= 40 )
1640 {
1641 return;
1642 }
1643
1644 //-----------------------------------------------------
1645 int ax, ay, bx, by, Decimals, Effect;
1646 double axDC, ayDC, dDC;
1647 wxColour Effect_Color;
1648 wxFont Font;
1649
1650 dDC = Get_Grid()->Get_Cellsize() * dc_Map.m_World2DC;
1651 Decimals = m_Parameters("VALUES_DECIMALS")->asInt();
1652 Font = Get_Font(m_Parameters("VALUES_FONT"));
1653 Font.SetPointSize((int)(dDC * m_Parameters("VALUES_SIZE")->asDouble() / 100.));
1654 dc_Map.dc.SetFont(Font);
1655 dc_Map.dc.SetTextForeground(Get_Color_asWX(m_Parameters("VALUES_FONT")->asColor()));
1656
1657 switch( m_Parameters("VALUES_EFFECT")->asInt() )
1658 {
1659 default: Effect = TEXTEFFECT_NONE ; break;
1660 case 1: Effect = TEXTEFFECT_FRAME ; break;
1661 case 2: Effect = TEXTEFFECT_TOP ; break;
1662 case 3: Effect = TEXTEFFECT_TOPLEFT ; break;
1663 case 4: Effect = TEXTEFFECT_LEFT ; break;
1664 case 5: Effect = TEXTEFFECT_BOTTOMLEFT ; break;
1665 case 6: Effect = TEXTEFFECT_BOTTOM ; break;
1666 case 7: Effect = TEXTEFFECT_BOTTOMRIGHT; break;
1667 case 8: Effect = TEXTEFFECT_RIGHT ; break;
1668 case 9: Effect = TEXTEFFECT_TOPRIGHT ; break;
1669 }
1670
1671 Effect_Color = m_Parameters("VALUES_EFFECT_COLOR")->asColor();
1672
1673 //-------------------------------------------------
1674 ax = Get_Grid()->Get_System().Get_xWorld_to_Grid(dc_Map.m_rWorld.Get_XMin());
1675 ay = Get_Grid()->Get_System().Get_yWorld_to_Grid(dc_Map.m_rWorld.Get_YMin());
1676 bx = Get_Grid()->Get_System().Get_xWorld_to_Grid(dc_Map.m_rWorld.Get_XMax());
1677 by = Get_Grid()->Get_System().Get_yWorld_to_Grid(dc_Map.m_rWorld.Get_YMax());
1678
1679 if( ax < 0 ) ax = 0; if( bx >= Get_Grid()->Get_NX() ) bx = Get_Grid()->Get_NX() - 1;
1680 if( ay < 0 ) ax = 0; if( by >= Get_Grid()->Get_NY() ) by = Get_Grid()->Get_NY() - 1;
1681
1682 axDC = dc_Map.xWorld2DC(Get_Grid()->Get_System().Get_xGrid_to_World(ax));
1683 ayDC = dc_Map.yWorld2DC(Get_Grid()->Get_System().Get_yGrid_to_World(ay));
1684
1685 int ny = by - ay;
1686
1687 //-------------------------------------------------
1688 for(int y=0; y<=ny; y++)
1689 {
1690 int x;
1691 double xDC, yDC = ayDC - y * dDC;// dc_Map.m_World2DC;
1692
1693 for(x=ax, xDC=axDC; x<=bx; x++, xDC+=dDC)
1694 {
1695 if( Get_Grid()->is_InGrid(x, ay + y) )
1696 {
1697 double Value = Get_Grid()->asDouble(x, ay + y);
1698
1699 switch( m_pClassify->Get_Mode() )
1700 {
1701 case CLASSIFY_RGB:
1702 Draw_Text(dc_Map.dc, TEXTALIGN_CENTER, (int)xDC, (int)yDC, wxString::Format(
1703 "R%03d G%03d B%03d", SG_GET_R((int)Value), SG_GET_G((int)Value), SG_GET_B((int)Value)
1704 ), Effect, Effect_Color);
1705 break;
1706
1707 default:
1708 Draw_Text(dc_Map.dc, TEXTALIGN_CENTER, (int)xDC, (int)yDC, wxString::Format(
1709 "%.*f", Decimals, Value
1710 ), Effect, Effect_Color);
1711 break;
1712 }
1713 }
1714 }
1715 }
1716 }
1717
1718 //---------------------------------------------------------
_Draw_Edit(CWKSP_Map_DC & dc_Map)1719 void CWKSP_Grid::_Draw_Edit(CWKSP_Map_DC &dc_Map)
1720 {
1721 if( m_Edit_Attributes.Get_Count() > 0 )
1722 {
1723 CSG_Rect r(
1724 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_xGrid_to_World(m_xSel),
1725 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_yGrid_to_World(m_ySel),
1726 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_xGrid_to_World(m_xSel + m_Edit_Attributes.Get_Field_Count() - 1),
1727 -Get_Grid()->Get_Cellsize() / 2. + Get_Grid()->Get_System().Get_yGrid_to_World(m_ySel + m_Edit_Attributes.Get_Count())
1728 );
1729
1730 TSG_Point_Int a(dc_Map.World2DC(r.Get_TopLeft ()));
1731 TSG_Point_Int b(dc_Map.World2DC(r.Get_BottomRight()));
1732
1733 a.x -= 1;
1734 b.x -= 1;
1735 a.y -= 1;
1736 b.y -= 1;
1737
1738 dc_Map.dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxPENSTYLE_SOLID));
1739 dc_Map.dc.DrawLine(a.x, a.y, a.x, b.y);
1740 dc_Map.dc.DrawLine(a.x, b.y, b.x, b.y);
1741 dc_Map.dc.DrawLine(b.x, b.y, b.x, a.y);
1742 dc_Map.dc.DrawLine(a.x, a.y, b.x, a.y);
1743 }
1744 }
1745
1746
1747 ///////////////////////////////////////////////////////////
1748 // //
1749 // //
1750 // //
1751 ///////////////////////////////////////////////////////////
1752
1753 //---------------------------------------------------------
1754