Skip to content

Commit 1b74639

Browse files
committed
Refactor:maptool:Replace hand-written OSM parsers with libosmium
maptool has four hand-written OSM input parsers: osm_xml.c, osm_o5m.c, osm_protobuf.c and osm_protobufdb.c. osm_xml.c scans XML line by line. The two protobuf parsers use generated protobuf-c code. All four parsers call the same eight osm_add_* and osm_end_* callbacks in osm.c. This change replaces the four parsers with one libosmium handler in osm_libosmium.cpp. The handler calls the same callbacks. The code after the parse stage does not change: item_bin, the tiles and the zip assembly stay the same. The change deletes about 2000 lines and adds about 180 lines. Reasons for the change: - The build no longer needs protobuf-c. This change also deletes the generated .pb-c sources, osmformat.proto and fileformat.proto. - maptool detects the input format from the file name. A plain -i reads .osm, .osm.gz, .osm.bz2, .pbf and .o5m files. Compressed XML no longer needs an external bzcat pipeline. - libosmium decodes PBF data with more than one thread. maptool parses France in 280 s. The old parser needed 354 s. These values are the medians of three runs. - The old XML parser needed one element for each line. If a valid OSM file contained an empty line, the parser stopped with a fatal error. libosmium reads these files. - maptool now reports progress during a PBF parse. osm_protobuf.c never armed the progress alarm, so phase 1 was silent for minutes on a large extract. - One parser is easier to maintain than four. Changes in behavior: - The options -P and -M are now format hints for standard input only. With -i, maptool detects the format from the file name. - This change removes the undocumented options -B and -O. These options only used osm_protobufdb.c, which has no replacement. - maptool now needs a C++14 compiler. DISABLE_CXX therefore has no effect if BUILD_MAPTOOL is on. All C++ code is in one file behind a C interface. - The old build excluded PBF on MSVC. libosmium supports MSVC, so this restriction is gone. - osm_psql.c (-d, HAVE_POSTGRESQL) does not change. libosmium has no PostgreSQL reader. Dependencies: libosmium and protozero contain only headers. The build prefers the system copies, libosmium2-dev and libprotozero-dev. The build downloads them only if they are absent. Distribution builds and offline builds therefore do not need the network. This change deletes cmake/FindPROTOBUF_C.cmake. It also updates the dependency lists in docs/development/targets, in scripts and in CPACK_DEBIAN_PACKAGE_DEPENDS. Verification: A comparison of the maps byte by byte does not work. The threaded phases of maptool put the items of a tile in a variable order. Two runs of the same binary give maps that differ by some hundred bytes. The comparison therefore ignores the order. Each tile becomes a multiset of item type, coordinates and sorted attributes. The comparison includes every per-phase counter. - Geofabrik France, 5.05 GB. The input has 524,532,569 nodes, 73,128,562 ways and 1,098,637 relations. The map has 3.47 GB. All 114,981 members are identical. All counters are identical. Both maps index the same five countries. - BBBike Denver metro, 1.4 million split ways. All 330 members are identical. - Liechtenstein PBF and an Overpass XML extract. All members are identical. These input paths also give correct results: XML with -i, XML from standard input, PBF with -i, PBF from standard input, .osm.gz with -i, .osm.bz2 with -i, and bzcat into standard input. Real o5m data is not tested. No o5m file and no converter were available. The o5m reader starts and rejects a bad header correctly.
1 parent 9f7ed95 commit 1b74639

20 files changed

Lines changed: 265 additions & 2005 deletions

CMakeLists.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ set(MACOSX_BUNDLE_BUNDLE_NAME "Navit")
66
set(CPACK_PACKAGE_CONTACT "navit@navit-project.org")
77
set(CPACK_DEB_COMPONENT_INSTALL ON)
88
#set(CPACK_DEBIAN_MAPTOOL_PACKAGE_DEPENDS "")
9-
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libglib2.0-0 (>= 2.10.0), libprotobuf-c1")
9+
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libglib2.0-0 (>= 2.10.0)")
1010
message(STATUS "Building with CMake V${CMAKE_VERSION}")
1111
if (DISABLE_CXX)
1212
project(navit C)
@@ -746,12 +746,6 @@ if(CMAKE_SIZEOF_VOID_P LESS 8)
746746
set_with_reason(BUILD_MAPTOOL "maptool works only on 64 bit architectures" FALSE)
747747
endif()
748748

749-
if(BUILD_MAPTOOL)
750-
find_package(PROTOBUF_C REQUIRED)
751-
if(NOT PROTOBUF_C_FOUND)
752-
set_with_reason(BUILD_MAPTOOL "PROTOBUF-C not found" FALSE)
753-
endif()
754-
endif()
755749

756750
set(LOCALEDIR "${LOCALE_DIR}")
757751

cmake/FindPROTOBUF_C.cmake

Lines changed: 0 additions & 121 deletions
This file was deleted.

docs/development/targets/Debian_dependencies.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ Translations for the user interface
3131
Maptool
3232
-------
3333

34-
**protobuf-c-compiler libprotobuf-c-dev**
34+
**libosmium2-dev libprotozero-dev**
35+
36+
If these packages are not available, the build downloads them. Both libraries
37+
are header-only.
3538

3639
GTK+
3740
----

docs/development/targets/OpenSuse_dependencies.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ Optionals
1818

1919
To build maptool:
2020

21-
- protobuf-c
22-
- libprotobuf-c-devel
21+
- libosmium-devel
22+
- protozero-devel
2323

2424

2525
GTK Gui

docs/development/targets/Ubuntu_dependencies.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ Minimum requirements
3333
--------------------
3434

3535
- cmake
36-
- protobuf-c-compiler
37-
- libprotobuf-c-dev
36+
- libosmium2-dev
37+
- libprotozero-dev
3838
- zlib1g-dev
3939
- libpng12-dev
4040
- libgtk2.0-dev
@@ -110,5 +110,5 @@ Everything in one command
110110

111111
| ``sudo apt-get install cmake zlib1g-dev libpng12-dev libgtk2.0-dev librsvg2-bin \``
112112
| ``g++ gpsd gpsd-clients libgps-dev libdbus-glib-1-dev freeglut3-dev libxft-dev \``
113-
| ``libglib2.0-dev libfreeimage-dev gettext protobuf-c-compiler  libprotobuf-c-dev``
113+
| ``libglib2.0-dev libfreeimage-dev gettext libosmium2-dev  libprotozero-dev``
114114

docs/user/configuration/maps/osm.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ From .pbf
9898
"""""""""
9999
.. code-block:: bash
100100
101-
maptool --protobuf -i my_OSM_map.osm.pbf my_Navit_map.bin
101+
maptool -i my_OSM_map.osm.pbf my_Navit_map.bin
102102
103103
Processing the whole Planet
104104
~~~~~~~~~~~~~~~~~~~~~~~~~~~

man/maptool.1

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,28 @@
22
.SH NAME
33
maptool \- parse osm textfile and convert to Navit binfile format
44
.SH SYNOPSIS
5-
.B For OSM XML data:
6-
.B bzcat planet.osm.bz2 | maptool mymap.bin
7-
[\-h] [\-6] [\-a <level>] [\-c] -[\-d <connect string]
8-
[\-e <phase>] [\-i <file>] [\-k] [\-M] [\-N] [\-o] [\-r <file>] [\-s <phase>]
5+
.B maptool \-i planet.osm.pbf planet.bin
6+
[\-h] [\-6] [\-a <level>] [\-c] [\-d <connect string>]
7+
[\-e <phase>] [\-k] [\-M] [\-N] [\-o] [\-P] [\-r <file>] [\-s <phase>]
98
[\-S <size>] [\-w] [\-W] [\-U] [\-z <level>]
109

11-
.B For OSM Protobuf/PBF data:
12-
.B maptool \-\-protobuf \-i planet.osm.pbf planet.bin
13-
[\-h] [\-6] [\-a <level>] [\-c] [\-e <phase>]
14-
[\-i <file>] [\-k] [\-M] [\-N] [\-o] [\-P] [\-r <file>] [\-s <phase>]
15-
[\-S <size>] [\-w] [\-W] [\-U] [\-z <level>]
10+
.B bzcat planet.osm.bz2 | maptool planet.bin
1611
.SH DESCRIPTION
17-
maptool parses osm textfile and converts it to Navit binfile format
12+
maptool reads OSM data and converts it to Navit binfile format.
13+
14+
If you give an input file with \-i, maptool detects the format from the file
15+
name. maptool recognizes
16+
.BR .osm ,
17+
.BR .osm.gz ,
18+
.BR .osm.bz2 ,
19+
.B .pbf
20+
and
21+
.BR .o5m .
22+
The options \-P and \-M are not necessary for these files.
23+
24+
maptool cannot detect the format of data from standard input. For standard
25+
input, maptool assumes OSM XML. The \-P option selects pbf data. The \-M option
26+
selects o5m data.
1827
.SH OPTIONS
1928
.TP
2029
\-h (\-\-help)
@@ -43,13 +52,15 @@ end at specified phase
4352
enable experimental features (if available)
4453
.TP
4554
\-i (\-\-input-file) <file>
46-
specify the input file name (OSM), overrules default stdin
55+
specify the input file name (OSM), overrules default stdin. maptool detects the
56+
format from the file name suffix
4757
.TP
4858
\-k (\-\-keep-tmpfiles)
4959
do not delete tmp files after processing. useful to reuse them
5060
.TP
5161
\-M (\-\-o5m)
52-
input data is in o5m format
62+
the data from standard input is in o5m format. With \-i, maptool detects the
63+
format, and this option is not necessary
5364
.TP
5465
\-n (\-\-ignore-unknown)
5566
do not output ways and nodes with unknown type
@@ -58,7 +69,8 @@ do not output ways and nodes with unknown type
5869
process only nodes
5970
.TP
6071
\-P (\-\-protobuf)
61-
input data is in pbf (Protocol Buffer) format
72+
the data from standard input is in pbf (Protocol Buffer) format. With \-i,
73+
maptool detects the format, and this option is not necessary
6274
.TP
6375
\-r (\-\-rule-file) <file>
6476
read mapping rules from specified file

navit/maptool/CMakeLists.txt

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
11
if(BUILD_MAPTOOL)
22

3-
find_package(PROTOBUF_C REQUIRED)
4-
include_directories(${PROTOBUF-C_INCLUDE_DIR})
5-
include_directories(${CMAKE_CURRENT_BINARY_DIR})
6-
#PROTOBUF_C_GENERATE_C(PROTO_SRCS PROTO_HDRS zfs.proto)
3+
enable_language(CXX)
4+
5+
find_package(ZLIB REQUIRED)
6+
find_package(EXPAT REQUIRED)
7+
find_package(BZip2 REQUIRED)
8+
find_package(Threads REQUIRED)
9+
10+
# libosmium and protozero are header-only. Prefer the system copies
11+
# (libosmium2-dev / libprotozero-dev on Debian and Ubuntu) so distro and
12+
# offline builds never hit the network; only fall back to downloading them.
13+
find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp)
14+
find_path(PROTOZERO_INCLUDE_DIR protozero/version.hpp)
15+
if(OSMIUM_INCLUDE_DIR AND PROTOZERO_INCLUDE_DIR)
16+
include_directories(${OSMIUM_INCLUDE_DIR} ${PROTOZERO_INCLUDE_DIR})
17+
else()
18+
message(STATUS "libosmium or protozero not found on the system, downloading them")
19+
# SOURCE_SUBDIR points nowhere on purpose: we only want the headers,
20+
# not the libraries' own CMake projects.
21+
include(FetchContent)
22+
FetchContent_Declare(libosmium
23+
URL https://github.com/osmcode/libosmium/archive/refs/tags/v2.20.0.tar.gz
24+
SOURCE_SUBDIR non-existent)
25+
FetchContent_Declare(protozero
26+
URL https://github.com/mapbox/protozero/archive/refs/tags/v1.7.1.tar.gz
27+
SOURCE_SUBDIR non-existent)
28+
FetchContent_MakeAvailable(libosmium protozero)
29+
include_directories(${libosmium_SOURCE_DIR}/include ${protozero_SOURCE_DIR}/include)
30+
endif()
731

832
add_definitions( -DMODULE=maptool ${NAVIT_COMPILE_FLAGS})
933

1034
add_executable (maptool maptool.c)
1135
add_library (maptool_core boundaries.c buffer.c ch.c coastline.c itembin.c
12-
itembin_buffer.c itembin_slicer.c misc.c osm.c osm_o5m.c osm_psql.c
13-
osm_relations.c sourcesink.c tempfile.c tile.c zip.c osm_xml.c)
14-
15-
if(NOT MSVC)
16-
PROTOBUF_C_GENERATE_C (PROTO_SRCS PROTO_HDRS osmformat.proto)
17-
PROTOBUF_C_GENERATE_C (PROTO_SRCS PROTO_HDRS fileformat.proto)
18-
target_sources(maptool_core PRIVATE osm_protobuf.c osm_protobufdb.c
19-
fileformat.pb-c.c osmformat.pb-c.c)
20-
target_link_libraries(maptool_core ${PROTOBUF_C_LIBRARY})
21-
endif(NOT MSVC)
36+
itembin_buffer.c itembin_slicer.c misc.c osm.c osm_psql.c
37+
osm_relations.c sourcesink.c tempfile.c tile.c zip.c osm_libosmium.cpp)
38+
set_property(TARGET maptool_core PROPERTY CXX_STANDARD 14)
39+
target_link_libraries(maptool_core ZLIB::ZLIB EXPAT::EXPAT BZip2::BZip2 Threads::Threads)
2240

2341
if(NOT MSVC)
2442
SET(NAVIT_LIBS ${NAVIT_LIBS} m)

navit/maptool/fileformat.proto

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)