pavi  0.0
Map Path Viewer
parser_gpx.bas
Go to the documentation of this file.
1 
9 
10 #INCLUDE ONCE "Gir/GLib-2.0.bi"
11 #INCLUDE ONCE "parser_gpx.bi"
12 #INCLUDE ONCE "datetime.bi"
13 
14 #IFDEF __FB_UNIX__
15 
16  #DEFINE NL !"\n" &
17 #ELSE
18  #DEFINE NL !"\r\n" &
19 '&*/
20 #ENDIF
21 
22 
23 
32 FUNCTION isnum(BYVAL N AS DOUBLE) AS INTEGER
33  SELECT CASE CAST(ULONG PTR, @N)[1]
34  CASE &h7FF00000UL, &hFFF00000UL : RETURN 0 ' +/- INF
35  CASE &h7FF80000UL, &hFFF80000UL : RETURN 0 ' +/- NaN
36  END SELECT : RETURN -1
37 END FUNCTION
38 
39 
40 
47 #DEFINE fetch(_T_) find_value(_T_, AttNams, AttVals)
48 
49 
58 #MACRO _START_PARSER(_N_)
59  SUB start_##_N_ CDECL( _
60  BYVAL ctx AS GMarkupParseContext PTR, _
61  BYVAL element_name AS CONST gchar PTR, _
62  BYVAL AttNams AS CONST gchar PTR PTR, _
63  BYVAL AttVals AS CONST gchar PTR PTR, _
64  BYVAL UserData AS gpointer, _
65  BYVAL error_ AS GError PTR PTR)
66  WITH PEEK(GPX, UserData)
67 #ENDMACRO
68 
69 
81 #MACRO _END_PARSER(_N_)
82  CASE ELSE
83  'PRINT NL "--> " & __FUNCTION__ & " Skipping " & *element_name
84  g_markup_parse_context_push(ctx, @Skip_parser, UserData) '& skip_parser();
85  END SELECT
86  END WITH
87  END SUB
88  SUB end_##_N_ CDECL( _
89  BYVAL ctx AS GMarkupParseContext PTR, _
90  BYVAL element_name AS CONST gchar PTR, _
91  BYVAL UserData AS gpointer, _
92  BYVAL error_ AS GError PTR PTR)
93  WITH PEEK(GPX, UserData)
94 #ENDMACRO
95 
96 
110 #MACRO _NEW_PARSER(_N_,_T_)
111  CASE ELSE
112  g_markup_parse_context_pop(ctx)
113  END SELECT
114  END WITH
115  END SUB
116  STATIC SHARED AS GMarkupParser _N_##_parser = TYPE(@start_##_N_, @end_##_N_, _T_, NULL, NULL)
117 #ENDMACRO
118 
119 
120 
121 '& SUB_CDECL skip_parser(){}; /*
122 STATIC SHARED AS GMarkupParser Skip_parser = TYPE(NULL, NULL, NULL, NULL, NULL)
123 '& */
124 
125 
137 FUNCTION find_value( _
138  BYVAL Nam AS CONST gchar PTR, _
139  BYVAL AttNams AS CONST gchar PTR PTR, _
140  BYVAL AttVals AS CONST gchar PTR PTR) AS CONST gchar PTR
141 
142  VAR i = 0
143  WHILE AttNams[i]
144  IF *AttNams[i] = *Nam THEN RETURN AttVals[i]
145  i += 1
146  WEND : RETURN NULL
147 END FUNCTION
148 
149 
150 
162 SUB text_content CDECL( _
163  BYVAL Ctx AS GMarkupParseContext PTR, _
164  BYVAL Text AS CONST gchar PTR, _
165  BYVAL Size AS gsize, _
166  BYVAL UserData AS gpointer, _
167  BYVAL Error_ AS GError PTR PTR)
168 
169  CAST(GPX PTR, UserData)->Cont = LEFT(*Text, Size)
170 END SUB
171 
172 
173 '& SUB_CDECL EXT_parser(){
174 '& find_value();
175 EXT_parser:
176 _START_PARSER(EXT)
177 
178  SELECT CASE *element_name
179  CASE "dir", "g_spd"
180 
181 _END_PARSER(EXT)
182 
183  SELECT CASE *element_name
184 '<dir>139</dir>
185  CASE "dir"
186  .Ang = g_ascii_strtod(.Cont, NULL)
187 '<g_spd>5.02999877929688</g_spd>
188  CASE "g_spd"
189  .Spd = g_ascii_strtod(.Cont, NULL) * 1.852 '[km/mile]
190 
191 _NEW_PARSER(EXT,@text_content)
192 '& };
193 
194 
195 
196 '& SUB_CDECL PNT_parser(){
197 '& find_value();
198 PNT_parser:
199 _START_PARSER(PNT)
200 
201  SELECT CASE *element_name
202  CASE "ele", "time"
203  CASE "extensions"
204  g_markup_parse_context_push(ctx, @EXT_parser, UserData)
205 
206 _END_PARSER(PNT)
207 
208  SELECT CASE *element_name
209 '<ele>460.00</ele>
210  CASE "ele"
211  .Ele = g_ascii_strtod(.Cont, NULL)
212 '<time>2020-07-10T18:31:57Z</time>
213  CASE "time"
214  .Tim = _
215  DATESERIAL( _
216  VALINT(MID(.Cont, 1, 4)) _
217  , VALINT(MID(.Cont, 6, 2)) _
218  , VALINT(MID(.Cont, 9, 2)) ) _
219  + TIMESERIAL( _
220  VALINT(MID(.Cont, 12, 2)) _
221  , VALINT(MID(.Cont, 15, 2)) _
222  , VALINT(MID(.Cont, 18, 2)) )
223  CASE "extensions"
224  g_markup_parse_context_pop(ctx)
225  .Ext += 1
226 
227 _NEW_PARSER(PNT,@text_content)
228 '& };
229 
230 
231 
232 '& SUB_CDECL SEG_parser(){
233 '& find_value();
234 SEG_parser:
235 _START_PARSER(SEG)
236 
237  SELECT CASE *element_name
238 '<trkpt lat="47.243324" lon="15.310627">
239  CASE "trkpt"
240  var _
241  p = fetch("lat") : if p then .Lat = g_ascii_strtod(p, NULL) * Deg2Rad
242  p = fetch("lon") : if p then .Lon = g_ascii_strtod(p, NULL) * Deg2Rad
243  g_markup_parse_context_push(ctx, @PNT_parser, UserData)
244 
245 _END_PARSER(SEG)
246 
247  SELECT CASE *element_name
248  CASE "trkpt"
249  g_markup_parse_context_pop(ctx)
250  VAR x = NEW(.Dat) TrP ( _
251  .Tim _
252  , .Lat _
253  , .Lon _
254  , .Ele _
255  , .Spd _
256  , .Ang _
257  , 0 ,0)
258  .Dat += SIZEOF(TrP)
259  IF isnum(.Tim) THEN .Tim = NaN ELSE .TiX += 1
260  IF isnum(.Lon) THEN .Lon = NaN ELSE .LoX += 1
261  IF isnum(.Lat) THEN .Lat = NaN ELSE .LaX += 1
262  IF isnum(.Ele) THEN .Ele = NaN ELSE .ElX += 1
263  IF isnum(.Spd) THEN .Spd = NaN ELSE .SpX += 1
264  IF isnum(.Ang) THEN .Ang = NaN ELSE .AnX += 1
265  .Pnt += 1
266 
267 _NEW_PARSER(SEG,NULL)
268 '& };
269 
270 
271 
272 '& SUB_CDECL TRK_parser(){
273 '& find_value();
274 TRK_parser:
275 _START_PARSER(TRK)
276 
277  SELECT CASE *element_name
278 '<name>2020-07-10_20-32-00.gpx</name>
279  CASE "name"
280 '<trkseg>
281  CASE "trkseg"
282  g_markup_parse_context_push(ctx, @SEG_parser, UserData)
283 
284 _END_PARSER(TRK)
285 
286  SELECT CASE *element_name
287  CASE "name"
288  CASE "trkseg"
289  g_markup_parse_context_pop(ctx)
290  .Seg += 1
291 
292 _NEW_PARSER(TRK,@text_content)
293 '& };
294 
295 
296 '& SUB_CDECL GPX_parser(){
297 '& find_value();
298 GPX_parser:
299 _START_PARSER(GPX)
300 
301  SELECT CASE *element_name
302 '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" creator="com.mapfactor.navigator">
303  CASE "gpx"
304  '?NL " " & *fetch("xmlns");
305  '?NL " " & *fetch("version");
306  '?NL " " & *fetch("xmlns:xsi");
307  '?NL " " & *fetch("xsi:schemaLocation");
308  '?NL " " & *fetch("creator");
309 '<trk>
310  CASE "trk"
311  g_markup_parse_context_push(ctx, @TRK_parser, UserData)
312 
313 _END_PARSER(GPX)
314 
315  SELECT CASE *element_name
316  CASE "gpx"
317  CASE "trk"
318  g_markup_parse_context_pop(ctx)
319  .Trk += 1
320 
321 _NEW_PARSER(GPX,NULL)
322 '& };
323 
324 
325 
336 CONSTRUCTOR GPX(BYVAL Parent AS TrackLoader PTR)
337 WITH *Parent
338  Dat = .Buff
339  DIM AS GError PTR er_r = NULL ' *< location for GLib errors
340  VAR ctx = g_markup_parse_context_new(@GPX_parser, 0, @THIS, NULL)
341  IF g_markup_parse_context_parse(ctx, .Buff, .Byt, @er_r) THEN _
342  IF 0 = g_markup_parse_context_end_parse(ctx, @er_r) THEN _
343  Tix += 1 : .Errr = @"cannot parse (invalid content)"
344  g_markup_parse_context_free(ctx)
345  .Siz = Dat - CAST(ANY PTR, .Buff)
346 END WITH
347 END CONSTRUCTOR
348 
parser_gpx.bi
Header code for GPX parser.
TRK_parser
SUB_CDECL TRK_parser()
The GMarkupParser for <trk> tags.
Definition: parser_gpx.bas:243
GPX_parser
SUB_CDECL GPX_parser()
The GMarkupParser for *.GPX files.
Definition: parser_gpx.bas:267
skip_parser
SUB_CDECL skip_parser()
This GMarkupParser parser does nothing, used for skipping unused XML-tags.
Definition: parser_gpx.bas:92
isnum
*FUNCTION_AS_INTEGER isnum(BYVAL_AS_DOUBLE N)
Check if floating point number is valid.
Definition: parser_gpx.bas:32
PNT_parser
SUB_CDECL PNT_parser()
The GMarkupParser for <trkpt> tags.
Definition: parser_gpx.bas:167
text_content
SUB_CDECL text_content(BYVAL_AS_GMarkupParseContext_PTR Ctx, BYVAL_AS_CONST_gchar_PTR Text, BYVAL_AS_gsize Size, BYVAL_AS_gpointer UserData, BYVAL_AS_GError_PTR_PTR Error_)
Grep content between start and end tag.
Definition: parser_gpx.bas:133
GPX::GPX
GPX(BYVAL_AS_TrackLoader_PTR)
CTOR parsing the context of a *.GPX file.
Definition: parser_gpx.bas:307
TrP
Data for a single track point.
Definition: track_loader.bi:32
find_value
FUNCTION_AS_CONST_gchar_PTR find_value(BYVAL_AS_CONST_gchar_PTR Nam, BYVAL_AS_CONST_gchar_PTR_PTR AttNams, BYVAL_AS_CONST_gchar_PTR_PTR AttVals)
Find an attribute by its name.
Definition: parser_gpx.bas:108
SEG_parser
SUB_CDECL SEG_parser()
The GMarkupParser for <trkseg> tags.
Definition: parser_gpx.bas:203
EXT_parser
SUB_CDECL EXT_parser()
The GMarkupParser for <extension> tags.
Definition: parser_gpx.bas:144
fetch
#define fetch(_T_)
Macro to read data from parser context.
Definition: parser_gpx.bas:47