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_Map.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 <wx/window.h>
50 #include <wx/dcmemory.h>
51 #include <wx/filename.h>
52 #include <wx/clipbrd.h>
53 #include <wx/dataobj.h>
54 
55 #include <saga_gdi/sgdi_helper.h>
56 
57 #include "res_commands.h"
58 #include "res_dialogs.h"
59 
60 #include "helper.h"
61 
62 #include "active.h"
63 #include "active_legend.h"
64 
65 #include "wksp_map_control.h"
66 #include "wksp_map_manager.h"
67 #include "wksp_map.h"
68 #include "wksp_map_layer.h"
69 #include "wksp_map_graticule.h"
70 #include "wksp_map_basemap.h"
71 #include "wksp_map_buttons.h"
72 
73 #include "wksp_layer_legend.h"
74 #include "wksp_shapes.h"
75 #include "wksp_data_manager.h"
76 
77 #include "view_map.h"
78 #include "view_map_control.h"
79 #include "view_map_3d.h"
80 #include "view_layout.h"
81 #include "view_layout_info.h"
82 
83 
84 ///////////////////////////////////////////////////////////
85 //														 //
86 //														 //
87 //														 //
88 ///////////////////////////////////////////////////////////
89 
90 //---------------------------------------------------------
91 #define LEGEND_SPACE	10
92 
93 
94 ///////////////////////////////////////////////////////////
95 //														 //
96 //														 //
97 //														 //
98 ///////////////////////////////////////////////////////////
99 
100 //---------------------------------------------------------
101 CSG_Rect	CWKSP_Map_Extents::m_Dummy	= CSG_Rect(0, 0, 1, 1);
102 
103 //---------------------------------------------------------
CWKSP_Map_Extents(void)104 CWKSP_Map_Extents::CWKSP_Map_Extents(void)
105 {
106 	m_iExtent	= -1;
107 	m_nExtents	= 0;
108 }
109 
110 //---------------------------------------------------------
Set_Back(void)111 CSG_Rect CWKSP_Map_Extents::Set_Back(void)
112 {
113 	if( m_iExtent < 0 )
114 	{
115 		return( m_Dummy );
116 	}
117 
118 	if( !is_First() )
119 	{
120 		m_iExtent--;
121 	}
122 
123 	return( Get_Rect(m_iExtent) );
124 }
125 
126 //---------------------------------------------------------
Set_Forward(void)127 CSG_Rect CWKSP_Map_Extents::Set_Forward(void)
128 {
129 	if( m_iExtent < 0 )
130 	{
131 		return( m_Dummy );
132 	}
133 
134 	if( !is_Last() )
135 	{
136 		m_iExtent++;
137 	}
138 
139 	return( Get_Rect(m_iExtent) );
140 }
141 
142 //---------------------------------------------------------
Add_Extent(const CSG_Rect & Extent,bool bReset)143 bool CWKSP_Map_Extents::Add_Extent(const CSG_Rect &Extent, bool bReset)
144 {
145 	if( Extent.Get_XRange() > 0. && Extent.Get_YRange() > 0. )
146 	{
147 		if( bReset )
148 		{
149 			m_iExtent	= -1;
150 			m_nExtents	= 0;
151 		}
152 
153 		if( Extent != Get_Extent() )
154 		{
155 			m_iExtent	++;
156 			m_nExtents	= m_iExtent + 1;
157 
158 			if( m_nExtents > Get_Count() )
159 			{
160 				Add(Extent);
161 			}
162 			else
163 			{
164 				Get_Rect(m_iExtent)	= Extent;
165 			}
166 
167 			return( true );
168 		}
169 	}
170 
171 	return( false );
172 }
173 
174 
175 ///////////////////////////////////////////////////////////
176 //														 //
177 //														 //
178 //														 //
179 ///////////////////////////////////////////////////////////
180 
181 //---------------------------------------------------------
CWKSP_Map(void)182 CWKSP_Map::CWKSP_Map(void)
183 {
184 	static int	iMap	= 0;
185 
186 	m_Name.Printf("%02d. %s", ++iMap, _TL("Map"));
187 
188 	m_pView			= NULL;
189 	m_pView_3D		= NULL;
190 	m_pLayout		= NULL;
191 	m_pLayout_Info	= new CVIEW_Layout_Info(this);
192 
193 	m_Img_bSave		= false;
194 	m_Sync_bLock	= 0;
195 
196 	On_Create_Parameters();
197 }
198 
199 //---------------------------------------------------------
~CWKSP_Map(void)200 CWKSP_Map::~CWKSP_Map(void)
201 {
202 	if( m_pView    ) m_pView   ->Do_Destroy();
203 	if( m_pView_3D ) m_pView_3D->Do_Destroy();
204 	if( m_pLayout  ) m_pLayout ->Do_Destroy();
205 
206 	delete(m_pLayout_Info);
207 }
208 
209 
210 ///////////////////////////////////////////////////////////
211 //														 //
212 ///////////////////////////////////////////////////////////
213 
214 //---------------------------------------------------------
Get_Name(void)215 wxString CWKSP_Map::Get_Name(void)
216 {
217 	return( m_Name );
218 }
219 
220 //---------------------------------------------------------
Get_Description(void)221 wxString CWKSP_Map::Get_Description(void)
222 {
223 	wxString	s;
224 
225 	//-----------------------------------------------------
226 	s	+= wxString::Format("<h4>%s</h4>", _TL("Map"));
227 
228 	s	+= "<table border=\"0\">";
229 
230 	DESC_ADD_STR(_TL("Name"             ), m_Name.c_str());
231 	DESC_ADD_INT(_TL("Layers"           ), Get_Count());
232 	DESC_ADD_STR(_TL("Coordinate System"), m_Projection.Get_Description().c_str());
233 
234 	s	+= "</table>";
235 
236 	//-----------------------------------------------------
237 	return( s );
238 }
239 
240 //---------------------------------------------------------
Get_Menu(void)241 wxMenu * CWKSP_Map::Get_Menu(void)
242 {
243 	wxMenu	*pMenu;
244 
245 	pMenu	= new wxMenu(_TL("Map"));
246 
247 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_CLOSE);
248 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_SHOW);
249 	pMenu->AppendSeparator();
250 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_3D_SHOW);
251 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_LAYOUT_SHOW);
252 	pMenu->AppendSeparator();
253 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_SCALEBAR);
254 //	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAP_NORTH_ARROW);
255 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_GRATICULE_ADD);
256 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_BASEMAP_ADD);
257 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_SYNCHRONIZE);
258 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_PROJECTION);
259 	pMenu->AppendSeparator();
260 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_SAVE_IMAGE);
261 	CMD_Menu_Add_Item(pMenu,  true, ID_CMD_MAPS_SAVE_IMAGE_ON_CHANGE);
262 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_SAVE_TO_CLIPBOARD);
263 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_MAPS_SAVE_TO_CLIPBOARD_LEGEND);
264 
265 	return( pMenu );
266 }
267 
268 
269 ///////////////////////////////////////////////////////////
270 //														 //
271 ///////////////////////////////////////////////////////////
272 
273 //---------------------------------------------------------
On_Command(int Cmd_ID)274 bool CWKSP_Map::On_Command(int Cmd_ID)
275 {
276 	switch( Cmd_ID )
277 	{
278 	default:
279 		return( CWKSP_Base_Manager::On_Command(Cmd_ID) );
280 
281 	case ID_CMD_WKSP_ITEM_RETURN:
282 		View_Show(true);
283 		break;
284 
285 	case ID_CMD_MAPS_SAVE_IMAGE:
286 		SaveAs_Image();
287 		break;
288 
289 	case ID_CMD_MAPS_SAVE_IMAGE_ON_CHANGE:
290 		SaveAs_Image_On_Change();
291 		break;
292 
293 	case ID_CMD_MAPS_SAVE_TO_CLIPBOARD:
294 		SaveAs_Image_Clipboard(false);
295 		break;
296 
297 	case ID_CMD_MAPS_SAVE_TO_CLIPBOARD_LEGEND:
298 		SaveAs_Image_Clipboard(true);
299 		break;
300 
301 	case ID_CMD_MAPS_SCALEBAR:
302 		Set_ScaleBar(!is_ScaleBar());
303 		break;
304 
305 	case ID_CMD_MAPS_SYNCHRONIZE:
306 		Set_Synchronising(!m_Parameters("SYNC_MAPS")->asBool());
307 		break;
308 
309 	case ID_CMD_MAPS_GRATICULE_ADD:
310 		Add_Graticule();
311 		break;
312 
313 	case ID_CMD_MAPS_BASEMAP_ADD:
314 		Add_BaseMap();
315 		break;
316 
317 	case ID_CMD_MAPS_PROJECTION:
318 		Set_Projection();
319 		break;
320 
321 	case ID_CMD_MAPS_SHOW:
322 		View_Toggle();
323 		break;
324 
325 	case ID_CMD_MAPS_3D_SHOW:
326 		View_3D_Toggle();
327 		break;
328 
329 	case ID_CMD_MAPS_LAYOUT_SHOW:
330 		View_Layout_Toggle();
331 		break;
332 	}
333 
334 	return( true );
335 }
336 
337 //---------------------------------------------------------
On_Command_UI(wxUpdateUIEvent & event)338 bool CWKSP_Map::On_Command_UI(wxUpdateUIEvent &event)
339 {
340 	switch( event.GetId() )
341 	{
342 	default:
343 		return( CWKSP_Base_Manager::On_Command_UI(event) );
344 
345 	case ID_CMD_MAPS_SHOW:
346 		event.Check(m_pView != NULL);
347 		break;
348 
349 	case ID_CMD_MAPS_3D_SHOW:
350 		event.Check(m_pView_3D != NULL);
351 		break;
352 
353 	case ID_CMD_MAPS_LAYOUT_SHOW:
354 		event.Check(m_pLayout != NULL);
355 		break;
356 
357 	case ID_CMD_MAPS_SAVE_IMAGE_ON_CHANGE:
358 		event.Check(is_Image_Save_Mode());
359 		break;
360 
361 	case ID_CMD_MAPS_SCALEBAR:
362 		event.Check(is_ScaleBar());
363 		break;
364 
365 	case ID_CMD_MAPS_GRATICULE_ADD:
366 	case ID_CMD_MAPS_BASEMAP_ADD:
367 		event.Enable(Get_Count() > 0 && m_Projection.is_Okay());
368 		break;
369 	}
370 
371 	return( true );
372 }
373 
374 
375 ///////////////////////////////////////////////////////////
376 //														 //
377 ///////////////////////////////////////////////////////////
378 
379 //---------------------------------------------------------
On_Create_Parameters(void)380 void CWKSP_Map::On_Create_Parameters(void)
381 {
382 	///////////////////////////////////////////////////////
383 	//-----------------------------------------------------
384 	m_Parameters.Add_Node("",
385 		"NODE_GENERAL"	, _TL("General"),
386 		_TL("")
387 	);
388 
389 	m_Parameters.Add_String("NODE_GENERAL",
390 		"NAME"			, _TL("Name"),
391 		_TL(""),
392 		&m_Name
393 	);
394 
395 	m_Parameters.Add_Bool("NODE_GENERAL",
396 		"GOTO_NEWLAYER"	, _TL("Zoom to Added Layer"),
397 		_TL(""),
398 		g_pMaps->Get_Parameter("GOTO_NEWLAYER")->asBool()
399 	);
400 
401 	m_Parameters.Add_Bool("NODE_GENERAL",
402 		"SYNC_MAPS"		, _TL("Synchronize Map Extents"),
403 		_TL(""),
404 		false
405 	);
406 
407 	m_Parameters.Add_Bool("NODE_GENERAL",
408 		"CRS_CHECK"		, _TL("CRS Check"),
409 		_TL("Perform a coordinate system compatibility check before a layer is added."),
410 		g_pMaps->Get_Parameter("CRS_CHECK")->asBool()
411 	);
412 
413 	//-----------------------------------------------------
414 	m_Parameters.Add_Bool("NODE_GENERAL",
415 		"GCS_POSITION"	, _TL("Position as Geographic Coordinates"),
416 		_TL("Display mouse position in status bar as geographic coordinates."),
417 		false
418 	);
419 
420 	//-----------------------------------------------------
421 	m_Parameters.Add_Bool("NODE_GENERAL",
422 		"SEL_EXTENT"	, _TL("Show Extent"),
423 		_TL("Display selected extent in map."),
424 		false
425 	);
426 
427 	m_Parameters.Add_Color("SEL_EXTENT",
428 		"SEL_COLOUR"	, _TL("Colour"),
429 		_TL(""),
430 		SG_GET_RGB(222, 222, 222)
431 	);
432 
433 	m_Parameters.Add_Double("SEL_EXTENT",
434 		"SEL_TRANSP"	, _TL("Transparency [%]"),
435 		_TL(""),
436 		50., 0., true, 100., true
437 	);
438 
439 	//-----------------------------------------------------
440 	m_Parameters.Add_Bool("NODE_GENERAL",
441 		"FRAME_SHOW"	, _TL("Frame"),
442 		_TL(""),
443 		g_pMaps->Get_Parameter("FRAME_SHOW")->asBool()
444 	);
445 
446 	m_Parameters.Add_Int("FRAME_SHOW",
447 		"FRAME_WIDTH"	, _TL("Size"),
448 		_TL(""),
449 		g_pMaps->Get_Parameter("FRAME_WIDTH")->asInt(), 10, true
450 	);
451 
452 	m_Parameters.Add_Bool("FRAME_SHOW",
453 		"FRAME_SCALE"	, _TL("Scale"),
454 		_TL("Displays the scale instead of coordinates in the bottom and left frame boxes, if there is no scale bar shown in the map."),
455 		false
456 	);
457 
458 	//-----------------------------------------------------
459 	m_Parameters.Add_Bool("NODE_GENERAL",
460 		"NORTH_SHOW"	, _TL("North Arrow"),
461 		_TL(""),
462 		false
463 	);
464 
465 	m_Parameters.Add_Double("NORTH_SHOW",
466 		"NORTH_ANGLE"	, _TL("Direction"),
467 		_TL(""),
468 		0., -180., true, 360., true
469 	);
470 
471 	m_Parameters.Add_Double("NORTH_SHOW",
472 		"NORTH_SIZE"	, _TL("Size"),
473 		_TL("Size given as percentage of map size"),
474 		 5., 1., true, 100., true
475 	);
476 
477 	m_Parameters.Add_Double("NORTH_SHOW",
478 		"NORTH_OFFSET_X", _TL("Horizontal Offset"),
479 		_TL("Offset given as percentage of map size"),
480 		 5., 0., true, 100., true
481 	);
482 
483 	m_Parameters.Add_Double("NORTH_SHOW",
484 		"NORTH_OFFSET_Y", _TL("Vertical Offset"),
485 		_TL("Offset given as percentage of map size"),
486 		90., 0., true, 100., true
487 	);
488 
489 	m_Parameters.Add_Bool("NORTH_SHOW",
490 		"NORTH_EXTENT"	, _TL("Relate to Extent"),
491 		_TL("Relate position and size to selected map extent."),
492 		false
493 	);
494 
495 	//-----------------------------------------------------
496 	m_Parameters.Add_Bool("NODE_GENERAL",
497 		"SCALE_SHOW"	, _TL("Scale Bar"),
498 		_TL(""),
499 		g_pMaps->Get_Parameter("SCALE_BAR")->asBool()
500 	);
501 
502 	m_Parameters.Add_Choice("SCALE_SHOW",
503 		"SCALE_STYLE"	, _TL("Style"),
504 		_TL(""),
505 		CSG_String::Format("%s|%s",
506 			_TL("scale line"),
507 			_TL("alternating scale bar")
508 		), 1
509 	);
510 
511 	m_Parameters.Add_Bool("SCALE_SHOW",
512 		"SCALE_UNIT"	, _TL("Unit"),
513 		_TL(""),
514 		true
515 	);
516 
517 	m_Parameters.Add_Double("SCALE_SHOW",
518 		"SCALE_WIDTH"	, _TL("Width"),
519 		_TL("Width given as percentage of map size"),
520 		40., 1., true, 100., true
521 	);
522 
523 	m_Parameters.Add_Double("SCALE_SHOW",
524 		"SCALE_HEIGHT"	, _TL("Height"),
525 		_TL("Height given as percentage of map size"),
526 		 4., 0.1, true, 100., true
527 	);
528 
529 	m_Parameters.Add_Double("SCALE_SHOW",
530 		"SCALE_OFFSET_X", _TL("Horizontal Offset"),
531 		_TL("Offset given as percentage of map size"),
532 		 5., 0., true, 100., true
533 	);
534 
535 	m_Parameters.Add_Double("SCALE_SHOW",
536 		"SCALE_OFFSET_Y", _TL("Vertical Offset"),
537 		_TL("Offset given as percentage of map size"),
538 		7.5, 0., true, 100., true
539 	);
540 
541 	m_Parameters.Add_Bool("SCALE_SHOW",
542 		"SCALE_EXTENT"	, _TL("Relate to Extent"),
543 		_TL("Relate position and size to selected map extent."),
544 		false
545 	);
546 
547 	///////////////////////////////////////////////////////
548 	//-----------------------------------------------------
549 	m_Img_Parms.Set_Name(_TL("Save Map as Image..."));
550 
551 	m_Img_Parms.Add_Int   (""      , "WIDTH"       , _TL("Width"     ), _TL("pixels"), 800, 1, true);
552 	m_Img_Parms.Add_Int   (""      , "HEIGHT"      , _TL("Height"    ), _TL("pixels"), 600, 1, true);
553 	m_Img_Parms.Add_Bool  (""      , "FRAME"       , _TL("Frame"     ), _TL(""      ), false);
554 	m_Img_Parms.Add_Int   ("FRAME" , "FRAME_WIDTH" , _TL("Width"     ), _TL("pixels"), 20, 5, true);
555 	m_Img_Parms.Add_Bool  (""      , "GEOREF"      , _TL("World File"), _TL(""      ), false);
556 	m_Img_Parms.Add_Bool  (""      , "KML"         , _TL("KML File"  ), _TL(""      ), false);
557 	m_Img_Parms.Add_Bool  (""      , "LEGEND"      , _TL("Legend"    ), _TL(""      ), false);
558 	m_Img_Parms.Add_Double("LEGEND", "LEGEND_SCALE", _TL("Scale"     ), _TL(""      ), 1., 0.1, true);
559 }
560 
561 //---------------------------------------------------------
Get_Frame_Width(void)562 int CWKSP_Map::Get_Frame_Width(void)
563 {
564 	return( m_Parameters("FRAME_SHOW")->asBool() ? m_Parameters("FRAME_WIDTH")->asInt() : 0 );
565 }
566 
567 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)568 int CWKSP_Map::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
569 {
570 	if( Flags & PARAMETER_CHECK_ENABLE )
571 	{
572 		if(	pParameter->Cmp_Identifier("SEL_EXTENT") )
573 		{
574 			pParameter->Set_Children_Enabled(pParameter->asBool());
575 		}
576 
577 		if(	pParameter->Cmp_Identifier("FRAME_SHOW") )
578 		{
579 			pParameter->Set_Children_Enabled(pParameter->asBool());
580 		}
581 
582 		if(	pParameter->Cmp_Identifier("NORTH_SHOW") )
583 		{
584 			pParameter->Set_Children_Enabled(pParameter->asBool());
585 		}
586 
587 		if(	pParameter->Cmp_Identifier("SCALE_SHOW") )
588 		{
589 			pParameter->Set_Children_Enabled(pParameter->asBool());
590 		}
591 	}
592 
593 	return( CWKSP_Base_Manager::On_Parameter_Changed(pParameters, pParameter, Flags) );
594 }
595 
596 //---------------------------------------------------------
Parameters_Changed(void)597 void CWKSP_Map::Parameters_Changed(void)
598 {
599 	m_Name	= m_Parameters("NAME")->asString();
600 
601 	if( m_pView )
602 	{
603 		m_pView->SetTitle(m_Name);
604 
605 		m_pView->Ruler_Set_Width(Get_Frame_Width());
606 	}
607 
608 	View_Refresh(false);
609 
610 	Set_Synchronising(m_Parameters("SYNC_MAPS")->asBool());
611 
612 	CWKSP_Base_Manager::Parameters_Changed();
613 }
614 
615 
616 ///////////////////////////////////////////////////////////
617 //														 //
618 ///////////////////////////////////////////////////////////
619 
620 //---------------------------------------------------------
Serialize(CSG_MetaData & Root,const wxString & ProjectDir,bool bSave)621 bool CWKSP_Map::Serialize(CSG_MetaData &Root, const wxString &ProjectDir, bool bSave)
622 {
623 	if( bSave )
624 	{
625 		CSG_MetaData	&Map	= *Root.Add_Child("MAP");
626 
627 		if( Get_Projection().is_Okay() )
628 		{
629 			Get_Projection().Save(*Map.Add_Child("PROJECTION"));
630 		}
631 
632 		Map.Add_Child("XMIN", Get_Extent().Get_XMin());
633 		Map.Add_Child("XMAX", Get_Extent().Get_XMax());
634 		Map.Add_Child("YMIN", Get_Extent().Get_YMin());
635 		Map.Add_Child("YMAX", Get_Extent().Get_YMax());
636 
637 		m_Parameters.Serialize(*Map.Add_Child("PARAMETERS"), true);
638 
639 		m_pLayout_Info->Save(*Map.Add_Child("LAYOUT"));
640 
641 		CSG_MetaData	&Layers	= *Map.Add_Child("LAYERS");
642 
643 		for(int i=Get_Count()-1; i>=0; i--)
644 		{
645 			switch( Get_Item(i)->Get_Type() )
646 			{
647 			case WKSP_ITEM_Map_Graticule: ((CWKSP_Map_Graticule *)Get_Item(i))->Save(Layers); break;
648 			case WKSP_ITEM_Map_BaseMap  : ((CWKSP_Map_BaseMap   *)Get_Item(i))->Save(Layers); break;
649 			case WKSP_ITEM_Map_Layer    :
650 			{
651 				CWKSP_Map_Layer	*pLayer  = (CWKSP_Map_Layer     *)Get_Item(i);
652 				CSG_Data_Object	*pObject = pLayer->Get_Layer()->Get_Object();
653 
654 				if( pObject && pObject->Get_File_Name(false) && *pObject->Get_File_Name(false) )
655 				{
656 					wxString	FileName(pObject->Get_File_Name(false));
657 
658 					if( FileName.Find("PGSQL") == 0 )
659 					{
660 						pLayer->Save_Settings(
661 							Layers.Add_Child("FILE", &FileName)
662 						);
663 					}
664 					else if( wxFileExists(FileName) )
665 					{
666 						pLayer->Save_Settings(
667 							Layers.Add_Child("FILE", SG_File_Get_Path_Relative(&ProjectDir, &FileName))
668 						);
669 					}
670 				}
671 				break; }
672 			}
673 		}
674 	}
675 
676 	//-----------------------------------------------------
677 	else // if( bSave == false )
678 	{
679 		TSG_Rect	Extent;
680 
681 		if( !Root.Cmp_Name("MAP") || !Root("LAYERS") || Root["LAYERS"].Get_Children_Count() < 1
682 		||	!Root("XMIN") || !Root("XMIN")->Get_Content().asDouble(Extent.xMin)
683 		||	!Root("XMAX") || !Root("XMAX")->Get_Content().asDouble(Extent.xMax)
684 		||	!Root("YMIN") || !Root("YMIN")->Get_Content().asDouble(Extent.yMin)
685 		||	!Root("YMAX") || !Root("YMAX")->Get_Content().asDouble(Extent.yMax) )
686 		{
687 			return( false );
688 		}
689 
690 		if( Root("PROJECTION") )
691 		{
692 			Get_Projection().Load(Root["PROJECTION"]);
693 		}
694 
695 		//-------------------------------------------------
696 		CSG_MetaData	&Layers	= *Root.Get_Child("LAYERS");	int	nLayers	= 0;
697 
698 		m_Parameters["CRS_CHECK"].Set_Value(false);
699 
700 		for(int i=0; i<Layers.Get_Children_Count(); i++)
701 		{
702 			CSG_MetaData	&Layer	= *Layers(i);
703 
704 			if( Layer.Cmp_Name("FILE") )
705 			{
706 				wxString	FileName(Layer.Get_Content().w_str());
707 
708 				if( FileName.Find("PGSQL") != 0 )
709 				{
710 					FileName	= Get_FilePath_Absolute(ProjectDir, FileName);
711 				}
712 
713 				CWKSP_Base_Item	*pItem	= g_pData->Get(SG_Get_Data_Manager().Find(&FileName, false));
714 
715 				if(	pItem &&
716 				(   pItem->Get_Type() == WKSP_ITEM_Grid
717 				||  pItem->Get_Type() == WKSP_ITEM_Grids
718 				||  pItem->Get_Type() == WKSP_ITEM_TIN
719 				||  pItem->Get_Type() == WKSP_ITEM_PointCloud
720 				||  pItem->Get_Type() == WKSP_ITEM_Shapes) )
721 				{
722 					CWKSP_Map_Layer	*pLayer	= Add_Layer((CWKSP_Layer *)pItem);
723 
724 					if( pLayer )
725 					{
726 						pLayer->Load_Settings(&Layer);
727 					}
728 
729 					nLayers++;
730 				}
731 			}
732 			else if( Layer.Cmp_Name("PARAMETERS") )
733 			{
734 				if( Layer.Cmp_Property("name", "GRATICULE") )
735 				{
736 					Add_Graticule(&Layer);
737 				}
738 
739 				if( Layer.Cmp_Property("name", "BASEMAP") )
740 				{
741 					Add_BaseMap  (&Layer);
742 				}
743 			}
744 		}
745 
746 		m_Parameters["CRS_CHECK"].Set_Value(true);
747 
748 		if( nLayers < 1 )
749 		{
750 			return( false );
751 		}
752 
753 		//-------------------------------------------------
754 		if( Root("LAYOUT") )
755 		{
756 			m_pLayout_Info->Load(*Root("LAYOUT"));
757 		}
758 
759 		if( Root("PARAMETERS") && m_Parameters.Serialize(*Root("PARAMETERS"), false) )
760 		{
761 			Parameters_Changed();
762 		}
763 
764 		Set_Extent(Extent, true);
765 
766 		View_Show(true);
767 	}
768 
769 	//-----------------------------------------------------
770 	return( true );
771 }
772 
773 
774 ///////////////////////////////////////////////////////////
775 //														 //
776 ///////////////////////////////////////////////////////////
777 
778 //---------------------------------------------------------
Update(CWKSP_Layer * pLayer,bool bMapOnly)779 bool CWKSP_Map::Update(CWKSP_Layer *pLayer, bool bMapOnly)
780 {
781 	bool	bRefresh	= false;
782 
783 	for(int i=0; i<Get_Count(); i++)
784 	{
785 		if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer && ((CWKSP_Map_Layer *)Get_Item(i))->Get_Layer()->Update(pLayer) )
786 		{
787 			bRefresh	= true;
788 
789 			if( !bMapOnly )
790 			{
791 				Get_Item(i)->Parameters_Changed();
792 			}
793 		}
794 	}
795 
796 	if( bRefresh )
797 	{
798 		if( m_pView )
799 		{
800 			View_Refresh(bMapOnly);
801 		}
802 
803 		_Img_Save_On_Change();
804 
805 		return( true );
806 	}
807 
808 	return( false );
809 }
810 
811 //---------------------------------------------------------
Get_Map_Layer_Index(CWKSP_Layer * pLayer)812 int CWKSP_Map::Get_Map_Layer_Index(CWKSP_Layer *pLayer)
813 {
814 	for(int i=0; i<Get_Count(); i++)
815 	{
816 		if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer && ((CWKSP_Map_Layer *)Get_Item(i))->Get_Layer() == pLayer )
817 		{
818 			return( i );
819 		}
820 	}
821 
822 	return( -1 );
823 }
824 
825 //---------------------------------------------------------
Get_Map_Layer(CWKSP_Layer * pLayer)826 CWKSP_Map_Layer * CWKSP_Map::Get_Map_Layer(CWKSP_Layer *pLayer)
827 {
828 	for(int i=0; i<Get_Count(); i++)
829 	{
830 		if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer && ((CWKSP_Map_Layer *)Get_Item(i))->Get_Layer() == pLayer )
831 		{
832 			return( (CWKSP_Map_Layer *)Get_Item(i) );
833 		}
834 	}
835 
836 	return( NULL );
837 }
838 
839 //---------------------------------------------------------
Get_Map_Layer_Active(bool bEditable)840 CWKSP_Map_Layer * CWKSP_Map::Get_Map_Layer_Active(bool bEditable)
841 {
842 	CWKSP_Map_Layer	*pLayer	= Get_Map_Layer(Get_Active_Layer());
843 
844 	return( pLayer && !(bEditable && pLayer->is_Projecting()) ? pLayer : NULL );
845 }
846 
847 //---------------------------------------------------------
Add_Layer(CWKSP_Layer * pLayer)848 CWKSP_Map_Layer * CWKSP_Map::Add_Layer(CWKSP_Layer *pLayer)
849 {
850 	if( Get_Map_Layer_Index(pLayer) >= 0 )	// don't load a layer more than once
851 	{
852 		return( NULL );
853 	}
854 
855 	//-----------------------------------------------------
856 	bool	bProject	= false;
857 
858 	if( m_Parameters("CRS_CHECK")->asBool()
859 	&&  m_Projection.is_Okay() && pLayer->Get_Object()->Get_Projection().is_Okay()
860 	&&  m_Projection.is_Equal(    pLayer->Get_Object()->Get_Projection()) == false )
861 	{
862 		wxString	s;
863 
864 		s	+= _TL("The coordinate system used by the layer is not identical with the one of the map!");
865 		s	+= "\n";
866 		s	+= wxString::Format("\n%s:\n  [%s]", _TL("Map"  ),                         m_Projection  .Get_Proj4().c_str());
867 		s	+= wxString::Format("\n%s:\n  [%s]", _TL("Layer"), pLayer->Get_Object()->Get_Projection().Get_Proj4().c_str());
868 		s	+= "\n\n";
869 		s	+= _TL("Do you want to activate on-the-fly projection for this layer in the map?");
870 		s	+= "\n";
871 		s	+= _TL("(Press cancel if you decide not to add the layer at all!)");
872 
873 		switch( DLG_Message_YesNoCancel(s, _TL("Add Layer to Map")) )
874 		{
875 		case  0: // yes
876 			bProject	= true;
877 			break;
878 
879 		case  1: // no
880 			break;
881 
882 		default: // cancel
883 			return( NULL );
884 		}
885 	}
886 
887 	if( !m_Projection.is_Okay() && pLayer->Get_Object()->Get_Projection().is_Okay() )
888 	{
889 		m_Projection	= pLayer->Get_Object()->Get_Projection();
890 	}
891 
892 	//-----------------------------------------------------
893 	CWKSP_Map_Layer	*pMapLayer	= new CWKSP_Map_Layer(pLayer);
894 
895 	Add_Item(pMapLayer);
896 
897 	pMapLayer->do_Project(bProject);
898 
899 	if( Get_Count() == 1 )
900 	{
901 		m_Parameters("NAME")->Set_Value(pLayer->Get_Name().wx_str());
902 
903 		Parameters_Changed();
904 	}
905 	else
906 	{
907 		Move_Top(pMapLayer);
908 	}
909 
910 	if( Get_Count() == 1 || (m_Parameters("GOTO_NEWLAYER")->asBool() && pLayer->Get_Object()->is_Valid()) )
911 	{
912 		switch( pLayer->Get_Object()->Get_ObjectType() )
913 		{
914 		case SG_DATAOBJECT_TYPE_Shapes    :
915 		case SG_DATAOBJECT_TYPE_PointCloud:
916 		case SG_DATAOBJECT_TYPE_TIN       :
917 			if( ((CSG_Table *)pLayer->Get_Object())->Get_Count() < 1 )
918 			{
919 				break;
920 			}
921 
922 		default:
923 			Set_Extent(pMapLayer->Get_Extent());
924 			break;
925 		}
926 	}
927 
928 	return( pMapLayer );
929 }
930 
931 //---------------------------------------------------------
Add_Graticule(CSG_MetaData * pEntry)932 CWKSP_Map_Graticule * CWKSP_Map::Add_Graticule(CSG_MetaData *pEntry)
933 {
934 	if( (Get_Count() > 0 && m_Projection.is_Okay()) || pEntry )
935 	{
936 		g_pMaps->Add(this);
937 
938 		CWKSP_Map_Graticule	*pItem	= new CWKSP_Map_Graticule(pEntry);
939 
940 		Add_Item(pItem);
941 		Move_Top(pItem);
942 
943 		View_Refresh(true);
944 
945 		return( pItem );
946 	}
947 
948 	return( NULL );
949 }
950 
951 //---------------------------------------------------------
Add_BaseMap(CSG_MetaData * pEntry)952 CWKSP_Map_BaseMap * CWKSP_Map::Add_BaseMap(CSG_MetaData *pEntry)
953 {
954 	if( (Get_Count() > 0 && m_Projection.is_Okay()) || pEntry )
955 	{
956 		g_pMaps->Add(this);
957 
958 		CWKSP_Map_BaseMap	*pItem	= new CWKSP_Map_BaseMap(pEntry);
959 
960 		Add_Item(pItem);
961 
962 		if( !pEntry )
963 		{
964 			pItem->Dlg_Parameters();
965 		}
966 
967 		switch( pItem->Get_Parameter("POSITION")->asInt() )
968 		{
969 		default: Move_Bottom(pItem); break;
970 		case  0: Move_Top   (pItem); break;
971 		}
972 
973 		View_Refresh(true);
974 
975 		return( pItem );
976 	}
977 
978 	return( NULL );
979 }
980 
981 //---------------------------------------------------------
Add_Copy(CWKSP_Base_Item * pItem)982 CWKSP_Base_Item * CWKSP_Map::Add_Copy(CWKSP_Base_Item *pItem)
983 {
984 	if( pItem )
985 	{
986 		if( pItem->Get_Type() == WKSP_ITEM_Map_Layer )
987 		{
988 			return( Add_Layer(((CWKSP_Map_Layer *)pItem)->Get_Layer()) );
989 		}
990 
991 		if( pItem->Get_Type() == WKSP_ITEM_Map_Graticule )
992 		{
993 			CWKSP_Map_Graticule	*pCopy	= Add_Graticule();
994 
995 			pCopy->Get_Parameters()->Assign_Values(pItem->Get_Parameters());
996 
997 			return( pCopy );
998 		}
999 
1000 		if( pItem->Get_Type() == WKSP_ITEM_Map_BaseMap )
1001 		{
1002 			CSG_MetaData	Settings;
1003 
1004 			pItem->Get_Parameters()->Serialize(Settings, true);
1005 
1006 			CWKSP_Map_BaseMap	*pCopy	= Add_BaseMap(&Settings);
1007 
1008 		//	pItem->Get_Parameters()->Assign_Values(pItem->Get_Parameters());
1009 
1010 			return( pCopy );
1011 		}
1012 	}
1013 
1014 	return( NULL );
1015 }
1016 
1017 
1018 ///////////////////////////////////////////////////////////
1019 //														 //
1020 ///////////////////////////////////////////////////////////
1021 
1022 //---------------------------------------------------------
_Set_Extent(const CSG_Rect & Extent)1023 bool CWKSP_Map::_Set_Extent(const CSG_Rect &Extent)
1024 {
1025 	if( Extent.Get_XRange() > 0. && Extent.Get_YRange() > 0. )
1026 	{
1027 		View_Refresh(true);
1028 
1029 		for(int i=0; i<Get_Count(); i++)
1030 		{
1031 			if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer )
1032 			{
1033 				((CWKSP_Map_Layer *)Get_Item(i))->Fit_Colors(Extent);
1034 			}
1035 		}
1036 
1037 		if( !m_Sync_bLock && m_Parameters("SYNC_MAPS")->asBool() )
1038 		{
1039 			((CWKSP_Map_Manager *)Get_Manager())->Set_Extents(Get_Extent(), m_Projection);
1040 		}
1041 
1042 		return( true );
1043 	}
1044 
1045 	return( false );
1046 }
1047 
1048 //---------------------------------------------------------
Set_Extent(const CSG_Rect & _Extent,bool bReset,bool bPan)1049 bool CWKSP_Map::Set_Extent(const CSG_Rect &_Extent, bool bReset, bool bPan)
1050 {
1051 	CSG_Rect	Extent(_Extent);
1052 
1053 	if( Extent.Get_XRange() == 0. )
1054 	{
1055 		Extent.m_rect.xMin	-= 1.;
1056 		Extent.m_rect.xMax	+= 1.;
1057 	}
1058 
1059 	if( Extent.Get_YRange() == 0. )
1060 	{
1061 		Extent.m_rect.yMin	-= 1.;
1062 		Extent.m_rect.yMax	+= 1.;
1063 	}
1064 
1065 	if( bPan )
1066 	{
1067 		Extent	= Get_Extent();
1068 
1069 		CSG_Point	Difference	= _Extent.Get_Center() - Get_Extent().Get_Center();
1070 
1071 		Extent.Move(Difference);
1072 	}
1073 
1074 	if( m_Extents.Add_Extent(Extent, bReset) )
1075 	{
1076 		_Set_Extent(Extent);
1077 
1078 		return( true );
1079 	}
1080 
1081 	return( false );
1082 }
1083 
1084 //---------------------------------------------------------
Set_Extent(const CSG_Rect & Extent,const CSG_Projection & Projection,bool bPan)1085 bool CWKSP_Map::Set_Extent(const CSG_Rect &Extent, const CSG_Projection &Projection, bool bPan)
1086 {
1087 	if( Projection.is_Okay() && m_Projection.is_Okay() && !(Projection == m_Projection) )
1088 	{
1089 		TSG_Rect	r	= Extent;
1090 
1091 		return( SG_Get_Projected(Projection, m_Projection, r) && Set_Extent(r, false, bPan) );
1092 	}
1093 
1094 	return( Set_Extent(Extent, false, bPan) );
1095 }
1096 
1097 //---------------------------------------------------------
Set_Extent_Full(void)1098 bool CWKSP_Map::Set_Extent_Full(void)
1099 {
1100 	CSG_Rect	Extent;
1101 
1102 	for(int i=0, n=0; i<Get_Count(); i++)
1103 	{
1104 		if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer )
1105 		{
1106 			CWKSP_Map_Layer	*pLayer	= (CWKSP_Map_Layer *)Get_Item(i);
1107 
1108 			if( n++ == 0 )
1109 			{
1110 				Extent.Assign(pLayer->Get_Extent());
1111 			}
1112 			else
1113 			{
1114 				Extent.Union (pLayer->Get_Extent());
1115 			}
1116 		}
1117 	}
1118 
1119 	return( Set_Extent(Extent) );
1120 }
1121 
1122 //---------------------------------------------------------
Set_Extent_Active(bool bPan)1123 bool CWKSP_Map::Set_Extent_Active(bool bPan)
1124 {
1125 	CWKSP_Layer	*pLayer	= Get_Active_Layer();
1126 
1127 	if( pLayer )
1128 	{
1129 		CWKSP_Map_Layer	*pMapLayer	= Get_Map_Layer(pLayer);
1130 
1131 		if( pMapLayer )
1132 		{
1133 			return( Set_Extent(pMapLayer->Get_Extent(), false, bPan) );
1134 		}
1135 
1136 		return( Set_Extent(pLayer->Get_Extent(), pLayer->Get_Object()->Get_Projection(), bPan) );
1137 	}
1138 
1139 	return( false );
1140 }
1141 
1142 //---------------------------------------------------------
Set_Extent_Selection(bool bPan)1143 bool CWKSP_Map::Set_Extent_Selection(bool bPan)
1144 {
1145 	CWKSP_Layer	*pLayer	= Get_Active_Layer();
1146 
1147 	if( pLayer )
1148 	{
1149 		CWKSP_Map_Layer	*pMapLayer	= Get_Map_Layer(Get_Active_Layer());
1150 
1151 		if( pMapLayer && !pMapLayer->do_Project() )
1152 		{
1153 			return( Set_Extent(pLayer->Edit_Get_Extent(), false, bPan) );
1154 		}
1155 
1156 		return( Set_Extent(pLayer->Edit_Get_Extent(), pLayer->Get_Object()->Get_Projection(), bPan) );
1157 	}
1158 
1159 	return( false );
1160 }
1161 
1162 //---------------------------------------------------------
Set_Extent_Back(bool bCheck_Only)1163 bool CWKSP_Map::Set_Extent_Back(bool bCheck_Only)
1164 {
1165 	if( !m_Extents.is_First() )
1166 	{
1167 		if( !bCheck_Only )
1168 		{
1169 			_Set_Extent(m_Extents.Set_Back());
1170 		}
1171 
1172 		return( true );
1173 	}
1174 
1175 	return( false );
1176 }
1177 
1178 //---------------------------------------------------------
Set_Extent_Forward(bool bCheck_Only)1179 bool CWKSP_Map::Set_Extent_Forward(bool bCheck_Only)
1180 {
1181 	if( !m_Extents.is_Last() )
1182 	{
1183 		if( !bCheck_Only )
1184 		{
1185 			_Set_Extent(m_Extents.Set_Forward());
1186 		}
1187 
1188 		return( true );
1189 	}
1190 
1191 	return( false );
1192 }
1193 
1194 //---------------------------------------------------------
Set_Extent(void)1195 bool CWKSP_Map::Set_Extent(void)
1196 {
1197 	CSG_Parameters	P(_TL("Map Extent"));
1198 
1199 	P.Add_Range("", "X", _TL("West-East"  ), _TL(""), Get_Extent().Get_XMin(), Get_Extent().Get_XMax());
1200 	P.Add_Range("", "Y", _TL("South-North"), _TL(""), Get_Extent().Get_YMin(), Get_Extent().Get_YMax());
1201 
1202 	if( DLG_Parameters(&P) )
1203 	{
1204 		return( Set_Extent(CSG_Rect(
1205 			P("X")->asRange()->Get_Min(), P("Y")->asRange()->Get_Min(),
1206 			P("X")->asRange()->Get_Max(), P("Y")->asRange()->Get_Max())
1207 		));
1208 	}
1209 
1210 	return( false );
1211 }
1212 
1213 
1214 ///////////////////////////////////////////////////////////
1215 //														 //
1216 ///////////////////////////////////////////////////////////
1217 
1218 //---------------------------------------------------------
is_Synchronising(void)1219 bool CWKSP_Map::is_Synchronising(void)
1220 {
1221 	return( m_Parameters("SYNC_MAPS")->asBool() );
1222 }
1223 
Set_Synchronising(bool bOn)1224 void CWKSP_Map::Set_Synchronising(bool bOn)
1225 {
1226 	if( m_Parameters("SYNC_MAPS")->asBool() != bOn )
1227 	{
1228 		m_Parameters("SYNC_MAPS")->Set_Value(bOn ? 1 : 0);
1229 	}
1230 
1231 	if( bOn )
1232 	{
1233 		((CWKSP_Map_Manager *)Get_Manager())->Set_Extents(Get_Extent(), m_Projection);
1234 	}
1235 }
1236 
Lock_Synchronising(bool bOn)1237 void CWKSP_Map::Lock_Synchronising(bool bOn)
1238 {
1239 	if( bOn )
1240 	{
1241 		m_Sync_bLock++;
1242 	}
1243 	else if( m_Sync_bLock > 0 )
1244 	{
1245 		m_Sync_bLock--;
1246 	}
1247 }
1248 
1249 //---------------------------------------------------------
is_North_Arrow(void)1250 bool CWKSP_Map::is_North_Arrow(void)
1251 {
1252 	return( m_Parameters("NORTH_SHOW")->asBool() );
1253 }
1254 
Set_North_Arrow(bool bOn)1255 void CWKSP_Map::Set_North_Arrow(bool bOn)
1256 {
1257 	if( m_Parameters("NORTH_SHOW")->asBool() != bOn )
1258 	{
1259 		m_Parameters("NORTH_SHOW")->Set_Value(bOn ? 1 : 0);
1260 
1261 		if( m_pView )
1262 		{
1263 			m_pView->Do_Update();
1264 		}
1265 	}
1266 }
1267 
1268 //---------------------------------------------------------
is_ScaleBar(bool bFrame)1269 bool CWKSP_Map::is_ScaleBar(bool bFrame)
1270 {
1271 	return( bFrame ? !m_Parameters("SCALE_SHOW")->asBool() && m_Parameters("FRAME_SCALE")->asBool() : m_Parameters("SCALE_SHOW")->asBool() );
1272 }
1273 
Set_ScaleBar(bool bOn)1274 void CWKSP_Map::Set_ScaleBar(bool bOn)
1275 {
1276 	if( m_Parameters("SCALE_SHOW")->asBool() != bOn )
1277 	{
1278 		m_Parameters("SCALE_SHOW")->Set_Value(bOn ? 1 : 0);
1279 
1280 		if( m_pView )
1281 		{
1282 			m_pView->Do_Update();
1283 			m_pView->Ruler_Refresh();
1284 		}
1285 	}
1286 }
1287 
1288 
1289 ///////////////////////////////////////////////////////////
1290 //														 //
1291 ///////////////////////////////////////////////////////////
1292 
1293 //---------------------------------------------------------
Set_Mouse_Position(const TSG_Point & Point)1294 void CWKSP_Map::Set_Mouse_Position(const TSG_Point &Point)
1295 {
1296 	((CWKSP_Map_Manager *)Get_Manager())->Set_Mouse_Position(Point, m_Projection);
1297 }
1298 
1299 //---------------------------------------------------------
Set_CrossHair(const TSG_Point & Point,const CSG_Projection & Projection)1300 void CWKSP_Map::Set_CrossHair(const TSG_Point &Point, const CSG_Projection &Projection)
1301 {
1302 	if( m_pView )
1303 	{
1304 		TSG_Point	p;
1305 
1306 		if( !Projection.is_Okay() || !m_Projection.is_Okay() || Projection == m_Projection )
1307 		{
1308 			m_pView->Get_Map_Control()->Set_CrossHair(Point);
1309 		}
1310 		else if( SG_Get_Projected(Projection, m_Projection, p = Point) )
1311 		{
1312 			m_pView->Get_Map_Control()->Set_CrossHair(p);
1313 		}
1314 	}
1315 }
1316 
1317 //---------------------------------------------------------
Set_CrossHair_Off(void)1318 void CWKSP_Map::Set_CrossHair_Off(void)
1319 {
1320 	if( m_pView )
1321 	{
1322 		m_pView->Get_Map_Control()->Set_CrossHair_Off();
1323 	}
1324 }
1325 
1326 
1327 ///////////////////////////////////////////////////////////
1328 //														 //
1329 ///////////////////////////////////////////////////////////
1330 
1331 //---------------------------------------------------------
Set_Projection(void)1332 void CWKSP_Map::Set_Projection(void)
1333 {
1334 	CSG_Tool	*pTool	= SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 15, true);	// CCRS_Picker
1335 
1336 	if(	pTool )
1337 	{
1338 		CSG_Parameters	P(*pTool->Get_Parameters());
1339 
1340 		P.Set_Parameter("CRS_PROJ4", m_Projection.Get_Proj4());
1341 
1342 		P.Add_Bool("", "ONTHEFLY", _TL("On-The-Fly Projection"),
1343 			_TL("Turn on the on-the-fly projection for all layers in the map."),
1344 			true
1345 		);
1346 
1347 		if(	DLG_Parameters(&P) && pTool->Get_Parameters()->Assign_Values(&P)
1348 		&&  pTool->Set_Manager(NULL) && pTool->On_Before_Execution() && pTool->Execute() )
1349 		{
1350 			CSG_Projection	Projection(pTool->Get_Parameter("CRS_PROJ4")->asString(), SG_PROJ_FMT_Proj4);
1351 
1352 			if( P("ONTHEFLY")->asBool() )
1353 			{
1354 				for(int i=0; i<Get_Count(); i++)
1355 				{
1356 					if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer )
1357 					{
1358 						((CWKSP_Map_Layer *)Get_Item(i))->do_Project(true);
1359 					}
1360 				}
1361 
1362 				CSG_Rect	r(Get_Extent());
1363 
1364 				SG_Get_Projected(m_Projection, Projection, r.m_rect);
1365 
1366 				Set_Extent(r, true);
1367 			}
1368 
1369 			m_Projection.Create(Projection);
1370 
1371 			View_Refresh(false);
1372 		}
1373 
1374 		SG_Get_Tool_Library_Manager().Delete_Tool(pTool);
1375 	}
1376 }
1377 
1378 
1379 ///////////////////////////////////////////////////////////
1380 //														 //
1381 ///////////////////////////////////////////////////////////
1382 
1383 //---------------------------------------------------------
View_Opened(MDI_ChildFrame * pView)1384 bool CWKSP_Map::View_Opened(MDI_ChildFrame *pView)
1385 {
1386     if( wxDynamicCast(pView, CVIEW_Map   ) != NULL )    {	m_pView		= (CVIEW_Map    *)pView;	return( true );	}
1387     if( wxDynamicCast(pView, CVIEW_Map_3D) != NULL )	{	m_pView_3D	= (CVIEW_Map_3D *)pView;	return( true );	}
1388 	if( wxDynamicCast(pView, CVIEW_Layout) != NULL )	{	m_pLayout	= (CVIEW_Layout *)pView;	return( true );	}
1389 
1390     return( false );
1391 }
1392 
1393 //---------------------------------------------------------
View_Closes(MDI_ChildFrame * pView)1394 void CWKSP_Map::View_Closes(MDI_ChildFrame *pView)
1395 {
1396 	if( pView == m_pView    )	m_pView		= NULL;
1397 	if( pView == m_pView_3D )	m_pView_3D	= NULL;
1398 	if( pView == m_pLayout  )	m_pLayout	= NULL;
1399 }
1400 
1401 //---------------------------------------------------------
View_Refresh(bool bMapOnly)1402 void CWKSP_Map::View_Refresh(bool bMapOnly)
1403 {
1404 	if( m_pView    )	m_pView   ->Do_Update();
1405 	if( m_pView_3D )	m_pView_3D->Do_Update();
1406 	if( m_pLayout  )	m_pLayout ->Do_Update();
1407 
1408 	if( !bMapOnly && g_pActive )
1409 	{
1410 		g_pActive->Update_Description();
1411 
1412 		if( g_pActive->Get_Legend() )
1413 		{
1414 			g_pActive->Get_Legend()->Refresh(true);
1415 		}
1416 	}
1417 
1418 	_Set_Thumbnail();
1419 
1420 	if( g_pMap_Buttons )
1421 	{
1422 		g_pMap_Buttons->Refresh();
1423 	}
1424 }
1425 
1426 //---------------------------------------------------------
View_Show(bool bShow)1427 void CWKSP_Map::View_Show(bool bShow)
1428 {
1429 	if( bShow )
1430 	{
1431 		if( !m_pView )
1432 		{
1433 			new CVIEW_Map(this, Get_Frame_Width());
1434 		}
1435 		else
1436 		{
1437 			View_Refresh(false);
1438 
1439 			m_pView->Activate();
1440 		}
1441 	}
1442 	else if( m_pView )
1443 	{
1444 		m_pView->Destroy();
1445 	}
1446 }
1447 
1448 //---------------------------------------------------------
View_Toggle(void)1449 void CWKSP_Map::View_Toggle(void)
1450 {
1451 	View_Show( m_pView == NULL );
1452 }
1453 
1454 //---------------------------------------------------------
View_3D_Show(bool bShow)1455 void CWKSP_Map::View_3D_Show(bool bShow)
1456 {
1457 	if( bShow && !m_pView_3D )
1458 	{
1459 		new CVIEW_Map_3D(this);
1460 	}
1461 	else if( !bShow && m_pView_3D )
1462 	{
1463 		m_pView_3D->Destroy();
1464 	}
1465 }
1466 
1467 //---------------------------------------------------------
View_3D_Toggle(void)1468 void CWKSP_Map::View_3D_Toggle(void)
1469 {
1470 	View_3D_Show( m_pView_3D == NULL );
1471 }
1472 
1473 //---------------------------------------------------------
View_Layout_Show(bool bShow)1474 void CWKSP_Map::View_Layout_Show(bool bShow)
1475 {
1476 	if( bShow && !m_pLayout )
1477 	{
1478 		new CVIEW_Layout(m_pLayout_Info);
1479 	}
1480 	else if( !bShow && m_pLayout )
1481 	{
1482 		m_pLayout->Destroy();
1483 	}
1484 }
1485 
1486 //---------------------------------------------------------
View_Layout_Toggle(void)1487 void CWKSP_Map::View_Layout_Toggle(void)
1488 {
1489 	View_Layout_Show( m_pLayout == NULL );
1490 }
1491 
1492 
1493 ///////////////////////////////////////////////////////////
1494 //														 //
1495 ///////////////////////////////////////////////////////////
1496 
1497 //---------------------------------------------------------
Get_World(wxRect rClient)1498 CSG_Rect CWKSP_Map::Get_World(wxRect rClient)
1499 {
1500 	double		d, dWorld, dClient;
1501 	TSG_Rect	Extent;
1502 
1503 	Extent	= Get_Extent().m_rect;
1504 
1505 	dClient	= (double)rClient.GetHeight() / (double)rClient.GetWidth();
1506 	dWorld	= Get_Extent().Get_YRange() / Get_Extent().Get_XRange();
1507 
1508 	if( dWorld > dClient )
1509 	{
1510 		d			= (Get_Extent().Get_XRange() - Get_Extent().Get_YRange() / dClient) / 2.;
1511 		Extent.xMin	+= d;
1512 		Extent.xMax	-= d;
1513 	}
1514 	else
1515 	{
1516 		d			= (Get_Extent().Get_YRange() - Get_Extent().Get_XRange() * dClient) / 2.;
1517 		Extent.yMin	+= d;
1518 		Extent.yMax	-= d;
1519 	}
1520 
1521 	return( CSG_Rect(Extent) );
1522 }
1523 
1524 //---------------------------------------------------------
Get_World(wxRect rClient,wxPoint Point)1525 CSG_Point CWKSP_Map::Get_World(wxRect rClient, wxPoint Point)
1526 {
1527 	CSG_Rect	rWorld(Get_World(rClient));
1528 
1529 	double	d	= rWorld.Get_XRange() / (double)rClient.GetWidth();
1530 
1531 	return( CSG_Point(
1532 		rWorld.Get_XMin() + d *                        Point.x,
1533 		rWorld.Get_YMin() + d * (rClient.GetHeight() - Point.y)
1534 	));
1535 }
1536 
1537 
1538 ///////////////////////////////////////////////////////////
1539 //														 //
1540 ///////////////////////////////////////////////////////////
1541 
1542 //---------------------------------------------------------
1543 #define MASK_R	254
1544 #define MASK_G	255
1545 #define MASK_B	255
1546 
1547 //---------------------------------------------------------
Get_Image(wxImage & Image,CSG_Rect & rWorld)1548 bool CWKSP_Map::Get_Image(wxImage &Image, CSG_Rect &rWorld)
1549 {
1550 	if( Image.GetWidth() > 0 && Image.GetHeight() > 0 )
1551 	{
1552 		wxBitmap	BMP(Image);
1553 		wxMemoryDC	dc;
1554 
1555 		dc.SelectObject(BMP);
1556 		Draw_Map(dc, 1., wxRect(0, 0, Image.GetWidth(), Image.GetHeight()), LAYER_DRAW_FLAG_NOEDITS, SG_GET_RGB(MASK_R, MASK_G, MASK_B));
1557 		dc.SelectObject(wxNullBitmap);
1558 
1559 		rWorld	= Get_World(wxRect(0, 0, Image.GetWidth(), Image.GetHeight()));
1560 		Image	= BMP.ConvertToImage();
1561 		Image.SetMaskColour(MASK_R, MASK_G, MASK_B);
1562 
1563 		return( true );
1564 	}
1565 
1566 	return( false );
1567 }
1568 
1569 //---------------------------------------------------------
SaveAs_Image(void)1570 void CWKSP_Map::SaveAs_Image(void)
1571 {
1572 	//-----------------------------------------------------
1573 	if( View_Get() && View_Get()->Get_Map_Control() )
1574 	{
1575 		wxSize	s(View_Get()->Get_Map_Control()->GetClientSize());
1576 
1577 		m_Img_Parms("WIDTH" )->Set_Value(s.x);
1578 		m_Img_Parms("HEIGHT")->Set_Value(s.y);
1579 	}
1580 
1581 	if( DLG_Image_Save(m_Img_File, m_Img_Type) && DLG_Parameters(&m_Img_Parms) )
1582 	{
1583 		_Img_Save(m_Img_File, m_Img_Type);
1584 	}
1585 }
1586 
1587 //---------------------------------------------------------
SaveAs_Image_Clipboard(bool bLegend)1588 void CWKSP_Map::SaveAs_Image_Clipboard(bool bLegend)
1589 {
1590 	if( bLegend == false )
1591 	{
1592 		SaveAs_Image_Clipboard(
1593 			Get_Manager()->Get_Parameter("CLIP_NX"         )->asInt (),
1594 			Get_Manager()->Get_Parameter("CLIP_NY"         )->asInt (),
1595 			Get_Manager()->Get_Parameter("CLIP_FRAME_SHOW" )->asBool() ?
1596 			Get_Manager()->Get_Parameter("CLIP_FRAME_WIDTH")->asInt () : 0
1597 		);
1598 
1599 		return;
1600 	}
1601 
1602 	//-----------------------------------------------------
1603 	// draw a legend...
1604 
1605 	Set_Buisy_Cursor(true);
1606 
1607 	int			Frame	= Get_Manager()->Get_Parameter("CLIP_LEGEND_FRAME")->asInt();
1608 	double		Scale	= Get_Manager()->Get_Parameter("CLIP_LEGEND_SCALE")->asDouble();
1609 	wxSize		s;
1610 	wxBitmap	BMP;
1611 	wxMemoryDC	dc;
1612 
1613 	if( Get_Legend_Size(s, 1., Scale) )
1614 	{
1615 		s.x	+= 2 * Frame;
1616 		s.y	+= 2 * Frame;
1617 
1618 		BMP.Create(s.GetWidth(), s.GetHeight());
1619 		dc.SelectObject(BMP);
1620 		dc.SetBackground(*wxWHITE_BRUSH);
1621 		dc.Clear();
1622 
1623 		if( Frame > 0 )
1624 		{
1625 			dc.SetPen(Get_Color_asWX(Get_Manager()->Get_Parameter("CLIP_LEGEND_COLOR")->asInt()));
1626 			Draw_Edge(dc, EDGE_STYLE_SIMPLE, 0, 0, s.x - 1, s.y - 1);
1627 		}
1628 
1629 		Draw_Legend(dc, 1., Scale, wxPoint(Frame, Frame));
1630 
1631 		dc.SelectObject(wxNullBitmap);
1632 
1633 		if( wxTheClipboard->Open() )
1634 		{
1635 			wxBitmapDataObject	*pBMP	= new wxBitmapDataObject;
1636 			pBMP->SetBitmap(BMP);
1637 			wxTheClipboard->SetData(pBMP);
1638 			wxTheClipboard->Close();
1639 		}
1640 	}
1641 
1642 	Set_Buisy_Cursor(false);
1643 }
1644 
1645 //---------------------------------------------------------
SaveAs_Image_Clipboard(int nx,int ny,int frame)1646 void CWKSP_Map::SaveAs_Image_Clipboard(int nx, int ny, int frame)
1647 {
1648 	Set_Buisy_Cursor(true);
1649 
1650 	wxSize		s;
1651 	wxRect		r;
1652 	wxBitmap	BMP;
1653 	wxMemoryDC	dc;
1654 
1655 //	if( frame <  0 ) frame = Get_Frame_Width();
1656 	if( frame < 10 ) frame = 0;
1657 
1658 	r		= wxRect(0, 0, nx + 2 * frame, ny + 2 * frame);
1659 
1660 	BMP.Create(r.GetWidth(), r.GetHeight());
1661 	r.Deflate(frame);
1662 	dc.SelectObject(BMP);
1663 	dc.SetBackground(*wxWHITE_BRUSH);
1664 	dc.Clear();
1665 
1666 	Draw_Map(dc, 1., r, LAYER_DRAW_FLAG_NOEDITS);
1667 
1668 	if( frame > 0 )
1669 	{
1670 		Draw_Frame(dc, r, frame);
1671 	}
1672 
1673 	dc.SelectObject(wxNullBitmap);
1674 
1675 	if( wxTheClipboard->Open() )
1676 	{
1677 		wxBitmapDataObject	*pBMP	= new wxBitmapDataObject;
1678 		pBMP->SetBitmap(BMP);
1679 		wxTheClipboard->SetData(pBMP);
1680 		wxTheClipboard->Close();
1681 	}
1682 
1683 	Set_Buisy_Cursor(false);
1684 }
1685 
1686 //---------------------------------------------------------
SaveAs_Image_To_KMZ(int nx,int ny)1687 void CWKSP_Map::SaveAs_Image_To_KMZ(int nx, int ny)
1688 {
1689 	if( nx < 1 || ny < 1 )
1690 	{
1691 		return;
1692 	}
1693 
1694 	//-----------------------------------------------------
1695 	CSG_Rect		Extent(Get_Extent());
1696 
1697 	CSG_Parameters	P(_TL("Export Map to Google Earth"));
1698 
1699 	P.Add_FilePath("", "FILE"    , _TL("File"    ), _TL(""), CSG_String::Format("%s|*.kmz|%s|*.*", _TL("KMZ Files"), _TL("All Files")), NULL, true);
1700 	P.Add_Double  ("", "CELLSIZE", _TL("Cellsize"), _TL(""), SG_Get_Rounded_To_SignificantFigures(Extent.Get_XRange() / (double)nx, 2), 0., true);
1701 	P.Add_Bool    ("", "LOAD"    , _TL("Load"    ), _TL(""), true);
1702 
1703 	if( !DLG_Parameters(&P) || P("CELLSIZE")->asDouble() <= 0. )
1704 	{
1705 		return;
1706 	}
1707 
1708 	wxFileName	FileName(P("FILE")->asString());
1709 
1710 	if( !FileName.IsOk() )
1711 	{
1712 		FileName.AssignTempFileName("saga_map");
1713 		FileName.SetExt("kmz");
1714 
1715 		if( !FileName.IsOk() )
1716 		{
1717 			DLG_Message_Show_Error(_TL("invalid file name"), _TL("Export Map to Google Earth"));
1718 
1719 			return;
1720 		}
1721 	}
1722 
1723 	//-----------------------------------------------------
1724 	nx	= Extent.Get_XRange() / P("CELLSIZE")->asDouble();
1725 	ny	= Extent.Get_YRange() / P("CELLSIZE")->asDouble();
1726 
1727 	wxImage		Image(nx, ny);
1728 
1729 	if( !Get_Image(Image, Extent) )
1730 	{
1731 		return;
1732 	}
1733 
1734 	//-----------------------------------------------------
1735 	CSG_Grid	Map(SG_DATATYPE_Int, Image.GetWidth(), Image.GetHeight(), Extent.Get_XRange() / (double)Image.GetWidth(), Extent.Get_XMin(), Extent.Get_YMin());
1736 
1737 	Map.Set_Name(Get_Name().wx_str());
1738 	Map.Set_NoData_Value(SG_GET_RGB(MASK_R, MASK_G, MASK_B));
1739 	Map.Get_Projection().Create(m_Projection);
1740 
1741 	for(int y=0, yy=Map.Get_NY()-1; y<Map.Get_NY(); y++, yy--)
1742 	{
1743 		for(int x=0; x<Map.Get_NX(); x++)
1744 		{
1745 			Map.Set_Value(x, y, SG_GET_RGB(Image.GetRed(x, yy), Image.GetGreen(x, yy), Image.GetBlue(x, yy)));
1746 		}
1747 	}
1748 
1749 	//-----------------------------------------------------
1750 	CSG_Tool	*pTool	= SG_Get_Tool_Library_Manager().Create_Tool("io_grid_image", 2, true);
1751 
1752 	if(	pTool && pTool->Settings_Push()
1753 	&&  pTool->Set_Parameter("GRID"     , &Map)
1754 	&&  pTool->Set_Parameter("FILE"     , FileName.GetFullPath().wc_str())
1755 	&&  pTool->Set_Parameter("COLOURING", 4)	// rgb coded values
1756 	&&  pTool->Set_Parameter("OUTPUT"   , 2)	// kmz file
1757 	&&  pTool->Execute() && P("LOAD")->asBool() )
1758 	{
1759 		Open_Application(FileName.GetFullPath());
1760 	}
1761 
1762 	SG_Get_Tool_Library_Manager().Delete_Tool(pTool);\
1763 }
1764 
1765 //---------------------------------------------------------
SaveAs_Image_To_Memory(int nx,int ny)1766 void CWKSP_Map::SaveAs_Image_To_Memory(int nx, int ny)
1767 {
1768 	if( nx < 1 || ny < 1 )
1769 		return;
1770 
1771 	CSG_Rect		Extent(Get_Extent());
1772 
1773 	CSG_Parameters	P(_TL("Save To Memory Grid"));
1774 
1775 	P.Add_Double("", "CELLSIZE", _TL("Cellsize"), _TL(""), Extent.Get_XRange() / (double)nx, 0., true);
1776 
1777 	if( !DLG_Parameters(&P) || P("CELLSIZE")->asDouble() <= 0. )
1778 		return;
1779 
1780 	nx	= Extent.Get_XRange() / P("CELLSIZE")->asDouble();
1781 	ny	= Extent.Get_YRange() / P("CELLSIZE")->asDouble();
1782 
1783 	wxImage		Image(nx, ny);
1784 
1785 	if( Get_Image(Image, Extent) )
1786 	{
1787 		CSG_Grid	*pGrid	= SG_Create_Grid(SG_DATATYPE_Int, Image.GetWidth(), Image.GetHeight(), Extent.Get_XRange() / (double)Image.GetWidth(), Extent.Get_XMin(), Extent.Get_YMin());
1788 
1789 		pGrid->Set_Name(Get_Name().wx_str());
1790 		pGrid->Set_NoData_Value(16711935);
1791 		pGrid->Get_Projection().Create(m_Projection);
1792 
1793 		for(int y=0, yy=pGrid->Get_NY()-1; y<pGrid->Get_NY(); y++, yy--)
1794 		{
1795 			for(int x=0; x<pGrid->Get_NX(); x++)
1796 			{
1797 				pGrid->Set_Value(x, y, SG_GET_RGB(Image.GetRed(x, yy), Image.GetGreen(x, yy), Image.GetBlue(x, yy)));
1798 			}
1799 		}
1800 
1801 		g_pData->Add(pGrid);
1802 		g_pData->Get_Parameters(pGrid, &P);
1803 
1804 		if( P("COLORS_TYPE") )
1805 		{
1806 			P("COLORS_TYPE")->Set_Value(5);	// Color Classification Type: RGB Coded Values
1807 
1808 			g_pData->Set_Parameters(pGrid, &P);
1809 		}
1810 	}
1811 }
1812 
1813 //---------------------------------------------------------
SaveAs_Image_To_Grid(CSG_Grid & Grid,int Size)1814 void CWKSP_Map::SaveAs_Image_To_Grid(CSG_Grid &Grid, int Size)
1815 {
1816 	if( Size < 1 )
1817 		return;
1818 
1819 	CSG_Rect	Extent(Get_Extent());
1820 	wxImage		Image;
1821 
1822 	if( Extent.Get_XRange() > Extent.Get_YRange() )
1823 	{
1824 		Image.Create(Size, Size * Extent.Get_YRange() / Extent.Get_XRange());
1825 	}
1826 	else
1827 	{
1828 		Image.Create(Size * Extent.Get_XRange() / Extent.Get_YRange(), Size);
1829 	}
1830 
1831 	if( Get_Image(Image, Extent) )
1832 	{
1833 		Grid.Create(SG_DATATYPE_Int, Image.GetWidth(), Image.GetHeight(), Extent.Get_XRange() / (double)Image.GetWidth(), Extent.Get_XMin(), Extent.Get_YMin());
1834 		Grid.Set_NoData_Value(SG_GET_RGB(MASK_R, MASK_G, MASK_B));
1835 
1836 		for(int y=0, yy=Grid.Get_NY()-1; y<Grid.Get_NY(); y++, yy--)
1837 		{
1838 			for(int x=0; x<Grid.Get_NX(); x++)
1839 			{
1840 				Grid.Set_Value(x, y, SG_GET_RGB(Image.GetRed(x, yy), Image.GetGreen(x, yy), Image.GetBlue(x, yy)));
1841 			}
1842 		}
1843 	}
1844 }
1845 
1846 //---------------------------------------------------------
SaveAs_Image_On_Change(void)1847 void CWKSP_Map::SaveAs_Image_On_Change(void)
1848 {
1849 	if( m_Img_bSave )
1850 	{
1851 		m_Img_bSave	= false;
1852 	}
1853 	else if( DLG_Image_Save(m_Img_File, m_Img_Type) && DLG_Parameters(&m_Img_Parms) )
1854 	{
1855 		m_Img_bSave	= true;
1856 		m_Img_Count	= 0;
1857 	}
1858 }
1859 
1860 //---------------------------------------------------------
_Img_Save_On_Change(void)1861 void CWKSP_Map::_Img_Save_On_Change(void)
1862 {
1863 	if( m_Img_bSave )
1864 	{
1865 		wxFileName	fn(m_Img_File), file(m_Img_File);
1866 
1867 		file.SetName(wxString::Format("%s_%03d", fn.GetName().c_str(), m_Img_Count++));
1868 
1869 		_Img_Save(file.GetFullPath(), m_Img_Type);
1870 	}
1871 }
1872 
1873 //---------------------------------------------------------
_Img_Save(wxString file,int type)1874 void CWKSP_Map::_Img_Save(wxString file, int type)
1875 {
1876 	Set_Buisy_Cursor(true);
1877 
1878 	//-----------------------------------------------------
1879 	int	nx    = m_Img_Parms("WIDTH" )->asInt();
1880 	int	ny    = m_Img_Parms("HEIGHT")->asInt();
1881 	int	Frame = m_Img_Parms("FRAME")->asBool() ? m_Img_Parms("FRAME_WIDTH")->asInt() : 0;
1882 
1883 	wxRect		r(0, 0, nx + 2 * Frame, ny + 2 * Frame);
1884 	wxBitmap	BMP(r.GetWidth(), r.GetHeight());
1885 	wxMemoryDC	dc;
1886 	dc.SelectObject(BMP);
1887 	dc.SetBackground(*wxWHITE_BRUSH);
1888 	dc.Clear();
1889 
1890 	Draw_Map(dc, 1., r, LAYER_DRAW_FLAG_NOEDITS);
1891 
1892 	r.Deflate(Frame);
1893 	Draw_Frame(dc, r, Frame);
1894 
1895 	dc.SelectObject(wxNullBitmap);
1896 	BMP.SaveFile(file, (wxBitmapType)type);
1897 
1898 	//-----------------------------------------------------
1899 	if( m_Img_Parms("GEOREF")->asBool() )
1900 	{
1901 		CSG_File	Stream;
1902 		wxFileName	fn(file);
1903 
1904 		switch( type )
1905 		{
1906 		default                : fn.SetExt("world"); break;
1907 		case wxBITMAP_TYPE_BMP : fn.SetExt("bpw"  ); break;
1908 		case wxBITMAP_TYPE_GIF : fn.SetExt("gfw"  ); break;
1909 		case wxBITMAP_TYPE_JPEG: fn.SetExt("jgw"  ); break;
1910 		case wxBITMAP_TYPE_PNG : fn.SetExt("pgw"  ); break;
1911 		case wxBITMAP_TYPE_PCX : fn.SetExt("pxw"  ); break;
1912 		case wxBITMAP_TYPE_TIF : fn.SetExt("tfw"  ); break;
1913 		}
1914 
1915 		if( Stream.Open(fn.GetFullPath().wx_str(), SG_FILE_W, false) )
1916 		{
1917 			CSG_Rect	rWorld(Get_World(r));
1918 			double		d	= rWorld.Get_XRange() / r.GetWidth();
1919 
1920 			Stream.Printf("%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n",
1921 				d, 0., 0., -d,
1922 				rWorld.Get_XMin() - Frame * d,
1923 				rWorld.Get_YMax() + Frame * d
1924 			);
1925 		}
1926 	}
1927 
1928 	//-----------------------------------------------------
1929 	if( m_Img_Parms("KML")->asBool() )
1930 	{
1931 		CSG_File	Stream;
1932 		wxFileName	fn(file);
1933 
1934 		fn.SetExt("kml");
1935 
1936 		if( Stream.Open(fn.GetFullPath().wx_str(), SG_FILE_W, false) )
1937 		{
1938 			CSG_Rect	rWorld(Get_World(r));
1939 			double		d	= rWorld.Get_XRange() / r.GetWidth();
1940 
1941 			fn.Assign(file);
1942 
1943 			Stream.Printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1944 			Stream.Printf("<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
1945 			Stream.Printf("  <Folder>\n");
1946 			Stream.Printf("    <name>Maps exported from SAGA</name>\n");
1947 			Stream.Printf("    <description>System for Automated Geoscientific Analyses - www.saga-gis.org</description>\n");
1948 			Stream.Printf("    <GroundOverlay>\n");
1949 			Stream.Printf("      <name>%s</name>\n"              , Get_Name().wx_str());
1950 			Stream.Printf("      <description>%s</description>\n", Get_Description().wx_str());
1951 			Stream.Printf("      <Icon>\n");
1952 			Stream.Printf("        <href>%s</href>\n"            , fn.GetFullName().wx_str());
1953 			Stream.Printf("      </Icon>\n");
1954 			Stream.Printf("      <LatLonBox>\n");
1955 			Stream.Printf("        <north>%f</north>\n"          , rWorld.Get_YMax() + Frame * d);
1956 			Stream.Printf("        <south>%f</south>\n"          , rWorld.Get_YMin() - Frame * d);
1957 			Stream.Printf("        <east>%f</east>\n"            , rWorld.Get_XMax() + Frame * d);
1958 			Stream.Printf("        <west>%f</west>\n"            , rWorld.Get_XMin() - Frame * d);
1959 			Stream.Printf("        <rotation>0.0</rotation>\n");
1960 			Stream.Printf("      </LatLonBox>\n");
1961 			Stream.Printf("    </GroundOverlay>\n");
1962 			Stream.Printf("  </Folder>\n");
1963 			Stream.Printf("</kml>\n");
1964 		}
1965 	}
1966 
1967 	//-----------------------------------------------------
1968 	wxSize		s;
1969 
1970 	if( m_Img_Parms("LEGEND")->asBool() && Get_Legend_Size(s, 1., m_Img_Parms("LEGEND_SCALE")->asDouble()) )
1971 	{
1972 		wxFileName	fn(file);
1973 		file	= fn.GetName() + "_legend";
1974 		fn.SetName(file);
1975 		file	= fn.GetFullPath();
1976 
1977 		BMP.Create(s.GetWidth(), s.GetHeight());
1978 		dc.SelectObject(BMP);
1979 		dc.SetBackground(*wxWHITE_BRUSH);
1980 		dc.Clear();
1981 
1982 		Draw_Legend(dc, 1., m_Img_Parms("LEGEND_SCALE")->asDouble(), wxPoint(0, 0));
1983 
1984 		dc.SelectObject(wxNullBitmap);
1985 		BMP.SaveFile(file, (wxBitmapType)type);
1986 	}
1987 
1988 	//-----------------------------------------------------
1989 	Set_Buisy_Cursor(false);
1990 }
1991 
1992 
1993 ///////////////////////////////////////////////////////////
1994 //														 //
1995 ///////////////////////////////////////////////////////////
1996 
1997 //---------------------------------------------------------
Get_Thumbnail(int dx,int dy)1998 const wxBitmap & CWKSP_Map::Get_Thumbnail(int dx, int dy)
1999 {
2000 	if( dx > 0 && dy > 0 && (!m_Thumbnail.IsOk() || m_Thumbnail.GetWidth() != dx || m_Thumbnail.GetHeight() != dy) )
2001 	{
2002 		m_Thumbnail.Create(dx, dy);
2003 
2004 		_Set_Thumbnail();
2005 	}
2006 
2007 	return( m_Thumbnail );
2008 }
2009 
2010 //---------------------------------------------------------
_Set_Thumbnail(void)2011 bool CWKSP_Map::_Set_Thumbnail(void)
2012 {
2013 	if( m_Thumbnail.IsOk() && m_Thumbnail.GetWidth() > 0 && m_Thumbnail.GetHeight() > 0 )
2014 	{
2015 		wxMemoryDC		dc;
2016 		wxRect			r(0, 0, m_Thumbnail.GetWidth(), m_Thumbnail.GetHeight());
2017 
2018 		dc.SelectObject(m_Thumbnail);
2019 		dc.SetBackground(*wxWHITE_BRUSH);
2020 		dc.Clear();
2021 
2022 		Draw_Map(dc, Get_Extent(), 1., r, LAYER_DRAW_FLAG_NOEDITS|LAYER_DRAW_FLAG_NOLABELS);
2023 
2024 		dc.SelectObject(wxNullBitmap);
2025 
2026 		return( true );
2027 	}
2028 
2029 	return( false );
2030 }
2031 
2032 
2033 ///////////////////////////////////////////////////////////
2034 //														 //
2035 ///////////////////////////////////////////////////////////
2036 
2037 //---------------------------------------------------------
Draw_Map(wxDC & dc,double Zoom,const wxRect & rClient,int Flags,int Background)2038 void CWKSP_Map::Draw_Map(wxDC &dc, double Zoom, const wxRect &rClient, int Flags, int Background)
2039 {
2040 	Draw_Map(dc, Get_World(rClient), Zoom, rClient, Flags, Background);
2041 }
2042 
2043 //---------------------------------------------------------
Draw_Map(wxDC & dc,const CSG_Rect & rWorld,double Zoom,const wxRect & rClient,int Flags,int Background)2044 void CWKSP_Map::Draw_Map(wxDC &dc, const CSG_Rect &rWorld, double Zoom, const wxRect &rClient, int Flags, int Background)
2045 {
2046 	CWKSP_Map_DC	dc_Map(rWorld, rClient, Zoom, Background);
2047 
2048 	int	Flag_Labels	= !(Flags & LAYER_DRAW_FLAG_NOLABELS) ? 0 : LAYER_DRAW_FLAG_NOLABELS;
2049 
2050 	//-----------------------------------------------------
2051 	for(int i=Get_Count()-1; i>=0; i--)
2052 	{
2053 		switch( Get_Item(i)->Get_Type() )
2054 		{
2055 		case WKSP_ITEM_Map_Layer:
2056 			{
2057 				CWKSP_Map_Layer     *pLayer	= (CWKSP_Map_Layer     *)Get_Item(i);
2058 
2059 				if( pLayer->do_Show() )
2060 				{
2061 					pLayer->Draw(dc_Map, !(Flags & LAYER_DRAW_FLAG_NOEDITS) && pLayer->Get_Layer() == Get_Active_Layer() ? Flags : Flag_Labels);
2062 				}
2063 			}
2064 			break;
2065 
2066 		case WKSP_ITEM_Map_Graticule:
2067 			{
2068 				CWKSP_Map_Graticule *pLayer	= (CWKSP_Map_Graticule *)Get_Item(i);
2069 
2070 				if( pLayer->do_Show() )//&& pLayer->Get_Graticule(Get_Extent()) )
2071 				{
2072 					pLayer->Draw(dc_Map);
2073 				}
2074 			}
2075 			break;
2076 
2077 		case WKSP_ITEM_Map_BaseMap:
2078 			{
2079 				CWKSP_Map_BaseMap   *pLayer	= (CWKSP_Map_BaseMap   *)Get_Item(i);
2080 
2081 				if( pLayer->do_Show() )
2082 				{
2083 					pLayer->Draw(dc_Map);
2084 				}
2085 			}
2086 			break;
2087 
2088 		default:
2089 			break;
2090 		}
2091 	}
2092 
2093 	//-----------------------------------------------------
2094 	Draw_Extent     (dc_Map, rWorld, rClient);
2095 	Draw_ScaleBar   (dc_Map, rWorld, rClient);
2096 	Draw_North_Arrow(dc_Map, rWorld, rClient);
2097 
2098 	//-----------------------------------------------------
2099 	dc_Map.Draw(dc);
2100 }
2101 
2102 //---------------------------------------------------------
Draw_Frame(wxDC & dc,wxRect rMap,int Width)2103 void CWKSP_Map::Draw_Frame(wxDC &dc, wxRect rMap, int Width)
2104 {
2105 	Draw_Frame(dc, Get_World(rMap), rMap, Width, is_ScaleBar(true));
2106 }
2107 
Draw_Frame(wxDC & dc,const CSG_Rect & rWorld,wxRect rMap,int Width,bool bScaleBar)2108 void CWKSP_Map::Draw_Frame(wxDC &dc, const CSG_Rect &rWorld, wxRect rMap, int Width, bool bScaleBar)
2109 {
2110 	Draw_Edge(dc, EDGE_STYLE_SIMPLE, rMap.GetLeft(), rMap.GetTop(), rMap.GetRight(), rMap.GetBottom());
2111 
2112 	wxRect	rFrame(rMap);	rFrame.Inflate(Width);
2113 
2114 	Draw_Scale(dc, wxRect(rMap  .GetLeft(), rFrame.GetTop(), rMap.GetWidth (), Width),
2115 		rWorld.Get_XMin(), rWorld.Get_XMax(),  true,  true, false
2116 	);
2117 
2118 	Draw_Scale(dc, wxRect(rFrame.GetLeft(), rMap  .GetTop(), Width, rMap.GetHeight()),
2119 		rWorld.Get_YMin(), rWorld.Get_YMax(), false, false, false
2120 	);
2121 
2122 	if( bScaleBar == false )
2123 	{
2124 		Draw_Scale(dc, wxRect(rMap.GetLeft (), rMap.GetBottom(), rMap.GetWidth (), Width),
2125 			rWorld.Get_XMin(), rWorld.Get_XMax(),  true,  true, true
2126 		);
2127 
2128 		Draw_Scale(dc, wxRect(rMap.GetRight(), rMap.GetTop   (), Width, rMap.GetHeight()),
2129 			rWorld.Get_YMin(), rWorld.Get_YMax(), false, false, true
2130 		);
2131 	}
2132 	else
2133 	{
2134 		Draw_Scale(dc, wxRect(rMap.GetLeft (), rMap.GetBottom(), rMap.GetWidth (), Width),
2135 			0., rWorld.Get_XRange(),  true,  true, true);
2136 
2137 		Draw_Scale(dc, wxRect(rMap.GetRight(), rMap.GetTop   (), Width, rMap.GetHeight()),
2138 			0., rWorld.Get_YRange(), false, false, true);
2139 	}
2140 
2141 	Draw_Edge(dc, EDGE_STYLE_SIMPLE, rFrame.GetLeft(), rFrame.GetTop(), rFrame.GetRight(), rFrame.GetBottom());
2142 }
2143 
2144 //---------------------------------------------------------
Draw_Legend(wxDC & dc,double Zoom_Map,double Zoom,wxPoint Position,wxSize * pSize)2145 bool CWKSP_Map::Draw_Legend(wxDC &dc, double Zoom_Map, double Zoom, wxPoint Position, wxSize *pSize)
2146 {
2147 	wxSize	s, Size(0, 0);
2148 
2149 	for(int i=0; i<Get_Count(); i++)
2150 	{
2151 		if( Get_Item(i)->Get_Type() == WKSP_ITEM_Map_Layer )
2152 		{
2153 			CWKSP_Layer	*pLayer	= ((CWKSP_Map_Layer *)Get_Item(i))->Get_Layer();
2154 
2155 			if( pLayer->do_Legend() )
2156 			{
2157 				pLayer->Get_Legend()->Draw(dc, Zoom, Zoom_Map, Position, &s);
2158 
2159 				if( 1 )	// m_pLayout->Get_Legend()->Get_Orientation() == LEGEND_VERTICAL )
2160 				{
2161 					s.y			+= (int)(Zoom * LEGEND_SPACE);
2162 					Position.y	+= s.y;
2163 					Size.y		+= s.y;
2164 
2165 					if( Size.x < s.x )
2166 						Size.x	= s.x;
2167 				}
2168 				else
2169 				{
2170 					s.x			+= (int)(Zoom * LEGEND_SPACE);
2171 					Position.x	+= s.x;
2172 					Size.x		+= s.x;
2173 
2174 					if( Size.y < s.y )
2175 						Size.y	= s.y;
2176 				}
2177 			}
2178 		}
2179 	}
2180 
2181 	if( pSize )
2182 	{
2183 		*pSize	= Size;
2184 	}
2185 
2186 	return( Size.GetX() > 0 || Size.GetY() > 0 );
2187 }
2188 
2189 //---------------------------------------------------------
Get_Legend_Size(wxSize & Size,double Zoom_Map,double Zoom)2190 bool CWKSP_Map::Get_Legend_Size(wxSize &Size, double Zoom_Map, double Zoom)
2191 {
2192 	wxBitmap	bmp(10, 10);
2193 	wxMemoryDC	dc(bmp);
2194 
2195 	return( Draw_Legend(dc, Zoom_Map, Zoom, wxPoint(0, 0), &Size) );
2196 }
2197 
2198 //---------------------------------------------------------
Draw_North_Arrow(CWKSP_Map_DC & dc_Map,const CSG_Rect & rWorld,const wxRect & rClient)2199 bool CWKSP_Map::Draw_North_Arrow(CWKSP_Map_DC &dc_Map, const CSG_Rect &rWorld, const wxRect &rClient)
2200 {
2201 	if( !m_Parameters("NORTH_SHOW")->asBool() )
2202 	{
2203 		return( true );
2204 	}
2205 
2206 	const double	Arrow[3][2]	= { { 0., 1. }, { 0.5, -1. }, { 0., -0.5 } };
2207 
2208 	wxRect	r	= !m_Parameters("NORTH_EXTENT")->asBool() ? wxRect(0, 0, rClient.GetWidth(), rClient.GetHeight()) : wxRect(
2209 		(int)(dc_Map.xWorld2DC   (Get_Extent().Get_XMin  ())),
2210 		(int)(dc_Map.yWorld2DC   (Get_Extent().Get_YMax  ())),
2211 		(int)(dc_Map.m_World2DC * Get_Extent().Get_XRange()),
2212 		(int)(dc_Map.m_World2DC * Get_Extent().Get_YRange())
2213 	);
2214 
2215 	double	cos_a	= cos(-m_Parameters("NORTH_ANGLE")->asDouble() * M_DEG_TO_RAD);
2216 	double	sin_a	= sin(-m_Parameters("NORTH_ANGLE")->asDouble() * M_DEG_TO_RAD);
2217 	double	scale	= m_Parameters("NORTH_SIZE")->asDouble() * 0.01 * M_GET_MIN(r.GetWidth(), r.GetHeight());
2218 
2219 	int		xOff	= r.GetX() + (int)(0.5 +                 m_Parameters("NORTH_OFFSET_X")->asDouble() * 0.01 * r.GetWidth ());
2220 	int		yOff	= r.GetY() + (int)(0.5 + r.GetHeight() - m_Parameters("NORTH_OFFSET_Y")->asDouble() * 0.01 * r.GetHeight());
2221 
2222 	for(int side=0; side<=1; side++)
2223 	{
2224 		wxPoint	Points[3];
2225 
2226 		for(int i=0; i<3; i++)
2227 		{
2228 			double	x	= scale * Arrow[i][0] * (side ? 1 : -1);
2229 			double	y	= scale * Arrow[i][1];
2230 
2231 			Points[i].x	= xOff + (int)(0.5 + cos_a * x - sin_a * y);
2232 			Points[i].y	= yOff - (int)(0.5 + sin_a * x + cos_a * y);
2233 		}
2234 
2235 		if( side == 0 )
2236 		{
2237 		//	dc_Map.dc.SetPen     (wxPen  (*wxWHITE, 3));
2238 		//	dc_Map.dc.DrawLines  (3, Points);
2239 
2240 			dc_Map.dc.SetPen     (wxPen  (*wxBLACK, 0));
2241 			dc_Map.dc.SetBrush   (wxBrush(*wxBLACK));
2242 			dc_Map.dc.DrawPolygon(3, Points);
2243             dc_Map.dc.DrawPolygon(3, Points);
2244 		}
2245 		else
2246 		{
2247 			dc_Map.dc.SetPen     (wxPen  (*wxBLACK, 0));
2248 			dc_Map.dc.SetBrush   (wxBrush(*wxWHITE));
2249 			dc_Map.dc.DrawPolygon(3, Points);
2250 		//	dc_Map.dc.DrawLines  (3, Points);
2251 		}
2252 	}
2253 
2254 	return( true );
2255 }
2256 
2257 //---------------------------------------------------------
Draw_ScaleBar(CWKSP_Map_DC & dc_Map,const CSG_Rect & rWorld,const wxRect & rClient)2258 bool CWKSP_Map::Draw_ScaleBar(CWKSP_Map_DC &dc_Map, const CSG_Rect &rWorld, const wxRect &rClient)
2259 {
2260 	if( !is_ScaleBar() )
2261 	{
2262 		return( true );
2263 	}
2264 
2265 	double	dWidth	= 0.01 * m_Parameters("SCALE_WIDTH")->asDouble();
2266 
2267 	wxRect	r	= !m_Parameters("SCALE_EXTENT")->asBool() ? wxRect(0, 0, rClient.GetWidth(), rClient.GetHeight()) : wxRect(
2268 		(int) dc_Map .xWorld2DC  (Get_Extent().Get_XMin  ()),
2269 		(int) dc_Map .yWorld2DC  (Get_Extent().Get_YMax  ()),
2270 		(int)(dc_Map.m_World2DC * Get_Extent().Get_XRange()),
2271 		(int)(dc_Map.m_World2DC * Get_Extent().Get_YRange())
2272 	);
2273 
2274 	r	= wxRect(
2275 		(int)(0.5 + r.GetWidth () * 0.01 * m_Parameters("SCALE_OFFSET_X")->asDouble()) + r.GetX(), r.GetY() + r.GetHeight() -
2276 		(int)(0.5 + r.GetHeight() * 0.01 * m_Parameters("SCALE_OFFSET_Y")->asDouble()),
2277 		(int)(0.5 + r.GetWidth () * dWidth),
2278 		(int)(0.5 + r.GetHeight() * 0.01 * m_Parameters("SCALE_HEIGHT"  )->asDouble())
2279 	);
2280 
2281 	dWidth	= dc_Map.m_DC2World * r.GetWidth();
2282 
2283 	CSG_String	Unit;
2284 
2285 	if( m_Projection.is_Okay() && m_Parameters("SCALE_UNIT")->asBool() )
2286 	{
2287 		Unit	= SG_Get_Projection_Unit_Name(m_Projection.Get_Unit(), true);
2288 
2289 		if( Unit.is_Empty() )	Unit	= m_Projection.Get_Unit_Name();
2290 
2291 		if( m_Projection.Get_Unit() == SG_PROJ_UNIT_Meter && dWidth > 10000. )
2292 		{
2293 			Unit	 = SG_Get_Projection_Unit_Name(SG_PROJ_UNIT_Kilometer, true);
2294 			dWidth	/= 1000.;
2295 		}
2296 	}
2297 
2298 	int	Style	= SCALE_STYLE_LINECONN|SCALE_STYLE_GLOOMING;
2299 
2300 	if( m_Parameters("SCALE_STYLE")->asInt() == 1 )
2301 		Style	|= SCALE_STYLE_BLACKWHITE;
2302 
2303 	Draw_Scale(dc_Map.dc, r, 0., dWidth, SCALE_HORIZONTAL, SCALE_TICK_TOP, Style, Unit.c_str());
2304 
2305 	return( true );
2306 }
2307 
2308 //---------------------------------------------------------
Draw_Extent(CWKSP_Map_DC & dc_Map,const CSG_Rect & rWorld,const wxRect & rClient)2309 bool CWKSP_Map::Draw_Extent(CWKSP_Map_DC &dc_Map, const CSG_Rect &rWorld, const wxRect &rClient)
2310 {
2311 	if( !m_Parameters("SEL_EXTENT")->asBool() || rWorld == Get_Extent() )
2312 	{
2313 		return( true );
2314 	}
2315 
2316 	if( dc_Map.IMG_Draw_Begin(m_Parameters("SEL_TRANSP")->asDouble() / 100.) )
2317 	{
2318 		int	Colour	= m_Parameters("SEL_COLOUR")->asColor();
2319 
2320 		wxRect	r(0, 0, rClient.GetWidth(), rClient.GetHeight()); r.Inflate(1);
2321 
2322 		if( rWorld.Get_XRange() > Get_Extent().Get_XRange() )
2323 		{
2324 			int	d	= (int)(0.5 + dc_Map.m_World2DC * (rWorld.Get_XRange() - Get_Extent().Get_XRange()) / 2.);
2325 
2326 			dc_Map.IMG_Set_Rect(r.GetLeft (), r.GetTop(), r.GetLeft () + d, r.GetBottom(), Colour);
2327 			dc_Map.IMG_Set_Rect(r.GetRight(), r.GetTop(), r.GetRight() - d, r.GetBottom(), Colour);
2328 		}
2329 		else
2330 		{
2331 			int	d	= (int)(0.5 + dc_Map.m_World2DC * (rWorld.Get_YRange() - Get_Extent().Get_YRange()) / 2.);
2332 
2333 			dc_Map.IMG_Set_Rect(r.GetLeft(), r.GetTop   (), r.GetRight(), r.GetTop   () + d, Colour);
2334 			dc_Map.IMG_Set_Rect(r.GetLeft(), r.GetBottom(), r.GetRight(), r.GetBottom() - d, Colour);
2335 		}
2336 
2337 		dc_Map.IMG_Draw_End();
2338 	}
2339 
2340 	return( true );
2341 }
2342 
2343 
2344 ///////////////////////////////////////////////////////////
2345 //														 //
2346 ///////////////////////////////////////////////////////////
2347 
2348 //---------------------------------------------------------
Show_Coordinate(const CSG_Point & Coordinate) const2349 void CWKSP_Map::Show_Coordinate(const CSG_Point &Coordinate) const
2350 {
2351 	CSG_Parameters	P(_TL("Coordinate"));
2352 
2353 	if( m_Projection.is_Okay() )
2354 	{
2355 		TSG_Point	Degree(Coordinate);
2356 
2357 		if( m_Projection.is_Geographic() || SG_Get_Projected(m_Projection, CSG_Projections::Get_GCS_WGS84(), Degree) )
2358 		{
2359 			if( !m_Projection.is_Geographic() )
2360 			{
2361 				P.Add_Node("", "MAP", m_Projection.Get_Name(), m_Projection.Get_Proj4());
2362 				P.Add_Info_Value("MAP", "MAP_X", _TL("Easting" ), _TL(""), PARAMETER_TYPE_Double, Coordinate.x);
2363 				P.Add_Info_Value("MAP", "MAP_Y", _TL("Northing"), _TL(""), PARAMETER_TYPE_Double, Coordinate.y);
2364 			}
2365 
2366 			P.Add_Node("", "DEG", _TL("Decimal Degrees"), _TL(""));
2367 			P.Add_Info_Value("DEG", "DEG_LON", _TL("Longitude"), _TL(""), PARAMETER_TYPE_Double, Degree.x);
2368 			P.Add_Info_Value("DEG", "DEG_LAT", _TL("Latitude" ), _TL(""), PARAMETER_TYPE_Double, Degree.y);
2369 
2370 			P.Add_Node("", "DMS", _TL("Degrees, Minutes, Seconds"), _TL(""));
2371 			P.Add_Info_Value("DMS", "DMS_LON", _TL("Longitude"), _TL(""), PARAMETER_TYPE_Degree, Degree.x);
2372 			P.Add_Info_Value("DMS", "DMS_LAT", _TL("Latitude" ), _TL(""), PARAMETER_TYPE_Degree, Degree.y);
2373 		}
2374 		else
2375 		{
2376 			P.Add_Info_Value("", "MAP_X", _TL("Easting" ), _TL(""), PARAMETER_TYPE_Double, Coordinate.x);
2377 			P.Add_Info_Value("", "MAP_Y", _TL("Northing"), _TL(""), PARAMETER_TYPE_Double, Coordinate.y);
2378 		}
2379 	}
2380 	else
2381 	{
2382 		P.Add_Info_Value("", "MAP_X", "X", _TL(""), PARAMETER_TYPE_Double, Coordinate.x);
2383 		P.Add_Info_Value("", "MAP_Y", "Y", _TL(""), PARAMETER_TYPE_Double, Coordinate.y);
2384 	}
2385 
2386 	DLG_Parameters(&P);
2387 }
2388 
2389 
2390 ///////////////////////////////////////////////////////////
2391 //														 //
2392 //														 //
2393 //														 //
2394 ///////////////////////////////////////////////////////////
2395 
2396 //---------------------------------------------------------
2397