1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Tool Library //
9 // Table_Tools //
10 // //
11 //-------------------------------------------------------//
12 // //
13 // Table_Enumerate.cpp //
14 // //
15 // Copyright (C) 2005 by //
16 // SAGA User Group Associaton //
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 // e-mail: oconrad@gwdg.de //
40 // //
41 // contact: SAGA User Group Associaton //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 ///////////////////////////////////////////////////////////
49
50 //---------------------------------------------------------
51 #include "Table_Enumerate.h"
52
53
54 ///////////////////////////////////////////////////////////
55 // //
56 // //
57 // //
58 ///////////////////////////////////////////////////////////
59
60 //---------------------------------------------------------
CTable_Enumerate(bool bShapes)61 CTable_Enumerate::CTable_Enumerate(bool bShapes)
62 {
63 Set_Author("O.Conrad (c) 2017");
64
65 Set_Description(_TW(
66 "Enumeration of a table attribute, i.e. a unique identifier "
67 "is assigned to identical values of the chosen attribute field. "
68 "If no attribute is chosen, a simple enumeration is done for "
69 "all records, and this with respect to the sorting order "
70 "if the dataset has been indexed.\n"
71 ));
72
73 if( bShapes )
74 {
75 Set_Name(_TL("Table Field Enumeration (Shapes)"));
76
77 Parameters.Add_Shapes("", "INPUT" , _TL("Input" ), _TL(""), PARAMETER_INPUT);
78 Parameters.Add_Shapes("", "OUTPUT", _TL("Output"), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
79 }
80 else
81 {
82 Set_Name(_TL("Table Field Enumeration"));
83
84 Parameters.Add_Table ("", "INPUT" , _TL("Input" ), _TL(""), PARAMETER_INPUT);
85 Parameters.Add_Table ("", "OUTPUT", _TL("Output"), _TL(""), PARAMETER_OUTPUT_OPTIONAL);
86 }
87
88 Parameters.Add_Table_Field("INPUT",
89 "FIELD" , _TL("Attribute"),
90 _TL(""),
91 true
92 );
93
94 Parameters.Add_Table_Field("INPUT",
95 "ENUM" , _TL("Enumeration"),
96 _TL(""),
97 true
98 );
99
100 Parameters.Add_String("ENUM",
101 "NAME" , _TL("Enumeration Field Name"),
102 _TL(""),
103 "ENUM"
104 );
105
106 Parameters.Add_Choice("",
107 "ORDER" , _TL("Order"),
108 _TL(""),
109 CSG_String::Format("%s|%s",
110 _TL("ascending"),
111 _TL("descending")
112 ), 0
113 );
114 }
115
116 //---------------------------------------------------------
Get_MenuPath(void)117 CSG_String CTable_Enumerate::Get_MenuPath(void)
118 {
119 if( Parameters("INPUT")->Get_Type() == PARAMETER_TYPE_Shapes )
120 {
121 return( _TL("A:Shapes|Table") );
122 }
123
124 return( CSG_Tool::Get_MenuPath() );
125 }
126
127
128 ///////////////////////////////////////////////////////////
129 // //
130 ///////////////////////////////////////////////////////////
131
132 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)133 int CTable_Enumerate::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
134 {
135 if( pParameter->Cmp_Identifier("ENUM") )
136 {
137 CSG_Table *pTable = (*pParameters)("INPUT")->asTable();
138
139 pParameters->Set_Enabled("NAME", pTable && pParameter->asInt() >= pTable->Get_Field_Count());
140 }
141
142 return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
143 }
144
145
146 ///////////////////////////////////////////////////////////
147 // //
148 ///////////////////////////////////////////////////////////
149
150 //---------------------------------------------------------
On_Execute(void)151 bool CTable_Enumerate::On_Execute(void)
152 {
153 CSG_Table *pTable = Parameters("INPUT")->asTable();
154
155 if( pTable->Get_Record_Count() <= 0 )
156 {
157 Error_Set(_TL("no records in data set"));
158
159 return( false );
160 }
161
162 //-----------------------------------------------------
163 if( Parameters("OUTPUT")->asTable() && Parameters("OUTPUT")->asTable() != pTable )
164 {
165 CSG_Table *pInput = pTable; pTable = Parameters("OUTPUT")->asTable();
166
167 if( pTable->Get_ObjectType() == SG_DATAOBJECT_TYPE_Shapes )
168 {
169 ((CSG_Shapes *)pTable)->Create(*((CSG_Shapes *)pInput)); // copy constructor
170 }
171 else
172 {
173 pTable->Create(*pInput); // copy constructor
174 }
175
176 pTable->Fmt_Name("%s [%s]", pTable->Get_Name(), _TL("Enumerated"));
177 }
178
179 //-----------------------------------------------------
180 bool bAscending = Parameters("ORDER")->asInt() != 1;
181
182 int Field = Parameters("FIELD")->asInt();
183 int Enum = Parameters("ENUM" )->asInt();
184
185 if( Enum < 0 )
186 {
187 Enum = pTable->Get_Field_Count();
188
189 CSG_String Name = Parameters("NAME")->asString();
190
191 if( Name.is_Empty() )
192 {
193 Name = "NR";
194 }
195
196 if( Field >= 0 )
197 {
198 Name += CSG_String("_") + pTable->Get_Field_Name(Field);
199 }
200
201 pTable->Add_Field(Name, SG_DATATYPE_Int);
202 }
203
204 //-----------------------------------------------------
205 if( Field < 0 )
206 {
207 for(int i=0; i<pTable->Get_Count(); i++)
208 {
209 pTable->Get_Record_byIndex(i)->Set_Value(Enum, bAscending ? 1 + i : pTable->Get_Count() - i);
210 }
211 }
212
213 //-----------------------------------------------------
214 else
215 {
216 CSG_Index Index;
217
218 if( !pTable->Set_Index(Index, Field, bAscending) )
219 {
220 Error_Fmt("%s (%s)", _TL("failed to create index on field"), pTable->Get_Field_Name(Field));
221
222 return( false );
223 }
224
225 CSG_String Value(pTable->Get_Record(Index[0])->asString(Field));
226
227 for(int i=0, n=1; i<pTable->Get_Count() && Set_Progress(i, pTable->Get_Count()); i++)
228 {
229 CSG_Table_Record *pRecord = pTable->Get_Record(Index[i]);
230
231 if( Value.Cmp(pRecord->asString(Field)) )
232 {
233 Value = pRecord->asString(Field);
234
235 n++;
236 }
237
238 pRecord->Set_Value(Enum, n);
239 }
240 }
241
242 //-----------------------------------------------------
243 if( pTable == Parameters("INPUT")->asTable() )
244 {
245 DataObject_Update(pTable);
246 }
247
248 return( true );
249 }
250
251
252 ///////////////////////////////////////////////////////////
253 // //
254 // //
255 // //
256 ///////////////////////////////////////////////////////////
257
258 //---------------------------------------------------------
259