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_Shapes.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 <saga_gdi/sgdi_helper.h>
52 
53 #include "res_commands.h"
54 #include "res_dialogs.h"
55 
56 #include "helper.h"
57 
58 #include "active.h"
59 
60 #include "wksp_layer_classify.h"
61 
62 #include "wksp_data_manager.h"
63 
64 #include "wksp_shapes.h"
65 #include "wksp_table.h"
66 
67 #include "data_source_pgsql.h"
68 
69 
70 ///////////////////////////////////////////////////////////
71 //														 //
72 //														 //
73 //														 //
74 ///////////////////////////////////////////////////////////
75 
76 //---------------------------------------------------------
CWKSP_Shapes(CSG_Shapes * pShapes)77 CWKSP_Shapes::CWKSP_Shapes(CSG_Shapes *pShapes)
78 	: CWKSP_Layer(pShapes)
79 {
80 	m_pTable		= new CWKSP_Table(pShapes);
81 
82 	m_fInfo			= -1;
83 
84 	m_Edit_Shapes.Create(pShapes->Get_Type());
85 	m_Edit_pShape	= NULL;
86 
87 	m_Edit_Attributes.Destroy();
88 	m_Edit_Attributes.Add_Field(_TL("Name" ), SG_DATATYPE_String);
89 	m_Edit_Attributes.Add_Field(_TL("Value"), SG_DATATYPE_String);
90 
91 	m_Edit_Color    = *wxBLACK;
92 	m_Edit_bGleam	= true;
93 	m_Edit_Mode		= EDIT_SHAPE_MODE_Normal;
94 
95 	m_Sel_Color		= *wxRED;
96 
97 	m_bVertices		= 0;
98 }
99 
100 //---------------------------------------------------------
~CWKSP_Shapes(void)101 CWKSP_Shapes::~CWKSP_Shapes(void)
102 {
103 	delete(m_pTable);
104 }
105 
106 
107 ///////////////////////////////////////////////////////////
108 //														 //
109 ///////////////////////////////////////////////////////////
110 
111 //---------------------------------------------------------
Get_Description(void)112 wxString CWKSP_Shapes::Get_Description(void)
113 {
114 	wxString	s;
115 
116 	//-----------------------------------------------------
117 	s	+= wxString::Format("<h4>%s</h4>", _TL("Shapes"));
118 
119 	s	+= "<table border=\"0\">";
120 
121 	DESC_ADD_STR(_TL("Name"            ), m_pObject->Get_Name());
122 	DESC_ADD_STR(_TL("Description"     ), m_pObject->Get_Description());
123 
124 	if( SG_File_Exists(m_pObject->Get_File_Name(false)) )
125 	{
126 		DESC_ADD_STR(_TL("File"        ), m_pObject->Get_File_Name(false));
127 
128 		if( m_pObject->Get_MetaData()("GDAL_DRIVER") )
129 			DESC_ADD_STR(_TL("Driver"  ), m_pObject->Get_MetaData()["GDAL_DRIVER"].Get_Content().c_str());
130 	}
131 	else if( m_pObject->Get_MetaData_DB().Get_Children_Count() )
132 	{
133 		DESC_ADD_STR(_TL("File"        ), m_pObject->Get_File_Name(false));
134 	}
135 	else
136 	{
137 		DESC_ADD_STR(_TL("File"        ), _TL("memory"));
138 	}
139 
140 	DESC_ADD_STR  (_TL("Modified"        ), m_pObject->is_Modified() ? _TL("yes") : _TL("no"));
141 	DESC_ADD_STR  (_TL("Projection"      ), m_pObject->Get_Projection().Get_Description().c_str());
142 	DESC_ADD_FLT  (_TL("West"            ), Get_Shapes()->Get_Extent().Get_XMin  ());
143 	DESC_ADD_FLT  (_TL("East"            ), Get_Shapes()->Get_Extent().Get_XMax  ());
144 	DESC_ADD_FLT  (_TL("West-East"       ), Get_Shapes()->Get_Extent().Get_XRange());
145 	DESC_ADD_FLT  (_TL("South"           ), Get_Shapes()->Get_Extent().Get_YMin  ());
146 	DESC_ADD_FLT  (_TL("North"           ), Get_Shapes()->Get_Extent().Get_YMax  ());
147 	DESC_ADD_FLT  (_TL("South-North"     ), Get_Shapes()->Get_Extent().Get_YRange());
148 	DESC_ADD_STR  (_TL("Type"            ), SG_Get_ShapeType_Name(Get_Shapes()->Get_Type()).c_str());
149 	DESC_ADD_STR  (_TL("Vertex Type"     ), Get_Shapes()->Get_Vertex_Type() == 0 ? _TL("X, Y") : Get_Shapes()->Get_Vertex_Type() == 1 ? _TL("X, Y, Z") : _TL("X, Y, Z, M"));
150 	DESC_ADD_INT  (_TL("Number of Shapes"), Get_Shapes()->Get_Count());
151 	DESC_ADD_SIZET(_TL("Selected"        ), Get_Shapes()->Get_Selection_Count());
152 	DESC_ADD_STR  (_TL("File Encoding"   ), Get_Shapes()->Get_File_Encoding() ? SG_T("UTF-8") : SG_T("ANSI"));
153 
154 	s	+= "</table>";
155 
156 	s	+= Get_TableInfo_asHTML(Get_Shapes());
157 
158 	//-----------------------------------------------------
159 //	s	+= wxString::Format(wxT("<hr><b>%s</b><font size=\"-1\">"), _TL("Data History"));
160 //	s	+= Get_Shapes()->Get_History().Get_HTML();
161 //	s	+= wxString::Format(wxT("</font"));
162 
163 	return( s );
164 }
165 
166 //---------------------------------------------------------
Get_Menu(void)167 wxMenu * CWKSP_Shapes::Get_Menu(void)
168 {
169 	wxMenu	*pMenu	= new wxMenu(m_pObject->Get_Name());
170 
171 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_CLOSE);
172 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SHOW);
173 
174 	pMenu->AppendSeparator();
175 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVE);
176 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVEAS);
177 
178 	if( PGSQL_has_Connections() )
179 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_SAVETODB);
180 
181 	if( m_pObject->is_File_Native() && m_pObject->is_Modified() )
182 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_RELOAD);
183 
184 	if( m_pObject->is_File_Native() )
185 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_DEL_FILES);
186 
187 	pMenu->AppendSeparator();
188 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECTION);
189 
190 	if( m_pObject->Get_MetaData().Get_Children_Count() > 0 )
191 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_METADATA);
192 
193 	pMenu->AppendSeparator();
194 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_SHAPES_HISTOGRAM);
195 
196 	pMenu->AppendSeparator();
197 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SET_LUT);
198 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_CLASSIFY_IMPORT);
199 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SETTINGS_COPY);
200 
201 	pMenu->AppendSeparator();
202 	wxMenu	*pTable	= new wxMenu(_TL("Attributes"));
203 	CMD_Menu_Add_Item(pTable,  true, ID_CMD_TABLE_SHOW);
204 	CMD_Menu_Add_Item(pTable,  true, ID_CMD_TABLE_DIAGRAM);
205 	CMD_Menu_Add_Item(pTable, false, ID_CMD_TABLE_SCATTERPLOT);
206 	CMD_Menu_Add_Item(pTable, false, ID_CMD_SHAPES_SAVE_ATTRIBUTES);
207 	pMenu->Append(ID_CMD_WKSP_FIRST, _TL("Attributes"), pTable);
208 
209 	pMenu->Append(ID_CMD_WKSP_FIRST, _TL("Edit"), Edit_Get_Menu());
210 
211 	return( pMenu );
212 }
213 
214 
215 ///////////////////////////////////////////////////////////
216 //														 //
217 ///////////////////////////////////////////////////////////
218 
219 //---------------------------------------------------------
On_Command(int Cmd_ID)220 bool CWKSP_Shapes::On_Command(int Cmd_ID)
221 {
222 	switch( Cmd_ID )
223 	{
224 	default:
225 		return( CWKSP_Layer::On_Command(Cmd_ID) );
226 
227 	//-----------------------------------------------------
228 	case ID_CMD_SHAPES_SET_LUT       :	_LUT_Create     ();	break;
229 	case ID_CMD_DATA_CLASSIFY_IMPORT :  _LUT_Import     ();	break;
230 	case ID_CMD_SHAPES_HISTOGRAM     :	Histogram_Toggle();	break;
231 
232 	//-----------------------------------------------------
233 	case ID_CMD_SHAPES_EDIT_SHAPE    :	_Edit_Shape    ();	break;
234 	case ID_CMD_SHAPES_EDIT_ADD_SHAPE:	_Edit_Shape_Add();	break;
235 	case ID_CMD_SHAPES_EDIT_DEL_SHAPE:	_Edit_Shape_Del();	break;
236 	case ID_CMD_SHAPES_EDIT_ADD_PART :	_Edit_Part_Add ();	break;
237 	case ID_CMD_SHAPES_EDIT_DEL_PART :	_Edit_Part_Del ();	break;
238 	case ID_CMD_SHAPES_EDIT_DEL_POINT:	_Edit_Point_Del();	break;
239 	case ID_CMD_SHAPES_EDIT_MERGE    :	_Edit_Merge    ();	break;
240 	case ID_CMD_SHAPES_EDIT_SPLIT    :	_Edit_Split    ();	break;
241 	case ID_CMD_SHAPES_EDIT_MOVE     :	_Edit_Move     ();	break;
242 
243 	case ID_CMD_SHAPES_EDIT_SEL_CLEAR:
244 		Get_Shapes()->Select();
245 		Update_Views();
246 		break;
247 
248 	case ID_CMD_SHAPES_EDIT_SEL_INVERT:
249 		Get_Shapes()->Inv_Selection();
250 		Update_Views();
251 		break;
252 
253 	//-----------------------------------------------------
254 	case ID_CMD_TABLE_SHOW   :	m_pTable->Toggle_View   ();	break;
255 	case ID_CMD_TABLE_DIAGRAM:	m_pTable->Toggle_Diagram();	break;
256 
257 	case ID_CMD_TABLE_SCATTERPLOT:
258 		Add_ScatterPlot();
259 		break;
260 
261 	case ID_CMD_SHAPES_SAVE_ATTRIBUTES:
262 		{
263 			wxString	File(m_pObject->Get_File_Name());
264 
265 			if( DLG_Save(File, ID_DLG_TABLE_SAVE) )
266 			{
267 				CSG_Table	Table(*((CSG_Table *)m_pObject));
268 
269 				Table.Save(&File);
270 			}
271 		}
272 		break;
273 	}
274 
275 	return( true );
276 }
277 
278 //---------------------------------------------------------
On_Command_UI(wxUpdateUIEvent & event)279 bool CWKSP_Shapes::On_Command_UI(wxUpdateUIEvent &event)
280 {
281 	switch( event.GetId() )
282 	{
283 	default:
284 		return( CWKSP_Layer::On_Command_UI(event) );
285 
286 	case ID_CMD_SHAPES_EDIT_SHAPE:
287 		event.Enable(Get_Shapes()->Get_Selection_Count() > 0 || m_Edit_pShape != NULL);
288 		event.Check(m_Edit_pShape != NULL);
289 		break;
290 
291 	case ID_CMD_SHAPES_EDIT_ADD_SHAPE:
292 		event.Enable(m_Edit_pShape == NULL);
293 		break;
294 
295 	case ID_CMD_SHAPES_EDIT_DEL_SHAPE:
296 		event.Enable(Get_Shapes()->Get_Selection_Count() > 0 && m_Edit_pShape == NULL);
297 		break;
298 
299 	case ID_CMD_SHAPES_EDIT_ADD_PART:
300 		event.Enable(m_Edit_pShape != NULL);
301 		break;
302 
303 	case ID_CMD_SHAPES_EDIT_DEL_PART:
304 		event.Enable(m_Edit_pShape != NULL && m_Edit_iPart >= 0);
305 		break;
306 
307 	case ID_CMD_SHAPES_EDIT_DEL_POINT:
308 		event.Enable(m_Edit_pShape != NULL && m_Edit_iPart >= 0 && m_Edit_iPoint >= 0);
309 		break;
310 
311 	case ID_CMD_SHAPES_EDIT_SEL_CLEAR:
312 		event.Enable(m_Edit_pShape == NULL && Get_Shapes()->Get_Selection_Count() > 0);
313 		break;
314 
315 	case ID_CMD_SHAPES_EDIT_SEL_INVERT:
316 		event.Enable(m_Edit_pShape == NULL);
317 		break;
318 
319 	case ID_CMD_TABLE_SHOW:
320 		event.Check(m_pTable->Get_View() != NULL);
321 		break;
322 
323 	case ID_CMD_TABLE_DIAGRAM:
324 		event.Check(m_pTable->Get_Diagram() != NULL);
325 		break;
326 
327 	case ID_CMD_SHAPES_HISTOGRAM:
328 		event.Check(m_pHistogram != NULL);
329 		break;
330 
331 	case ID_CMD_SHAPES_EDIT_MOVE:
332 		event.Check(m_Edit_Mode == EDIT_SHAPE_MODE_Move);
333 		break;
334 	}
335 
336 	return( true );
337 }
338 
339 
340 ///////////////////////////////////////////////////////////
341 //														 //
342 ///////////////////////////////////////////////////////////
343 
344 //---------------------------------------------------------
On_Create_Parameters(void)345 void CWKSP_Shapes::On_Create_Parameters(void)
346 {
347 	CWKSP_Layer::On_Create_Parameters();
348 
349 	//-----------------------------------------------------
350 	// General...
351 
352 	m_Parameters.Add_Choice("NODE_GENERAL",
353 		"INFO_ATTRIB"	, _TL("Additional Information"),
354 		_TL("Field that provides file paths to additional record information (HTML formatted), either absolute or relative to this data set."),
355 		_TL("<default>")
356 	);
357 
358 	//-----------------------------------------------------
359 	// Display...
360 
361 	m_Parameters.Add_Parameters("NODE_DISPLAY",
362 		"DISPLAY_CHART"	, _TL("Chart"), _TL("")
363 	);
364 
365 	//-----------------------------------------------------
366 	// Classification...
367 
368 	m_Parameters.Add_Bool("NODE_COLORS",
369 		"NODATA_SHOW"	, _TL("Show No-Data"), _TL(""), true
370 	);
371 
372 	m_Parameters.Add_Color("NODATA_SHOW",
373 		"NODATA_COLOR"	, _TL("Color"), _TL(""), SG_COLOR_GREY_LIGHT
374 	);
375 
376 	//-----------------------------------------------------
377 	// Label...
378 
379 	m_Parameters.Add_Choice("NODE_LABEL",
380 		"LABEL_ATTRIB"	, _TL("Attribute"),
381 		_TL(""),
382 		_TL("<default>")
383 	);
384 
385 	m_Parameters.Add_Font("LABEL_ATTRIB",
386 		"LABEL_ATTRIB_FONT"	, _TL("Font"),
387 		_TL("")
388 	);
389 
390 	m_Parameters.Add_Choice("LABEL_ATTRIB",
391 		"LABEL_ATTRIB_PREC"	, _TL("Numerical Precision"),
392 		_TL(""),
393 		CSG_String::Format("%s|%s|%s",
394 			_TL("fit to value"),
395 			_TL("standard"),
396 			SG_T("0|0.1|0.12|0.123|0.1234|0.12345|0.1234567|0.12345678|0.123456789|0.1234567890|0.12345678901|0.123456789012|0.1234567890123|0.12345678901234|0.123456789012345|0.1234567890123456|0.12345678901234567|0.123456789012345678|0.1234567890123456789|0.12345678901234567890")
397 		), 0
398 	);
399 
400 	m_Parameters.Add_Choice("LABEL_ATTRIB",
401 		"LABEL_ATTRIB_SIZE_TYPE", _TL("Size relates to..."),
402 		_TL(""),
403 		CSG_String::Format("%s|%s|",
404 			_TL("Screen"),
405 			_TL("Map Units")
406 		), 0
407 	);
408 
409 	m_Parameters.Add_Choice("LABEL_ATTRIB",
410 		"LABEL_ATTRIB_EFFECT"	, _TL("Boundary Effect"),
411 		_TL(""),
412 		CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
413 			_TL("none"),
414 			_TL("full frame"),
415 			_TL("top"),
416 			_TL("top left"),
417 			_TL("left"),
418 			_TL("bottom left"),
419 			_TL("bottom"),
420 			_TL("bottom right"),
421 			_TL("right"),
422 			_TL("top right")
423 		), 1
424 	);
425 
426 	m_Parameters.Add_Color("LABEL_ATTRIB_EFFECT",
427 		"LABEL_ATTRIB_EFFECT_COLOR"	, _TL("Color"),
428 		_TL(""),
429 		SG_GET_RGB(255, 255, 255)
430 	);
431 
432 	m_Parameters.Add_Int("LABEL_ATTRIB_EFFECT",
433 		"LABEL_ATTRIB_EFFECT_SIZE"	, _TL("Size"),
434 		_TL(""),
435 		1, 1, true
436 	);
437 
438 	m_Parameters.Add_Choice("LABEL_ATTRIB",
439 		"LABEL_ATTRIB_SIZE_BY"		, _TL("Size by Attribute"),
440 		_TL(""),
441 		_TL("<default>")
442 	);
443 
444 	m_Parameters.Add_Double("LABEL_ATTRIB_SIZE_BY",
445 		"LABEL_ATTRIB_SIZE"			, _TL("Default Size"),
446 		_TL(""),
447 		100., 0., true
448 	);
449 
450 	//-----------------------------------------------------
451 	// Selection...
452 
453 	m_Parameters.Add_Color("NODE_SELECTION",
454 		"SEL_COLOR"		, _TL("Color"),
455 		_TL(""),
456 		m_Sel_Color.GetRGB()
457 	);
458 
459 	//-----------------------------------------------------
460 	// Edit...
461 
462 	m_Parameters.Add_Color("NODE_EDIT",
463 		"EDIT_COLOR"	, _TL("Color"),
464 		_TL(""),
465 		m_Edit_Color.GetRGB()
466 	);
467 
468 	m_Parameters.Add_Bool("NODE_EDIT",
469 		"EDIT_GLEAM"	, _TL("Gleam"),
470 		_TL(""),
471 		m_Edit_bGleam
472 	);
473 
474 	m_Parameters.Add_Shapes_List("NODE_EDIT",
475 		"EDIT_SNAP_LIST", _TL("Snap to..."),
476 		_TL(""),
477 		PARAMETER_INPUT
478 	)->asShapesList()->Add_Item(m_pObject);
479 
480 	m_Parameters.Add_Int("EDIT_SNAP_LIST",
481 		"EDIT_SNAP_DIST", _TL("Snap Distance"),
482 		_TL("snap distance in screen units (pixels)"),
483 		10, 0, true
484 	);
485 
486 	m_Parameters("LUT")->asTable()->Set_Field_Type(LUT_MIN, SG_DATATYPE_String);
487 	m_Parameters("LUT")->asTable()->Set_Field_Type(LUT_MAX, SG_DATATYPE_String);
488 }
489 
490 
491 ///////////////////////////////////////////////////////////
492 //														 //
493 ///////////////////////////////////////////////////////////
494 
495 //---------------------------------------------------------
On_DataObject_Changed(void)496 void CWKSP_Shapes::On_DataObject_Changed(void)
497 {
498 	AttributeList_Set(m_Parameters("LUT_ATTRIB"          ), false);
499 	AttributeList_Set(m_Parameters("METRIC_ATTRIB"       ), false);
500 	AttributeList_Set(m_Parameters("METRIC_NORMAL"       ), true );
501 	AttributeList_Set(m_Parameters("LABEL_ATTRIB"        ), true );
502 	AttributeList_Set(m_Parameters("LABEL_ATTRIB_SIZE_BY"), true );
503 	AttributeList_Set(m_Parameters("INFO_ATTRIB"         ), true );
504 
505 	_Chart_Set_Options();
506 
507 	//-----------------------------------------------------
508 	CWKSP_Layer::On_DataObject_Changed();
509 
510 	m_pTable->DataObject_Changed();
511 }
512 
513 //---------------------------------------------------------
On_Parameters_Changed(void)514 void CWKSP_Shapes::On_Parameters_Changed(void)
515 {
516 	CWKSP_Layer::On_Parameters_Changed();
517 
518 	//-----------------------------------------------------
519 	switch( m_Parameters("COLORS_TYPE")->asInt() )
520 	{
521 	default:	// CLASSIFY_SINGLE
522 		m_fValue	= -1;
523 		m_fNormal	= -1;
524 		break;
525 
526 	case  1:	// CLASSIFY_LUT
527 		m_fValue	= m_Parameters("LUT_ATTRIB"   )->asInt();	if( m_fValue >= Get_Shapes()->Get_Field_Count() )	{	m_fValue	= -1;	}
528 		m_fNormal	= -1;
529 
530 		{
531 			TSG_Data_Type	Type	= SG_Data_Type_is_Numeric(Get_Shapes()->Get_Field_Type(m_Parameters("LUT_ATTRIB")->asInt())) ? SG_DATATYPE_Double : SG_DATATYPE_String;
532 
533 			m_Parameters("LUT")->asTable()->Set_Field_Type(LUT_MIN, Type);
534 			m_Parameters("LUT")->asTable()->Set_Field_Type(LUT_MAX, Type);
535 		}
536 		break;
537 
538 	case  2:	// CLASSIFY_DISCRETE
539 	case  3:	// CLASSIFY_GRADUATED
540 		m_fValue	= m_Parameters("METRIC_ATTRIB")->asInt();	if( m_fValue  >= Get_Shapes()->Get_Field_Count() )	{	m_fValue	= -1;	}
541 		m_fNormal	= m_Parameters("METRIC_NORMAL")->asInt();	if( m_fNormal >= Get_Shapes()->Get_Field_Count() )	{	m_fNormal	= -1;	}
542 		m_dNormal	= m_Parameters("METRIC_NORFMT")->asInt() == 0 ? 1. : 100.;
543 		break;
544 	}
545 
546 	if( m_fValue < 0 )
547 	{
548 		m_pClassify->Set_Mode(CLASSIFY_SINGLE);
549 	}
550 
551 	m_pClassify->Set_Unique_Color(m_pClassify->Get_Mode() == CLASSIFY_SINGLE
552 		? m_Parameters("SINGLE_COLOR")->asColor()
553 		: m_Parameters("NODATA_COLOR")->asColor()
554 	);
555 
556 	m_bNoData	= m_Parameters("NODATA_SHOW")->asBool();
557 
558 	//-----------------------------------------------------
559 	int	fInfo	= m_Parameters("INFO_ATTRIB")->asInt();
560 
561 	if( fInfo >= Get_Shapes()->Get_Field_Count() )
562 	{
563 		fInfo	= -1;
564 	}
565 
566 	if( m_fInfo != fInfo )
567 	{
568 		m_fInfo	= fInfo;
569 
570 		if( g_pActive->Get_Active() == this )
571 		{
572 			g_pActive->Update_Info();
573 		}
574 	}
575 
576 	//-----------------------------------------------------
577 	if( (m_fLabel = m_Parameters("LABEL_ATTRIB")->asInt()) >= Get_Shapes()->Get_Field_Count() )
578 	{
579 		m_fLabel	= -1;
580 	}
581 
582 	m_Label_Eff_Color	= m_Parameters("LABEL_ATTRIB_EFFECT_COLOR")->asColor();
583 	m_Label_Eff_Size	= m_Parameters("LABEL_ATTRIB_EFFECT_SIZE" )->asInt  ();
584 	m_Label_Prec		= m_Parameters("LABEL_ATTRIB_PREC"        )->asInt  ();
585 
586 	switch( m_Label_Prec )
587 	{
588 	case  0:	m_Label_Prec  = -m_Parameters("TABLE_FLT_DECIMALS")->asInt(); break;
589 	case  1:	m_Label_Prec  = -99; break;
590 	default:	m_Label_Prec -=   2; break;
591 	}
592 
593 	switch( m_Parameters("LABEL_ATTRIB_EFFECT")->asInt() )
594 	{
595 	default:	m_Label_Eff = TEXTEFFECT_NONE       ;	break;
596 	case  1:	m_Label_Eff = TEXTEFFECT_FRAME      ;	break;
597 	case  2:	m_Label_Eff = TEXTEFFECT_TOP        ;	break;
598 	case  3:	m_Label_Eff = TEXTEFFECT_TOPLEFT    ;	break;
599 	case  4:	m_Label_Eff = TEXTEFFECT_LEFT       ;	break;
600 	case  5:	m_Label_Eff = TEXTEFFECT_BOTTOMLEFT ;	break;
601 	case  6:	m_Label_Eff = TEXTEFFECT_BOTTOM     ;	break;
602 	case  7:	m_Label_Eff = TEXTEFFECT_BOTTOMRIGHT;	break;
603 	case  8:	m_Label_Eff = TEXTEFFECT_RIGHT      ;	break;
604 	case  9:	m_Label_Eff = TEXTEFFECT_TOPRIGHT   ;	break;
605 	}
606 
607 	//-----------------------------------------------------
608 	_Chart_Get_Options();
609 }
610 
611 
612 ///////////////////////////////////////////////////////////
613 //														 //
614 ///////////////////////////////////////////////////////////
615 
616 //---------------------------------------------------------
Set_Metrics(int zField,int nField,int nType)617 bool CWKSP_Shapes::Set_Metrics(int zField, int nField, int nType)
618 {
619 	if( zField >= 0 && zField < Get_Shapes()->Get_Field_Count() )
620 	{
621 		if( nField < Get_Shapes()->Get_Field_Count() )
622 		{
623 			m_Metrics.Create();
624 
625 			for(int i=0; i<Get_Shapes()->Get_Count(); i++)
626 			{
627 				double	z	= Get_Shapes()->Get_Record(i)->asDouble(zField);
628 				double	n	= Get_Shapes()->Get_Record(i)->asDouble(nField) / (nType == 0 ? 1. : 100.);
629 
630 				if( !Get_Shapes()->is_NoData_Value(z) && !Get_Shapes()->is_NoData_Value(n) && n != 0. )
631 				{
632 					m_Metrics.Add_Value(z / n);
633 				}
634 			}
635 		}
636 		else
637 		{
638 			m_Metrics.Create(Get_Shapes()->Get_Statistics(zField));
639 		}
640 
641 		return( true );
642 	}
643 
644 	return( false );
645 }
646 
647 
648 ///////////////////////////////////////////////////////////
649 //														 //
650 ///////////////////////////////////////////////////////////
651 
652 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)653 int CWKSP_Shapes::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
654 {
655 	//-----------------------------------------------------
656 	if( pParameters->Cmp_Identifier("CLASSIFY") )
657 	{
658 		if( Flags & PARAMETER_CHECK_ENABLE )
659 		{
660 			if( pParameter->Cmp_Identifier("METHOD") )
661 			{
662 				pParameters->Set_Enabled("COUNT"   , pParameter->asInt() != 0);
663 				pParameters->Set_Enabled("COUNTMAX", pParameter->asInt() == 0);
664 			}
665 		}
666 
667 		return( CWKSP_Layer::On_Parameter_Changed(pParameters, pParameter, Flags) );
668 	}
669 
670 	//-----------------------------------------------------
671 	if( Flags & PARAMETER_CHECK_VALUES )
672 	{
673 		if(	pParameter->Cmp_Identifier("COLORS_TYPE"  )
674 		||	pParameter->Cmp_Identifier("METRIC_ATTRIB")
675 		||	pParameter->Cmp_Identifier("METRIC_NORMAL")
676 		||	pParameter->Cmp_Identifier("METRIC_NORFMT") )
677 		{
678 			Set_Metrics(
679 				pParameters->Get_Parameter("METRIC_ATTRIB")->asInt(),
680 				pParameters->Get_Parameter("METRIC_NORMAL")->asInt(),
681 				pParameters->Get_Parameter("METRIC_NORFMT")->asInt()
682 			);
683 
684 			pParameters->Get_Parameter("METRIC_ZRANGE")->asRange()->Set_Range(
685 				m_Metrics.Get_Minimum(),
686 				m_Metrics.Get_Maximum()
687 			);
688 		}
689 
690 		if( pParameter->Cmp_Identifier("METRIC_NORMAL") )
691 		{
692 			pParameters->Set_Enabled("METRIC_NORFMT", pParameter->asInt() >= 0 && pParameter->asInt() < Get_Shapes()->Get_Field_Count());
693 		}
694 
695 		if(	pParameter->Cmp_Identifier("LUT_ATTRIB")
696 		&&  pParameter->asInt() >= 0 && pParameter->asInt() < Get_Shapes()->Get_Field_Count() )
697 		{
698 			TSG_Data_Type	Type	= SG_Data_Type_is_Numeric(Get_Shapes()->Get_Field_Type(pParameter->asInt()))
699 									? SG_DATATYPE_Double : SG_DATATYPE_String;
700 
701 			pParameters->Get_Parameter("LUT")->asTable()->Set_Field_Type(LUT_MIN, Type);
702 			pParameters->Get_Parameter("LUT")->asTable()->Set_Field_Type(LUT_MAX, Type);
703 		}
704 	}
705 
706 	//-----------------------------------------------------
707 	if( Flags & PARAMETER_CHECK_ENABLE )
708 	{
709 		if(	pParameter->Cmp_Identifier("COLORS_TYPE") )
710 		{
711 			pParameters->Set_Enabled("NODATA_SHOW"  , pParameter->asInt() > 0);	// not 'single symbol'
712 		}
713 
714 		if(	pParameter->Cmp_Identifier("NODATA_SHOW") )
715 		{
716 			pParameters->Set_Enabled("NODATA_COLOR" , pParameter->asBool());
717 		}
718 
719 		if(	pParameter->Cmp_Identifier("METRIC_ATTRIB") )
720 		{
721 			pParameters->Set_Enabled("METRIC_NORMAL", pParameter->asInt() >= 0);
722 		}
723 
724 		if(	pParameter->Cmp_Identifier("OUTLINE") )
725 		{
726 			pParameters->Set_Enabled("OUTLINE_COLOR", pParameter->asBool());
727 			pParameters->Set_Enabled("OUTLINE_SIZE" , pParameter->asBool());
728 		}
729 
730 		if(	pParameter->Cmp_Identifier("LABEL_ATTRIB") )
731 		{
732 			bool	Value	= pParameter->asInt() < Get_Shapes()->Get_Field_Count();
733 
734 			pParameters->Set_Enabled("LABEL_ATTRIB_FONT"     , Value);
735 			pParameters->Set_Enabled("LABEL_ATTRIB_SIZE_TYPE", Value);
736 			pParameters->Set_Enabled("LABEL_ATTRIB_PREC"     , Value);
737 			pParameters->Set_Enabled("LABEL_ATTRIB_SIZE_BY"  , Value);
738 			pParameters->Set_Enabled("LABEL_ATTRIB_EFFECT"   , Value);
739 		}
740 
741 		if( pParameter->Cmp_Identifier("LABEL_ATTRIB_SIZE_TYPE")
742 		||  pParameter->Cmp_Identifier("LABEL_ATTRIB_SIZE_BY"  ) )
743 		{
744 			bool	Value	= pParameters->Get_Parameter("LABEL_ATTRIB_SIZE_TYPE")->asInt() != 0
745 						||    pParameters->Get_Parameter("LABEL_ATTRIB_SIZE_BY"  )->asInt() < Get_Shapes()->Get_Field_Count();
746 
747 			pParameters->Set_Enabled("LABEL_ATTRIB_SIZE", Value);
748 		}
749 
750 		if(	pParameter->Cmp_Identifier("LABEL_ATTRIB_EFFECT") )
751 		{
752 			bool	Value	= pParameter->asInt() > 0;
753 
754 			pParameters->Set_Enabled("LABEL_ATTRIB_EFFECT_COLOR", Value);
755 		}
756 
757 		if(	pParameter->Cmp_Identifier("EDIT_SNAP_LIST") )
758 		{
759 			pParameters->Set_Enabled("EDIT_SNAP_DIST", pParameter->asList()->Get_Item_Count() > 0);
760 		}
761 
762 		if(	pParameters->Cmp_Identifier("DISPLAY_CHART") )
763 		{
764 			CSG_String	s(pParameter->Get_Identifier());
765 
766 			if( s.Find("FIELD_") == 0 )
767 			{
768 				s.Replace("FIELD_", "COLOR_");
769 
770 				pParameters->Set_Enabled(s, pParameter->asBool());
771 			}
772 		}
773 	}
774 
775 	//-----------------------------------------------------
776 	return( CWKSP_Layer::On_Parameter_Changed(pParameters, pParameter, Flags) );
777 }
778 
779 //---------------------------------------------------------
On_Update_Views(void)780 void CWKSP_Shapes::On_Update_Views(void)
781 {
782 	m_pTable->Update_Views();
783 }
784 
785 
786 ///////////////////////////////////////////////////////////
787 //														 //
788 ///////////////////////////////////////////////////////////
789 
790 //---------------------------------------------------------
_LUT_Create(void)791 void CWKSP_Shapes::_LUT_Create(void)
792 {
793 	//-----------------------------------------------------
794 	if( Get_Shapes()->Get_Field_Count() <= 0 || Get_Shapes()->Get_Count() < 1 )
795 	{
796 		DLG_Message_Show(_TL("Function failed because no attributes are available"), _TL("Classify"));
797 
798 		return;
799 	}
800 
801 	//-----------------------------------------------------
802 	static CSG_Parameters	PStatic;
803 
804 	if( PStatic.Get_Count() == 0 )
805 	{
806 		PStatic.Create(_TL("Classify"), _TL(""), SG_T("CLASSIFY"));
807 		PStatic.Add_Choice("", "FIELD"   , _TL("Attribute"                ), _TL(""), "");
808 		PStatic.Add_Colors("", "COLORS"  , _TL("Colors"                   ), _TL(""));
809 		PStatic.Add_Int   ("", "COUNT"   , _TL("Number of Classes"        ), _TL(""),   10, 1, true);
810 		PStatic.Add_Int   ("", "COUNTMAX", _TL("Maximum Number of Classes"), _TL(""), 1000, 1, true);
811 		PStatic.Add_Choice("", "METHOD"  , _TL("Classification"           ), _TL(""),
812 			CSG_String::Format("%s|%s|%s|%s",
813 				_TL("unique values"),
814 				_TL("equal intervals"),
815 				_TL("quantiles"),
816 				_TL("natural breaks")
817 			), 0
818 		);
819 	}
820 
821 	AttributeList_Set(PStatic("FIELD"), false);
822 
823 	CSG_Parameters	Parameters(this, _TL("Classify"), _TL(""), SG_T("CLASSIFY"));
824 
825 	Parameters.Assign_Parameters(&PStatic);
826 
827 	Parameters.Set_Callback_On_Parameter_Changed(&Parameter_Callback);
828 
829 	if( !DLG_Parameters(&Parameters) )
830 	{
831 		return;
832 	}
833 
834 	PStatic.Assign_Values(&Parameters);
835 
836 	//-----------------------------------------------------
837 	DataObject_Changed();
838 
839 	int	Field	= Parameters("FIELD")->asInt();
840 
841 	int	Method	= SG_Data_Type_is_Numeric(Get_Shapes()->Get_Field_Type(Field)) ? Parameters("METHOD")->asInt() : 0;
842 
843 	CSG_Colors	Colors(*Parameters("COLORS")->asColors());
844 
845 	if( Method != 0 )
846 	{
847 		Colors.Set_Count(Parameters("COUNT")->asInt());
848 	}
849 
850 	CSG_Table	Classes(m_Parameters("LUT")->asTable());
851 
852 	switch( Method )
853 	{
854 	//-----------------------------------------------------
855 	case 0:	// unique values
856 		{
857 			TSG_Data_Type	Type	= SG_Data_Type_is_Numeric(Get_Shapes()->Get_Field_Type(Field))
858 				? SG_DATATYPE_Double : SG_DATATYPE_String;
859 
860 			Classes.Set_Field_Type(LUT_MIN, Type);
861 			Classes.Set_Field_Type(LUT_MAX, Type);
862 
863 			CSG_Unique_String_Statistics	s;
864 
865 			int	maxClasses	= Parameters("COUNTMAX")->asInt();
866 
867 			for(int iShape=0; iShape<Get_Shapes()->Get_Count() && s.Get_Count()<maxClasses; iShape++)
868 			{
869 				s	+= Get_Shapes()->Get_Shape(iShape)->asString(Field);
870 			}
871 
872 			Colors.Set_Count(s.Get_Count());
873 
874 			for(int iClass=0; iClass<s.Get_Count(); iClass++)
875 			{
876 				CSG_String	Value	= s.Get_Value(iClass);
877 
878 				CSG_Table_Record	*pClass	= Classes.Add_Record();
879 
880 				pClass->Set_Value(0, Colors[iClass]);	// Color
881 				pClass->Set_Value(1, Value         );	// Name
882 				pClass->Set_Value(2, Value         );	// Description
883 				pClass->Set_Value(3, Value         );	// Minimum
884 				pClass->Set_Value(4, Value         );	// Maximum
885 			}
886 		}
887 		break;
888 
889 	//-----------------------------------------------------
890 	case 1:	// equal intervals
891 		{
892 			double	Minimum, Maximum, Interval;
893 
894 			Interval	= Get_Shapes()->Get_Range  (Field) / (double)Colors.Get_Count();
895 			Minimum		= Get_Shapes()->Get_Minimum(Field);
896 
897 			Classes.Set_Field_Type(LUT_MIN, SG_DATATYPE_Double);
898 			Classes.Set_Field_Type(LUT_MAX, SG_DATATYPE_Double);
899 
900 			for(int iClass=0; iClass<Colors.Get_Count(); iClass++, Minimum+=Interval)
901 			{
902 				Maximum	= iClass < Colors.Get_Count() - 1 ? Minimum + Interval : Get_Shapes()->Get_Maximum(Field) + 1.;
903 
904 				CSG_String	Name	= SG_Get_String(Minimum, -2)
905 							+ " - " + SG_Get_String(Maximum, -2);
906 
907 				CSG_Table_Record	*pClass	= Classes.Add_Record();
908 
909 				pClass->Set_Value(0, Colors[iClass]);	// Color
910 				pClass->Set_Value(1, Name          );	// Name
911 				pClass->Set_Value(2, Name          );	// Description
912 				pClass->Set_Value(3, Minimum       );	// Minimum
913 				pClass->Set_Value(4, Maximum       );	// Maximum
914 			}
915 		}
916 		break;
917 
918 	//-----------------------------------------------------
919 	case 2:	// quantiles
920 		{
921 			TSG_Table_Index_Order	old_Order	= Get_Shapes()->Get_Index_Order(0);
922 			int						old_Field	= Get_Shapes()->Get_Index_Field(0);
923 
924 			Get_Shapes()->Set_Index(Field, TABLE_INDEX_Ascending);
925 
926 			Classes.Set_Field_Type(LUT_MIN, SG_DATATYPE_Double);
927 			Classes.Set_Field_Type(LUT_MAX, SG_DATATYPE_Double);
928 
929 			if( Get_Shapes()->Get_Count() < Colors.Get_Count() )
930 			{
931 				Colors.Set_Count(Get_Shapes()->Get_Count());
932 			}
933 
934 			double	Minimum, Maximum, Count, iRecord;
935 
936 			Maximum	= Get_Shapes()->Get_Minimum(Field);
937 			iRecord	= Count	= Get_Shapes()->Get_Count() / (double)Colors.Get_Count();
938 
939 			for(int iClass=0; iClass<Colors.Get_Count(); iClass++, iRecord+=Count)
940 			{
941 				Minimum	= Maximum;
942 				Maximum	= iRecord < Get_Shapes()->Get_Count() ? Get_Shapes()->Get_Record_byIndex((int)iRecord)->asDouble(Field) : Get_Shapes()->Get_Maximum(Field) + 1.;
943 
944 				CSG_String	Name	= SG_Get_String(Minimum, -2)
945 							+ " - " + SG_Get_String(Maximum, -2);
946 
947 				CSG_Table_Record	*pClass	= Classes.Add_Record();
948 
949 				pClass->Set_Value(0, Colors[iClass]);	// Color
950 				pClass->Set_Value(1, Name          );	// Name
951 				pClass->Set_Value(2, Name          );	// Description
952 				pClass->Set_Value(3, Minimum       );	// Minimum
953 				pClass->Set_Value(4, Maximum       );	// Maximum
954 			}
955 
956 			Get_Shapes()->Set_Index(old_Field, old_Order);
957 		}
958 		break;
959 
960 	//-----------------------------------------------------
961 	case 3:	// natural breaks
962 		{
963 			CSG_Natural_Breaks	Breaks(Get_Shapes(), Field, Colors.Get_Count(), Get_Shapes()->Get_Count() > 4096 ? 256 : 0);
964 
965 			if( Breaks.Get_Count() <= Colors.Get_Count() ) return;
966 
967 			Classes.Set_Field_Type(LUT_MIN, SG_DATATYPE_Double);
968 			Classes.Set_Field_Type(LUT_MAX, SG_DATATYPE_Double);
969 
970 			for(int iClass=0; iClass<Colors.Get_Count(); iClass++)
971 			{
972 				CSG_Table_Record	*pClass	= Classes.Add_Record();
973 
974 				double	Minimum	= Breaks[iClass    ];
975 				double	Maximum	= Breaks[iClass + 1];
976 
977 				CSG_String	Name	= SG_Get_String(Minimum, -2)
978 							+ " - " + SG_Get_String(Maximum, -2);
979 
980 				pClass->Set_Value(0, Colors[iClass]);	// Color
981 				pClass->Set_Value(1, Name          );	// Name
982 				pClass->Set_Value(2, Name          );	// Description
983 				pClass->Set_Value(3, Minimum       );	// Minimum
984 				pClass->Set_Value(4, Maximum       );	// Maximum
985 			}
986 		}
987 		break;
988 	}
989 
990 	//-----------------------------------------------------
991 	if( Classes.Get_Count() > 0 )
992 	{
993 		m_Parameters("LUT")->asTable()->Assign(&Classes);
994 		m_Parameters("LUT")->asTable()->Get_MetaData().Add_Child("SAGA_GUI_LUT_TYPE", m_pObject->Get_ObjectType());
995 
996 		m_Parameters("COLORS_TYPE")->Set_Value(CLASSIFY_LUT);	// Lookup Table
997 		m_Parameters("LUT_ATTRIB" )->Set_Value(Field);
998 
999 		Parameters_Changed();
1000 	}
1001 }
1002 
1003 //---------------------------------------------------------
_LUT_Import(void)1004 void CWKSP_Shapes::_LUT_Import(void)
1005 {
1006 	wxString	File, Filter;
1007 
1008 	Filter.Printf("%s (*.qml)|*.qml|%s|*.*", _TL("QGIS Layer Style File"), _TL("All Files"));
1009 
1010 	if( DLG_Open(File, _TL("Import Classification"), SG_T("QGIS Layer Style File (*.qml)|*.qml|All Files|*.*|")) )
1011 	{
1012 		CSG_Table	Classes;
1013 		CSG_String	Attribute;
1014 
1015 		if( QGIS_Styles_Import(&File, Classes, Attribute) )
1016 		{
1017 			m_Parameters.Set_Parameter("LUT_ATTRIB", Attribute);
1018 
1019 			m_Parameters("LUT")->asTable()->Assign(&Classes);
1020 			m_Parameters("LUT")->asTable()->Get_MetaData().Add_Child("SAGA_GUI_LUT_TYPE", m_pObject->Get_ObjectType());
1021 
1022 			m_Parameters("COLORS_TYPE")->Set_Value(CLASSIFY_LUT);	// Lookup Table
1023 
1024 			Parameters_Changed();
1025 		}
1026 	}
1027 }
1028 
1029 
1030 ///////////////////////////////////////////////////////////
1031 //														 //
1032 ///////////////////////////////////////////////////////////
1033 
1034 //---------------------------------------------------------
Get_Value(CSG_Point ptWorld,double Epsilon)1035 wxString CWKSP_Shapes::Get_Value(CSG_Point ptWorld, double Epsilon)
1036 {
1037 	CSG_Shape	*pShape	= Get_Shapes()->Get_Shape(ptWorld, Epsilon);
1038 
1039 	if( pShape == NULL )
1040 	{
1041 		return( _TL("") );
1042 	}
1043 
1044 	if( m_fValue < 0 )
1045 	{
1046 		return( wxString::Format("%s: %d", _TL("Index"), pShape->Get_Index() + 1) );
1047 	}
1048 
1049 	if( m_pClassify->Get_Mode() == CLASSIFY_LUT )
1050 	{
1051 		return( m_pClassify->Get_Class_Name_byValue(pShape->asString(m_fValue)) );
1052 	}
1053 
1054 	if( !pShape->is_NoData(m_fValue) )
1055 	{
1056 		if( m_fNormal < 0 )
1057 		{
1058 			return( pShape->asString(m_fValue) );
1059 		}
1060 
1061 		if( !pShape->is_NoData(m_fNormal) && pShape->asDouble(m_fNormal) != 0. )
1062 		{
1063 			return( wxString::Format("%f", m_dNormal * pShape->asDouble(m_fValue) / pShape->asDouble(m_fNormal)) );
1064 		}
1065 	}
1066 
1067 	return( _TL("") );
1068 }
1069 
1070 
1071 ///////////////////////////////////////////////////////////
1072 //														 //
1073 ///////////////////////////////////////////////////////////
1074 
1075 //---------------------------------------------------------
Get_Value_Minimum(void)1076 double CWKSP_Shapes::Get_Value_Minimum(void)	{	return( m_Metrics.Get_Minimum() );	}
Get_Value_Maximum(void)1077 double CWKSP_Shapes::Get_Value_Maximum(void)	{	return( m_Metrics.Get_Maximum() );	}
Get_Value_Range(void)1078 double CWKSP_Shapes::Get_Value_Range  (void)	{	return( m_Metrics.Get_Range  () );	}
Get_Value_Mean(void)1079 double CWKSP_Shapes::Get_Value_Mean   (void)	{	return( m_Metrics.Get_Mean   () );	}
Get_Value_StdDev(void)1080 double CWKSP_Shapes::Get_Value_StdDev (void)	{	return( m_Metrics.Get_StdDev () );	}
1081 
1082 
1083 ///////////////////////////////////////////////////////////
1084 //														 //
1085 ///////////////////////////////////////////////////////////
1086 
1087 //---------------------------------------------------------
Get_Name_Attribute(void)1088 wxString CWKSP_Shapes::Get_Name_Attribute(void)
1089 {
1090 	wxString	s;
1091 
1092 	if(	m_fValue >= 0 && m_pClassify->Get_Mode() != CLASSIFY_SINGLE )
1093 	{
1094 		s	= Get_Shapes()->Get_Field_Name(m_fValue);
1095 
1096 		if( m_fNormal >= 0
1097 		&& (m_pClassify->Get_Mode() == CLASSIFY_DISCRETE
1098 		||  m_pClassify->Get_Mode() == CLASSIFY_GRADUATED) )
1099 		{
1100 			s	+= " / "; s += Get_Shapes()->Get_Field_Name(m_fNormal);
1101 		}
1102 	}
1103 
1104 	return( s );
1105 }
1106 
1107 
1108 ///////////////////////////////////////////////////////////
1109 //														 //
1110 ///////////////////////////////////////////////////////////
1111 
1112 //---------------------------------------------------------
On_Draw(CWKSP_Map_DC & dc_Map,int Flags)1113 void CWKSP_Shapes::On_Draw(CWKSP_Map_DC &dc_Map, int Flags)
1114 {
1115 	//-----------------------------------------------------
1116 	if( Get_Extent().Intersects(dc_Map.m_rWorld) == INTERSECTION_None )
1117 	{
1118 		if( m_Edit_pShape )
1119 		{
1120 			Edit_Shape_Draw(dc_Map);
1121 		}
1122 
1123 		return;
1124 	}
1125 
1126 	//-----------------------------------------------------
1127 	if( (Flags & LAYER_DRAW_FLAG_THUMBNAIL) != 0 )
1128 	{
1129 		Draw_Initialize(dc_Map, Flags);
1130 
1131 		for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1132 		{
1133 			_Draw_Shape(dc_Map, Get_Shapes()->Get_Shape(iShape));
1134 		}
1135 
1136 		return;
1137 	}
1138 
1139 	//-----------------------------------------------------
1140 	double	Transparency	= m_Parameters("DISPLAY_TRANSPARENCY")->asDouble() / 100.;
1141 
1142 	CWKSP_Map_DC	*pDC	= Transparency > 0. ? new CWKSP_Map_DC(dc_Map.m_rWorld, dc_Map.m_rDC, dc_Map.m_Scale, SG_GET_RGB(254, 255, 255)) : NULL;
1143 	CWKSP_Map_DC	&dc		= pDC ? *pDC : dc_Map;
1144 
1145 	m_Sel_Color		= Get_Color_asWX(m_Parameters("SEL_COLOR" )->asInt());
1146 	m_Edit_Color	= Get_Color_asWX(m_Parameters("EDIT_COLOR")->asInt());
1147 	m_Edit_bGleam	=                m_Parameters("EDIT_GLEAM")->asBool();
1148 
1149 	Draw_Initialize(dc, Flags);
1150 
1151 	//-----------------------------------------------------
1152 	if( (Flags & LAYER_DRAW_FLAG_NOEDITS) != 0 || !(m_Edit_pShape || Get_Shapes()->Get_Selection_Count()) )
1153 	{
1154 		for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1155 		{
1156 			_Draw_Shape(dc, Get_Shapes()->Get_Shape(iShape));
1157 		}
1158 
1159 		if( _Chart_is_Valid() )
1160 		{
1161 			for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1162 			{
1163 				_Draw_Chart(dc, Get_Shapes()->Get_Shape(iShape));
1164 			}
1165 		}
1166 	}
1167 	else	// selection and/or editing
1168 	{
1169 		for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1170 		{
1171 			if( !Get_Shapes()->Get_Shape(iShape)->is_Selected() )
1172 			{
1173 				_Draw_Shape(dc, Get_Shapes()->Get_Shape(iShape));
1174 			}
1175 		}
1176 
1177 		for(int iShape=0; iShape<(int)Get_Shapes()->Get_Selection_Count(); iShape++)
1178 		{
1179 			if( iShape != m_Edit_Index )
1180 			{
1181 				_Draw_Shape(dc, Get_Shapes()->Get_Selection(iShape), 2);
1182 			}
1183 		}
1184 
1185 		//-------------------------------------------------
1186 		if( !m_Edit_pShape )
1187 		{
1188 			_Draw_Shape(dc, Get_Shapes()->Get_Selection(m_Edit_Index), 1);
1189 		}
1190 		else
1191 		{
1192 			Edit_Shape_Draw(dc);
1193 		}
1194 
1195 		if( m_Edit_Mode == EDIT_SHAPE_MODE_Split )
1196 		{
1197 			CSG_Shape	*pSplit	= m_Edit_Shapes.Get_Shape(1);
1198 
1199 			if( pSplit && pSplit->Get_Point_Count() > 1 )
1200 			{
1201 				for(int i=0; i<=1; i++)
1202 				{
1203 					dc_Map.dc.SetPen(wxPen(i == 0 ? *wxWHITE : *wxBLACK, i == 0 ? 3 : 1));
1204 
1205 					TSG_Point_Int	B, A	= dc_Map.World2DC(pSplit->Get_Point(0));
1206 
1207 					for(int iPoint=1; iPoint<pSplit->Get_Point_Count(); iPoint++)
1208 					{
1209 						B	= A;	A	= dc_Map.World2DC(pSplit->Get_Point(iPoint));
1210 
1211 						dc_Map.dc.DrawLine(A.x, A.y, B.x, B.y);
1212 					}
1213 				}
1214 			}
1215 		}
1216 	}
1217 
1218 	//-----------------------------------------------------
1219 	if( (Flags & LAYER_DRAW_FLAG_NOLABELS) == 0 && m_fLabel >= 0 )	// Labels
1220 	{
1221 		int		iSize	= m_Parameters("LABEL_ATTRIB_SIZE_BY"  )->asInt();
1222 		double	dSize	= m_Parameters("LABEL_ATTRIB_SIZE_TYPE")->asInt() == 1 ?
1223 			dc.m_World2DC * m_Parameters("LABEL_ATTRIB_SIZE")->asDouble() : 1.;
1224 
1225 		dc.dc.SetFont(Get_Font (m_Parameters("LABEL_ATTRIB_FONT")));
1226 		dc.dc.SetTextForeground(m_Parameters("LABEL_ATTRIB_FONT")->asColor());
1227 
1228 		if( iSize >= 0 && iSize < Get_Shapes()->Get_Field_Count() )	// size by attribute
1229 		{
1230 			for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1231 			{
1232 				int	Size	= (int)(0.5 + dSize * Get_Shapes()->Get_Shape(iShape)->asDouble(iSize));
1233 
1234 				if( Size > 0 )
1235 				{
1236 					_Draw_Label(dc, Get_Shapes()->Get_Shape(iShape), Size);
1237 				}
1238 			}
1239 		}
1240 		else	// one size fits all
1241 		{
1242 			int	Size	= m_Parameters("LABEL_ATTRIB_SIZE_TYPE")->asInt() == 1 ? (int)(0.5 + dSize) : dc.dc.GetFont().GetPointSize();
1243 
1244 			if( Size > 0 )
1245 			{
1246 				for(int iShape=0; iShape<Get_Shapes()->Get_Count(); iShape++)
1247 				{
1248 					_Draw_Label(dc, Get_Shapes()->Get_Shape(iShape), Size);
1249 				}
1250 			}
1251 		}
1252 	}
1253 
1254 	//-----------------------------------------------------
1255 	if( pDC )	// Transparency ?
1256 	{
1257 		dc_Map.Draw_DC(dc, Transparency);
1258 
1259 		delete(pDC);
1260 	}
1261 }
1262 
1263 //---------------------------------------------------------
_Draw_Shape(CWKSP_Map_DC & dc_Map,CSG_Shape * pShape,int Selection)1264 void CWKSP_Shapes::_Draw_Shape(CWKSP_Map_DC &dc_Map, CSG_Shape *pShape, int Selection)
1265 {
1266 	if( pShape && dc_Map.m_rWorld.Intersects(pShape->Get_Extent()) != INTERSECTION_None )
1267 	{
1268 		Draw_Shape(dc_Map, pShape, Selection);
1269 
1270 		if( m_bVertices > 0 )
1271 		{
1272 			wxPen	oldPen  (dc_Map.dc.GetPen  ());	dc_Map.dc.SetPen  (*wxBLACK_PEN  );
1273 			wxBrush	oldBrush(dc_Map.dc.GetBrush());	dc_Map.dc.SetBrush(*wxWHITE_BRUSH);
1274 
1275 			for(int iPart=0; iPart<pShape->Get_Part_Count(); iPart++)
1276 			{
1277 				for(int iPoint=0; iPoint<pShape->Get_Point_Count(iPart); iPoint++)
1278 				{
1279 					TSG_Point_Int	A	= dc_Map.World2DC(pShape->Get_Point(iPoint, iPart));
1280 
1281 					dc_Map.dc.DrawCircle(A.x, A.y, 2);
1282 
1283 					if( m_bVertices == 2 )
1284 					{
1285 						Draw_Text(dc_Map.dc, TEXTALIGN_TOPLEFT, A.x, A.y, wxString::Format("%d", iPoint + 1));
1286 					}
1287 				}
1288 			}
1289 
1290 			dc_Map.dc.SetPen  (oldPen  );
1291 			dc_Map.dc.SetBrush(oldBrush);
1292 		}
1293 	}
1294 }
1295 
1296 //---------------------------------------------------------
_Draw_Label(CWKSP_Map_DC & dc_Map,CSG_Shape * pShape,int PointSize)1297 void CWKSP_Shapes::_Draw_Label(CWKSP_Map_DC &dc_Map, CSG_Shape *pShape, int PointSize)
1298 {
1299 	if( pShape && dc_Map.m_rWorld.Intersects(pShape->Get_Extent()) != INTERSECTION_None )
1300 	{
1301 		wxString	Label(pShape->asString(m_fLabel, m_Label_Prec));	Label.Trim(true).Trim(false);
1302 
1303 		if( !Label.IsEmpty() )
1304 		{
1305 			if( PointSize > 0 && PointSize != dc_Map.dc.GetFont().GetPointSize() )
1306 			{
1307 				wxFont	Font(dc_Map.dc.GetFont());
1308 
1309 				Font.SetPointSize(PointSize);
1310 
1311 				dc_Map.dc.SetFont(Font);
1312 			}
1313 
1314 			Draw_Label(dc_Map, pShape, Label);
1315 		}
1316 	}
1317 }
1318 
1319 
1320 ///////////////////////////////////////////////////////////
1321 //														 //
1322 ///////////////////////////////////////////////////////////
1323 
1324 //---------------------------------------------------------
AttributeList_Set(CSG_Parameter * pFields,bool bAddNoField)1325 void CWKSP_Shapes::AttributeList_Set(CSG_Parameter *pFields, bool bAddNoField)
1326 {
1327 	if( pFields && pFields->Get_Type() == PARAMETER_TYPE_Choice )
1328 	{
1329 		CSG_String	Items;
1330 
1331 		for(int i=0; i<Get_Shapes()->Get_Field_Count(); i++)
1332 		{
1333 			Items	+= CSG_String(Get_Shapes()->Get_Field_Name(i)) + "|";
1334 		}
1335 
1336 		if( bAddNoField || Get_Shapes()->Get_Field_Count() == 0 )
1337 		{
1338 			Items	+= CSG_String(_TL("<none>")) + "|";
1339 		}
1340 
1341 		int			iChoice	= pFields->asInt   ();
1342 		CSG_String	sChoice	= pFields->asString();
1343 
1344 		pFields->asChoice()->Set_Items(Items);
1345 
1346 		if( bAddNoField && (iChoice < 0 || iChoice >= pFields->asChoice()->Get_Count() || sChoice.Cmp(pFields->asChoice()->Get_Item(iChoice))) )
1347 		{
1348 			pFields->Set_Value(Get_Shapes()->Get_Field_Count());
1349 		}
1350 	}
1351 }
1352 
1353 
1354 ///////////////////////////////////////////////////////////
1355 //														 //
1356 ///////////////////////////////////////////////////////////
1357 
1358 //---------------------------------------------------------
BrushList_Add(const CSG_String & ParentID,const CSG_String & Identifier,const CSG_String & Name,const CSG_String & Description)1359 CSG_Parameter * CWKSP_Shapes::BrushList_Add(const CSG_String &ParentID, const CSG_String &Identifier, const CSG_String &Name, const CSG_String &Description)
1360 {
1361 	return( m_Parameters.Add_Choice(ParentID, Identifier, Name, Description,
1362 		CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|",
1363 			_TL("Opaque"           ),
1364 			_TL("Transparent"      ),
1365 			_TL("Backward Diagonal"),
1366 			_TL("Cross Diagonal"   ),
1367 			_TL("Forward Diagonal" ),
1368 			_TL("Cross"            ),
1369 			_TL("Horizontal"       ),
1370 			_TL("Vertical"         )
1371 		), 0)
1372 	);
1373 }
1374 
1375 //---------------------------------------------------------
BrushList_Get_Style(const CSG_String & Identifier)1376 wxBrushStyle CWKSP_Shapes::BrushList_Get_Style(const CSG_String &Identifier)
1377 {
1378 	switch( m_Parameters(Identifier)->asInt() )
1379 	{
1380 	default:	return( wxBRUSHSTYLE_SOLID           );
1381 	case  1:	return( wxBRUSHSTYLE_TRANSPARENT     );
1382 	case  2:	return( wxBRUSHSTYLE_BDIAGONAL_HATCH );
1383 	case  3:	return( wxBRUSHSTYLE_CROSSDIAG_HATCH );
1384 	case  4:	return( wxBRUSHSTYLE_FDIAGONAL_HATCH );
1385 	case  5:	return( wxBRUSHSTYLE_CROSS_HATCH     );
1386 	case  6:	return( wxBRUSHSTYLE_HORIZONTAL_HATCH);
1387 	case  7:	return( wxBRUSHSTYLE_VERTICAL_HATCH  );
1388 	}
1389 }
1390 
1391 //---------------------------------------------------------
PenList_Add(const CSG_String & ParentID,const CSG_String & Identifier,const CSG_String & Name,const CSG_String & Description)1392 CSG_Parameter * CWKSP_Shapes::PenList_Add(const CSG_String &ParentID, const CSG_String &Identifier, const CSG_String &Name, const CSG_String &Description)
1393 {
1394 	return( m_Parameters.Add_Choice(ParentID, Identifier, Name, Description,
1395 		CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|",
1396 			_TL("Solid style"),
1397 			_TL("Dotted style"),
1398 			_TL("Long dashed style"),
1399 			_TL("Short dashed style"),
1400 			_TL("Dot and dash style"),
1401 			_TL("Backward diagonal hatch"),
1402 			_TL("Cross-diagonal hatch"),
1403 			_TL("Forward diagonal hatch"),
1404 			_TL("Cross hatch"),
1405 			_TL("Horizontal hatch"),
1406 			_TL("Vertical hatch")
1407 		//	_TL("Use the stipple bitmap")
1408 		//	_TL("Use the user dashes")
1409 		//	_TL("No pen is used")
1410 		), 0)
1411 	);
1412 }
1413 
1414 //---------------------------------------------------------
PenList_Get_Style(const CSG_String & Identifier)1415 int CWKSP_Shapes::PenList_Get_Style(const CSG_String &Identifier)
1416 {
1417 	switch( m_Parameters(Identifier)->asInt() )
1418 	{
1419 	default:	return( wxPENSTYLE_SOLID            ); // Solid style.
1420 	case  1:	return( wxPENSTYLE_DOT              ); // Dotted style.
1421 	case  2:	return( wxPENSTYLE_LONG_DASH        ); // Long dashed style.
1422 	case  3:	return( wxPENSTYLE_SHORT_DASH       ); // Short dashed style.
1423 	case  4:	return( wxPENSTYLE_DOT_DASH         ); // Dot and dash style.
1424 	case  5:	return( wxPENSTYLE_BDIAGONAL_HATCH  ); // Backward diagonal hatch.
1425 	case  6:	return( wxPENSTYLE_CROSSDIAG_HATCH  ); // Cross-diagonal hatch.
1426 	case  7:	return( wxPENSTYLE_FDIAGONAL_HATCH  ); // Forward diagonal hatch.
1427 	case  8:	return( wxPENSTYLE_CROSS_HATCH      ); // Cross hatch.
1428 	case  9:	return( wxPENSTYLE_HORIZONTAL_HATCH ); // Horizontal hatch.
1429 	case 10:	return( wxPENSTYLE_VERTICAL_HATCH   ); // Vertical hatch.
1430 //	case 11:	return( wxPENSTYLE_STIPPLE          ); // Use the stipple bitmap.
1431 //	case 12:	return( wxPENSTYLE_USER_DASH        ); // Use the user dashes: see wxPen::SetDashes.
1432 //	case 13:	return( wxPENSTYLE_TRANSPARENT      ); // No pen is used.
1433 	}
1434 }
1435 
1436 
1437 ///////////////////////////////////////////////////////////
1438 //														 //
1439 ///////////////////////////////////////////////////////////
1440 
1441 //---------------------------------------------------------
Get_Class_Color(CSG_Shape * pShape,int & Color)1442 bool CWKSP_Shapes::Get_Class_Color(CSG_Shape *pShape, int &Color)
1443 {
1444 	//-----------------------------------------------------
1445 	if( m_fValue >= 0 )
1446 	{
1447 		if( m_pClassify->Get_Mode() == CLASSIFY_LUT )
1448 		{
1449 			if( !SG_Data_Type_is_Numeric(Get_Shapes()->Get_Field_Type(m_fValue)) )
1450 			{
1451 				return( m_pClassify->Get_Class_Color_byValue(pShape->asString(m_fValue), Color) );
1452 			}
1453 			else
1454 			{
1455 				return( m_pClassify->Get_Class_Color_byValue(pShape->asDouble(m_fValue), Color) );
1456 			}
1457 		}
1458 
1459 		//-------------------------------------------------
1460 		if( !pShape->is_NoData(m_fValue) )
1461 		{
1462 			if( m_fNormal < 0 )	// don't normalize
1463 			{
1464 				return( m_pClassify->Get_Class_Color_byValue(pShape->asDouble(m_fValue), Color) );
1465 			}
1466 
1467 			if( !pShape->is_NoData(m_fNormal) && pShape->asDouble(m_fNormal) != 0. )
1468 			{
1469 				return( m_pClassify->Get_Class_Color_byValue(m_dNormal * pShape->asDouble(m_fValue) / pShape->asDouble(m_fNormal), Color) );
1470 			}
1471 		}
1472 	}
1473 
1474 	//-----------------------------------------------------
1475 	Color	= m_pClassify->Get_Unique_Color();
1476 
1477 	return( m_pClassify->Get_Mode() == CLASSIFY_SINGLE );
1478 }
1479 
1480 
1481 ///////////////////////////////////////////////////////////
1482 //														 //
1483 ///////////////////////////////////////////////////////////
1484 
1485 //---------------------------------------------------------
_Chart_Set_Options(void)1486 bool CWKSP_Shapes::_Chart_Set_Options(void)
1487 {
1488 	CSG_Parameters	*pChart	= m_Parameters("DISPLAY_CHART")->asParameters();
1489 
1490 	pChart->Del_Parameters();
1491 	m_Chart.Clear();
1492 
1493 	if( 1 )
1494 	{
1495 		int	i, n;
1496 
1497 		for(i=0, n=0; i<Get_Shapes()->Get_Field_Count(); i++)
1498 		{
1499 			if( Get_Shapes()->Get_Field_Type(i) != SG_DATATYPE_String )
1500 			{
1501 				n++;
1502 			}
1503 		}
1504 
1505 		if( n > 0 )
1506 		{
1507 			pChart->Add_Choice("",
1508 				"TYPE"			, _TL("Chart Type"),
1509 				_TL(""),
1510 				CSG_String::Format("%s|%s|%s|%s|",
1511 					_TL("bar"),
1512 					_TL("bar (not outlined)"),
1513 					_TL("pie"),
1514 					_TL("pie (not outlined)")
1515 				), 0
1516 			);
1517 
1518 			pChart->Add_Choice("",
1519 				"SIZE_FIELD"	, _TL("Attribute (Size)"),
1520 				_TL(""),
1521 				CSG_String::Format("%s|", _TL("<not set>")), 0
1522 			);
1523 
1524 			pChart->Add_Choice("",
1525 				"SIZE_TYPE"		, _TL("Size relates to..."),
1526 				_TL(""),
1527 				CSG_String::Format("%s|%s|",
1528 					_TL("Screen"),
1529 					_TL("Map Units")
1530 				), 0
1531 			);
1532 
1533 			pChart->Add_Double("",
1534 				"SIZE_DEFAULT"	, _TL("Default Size"),
1535 				_TL(""),
1536 				15., 0., true
1537 			);
1538 
1539 			pChart->Add_Range("",
1540 				"SIZE_RANGE"	, _TL("Size Range"),
1541 				_TL(""),
1542 				5, 25, 0, true
1543 			);
1544 
1545 			pChart->Add_Node("", "FIELDS", _TL("Fields"), _TL(""));
1546 
1547 			CSG_String	Fields, Field;
1548 			CSG_Colors	Colors(n);
1549 
1550 			for(i=0, n=0; i<Get_Shapes()->Get_Field_Count(); i++)
1551 			{
1552 				if( Get_Shapes()->Get_Field_Type(i) != SG_DATATYPE_String )
1553 				{
1554 					Fields	+= CSG_String::Format("%s|", Get_Shapes()->Get_Field_Name(i));
1555 
1556 					Field.Printf("FIELD_%d", i);
1557 
1558 					pChart->Add_Bool("FIELDS", Field, Get_Shapes()->Get_Field_Name(i), _TL(""), false);
1559 					pChart->Add_Color(Field, CSG_String::Format("COLOR_%d", i), SG_T(""), _TL(""), Colors.Get_Color(n++));
1560 				}
1561 			}
1562 
1563 			Fields	+= CSG_String::Format("%s|", _TL("<none>"));
1564 
1565 			(*pChart)("SIZE_FIELD")->asChoice()->Set_Items(Fields);
1566 			(*pChart)("SIZE_FIELD")->Set_Value(n);
1567 
1568 			return( true );
1569 		}
1570 	}
1571 
1572 	return( false );
1573 }
1574 
1575 //---------------------------------------------------------
_Chart_Get_Options(void)1576 bool CWKSP_Shapes::_Chart_Get_Options(void)
1577 {
1578 	m_Chart.Clear();
1579 	m_Chart_sField	= -1;
1580 
1581 	CSG_Parameters	*pChart	= m_Parameters("DISPLAY_CHART")->asParameters();
1582 
1583 	if( (*pChart)("FIELDS") )
1584 	{
1585 		for(int i=0, n=0; i<Get_Shapes()->Get_Field_Count(); i++)
1586 		{
1587 			CSG_Parameter	*p	= (*pChart)(CSG_String::Format("FIELD_%d", i));
1588 
1589 			if(	p )
1590 			{
1591 				if( (*pChart)("SIZE_FIELD")->asInt() == n++ )
1592 					m_Chart_sField	= i;
1593 
1594 				if( p->asBool() && (p = (*pChart)(CSG_String::Format("COLOR_%d", i))) != NULL )
1595 					m_Chart.Add(i, p->asColor());
1596 			}
1597 		}
1598 
1599 		m_Chart_Type	= (*pChart)("TYPE"        )->asInt();
1600 		m_Chart_sType	= (*pChart)("SIZE_TYPE"   )->asInt();
1601 		m_Chart_sSize	= m_Chart_sField < 0
1602 						? (*pChart)("SIZE_DEFAULT")->asDouble()
1603 						: (*pChart)("SIZE_RANGE"  )->asRange()->Get_Min();
1604 		m_Chart_sRange	= (*pChart)("SIZE_RANGE"  )->asRange()->Get_Max() - m_Chart_sSize;
1605 
1606 		return( true );
1607 	}
1608 
1609 	return( false );
1610 }
1611 
1612 //---------------------------------------------------------
_Draw_Chart(CWKSP_Map_DC & dc_Map,CSG_Shape * pShape)1613 void CWKSP_Shapes::_Draw_Chart(CWKSP_Map_DC &dc_Map, CSG_Shape *pShape)
1614 {
1615 	if( dc_Map.m_rWorld.Intersects(pShape->Get_Extent()) != INTERSECTION_None )
1616 	{
1617 		int			s;
1618 		double		dSize	= m_Chart_sSize;
1619 		TSG_Point_Int	p;
1620 
1621 		if( m_Chart_sField >= 0 )
1622 		{
1623 			double	range	= Get_Shapes()->Get_Range(m_Chart_sField);
1624 
1625 			if( range > 0. )
1626 			{
1627 				dSize	+= m_Chart_sRange * ((pShape->asDouble(m_Chart_sField) - Get_Shapes()->Get_Minimum(m_Chart_sField)) / range);
1628 			}
1629 		}
1630 
1631 		s	= (int)(dSize * (m_Chart_sType == 1 ? dc_Map.m_World2DC : dc_Map.m_Scale));
1632 
1633 		switch( pShape->Get_Type() )
1634 		{
1635 		default:					p	= dc_Map.World2DC(pShape->Get_Extent().Get_Center());			break;
1636 		case SHAPE_TYPE_Polygon:	p	= dc_Map.World2DC(((CSG_Shape_Polygon *)pShape)->Get_Centroid());	break;
1637 		}
1638 
1639 		dc_Map.dc.SetPen(*wxBLACK_PEN);
1640 
1641 		switch( m_Chart_Type )
1642 		{
1643 		case 0:	_Draw_Chart_Bar(dc_Map, pShape,  true, p.x, p.y, (int)(0.8 * s), s);	break; // bar outlined
1644 		case 1:	_Draw_Chart_Bar(dc_Map, pShape, false, p.x, p.y, (int)(0.8 * s), s);	break; // bar
1645 		case 2:	_Draw_Chart_Pie(dc_Map, pShape,  true, p.x, p.y, (int)(1.0 * s));	break; // pie outlined
1646 		case 3:	_Draw_Chart_Pie(dc_Map, pShape, false, p.x, p.y, (int)(1.0 * s));	break; // pie
1647 		}
1648 	}
1649 }
1650 
1651 //---------------------------------------------------------
_Draw_Chart_Pie(CWKSP_Map_DC & dc_Map,CSG_Table_Record * pRecord,bool bOutline,int x,int y,int size)1652 void CWKSP_Shapes::_Draw_Chart_Pie(CWKSP_Map_DC &dc_Map, CSG_Table_Record *pRecord, bool bOutline, int x, int y, int size)
1653 {
1654 	int		i, ix, iy, jx, jy;
1655 	double	d, sum;
1656 
1657 	for(i=0, sum=0.; i<m_Chart.Get_Count(); i++)
1658 	{
1659 		sum	+= fabs(pRecord->asDouble(m_Chart[i].x));
1660 	}
1661 
1662 	if( sum > 0. )
1663 	{
1664 		sum	= M_PI_360 / sum;
1665 
1666 		for(i=0, jx=x, jy=y-size, d=0.; i<m_Chart.Get_Count(); i++)
1667 		{
1668 			if( !bOutline )
1669 			dc_Map.dc.SetPen	(wxPen  (Get_Color_asWX(m_Chart[i].y)));
1670 			dc_Map.dc.SetBrush	(wxBrush(Get_Color_asWX(m_Chart[i].y)));
1671 
1672 			d	+= sum * fabs(pRecord->asDouble(m_Chart[i].x));
1673 
1674 			ix	= jx;
1675 			iy	= jy;
1676 			jx	= x - (int)(size * sin(-d));
1677 			jy	= y - (int)(size * cos(-d));
1678 
1679 			dc_Map.dc.DrawArc(jx, jy, ix, iy, x, y);
1680 		}
1681 	}
1682 }
1683 
1684 //---------------------------------------------------------
_Draw_Chart_Bar(CWKSP_Map_DC & dc_Map,CSG_Table_Record * pRecord,bool bOutline,int x,int y,int sx,int sy)1685 void CWKSP_Shapes::_Draw_Chart_Bar(CWKSP_Map_DC &dc_Map, CSG_Table_Record *pRecord, bool bOutline, int x, int y, int sx, int sy)
1686 {
1687 	int		i;
1688 	double	d, dx, dy, max, ix;
1689 
1690 	y	+= sy / 2;
1691 
1692 	for(i=1, max=fabs(pRecord->asDouble(m_Chart[0].x)); i<m_Chart.Get_Count(); i++)
1693 	{
1694 		if( (d = fabs(pRecord->asDouble(m_Chart[i].x))) > max )
1695 			max	= d;
1696 	}
1697 
1698 	if( max != 0. )
1699 	{
1700 		max	= sy / max;
1701 		dx	= sx / (double)m_Chart.Get_Count();
1702 
1703 		for(i=0, ix=x-sx/2.; i<m_Chart.Get_Count(); i++, ix+=dx)
1704 		{
1705 			if( !bOutline )
1706 			dc_Map.dc.SetPen	(wxPen  (Get_Color_asWX(m_Chart[i].y)));
1707 			dc_Map.dc.SetBrush	(wxBrush(Get_Color_asWX(m_Chart[i].y)));
1708 
1709 			dy	= -pRecord->asDouble(m_Chart[i].x) * max;
1710 
1711 			dc_Map.dc.DrawRectangle((int)ix, y, (int)dx, (int)dy);
1712 		}
1713 
1714 		if( !bOutline )
1715 		{
1716 			dc_Map.dc.SetPen(*wxBLACK_PEN);
1717 			dc_Map.dc.DrawLine(x - sx / 2, y, x + sx / 2, y);
1718 		}
1719 	}
1720 }
1721 
1722 
1723 ///////////////////////////////////////////////////////////
1724 //														 //
1725 //														 //
1726 //														 //
1727 ///////////////////////////////////////////////////////////
1728 
1729 //---------------------------------------------------------
1730