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