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_Layer.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 // Germany //
43 // //
44 // e-mail: oconrad@saga-gis.org //
45 // //
46 ///////////////////////////////////////////////////////////
47
48 //---------------------------------------------------------
49 #include "res_commands.h"
50 #include "res_dialogs.h"
51
52 #include "saga_frame.h"
53
54 #include "helper.h"
55
56 #include "active.h"
57 #include "active_parameters.h"
58
59 #include "wksp_base_control.h"
60
61 #include "wksp_data_manager.h"
62 #include "wksp_data_menu_files.h"
63
64 #include "wksp_map_manager.h"
65 #include "wksp_map.h"
66 #include "wksp_map_layer.h"
67
68 #include "wksp_data_manager.h"
69 #include "wksp_data_layers.h"
70
71 #include "wksp_layer.h"
72 #include "wksp_layer_classify.h"
73 #include "wksp_layer_legend.h"
74
75 #include "wksp_shapes.h"
76
77 #include "view_histogram.h"
78
79
80 ///////////////////////////////////////////////////////////
81 // //
82 // //
83 // //
84 ///////////////////////////////////////////////////////////
85
86 //---------------------------------------------------------
87 #define DEF_LAYER_COLOUR_COUNT 15
88
89 //---------------------------------------------------------
90 static int s_Def_Layer_Colours[DEF_LAYER_COLOUR_COUNT] =
91 {
92 SG_COLOR_RED,
93 SG_COLOR_GREEN,
94 SG_COLOR_BLUE,
95 SG_COLOR_YELLOW,
96
97 SG_GET_RGB(255, 127, 0),
98 SG_COLOR_GREEN_LIGHT,
99 SG_COLOR_BLUE_LIGHT,
100 SG_GET_RGB(255, 255, 127),
101
102 SG_COLOR_RED_DARK,
103 SG_COLOR_GREEN_DARK,
104 SG_COLOR_BLUE_DARK,
105 SG_COLOR_YELLOW_DARK,
106
107 SG_COLOR_BLUE_GREEN,
108 SG_COLOR_PURPLE,
109 SG_COLOR_PINK
110 };
111
112
113 ///////////////////////////////////////////////////////////
114 // //
115 ///////////////////////////////////////////////////////////
116
117 //---------------------------------------------------------
Get_Active_Layer(void)118 CWKSP_Layer * Get_Active_Layer(void)
119 {
120 return( g_pActive ? g_pActive->Get_Active_Layer() : NULL );
121 }
122
123
124 ///////////////////////////////////////////////////////////
125 // //
126 // //
127 // //
128 ///////////////////////////////////////////////////////////
129
130 //---------------------------------------------------------
CWKSP_Layer(CSG_Data_Object * pObject)131 CWKSP_Layer::CWKSP_Layer(CSG_Data_Object *pObject)
132 : CWKSP_Data_Item(pObject)
133 {
134 m_pClassify = new CWKSP_Layer_Classify;
135 m_pLegend = new CWKSP_Layer_Legend(this);
136
137 m_pHistogram = NULL;
138
139 m_Edit_Index = 0;
140 }
141
142 //---------------------------------------------------------
~CWKSP_Layer(void)143 CWKSP_Layer::~CWKSP_Layer(void)
144 {
145 if( g_pSAGA_Frame ) { g_pSAGA_Frame->Freeze(); }
146
147 if( g_pMaps ) { g_pMaps->Del(this); }
148
149 if( m_pClassify ) { delete(m_pClassify); }
150 if( m_pLegend ) { delete(m_pLegend ); }
151
152 if( g_pSAGA_Frame ) { g_pSAGA_Frame->Thaw(); }
153 }
154
155
156 ///////////////////////////////////////////////////////////
157 // //
158 ///////////////////////////////////////////////////////////
159
160 //---------------------------------------------------------
On_Command(int Cmd_ID)161 bool CWKSP_Layer::On_Command(int Cmd_ID)
162 {
163 switch( Cmd_ID )
164 {
165 default:
166 return( CWKSP_Data_Item::On_Command(Cmd_ID) );
167
168 case ID_CMD_WKSP_ITEM_RETURN:
169 case ID_CMD_SHAPES_SHOW:
170 case ID_CMD_GRID_SHOW:
171 case ID_CMD_TIN_SHOW:
172 case ID_CMD_POINTCLOUD_SHOW:
173 g_pMaps->Add(this);
174 break;
175
176 case ID_CMD_DATA_PROJECTION:
177 _Set_Projection();
178 break;
179
180 case ID_CMD_DATA_FORCE_UPDATE:
181 m_pObject->Update(true);
182 DataObject_Changed();
183 break;
184 }
185
186 return( true );
187 }
188
189 //---------------------------------------------------------
On_Command_UI(wxUpdateUIEvent & event)190 bool CWKSP_Layer::On_Command_UI(wxUpdateUIEvent &event)
191 {
192 return( CWKSP_Data_Item::On_Command_UI(event) );
193 }
194
195
196 ///////////////////////////////////////////////////////////
197 // //
198 ///////////////////////////////////////////////////////////
199
200 //---------------------------------------------------------
On_Create_Parameters(void)201 void CWKSP_Layer::On_Create_Parameters(void)
202 {
203 CWKSP_Data_Item::On_Create_Parameters();
204
205 //-----------------------------------------------------
206 // Nodes...
207
208 m_Parameters.Add_Node("", "NODE_DISPLAY" , _TL("Display" ), _TL(""));
209 m_Parameters.Add_Node("", "NODE_COLORS" , _TL("Colors" ), _TL(""));
210 m_Parameters.Add_Node("", "NODE_SIZE" , _TL("Size" ), _TL(""));
211 m_Parameters.Add_Node("", "NODE_LABEL" , _TL("Labels" ), _TL(""));
212 m_Parameters.Add_Node("", "NODE_SELECTION", _TL("Selection"), _TL(""));
213 m_Parameters.Add_Node("", "NODE_EDIT" , _TL("Edit" ), _TL(""));
214
215 //-----------------------------------------------------
216 // General...
217
218 m_Parameters.Add_Bool("NODE_GENERAL",
219 "LEGEND_SHOW" , _TL("Show Legend"),
220 _TL(""),
221 true
222 );
223
224 m_Parameters.Add_Choice("LEGEND_SHOW",
225 "LEGEND_STYLE" , _TL("Style"),
226 _TL(""),
227 CSG_String::Format("%s|%s",
228 _TL("vertical"),
229 _TL("horizontal")
230 ), 0
231 );
232
233 //-----------------------------------------------------
234 // Display...
235
236 m_Parameters.Add_Double("NODE_DISPLAY",
237 "DISPLAY_TRANSPARENCY", _TL("Transparency [%]"),
238 _TL(""),
239 0., 0., true, 100., true
240 );
241
242 m_Parameters.Add_Bool("NODE_DISPLAY",
243 "SHOW_ALWAYS" , _TL("Show at all scales"),
244 _TL(""),
245 true
246 );
247
248 m_Parameters.Add_Range("SHOW_ALWAYS",
249 "SHOW_RANGE" , _TL("Scale Range"),
250 _TL("only show within scale range; values are given as extent measured in map units"),
251 100., 1000., 0., true
252 );
253
254 //-----------------------------------------------------
255 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes
256 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud
257 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
258 {
259 m_Parameters.Add_Choice("NODE_DISPLAY",
260 "TABLE_FLT_STYLE" , _TL("Floating Point Numbers"),
261 _TL("Specify floating point decimal precision in table and similar views."),
262 CSG_String::Format("%s|%s|%s",
263 _TL("system default"),
264 _TL("compact"),
265 _TL("fix number of decimals")
266 ), g_pData->Get_Parameter("TABLE_FLT_STYLE")->asInt()
267 );
268
269 m_Parameters.Add_Int("TABLE_FLT_STYLE",
270 "TABLE_FLT_DECIMALS" , _TL("Decimals"),
271 _TL(""),
272 g_pData->Get_Parameter("TABLE_FLT_DECIMALS")->asInt(), 0, true
273 );
274 }
275
276 //-----------------------------------------------------
277 // Classification...
278
279 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes
280 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
281 {
282 m_Parameters.Add_Choice("NODE_COLORS", "COLORS_TYPE", _TL("Type"), _TL(""), CSG_String::Format("%s|%s|%s|%s",
283 _TL("Single Symbol" ), // CLASSIFY_SINGLE
284 _TL("Classified" ), // CLASSIFY_LUT
285 _TL("Discrete Colors" ), // CLASSIFY_DISCRETE
286 _TL("Graduated Colors") // CLASSIFY_GRADUATED
287 ), 0);
288 }
289 else if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud )
290 {
291 m_Parameters.Add_Choice("NODE_COLORS", "COLORS_TYPE", _TL("Type"), _TL(""), CSG_String::Format("%s|%s|%s|%s|%s",
292 _TL("Single Symbol" ), // CLASSIFY_SINGLE
293 _TL("Classified" ), // CLASSIFY_LUT
294 _TL("Discrete Colors" ), // CLASSIFY_DISCRETE
295 _TL("Graduated Colors"), // CLASSIFY_GRADUATED
296 _TL("RGB Coded Values") // CLASSIFY_OVERLAY !!!
297 ), 0);
298 }
299 else if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grids )
300 {
301 m_Parameters.Add_Choice("NODE_COLORS", "COLORS_TYPE", _TL("Type"), _TL(""), CSG_String::Format("%s|%s|%s|%s|%s",
302 _TL("Single Symbol" ), // CLASSIFY_SINGLE
303 _TL("Classified" ), // CLASSIFY_LUT
304 _TL("Discrete Colors" ), // CLASSIFY_DISCRETE
305 _TL("Graduated Colors"), // CLASSIFY_GRADUATED
306 _TL("RGB Composite" ) // CLASSIFY_OVERLAY
307 ), 4);
308
309 m_Parameters.Add_Choice("NODE_COLORS", "BAND" , _TL("Band" ), _TL(""), _TL("<default>"));
310 m_Parameters.Add_Choice("NODE_COLORS", "OVERLAY_FIT", _TL("Statistics"), _TL(""), CSG_String::Format("%s|%s", _TL("all bands"), _TL("each band")), 1);
311 m_Parameters.Add_Choice("NODE_COLORS", "BAND_R" , _TL("Red" ), _TL(""), "");
312 m_Parameters.Add_Choice("NODE_COLORS", "BAND_G" , _TL("Green" ), _TL(""), "");
313 m_Parameters.Add_Choice("NODE_COLORS", "BAND_B" , _TL("Blue" ), _TL(""), "");
314 }
315 else if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grid )
316 {
317 m_Parameters.Add_Choice("NODE_COLORS", "COLORS_TYPE", _TL("Type"), _TL(""), CSG_String::Format("%s|%s|%s|%s|%s|%s|%s",
318 _TL("Single Symbol" ), // CLASSIFY_SINGLE
319 _TL("Classified" ), // CLASSIFY_LUT
320 _TL("Discrete Colors" ), // CLASSIFY_DISCRETE
321 _TL("Graduated Colors"), // CLASSIFY_GRADUATED
322 _TL("RGB Composite" ), // CLASSIFY_OVERLAY
323 _TL("RGB Coded Values"), // CLASSIFY_RGB
324 _TL("Shade" ) // CLASSIFY_SHADE
325 ), 3);
326 }
327
328 //-----------------------------------------------------
329 // Classification: Single Symbol...
330
331 static BYTE s_Def_Layer_Colour = 0;
332
333 m_Parameters.Add_Node("NODE_COLORS",
334 "NODE_SINGLE" , _TL("Single Symbol"),
335 _TL("")
336 );
337
338 m_Parameters.Add_Color("NODE_SINGLE",
339 "SINGLE_COLOR" , _TL("Color"),
340 _TL(""),
341 s_Def_Layer_Colours[s_Def_Layer_Colour++ % DEF_LAYER_COLOUR_COUNT]
342 );
343
344 //-----------------------------------------------------
345 // Classification: Classified...
346
347 m_Parameters.Add_Node("NODE_COLORS",
348 "NODE_LUT" , _TL("Classified"),
349 _TL("")
350 );
351
352 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes
353 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud
354 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
355 {
356 m_Parameters.Add_Choice("NODE_LUT", "LUT_ATTRIB", _TL("Attribute"), _TL(""), _TL("<default>"));
357 }
358
359 CSG_Table *pLUT = m_Parameters.Add_FixedTable("NODE_LUT",
360 "LUT" , _TL("Table"),
361 _TL("")
362 )->asTable();
363
364 pLUT->Get_MetaData().Add_Child("SAGA_GUI_LUT_TYPE", m_pObject->Get_ObjectType());
365
366 pLUT->Add_Field(_TL("Color" ), SG_DATATYPE_Color );
367 pLUT->Add_Field(_TL("Name" ), SG_DATATYPE_String);
368 pLUT->Add_Field(_TL("Description"), SG_DATATYPE_String);
369 pLUT->Add_Field(_TL("Minimum" ), SG_DATATYPE_Double);
370 pLUT->Add_Field(_TL("Maximum" ), SG_DATATYPE_Double);
371
372 m_pClassify->Initialise(this, pLUT, g_pData->Get_Parameter("COLORS_DEFAULT")->asColors());
373
374 //-----------------------------------------------------
375 // Classification: Colors...
376
377 ColorsParms_Add();
378 }
379
380
381 ///////////////////////////////////////////////////////////
382 // //
383 ///////////////////////////////////////////////////////////
384
385 //---------------------------------------------------------
ColorsParms_Add(void)386 void CWKSP_Layer::ColorsParms_Add(void)
387 {
388 m_Parameters.Add_Node("NODE_COLORS",
389 "NODE_METRIC" , _TL("Histogram Stretch"),
390 _TL("")
391 );
392
393 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes )
394 {
395 m_Parameters.Add_Choice("NODE_METRIC", "METRIC_ATTRIB", _TL("Attribute"), _TL(""), _TL("<default>"));
396 m_Parameters.Add_Choice("NODE_METRIC", "METRIC_NORMAL", _TL("Normalize"), _TL(""), _TL("<default>"));
397
398 m_Parameters.Add_Choice("METRIC_NORMAL", "METRIC_NORFMT", _TL("Labeling"), _TL(""),
399 CSG_String::Format("%s|%s", _TL("fraction"), _TL("percentage")), 1
400 );
401 }
402 else if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud
403 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
404 {
405 m_Parameters.Add_Choice("NODE_METRIC", "METRIC_ATTRIB", _TL("Attribute"), _TL(""), _TL("<default>"));
406 }
407
408 //-----------------------------------------------------
409 m_Parameters.Add_Colors("NODE_METRIC",
410 "METRIC_COLORS" , _TL("Colors"),
411 _TL(""),
412 g_pData->Get_Parameter("COLORS_DEFAULT")->asColors()
413 );
414
415 m_Parameters.Add_Range("NODE_METRIC",
416 "METRIC_ZRANGE" , _TL("Range"),
417 _TL("")
418 );
419
420 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grids )
421 {
422 m_Parameters.Add_Range("NODE_METRIC", "METRIC_ZRANGE_R", _TL("Red" ), _TL(""));
423 m_Parameters.Add_Range("NODE_METRIC", "METRIC_ZRANGE_G", _TL("Green"), _TL(""));
424 m_Parameters.Add_Range("NODE_METRIC", "METRIC_ZRANGE_B", _TL("Blue" ), _TL(""));
425 }
426
427 //-----------------------------------------------------
428 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grid
429 || m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grids )
430 {
431 m_Parameters.Add_Bool("", "STRETCH_UPDATE", "update flag, for internal use only", "", true)->Set_Enabled(false);
432
433 m_Parameters.Add_Choice("NODE_METRIC",
434 "STRETCH_DEFAULT" , _TL("Adjustment"),
435 _TL("Specify how to adjust histogram stretch."),
436 CSG_String::Format("%s|%s|%s|%s",
437 _TL("Linear"),
438 _TL("Standard Deviation"),
439 _TL("Percent Clip"),
440 _TL("Manual")
441 ), g_pData->Get_Parameter("GRID_STRETCH_DEFAULT")->asInt()
442 );
443
444 m_Parameters.Add_Range("STRETCH_DEFAULT",
445 "STRETCH_LINEAR" , _TL("Linear Percent Stretch"),
446 _TL("Linear percent stretch allows you to trim extreme values from both ends of the histogram using the percentage specified here."),
447 5., 95., 0., true, 100., true
448 );
449
450 m_Parameters.Add_Double("STRETCH_DEFAULT",
451 "STRETCH_STDDEV" , _TL("Standard Deviation"),
452 _TL(""),
453 2., 0., true
454 );
455
456 m_Parameters.Add_Bool("STRETCH_STDDEV",
457 "STRETCH_INRANGE" , _TL("Keep in Range"),
458 _TL("Prevents that minimum or maximum stretch value fall outside the data value range."),
459 true
460 );
461
462 m_Parameters.Add_Range("STRETCH_DEFAULT",
463 "STRETCH_PCTL" , _TL("Percent Clip"),
464 _TL(""),
465 2., 98., 0., true, 100., true
466 );
467 }
468
469 //-----------------------------------------------------
470 if( m_pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud )
471 {
472 m_Parameters.Add_Choice("NODE_METRIC",
473 "STRETCH_DEFAULT" , _TL("Adjustment"),
474 _TL("Specify how to adjust histogram stretch."),
475 CSG_String::Format("%s|%s|%s",
476 _TL("Linear"),
477 _TL("Standard Deviation"),
478 _TL("Manual")
479 ), 1
480 );
481
482 m_Parameters.Add_Range("STRETCH_DEFAULT",
483 "STRETCH_LINEAR" , _TL("Linear Percent Stretch"),
484 _TL("Linear percent stretch allows you to trim extreme values from both ends of the histogram using the percentage specified here."),
485 5., 95., 0., true, 100., true
486 );
487
488 m_Parameters.Add_Double("STRETCH_DEFAULT",
489 "STRETCH_STDDEV" , _TL("Standard Deviation"),
490 _TL(""),
491 2., 0., true
492 );
493
494 m_Parameters.Add_Bool("STRETCH_STDDEV",
495 "STRETCH_INRANGE" , _TL("Keep in Range"),
496 _TL("Prevents that minimum or maximum stretch value fall outside the data value range."),
497 true
498 );
499 }
500
501 //-----------------------------------------------------
502 m_Parameters.Add_Choice("NODE_METRIC",
503 "METRIC_SCALE_MODE" , _TL("Scaling"),
504 _TL(""),
505 CSG_String::Format("%s|%s|%s",
506 _TL("linear intervals"),
507 _TL("increasing geometrical intervals"),
508 _TL("decreasing geometrical intervals")
509 ), 0
510 );
511
512 m_Parameters.Add_Double("METRIC_SCALE_MODE",
513 "METRIC_SCALE_LOG" , _TL("Geometrical Interval Factor"),
514 _TL(""),
515 10.
516 );
517 }
518
519 //---------------------------------------------------------
ColorsParms_On_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)520 void CWKSP_Layer::ColorsParms_On_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
521 {
522 //-----------------------------------------------------
523 if( Flags & PARAMETER_CHECK_VALUES )
524 {
525 if( pParameter->Cmp_Identifier("METRIC_ZRANGE" )
526 || pParameter->Cmp_Identifier("METRIC_ZRANGE_R")
527 || pParameter->Cmp_Identifier("METRIC_ZRANGE_G")
528 || pParameter->Cmp_Identifier("METRIC_ZRANGE_B") )
529 {
530 pParameters->Set_Parameter("STRETCH_DEFAULT", 3); // manual
531 }
532 }
533
534 //-----------------------------------------------------
535 if( Flags & PARAMETER_CHECK_ENABLE )
536 {
537 if( pParameter->Cmp_Identifier("METRIC_SCALE_MODE") )
538 {
539 pParameters->Set_Enabled("METRIC_SCALE_LOG", pParameter->asInt() != 0);
540 }
541
542 CSG_Parameter *pStretch = (*pParameters)("STRETCH_DEFAULT");
543
544 if( pStretch )
545 {
546 pParameters->Set_Enabled("STRETCH_LINEAR", pStretch->asInt() == 0);
547 pParameters->Set_Enabled("STRETCH_STDDEV", pStretch->asInt() == 1);
548 pParameters->Set_Enabled("STRETCH_PCTL" , pStretch->asInt() == 2);
549 }
550 }
551 }
552
553 //---------------------------------------------------------
ColorsParms_Adjust(CSG_Parameters & Parameters,CSG_Data_Object * pObject,const CSG_String & Suffix)554 bool CWKSP_Layer::ColorsParms_Adjust(CSG_Parameters &Parameters, CSG_Data_Object *pObject, const CSG_String &Suffix)
555 {
556 if( !pObject )
557 {
558 pObject = Get_Object();
559
560 if( pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Grids && Parameters("COLORS_TYPE")->asInt() != CLASSIFY_OVERLAY )
561 {
562 int i = Parameters("BAND") ? Parameters("BAND")->asInt() : -1;
563
564 if( i < 0 || i >= ((CSG_Grids *)pObject)->Get_NZ() || !(pObject = ((CSG_Grids *)pObject)->Get_Grid_Ptr(i)) )
565 {
566 return( false );
567 }
568 }
569 }
570
571 int Field = -1;
572
573 if( pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes
574 || pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_PointCloud
575 || pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
576 {
577 if( !Parameters("METRIC_ATTRIB") || (Field = Parameters("METRIC_ATTRIB")->asInt()) < 0 || Field >= ((CSG_Shapes *)pObject)->Get_Field_Count() )
578 {
579 return( false );
580 }
581
582 if( pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_TIN )
583 { // currently no support for histogram stretch options with shapes and tin...
584 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MIN", ((CSG_TIN *)pObject)->Get_Minimum(Field));
585 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MAX", ((CSG_TIN *)pObject)->Get_Maximum(Field));
586
587 return( true );
588 }
589
590 if( pObject->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes )
591 { // currently no support for histogram stretch options with shapes and tin...
592 CWKSP_Shapes *pShapes = (CWKSP_Shapes *)this;
593
594 pShapes->Set_Metrics(
595 Parameters("METRIC_ATTRIB")->asInt(),
596 Parameters("METRIC_NORMAL")->asInt(),
597 Parameters("METRIC_NORFMT")->asInt()
598 );
599
600 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MIN", pShapes->Get_Value_Minimum());
601 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MAX", pShapes->Get_Value_Maximum());
602
603 return( true );
604 }
605 }
606
607 double Minimum, Maximum;
608
609 switch( Parameters("STRETCH_DEFAULT")->asInt() )
610 {
611 case 0: {
612 //-------------------------------------------------
613 switch( pObject->Get_ObjectType() )
614 {
615 case SG_DATAOBJECT_TYPE_Grid:
616 Minimum = pObject->asGrid ()->Get_Min();
617 Maximum = pObject->asGrid ()->Get_Max();
618 break;
619
620 case SG_DATAOBJECT_TYPE_Grids:
621 Minimum = pObject->asGrids()->Get_Min();
622 Maximum = pObject->asGrids()->Get_Max();
623 break;
624
625 case SG_DATAOBJECT_TYPE_Shapes:
626 case SG_DATAOBJECT_TYPE_PointCloud:
627 case SG_DATAOBJECT_TYPE_TIN:
628 Minimum = ((CSG_Shapes *)pObject)->Get_Minimum(Field);
629 Maximum = ((CSG_Shapes *)pObject)->Get_Maximum(Field);
630 break;
631
632 default:
633 return( false );
634 }
635
636 if( Parameters("STRETCH_DEFAULT")->asInt() == 0 )
637 {
638 double Range = (Maximum - Minimum) / 100.;
639
640 Maximum = Minimum + Range * Parameters("STRETCH_LINEAR.MAX")->asDouble();
641 Minimum = Minimum + Range * Parameters("STRETCH_LINEAR.MIN")->asDouble();
642 }
643 break; }
644
645 //-----------------------------------------------------
646 case 1: {
647 double d = Parameters("STRETCH_STDDEV")->asDouble(), Mean;
648
649 switch( pObject->Get_ObjectType() )
650 {
651 case SG_DATAOBJECT_TYPE_Grid:
652 Minimum = pObject->asGrid ()->Get_Min ();
653 Maximum = pObject->asGrid ()->Get_Max ();
654 Mean = pObject->asGrid ()->Get_Mean ();
655 d *= pObject->asGrid ()->Get_StdDev();
656 break;
657
658 case SG_DATAOBJECT_TYPE_Grids:
659 Minimum = pObject->asGrids()->Get_Min ();
660 Maximum = pObject->asGrids()->Get_Max ();
661 Mean = pObject->asGrids()->Get_Mean ();
662 d *= pObject->asGrids()->Get_StdDev();
663 break;
664
665 case SG_DATAOBJECT_TYPE_Shapes:
666 case SG_DATAOBJECT_TYPE_PointCloud:
667 case SG_DATAOBJECT_TYPE_TIN:
668 Minimum = ((CSG_Shapes *)pObject)->Get_Minimum(Field);
669 Maximum = ((CSG_Shapes *)pObject)->Get_Maximum(Field);
670 Mean = ((CSG_Shapes *)pObject)->Get_Mean (Field);
671 d *= ((CSG_Shapes *)pObject)->Get_StdDev (Field);
672 break;
673
674 default:
675 return( false );
676 }
677
678 if( !Parameters("STRETCH_INRANGE")->asBool() || Minimum < Mean - d ) Minimum = Mean - d;
679 if( !Parameters("STRETCH_INRANGE")->asBool() || Maximum > Mean + d ) Maximum = Mean + d;
680
681 break; }
682
683 //-----------------------------------------------------
684 case 2: {
685 switch( pObject->Get_ObjectType() )
686 {
687 case SG_DATAOBJECT_TYPE_Grid:
688 Minimum = ((CSG_Grid *)pObject)->Get_Percentile(Parameters("STRETCH_PCTL.MIN")->asDouble());
689 Maximum = ((CSG_Grid *)pObject)->Get_Percentile(Parameters("STRETCH_PCTL.MAX")->asDouble());
690 break;
691
692 case SG_DATAOBJECT_TYPE_Grids:
693 Minimum = ((CSG_Grids *)pObject)->Get_Percentile(Parameters("STRETCH_PCTL.MIN")->asDouble());
694 Maximum = ((CSG_Grids *)pObject)->Get_Percentile(Parameters("STRETCH_PCTL.MAX")->asDouble());
695 break;
696
697 default:
698 return( false );
699 }
700 break; }
701
702 //-----------------------------------------------------
703 default:
704 return( false );
705 }
706
707 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MIN", Minimum);
708 Parameters.Set_Parameter("METRIC_ZRANGE" + Suffix + ".MAX", Maximum);
709
710 return( true );
711 }
712
713
714 ///////////////////////////////////////////////////////////
715 // //
716 ///////////////////////////////////////////////////////////
717
718 //---------------------------------------------------------
On_DataObject_Changed(void)719 void CWKSP_Layer::On_DataObject_Changed(void)
720 {
721 ColorsParms_Adjust(m_Parameters);
722 }
723
724
725 ///////////////////////////////////////////////////////////
726 // //
727 ///////////////////////////////////////////////////////////
728
729 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)730 int CWKSP_Layer::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
731 {
732 //-----------------------------------------------------
733 if( Flags & PARAMETER_CHECK_VALUES )
734 {
735 if( pParameter->Cmp_Identifier("STRETCH_DEFAULT")
736 || pParameter->Cmp_Identifier("STRETCH_LINEAR" )
737 || pParameter->Cmp_Identifier("STRETCH_STDDEV" )
738 || pParameter->Cmp_Identifier("STRETCH_INRANGE")
739 || pParameter->Cmp_Identifier("STRETCH_PCTL" )
740 || pParameter->Cmp_Identifier("BAND" ) )
741 {
742 ColorsParms_Adjust(*pParameters);
743 }
744 }
745
746 //-----------------------------------------------------
747 if( Flags & PARAMETER_CHECK_ENABLE )
748 {
749 if( pParameter->Cmp_Identifier("LEGEND_SHOW")
750 || pParameter->Cmp_Identifier("COLORS_TYPE") )
751 {
752 pParameters->Set_Enabled("LEGEND_STYLE",
753 (*pParameters)("LEGEND_SHOW")->asBool()
754 && (*pParameters)("COLORS_TYPE")->asInt() == CLASSIFY_GRADUATED
755 );
756 }
757
758 if( pParameter->Cmp_Identifier("SHOW_ALWAYS") )
759 {
760 pParameters->Set_Enabled("SHOW_RANGE", pParameter->asBool() == false);
761 }
762
763 if( pParameter->Cmp_Identifier("TABLE_FLT_STYLE") )
764 {
765 pParameters->Set_Enabled("TABLE_FLT_DECIMALS", pParameter->asInt() == 2);
766 }
767
768 if( pParameter->Cmp_Identifier("COLORS_TYPE") )
769 {
770 int Value = pParameter->asInt();
771
772 pParameters->Set_Enabled("METRIC_COLORS" , Value == CLASSIFY_DISCRETE || Value == CLASSIFY_GRADUATED);
773 pParameters->Set_Enabled("NODE_SINGLE", Value == CLASSIFY_SINGLE);
774 pParameters->Set_Enabled("NODE_LUT" , Value == CLASSIFY_LUT);
775
776 if( m_pObject->Get_ObjectType() != SG_DATAOBJECT_TYPE_Grids )
777 {
778 pParameters->Set_Enabled("NODE_METRIC", Value != CLASSIFY_SINGLE && Value != CLASSIFY_LUT && Value != CLASSIFY_RGB);
779 }
780 }
781 }
782
783 //-----------------------------------------------------
784 ColorsParms_On_Changed(pParameters, pParameter, Flags);
785
786 return( CWKSP_Data_Item::On_Parameter_Changed(pParameters, pParameter, Flags) );
787 }
788
789
790 ///////////////////////////////////////////////////////////
791 // //
792 ///////////////////////////////////////////////////////////
793
794 //---------------------------------------------------------
On_Parameters_Changed(void)795 void CWKSP_Layer::On_Parameters_Changed(void)
796 {
797 //-----------------------------------------------------
798 m_pClassify->Initialise(this, m_Parameters("LUT")->asTable(), m_Parameters("METRIC_COLORS")->asColors());
799
800 m_pClassify->Set_Mode(m_Parameters("COLORS_TYPE")->asInt());
801
802 m_pClassify->Set_Unique_Color(m_Parameters("SINGLE_COLOR")->asInt());
803
804 m_pClassify->Set_Metric(
805 m_Parameters("METRIC_SCALE_MODE")->asInt (),
806 m_Parameters("METRIC_SCALE_LOG" )->asDouble(),
807 m_Parameters("METRIC_ZRANGE.MIN")->asDouble(),
808 m_Parameters("METRIC_ZRANGE.MAX")->asDouble()
809 );
810
811 m_pLegend->Set_Orientation(m_Parameters("LEGEND_STYLE")->asInt() == LEGEND_VERTICAL ? LEGEND_VERTICAL : LEGEND_HORIZONTAL);
812
813 //-----------------------------------------------------
814 CWKSP_Data_Item::On_Parameters_Changed();
815 }
816
817
818 ///////////////////////////////////////////////////////////
819 // //
820 ///////////////////////////////////////////////////////////
821
822 //---------------------------------------------------------
Get_Thumbnail(int dx,int dy)823 const wxBitmap & CWKSP_Layer::Get_Thumbnail(int dx, int dy)
824 {
825 if( dx > 0 && dy > 0 && (!m_Thumbnail.IsOk() || m_Thumbnail.GetWidth() != dx || m_Thumbnail.GetHeight() != dy) )
826 {
827 m_Thumbnail.Create(dx, dy);
828
829 _Set_Thumbnail(false);
830 }
831
832 return( m_Thumbnail );
833 }
834
835 //---------------------------------------------------------
_Set_Thumbnail(bool bRefresh)836 bool CWKSP_Layer::_Set_Thumbnail(bool bRefresh)
837 {
838 if( m_pObject && m_Thumbnail.IsOk() && m_Thumbnail.GetWidth() > 0 && m_Thumbnail.GetHeight() > 0 )
839 {
840 wxMemoryDC dc;
841 wxRect r(0, 0, m_Thumbnail.GetWidth(), m_Thumbnail.GetHeight());
842 CWKSP_Map_DC dc_Map(Get_Extent(), r, 1., SG_GET_RGB(255, 255, 255));
843
844 Draw(dc_Map, LAYER_DRAW_FLAG_NOEDITS|LAYER_DRAW_FLAG_NOLABELS|LAYER_DRAW_FLAG_THUMBNAIL);
845
846 dc.SelectObject(m_Thumbnail);
847 dc.SetBackground(*wxWHITE_BRUSH);
848 dc.Clear();
849
850 dc_Map.Draw(dc);
851
852 dc.SelectObject(wxNullBitmap);
853
854 if( bRefresh )
855 {
856 g_pData_Buttons->Refresh(false);
857 }
858
859 return( true );
860 }
861
862 return( false );
863 }
864
865
866 ///////////////////////////////////////////////////////////
867 // //
868 ///////////////////////////////////////////////////////////
869
870 //---------------------------------------------------------
Get_Extent(void)871 CSG_Rect CWKSP_Layer::Get_Extent(void)
872 {
873 if( m_pObject )
874 {
875 switch( m_pObject->Get_ObjectType() )
876 {
877 case SG_DATAOBJECT_TYPE_Grid:
878 return( ((CSG_Grid *)m_pObject)->Get_Extent(true) );
879
880 case SG_DATAOBJECT_TYPE_Grids:
881 return( ((CSG_Grids *)m_pObject)->Get_Extent(true) );
882
883 case SG_DATAOBJECT_TYPE_Shapes:
884 return( ((CSG_Shapes *)m_pObject)->Get_Extent() );
885
886 case SG_DATAOBJECT_TYPE_TIN:
887 return( ((CSG_TIN *)m_pObject)->Get_Extent() );
888
889 case SG_DATAOBJECT_TYPE_PointCloud:
890 return( ((CSG_PointCloud *)m_pObject)->Get_Extent() );
891
892 default:
893 break;
894 }
895 }
896
897 return( CSG_Rect(0., 0., 0., 0.) );
898 }
899
900
901 ///////////////////////////////////////////////////////////
902 // //
903 ///////////////////////////////////////////////////////////
904
905 //---------------------------------------------------------
_Set_Projection(void)906 void CWKSP_Layer::_Set_Projection(void)
907 {
908 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 15, true); // CCRS_Picker
909
910 CSG_Projection Projection(Get_Object()->Get_Projection());
911
912 if( pTool
913 && pTool->Set_Parameter("CRS_EPSG" , Projection.Get_Authority_ID())
914 && pTool->Set_Parameter("CRS_EPSG_AUTH", Projection.Get_Authority ())
915 && pTool->Set_Parameter("CRS_PROJ4" , Projection.Get_Proj4 ())
916 && pTool->On_Before_Execution() && DLG_Parameters(pTool->Get_Parameters()) )
917 {
918 Projection.Destroy();
919
920 if( pTool->Get_Parameter("CRS_EPSG")->asInt() > 0 )
921 {
922 Projection.Create(
923 pTool->Get_Parameter("CRS_EPSG" )->asInt (),
924 pTool->Get_Parameter("CRS_EPSG_AUTH")->asString()
925 );
926 }
927
928 if( !Projection.is_Okay() )
929 {
930 Projection.Create(
931 pTool->Get_Parameter("CRS_PROJ4")->asString(), SG_PROJ_FMT_Proj4
932 );
933 }
934
935 if( Projection.is_Okay() && !Projection.is_Equal(Get_Object()->Get_Projection()) )
936 {
937 Get_Object()->Get_Projection().Create(Projection);
938 Get_Object()->Set_Modified();
939
940 DataObject_Changed();
941 }
942 }
943
944 SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
945 }
946
947
948 ///////////////////////////////////////////////////////////
949 // //
950 ///////////////////////////////////////////////////////////
951
952 //---------------------------------------------------------
Get_Colors(void)953 CSG_Colors * CWKSP_Layer::Get_Colors(void)
954 {
955 return( m_pClassify->Get_Metric_Colors() );
956 }
957
958 //---------------------------------------------------------
Get_Colors(CSG_Colors * pColors)959 bool CWKSP_Layer::Get_Colors(CSG_Colors *pColors)
960 {
961 if( m_pClassify->Get_Metric_Colors() && pColors )
962 {
963 return( pColors->Assign(m_pClassify->Get_Metric_Colors()) );
964 }
965
966 return( false );
967 }
968
969 //---------------------------------------------------------
Set_Colors(CSG_Colors * pColors)970 bool CWKSP_Layer::Set_Colors(CSG_Colors *pColors)
971 {
972 if( m_pClassify->Get_Metric_Colors() && pColors && m_pClassify->Get_Metric_Colors()->Assign(pColors) )
973 {
974 Parameters_Changed();
975
976 return( true );
977 }
978
979 return( false );
980 }
981
982 //---------------------------------------------------------
Set_Color_Range(double Minimum,double Maximum)983 bool CWKSP_Layer::Set_Color_Range(double Minimum, double Maximum)
984 {
985 m_Parameters.Set_Parameter("STRETCH_DEFAULT" , 3); // manual
986 m_Parameters.Set_Parameter("METRIC_ZRANGE.MIN", Minimum < Maximum ? Minimum : Maximum);
987 m_Parameters.Set_Parameter("METRIC_ZRANGE.MAX", Minimum < Maximum ? Maximum : Minimum);
988
989 Parameters_Changed();
990
991 return( true );
992
993 // return( DataObject_Changed() );
994 }
995
996
997 ///////////////////////////////////////////////////////////
998 // //
999 ///////////////////////////////////////////////////////////
1000
1001 //---------------------------------------------------------
do_Legend(void)1002 bool CWKSP_Layer::do_Legend(void)
1003 {
1004 return( m_Parameters("LEGEND_SHOW")->asBool() );
1005 }
1006
1007 //---------------------------------------------------------
do_Show(CSG_Rect const & Map_Extent,bool bIntersects)1008 bool CWKSP_Layer::do_Show(CSG_Rect const &Map_Extent, bool bIntersects)
1009 {
1010 if( bIntersects && !Map_Extent.Intersects(Get_Extent()) && !Map_Extent.Intersects(Edit_Get_Extent()) )
1011 {
1012 return( false );
1013 }
1014
1015 if( !m_Parameters("SHOW_ALWAYS")->asBool() )
1016 {
1017 double d = Map_Extent.Get_XRange() > Map_Extent.Get_YRange()
1018 ? Map_Extent.Get_XRange()
1019 : Map_Extent.Get_YRange();
1020
1021 return( m_Parameters("SHOW_RANGE.MIN")->asDouble() <= d
1022 && m_Parameters("SHOW_RANGE.MAX")->asDouble() >= d
1023 );
1024 }
1025
1026 return( true );
1027 }
1028
1029
1030 ///////////////////////////////////////////////////////////
1031 // //
1032 ///////////////////////////////////////////////////////////
1033
1034 //---------------------------------------------------------
Draw(CWKSP_Map_DC & dc_Map,int Flags,CSG_Data_Object * pObject)1035 bool CWKSP_Layer::Draw(CWKSP_Map_DC &dc_Map, int Flags, CSG_Data_Object *pObject)
1036 {
1037 if( pObject && pObject->is_Valid() && pObject->Get_ObjectType() == m_pObject->Get_ObjectType() )
1038 {
1039 CSG_Data_Object *pOriginal = m_pObject;
1040
1041 m_pObject = pObject;
1042
1043 On_Draw(dc_Map, Flags);
1044
1045 m_pObject = pOriginal;
1046 }
1047 else
1048 {
1049 On_Draw(dc_Map, Flags);
1050 }
1051
1052 dc_Map.dc.SetBrush(wxNullBrush);
1053 dc_Map.dc.SetPen (wxNullPen );
1054
1055 return( true );
1056 }
1057
1058
1059 ///////////////////////////////////////////////////////////
1060 // //
1061 ///////////////////////////////////////////////////////////
1062
1063 //---------------------------------------------------------
Show(CWKSP_Map * pMap)1064 bool CWKSP_Layer::Show(CWKSP_Map *pMap)
1065 {
1066 if( pMap != NULL )
1067 {
1068 if( g_pMaps->Add(this, pMap) )
1069 {
1070 pMap->View_Show(true);
1071
1072 return( true );
1073 }
1074 }
1075 else
1076 {
1077 for(int i=0; i<g_pMaps->Get_Count(); i++)
1078 {
1079 if( g_pMaps->Get_Map(i)->Get_Map_Layer(this) != NULL )
1080 {
1081 pMap = g_pMaps->Get_Map(i);
1082
1083 pMap->View_Show(true);
1084
1085 return( true );
1086 }
1087 }
1088
1089 if( g_pMaps->Add(this, NULL) )
1090 {
1091 return( Show((CWKSP_Map *)NULL) );
1092 }
1093 }
1094
1095 return( false );
1096 }
1097
1098 //---------------------------------------------------------
Show(int Flags)1099 bool CWKSP_Layer::Show(int Flags)
1100 {
1101 switch( Flags )
1102 {
1103 case SG_UI_DATAOBJECT_SHOW:
1104 return( Show((CWKSP_Map *)NULL) );
1105
1106 case SG_UI_DATAOBJECT_SHOW_NEW_MAP:
1107 g_pMaps->Add(this, NULL);
1108
1109 case SG_UI_DATAOBJECT_SHOW_LAST_MAP:
1110 return( Show(g_pMaps->Get_Map(g_pMaps->Get_Count() - 1)) );
1111 }
1112
1113 return( true );
1114 }
1115
1116 //---------------------------------------------------------
Update(CWKSP_Layer * pChanged)1117 bool CWKSP_Layer::Update(CWKSP_Layer *pChanged)
1118 {
1119 return( pChanged == this );
1120 }
1121
1122 //---------------------------------------------------------
On_Update_Views(bool bAll)1123 void CWKSP_Layer::On_Update_Views(bool bAll)
1124 {
1125 _Set_Thumbnail(true);
1126
1127 g_pMaps->Update(this, !bAll);
1128
1129 if( bAll )
1130 {
1131 On_Update_Views();
1132 }
1133 }
1134
1135 //---------------------------------------------------------
View_Closes(MDI_ChildFrame * pView)1136 bool CWKSP_Layer::View_Closes(MDI_ChildFrame *pView)
1137 {
1138 if( pView == m_pHistogram )
1139 {
1140 m_pHistogram = NULL;
1141 }
1142
1143 return( CWKSP_Data_Item::View_Closes(pView) );
1144 }
1145
1146
1147 ///////////////////////////////////////////////////////////
1148 // //
1149 ///////////////////////////////////////////////////////////
1150
1151 //---------------------------------------------------------
Histogram_Show(bool bShow)1152 void CWKSP_Layer::Histogram_Show(bool bShow)
1153 {
1154 if( bShow && !m_pHistogram )
1155 {
1156 m_pHistogram = new CVIEW_Histogram(this);
1157 }
1158 else if( !bShow && m_pHistogram )
1159 {
1160 m_pHistogram->Destroy();
1161 delete(m_pHistogram);
1162 }
1163 }
1164
1165 //---------------------------------------------------------
Histogram_Toggle(void)1166 void CWKSP_Layer::Histogram_Toggle(void)
1167 {
1168 Histogram_Show( m_pHistogram == NULL );
1169 }
1170
1171
1172 ///////////////////////////////////////////////////////////
1173 // //
1174 ///////////////////////////////////////////////////////////
1175
1176
1177 //---------------------------------------------------------
Edit_Get_Menu(void)1178 wxMenu * CWKSP_Layer::Edit_Get_Menu(void)
1179 {
1180 return( NULL );
1181 }
1182
1183 //---------------------------------------------------------
Edit_On_Key_Down(int KeyCode)1184 bool CWKSP_Layer::Edit_On_Key_Down(int KeyCode)
1185 {
1186 return( false );
1187 }
1188
1189 //---------------------------------------------------------
Edit_On_Mouse_Down(CSG_Point Point,double ClientToWorld,int Key)1190 bool CWKSP_Layer::Edit_On_Mouse_Down(CSG_Point Point, double ClientToWorld, int Key)
1191 {
1192 m_Edit_Mouse_Down = Point;
1193
1194 return( true );
1195 }
1196
1197 //---------------------------------------------------------
Edit_On_Mouse_Up(CSG_Point Point,double ClientToWorld,int Key)1198 bool CWKSP_Layer::Edit_On_Mouse_Up(CSG_Point Point, double ClientToWorld, int Key)
1199 {
1200 return( false );
1201 }
1202
1203 //---------------------------------------------------------
Edit_On_Mouse_Move(wxWindow * pMap,CSG_Rect rWorld,wxPoint pt,wxPoint ptLast,int Key)1204 bool CWKSP_Layer::Edit_On_Mouse_Move(wxWindow *pMap, CSG_Rect rWorld, wxPoint pt, wxPoint ptLast, int Key)
1205 {
1206 return( false );
1207 }
1208
1209 //---------------------------------------------------------
Edit_Set_Index(int Index)1210 bool CWKSP_Layer::Edit_Set_Index(int Index)
1211 {
1212 return( true );
1213 }
1214
1215 //---------------------------------------------------------
Edit_Get_Index(void)1216 int CWKSP_Layer::Edit_Get_Index(void)
1217 {
1218 return( m_Edit_Index );
1219 }
1220
1221 //---------------------------------------------------------
Edit_Get_Attributes(void)1222 CSG_Table * CWKSP_Layer::Edit_Get_Attributes(void)
1223 {
1224 return( &m_Edit_Attributes );
1225 }
1226
1227
1228 ///////////////////////////////////////////////////////////
1229 // //
1230 // //
1231 // //
1232 ///////////////////////////////////////////////////////////
1233
1234 //---------------------------------------------------------
1235