FortranGIS Version 3.0
readosm.F90
1! Copyright 2011 Davide Cesari <dcesari69 at gmail dot com>
2!
3! This file is part of FortranGIS.
4!
5! FortranGIS is free software: you can redistribute it and/or modify
6! it under the terms of the GNU Lesser General Public License as
7! published by the Free Software Foundation, either version 3 of the
8! License, or (at your option) any later version.
9!
10! FortranGIS is distributed in the hope that it will be useful, but
11! WITHOUT ANY WARRANTY; without even the implied warranty of
12! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13! Lesser General Public License for more details.
14!
15! You should have received a copy of the GNU Lesser General Public
16! License along with FortranGIS. If not, see
17! <http://www.gnu.org/licenses/>.
18
19!> Fortran 2003 interface to the readosm
20!! https://www.gaia-gis.it/fossil/readosm/index library.
21!! ReadOSM is an open source library which is able to extract valid
22!! data from within an Open Street Map input file. It can read files
23!! in the .osm and .osm.pbf formats. ReadOSM is developed and
24!! maintained by Alessandro Furieri. This module defines an API which
25!! reflects the original readosm C API, plus some additional objects
26!! and methods to simplify the use from Fortran.
27!!
28!! The reading of the file is callback-based, i.e. a user-defined
29!! function is called whenever a node, way or relation is encounterd
30!! in the file; the callback functions receive a copy of the entity
31!! read from the file in the form of a C-interoperable derived type
32!! which matches exactly the structures defined in the original
33!! readosm C library. The derived types can be converted on the fly to
34!! a more Fortran-friendly version, where pointers are replaced with
35!! Fortran arrays where possible. It is up to the callbacks to do
36!! something useful with the data received.
37!!
38!! For an example of application of the \a readosm module, please
39!! refer to the following test program, which parses an osm file and
40!! dumps some information about it:
41!! \include readosm_test.F90
42!!
43!! \ingroup libfortrangis
44MODULE readosm
45use,INTRINSIC :: iso_c_binding
46USE fortranc
47IMPLICIT NONE
48
49
50INTEGER,PARAMETER :: READOSM_UNDEFINED = -1234567890 !< information is not available
51INTEGER,PARAMETER :: READOSM_MEMBER_NODE = 7361 !< MemberType: NODE
52INTEGER,PARAMETER :: READOSM_MEMBER_WAY = 6731 !< MemberType: WAY
53INTEGER,PARAMETER :: READOSM_MEMBER_RELATION = 3671 !< MemberType: RELATION
54INTEGER,PARAMETER :: READOSM_OK = 0 !< No error, success
55INTEGER,PARAMETER :: READOSM_INVALID_SUFFIX = -1 !< not .osm or .pbf suffix
56INTEGER,PARAMETER :: READOSM_FILE_NOT_FOUND = -2 !< .osm or .pbf file does not exist or is not accessible for reading
57INTEGER,PARAMETER :: READOSM_NULL_HANDLE = -3 !< Null OSM_handle argument
58INTEGER,PARAMETER :: READOSM_INVALID_HANDLE = -4 !< Invalid OSM_handle argument
59INTEGER,PARAMETER :: READOSM_INSUFFICIENT_MEMORY = -5 !< some kind of memory allocation failure
60INTEGER,PARAMETER :: READOSM_CREATE_XML_PARSER_ERROR = -6 !< cannot create the XML Parser
61INTEGER,PARAMETER :: readosm_read_error = -7 !< read error
62INTEGER,PARAMETER :: readosm_xml_error = -8 !< XML parser error
63INTEGER,PARAMETER :: readosm_invalid_pbf_header = -9 !< invalid PBF header
64INTEGER,PARAMETER :: readosm_unzip_error = -10 !< unZip error
65INTEGER,PARAMETER :: readosm_abort = -11 !< user-required parser abort
67!> Object describing a TAG structure.
68!! A derived type representing a <b>key:value</b> pair.
69TYPE,BIND(C) :: readosm_tag
70 TYPE(c_ptr) :: key !< the KEY
71 TYPE(c_ptr) :: value !< the VALUE
74!> A more Fortran-friendly object describing a TAG structure.
76 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: key(:) !< the KEY
77 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: value(:) !< the VALUE
78END TYPE readosm_tag_f
79
81!> Object describing a NODE structure.
82!! A derived type representing a NODE object, wrapping a complex
83!! XML fragment like the following:
84!! \verbatim
85!! <node id="12345" lat="6.66666" lon="7.77777" version="1" changeset="54321" user="some-user" uid="66" timestamp="2005-02-28T17:45:15Z">
86!! <tag key="created_by" value="JOSM" />
87!! <tag key="tourism" value="camp_site" />
88!! </node>
89!! \endverbatim
90TYPE,BIND(C) :: readosm_node
91 INTEGER(kind=c_long_long) :: id !< NODE-ID (expected to be a unique value)
92 REAL(kind=c_double) :: latitude !< geographic latitude
93 REAL(kind=c_double) :: longitude !< geographic longitude
94 INTEGER(kind=c_int) :: version !< object version
95 INTEGER(kind=c_long_long) :: changeset !< ChangeSet ID
96 TYPE(c_ptr) :: user !< name of the User defining this NODE
97 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
98 TYPE(c_ptr) :: timestamp !< when this NODE was defined
99 INTEGER(kind=c_int) :: tag_count !< number of associated TAGs (may be zero)
100 TYPE(c_ptr) :: tags !< array of TAG objects (may be NULL)
103!> A more Fortran-friendly object describing a NODE structure.
105 INTEGER(kind=c_long_long) :: id=0 !< NODE-ID (expected to be a unique value)
106 REAL(kind=c_double) :: latitude !< geographic latitude
107 REAL(kind=c_double) :: longitude !< geographic longitude
108 INTEGER(kind=c_int) :: version !< object version
109 INTEGER(kind=c_long_long) :: changeset !< ChangeSet ID
110! TYPE(c_ptr) :: user !< name of the User defining this NODE
111 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
112! TYPE(c_ptr) :: timestamp !< when this NODE was defined
113 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:) !< array of TAG objects (may be NULL)
114END TYPE readosm_node_f
117!> Object describing a WAY structure.
118!! A derived type representing a WAY object, wrapping a complex
119!! XML fragment like the following:
120!! \verbatim
121!! <way id="12345" version="1" changeset="54321" user="some-user" uid="66" timestamp="2005-02-28T17:45:15Z">
122!! <nd ref="12345" />
123!! <nd ref="12346" />
124!! <nd ref="12347" />
125!! <tag key="created_by" value="JOSM" />
126!! <tag key="tourism" value="camp_site" />
127!! </way>
128!! \endverbatim
129TYPE,BIND(C) :: readosm_way
130 INTEGER(kind=c_long_long) :: id !< WAY-ID (expected to be a unique value)
131 INTEGER(kind=c_int) :: version; !< object version
132 INTEGER(kind=c_long_long) :: changeset !< ChangeSet ID
133 TYPE(c_ptr) :: user !< name of the User defining this WAY
134 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
135 TYPE(c_ptr) :: timestamp; !< when this WAY was defined
136 INTEGER(kind=c_int) :: node_ref_count !< number of referenced NODE-IDs (may be zero)
137 TYPE(c_ptr) :: node_refs !< array of NODE-IDs (may be NULL)
138 INTEGER(kind=c_int) :: tag_count !< number of associated TAGs (may be zero)
139 TYPE(c_ptr) :: tags !< array of TAG objects (may be NULL)
142!> A more Fortran-friendly object describing a WAY structure.
144 INTEGER(kind=c_long_long) :: id=0 !< WAY-ID (expected to be a unique value)
145 INTEGER(kind=c_int) :: version; !< object version
146 INTEGER(kind=c_long_long) :: changeset; !< ChangeSet ID
147! TYPE(c_ptr) :: user !< name of the User defining this WAY
148 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
149! TYPE(c_ptr) :: timestamp; !< when this WAY was defined
150 INTEGER(kind=c_long_long),ALLOCATABLE :: node_refs(:) !< array of NODE-IDs (may be NULL)
151 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:) !< array of TAG objects (may be NULL)
152END TYPE readosm_way_f
153
155!> Object describing a RELATION-MEMBER structure.
156!! A derived type representing a RELATION-MEMBER object, and wrapping
157!! an XML fragment like the following:
158!! \verbatim
159!! <member type="some-type" ref="12345" role="some-role" />
160!! \endverbatim
161TYPE,BIND(C) :: readosm_member
162 INTEGER(kind=c_int) :: member_type !< can be one of: READOSM_MEMBER_NODE, READOSM_MEMBER_WAY or READOSM_MEMBER_RELATION
163 INTEGER(kind=c_long_long) :: id !< ID-value identifying the referenced object
164 TYPE(c_ptr) :: role !< intended role for this reference
165END TYPE readosm_member
166
167!> A more Fortran-friendly object describing a RELATION-MEMEBER structure.
168TYPE :: readosm_member_f
169 INTEGER(kind=c_int) :: member_type=readosm_undefined !< can be one of: READOSM_MEMBER_NODE, READOSM_MEMBER_WAY or READOSM_MEMBER_RELATION
170 INTEGER(kind=c_long_long) :: id !< ID-value identifying the referenced object
171 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: role(:) !< intended role for this reference
175!> Object describing a RELATION structure.
176!! A derived type representing a RELATION object, and wrapping a
177!! complex XML fragment like the following:
178!! \verbatim
179!! <relation id="12345" version="1" changeset="54321" user="some-user" uid="66" timestamp="2005-02-28T17:45:15Z">
180!! <member type="way" ref="12345" role="outer" />
181!! <member type="way" ref="12346" role="inner" />
182!! <tag key="created_by" value="JOSM" />
183!! <tag key="tourism" value="camp_site" />
184!! </relation>
185!! \endverbatim
186TYPE,BIND(C) :: readosm_relation
187 INTEGER(kind=c_long_long) :: id !< RELATION-ID (expected to be a unique value)
188 INTEGER(kind=c_int) :: version; !< object version
189 INTEGER(kind=c_long_long) :: changeset; !< ChangeSet ID
190 TYPE(c_ptr) :: user !< name of the User defining this RELATION
191 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
192 TYPE(c_ptr) :: timestamp; !< when this RELATION was defined
193 INTEGER(kind=c_int) :: member_count !< number of associated MEMBERs (may be zero)
194 TYPE(c_ptr) :: members !< array of MEMBER objects (may be NULL)
195 INTEGER(kind=c_int) :: tag_count; !< number of associated TAGs (may be zero)
196 TYPE(c_ptr) :: tags !< array of TAG objects (may be NULL)
199!> A more Fortran-friendly object describing a RELATION structure.
201 INTEGER(kind=c_long_long) :: id !< RELATION-ID (expected to be a unique value)
202 INTEGER(kind=c_int) :: version; !< object version
203 INTEGER(kind=c_long_long) :: changeset; !< ChangeSet ID
204! TYPE(c_ptr) :: user !< name of the User defining this RELATION
205 INTEGER(kind=c_int) :: uid !< corresponding numeric UserID
206! TYPE(c_ptr) :: timestamp; !< when this RELATION was defined
207 TYPE(readosm_member_f),ALLOCATABLE :: members(:) !< array of MEMBER objects (may be NULL)
208 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:) !< array of TAG objects (may be NULL)
209END TYPE readosm_relation_f
210
211! define dynamically extensible arrays of the _f types, first part
212#undef ARRAYOF_ORIGEQ
214#undef ARRAYOF_ORIGTYPE
215#undef ARRAYOF_TYPE
216#define ARRAYOF_ORIGTYPE TYPE(readosm_node_f)
217#define ARRAYOF_TYPE arrayof_readosm_node_f
218#include "arrayof_pre.F90"
220#undef ARRAYOF_ORIGTYPE
221#undef ARRAYOF_TYPE
222#define ARRAYOF_ORIGTYPE TYPE(readosm_way_f)
223#define ARRAYOF_TYPE arrayof_readosm_way_f
224#include "arrayof_pre.F90"
225
226#undef ARRAYOF_ORIGTYPE
227#undef ARRAYOF_TYPE
228#define ARRAYOF_ORIGTYPE TYPE(readosm_relation_f)
229#define ARRAYOF_TYPE arrayof_readosm_relation_f
230#include "arrayof_pre.F90"
231
232
233!> Derived type for performing a prepackaged full parsing of an osm file.
234!! An object of this type can contain all the information from an osm
235!! file and it can be used in association with the simpified \a
236!! readosm_parse_full_f method for importing the full information from
237!! a file in a DOM (Document Object Model) style.
239 TYPE(arrayof_readosm_node_f) :: nodes !< array containing all the nodes
240 TYPE(arrayof_readosm_way_f) :: ways !< array containing all the ways
241 TYPE(arrayof_readosm_relation_f) :: relations !< array containing all the relations
242END TYPE readosm_full_f
243
244
245!> Open the .osm or .pbf file, preparing for future functions.
246!! \return READOSM_OK will be returned on success, otherwise any
247!! appropriate error code on failure.
248!! \note You are expected to readosm_close() even on failure, so as to
249!! correctly release any dynamic memory allocation.
250INTERFACE
251 FUNCTION readosm_open(path, osm_handle) bind(C,name='readosm_open')
252 IMPORT
253 CHARACTER(kind=c_char),INTENT(in) :: path(*) !< full or relative pathname of the input file
254 TYPE(c_ptr),INTENT(out) :: osm_handle !< an opaque reference (handle) to be used in each subsequent function
255 INTEGER(kind=c_int) :: readosm_open
256 END FUNCTION readosm_open
257END INTERFACE
258
259
260!> Close the .osm or .pbf file and release any allocated resource.
261!! \return READOSM_OK will be returned on success, otherwise any
262!! appropriate error code on failure.
263!! \note After calling readosm_close() any related resource will be
264!! released, and the handle will no longer be valid.
265INTERFACE
266 FUNCTION readosm_close(osm_handle) bind(C,name='readosm_close')
267 IMPORT
268 TYPE(c_ptr),VALUE :: osm_handle !< the handle previously returned by readosm_open()
269 INTEGER(kind=c_int) :: readosm_close
270 END FUNCTION readosm_close
271END INTERFACE
273
274!> Parse the corresponding file calling the selected callbacks for
275!! every entity encountered.
276!! \return READOSM_OK will be returned on success, otherwise any
277!! appropriate error code on failure.
278INTERFACE readosm_parse
279!> Parse the corresponding file calling the selected callbacks for
280!! every entity encountered.
281!! This is the original C interface, where callback functions are
282!! interoperable C function pointers, \a c_null_funptr can be passed
283!! in order to disable the corresponding callback.
284!! \return READOSM_OK will be returned on success, otherwise any
285!! appropriate error code on failure.
286 FUNCTION readosm_parse(osm_handle, user_data, node_fnct, way_fnct, &
287 relation_fnct) bind(C,name='readosm_parse')
288 IMPORT
289 TYPE(c_ptr),VALUE :: osm_handle !< the handle previously returned by readosm_open()
290 TYPE(c_ptr),VALUE :: user_data !< user_data pointer to some user-supplied data struct
291 TYPE(c_funptr),VALUE :: node_fnct !< pointer to callback function intended to consume NODE objects (may be NULL if processing NODEs is not an interesting option)
292 TYPE(c_funptr),VALUE :: way_fnct !< pointer to callback function intended to consume WAY objects (may be NULL if processing WAYs is not an interesting option)
293 TYPE(c_funptr),VALUE :: relation_fnct !< pointer to callback function intended to consume RELATION objects (may be NULL if processing RELATIONs is not an interesting option)
294 INTEGER(kind=c_int) :: readosm_parse
295 END FUNCTION readosm_parse
296
297 MODULE PROCEDURE readosm_parse_f
298END INTERFACE readosm_parse
299
300
301INTERFACE readosm_object_f
302 MODULE PROCEDURE readosm_object_f_node, readosm_object_f_way, &
303 readosm_object_f_relation
304END INTERFACE readosm_object_f
305
306
307INTERFACE readosm_parse
308END INTERFACE readosm_parse
309
310PRIVATE readosm_object_f_node, readosm_object_f_way, &
311 readosm_object_f_relation
312
313CONTAINS
314
315!> Parse the corresponding file calling the selected callbacks for
316!! every entity encountered.
317!! This is the Fortran-friendly interface where callback functions are
318!! optional arguments (thus the keyword form is preferred if any of
319!! them is missing) and represent interfaced Fortran FUNCTIONS.
320!! \return READOSM_OK will be returned on success, otherwise any
321!! appropriate error code on failure.
322FUNCTION readosm_parse_f(osm_handle, user_data, node_fnct, way_fnct, &
323 relation_fnct)
324TYPE(c_ptr),VALUE :: osm_handle !< the handle previously returned by readosm_open()
325TYPE(c_ptr),VALUE :: user_data !< user_data pointer to some user-supplied data struct
326INTERFACE !< callback function intended to consume node objects (may be NULL if processing NODEs is not an interesting option)
327 FUNCTION node_fnct(user_data, node) BIND(C)
328 IMPORT
329 TYPE(c_ptr),VALUE :: user_data
330 TYPE(readosm_node) :: node
331 INTEGER(kind=c_int) :: node_fnct
332 END FUNCTION node_fnct
333END INTERFACE
334
335!> callback function intended to consume WAY objects (may be NULL if processing WAYs is not an interesting option)
336INTERFACE
337 FUNCTION way_fnct(user_data, way) BIND(C)
338 IMPORT
339 TYPE(c_ptr),VALUE :: user_data
340 TYPE(readosm_way) :: way
341 INTEGER(kind=c_int) :: way_fnct
342 END FUNCTION way_fnct
343END INTERFACE
344
345!> callback function intended to consume RELATION objects (may be NULL if processing RELATIONs is not an interesting option)
346INTERFACE
347 FUNCTION relation_fnct(user_data, relation) BIND(C)
348 IMPORT
349 TYPE(c_ptr),VALUE :: user_data
350 TYPE(readosm_relation) :: relation
351 INTEGER(kind=c_int) :: relation_fnct
352 END FUNCTION relation_fnct
353END INTERFACE
354
355OPTIONAL :: node_fnct
356OPTIONAL :: way_fnct
357OPTIONAL :: relation_fnct !< callback function intended to consume RELATION objects (may be NULL if processing RELATIONs is not an interesting option)
358INTEGER(kind=c_int) :: readosm_parse_f
359
360TYPE(c_funptr) :: nf, wf, rf
361
362IF (present(node_fnct)) THEN
363 nf = c_funloc(node_fnct)
364ELSE
365 nf = c_null_funptr
366ENDIF
367IF (present(way_fnct)) THEN
368 wf = c_funloc(way_fnct)
369ELSE
370 wf = c_null_funptr
371ENDIF
372IF (present(relation_fnct)) THEN
373 rf = c_funloc(relation_fnct)
374ELSE
375 rf = c_null_funptr
376ENDIF
377
378readosm_parse_f = readosm_parse(osm_handle, user_data, nf, wf, rf)
379
380END FUNCTION readosm_parse_f
381
382
383! private function for "fortranizing" tags array, it has been
384! temporarily converted to a subroutine because of (de)allocations
385! problems with gfortran 4.6.3
386SUBROUTINE readosm_object_f_tags(tags, tag_count, f_type) ! RESULT(f_type)
387TYPE(c_ptr) :: tags ! array of TAG objects (may be NULL)
388INTEGER(kind=c_int) :: tag_count; ! number of associated TAGs (may be zero)
389
390TYPE(readosm_tag_f),INTENT(out),ALLOCATABLE :: f_type(:)
391
392TYPE(readosm_tag),POINTER :: tmptags(:)
393INTEGER :: i
394
395IF (tag_count > 0 .AND. c_associated(tags)) THEN
396 CALL c_f_pointer(tags, tmptags, (/tag_count/))
397 ALLOCATE(f_type(tag_count))
398 DO i = 1, tag_count
399 f_type(i)%key = tmptags(i)%key
400 f_type(i)%value = tmptags(i)%value
401 ENDDO
402ELSE
403 ALLOCATE(f_type(0))
404ENDIF
405
406END SUBROUTINE readosm_object_f_tags
407
408
409! private function for "fortranizing" members array, it has been
410! temporarily converted to a subroutine because of (de)allocations
411! problems with gfortran 4.6.3
412SUBROUTINE readosm_object_f_members(members, member_count, f_type) ! RESULT(f_type)
413TYPE(c_ptr) :: members ! array of MEMBER objects (may be NULL)
414INTEGER(kind=c_int) :: member_count; ! number of associated MEMBERs (may be zero)
415
416TYPE(readosm_member_f),INTENT(out),ALLOCATABLE :: f_type(:)
417
418TYPE(readosm_member),POINTER :: tmpmembers(:)
419INTEGER :: i
420
421IF (member_count > 0 .AND. c_associated(members)) THEN
422 CALL c_f_pointer(members, tmpmembers, (/member_count/))
423 ALLOCATE(f_type(member_count))
424 DO i = 1, member_count
425 f_type(i)%member_type = tmpmembers(i)%member_type
426 f_type(i)%id = tmpmembers(i)%id
427 f_type(i)%role = tmpmembers(i)%role
428 ENDDO
429ELSE
430 ALLOCATE(f_type(0))
431ENDIF
432
433END SUBROUTINE readosm_object_f_members
434
435
436FUNCTION readosm_object_f_node(c_type) RESULT(f_type)
437TYPE(readosm_node),INTENT(in) :: c_type
438
439TYPE(readosm_node_f) :: f_type
440
441f_type%id = c_type%id
442f_type%latitude = c_type%latitude
443f_type%longitude = c_type%longitude
444f_type%version = c_type%version
445f_type%changeset = c_type%changeset
446!f_type%user = c_type%user
447f_type%uid = c_type%uid
448!f_type%timestamp = c_type%timestamp
449CALL readosm_object_f_tags(c_type%tags, c_type%tag_count, f_type%tags)
450!f_type%tags = readosm_object_f_tags(c_type%tags, c_type%tag_count)
451
452END FUNCTION readosm_object_f_node
453
454
455FUNCTION readosm_object_f_way(c_type) RESULT(f_type)
456TYPE(readosm_way),INTENT(in) :: c_type
457
458TYPE(readosm_way_f) :: f_type
459
460INTEGER(kind=c_long_long),POINTER :: node_refs(:)
461
462f_type%id = c_type%id
463f_type%version = c_type%version
464f_type%changeset = c_type%changeset
465!f_type%user = c_type%user
466f_type%uid = c_type%uid
467!f_type%timestamp = c_type%timestamp
468IF (c_type%node_ref_count > 0 .AND. c_associated(c_type%node_refs)) THEN
469 CALL c_f_pointer(c_type%node_refs, node_refs, (/c_type%node_ref_count/))
470 f_type%node_refs = node_refs
471ELSE
472 ALLOCATE(f_type%node_refs(0))
473ENDIF
474CALL readosm_object_f_tags(c_type%tags, c_type%tag_count, f_type%tags)
475!f_type%tags = readosm_object_f_tags(c_type%tags, c_type%tag_count)
477END FUNCTION readosm_object_f_way
478
479
480FUNCTION readosm_object_f_relation(c_type) RESULT(f_type)
481TYPE(readosm_relation),INTENT(in) :: c_type
482
483TYPE(readosm_relation_f) :: f_type
484
485f_type%id = c_type%id
486f_type%version = c_type%version
487f_type%changeset = c_type%changeset
488!f_type%user = c_type%user
489f_type%uid = c_type%uid
490!f_type%timestamp = c_type%timestamp
491CALL readosm_object_f_members(c_type%members, c_type%member_count, f_type%members)
492CALL readosm_object_f_tags(c_type%tags, c_type%tag_count, f_type%tags)
493!f_type%tags = readosm_object_f_tags(c_type%tags, c_type%tag_count)
494
495END FUNCTION readosm_object_f_relation
496
497
498! define dynamically extendible arrays of the _f types, second part
499#undef ARRAYOF_ORIGEQ
500
501#undef ARRAYOF_ORIGTYPE
502#undef ARRAYOF_TYPE
503#define ARRAYOF_ORIGTYPE TYPE(readosm_node_f)
504#define ARRAYOF_TYPE arrayof_readosm_node_f
505#include "arrayof_post.F90"
506
507#undef ARRAYOF_ORIGTYPE
508#undef ARRAYOF_TYPE
509#define ARRAYOF_ORIGTYPE TYPE(readosm_way_f)
510#define ARRAYOF_TYPE arrayof_readosm_way_f
511#include "arrayof_post.F90"
512
513#undef ARRAYOF_ORIGTYPE
514#undef ARRAYOF_TYPE
515#define ARRAYOF_ORIGTYPE TYPE(readosm_relation_f)
516#define ARRAYOF_TYPE arrayof_readosm_relation_f
517#include "arrayof_post.F90"
518
519
520!> Simplified parsing method for quickly retrieving all the
521!! information from a osm file. This method can be called in place of
522!! \a readosm_parse, thus avoiding the need to define own
523!! callbacks. After successful execution, the \a fulldata argument
524!! will contain the full information from the file in a DOM (Document
525!! Object Model) style. It must be used with care on big datasets
526!! since it can consume a lot of memory. It uses the \a
527!! readosm_full_node, \a readosm_full_way and \a readosm_full_relation
528!! predefined callbacks.
529FUNCTION readosm_parse_full_f(osm_handle, fulldata)
530TYPE(c_ptr),VALUE :: osm_handle !< the handle previously returned by readosm_open()
531TYPE(readosm_full_f),INTENT(inout),TARGET :: fulldata !< an object which, on exit, will contain the full information read from the file
532INTEGER :: readosm_parse_full_f
533
534! parse using the predefined callbacks
535readosm_parse_full_f = readosm_parse(osm_handle, c_loc(fulldata), &
536 readosm_full_node, readosm_full_way, readosm_full_relation)
537
538CALL packarray(fulldata%nodes)
539CALL packarray(fulldata%ways)
540CALL packarray(fulldata%relations)
541
542END FUNCTION readosm_parse_full_f
543
544
545!> Predefined callback for parsing nodes.
546!! It receives an object of the type \a readosm_full_f as \a user_data
547!! and adds to it the node entity received.
548FUNCTION readosm_full_node(user_data, node) BIND(C)
549TYPE(c_ptr),VALUE :: user_data
550TYPE(readosm_node) :: node
551INTEGER(kind=c_int) :: readosm_full_node
552
553TYPE(readosm_full_f),POINTER :: fulldata
554
555! cast user_data to the desired fortran object and insert the entity
556! in "Fortran-friendly" format
557CALL c_f_pointer(user_data, fulldata)
558CALL insert(fulldata%nodes, readosm_object_f(node))
559! set the return code to OK, otherwise parsing will stop
560readosm_full_node = readosm_ok
561
562END FUNCTION readosm_full_node
563
564
565!> Predefined callback for parsing ways.
566!! It receives an object of the type \a readosm_full_f as \a user_data
567!! and adds to it the way entity received.
568FUNCTION readosm_full_way(user_data, way) BIND(C)
569TYPE(c_ptr),VALUE :: user_data
570TYPE(readosm_way) :: way
571INTEGER(kind=c_int) :: readosm_full_way
572
573TYPE(readosm_full_f),POINTER :: fulldata
574
575! cast user_data to the desired fortran object and insert the entity
576! in "Fortran-friendly" format
577CALL c_f_pointer(user_data, fulldata)
578CALL insert(fulldata%ways, readosm_object_f(way))
579! set the return code to OK, otherwise parsing will stop
580readosm_full_way = readosm_ok
581
582END FUNCTION readosm_full_way
583
584
585!> Predefined callback for parsing relations.
586!! It receives an object of the type \a readosm_full_f as \a user_data
587!! and adds to it the relation entity received.
588FUNCTION readosm_full_relation(user_data, relation) BIND(C)
589TYPE(c_ptr),VALUE :: user_data
590TYPE(readosm_relation) :: relation
591INTEGER(kind=c_int) :: readosm_full_relation
592
593TYPE(readosm_full_f),POINTER :: fulldata
594
595! cast user_data to the desired fortran object and insert the entity
596! in "Fortran-friendly" format
597CALL c_f_pointer(user_data, fulldata)
598CALL insert(fulldata%relations, readosm_object_f(relation))
599! set the return code to OK, otherwise parsing will stop
600readosm_full_relation = readosm_ok
601
602END FUNCTION readosm_full_relation
603
604
605END MODULE readosm
Quick method to append an element to the array.
Definition readosm.F90:266
Destructor for finalizing an array object.
Definition readosm.F90:279
Method for inserting elements of the array at a desired position.
Definition readosm.F90:257
Method for packing the array object reducing at a minimum the memory occupation, without destroying i...
Definition readosm.F90:289
Close the .osm or .pbf file and release any allocated resource.
Definition readosm.F90:501
Open the .osm or .pbf file, preparing for future functions.
Definition readosm.F90:486
Parse the corresponding file calling the selected callbacks for every entity encountered.
Definition readosm.F90:513
Method for removing elements of the array at a desired position.
Definition readosm.F90:272
Utility module for supporting Fortran 2003 C language interface module.
Definition fortranc.F90:103
Fortran 2003 interface to the readosm https://www.gaia-gis.it/fossil/readosm/index library.
Definition readosm.F90:55
Derived type defining a dynamically extensible array of TYPE(readosm_node_f) elements.
Definition readosm.F90:249
Derived type defining a dynamically extensible array of TYPE(readosm_relation_f) elements.
Definition readosm.F90:411
Derived type defining a dynamically extensible array of TYPE(readosm_way_f) elements.
Definition readosm.F90:330
Derived type for performing a prepackaged full parsing of an osm file.
Definition readosm.F90:473
A more Fortran-friendly object describing a RELATION-MEMEBER structure.
Definition readosm.F90:179
Object describing a RELATION-MEMBER structure.
Definition readosm.F90:172
A more Fortran-friendly object describing a NODE structure.
Definition readosm.F90:115
Object describing a NODE structure.
Definition readosm.F90:101
A more Fortran-friendly object describing a RELATION structure.
Definition readosm.F90:211
Object describing a RELATION structure.
Definition readosm.F90:197
A more Fortran-friendly object describing a TAG structure.
Definition readosm.F90:86
Object describing a TAG structure.
Definition readosm.F90:80
A more Fortran-friendly object describing a WAY structure.
Definition readosm.F90:154
Object describing a WAY structure.
Definition readosm.F90:140