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
44MODULE readosm
45use,INTRINSIC :: iso_c_binding
46USE fortranc
47IMPLICIT NONE
48
49
50INTEGER,PARAMETER :: READOSM_UNDEFINED = -1234567890
51INTEGER,PARAMETER :: READOSM_MEMBER_NODE = 7361
52INTEGER,PARAMETER :: READOSM_MEMBER_WAY = 6731
53INTEGER,PARAMETER :: READOSM_MEMBER_RELATION = 3671
54INTEGER,PARAMETER :: READOSM_OK = 0
55INTEGER,PARAMETER :: READOSM_INVALID_SUFFIX = -1
56INTEGER,PARAMETER :: READOSM_FILE_NOT_FOUND = -2
57INTEGER,PARAMETER :: READOSM_NULL_HANDLE = -3
58INTEGER,PARAMETER :: READOSM_INVALID_HANDLE = -4
59INTEGER,PARAMETER :: READOSM_INSUFFICIENT_MEMORY = -5
60INTEGER,PARAMETER :: READOSM_CREATE_XML_PARSER_ERROR = -6
61INTEGER,PARAMETER :: readosm_read_error = -7
62INTEGER,PARAMETER :: readosm_xml_error = -8
63INTEGER,PARAMETER :: readosm_invalid_pbf_header = -9
64INTEGER,PARAMETER :: readosm_unzip_error = -10
65INTEGER,PARAMETER :: readosm_abort = -11
69TYPE,BIND(C) :: readosm_tag
70 TYPE(c_ptr) :: key
71 TYPE(c_ptr) :: value
76 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: key(:)
77 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: value(:)
78END TYPE readosm_tag_f
79
90TYPE,BIND(C) :: readosm_node
91 INTEGER(kind=c_long_long) :: id
92 REAL(kind=c_double) :: latitude
93 REAL(kind=c_double) :: longitude
94 INTEGER(kind=c_int) :: version
95 INTEGER(kind=c_long_long) :: changeset
96 TYPE(c_ptr) :: user
97 INTEGER(kind=c_int) :: uid
98 TYPE(c_ptr) :: timestamp
99 INTEGER(kind=c_int) :: tag_count
100 TYPE(c_ptr) :: tags
105 INTEGER(kind=c_long_long) :: id=0
106 REAL(kind=c_double) :: latitude
107 REAL(kind=c_double) :: longitude
108 INTEGER(kind=c_int) :: version
109 INTEGER(kind=c_long_long) :: changeset
110! TYPE(c_ptr) :: user !< name of the User defining this NODE
111 INTEGER(kind=c_int) :: uid
112! TYPE(c_ptr) :: timestamp !< when this NODE was defined
113 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:)
114END TYPE readosm_node_f
129TYPE,BIND(C) :: readosm_way
130 INTEGER(kind=c_long_long) :: id
131 INTEGER(kind=c_int) :: version;
132 INTEGER(kind=c_long_long) :: changeset
133 TYPE(c_ptr) :: user
134 INTEGER(kind=c_int) :: uid
135 TYPE(c_ptr) :: timestamp;
136 INTEGER(kind=c_int) :: node_ref_count
137 TYPE(c_ptr) :: node_refs
138 INTEGER(kind=c_int) :: tag_count
139 TYPE(c_ptr) :: tags
144 INTEGER(kind=c_long_long) :: id=0
145 INTEGER(kind=c_int) :: version;
146 INTEGER(kind=c_long_long) :: changeset;
147! TYPE(c_ptr) :: user !< name of the User defining this WAY
148 INTEGER(kind=c_int) :: uid
149! TYPE(c_ptr) :: timestamp; !< when this WAY was defined
150 INTEGER(kind=c_long_long),ALLOCATABLE :: node_refs(:)
151 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:)
152END TYPE readosm_way_f
153
161TYPE,BIND(C) :: readosm_member
162 INTEGER(kind=c_int) :: member_type
163 INTEGER(kind=c_long_long) :: id
164 TYPE(c_ptr) :: role
165END TYPE readosm_member
166
168TYPE :: readosm_member_f
169 INTEGER(kind=c_int) :: member_type=readosm_undefined
170 INTEGER(kind=c_long_long) :: id
171 CHARACTER(kind=c_char,len=1),ALLOCATABLE :: role(:)
186TYPE,BIND(C) :: readosm_relation
187 INTEGER(kind=c_long_long) :: id
188 INTEGER(kind=c_int) :: version;
189 INTEGER(kind=c_long_long) :: changeset;
190 TYPE(c_ptr) :: user
191 INTEGER(kind=c_int) :: uid
192 TYPE(c_ptr) :: timestamp;
193 INTEGER(kind=c_int) :: member_count
194 TYPE(c_ptr) :: members
195 INTEGER(kind=c_int) :: tag_count;
196 TYPE(c_ptr) :: tags
201 INTEGER(kind=c_long_long) :: id
202 INTEGER(kind=c_int) :: version;
203 INTEGER(kind=c_long_long) :: changeset;
204! TYPE(c_ptr) :: user !< name of the User defining this RELATION
205 INTEGER(kind=c_int) :: uid
206! TYPE(c_ptr) :: timestamp; !< when this RELATION was defined
207 TYPE(readosm_member_f),ALLOCATABLE :: members(:)
208 TYPE(readosm_tag_f),ALLOCATABLE :: tags(:)
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
239 TYPE(arrayof_readosm_node_f) :: nodes
240 TYPE(arrayof_readosm_way_f) :: ways
241 TYPE(arrayof_readosm_relation_f) :: relations
242END TYPE readosm_full_f
243
244
250INTERFACE
251 FUNCTION readosm_open(path, osm_handle) bind(C,name='readosm_open')
252 IMPORT
253 CHARACTER(kind=c_char),INTENT(in) :: path(*)
254 TYPE(c_ptr),INTENT(out) :: osm_handle
255 INTEGER(kind=c_int) :: readosm_open
256 END FUNCTION readosm_open
257END INTERFACE
258
259
265INTERFACE
266 FUNCTION readosm_close(osm_handle) bind(C,name='readosm_close')
267 IMPORT
268 TYPE(c_ptr),VALUE :: osm_handle
269 INTEGER(kind=c_int) :: readosm_close
270 END FUNCTION readosm_close
271END INTERFACE
273
278INTERFACE readosm_parse
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
290 TYPE(c_ptr),VALUE :: user_data
291 TYPE(c_funptr),VALUE :: node_fnct
292 TYPE(c_funptr),VALUE :: way_fnct
293 TYPE(c_funptr),VALUE :: relation_fnct
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
322FUNCTION readosm_parse_f(osm_handle, user_data, node_fnct, way_fnct, &
323 relation_fnct)
324TYPE(c_ptr),VALUE :: osm_handle
325TYPE(c_ptr),VALUE :: user_data
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
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
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
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
529FUNCTION readosm_parse_full_f(osm_handle, fulldata)
530TYPE(c_ptr),VALUE :: osm_handle
531TYPE(readosm_full_f),INTENT(inout),TARGET :: fulldata
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
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
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
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