SAGA API Version 9.14
Loading...
Searching...
No Matches
map_graticule.cpp
Go to the documentation of this file.
1
3// //
4// SAGA //
5// //
6// System for Automated Geoscientific Analyses //
7// //
8// Application Programming Interface //
9// //
10// Library: SAGA_API //
11// //
12//-------------------------------------------------------//
13// //
14// map_graticule.cpp //
15// //
16// Copyright (C) 2026 by //
17// Olaf Conrad //
18// //
19//-------------------------------------------------------//
20// //
21// This file is part of 'SAGA - System for Automated //
22// Geoscientific Analyses'. SAGA is free software; you //
23// can redistribute it and/or modify it under the terms //
24// of the GNU General Public License as published by the //
25// Free Software Foundation, either version 2 of the //
26// License, or (at your option) any later version. //
27// //
28// SAGA is distributed in the hope that it will be //
29// useful, but WITHOUT ANY WARRANTY; without even the //
30// implied warranty of MERCHANTABILITY or FITNESS FOR A //
31// PARTICULAR PURPOSE. See the GNU General Public //
32// License for more details. //
33// //
34// You should have received a copy of the GNU General //
35// Public License along with this program; if not, see //
36// <http://www.gnu.org/licenses/>. //
37// //
38//-------------------------------------------------------//
39// //
40// e-mail: oconrad@saga-gis.org //
41// //
42// contact: Olaf Conrad //
43// Institute of Geography //
44// University of Hamburg //
45// Germany //
46// //
48
49//---------------------------------------------------------
50#include "../dc_helper.h"
51#include "map_dc.h"
52#include "map_layer.h"
53
54#include "../tool_library.h"
55
56
58// //
59// //
60// //
62
63//---------------------------------------------------------
65{
66 m_pTool = NULL; // remember the last created graticule tool instance
67
68 m_Parameters.Set_Name ("GRATICULE");
69 m_Parameters.Set_Identifier("GRATICULE");
70
71 //-----------------------------------------------------
72 m_Parameters.Add_Node("", "NODE_GENERAL", _TL("General"), _TL(""));
73
74 m_Parameters.Add_String("NODE_GENERAL",
75 "NAME" , _TL("Name"),
76 _TL(""),
77 _TL("Graticule")
78 );
79
80 m_Parameters.Add_Choice("NODE_GENERAL",
81 "INTERVAL" , _TL("Interval"),
82 _TL(""),
83 CSG_String::Format("%s|%s",
84 _TL("fixed interval"),
85 _TL("fitted interval")
86 ), 1
87 );
88
89 m_Parameters.Add_Double("INTERVAL",
90 "FIXED" , _TL("Fixed Interval (Degree)"),
91 _TL(""),
92 5., 0., true, 20.
93 );
94
95 m_Parameters.Add_Int("INTERVAL",
96 "FITTED" , _TL("Number of Intervals"),
97 _TL(""),
98 5, 1, true
99 );
100
101 m_Parameters.Add_Double("NODE_GENERAL",
102 "RESOLUTION" , _TL("Minimum Resolution (Degree)"),
103 _TL(""),
104 0.5, 0., true
105 );
106
107 //-----------------------------------------------------
108 m_Parameters.Add_Node("", "NODE_DISPLAY", _TL("Display"), _TL(""));
109
110 m_Parameters.Add_Double("NODE_DISPLAY",
111 "TRANSPARENCY", _TL("Transparency"),
112 _TL("Transparency specified as percentage."),
113 0, 0., true, 100., true
114 );
115
116 m_Parameters.Add_Color("NODE_DISPLAY",
117 "LINE_COLOR" , _TL("Line Color"),
118 _TL(""),
120 );
121
122 m_Parameters.Add_Int("NODE_DISPLAY",
123 "LINE_WIDTH" , _TL("Line Width"),
124 _TL(""),
125 1, 1, true
126 );
127
128 m_Parameters.Add_Choice("NODE_DISPLAY",
129 "LINE_STYLE" , _TL("Line Style"),
130 _TL(""),
131 CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
132 _TL("Solid style" ),
133 _TL("Dotted style" ),
134 _TL("Long dashed style" ),
135 _TL("Short dashed style" ),
136 _TL("Dot and dash style" ),
137 _TL("Backward diagonal hatch"),
138 _TL("Cross-diagonal hatch" ),
139 _TL("Forward diagonal hatch" ),
140 _TL("Cross hatch" ),
141 _TL("Horizontal hatch" ),
142 _TL("Vertical hatch" )
143 // _TL("Use the stipple bitmap" )
144 // _TL("Use the user dashes" )
145 // _TL("No pen is used" )
146 ), 4
147 );
148
149 //-----------------------------------------------------
150 m_Parameters.Add_Bool("NODE_DISPLAY",
151 "LABEL" , _TL("Label"),
152 _TL(""),
153 true
154 );
155
156 m_Parameters.Add_Choice("LABEL",
157 "LABEL_UNITS" , _TL("Units"),
158 _TL(""),
159 CSG_String::Format("%s|%s|%s",
160 _TL("Decimal Degrees"),
161 _TL("Degrees, Minutes, Seconds"),
162 _TL("Degrees, Minutes, Seconds (significant)")
163 ), 0
164 );
165
166 m_Parameters.Add_Int("LABEL",
167 "LABEL_DECIMALS", _TL("Decimals"),
168 _TL("Maximum number of decimals of a second to be printed."),
169 2, 1, true
170 );
171
172 m_Parameters.Add_Font("LABEL",
173 "LABEL_FONT" , _TL("Font"),
174 _TL("")
175 );
176
177 m_Parameters.Add_Double("LABEL",
178 "LABEL_SIZE" , _TL("Size"),
179 _TL("Font size given as percentage of map size."),
180 2., 0., true, 10., true
181 );
182
183 m_Parameters.Add_Choice("LABEL",
184 "LABEL_ORIENT" , _TL("Latitude Orientation"),
185 _TL(""),
186 CSG_String::Format("%s|%s",
187 _TL("horizontal"),
188 _TL("vertical")
189 ), 1
190 );
191
192 m_Parameters.Add_Choice("LABEL",
193 "LABEL_EFFECT" , _TL("Boundary Effect"),
194 _TL(""),
195 CSG_String::Format("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s",
196 _TL("none" ),
197 _TL("full frame" ),
198 _TL("top" ),
199 _TL("top left" ),
200 _TL("left" ),
201 _TL("bottom left" ),
202 _TL("bottom" ),
203 _TL("bottom right"),
204 _TL("right" ),
205 _TL("top right" )
206 ), 1
207 );
208
209 m_Parameters.Add_Color("LABEL",
210 "LABEL_EFFCOL" , _TL("Boundary Effect Color"),
211 _TL(""),
212 SG_GET_RGB(255, 255, 255)
213 );
214}
215
216//---------------------------------------------------------
221
222
224// //
226
227//---------------------------------------------------------
229{
230 m_Parameters.Assign_Values(&Parameters);
231
233
234 return( true );
235}
236
237//---------------------------------------------------------
239{
240 if( Flags & PARAMETER_CHECK_ENABLE )
241 {
242 if( Parameter.Cmp_Identifier("INTERVAL") )
243 {
244 Parameters.Set_Enabled("FIXED" , Parameter.asInt() == 0);
245 Parameters.Set_Enabled("FITTED" , Parameter.asInt() == 1);
246 }
247
248 if( Parameter.Cmp_Identifier("SHOW_ALWAYS") )
249 {
250 Parameters.Set_Enabled("SHOW_RANGE", Parameter.asBool() == false);
251 }
252
253 if( Parameter.Cmp_Identifier("LABEL") )
254 {
255 Parameter.Set_Children_Enabled(Parameter.asBool());
256 }
257 }
258
259 return( true );
260}
261
262//---------------------------------------------------------
264{
265 return( true );
266}
267
268
270// //
272
273//---------------------------------------------------------
275{
276 if( !Get_Graticule(dc_Map.rWorld(), Projection) || m_Graticule.Get_Count() <= 0 )
277 {
278 return( false );
279 }
280
281 //-----------------------------------------------------
282 if( m_Parameters["TRANSPARENCY"].asDouble() > 0. )
283 {
284 dc_Map.Draw_Layer_Begin();
285 }
286
287 //-----------------------------------------------------
288 wxPen Pen(m_Parameters["LINE_COLOR"].asColor(), m_Parameters["LINE_WIDTH"].asInt());
289
290 switch( m_Parameters["LINE_STYLE"].asInt() )
291 {
292 default: Pen.SetStyle(wxPENSTYLE_SOLID ); break; // Solid style.
293 case 1: Pen.SetStyle(wxPENSTYLE_DOT ); break; // Dotted style.
294 case 2: Pen.SetStyle(wxPENSTYLE_LONG_DASH ); break; // Long dashed style.
295 case 3: Pen.SetStyle(wxPENSTYLE_SHORT_DASH ); break; // Short dashed style.
296 case 4: Pen.SetStyle(wxPENSTYLE_DOT_DASH ); break; // Dot and dash style.
297 case 5: Pen.SetStyle(wxPENSTYLE_BDIAGONAL_HATCH ); break; // Backward diagonal hatch.
298 case 6: Pen.SetStyle(wxPENSTYLE_CROSSDIAG_HATCH ); break; // Cross-diagonal hatch.
299 case 7: Pen.SetStyle(wxPENSTYLE_FDIAGONAL_HATCH ); break; // Forward diagonal hatch.
300 case 8: Pen.SetStyle(wxPENSTYLE_CROSS_HATCH ); break; // Cross hatch.
301 case 9: Pen.SetStyle(wxPENSTYLE_HORIZONTAL_HATCH); break; // Horizontal hatch.
302 case 10: Pen.SetStyle(wxPENSTYLE_VERTICAL_HATCH ); break; // Vertical hatch.
303// case 11: Pen.SetStyle(wxPENSTYLE_STIPPLE ); break; // Use the stipple bitmap.
304// case 12: Pen.SetStyle(wxPENSTYLE_USER_DASH ); break; // Use the user dashes: see wxPen::SetDashes.
305// case 13: Pen.SetStyle(wxPENSTYLE_TRANSPARENT ); break; // No pen is used.
306 }
307
308 dc_Map.SetPen(Pen);
309
310 //-----------------------------------------------------
311 for(sLong iLine=0; iLine<m_Graticule.Get_Count(); iLine++)
312 {
313 CSG_Shape *pLine = m_Graticule.Get_Shape(iLine);
314
315 for(int iPart=0; iPart<pLine->Get_Part_Count(); iPart++)
316 {
317 if( pLine->Get_Point_Count(iPart) > 1 )
318 {
319 TSG_Point_Int B, A = dc_Map.World2DC(pLine->Get_Point(0, iPart));
320
321 for(int iPoint=1; iPoint<pLine->Get_Point_Count(iPart); iPoint++)
322 {
323 B = A; A = dc_Map.World2DC(pLine->Get_Point(iPoint, iPart));
324
325 dc_Map.DrawLine(A.x, A.y, B.x, B.y);
326 }
327 }
328 }
329 }
330
331 //-----------------------------------------------------
332 if( m_Parameters["LABEL"].asBool() )
333 {
334 int Size = (int)(0.5 + 0.01 * m_Parameters["LABEL_SIZE"].asDouble()
335 * ( dc_Map.rDC().GetWidth() < dc_Map.rDC().GetHeight()
336 ? dc_Map.rDC().GetWidth() : dc_Map.rDC().GetHeight() )
337 );
338
339 if( Size > 2 )
340 {
341 bool bLatVertical = m_Parameters["LABEL_ORIENT"].asInt() == 1;
342 int Effect, Units = m_Parameters["LABEL_UNITS" ].asInt(), Decimals = m_Parameters["LABEL_DECIMALS"].asInt();
343 wxColour Effect_Color = SG_Get_wxColor(m_Parameters["LABEL_EFFCOL"].asInt());
344 wxFont Font = SG_Get_wxFont (m_Parameters("LABEL_FONT"));
345
346 Font.SetPointSize(Size);
347
348 dc_Map.SetFont(Font);
349 dc_Map.Get_DC().SetTextForeground(m_Parameters["LABEL_FONT"].asColor());
350
351 switch( m_Parameters["LABEL_EFFECT"].asInt() )
352 {
353 default: Effect = SG_DC_TEXTEFFECT_NONE ; break;
354 case 1: Effect = SG_DC_TEXTEFFECT_FRAME ; break;
355 case 2: Effect = SG_DC_TEXTEFFECT_TOP ; break;
356 case 3: Effect = SG_DC_TEXTEFFECT_TOPLEFT ; break;
357 case 4: Effect = SG_DC_TEXTEFFECT_LEFT ; break;
358 case 5: Effect = SG_DC_TEXTEFFECT_BOTTOMLEFT ; break;
359 case 6: Effect = SG_DC_TEXTEFFECT_BOTTOM ; break;
360 case 7: Effect = SG_DC_TEXTEFFECT_BOTTOMRIGHT; break;
361 case 8: Effect = SG_DC_TEXTEFFECT_RIGHT ; break;
362 case 9: Effect = SG_DC_TEXTEFFECT_TOPRIGHT ; break;
363 }
364
365 for(sLong iPoint=0; iPoint<m_Coordinates.Get_Count(); iPoint++)
366 {
367 CSG_Shape *pPoint = m_Coordinates.Get_Shape(iPoint);
368
369 TSG_Point_Int p(dc_Map.World2DC(pPoint->Get_Point())); wxString Type(pPoint->asString(0));
370
371 CSG_String Coordinate(Get_Unit(pPoint, Units, Decimals, (!Type.Cmp("LAT_MIN") || !Type.Cmp("LAT_MAX"))));
372
373 int Align; double Angle;
374
375 if( bLatVertical )
376 {
377 Align = !Type.Cmp("LON_MIN") ? SG_DC_TEXTALIGN_BOTTOMCENTER : SG_DC_TEXTALIGN_TOPCENTER;
378 Angle = !Type.Cmp("LAT_MIN") ? 90. : !Type.Cmp("LAT_MAX") ? -90. : 0.;
379 }
380 else
381 {
382 Align = !Type.Cmp("LAT_MIN") ? SG_DC_TEXTALIGN_CENTERLEFT
383 : !Type.Cmp("LAT_MAX") ? SG_DC_TEXTALIGN_CENTERRIGHT
384 : !Type.Cmp("LON_MIN") ? SG_DC_TEXTALIGN_BOTTOMCENTER
385 : !Type.Cmp("LON_MAX") ? SG_DC_TEXTALIGN_TOPCENTER : SG_DC_TEXTALIGN_CENTER;
386 Angle = 0.;
387 }
388
389 dc_Map.DrawText(Align, p.x, p.y, Angle, Coordinate.c_str(), Effect, Effect_Color);
390 }
391 }
392 }
393
394 //-----------------------------------------------------
395 if( m_Parameters["TRANSPARENCY"].asDouble() > 0. )
396 {
397 dc_Map.Draw_Layer_End(m_Parameters["TRANSPARENCY"].asDouble() / 100.);
398 }
399
400 return( true );
401}
402
403
405// //
407
408//---------------------------------------------------------
409bool CSG_Map_Graticule::Get_Graticule(const CSG_Rect &Extent, const CSG_Projection &Projection)
410{
411 if( !Projection.is_Okay() || !Extent.Get_XRange() || !Extent.Get_YRange() )
412 {
413 return( false );
414 }
415
416 if( !m_pTool )
417 {
418 if( !(m_pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 14)) )
419 {
420 return( false );
421 }
422
423 m_pTool->Set_Manager(NULL);
424 }
425
426 m_Graticule .Create(SHAPE_TYPE_Line );
427 m_Coordinates.Create(SHAPE_TYPE_Point);
428
430
431 bool bResult =
432 m_pTool->Set_Parameter("XMIN" , Extent .Get_XMin())
433 && m_pTool->Set_Parameter("XMAX" , Extent .Get_XMax())
434 && m_pTool->Set_Parameter("YMIN" , Extent .Get_YMin())
435 && m_pTool->Set_Parameter("YMAX" , Extent .Get_YMax())
436 && m_pTool->Set_Parameter("CRS_WKT" , Projection.Get_WKT2())
437 && m_pTool->Set_Parameter("CRS_PROJ" , Projection.Get_PROJ())
438 && m_pTool->Set_Parameter("INTERVAL" , m_Parameters("INTERVAL" ))
439 && m_pTool->Set_Parameter("FIXED" , m_Parameters("FIXED" ))
440 && m_pTool->Set_Parameter("FITTED" , m_Parameters("FITTED" ))
441 && m_pTool->Set_Parameter("RESOLUTION", m_Parameters("RESOLUTION"))
442 && m_pTool->Set_Parameter("GRATICULE" , &m_Graticule)
443 && m_pTool->Set_Parameter("COORDS" , &m_Coordinates)
444 && m_pTool->On_Before_Execution()
445 && m_pTool->Execute();
446
448
449 return( bResult );
450}
451
452
454// //
456
457//---------------------------------------------------------
458CSG_String CSG_Map_Graticule::Get_Unit(CSG_Shape *pPoint, int Units, int Decimals, bool bLatitude)
459{
460 double Value = pPoint->asDouble(1);
461
462 const SG_Char *D = SG_T("\xb0");
463
464 const SG_Char *C = bLatitude
465 ? (Value < 0. ? SG_T("S") : SG_T("N"))
466 : (Value > 0. ? SG_T("E") : SG_T("W"));
467
468 CSG_String String;
469
470 //-----------------------------------------------------
471 if( Units == 0 ) // decimal degrees
472 {
473 // String.Printf("%s%s", pPoint->asString(1) + (Value < 0 ? 1 : 0), D); // no! label already includes degree symbol
474 String.Printf("%s", pPoint->asString(1) + (Value < 0 ? 1 : 0));
475 }
476
477 //-----------------------------------------------------
478 else // degrees, minutes, seconds
479 {
480 if( Value < 0. )
481 {
482 Value = -Value;
483 }
484
485 Value = fmod(Value, 360.);
486 int d = (int)Value;
487 Value = (Value - d) * 60.;
488 int h = (int)Value;
489 Value = (Value - h) * 60.;
490 int s = (int)Value;
491 Value = (Value - s);
492
493 //-------------------------------------------------
494 if( Value > 0. ) // floating point remainder
495 {
496 int n = SG_Get_Significant_Decimals(Value, Decimals);
497
498 String.Printf("%d%s%02d'%02d.%d''", d, D, h, s, (int)(Value * pow(10, n)));
499 }
500 else if( s > 0 || Units == 1 )
501 {
502 String.Printf("%d%s%02d'%02d''" , d, D, h, s);
503 }
504 else if( h > 0 )
505 {
506 String.Printf("%d%s%02d'" , d, D, h);
507 }
508 else
509 {
510 String.Printf("%d%s" , d, D);
511 }
512 }
513
514 String += C;
515
516 return( String );
517}
518
519
521// //
522// //
523// //
525
526//---------------------------------------------------------
void SG_UI_ProgressAndMsg_Lock(bool bOn)
signed long long sLong
Definition api_core.h:158
#define SG_T(s)
Definition api_core.h:537
#define SG_COLOR_GREY
Definition api_core.h:1355
#define SG_Char
Definition api_core.h:536
#define SG_GET_RGB(r, g, b)
Definition api_core.h:1345
#define _TL(s)
Definition api_core.h:1619
SAGA_API_DLL_EXPORT int SG_Get_Significant_Decimals(double Value, int maxDecimals=6)
bool Draw_Layer_Begin(void)
Definition map_dc.cpp:271
void SetPen(const wxPen &Pen)
Definition map_dc.cpp:482
const CSG_Rect & rWorld(void) const
Definition map_dc.h:124
bool Draw_Layer_End(double Transparency=0.)
Definition map_dc.cpp:290
void DrawLine(int x1, int y1, int x2, int y2)
Definition map_dc.cpp:524
wxMemoryDC & Get_DC(void)
Definition map_dc.h:96
const wxRect & rDC(void) const
Definition map_dc.h:129
const double & World2DC(void) const
Definition map_dc.h:131
void SetFont(const wxFont &Font)
Definition map_dc.cpp:471
void DrawText(int Align, int x, int y, const wxString &Text)
Definition map_dc.cpp:616
virtual bool Parameter_Changed(CSG_Parameters &Parameters, CSG_Parameter &Parameter, int Flags)
virtual ~CSG_Map_Graticule(void)
virtual bool Draw(CSG_Map_DC &dc, const CSG_Projection &Projection)
virtual bool Parameters_Changed(void)
virtual bool Set_Parameters(const CSG_Parameters &Parameters)
bool Set_Children_Enabled(bool bEnabled=true)
bool asBool(void) const
Definition parameters.h:286
bool Cmp_Identifier(const CSG_String &Identifier) const
int asInt(void) const
Definition parameters.h:287
void Set_Enabled(bool bEnabled=true)
virtual int Get_Point_Count(void) const =0
virtual int Get_Part_Count(void) const =0
virtual TSG_Point Get_Point(int iPoint=0) const =0
static CSG_String Format(const char *Format,...)
const SG_Char * c_str(void) const
int Printf(const char *Format,...)
double asDouble(int Field) const
const SG_Char * asString(int Field, int Decimals=-99) const
bool Delete_Tool(CSG_Tool *pTool) const
wxColour SG_Get_wxColor(int Color)
Definition dc_helper.cpp:70
wxFont SG_Get_wxFont(CSG_Parameter *pFont)
#define SG_DC_TEXTALIGN_TOPCENTER
Definition dc_helper.h:132
#define SG_DC_TEXTEFFECT_TOPRIGHT
Definition dc_helper.h:149
#define SG_DC_TEXTEFFECT_LEFT
Definition dc_helper.h:144
#define SG_DC_TEXTALIGN_CENTER
Definition dc_helper.h:135
#define SG_DC_TEXTALIGN_BOTTOMCENTER
Definition dc_helper.h:138
#define SG_DC_TEXTEFFECT_BOTTOM
Definition dc_helper.h:146
#define SG_DC_TEXTEFFECT_NONE
Definition dc_helper.h:141
#define SG_DC_TEXTEFFECT_BOTTOMRIGHT
Definition dc_helper.h:147
#define SG_DC_TEXTEFFECT_TOPLEFT
Definition dc_helper.h:143
#define SG_DC_TEXTEFFECT_BOTTOMLEFT
Definition dc_helper.h:145
#define SG_DC_TEXTALIGN_CENTERRIGHT
Definition dc_helper.h:136
#define SG_DC_TEXTEFFECT_RIGHT
Definition dc_helper.h:148
#define SG_DC_TEXTEFFECT_TOP
Definition dc_helper.h:142
#define SG_DC_TEXTEFFECT_FRAME
Definition dc_helper.h:150
#define SG_DC_TEXTALIGN_CENTERLEFT
Definition dc_helper.h:134
#define B
#define A
#define C
struct SSG_Point_Int TSG_Point_Int
#define asDouble(i)
#define PARAMETER_CHECK_ENABLE
Definition parameters.h:191
@ SHAPE_TYPE_Line
Definition shapes.h:104
@ SHAPE_TYPE_Point
Definition shapes.h:102
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)