[osm2pgsql] 03/09: Imported Upstream version 0.87.4
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Mon Jul 6 06:50:51 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository osm2pgsql.
commit a8c2a65b8670dc86e1af71210c6a5031cb4ac23d
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Mon Jul 6 08:02:55 2015 +0200
Imported Upstream version 0.87.4
---
.travis.yml | 92 ++-
Makefile.am | 29 +-
UTF8sanitizer.cpp | 10 +-
configure.ac | 29 +-
default.style | 10 +-
docs/osm2pgsql.1 | 7 +-
empty.style | 2 +-
expire-tiles.cpp | 14 +-
expire-tiles.hpp | 8 +-
geometry-builder.cpp | 18 +-
geometry-processor.cpp | 8 +-
geometry-processor.hpp | 12 +-
input.cpp | 9 +-
input.hpp | 1 +
m4/ax_cxx_compile_stdcxx_11.m4 | 142 ++++
middle-pgsql.cpp | 20 +-
middle-ram.cpp | 9 +-
middle-ram.hpp | 6 +-
middle.hpp | 7 +-
multi.lua | 4 +-
multi.style.json | 2 +-
node-persistent-cache-reader.cpp | 30 +-
node-persistent-cache.cpp | 361 ++++------
node-persistent-cache.hpp | 18 +-
node-ram-cache.cpp | 113 ++--
node-ram-cache.hpp | 83 ++-
options.cpp | 5 -
osm2pgsql.cpp | 8 +-
osmdata.cpp | 44 +-
output-multi.cpp | 12 +-
output-multi.hpp | 20 +-
output-null.cpp | 13 +-
output-pgsql.cpp | 2 +-
output.hpp | 9 +-
parse-o5m.cpp | 11 +-
parse-o5m.hpp | 5 +-
parse-pbf.cpp | 21 +-
parse-pbf.hpp | 10 +-
parse-xml2.cpp | 11 +-
parse-xml2.hpp | 1 -
parse.cpp | 14 +-
parse.hpp | 9 +-
pgsql-id-tracker.cpp | 4 +-
pgsql-id-tracker.hpp | 3 +
pgsql.cpp | 8 +-
processor-line.cpp | 2 -
processor-point.cpp | 11 +-
processor-point.hpp | 5 +-
processor-polygon.cpp | 2 -
rb.cpp | 930 --------------------------
rb.hpp | 122 ----
reprojection.cpp | 13 +-
reprojection.hpp | 2 +-
sanitizer.hpp | 1 -
style.lua | 137 ++--
table.cpp | 19 +-
table.hpp | 9 +-
tagtransform.cpp | 20 +-
tagtransform.hpp | 13 +-
tests/middle-tests.cpp | 140 +++-
tests/middle-tests.hpp | 3 +
tests/regression-test.py | 2 +-
tests/test-expire-tiles.cpp | 1 +
tests/test-middle-pgsql.cpp | 95 ++-
tests/test-middle-ram.cpp | 62 +-
tests/test-output-multi-line-storage.cpp | 2 +-
tests/test-output-multi-line.cpp | 2 +-
tests/test-output-multi-point-multi-table.cpp | 2 +-
tests/test-output-multi-point.cpp | 2 +-
tests/test-output-multi-poly-trivial.cpp | 2 +-
tests/test-output-multi-polygon.cpp | 2 +-
tests/test-output-multi-tags.cpp | 2 +-
tests/test-output-pgsql.cpp | 4 +-
tests/test-parse-options.cpp | 1 -
tests/test-parse-xml2.cpp | 1 +
util.hpp | 7 +-
76 files changed, 1027 insertions(+), 1843 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 52f3c92..d339253 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,43 +1,73 @@
language: cpp
-compiler:
- - gcc
- - clang
-env:
- - USE_LUA=true BOOST_PPA=false
- - USE_LUA=true BOOST_PPA=1.54
- - USE_LUA=true BOOST_PPA=1.55
-# Skip some parts of the matrix for speed
-# - USE_LUA=false BOOST_PPA=false
-# - USE_LUA=false BOOST_PPA=1.54
- - USE_LUA=false BOOST_PPA=1.55
+
+addons:
+ apt:
+ packages:
+ - libtool
+ - libxml2-dev
+ - libgeos-dev
+ - libgeos++-dev
+ - libpq-dev
+ - libbz2-dev
+ - libproj-dev
+ - protobuf-c-compiler
+ - libprotobuf-c0-dev
+
+matrix:
+ include:
+ #basic tests of with/without lua and old boost versions, with both clang and gc
+ - os: linux
+ compiler: clang
+ env: USE_LUA=true
+ - os: linux
+ compiler: clang
+ env: USE_LUA=true BOOST_PPA=1.55
+ - os: linux
+ compiler: clang
+ env: USE_LUA=false BOOST_PPA=1.55
+ - os: linux
+ compiler: gcc
+ env: USE_LUA=true
+ - os: linux
+ compiler: gcc
+ env: USE_LUA=true BOOST_PPA=1.55
+ - os: linux
+ compiler: gcc
+ env: USE_LUA=false BOOST_PPA=1.55
+ # additional tests
+ - os: linux
+ compiler: clang
+ env: USE_LUA=true BOOST_PPA=1.54
+
before_install:
- - |-
- if [ "${BOOST_PPA}" != "false" ]; then
- sudo add-apt-repository -y ppa:boost-latest/ppa
- fi
- - sudo apt-get update -qq
-install:
- - sudo apt-get install -y -qq autoconf automake libtool make g++ libpq-dev libxml2-dev libbz2-dev libproj0 proj-bin libproj-dev # core deps
- - |-
- if [ "${BOOST_PPA}" = "false" ]; then
- sudo apt-get install -y -qq libboost1.48-all-dev
+ # BOOST_PPA is only set on linux
+ - if [ -z ${BOOST_PPA+x} ]; then
+ echo "Using system Boost";
else
- sudo apt-get install -y -qq boost${BOOST_PPA}
+ echo "Using Boost PPA";
+ sudo add-apt-repository -y ppa:boost-latest/ppa;
fi
- - sudo apt-get install -y -qq protobuf-c-compiler libprotobuf-c0-dev
- - sudo apt-get install -y -qq libgeos-3.3.3 libgeos-dev libgeos++-dev
- - |-
- if [ "${USE_LUA}" = "true" ]; then
- sudo apt-get install -y -qq lua5.2 liblua5.2-dev
+ - if [[ $(uname -s) == 'Linux' ]]; then
+ sudo apt-get update -qq;
fi
+install:
+ - if [[ $(uname -s) == 'Linux' ]]; then
+ if [ -z ${BOOST_PPA+x} ]; then
+ sudo apt-get install -y -qq libboost1.48-all-dev;
+ else
+ sudo apt-get install -y -qq "boost${BOOST_PPA}";
+ fi;
+ if [[ "${USE_LUA}" = "true" ]]; then
+ sudo apt-get install -y -qq lua5.2 liblua5.2-dev;
+ fi;
+ fi;
before_script:
- xml2-config --version
- geos-config --version
- proj | head -n1
- - |-
- if [ "${USE_LUA}" = "true" ]; then
- lua -v
- fi
+ - if [ "${USE_LUA}" = "true" ]; then
+ lua -v;
+ fi;
script:
./autogen.sh && ./configure && make -j2
after_failure:
diff --git a/Makefile.am b/Makefile.am
index b4c0ef9..8ce3f4f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,33 +4,7 @@ AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = osm2pgsql nodecachefilereader
noinst_LTLIBRARIES = libosm2pgsql.la
-osm2pgsql_SOURCES = osm2pgsql.cpp \
- geometry-builder.hpp \
- expire-tiles.hpp \
- input.hpp \
- middle-pgsql.hpp \
- middle-ram.hpp \
- middle.hpp \
- node-persistent-cache.hpp \
- node-ram-cache.hpp \
- options.hpp \
- osmdata.hpp \
- osmtypes.hpp \
- output-gazetteer.hpp \
- output-null.hpp \
- output-pgsql.hpp \
- output.hpp \
- parse.hpp \
- parse-o5m.hpp \
- parse-pbf.hpp \
- parse-xml2.hpp \
- pgsql.hpp \
- rb.hpp \
- reprojection.hpp \
- sanitizer.hpp \
- sprompt.hpp \
- table.hpp \
- util.hpp
+osm2pgsql_SOURCES = osm2pgsql.cpp
osm2pgsql_LDADD = libosm2pgsql.la
@@ -62,7 +36,6 @@ libosm2pgsql_la_SOURCES = \
processor-line.cpp \
processor-point.cpp \
processor-polygon.cpp \
- rb.cpp \
reprojection.cpp \
sprompt.cpp \
table.cpp \
diff --git a/UTF8sanitizer.cpp b/UTF8sanitizer.cpp
index c0f2753..604067d 100644
--- a/UTF8sanitizer.cpp
+++ b/UTF8sanitizer.cpp
@@ -1,10 +1,6 @@
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <zlib.h>
-#include <bzlib.h>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
#include "sanitizer.hpp"
#include "input.hpp"
diff --git a/configure.ac b/configure.ac
index 91a3d1d..278de33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(osm2pgsql, 0.87.3)
+AC_INIT(osm2pgsql, 0.87.4)
dnl Required autoconf version
AC_PREREQ(2.61)
@@ -112,17 +112,21 @@ AX_BOOST_BASE([1.48], , [AC_MSG_ERROR([cannot find Boost libraries, which are ar
AX_BOOST_SYSTEM
AX_BOOST_FILESYSTEM
AX_BOOST_THREAD
+if test "x$BOOST_SYSTEM_LIB" = "x" -o "x$BOOST_FILESYSTEM_LIB" = "x" -o "x$BOOST_THREAD_LIB" = "x"
+then
+ AC_MSG_ERROR([One or more of the mandatory Boost libraries not found.])
+fi
-dnl Check if Boost is recent enough for lockfree, and if it hasn't been overridden
-AC_ARG_WITH([lockfree],
- [AS_HELP_STRING([--without-lockfree],
- [disable lockfree queue])],
+dnl Boost json parser in 1.49 has a bug when compiled with C++11
+dnl see https://svn.boost.org/trac/boost/ticket/6785
+AC_ARG_WITH([cxx11],
+ [AS_HELP_STRING([--without-cxx11],
+ [do not check for C++11-capable compiler (for testing only)])],
[],
- [with_lockfree=yes])
+ [with_cxx11=yes])
-if test "x$with_lockfree" = "xyes"
-then
- AX_BOOST_BASE([1.53], AC_DEFINE([HAVE_LOCKFREE], [1], [Using lockfree queue]), [])
+if test "x$with_cxx11" = "xyes"; then
+ AX_BOOST_BASE([1.50], [ AX_CXX_COMPILE_STDCXX_11(,optional) ], [])
fi
dnl Check for Lua libraries and headers
@@ -135,6 +139,13 @@ AX_PROG_LUA([5.0],[],[
],[AC_MSG_WARN([cannot find Lua includes])])
],[AC_MSG_WARN([cannot find Lua interpreter])])
+dnl Enable fixed point
+AC_ARG_WITH([fixed-point],
+ [AS_HELP_STRING([--without-fixed-point],
+ [use double instead of fixed point floats for coordinates])],
+ [],
+ [AC_DEFINE([FIXED_POINT], [1], [Store +-20,000km Mercator co-ordinates as fixed point 32bit number with maximum precision])])
+
dnl Generate Makefile
AC_OUTPUT(Makefile)
diff --git a/default.style b/default.style
index 690f3d1..30cd48c 100644
--- a/default.style
+++ b/default.style
@@ -86,9 +86,9 @@ node,way admin_level text linear
node,way aerialway text linear
node,way aeroway text polygon
node,way amenity text polygon
-node,way area text # hard coded support for area=1/yes => polygon is in osm2pgsql
+node,way area text polygon # hard coded support for area=1/yes => polygon is in osm2pgsql
node,way barrier text linear
-node,way bicycle text
+node,way bicycle text linear
node,way brand text linear
node,way bridge text linear
node,way boundary text linear
@@ -123,14 +123,14 @@ node,way office text polygon
node,way oneway text linear
node,way operator text linear
node,way place text polygon
-node poi text
+node poi text linear
node,way population text linear
node,way power text polygon
node,way power_source text linear
node,way public_transport text polygon
node,way railway text linear
node,way ref text linear
-node,way religion text
+node,way religion text linear
node,way route text linear
node,way service text linear
node,way shop text polygon
@@ -147,7 +147,7 @@ node,way wetland text polygon
node,way width text linear
node,way wood text linear
node,way z_order int4 linear # This is calculated during import
-way way_area real # This is calculated during import
+way way_area real linear # This is calculated during import
# Area tags
# We don't make columns for these tags, but objects with them are areas.
diff --git a/docs/osm2pgsql.1 b/docs/osm2pgsql.1
index 4d96a5d..bde5149 100644
--- a/docs/osm2pgsql.1
+++ b/docs/osm2pgsql.1
@@ -78,9 +78,6 @@ Store data in degrees of latitude & longitude.
\fB\-m\fR|\-\-merc
Store data in proper spherical Mercator (the default).
.TP
-\fB\-M\fR|\-\-oldmerc
-Store data in the legacy OSM Mercator format.
-.TP
\fB\-E\fR|\-\-proj num
Use projection EPSG:num
.TP
@@ -246,9 +243,9 @@ Verbose output.
.SH SUPPORTED PROJECTIONS
Latlong (\-l) SRS: 4326 (none)
.br
-WGS84 Mercator ( ) SRS: 3395 +proj=merc +datum=WGS84 +k=1.0 +units=m +over +no_defs
-.br
Spherical Mercator (\-m) SRS:900913 +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over
+.br
+EPSG-defined (\-E) SRS: +init=epsg:(as given in parameter)
.PP
.SH SEE ALSO
.BR proj (1),
diff --git a/empty.style b/empty.style
index 6c9919d..d06be71 100644
--- a/empty.style
+++ b/empty.style
@@ -34,7 +34,7 @@ node,way water text phstore
node,way waterway text phstore
node,way wetland text phstore
node,way z_order int4 linear # This is calculated during import
-way way_area real # This is calculated during import
+way way_area real linear # This is calculated during import
# Deleted tags
# These are tags that are generally regarded as useless for most rendering.
diff --git a/expire-tiles.cpp b/expire-tiles.cpp
index 9e14fd8..3533339 100644
--- a/expire-tiles.cpp
+++ b/expire-tiles.cpp
@@ -8,15 +8,15 @@
* https://subversion.nexusuk.org/trac/browser/openpistemap/trunk/scripts/expire_tiles.py
*/
-#include <libpq-fe.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include "output.hpp"
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <string>
+
+#include "expire-tiles.hpp"
#include "options.hpp"
#include "geometry-builder.hpp"
-#include "pgsql.hpp"
#include "reprojection.hpp"
#include "table.hpp"
diff --git a/expire-tiles.hpp b/expire-tiles.hpp
index 08d6839..64133b6 100644
--- a/expire-tiles.hpp
+++ b/expire-tiles.hpp
@@ -1,15 +1,15 @@
#ifndef EXPIRE_TILES_H
#define EXPIRE_TILES_H
-#include "options.hpp"
+#include "osmtypes.hpp"
#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
class table_t;
+struct options_t;
struct expire_tiles : public boost::noncopyable {
- explicit expire_tiles(const struct options_t *options);
+ explicit expire_tiles(const options_t *options);
~expire_tiles();
//TODO: copy constructor
@@ -57,7 +57,7 @@ private:
int map_width;
double tile_width;
- const struct options_t *Options;
+ const options_t *Options;
struct tile *dirty;
};
diff --git a/geometry-builder.cpp b/geometry-builder.cpp
index 0aaf578..143a1cc 100644
--- a/geometry-builder.cpp
+++ b/geometry-builder.cpp
@@ -22,26 +22,29 @@
#include <iostream>
#include <algorithm>
-#include <cstring>
-#include <cstdlib>
#include <cmath>
-#include <exception>
+#include <cstddef>
+#include <stdexcept>
+#include <memory>
+#include <new>
#if defined(__CYGWIN__)
#define GEOS_INLINE
#endif
+#include <geos/geom/prep/PreparedGeometry.h>
#include <geos/geom/prep/PreparedGeometryFactory.h>
-#include <geos/geom/prep/PreparedPolygon.h>
#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Coordinate.h>
+#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/CoordinateSequenceFactory.h>
#include <geos/geom/Geometry.h>
+#include <geos/geom/GeometryCollection.h>
#include <geos/geom/LineString.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/MultiLineString.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/MultiPolygon.h>
-#include <geos/geom/Point.h>
#include <geos/io/WKTReader.h>
#include <geos/io/WKTWriter.h>
#include <geos/util/GEOSException.h>
@@ -182,11 +185,12 @@ geometry_builder::maybe_wkts_t geometry_builder::get_wkt_split(const nodelist_t
const Coordinate this_pt = coords->getAt(i);
const Coordinate prev_pt = coords->getAt(i-1);
const double delta = this_pt.distance(prev_pt);
+ assert(!isnan(delta));
// figure out if the addition of this point would take the total
// length of the line in `segment` over the `split_at` distance.
- const size_t splits = std::floor((distance + delta) / split_at);
- if (splits > 0) {
+ if (distance + delta > split_at) {
+ const size_t splits = std::floor((distance + delta) / split_at);
// use the splitting distance to split the current segment up
// into as many parts as necessary to keep each part below
// the `split_at` distance.
diff --git a/geometry-processor.cpp b/geometry-processor.cpp
index 4261693..49f8b22 100644
--- a/geometry-processor.cpp
+++ b/geometry-processor.cpp
@@ -2,20 +2,22 @@
#include "processor-line.hpp"
#include "processor-point.hpp"
#include "processor-polygon.hpp"
-
+#include "middle.hpp"
+#include "options.hpp"
+#include "reprojection.hpp"
#include <boost/make_shared.hpp>
#include <boost/format.hpp>
+#include <boost/optional.hpp>
#include <stdexcept>
boost::shared_ptr<geometry_processor> geometry_processor::create(const std::string &type,
const options_t *options) {
boost::shared_ptr<geometry_processor> ptr;
int srid = options->projection->project_getprojinfo()->srs;
- double scale = options->scale;
if (type == "point") {
- ptr = boost::make_shared<processor_point>(srid, scale);
+ ptr = boost::make_shared<processor_point>(srid);
}
else if (type == "line") {
ptr = boost::make_shared<processor_line>(srid);
diff --git a/geometry-processor.hpp b/geometry-processor.hpp
index 98e9077..336553c 100644
--- a/geometry-processor.hpp
+++ b/geometry-processor.hpp
@@ -1,10 +1,16 @@
#ifndef GEOMETRY_PROCESSOR_HPP
#define GEOMETRY_PROCESSOR_HPP
-#include "middle.hpp"
-#include "geometry-builder.hpp"
+#include <cstddef>
#include <string>
-#include <boost/optional.hpp>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include "geometry-builder.hpp"
+#include "osmtypes.hpp"
+
+struct middle_query_t;
+struct middle_t;
+struct options_t;
struct geometry_processor {
// factory method for creating various types of geometry processors either by name or by geometry column type
diff --git a/input.cpp b/input.cpp
index 87c27e5..a56c45b 100644
--- a/input.cpp
+++ b/input.cpp
@@ -6,18 +6,15 @@
#include <io.h>
#define STDIN_FILENO 0
#else
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <cstdio>
#endif
+#include <cstdlib>
+#include <cstring>
#include <fcntl.h>
#include <zlib.h>
#include <bzlib.h>
-#include <string.h>
-#include "sanitizer.hpp"
#include "input.hpp"
struct Input {
diff --git a/input.hpp b/input.hpp
index 6313181..61213b2 100644
--- a/input.hpp
+++ b/input.hpp
@@ -1,6 +1,7 @@
#ifndef INPUT_H
#define INPUT_H
+#include <libxml/xmlreader.h>
struct Input;
int readFile(struct Input *context, char * buffer, int len);
diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 0000000..163a4c6
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,142 @@
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+# Check for baseline language coverage in the compiler for the C++11
+# standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+# The first argument, if specified, indicates whether you insist on an
+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+# -std=c++11). If neither is specified, you get whatever works, with
+# preference for an extended mode.
+#
+# The second argument, if specified 'mandatory' or if left unspecified,
+# indicates that baseline C++11 support is required and that the macro
+# should error out if no mode with that support is found. If specified
+# 'optional', then configuration proceeds regardless, after defining
+# HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Benjamin Kosnik <bkoz at redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw at panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr at ices.utexas.edu>
+# Copyright (c) 2014 Alexey Sokolov <sokolov at google.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 4
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
+ template <typename T>
+ struct check
+ {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
+
+ struct Base {
+ virtual void f() {}
+ };
+ struct Child : public Base {
+ virtual void f() override {}
+ };
+
+ typedef check<check<bool>> right_angle_brackets;
+
+ int a;
+ decltype(a) b;
+
+ typedef check<int> check_type;
+ check_type c;
+ check_type&& cr = static_cast<check_type&&>(c);
+
+ auto d = a;
+ auto l = [](){};
+]])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+ m4_if([$1], [], [],
+ [$1], [ext], [],
+ [$1], [noext], [],
+ [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+ m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+ [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+ [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
+ AC_LANG_PUSH([C++])dnl
+ ac_success=no
+ AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+ ax_cv_cxx_compile_cxx11,
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [ax_cv_cxx_compile_cxx11=yes],
+ [ax_cv_cxx_compile_cxx11=no])])
+ if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+ ac_success=yes
+ fi
+
+ m4_if([$1], [noext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=gnu++11 -std=gnu++0x; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+
+ m4_if([$1], [ext], [], [dnl
+ if test x$ac_success = xno; then
+ for switch in -std=c++11 -std=c++0x; do
+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+ AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+ $cachevar,
+ [ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS $switch"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+ [eval $cachevar=yes],
+ [eval $cachevar=no])
+ CXXFLAGS="$ac_save_CXXFLAGS"])
+ if eval test x\$$cachevar = xyes; then
+ CXXFLAGS="$CXXFLAGS $switch"
+ ac_success=yes
+ break
+ fi
+ done
+ fi])
+ AC_LANG_POP([C++])
+ if test x$ax_cxx_compile_cxx11_required = xtrue; then
+ if test x$ac_success = xno; then
+ AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+ fi
+ else
+ if test x$ac_success = xno; then
+ HAVE_CXX11=0
+ AC_MSG_NOTICE([No compiler with C++11 support was found])
+ else
+ HAVE_CXX11=1
+ AC_DEFINE(HAVE_CXX11,1,
+ [define if the compiler supports basic C++11 syntax])
+ fi
+
+ AC_SUBST(HAVE_CXX11)
+ fi
+])
diff --git a/middle-pgsql.cpp b/middle-pgsql.cpp
index 03b17c5..ab198e7 100644
--- a/middle-pgsql.cpp
+++ b/middle-pgsql.cpp
@@ -322,7 +322,9 @@ int middle_pgsql_t::local_nodes_set(const osmid_t& id, const double& lat,
int length = strlen(tag_buf) + 64;
char *buffer = (char *)alloca( length );
#ifdef FIXED_POINT
- if( snprintf( buffer, length, "%" PRIdOSMID "\t%d\t%d\t%s\n", id, util::double_to_fix(lat, out_options->scale), util::double_to_fix(lon, out_options->scale), tag_buf ) > (length-10) )
+ ramNode n(lon, lat);
+ if( snprintf(buffer, length, "%" PRIdOSMID "\t%d\t%d\t%s\n",
+ id, n.int_lat(), n.int_lon(), tag_buf ) > (length-10) )
{ fprintf( stderr, "buffer overflow node id %" PRIdOSMID "\n", id); return 1; }
#else
if( snprintf( buffer, length, "%" PRIdOSMID "\t%.10f\t%.10f\t%s\n", id, lat, lon, tag_buf ) > (length-10) )
@@ -340,9 +342,10 @@ int middle_pgsql_t::local_nodes_set(const osmid_t& id, const double& lat,
ptr += sprintf( ptr, "%" PRIdOSMID, id ) + 1;
paramValues[1] = ptr;
#ifdef FIXED_POINT
- ptr += sprintf( ptr, "%d", util::double_to_fix(lat, out_options->scale) ) + 1;
+ ramNode n(lon, lat);
+ ptr += sprintf(ptr, "%d", n.int_lat()) + 1;
paramValues[2] = ptr;
- sprintf( ptr, "%d", util::double_to_fix(lon, out_options->scale) );
+ sprintf(ptr, "%d", n.int_lon());
#else
ptr += sprintf( ptr, "%.10f", lat ) + 1;
paramValues[2] = ptr;
@@ -405,8 +408,11 @@ int middle_pgsql_t::local_nodes_get_list(nodelist_t &out, const idlist_t nds) co
osmid_t id = strtoosmid(PQgetvalue(res, i, 0), NULL, 10);
osmNode node;
#ifdef FIXED_POINT
- node.lat = util::fix_to_double(strtol(PQgetvalue(res, i, 1), NULL, 10), out_options->scale);
- node.lon = util::fix_to_double(strtol(PQgetvalue(res, i, 2), NULL, 10), out_options->scale);
+ ramNode n((int) strtol(PQgetvalue(res, i, 2), NULL, 10),
+ (int) strtol(PQgetvalue(res, i, 1), NULL, 10));
+
+ node.lat = n.lat();
+ node.lon = n.lon();
#else
node.lat = strtod(PQgetvalue(res, i, 1), NULL);
node.lon = strtod(PQgetvalue(res, i, 2), NULL);
@@ -1060,7 +1066,7 @@ int middle_pgsql_t::start(const options_t *out_options_)
build_indexes = 0;
cache.reset(new node_ram_cache( out_options->alloc_chunkwise | ALLOC_LOSSY, out_options->cache, out_options->scale));
- if (out_options->flat_node_cache_enabled) persistent_cache.reset(new node_persistent_cache(out_options, out_options->append, cache));
+ if (out_options->flat_node_cache_enabled) persistent_cache.reset(new node_persistent_cache(out_options, out_options->append, false, cache));
fprintf(stderr, "Mid: pgsql, scale=%d cache=%d\n", out_options->scale, out_options->cache);
@@ -1364,7 +1370,7 @@ boost::shared_ptr<const middle_query_t> middle_pgsql_t::get_instance() const {
// The persistent cache on the other hand is not thread-safe for reading,
// so we create one per instance.
if (out_options->flat_node_cache_enabled)
- mid->persistent_cache.reset(new node_persistent_cache(out_options,1,cache));
+ mid->persistent_cache.reset(new node_persistent_cache(out_options, 1, true, cache));
// We use a connection per table to enable the use of COPY */
for(int i=0; i<num_tables; i++) {
diff --git a/middle-ram.cpp b/middle-ram.cpp
index fcaf290..4e79d03 100644
--- a/middle-ram.cpp
+++ b/middle-ram.cpp
@@ -9,20 +9,13 @@
#include <stdexcept>
#include <cstdio>
-#include <cstdlib>
#include <cstring>
#include <cassert>
-#include "osmtypes.hpp"
#include "middle-ram.hpp"
#include "node-ram-cache.hpp"
-#include "output-pgsql.hpp"
#include "options.hpp"
-#include "util.hpp"
-
-/* Store +-20,000km Mercator co-ordinates as fixed point 32bit number with maximum precision */
-/* Scale is chosen such that 40,000 * SCALE < 2^32 */
-#define FIXED_POINT
+#include "id-tracker.hpp"
/* Object storage now uses 2 levels of storage arrays.
*
diff --git a/middle-ram.hpp b/middle-ram.hpp
index 2c68ea4..8eec63b 100644
--- a/middle-ram.hpp
+++ b/middle-ram.hpp
@@ -9,10 +9,14 @@
#ifndef MIDDLE_RAM_H
#define MIDDLE_RAM_H
+#include <memory>
+
#include "middle.hpp"
-#include "node-ram-cache.hpp"
#include <vector>
+struct node_ram_cache;
+struct options_t;
+
struct middle_ram_t : public middle_t {
middle_ram_t();
virtual ~middle_ram_t();
diff --git a/middle.hpp b/middle.hpp
index ae685a8..104c653 100644
--- a/middle.hpp
+++ b/middle.hpp
@@ -8,8 +8,11 @@
#define MIDDLE_H
#include "osmtypes.hpp"
-#include "options.hpp"
-#include <vector>
+
+#include <cstddef>
+#include <boost/shared_ptr.hpp>
+
+struct options_t;
struct middle_query_t {
virtual ~middle_query_t() {}
diff --git a/multi.lua b/multi.lua
index 283b33b..550c0de 100644
--- a/multi.lua
+++ b/multi.lua
@@ -42,7 +42,7 @@ function building_rels (kv, num_keys)
return generic_rels(building_interesting, kv)
end
-function builing_rel_members (kv, keyvaluemembers, roles, membercount)
+function building_rel_members (kv, keyvaluemembers, roles, membercount)
return generic_rel_members(building_interesting, kv, keyvaluemembers, roles, membercount, building_transform)
end
@@ -268,4 +268,4 @@ function generic_rel_members (f, keyvals, keyvaluemembers, roles, membercount, t
end
tags = t(keyvals)
return filter, tags, membersuperseeded, boundary, polygon, roads
-end
\ No newline at end of file
+end
diff --git a/multi.style.json b/multi.style.json
index 400146c..3c36aee 100644
--- a/multi.style.json
+++ b/multi.style.json
@@ -53,7 +53,7 @@
"tagtransform-node-function": "drop_all",
"tagtransform-way-function": "building_ways",
"tagtransform-relation-function": "building_rels",
- "tagtransform-relation-member-function": "builing_rel_members",
+ "tagtransform-relation-member-function": "building_rel_members",
"tags": [
{"name": "name", "type": "text"},
{"name": "name_en", "type": "text"},
diff --git a/node-persistent-cache-reader.cpp b/node-persistent-cache-reader.cpp
index 4ca6572..c2c8b68 100644
--- a/node-persistent-cache-reader.cpp
+++ b/node-persistent-cache-reader.cpp
@@ -1,18 +1,12 @@
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <math.h>
+#include <cstring>
#include <sys/wait.h>
#include <sys/time.h>
+#include <boost/shared_ptr.hpp>
#include "osmtypes.hpp"
-#include "output.hpp"
#include "options.hpp"
#include "node-persistent-cache.hpp"
#include "node-ram-cache.hpp"
@@ -64,7 +58,7 @@ int main(int argc, char *argv[]) {
if (argc > 3) {
- cache.reset(new node_persistent_cache(&options, 1, ram_cache));
+ cache.reset(new node_persistent_cache(&options, 1, true, ram_cache));
node_cnt = argc - 2;
for (i = 0; i < node_cnt; i++) {
osmids.push_back(strtoosmid(argv[2 + i], NULL, 10));
@@ -80,9 +74,9 @@ int main(int argc, char *argv[]) {
setstate(state);
printf("Testing mode\n");
- cache.reset(new node_persistent_cache(&options, 1, ram_cache));
+ cache.reset(new node_persistent_cache(&options, 1, true, ram_cache));
test_get_node_list(cache, 10, 200, 0);
- cache.reset();
+ cache.reset();
#ifdef HAVE_FORK
printf("Testing using multiple processes\n");
int noProcs = 4;
@@ -100,11 +94,11 @@ int main(int argc, char *argv[]) {
gettimeofday(&start, NULL);
initstate(start.tv_usec, state, 8);
setstate(state);
- cache.reset(new node_persistent_cache(&options, 1, ram_cache));
+ cache.reset(new node_persistent_cache(&options, 1, true, ram_cache));
test_get_node_list(cache, 10,200,p);
if (pid == 0) {
- cache.reset();
+ cache.reset();
fprintf(stderr,"Exiting process %i\n", p);
exit(0);
} else {
@@ -114,7 +108,7 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "\nAll child processes exited\n");
#endif
} else {
- cache.reset(new node_persistent_cache(&options, 1, ram_cache));
+ cache.reset(new node_persistent_cache(&options, 1, true, ram_cache));
if (strstr(argv[2],",") == NULL) {
cache->get(&node, strtoosmid(argv[2], NULL, 10));
printf("lat: %f / lon: %f\n", node.lat, node.lon);
@@ -139,8 +133,8 @@ int main(int argc, char *argv[]) {
}
- cache.reset();
- ram_cache.reset();
+ cache.reset();
+ ram_cache.reset();
return 0;
}
diff --git a/node-persistent-cache.cpp b/node-persistent-cache.cpp
index 17eca7d..61a4804 100644
--- a/node-persistent-cache.cpp
+++ b/node-persistent-cache.cpp
@@ -45,96 +45,35 @@
#endif
#endif
-void node_persistent_cache::writeout_dirty_nodes(osmid_t id)
+void node_persistent_cache::writeout_dirty_nodes()
{
- int i;
-
- if (writeNodeBlock.dirty > 0)
- {
- if (lseek64(node_cache_fd,
- (writeNodeBlock.block_offset << WRITE_NODE_BLOCK_SHIFT)
- * sizeof(struct ramNode)
- + sizeof(struct persistentCacheHeader), SEEK_SET) < 0) {
- fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
- strerror(errno));
- util::exit_nicely();
-
- };
- if (write(node_cache_fd, writeNodeBlock.nodes,
- WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- < ssize_t(WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode)))
- {
- fprintf(stderr, "Failed to write out node cache: %s\n",
- strerror(errno));
- util::exit_nicely();
- }
- cacheHeader.max_initialised_id = ((writeNodeBlock.block_offset + 1)
- << WRITE_NODE_BLOCK_SHIFT) - 1;
- writeNodeBlock.used = 0;
- writeNodeBlock.dirty = 0;
- if (lseek64(node_cache_fd, 0, SEEK_SET) < 0) {
- fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
- strerror(errno));
- util::exit_nicely();
- };
- if (write(node_cache_fd, &cacheHeader,
- sizeof(struct persistentCacheHeader))
- != sizeof(struct persistentCacheHeader))
- {
- fprintf(stderr, "Failed to update persistent cache header: %s\n",
- strerror(errno));
- util::exit_nicely();
- }
- if (fsync(node_cache_fd) < 0) {
- fprintf(stderr, "Info: Node cache could not be guaranteeded to be made durable. fsync failed: %s\n",
- strerror(errno));
- };
- }
- if (id < 0)
+ for (int i = 0; i < READ_NODE_CACHE_SIZE; i++)
{
- for (i = 0; i < READ_NODE_CACHE_SIZE; i++)
+ if (readNodeBlockCache[i].dirty)
{
- if (readNodeBlockCache[i].dirty)
+ if (lseek64(node_cache_fd,
+ (readNodeBlockCache[i].block_offset
+ << READ_NODE_BLOCK_SHIFT)
+ * sizeof(ramNode)
+ + sizeof(persistentCacheHeader),
+ SEEK_SET) < 0) {
+ fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
+ strerror(errno));
+ util::exit_nicely();
+ };
+ if (write(node_cache_fd, readNodeBlockCache[i].nodes,
+ READ_NODE_BLOCK_SIZE * sizeof(ramNode))
+ < ssize_t(READ_NODE_BLOCK_SIZE * sizeof(ramNode)))
{
- if (lseek64(node_cache_fd,
- (readNodeBlockCache[i].block_offset
- << READ_NODE_BLOCK_SHIFT)
- * sizeof(struct ramNode)
- + sizeof(struct persistentCacheHeader),
- SEEK_SET) < 0) {
- fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
- strerror(errno));
- util::exit_nicely();
- };
- if (write(node_cache_fd, readNodeBlockCache[i].nodes,
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- < ssize_t(READ_NODE_BLOCK_SIZE * sizeof(struct ramNode)))
- {
- fprintf(stderr, "Failed to write out node cache: %s\n",
- strerror(errno));
- util::exit_nicely();
- }
+ fprintf(stderr, "Failed to write out node cache: %s\n",
+ strerror(errno));
+ util::exit_nicely();
}
- readNodeBlockCache[i].dirty = 0;
}
+ readNodeBlockCache[i].dirty = 0;
}
-
}
-static void ramNodes_clear(struct ramNode * nodes, int size)
-{
- int i;
- for (i = 0; i < size; i++)
- {
-#ifdef FIXED_POINT
- nodes[i].lon = INT_MIN;
- nodes[i].lat = INT_MIN;
-#else
- nodes[i].lon = NAN;
- nodes[i].lat = NAN;
-#endif
- }
-}
/**
* Find the cache block with the lowest usage count for replacement
@@ -143,9 +82,8 @@ int node_persistent_cache::replace_block()
{
int min_used = INT_MAX;
int block_id = -1;
- int i;
- for (i = 0; i < READ_NODE_CACHE_SIZE; i++)
+ for (int i = 0; i < READ_NODE_CACHE_SIZE; i++)
{
if (readNodeBlockCache[i].used < min_used)
{
@@ -155,7 +93,7 @@ int node_persistent_cache::replace_block()
}
if (min_used > 0)
{
- for (i = 0; i < READ_NODE_CACHE_SIZE; i++)
+ for (int i = 0; i < READ_NODE_CACHE_SIZE; i++)
{
if (readNodeBlockCache[i].used > 1)
{
@@ -200,33 +138,26 @@ void node_persistent_cache::add_to_cache_idx(cache_index_entry const &entry)
readNodeBlockCacheIdx.insert(it, entry);
}
+// A cache block with invalid nodes, just for writing out empty cache blocks
+static const ramNode nullNodes[READ_NODE_BLOCK_SIZE];
/**
* Initialise the persistent cache with NaN values to identify which IDs are valid or not
*/
void node_persistent_cache::expand_cache(osmid_t block_offset)
{
- osmid_t i;
- struct ramNode * dummyNodes = (struct ramNode *)malloc(
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode));
- if (!dummyNodes) {
- fprintf(stderr, "Out of memory: Could not allocate node structure during cache expansion\n");
- util::exit_nicely();
- }
- ramNodes_clear(dummyNodes, READ_NODE_BLOCK_SIZE);
/* Need to expand the persistent node cache */
if (lseek64(node_cache_fd,
- cacheHeader.max_initialised_id * sizeof(struct ramNode)
- + sizeof(struct persistentCacheHeader), SEEK_SET) < 0) {
+ cacheHeader.max_initialised_id * sizeof(ramNode)
+ + sizeof(persistentCacheHeader), SEEK_SET) < 0) {
fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
strerror(errno));
util::exit_nicely();
};
- for (i = cacheHeader.max_initialised_id >> READ_NODE_BLOCK_SHIFT;
+ for (osmid_t i = cacheHeader.max_initialised_id >> READ_NODE_BLOCK_SHIFT;
i <= block_offset; i++)
{
- if (write(node_cache_fd, dummyNodes,
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- < ssize_t(READ_NODE_BLOCK_SIZE * sizeof(struct ramNode)))
+ if (write(node_cache_fd, nullNodes, sizeof(nullNodes))
+ < ssize_t(sizeof(nullNodes)))
{
fprintf(stderr, "Failed to expand persistent node cache: %s\n",
strerror(errno));
@@ -247,7 +178,6 @@ void node_persistent_cache::expand_cache(osmid_t block_offset)
strerror(errno));
util::exit_nicely();
}
- free(dummyNodes);
fsync(node_cache_fd);
}
@@ -257,19 +187,18 @@ void node_persistent_cache::nodes_prefetch_async(osmid_t id)
#ifdef HAVE_POSIX_FADVISE
osmid_t block_offset = id >> READ_NODE_BLOCK_SHIFT;
- int block_id = find_block(block_offset);
-
- if (block_id < 0)
- { /* The needed block isn't in cache already, so initiate loading */
- writeout_dirty_nodes(id);
+ const int block_id = find_block(block_offset);
- /* Make sure the node cache is correctly initialised for the block that will be read */
- if (cacheHeader.max_initialised_id
- < ((block_offset + 1) << READ_NODE_BLOCK_SHIFT))
- expand_cache(block_offset);
+ if (block_id < 0) {
+ // The needed block isn't in cache already, so initiate loading
+ if (cacheHeader.max_initialised_id < id) {
+ fprintf(stderr, "Warning: reading node outside node cache. (%lu vs. %lu)\n",
+ cacheHeader.max_initialised_id, id);
+ return;
+ }
- if (posix_fadvise(node_cache_fd, (block_offset << READ_NODE_BLOCK_SHIFT) * sizeof(struct ramNode)
- + sizeof(struct persistentCacheHeader), READ_NODE_BLOCK_SIZE * sizeof(struct ramNode),
+ if (posix_fadvise(node_cache_fd, (block_offset << READ_NODE_BLOCK_SHIFT) * sizeof(ramNode)
+ + sizeof(persistentCacheHeader), READ_NODE_BLOCK_SIZE * sizeof(ramNode),
POSIX_FADV_WILLNEED | POSIX_FADV_RANDOM) != 0) {
fprintf(stderr, "Info: async prefetch of node cache failed. This might reduce performance\n");
};
@@ -283,22 +212,21 @@ void node_persistent_cache::nodes_prefetch_async(osmid_t id)
*/
int node_persistent_cache::load_block(osmid_t block_offset)
{
-
- int block_id = replace_block();
+ const int block_id = replace_block();
if (readNodeBlockCache[block_id].dirty)
{
if (lseek64(node_cache_fd,
(readNodeBlockCache[block_id].block_offset
- << READ_NODE_BLOCK_SHIFT) * sizeof(struct ramNode)
+ << READ_NODE_BLOCK_SHIFT) * sizeof(ramNode)
+ sizeof(struct persistentCacheHeader), SEEK_SET) < 0) {
fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
strerror(errno));
util::exit_nicely();
};
if (write(node_cache_fd, readNodeBlockCache[block_id].nodes,
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- < ssize_t(READ_NODE_BLOCK_SIZE * sizeof(struct ramNode)))
+ READ_NODE_BLOCK_SIZE * sizeof(ramNode))
+ < ssize_t(READ_NODE_BLOCK_SIZE * sizeof(ramNode)))
{
fprintf(stderr, "Failed to write out node cache: %s\n",
strerror(errno));
@@ -308,7 +236,7 @@ int node_persistent_cache::load_block(osmid_t block_offset)
}
remove_from_cache_idx(readNodeBlockCache[block_id].block_offset);
- ramNodes_clear(readNodeBlockCache[block_id].nodes, READ_NODE_BLOCK_SIZE);
+ new(readNodeBlockCache[block_id].nodes) ramNode[READ_NODE_BLOCK_SIZE];
readNodeBlockCache[block_id].block_offset = block_offset;
readNodeBlockCache[block_id].used = READ_NODE_CACHE_SIZE;
@@ -321,22 +249,21 @@ int node_persistent_cache::load_block(osmid_t block_offset)
/* Read the block into cache */
if (lseek64(node_cache_fd,
- (block_offset << READ_NODE_BLOCK_SHIFT) * sizeof(struct ramNode)
+ (block_offset << READ_NODE_BLOCK_SHIFT) * sizeof(ramNode)
+ sizeof(struct persistentCacheHeader), SEEK_SET) < 0) {
fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
strerror(errno));
util::exit_nicely();
};
if (read(node_cache_fd, readNodeBlockCache[block_id].nodes,
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- != READ_NODE_BLOCK_SIZE * sizeof(struct ramNode))
+ READ_NODE_BLOCK_SIZE * sizeof(ramNode))
+ != READ_NODE_BLOCK_SIZE * sizeof(ramNode))
{
fprintf(stderr, "Failed to read from node cache: %s\n",
strerror(errno));
exit(1);
}
- add_to_cache_idx(cache_index_entry(readNodeBlockCache[block_id].block_offset,
- block_id));
+ add_to_cache_idx(cache_index_entry(block_offset, block_id));
return block_id;
}
@@ -344,8 +271,8 @@ int node_persistent_cache::load_block(osmid_t block_offset)
void node_persistent_cache::nodes_set_create_writeout_block()
{
if (write(node_cache_fd, writeNodeBlock.nodes,
- WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode))
- < ssize_t(WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode)))
+ WRITE_NODE_BLOCK_SIZE * sizeof(ramNode))
+ < ssize_t(WRITE_NODE_BLOCK_SIZE * sizeof(ramNode)))
{
fprintf(stderr, "Failed to write out node cache: %s\n",
strerror(errno));
@@ -355,31 +282,31 @@ void node_persistent_cache::nodes_set_create_writeout_block()
/* writing out large files can cause trouble on some operating systems.
* For one, if to much dirty data is in RAM, the whole OS can stall until
* enough dirty data is written out which can take a while. It can also interfere
- * with outher disk caching operations and might push things out to swap. By forcing the OS to
+ * with other disk caching operations and might push things out to swap. By forcing the OS to
* immediately write out the data and blocking after a while, we ensure that no more
* than a couple of 10s of MB are dirty in RAM at a time.
* Secondly, the nodes are stored in an additional ram cache during import. Keeping the
* node cache file in buffer cache therefore duplicates the data wasting 16GB of ram.
* Therefore tell the OS not to cache the node-persistent-cache during initial import.
* */
- if (sync_file_range(node_cache_fd, writeNodeBlock.block_offset*WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode) +
- sizeof(struct persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode),
+ if (sync_file_range(node_cache_fd, writeNodeBlock.block_offset*WRITE_NODE_BLOCK_SIZE * sizeof(ramNode) +
+ sizeof(persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(ramNode),
SYNC_FILE_RANGE_WRITE) < 0) {
fprintf(stderr, "Info: Sync_file_range writeout has an issue. This shouldn't be anything to worry about.: %s\n",
strerror(errno));
};
if (writeNodeBlock.block_offset > 16) {
- if(sync_file_range(node_cache_fd, (writeNodeBlock.block_offset - 16)*WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode) +
- sizeof(struct persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode),
+ if(sync_file_range(node_cache_fd, (writeNodeBlock.block_offset - 16)*WRITE_NODE_BLOCK_SIZE * sizeof(ramNode) +
+ sizeof(persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(ramNode),
SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER) < 0) {
fprintf(stderr, "Info: Sync_file_range block has an issue. This shouldn't be anything to worry about.: %s\n",
strerror(errno));
}
#ifdef HAVE_POSIX_FADVISE
- if (posix_fadvise(node_cache_fd, (writeNodeBlock.block_offset - 16)*WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode) +
- sizeof(struct persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode), POSIX_FADV_DONTNEED) !=0 ) {
+ if (posix_fadvise(node_cache_fd, (writeNodeBlock.block_offset - 16)*WRITE_NODE_BLOCK_SIZE * sizeof(ramNode) +
+ sizeof(persistentCacheHeader), WRITE_NODE_BLOCK_SIZE * sizeof(ramNode), POSIX_FADV_DONTNEED) !=0 ) {
fprintf(stderr, "Info: Posix_fadvise failed. This shouldn't be anything to worry about.: %s\n",
strerror(errno));
};
@@ -390,18 +317,16 @@ void node_persistent_cache::nodes_set_create_writeout_block()
int node_persistent_cache::set_create(osmid_t id, double lat, double lon)
{
- osmid_t block_offset = id >> WRITE_NODE_BLOCK_SHIFT;
- int i;
+ assert(!append_mode);
+ assert(!read_mode);
- if (cache_already_written)
- return 0;
+ osmid_t block_offset = id >> WRITE_NODE_BLOCK_SHIFT;
if (writeNodeBlock.block_offset != block_offset)
{
if (writeNodeBlock.dirty)
{
nodes_set_create_writeout_block();
- writeNodeBlock.used = 0;
writeNodeBlock.dirty = 0;
/* After writing out the node block, the file pointer is at the next block level */
writeNodeBlock.block_offset++;
@@ -416,25 +341,18 @@ int node_persistent_cache::set_create(osmid_t id, double lat, double lon)
util::exit_nicely();
}
+ new(writeNodeBlock.nodes) ramNode[WRITE_NODE_BLOCK_SIZE];
+
/* We need to fill the intermediate node cache with node nodes to identify which nodes are valid */
- for (i = writeNodeBlock.block_offset; i < block_offset; i++)
+ while (writeNodeBlock.block_offset < block_offset)
{
- ramNodes_clear(writeNodeBlock.nodes, WRITE_NODE_BLOCK_SIZE);
nodes_set_create_writeout_block();
+ writeNodeBlock.block_offset++;
}
- ramNodes_clear(writeNodeBlock.nodes, WRITE_NODE_BLOCK_SIZE);
- writeNodeBlock.used = 0;
- writeNodeBlock.block_offset = block_offset;
}
-#ifdef FIXED_POINT
- writeNodeBlock.nodes[id & WRITE_NODE_BLOCK_MASK].lat = util::double_to_fix(lat, scale_);
- writeNodeBlock.nodes[id & WRITE_NODE_BLOCK_MASK].lon = util::double_to_fix(lon, scale_);
-#else
- writeNodeBlock.nodes[id & WRITE_NODE_BLOCK_MASK].lat = lat;
- writeNodeBlock.nodes[id & WRITE_NODE_BLOCK_MASK].lon = lon;
-#endif
- writeNodeBlock.used++;
+
+ writeNodeBlock.nodes[id & WRITE_NODE_BLOCK_MASK] = ramNode(lon, lat);
writeNodeBlock.dirty = 1;
return 0;
@@ -442,6 +360,8 @@ int node_persistent_cache::set_create(osmid_t id, double lat, double lon)
int node_persistent_cache::set_append(osmid_t id, double lat, double lon)
{
+ assert(!read_mode);
+
osmid_t block_offset = id >> READ_NODE_BLOCK_SHIFT;
int block_id = find_block(block_offset);
@@ -449,25 +369,10 @@ int node_persistent_cache::set_append(osmid_t id, double lat, double lon)
if (block_id < 0)
block_id = load_block(block_offset);
-#ifdef FIXED_POINT
if (isnan(lat) && isnan(lon))
- {
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat =
- INT_MIN;
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon =
- INT_MIN;
- }
+ readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK] = ramNode();
else
- {
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat =
- util::double_to_fix(lat, scale_);
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon =
- util::double_to_fix(lon, scale_);
- }
-#else
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat = lat;
- readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon = lon;
-#endif
+ readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK] = ramNode(lon, lat);
readNodeBlockCache[block_id].used++;
readNodeBlockCache[block_id].dirty = 1;
@@ -481,61 +386,40 @@ int node_persistent_cache::set(osmid_t id, double lat, double lon)
set_create(id, lat, lon);
}
-int node_persistent_cache::get(struct osmNode *out, osmid_t id)
+int node_persistent_cache::get(osmNode *out, osmid_t id)
{
+ set_read_mode();
+
osmid_t block_offset = id >> READ_NODE_BLOCK_SHIFT;
int block_id = find_block(block_offset);
if (block_id < 0)
{
- writeout_dirty_nodes(id);
block_id = load_block(block_offset);
}
readNodeBlockCache[block_id].used++;
-#ifdef FIXED_POINT
- if ((readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat
- == INT_MIN)
- && (readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon
- == INT_MIN))
- {
+ if (!readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].is_valid())
return 1;
- }
- else
- {
- out->lat =
- util::fix_to_double(readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat, scale_);
- out->lon =
- util::fix_to_double(readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon, scale_);
- return 0;
- }
-#else
- if ((isnan(readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat)) &&
- (isnan(readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon)))
- {
- return 1;
- }
- else
- {
- out->lat = readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat;
- out->lon = readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon;
- return 0;
- }
-#endif
+
+ out->lat = readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lat();
+ out->lon = readNodeBlockCache[block_id].nodes[id & READ_NODE_BLOCK_MASK].lon();
return 0;
}
int node_persistent_cache::get_list(nodelist_t &out, const idlist_t nds)
{
+ set_read_mode();
+
out.assign(nds.size(), osmNode());
- bool need_fetch = false;;
+ bool need_fetch = false;
for (size_t i = 0; i < nds.size(); ++i) {
/* Check cache first */
- if (ram_cache && (ram_cache->get(&out[i], nds[i]) != 0)) {
+ if (ram_cache->get(&out[i], nds[i]) != 0) {
/* In order to have a higher OS level I/O queue depth
issue posix_fadvise(WILLNEED) requests for all I/O */
nodes_prefetch_async(nds[i]);
@@ -562,14 +446,45 @@ int node_persistent_cache::get_list(nodelist_t &out, const idlist_t nds)
return wrtidx;
}
+void node_persistent_cache::set_read_mode()
+{
+ if (read_mode)
+ return;
+
+ if (writeNodeBlock.dirty > 0) {
+ assert(!append_mode);
+ fprintf(stderr, "Switching to read mode\n");
+ nodes_set_create_writeout_block();
+ writeNodeBlock.dirty = 0;
+ writeNodeBlock.block_offset++;
+ cacheHeader.max_initialised_id = (writeNodeBlock.block_offset
+ << WRITE_NODE_BLOCK_SHIFT) - 1;
+
+ /* write out the header */
+ if (lseek64(node_cache_fd, 0, SEEK_SET) < 0) {
+ fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
+ strerror(errno));
+ util::exit_nicely();
+ };
+ if (write(node_cache_fd, &cacheHeader, sizeof(persistentCacheHeader))
+ != sizeof(persistentCacheHeader)) {
+ fprintf(stderr, "Failed to update persistent cache header: %s\n",
+ strerror(errno));
+ util::exit_nicely();
+ }
+ }
+
+ read_mode = true;
+
+ fprintf(stderr, "Switching to read mode done\n");
+}
+
node_persistent_cache::node_persistent_cache(const options_t *options, int append,
- boost::shared_ptr<node_ram_cache> ptr)
+ bool ro, boost::shared_ptr<node_ram_cache> ptr)
: node_cache_fd(0), node_cache_fname(NULL), append_mode(0), cacheHeader(),
- writeNodeBlock(), readNodeBlockCache(NULL),
- scale_(0), cache_already_written(0), ram_cache(ptr)
+ writeNodeBlock(), readNodeBlockCache(NULL), read_mode(ro), ram_cache(ptr)
{
int i, err;
- scale_ = options->scale;
append_mode = append;
if (options->flat_node_file) {
node_cache_fname = options->flat_node_file->c_str();
@@ -595,7 +510,7 @@ node_persistent_cache::node_persistent_cache(const options_t *options, int appen
}
else
{
- if (cache_already_written)
+ if (read_mode)
{
node_cache_fd = open(node_cache_fname, O_RDWR, S_IRUSR | S_IWUSR);
}
@@ -616,12 +531,17 @@ node_persistent_cache::node_persistent_cache(const options_t *options, int appen
strerror(errno));
util::exit_nicely();
};
- if (cache_already_written == 0)
+
+ writeNodeBlock.block_offset = 0;
+ writeNodeBlock.dirty = 0;
+ writeNodeBlock.nodes = 0;
+
+ if (!read_mode)
{
#ifdef HAVE_POSIX_FALLOCATE
if ((err = posix_fallocate(node_cache_fd, 0,
- sizeof(struct ramNode) * MAXIMUM_INITIAL_ID)) != 0)
+ sizeof(ramNode) * MAXIMUM_INITIAL_ID)) != 0)
{
if (err == ENOSPC) {
fprintf(stderr, "Failed to allocate space for node cache file: No space on disk\n");
@@ -636,16 +556,11 @@ node_persistent_cache::node_persistent_cache(const options_t *options, int appen
}
fprintf(stderr, "Allocated space for persistent node cache file\n");
#endif
- writeNodeBlock.nodes = (struct ramNode *)malloc(
- WRITE_NODE_BLOCK_SIZE * sizeof(struct ramNode));
+ writeNodeBlock.nodes = new ramNode[WRITE_NODE_BLOCK_SIZE];
if (!writeNodeBlock.nodes) {
fprintf(stderr, "Out of memory: Failed to allocate node writeout buffer\n");
util::exit_nicely();
}
- ramNodes_clear(writeNodeBlock.nodes, WRITE_NODE_BLOCK_SIZE);
- writeNodeBlock.block_offset = 0;
- writeNodeBlock.used = 0;
- writeNodeBlock.dirty = 0;
cacheHeader.format_version = PERSISTENT_CACHE_FORMAT_VERSION;
cacheHeader.id_size = sizeof(osmid_t);
cacheHeader.max_initialised_id = 0;
@@ -691,16 +606,14 @@ node_persistent_cache::node_persistent_cache(const options_t *options, int appen
fprintf(stderr,"Maximum node in persistent node cache: %" PRIdOSMID "\n", cacheHeader.max_initialised_id);
- readNodeBlockCache = (struct ramNodeBlock *)malloc(
- READ_NODE_CACHE_SIZE * sizeof(struct ramNodeBlock));
+ readNodeBlockCache = new ramNodeBlock [READ_NODE_CACHE_SIZE];
if (!readNodeBlockCache) {
fprintf(stderr, "Out of memory: Failed to allocate node read cache\n");
util::exit_nicely();
}
for (i = 0; i < READ_NODE_CACHE_SIZE; i++)
{
- readNodeBlockCache[i].nodes = (struct ramNode *)malloc(
- READ_NODE_BLOCK_SIZE * sizeof(struct ramNode));
+ readNodeBlockCache[i].nodes = new ramNode[READ_NODE_BLOCK_SIZE];
if (!readNodeBlockCache[i].nodes) {
fprintf(stderr, "Out of memory: Failed to allocate node read cache\n");
util::exit_nicely();
@@ -713,8 +626,13 @@ node_persistent_cache::node_persistent_cache(const options_t *options, int appen
node_persistent_cache::~node_persistent_cache()
{
- int i;
- writeout_dirty_nodes(-1);
+ if (writeNodeBlock.dirty > 0)
+ nodes_set_create_writeout_block();
+
+ writeout_dirty_nodes();
+
+ if (writeNodeBlock.nodes)
+ delete[] writeNodeBlock.nodes;
if (lseek64(node_cache_fd, 0, SEEK_SET) < 0) {
fprintf(stderr, "Failed to seek to correct position in node cache: %s\n",
@@ -738,10 +656,11 @@ node_persistent_cache::~node_persistent_cache()
strerror(errno));
}
- for (i = 0; i < READ_NODE_CACHE_SIZE; i++)
- {
- free(readNodeBlockCache[i].nodes);
+ if (readNodeBlockCache) {
+ for (int i = 0; i < READ_NODE_CACHE_SIZE; i++)
+ {
+ delete[] readNodeBlockCache[i].nodes;
+ }
+ delete[] readNodeBlockCache;
}
- free(readNodeBlockCache);
- readNodeBlockCache = NULL;
}
diff --git a/node-persistent-cache.hpp b/node-persistent-cache.hpp
index a0c2a48..2363d11 100644
--- a/node-persistent-cache.hpp
+++ b/node-persistent-cache.hpp
@@ -51,12 +51,12 @@ inline bool operator<(osmid_t a, cache_index_entry const &b)
struct node_persistent_cache : public boost::noncopyable
{
- node_persistent_cache(const struct options_t *options, const int append,
- boost::shared_ptr<node_ram_cache> ptr);
+ node_persistent_cache(const struct options_t *options, int append,
+ bool ro, boost::shared_ptr<node_ram_cache> ptr);
~node_persistent_cache();
int set(osmid_t id, double lat, double lon);
- int get(struct osmNode *out, osmid_t id);
+ int get(osmNode *out, osmid_t id);
int get_list(nodelist_t &out, const idlist_t nds);
private:
@@ -64,7 +64,7 @@ private:
int set_append(osmid_t id, double lat, double lon);
int set_create(osmid_t id, double lat, double lon);
- void writeout_dirty_nodes(osmid_t id);
+ void writeout_dirty_nodes();
int replace_block();
int find_block(osmid_t block_offset);
void expand_cache(osmid_t block_offset);
@@ -74,20 +74,20 @@ private:
void remove_from_cache_idx(osmid_t block_offset);
void add_to_cache_idx(cache_index_entry const &entry);
+ void set_read_mode();
int node_cache_fd;
const char * node_cache_fname;
int append_mode;
- struct persistentCacheHeader cacheHeader;
- struct ramNodeBlock writeNodeBlock; /* larger node block for more efficient initial sequential writing of node cache */
- struct ramNodeBlock * readNodeBlockCache;
+ persistentCacheHeader cacheHeader;
+ ramNodeBlock writeNodeBlock; /* larger node block for more efficient initial sequential writing of node cache */
+ ramNodeBlock * readNodeBlockCache;
typedef std::vector<cache_index_entry> cache_index;
cache_index readNodeBlockCacheIdx;
- int scale_;
- int cache_already_written;
+ bool read_mode;
boost::shared_ptr<node_ram_cache> ram_cache;
};
diff --git a/node-ram-cache.cpp b/node-ram-cache.cpp
index 7a467ba..167f6b7 100644
--- a/node-ram-cache.cpp
+++ b/node-ram-cache.cpp
@@ -5,21 +5,14 @@
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "osmtypes.hpp"
-#include "middle.hpp"
#include "node-ram-cache.hpp"
#include "util.hpp"
-
-
-
-
/* Here we use a similar storage structure as middle-ram, except we allow
* the array to be lossy so we can cap the total memory usage. Hence it is a
* combination of a sparse array with a priority queue
@@ -65,6 +58,8 @@
#define SAFETY_MARGIN 1024*PER_BLOCK*sizeof(ramNode)
+int ramNode::scale;
+
static int id2block(osmid_t id)
{
/* + NUM_BLOCKS/2 allows for negative IDs */
@@ -99,21 +94,20 @@ void node_ram_cache::percolate_up( int pos )
}
}
-ramNode *node_ram_cache::next_chunk(size_t count, size_t size) {
+ramNode *node_ram_cache::next_chunk() {
if ( (allocStrategy & ALLOC_DENSE_CHUNK) == 0 ) {
- static size_t pos = 0;
- char *result;
- pos += count * size;
- result = blockCache + cacheSize - pos + SAFETY_MARGIN;
+ // allocate starting from the upper end of the block cache
+ blockCachePos += PER_BLOCK * sizeof(ramNode);
+ char *result = blockCache + cacheSize - blockCachePos + SAFETY_MARGIN;
- return (ramNode *)result;
+ return new(result) ramNode[PER_BLOCK];
} else {
- return (ramNode *)calloc(PER_BLOCK, sizeof(ramNode));
+ return new ramNode[PER_BLOCK];
}
}
-int node_ram_cache::set_sparse(osmid_t id, double lat, double lon) {
+int node_ram_cache::set_sparse(osmid_t id, const ramNode &coord) {
if ((sizeSparseTuples > maxSparseTuples) || ( cacheUsed > cacheSize)) {
if ((allocStrategy & ALLOC_LOSSY) > 0)
return 1;
@@ -123,20 +117,15 @@ int node_ram_cache::set_sparse(osmid_t id, double lat, double lon) {
}
}
sparseBlock[sizeSparseTuples].id = id;
-#ifdef FIXED_POINT
- sparseBlock[sizeSparseTuples].coord.lat = util::double_to_fix(lat, scale_);
- sparseBlock[sizeSparseTuples].coord.lon = util::double_to_fix(lon, scale_);
-#else
- sparseBlock[sizeSparseTuples].coord.lat = lat;
- sparseBlock[sizeSparseTuples].coord.lon = lon;
-#endif
+ sparseBlock[sizeSparseTuples].coord = coord;
+
sizeSparseTuples++;
cacheUsed += sizeof(ramNodeID);
storedNodes++;
return 0;
}
-int node_ram_cache::set_dense(osmid_t id, double lat, double lon) {
+int node_ram_cache::set_dense(osmid_t id, const ramNode &coord) {
int block = id2block(id);
int offset = id2offset(id);
int i = 0;
@@ -160,32 +149,25 @@ int node_ram_cache::set_dense(osmid_t id, double lat, double lon) {
/* We've just finished with the previous block, so we need to percolate it up the queue to its correct position */
/* Upto log(usedBlocks) iterations */
percolate_up( usedBlocks-1 );
- blocks[block].nodes = next_chunk(PER_BLOCK, sizeof(ramNode));
+ blocks[block].nodes = next_chunk();
} else {
/* previous block was not dense enough, so push it into the sparse node cache instead */
for (i = 0; i < (1 << BLOCK_SHIFT); i++) {
- if (queue[usedBlocks -1]->nodes[i].lat || queue[usedBlocks -1]->nodes[i].lon) {
- set_sparse(block2id(queue[usedBlocks - 1]->block_offset,i),
-#ifdef FIXED_POINT
- util::fix_to_double(queue[usedBlocks -1]->nodes[i].lat, scale_),
- util::fix_to_double(queue[usedBlocks -1]->nodes[i].lon, scale_)
-#else
- queue[usedBlocks -1]->nodes[i].lat,
- queue[usedBlocks -1]->nodes[i].lon
-#endif
- );
+ if (queue[usedBlocks -1]->nodes[i].is_valid()) {
+ set_sparse(block2id(queue[usedBlocks - 1]->block_offset, i),
+ queue[usedBlocks -1]->nodes[i]);
+ queue[usedBlocks -1]->nodes[i] = ramNode(); // invalidate
}
}
- /* reuse previous block, as it's content is now in the dense representation */
+ /* reuse previous block, as its content is now in the sparse representation */
storedNodes -= queue[usedBlocks - 1]->used;
blocks[block].nodes = queue[usedBlocks - 1]->nodes;
blocks[queue[usedBlocks - 1]->block_offset].nodes = NULL;
- memset( blocks[block].nodes, 0, PER_BLOCK * sizeof(ramNode) );
usedBlocks--;
cacheUsed -= PER_BLOCK * sizeof(ramNode);
}
} else {
- blocks[block].nodes = next_chunk(PER_BLOCK, sizeof(ramNode));
+ blocks[block].nodes = next_chunk();
}
blocks[block].used = 0;
@@ -232,7 +214,7 @@ int node_ram_cache::set_dense(osmid_t id, double lat, double lon) {
/* Now the head of the queue is the smallest, so it becomes our replacement candidate */
blocks[block].nodes = queue[0]->nodes;
blocks[block].used = 0;
- memset( blocks[block].nodes, 0, PER_BLOCK * sizeof(ramNode) );
+ new(blocks[block].nodes) ramNode[PER_BLOCK];
/* Clear old head block and point to new block */
storedNodes -= queue[0]->used;
@@ -260,13 +242,7 @@ int node_ram_cache::set_dense(osmid_t id, double lat, double lon) {
}
}
-#ifdef FIXED_POINT
- blocks[block].nodes[offset].lat = util::double_to_fix(lat, scale_);
- blocks[block].nodes[offset].lon = util::double_to_fix(lon, scale_);
-#else
- blocks[block].nodes[offset].lat = lat;
- blocks[block].nodes[offset].lon = lon;
-#endif
+ blocks[block].nodes[offset] = coord;
blocks[block].used++;
storedNodes++;
return 0;
@@ -280,13 +256,8 @@ int node_ram_cache::get_sparse(osmNode *out, osmid_t id) {
while (minPos <= maxPos) {
if ( sparseBlock[pivotPos].id == id ) {
-#ifdef FIXED_POINT
- out->lat = util::fix_to_double(sparseBlock[pivotPos].coord.lat, scale_);
- out->lon = util::fix_to_double(sparseBlock[pivotPos].coord.lon, scale_);
-#else
- out->lat = sparseBlock[pivotPos].coord.lat;
- out->lon = sparseBlock[pivotPos].coord.lon;
-#endif
+ out->lat = sparseBlock[pivotPos].coord.lat();
+ out->lon = sparseBlock[pivotPos].coord.lon();
return 0;
}
if ( (pivotPos == minPos) || (pivotPos == maxPos)) return 1;
@@ -310,16 +281,11 @@ int node_ram_cache::get_dense(osmNode *out, osmid_t id) {
if (!blocks[block].nodes)
return 1;
- if (!blocks[block].nodes[offset].lat && !blocks[block].nodes[offset].lon)
+ if (!blocks[block].nodes[offset].is_valid())
return 1;
-#ifdef FIXED_POINT
- out->lat = util::fix_to_double(blocks[block].nodes[offset].lat, scale_);
- out->lon = util::fix_to_double(blocks[block].nodes[offset].lon, scale_);
-#else
- out->lat = blocks[block].nodes[offset].lat;
- out->lon = blocks[block].nodes[offset].lon;
-#endif
+ out->lat = blocks[block].nodes[offset].lat();
+ out->lon = blocks[block].nodes[offset].lon();
return 0;
}
@@ -327,12 +293,14 @@ int node_ram_cache::get_dense(osmNode *out, osmid_t id) {
node_ram_cache::node_ram_cache( int strategy, int cacheSizeMB, int fixpointscale )
: allocStrategy(ALLOC_DENSE), blocks(NULL), usedBlocks(0),
- maxBlocks(0), blockCache(NULL), queue(NULL), scale_(fixpointscale), sparseBlock(NULL),
+ maxBlocks(0), blockCache(NULL), queue(NULL), sparseBlock(NULL),
maxSparseTuples(0), sizeSparseTuples(0), cacheUsed(0),
cacheSize(0), storedNodes(0), totalNodes(0), nodesCacheHits(0),
nodesCacheLookups(0), warn_node_order(0) {
+ ramNode::scale = fixpointscale;
blockCache = 0;
+ blockCachePos = 0;
cacheUsed = 0;
cacheSize = (int64_t)cacheSizeMB*(1024*1024);
/* How much we can fit, and make sure it's odd */
@@ -361,7 +329,7 @@ node_ram_cache::node_ram_cache( int strategy, int cacheSizeMB, int fixpointscale
}
} else {
fprintf(stderr, "Allocating dense node cache in one big chunk\n");
- blockCache = (char *)calloc(maxBlocks + 1024,PER_BLOCK * sizeof(ramNode));
+ blockCache = (char *)malloc((maxBlocks + 1024) * PER_BLOCK * sizeof(ramNode));
if (!queue || !blockCache) {
fprintf(stderr, "Out of memory for dense node cache, reduce --cache size\n");
util::exit_nicely();
@@ -379,7 +347,7 @@ node_ram_cache::node_ram_cache( int strategy, int cacheSizeMB, int fixpointscale
if ((allocStrategy & ALLOC_SPARSE) > 0 ) {
fprintf(stderr, "Allocating memory for sparse node cache\n");
if (!blockCache) {
- sparseBlock = (ramNodeID *)calloc(maxSparseTuples,sizeof(ramNodeID));
+ sparseBlock = (ramNodeID *)malloc(maxSparseTuples * sizeof(ramNodeID));
} else {
fprintf(stderr, "Sharing dense sparse\n");
sparseBlock = (ramNodeID *)blockCache;
@@ -398,7 +366,6 @@ node_ram_cache::node_ram_cache( int strategy, int cacheSizeMB, int fixpointscale
}
node_ram_cache::~node_ram_cache() {
- int i;
fprintf( stderr, "node cache: stored: %" PRIdOSMID "(%.2f%%), storage efficiency: %.2f%% (dense blocks: %i, sparse nodes: %li), hit rate: %.2f%%\n",
storedNodes, 100.0f*storedNodes/totalNodes, 100.0f*storedNodes*sizeof(ramNode)/cacheUsed,
usedBlocks, sizeSparseTuples,
@@ -406,8 +373,8 @@ node_ram_cache::~node_ram_cache() {
if ( (allocStrategy & ALLOC_DENSE) > 0 ) {
if ( (allocStrategy & ALLOC_DENSE_CHUNK) > 0 ) {
- for( i=0; i<usedBlocks; i++ ) {
- free(queue[i]->nodes);
+ for(int i = 0; i < usedBlocks; ++i) {
+ delete[] queue[i]->nodes;
queue[i]->nodes = NULL;
}
} else {
@@ -429,10 +396,10 @@ int node_ram_cache::set(osmid_t id, double lat, double lon, const taglist_t &) {
* get pushed to the sparse cache if a block is sparse and ALLOC_SPARSE is set
*/
if ( (allocStrategy & ALLOC_DENSE) > 0 ) {
- return set_dense(id, lat, lon);
+ return set_dense(id, ramNode(lon, lat));
}
if ( (allocStrategy & ALLOC_SPARSE) > 0 )
- return set_sparse(id, lat, lon);
+ return set_sparse(id, ramNode(lon, lat));
return 1;
}
@@ -440,13 +407,13 @@ int node_ram_cache::get(osmNode *out, osmid_t id) {
nodesCacheLookups++;
if ((allocStrategy & ALLOC_DENSE) > 0) {
- if (get_dense(out,id) == 0) {
+ if (get_dense(out, id) == 0) {
nodesCacheHits++;
return 0;
}
}
if ((allocStrategy & ALLOC_SPARSE) > 0) {
- if (get_sparse(out,id) == 0) {
+ if (get_sparse(out, id) == 0) {
nodesCacheHits++;
return 0;
}
diff --git a/node-ram-cache.hpp b/node-ram-cache.hpp
index 8c64eb3..0404904 100644
--- a/node-ram-cache.hpp
+++ b/node-ram-cache.hpp
@@ -8,8 +8,12 @@
#ifndef NODE_RAM_CACHE_H
#define NODE_RAM_CACHE_H
+#include "config.h"
#include "osmtypes.hpp"
+#include <cstddef>
+#include <climits>
+#include <stdint.h>
#include <boost/noncopyable.hpp>
#define ALLOC_SPARSE 1
@@ -17,26 +21,70 @@
#define ALLOC_DENSE_CHUNK 4
#define ALLOC_LOSSY 8
-/* Store +-20,000km Mercator co-ordinates as fixed point 32bit number with maximum precision */
-#define FIXED_POINT
-
-struct ramNode {
+/**
+ * A set of coordinates, for caching in RAM or on disk.
+ *
+ * If FIXED_POINT is enabled, it uses internally a more efficient
+ * representation as integer.
+ */
+class ramNode {
+public:
#ifdef FIXED_POINT
- int lon;
- int lat;
+ static int scale;
+
+ /// Default constructor creates an invalid node
+ ramNode() : _lon(INT_MIN), _lat(INT_MIN) {}
+ /**
+ * Standard constructor takes geographic coordinates and saves them
+ * in the internal node representation.
+ */
+ ramNode(double lon, double lat) : _lon(dbl2fix(lon)), _lat(dbl2fix(lat)) {}
+ /**
+ * Internal constructor which takes already encoded nodes.
+ *
+ * Used by middle-pgsql which stores encoded nodes in the DB.
+ */
+ ramNode(int lon, int lat) : _lon(lon), _lat(lat) {}
+
+ /// Return true if the node currently stores valid coordinates.
+ bool is_valid() const { return _lon != INT_MIN; }
+ /// Return longitude (converting from internal representation)
+ double lon() const { return fix2dbl(_lon); }
+ /// Return latitude (converting from internal representation)
+ double lat() const { return fix2dbl(_lat); }
+ /// Return internal representation of longitude (for external storage).
+ int int_lon() const { return _lon; }
+ /// Return internal representation of latitude (for external storage).
+ int int_lat() const { return _lat; }
+
+private:
+ int _lon;
+ int _lat;
+
+ int dbl2fix(const double x) const { return x * scale + 0.4; }
+ double fix2dbl(const int x) const { return (double)x / scale; }
#else
- double lon;
- double lat;
+public:
+ ramNode() : _lat(NAN), _lon(NAN) {}
+ ramNode(double _lon, double _lat) : _lon(lon), _lat(lat) {}
+
+ bool is_valid() const ( return !isnan(_lon); }
+ double lon() const { return _lon; }
+ double lat() const { return _lat; }
+private:
+ double _lon;
+ double _lat;
+
#endif
};
struct ramNodeID {
osmid_t id;
- struct ramNode coord;
+ ramNode coord;
};
struct ramNodeBlock {
- struct ramNode *nodes;
+ ramNode *nodes;
osmid_t block_offset;
int used;
int dirty;
@@ -52,25 +100,24 @@ struct node_ram_cache : public boost::noncopyable
private:
void percolate_up( int pos );
- struct ramNode *next_chunk(size_t count, size_t size);
- int set_sparse(osmid_t id, double lat, double lon);
- int set_dense(osmid_t id, double lat, double lon);
+ ramNode *next_chunk();
+ int set_sparse(osmid_t id, const ramNode &coord);
+ int set_dense(osmid_t id, const ramNode& coord);
int get_sparse(osmNode *out, osmid_t id);
int get_dense(osmNode *out, osmid_t id);
int allocStrategy;
- struct ramNodeBlock *blocks;
+ ramNodeBlock *blocks;
int usedBlocks;
/* Note: maxBlocks *must* be odd, to make sure the priority queue has no nodes with only one child */
int maxBlocks;
char *blockCache;
+ size_t blockCachePos;
- struct ramNodeBlock **queue;
-
- int scale_;
+ ramNodeBlock **queue;
- struct ramNodeID *sparseBlock;
+ ramNodeID *sparseBlock;
int64_t maxSparseTuples;
int64_t sizeSparseTuples;
diff --git a/options.cpp b/options.cpp
index eea61bc..19462b4 100644
--- a/options.cpp
+++ b/options.cpp
@@ -29,7 +29,6 @@ namespace
{"prefix", 1, 0, 'p'},
{"proj", 1, 0, 'E'},
{"merc", 0, 0, 'm'},
- {"oldmerc", 0, 0, 'M'},
{"utf8-sanitize", 0, 0, 'u'},
{"cache", 1, 0, 'C'},
{"username", 1, 0, 'U'},
@@ -128,7 +127,6 @@ namespace
Obsolete options:\n\
-u|--utf8-sanitize Repair bad UTF8 input data (present in planet\n\
dumps prior to August 2007). Adds about 10% overhead.\n\
- -M|--oldmerc Store data in the legacy OSM mercator format\n\
\n\
Performance options:\n\
-i|--tablespace-index The name of the PostgreSQL tablespace where\n\
@@ -326,9 +324,6 @@ options_t options_t::parse(int argc, char *argv[])
case 'm':
options.projection.reset(new reprojection(PROJ_SPHERE_MERC));
break;
- case 'M':
- options.projection.reset(new reprojection(PROJ_MERC));
- break;
case 'E':
options.projection.reset(new reprojection(-atoi(optarg)));
break;
diff --git a/osm2pgsql.cpp b/osm2pgsql.cpp
index fadb41c..aa5674e 100644
--- a/osm2pgsql.cpp
+++ b/osm2pgsql.cpp
@@ -24,6 +24,8 @@
*/
#include "config.h"
+#include "osmtypes.hpp"
+#include "reprojection.hpp"
#include "options.hpp"
#include "parse.hpp"
#include "middle.hpp"
@@ -31,10 +33,12 @@
#include "osmdata.hpp"
#include "util.hpp"
-#include <unistd.h>
-#include <assert.h>
#include <time.h>
#include <stdexcept>
+#include <string>
+#include <vector>
+#include <cstdio>
+#include <cstdlib>
#include <libpq-fe.h>
#include <boost/format.hpp>
diff --git a/osmdata.cpp b/osmdata.cpp
index aa03556..95c25b5 100644
--- a/osmdata.cpp
+++ b/osmdata.cpp
@@ -1,6 +1,7 @@
#include "osmdata.hpp"
#include "output.hpp"
#include "middle.hpp"
+#include "node-ram-cache.hpp"
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
@@ -13,10 +14,6 @@
#include <utility>
#include <cstdio>
-#ifdef HAVE_LOCKFREE
-#include <boost/atomic.hpp>
-#endif
-
osmdata_t::osmdata_t(boost::shared_ptr<middle_t> mid_, const boost::shared_ptr<output_t>& out_): mid(mid_)
{
outs.push_back(out_);
@@ -38,9 +35,12 @@ osmdata_t::~osmdata_t()
int osmdata_t::node_add(osmid_t id, double lat, double lon, const taglist_t &tags) {
mid->nodes_set(id, lat, lon, tags);
+ // guarantee that we use the same values as in the node cache
+ ramNode n(lon, lat);
+
int status = 0;
BOOST_FOREACH(boost::shared_ptr<output_t>& out, outs) {
- status |= out->node_add(id, lat, lon, tags);
+ status |= out->node_add(id, n.lat(), n.lon(), tags);
}
return status;
}
@@ -71,9 +71,12 @@ int osmdata_t::node_modify(osmid_t id, double lat, double lon, const taglist_t &
slim->nodes_delete(id);
slim->nodes_set(id, lat, lon, tags);
+ // guarantee that we use the same values as in the node cache
+ ramNode n(lon, lat);
+
int status = 0;
BOOST_FOREACH(boost::shared_ptr<output_t>& out, outs) {
- status |= out->node_modify(id, lat, lon, tags);
+ status |= out->node_modify(id, n.lat(), n.lon(), tags);
}
slim->node_changed(id);
@@ -169,7 +172,6 @@ struct pending_threaded_processor : public middle_t::pending_processor {
typedef std::vector<boost::shared_ptr<output_t> > output_vec_t;
typedef std::pair<boost::shared_ptr<const middle_query_t>, output_vec_t> clone_t;
-#ifndef HAVE_LOCKFREE
static void do_jobs(output_vec_t const& outputs, pending_queue_t& queue, size_t& ids_done, boost::mutex& mutex, int append, bool ways) {
while (true) {
//get the job off the queue synchronously
@@ -196,29 +198,13 @@ struct pending_threaded_processor : public middle_t::pending_processor {
mutex.unlock();
}
}
-#else
- static void do_jobs(output_vec_t const& outputs, pending_queue_t& queue, boost::atomic_size_t& ids_done, int append, bool ways) {
- pending_job_t job;
- while (queue.pop(job)) {
- if(ways)
- outputs.at(job.output_id)->pending_way(job.osm_id, append);
- else
- outputs.at(job.output_id)->pending_relation(job.osm_id, append);
- ++ids_done;
- }
- }
-#endif
//starts up count threads and works on the queue
pending_threaded_processor(boost::shared_ptr<middle_query_t> mid, const output_vec_t& outs, size_t thread_count, size_t job_count, int append)
-#ifndef HAVE_LOCKFREE
//note that we cant hint to the stack how large it should be ahead of time
//we could use a different datastructure like a deque or vector but then
//the outputs the enqueue jobs would need the version check for the push(_back) method
: outs(outs), ids_queued(0), append(append), queue(), ids_done(0) {
-#else
- : outs(outs), ids_queued(0), append(append), queue(job_count), ids_done(0) {
-#endif
//clone all the things we need
clones.reserve(thread_count);
@@ -258,11 +244,7 @@ struct pending_threaded_processor : public middle_t::pending_processor {
//make the threads and start them
for (size_t i = 0; i < clones.size(); ++i) {
-#ifndef HAVE_LOCKFREE
workers.create_thread(boost::bind(do_jobs, boost::cref(clones[i].second), boost::ref(queue), boost::ref(ids_done), boost::ref(mutex), append, true));
-#else
- workers.create_thread(boost::bind(do_jobs, boost::cref(clones[i].second), boost::ref(queue), boost::ref(ids_done), append, true));
-#endif
}
//TODO: print out partial progress
@@ -309,11 +291,7 @@ struct pending_threaded_processor : public middle_t::pending_processor {
//make the threads and start them
for (size_t i = 0; i < clones.size(); ++i) {
-#ifndef HAVE_LOCKFREE
workers.create_thread(boost::bind(do_jobs, boost::cref(clones[i].second), boost::ref(queue), boost::ref(ids_done), boost::ref(mutex), append, false));
-#else
- workers.create_thread(boost::bind(do_jobs, boost::cref(clones[i].second), boost::ref(queue), boost::ref(ids_done), append, false));
-#endif
}
//TODO: print out partial progress
@@ -355,14 +333,10 @@ private:
//job queue
pending_queue_t queue;
-#ifndef HAVE_LOCKFREE
//how many ids within the job have been processed
size_t ids_done;
//so the threads can manage some of the shared state
boost::mutex mutex;
-#else
- boost::atomic_size_t ids_done;
-#endif
};
} // anonymous namespace
diff --git a/output-multi.cpp b/output-multi.cpp
index eeb9edb..49f44a0 100644
--- a/output-multi.cpp
+++ b/output-multi.cpp
@@ -1,9 +1,13 @@
#include "output-multi.hpp"
#include "taginfo_impl.hpp"
+#include "table.hpp"
+#include "tagtransform.hpp"
+#include "options.hpp"
+#include "middle.hpp"
+#include "id-tracker.hpp"
+#include "geometry-builder.hpp"
+#include "expire-tiles.hpp"
-#include <boost/format.hpp>
-#include <boost/foreach.hpp>
-#include <boost/make_shared.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <vector>
@@ -19,7 +23,7 @@ output_multi_t::output_multi_t(const std::string &name,
m_osm_type(m_processor->interests(geometry_processor::interest_node) ? OSMTYPE_NODE : OSMTYPE_WAY),
m_table(new table_t(m_options.conninfo, name, m_processor->column_type(),
m_export_list->normal_columns(m_osm_type),
- m_options.hstore_columns, m_processor->srid(), m_options.scale,
+ m_options.hstore_columns, m_processor->srid(),
m_options.append, m_options.slim, m_options.droptemp,
m_options.hstore_mode, m_options.enable_hstore_index,
m_options.tblsmain_data, m_options.tblsmain_index)),
diff --git a/output-multi.hpp b/output-multi.hpp
index fd4f4d9..b2f17ec 100644
--- a/output-multi.hpp
+++ b/output-multi.hpp
@@ -7,22 +7,28 @@
#ifndef OUTPUT_MULTI_HPP
#define OUTPUT_MULTI_HPP
+#include "osmtypes.hpp"
#include "output.hpp"
-#include "tagtransform.hpp"
-#include "table.hpp"
#include "geometry-processor.hpp"
-#include "id-tracker.hpp"
-#include "expire-tiles.hpp"
-#include <vector>
+#include <cstddef>
+#include <string>
#include <boost/scoped_ptr.hpp>
-#include <boost/variant.hpp>
+#include <boost/shared_ptr.hpp>
+
+class table_t;
+class tagtransform;
+struct expire_tiles;
+struct export_list;
+struct id_tracker;
+struct middle_query_t;
+struct options_t;
class output_multi_t : public output_t {
public:
output_multi_t(const std::string &name,
boost::shared_ptr<geometry_processor> processor_,
- const struct export_list &export_list_,
+ const export_list &export_list_,
const middle_query_t* mid_, const options_t &options_);
output_multi_t(const output_multi_t& other);
virtual ~output_multi_t();
diff --git a/output-null.cpp b/output-null.cpp
index 5cd18e2..92a1521 100644
--- a/output-null.cpp
+++ b/output-null.cpp
@@ -1,15 +1,8 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <boost/make_shared.hpp>
-
#include "osmtypes.hpp"
#include "output-null.hpp"
-#include "options.hpp"
+
+struct middle_query_t;
+struct options_t;
void output_null_t::cleanup() {
}
diff --git a/output-pgsql.cpp b/output-pgsql.cpp
index b75ab82..8800d49 100644
--- a/output-pgsql.cpp
+++ b/output-pgsql.cpp
@@ -719,7 +719,7 @@ output_pgsql_t::output_pgsql_t(const middle_query_t* mid_, const options_t &opti
//have a different tablespace/hstores/etc per table
m_tables.push_back(boost::shared_ptr<table_t>(
new table_t(
- m_options.conninfo, name, type, columns, m_options.hstore_columns, SRID, m_options.scale,
+ m_options.conninfo, name, type, columns, m_options.hstore_columns, SRID,
m_options.append, m_options.slim, m_options.droptemp, m_options.hstore_mode,
m_options.enable_hstore_index, m_options.tblsmain_data, m_options.tblsmain_index
)
diff --git a/output.hpp b/output.hpp
index 2e5c7cb..bf93f5d 100644
--- a/output.hpp
+++ b/output.hpp
@@ -10,14 +10,15 @@
#ifndef OUTPUT_H
#define OUTPUT_H
+#include "options.hpp"
#include "middle.hpp"
#include "id-tracker.hpp"
#include "expire-tiles.hpp"
#include <boost/noncopyable.hpp>
#include <boost/version.hpp>
-
#include <utility>
+#include <stack>
struct pending_job_t {
osmid_t osm_id;
@@ -27,13 +28,7 @@ struct pending_job_t {
pending_job_t(osmid_t id, size_t oid) : osm_id(id), output_id(oid) {}
};
-#ifndef HAVE_LOCKFREE
-#include <stack>
typedef std::stack<pending_job_t> pending_queue_t;
-#else
-#include <boost/lockfree/queue.hpp>
-typedef boost::lockfree::queue<pending_job_t> pending_queue_t;
-#endif
class output_t : public boost::noncopyable {
public:
diff --git a/parse-o5m.cpp b/parse-o5m.cpp
index 1e3ca36..5162469 100644
--- a/parse-o5m.cpp
+++ b/parse-o5m.cpp
@@ -29,9 +29,10 @@
// to get the print format specifiers in the inttypes.h header.
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include <stdint.h>
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
@@ -41,7 +42,9 @@
#endif
#include "parse-o5m.hpp"
-#include "output.hpp"
+#include "osmdata.hpp"
+#include "osmtypes.hpp"
+#include "reprojection.hpp"
#define inline
diff --git a/parse-o5m.hpp b/parse-o5m.hpp
index d7d3f2c..31774e5 100644
--- a/parse-o5m.hpp
+++ b/parse-o5m.hpp
@@ -26,6 +26,9 @@
#define PARSE_O5M_H
#include "parse.hpp"
+#include <boost/shared_ptr.hpp>
+
+struct reprojection;
class parse_o5m_t: public parse_t
{
@@ -33,7 +36,7 @@ public:
parse_o5m_t(const int extra_attributes_, const bool bbox_, const boost::shared_ptr<reprojection>& projection_,
const double minlon, const double minlat, const double maxlon, const double maxlat);
virtual ~parse_o5m_t();
- virtual int streamFile(const char *filename, const int sanitize, osmdata_t *osmdata);
+ int streamFile(const char *filename, const int sanitize, osmdata_t *osmdata);
protected:
parse_o5m_t();
};
diff --git a/parse-pbf.cpp b/parse-pbf.cpp
index e64f603..6405b8e 100644
--- a/parse-pbf.cpp
+++ b/parse-pbf.cpp
@@ -22,9 +22,15 @@
#-----------------------------------------------------------------------------
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "config.h"
+
+#ifdef BUILD_READER_PBF
+
+#include <cassert>
+#include <cstdlib>
+#include <stdint.h>
+#include <cstdio>
+#include <cstring>
#ifdef _WIN32
#include <winsock2.h>
#else
@@ -33,13 +39,12 @@
#include <time.h>
#include <zlib.h>
-
-#include "config.h"
-
-#ifdef BUILD_READER_PBF
+#include <string>
#include "parse-pbf.hpp"
-#include "output.hpp"
+#include "osmdata.hpp"
+#include "osmtypes.hpp"
+#include "reprojection.hpp"
#define MAX_BLOCK_HEADER_SIZE 64*1024
#define MAX_BLOB_SIZE 32*1024*1024
diff --git a/parse-pbf.hpp b/parse-pbf.hpp
index 024fecc..8a2fc98 100644
--- a/parse-pbf.hpp
+++ b/parse-pbf.hpp
@@ -25,8 +25,6 @@
#ifndef PARSE_PBF_H
#define PARSE_PBF_H
-#include "parse.hpp"
-
#include "config.h"
#ifdef BUILD_READER_PBF
@@ -35,6 +33,14 @@ extern "C" {
#include "osmformat.pb-c.h"
}
+#include "parse.hpp"
+
+#include <cstddef>
+#include <boost/shared_ptr.hpp>
+
+struct reprojection;
+class osmdata_t;
+
class parse_pbf_t: public parse_t
{
public:
diff --git a/parse-xml2.cpp b/parse-xml2.cpp
index 8718f76..49fe259 100644
--- a/parse-xml2.cpp
+++ b/parse-xml2.cpp
@@ -22,17 +22,20 @@
#-----------------------------------------------------------------------------
*/
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
#include <time.h>
#include "sanitizer.hpp"
#include "input.hpp"
#include "parse-xml2.hpp"
-#include "output.hpp"
+#include "osmtypes.hpp"
+#include "osmdata.hpp"
#include "util.hpp"
+#include "reprojection.hpp"
/* Parses the action="foo" tags in JOSM change files. Obvisouly not useful from osmChange files */
actions_t parse_xml2_t::ParseAction( xmlTextReaderPtr reader)
diff --git a/parse-xml2.hpp b/parse-xml2.hpp
index 55d6112..d9cd263 100644
--- a/parse-xml2.hpp
+++ b/parse-xml2.hpp
@@ -40,7 +40,6 @@
#include "parse.hpp"
-#include <libxml/xmlstring.h>
#include <libxml/xmlreader.h>
class parse_xml2_t: public parse_t
diff --git a/parse.cpp b/parse.cpp
index cf760ca..f02d463 100644
--- a/parse.cpp
+++ b/parse.cpp
@@ -1,13 +1,17 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdexcept>
+#include "config.h"
+#include "parse.hpp"
#include "parse-o5m.hpp"
#ifdef BUILD_READER_PBF
# include "parse-pbf.hpp"
#endif
#include "parse-xml2.hpp"
-#include "util.hpp"
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <stdexcept>
+#include <algorithm>
+
#define INIT_MAX_MEMBERS 64
#define INIT_MAX_NODES 4096
diff --git a/parse.hpp b/parse.hpp
index 718cb30..6e3aeb2 100644
--- a/parse.hpp
+++ b/parse.hpp
@@ -1,13 +1,10 @@
#ifndef PARSE_H
#define PARSE_H
-#include <time.h>
-
-#include "config.h"
#include "osmtypes.hpp"
-#include "reprojection.hpp"
-#include "osmdata.hpp"
+#include <time.h>
+#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
@@ -15,6 +12,8 @@ typedef enum { FILETYPE_NONE, FILETYPE_OSM, FILETYPE_OSMCHANGE, FILETYPE_PLANETD
typedef enum { ACTION_NONE, ACTION_CREATE, ACTION_MODIFY, ACTION_DELETE } actions_t;
class parse_t;
+class osmdata_t;
+struct reprojection;
class parse_delegate_t
{
diff --git a/pgsql-id-tracker.cpp b/pgsql-id-tracker.cpp
index 890eff6..bcd54af 100644
--- a/pgsql-id-tracker.cpp
+++ b/pgsql-id-tracker.cpp
@@ -1,7 +1,9 @@
#include "pgsql-id-tracker.hpp"
+#include <cassert>
+#include <cstdio>
+#include <limits>
#include <libpq-fe.h>
-#include <string>
#include <boost/format.hpp>
#include "osmtypes.hpp"
diff --git a/pgsql-id-tracker.hpp b/pgsql-id-tracker.hpp
index 1726149..4a140ee 100644
--- a/pgsql-id-tracker.hpp
+++ b/pgsql-id-tracker.hpp
@@ -3,6 +3,9 @@
#include "id-tracker.hpp"
+#include <string>
+#include <boost/smart_ptr/scoped_ptr.hpp>
+
struct pgsql_id_tracker : public id_tracker {
pgsql_id_tracker(const std::string &conninfo,
const std::string &prefix,
diff --git a/pgsql.cpp b/pgsql.cpp
index 9c164b2..847ab8a 100644
--- a/pgsql.cpp
+++ b/pgsql.cpp
@@ -1,11 +1,9 @@
/* Helper functions for the postgresql connections */
#include "pgsql.hpp"
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libpq-fe.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstdarg>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
diff --git a/processor-line.cpp b/processor-line.cpp
index cc540a8..7ac7cd8 100644
--- a/processor-line.cpp
+++ b/processor-line.cpp
@@ -1,7 +1,5 @@
#include "processor-line.hpp"
-#include <boost/format.hpp>
-
processor_line::processor_line(int srid) : geometry_processor(srid, "LINESTRING", interest_way)
{
}
diff --git a/processor-point.cpp b/processor-point.cpp
index bd84f06..4eab45d 100644
--- a/processor-point.cpp
+++ b/processor-point.cpp
@@ -1,22 +1,17 @@
+#include "config.h" // for FIXED_POINT
#include "processor-point.hpp"
#include "util.hpp"
#include <boost/format.hpp>
-processor_point::processor_point(int srid, double scale)
- : geometry_processor(srid, "POINT", interest_node),
- m_scale(scale) {
+processor_point::processor_point(int srid)
+ : geometry_processor(srid, "POINT", interest_node) {
}
processor_point::~processor_point() {
}
geometry_builder::maybe_wkt_t processor_point::process_node(double lat, double lon) {
-#ifdef FIXED_POINT
- // guarantee that we use the same values as in the node cache
- lon = util::fix_to_double(util::double_to_fix(lon, m_scale), m_scale);
- lat = util::fix_to_double(util::double_to_fix(lat, m_scale), m_scale);
-#endif
geometry_builder::maybe_wkt_t wkt(new geometry_builder::wkt_t());
wkt->geom = (boost::format("POINT(%.15g %.15g)") % lon % lat).str();
return wkt;
diff --git a/processor-point.hpp b/processor-point.hpp
index 088ef97..55b9ebd 100644
--- a/processor-point.hpp
+++ b/processor-point.hpp
@@ -4,13 +4,10 @@
#include "geometry-processor.hpp"
struct processor_point : public geometry_processor {
- processor_point(int srid, double scale);
+ processor_point(int srid);
virtual ~processor_point();
geometry_builder::maybe_wkt_t process_node(double lat, double lon);
-
-private:
- double m_scale; // <-- used only when FIXED_POINT is defined, which seems like never?
};
#endif /* PROCESSOR_POINT_HPP */
diff --git a/processor-polygon.cpp b/processor-polygon.cpp
index e91d55f..95b9ff1 100644
--- a/processor-polygon.cpp
+++ b/processor-polygon.cpp
@@ -1,7 +1,5 @@
#include "processor-polygon.hpp"
-#include <boost/format.hpp>
-
processor_polygon::processor_polygon(int srid, bool enable_multi) : geometry_processor(srid, "GEOMETRY", interest_way | interest_relation), enable_multi(enable_multi)
{
}
diff --git a/rb.cpp b/rb.cpp
deleted file mode 100644
index 084e7fd..0000000
--- a/rb.cpp
+++ /dev/null
@@ -1,930 +0,0 @@
-/* Produced by texiweb from libavl.w. */
-
-/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- The author may be contacted at <blp at gnu.org> on the Internet, or
- write to Ben Pfaff, Stanford University, Computer Science Dept., 353
- Serra Mall, Stanford CA 94305, USA.
-*/
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "rb.hpp"
-
-/* Creates and returns a new table
- with comparison function |compare| using parameter |param|
- and memory allocator |allocator|.
- Returns |NULL| if memory allocation failed. */
-struct rb_table *
-rb_create (rb_comparison_func *compare, void *param,
- struct libavl_allocator *allocator)
-{
- struct rb_table *tree;
-
- assert (compare != NULL);
-
- if (allocator == NULL)
- allocator = &rb_allocator_default;
-
- tree = (struct rb_table *)allocator->libavl_malloc (allocator, sizeof *tree);
- if (tree == NULL)
- return NULL;
-
- tree->rb_root = NULL;
- tree->rb_compare = compare;
- tree->rb_param = param;
- tree->rb_alloc = allocator;
- tree->rb_count = 0;
- tree->rb_generation = 0;
-
- return tree;
-}
-
-/* Search |tree| for an item matching |item|, and return it if found.
- Otherwise return |NULL|. */
-void *
-rb_find (const struct rb_table *tree, const void *item)
-{
- const struct rb_node *p;
-
- assert (tree != NULL && item != NULL);
- for (p = tree->rb_root; p != NULL; )
- {
- int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
-
- if (cmp < 0)
- p = p->rb_link[0];
- else if (cmp > 0)
- p = p->rb_link[1];
- else /* |cmp == 0| */
- return p->rb_data;
- }
-
- return NULL;
-}
-
-/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
- If a duplicate item is found in the tree,
- returns a pointer to the duplicate without inserting |item|.
- Returns |NULL| in case of memory allocation failure. */
-void **
-rb_probe (struct rb_table *tree, void *item)
-{
- struct rb_node *pa[RB_MAX_HEIGHT]; /* Nodes on stack. */
- unsigned char da[RB_MAX_HEIGHT]; /* Directions moved from stack nodes. */
- int k; /* Stack height. */
-
- struct rb_node *p; /* Traverses tree looking for insertion point. */
- struct rb_node *n; /* Newly inserted node. */
-
- assert (tree != NULL && item != NULL);
-
- pa[0] = (struct rb_node *) &tree->rb_root;
- da[0] = 0;
- k = 1;
- for (p = tree->rb_root; p != NULL; p = p->rb_link[da[k - 1]])
- {
- int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
- if (cmp == 0)
- return &p->rb_data;
-
- pa[k] = p;
- da[k++] = cmp > 0;
- }
-
- n = pa[k - 1]->rb_link[da[k - 1]] =
- (struct rb_node *)tree->rb_alloc->libavl_malloc (tree->rb_alloc, sizeof *n);
- if (n == NULL)
- return NULL;
-
- n->rb_data = item;
- n->rb_link[0] = n->rb_link[1] = NULL;
- n->rb_color = RB_RED;
- tree->rb_count++;
- tree->rb_generation++;
-
- while (k >= 3 && pa[k - 1]->rb_color == RB_RED)
- {
- if (da[k - 2] == 0)
- {
- struct rb_node *y = pa[k - 2]->rb_link[1];
- if (y != NULL && y->rb_color == RB_RED)
- {
- pa[k - 1]->rb_color = y->rb_color = RB_BLACK;
- pa[k - 2]->rb_color = RB_RED;
- k -= 2;
- }
- else
- {
- struct rb_node *x;
-
- if (da[k - 1] == 0)
- y = pa[k - 1];
- else
- {
- x = pa[k - 1];
- y = x->rb_link[1];
- x->rb_link[1] = y->rb_link[0];
- y->rb_link[0] = x;
- pa[k - 2]->rb_link[0] = y;
- }
-
- x = pa[k - 2];
- x->rb_color = RB_RED;
- y->rb_color = RB_BLACK;
-
- x->rb_link[0] = y->rb_link[1];
- y->rb_link[1] = x;
- pa[k - 3]->rb_link[da[k - 3]] = y;
- break;
- }
- }
- else
- {
- struct rb_node *y = pa[k - 2]->rb_link[0];
- if (y != NULL && y->rb_color == RB_RED)
- {
- pa[k - 1]->rb_color = y->rb_color = RB_BLACK;
- pa[k - 2]->rb_color = RB_RED;
- k -= 2;
- }
- else
- {
- struct rb_node *x;
-
- if (da[k - 1] == 1)
- y = pa[k - 1];
- else
- {
- x = pa[k - 1];
- y = x->rb_link[0];
- x->rb_link[0] = y->rb_link[1];
- y->rb_link[1] = x;
- pa[k - 2]->rb_link[1] = y;
- }
-
- x = pa[k - 2];
- x->rb_color = RB_RED;
- y->rb_color = RB_BLACK;
-
- x->rb_link[1] = y->rb_link[0];
- y->rb_link[0] = x;
- pa[k - 3]->rb_link[da[k - 3]] = y;
- break;
- }
- }
- }
- tree->rb_root->rb_color = RB_BLACK;
-
-
- return &n->rb_data;
-}
-
-/* Inserts |item| into |table|.
- Returns |NULL| if |item| was successfully inserted
- or if a memory allocation error occurred.
- Otherwise, returns the duplicate item. */
-void *
-rb_insert (struct rb_table *table, void *item)
-{
- void **p = rb_probe (table, item);
- return p == NULL || *p == item ? NULL : *p;
-}
-
-/* Inserts |item| into |table|, replacing any duplicate item.
- Returns |NULL| if |item| was inserted without replacing a duplicate,
- or if a memory allocation error occurred.
- Otherwise, returns the item that was replaced. */
-void *
-rb_replace (struct rb_table *table, void *item)
-{
- void **p = rb_probe (table, item);
- if (p == NULL || *p == item)
- return NULL;
- else
- {
- void *r = *p;
- *p = item;
- return r;
- }
-}
-
-/* Deletes from |tree| and returns an item matching |item|.
- Returns a null pointer if no matching item found. */
-void *
-rb_delete (struct rb_table *tree, const void *item)
-{
- struct rb_node *pa[RB_MAX_HEIGHT]; /* Nodes on stack. */
- unsigned char da[RB_MAX_HEIGHT]; /* Directions moved from stack nodes. */
- int k; /* Stack height. */
-
- struct rb_node *p; /* The node to delete, or a node part way to it. */
- int cmp; /* Result of comparison between |item| and |p|. */
-
- assert (tree != NULL && item != NULL);
-
- k = 0;
- p = (struct rb_node *) &tree->rb_root;
- for (cmp = -1; cmp != 0;
- cmp = tree->rb_compare (item, p->rb_data, tree->rb_param))
- {
- int dir = cmp > 0;
-
- pa[k] = p;
- da[k++] = dir;
-
- p = p->rb_link[dir];
- if (p == NULL)
- return NULL;
- }
- item = p->rb_data;
-
- if (p->rb_link[1] == NULL)
- pa[k - 1]->rb_link[da[k - 1]] = p->rb_link[0];
- else
- {
- enum rb_color t;
- struct rb_node *r = p->rb_link[1];
-
- if (r->rb_link[0] == NULL)
- {
- r->rb_link[0] = p->rb_link[0];
- t = r->rb_color;
- r->rb_color = p->rb_color;
- p->rb_color = t;
- pa[k - 1]->rb_link[da[k - 1]] = r;
- da[k] = 1;
- pa[k++] = r;
- }
- else
- {
- struct rb_node *s;
- int j = k++;
-
- for (;;)
- {
- da[k] = 0;
- pa[k++] = r;
- s = r->rb_link[0];
- if (s->rb_link[0] == NULL)
- break;
-
- r = s;
- }
-
- da[j] = 1;
- pa[j] = s;
- pa[j - 1]->rb_link[da[j - 1]] = s;
-
- s->rb_link[0] = p->rb_link[0];
- r->rb_link[0] = s->rb_link[1];
- s->rb_link[1] = p->rb_link[1];
-
- t = s->rb_color;
- s->rb_color = p->rb_color;
- p->rb_color = t;
- }
- }
-
- if (p->rb_color == RB_BLACK)
- {
- for (;;)
- {
- struct rb_node *x = pa[k - 1]->rb_link[da[k - 1]];
- if (x != NULL && x->rb_color == RB_RED)
- {
- x->rb_color = RB_BLACK;
- break;
- }
- if (k < 2)
- break;
-
- if (da[k - 1] == 0)
- {
- struct rb_node *w = pa[k - 1]->rb_link[1];
-
- if (w->rb_color == RB_RED)
- {
- w->rb_color = RB_BLACK;
- pa[k - 1]->rb_color = RB_RED;
-
- pa[k - 1]->rb_link[1] = w->rb_link[0];
- w->rb_link[0] = pa[k - 1];
- pa[k - 2]->rb_link[da[k - 2]] = w;
-
- pa[k] = pa[k - 1];
- da[k] = 0;
- pa[k - 1] = w;
- k++;
-
- w = pa[k - 1]->rb_link[1];
- }
-
- if ((w->rb_link[0] == NULL
- || w->rb_link[0]->rb_color == RB_BLACK)
- && (w->rb_link[1] == NULL
- || w->rb_link[1]->rb_color == RB_BLACK))
- w->rb_color = RB_RED;
- else
- {
- if (w->rb_link[1] == NULL
- || w->rb_link[1]->rb_color == RB_BLACK)
- {
- struct rb_node *y = w->rb_link[0];
- y->rb_color = RB_BLACK;
- w->rb_color = RB_RED;
- w->rb_link[0] = y->rb_link[1];
- y->rb_link[1] = w;
- w = pa[k - 1]->rb_link[1] = y;
- }
-
- w->rb_color = pa[k - 1]->rb_color;
- pa[k - 1]->rb_color = RB_BLACK;
- w->rb_link[1]->rb_color = RB_BLACK;
-
- pa[k - 1]->rb_link[1] = w->rb_link[0];
- w->rb_link[0] = pa[k - 1];
- pa[k - 2]->rb_link[da[k - 2]] = w;
- break;
- }
- }
- else
- {
- struct rb_node *w = pa[k - 1]->rb_link[0];
-
- if (w->rb_color == RB_RED)
- {
- w->rb_color = RB_BLACK;
- pa[k - 1]->rb_color = RB_RED;
-
- pa[k - 1]->rb_link[0] = w->rb_link[1];
- w->rb_link[1] = pa[k - 1];
- pa[k - 2]->rb_link[da[k - 2]] = w;
-
- pa[k] = pa[k - 1];
- da[k] = 1;
- pa[k - 1] = w;
- k++;
-
- w = pa[k - 1]->rb_link[0];
- }
-
- if ((w->rb_link[0] == NULL
- || w->rb_link[0]->rb_color == RB_BLACK)
- && (w->rb_link[1] == NULL
- || w->rb_link[1]->rb_color == RB_BLACK))
- w->rb_color = RB_RED;
- else
- {
- if (w->rb_link[0] == NULL
- || w->rb_link[0]->rb_color == RB_BLACK)
- {
- struct rb_node *y = w->rb_link[1];
- y->rb_color = RB_BLACK;
- w->rb_color = RB_RED;
- w->rb_link[1] = y->rb_link[0];
- y->rb_link[0] = w;
- w = pa[k - 1]->rb_link[0] = y;
- }
-
- w->rb_color = pa[k - 1]->rb_color;
- pa[k - 1]->rb_color = RB_BLACK;
- w->rb_link[0]->rb_color = RB_BLACK;
-
- pa[k - 1]->rb_link[0] = w->rb_link[1];
- w->rb_link[1] = pa[k - 1];
- pa[k - 2]->rb_link[da[k - 2]] = w;
- break;
- }
- }
-
- k--;
- }
-
- }
-
- tree->rb_alloc->libavl_free (tree->rb_alloc, p);
- tree->rb_count--;
- tree->rb_generation++;
- return (void *) item;
-}
-
-/* Refreshes the stack of parent pointers in |trav|
- and updates its generation number. */
-static void
-trav_refresh (struct rb_traverser *trav)
-{
- assert (trav != NULL);
-
- trav->rb_generation = trav->rb_table->rb_generation;
-
- if (trav->rb_node != NULL)
- {
- rb_comparison_func *cmp = trav->rb_table->rb_compare;
- void *param = trav->rb_table->rb_param;
- struct rb_node *node = trav->rb_node;
- struct rb_node *i;
-
- trav->rb_height = 0;
- for (i = trav->rb_table->rb_root; i != node; )
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- assert (i != NULL);
-
- trav->rb_stack[trav->rb_height++] = i;
- i = i->rb_link[cmp (node->rb_data, i->rb_data, param) > 0];
- }
- }
-}
-
-/* Initializes |trav| for use with |tree|
- and selects the null node. */
-void
-rb_t_init (struct rb_traverser *trav, struct rb_table *tree)
-{
- trav->rb_table = tree;
- trav->rb_node = NULL;
- trav->rb_height = 0;
- trav->rb_generation = tree->rb_generation;
-}
-
-/* Initializes |trav| for |tree|
- and selects and returns a pointer to its least-valued item.
- Returns |NULL| if |tree| contains no nodes. */
-void *
-rb_t_first (struct rb_traverser *trav, struct rb_table *tree)
-{
- struct rb_node *x;
-
- assert (tree != NULL && trav != NULL);
-
- trav->rb_table = tree;
- trav->rb_height = 0;
- trav->rb_generation = tree->rb_generation;
-
- x = tree->rb_root;
- if (x != NULL)
- while (x->rb_link[0] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[0];
- }
- trav->rb_node = x;
-
- return x != NULL ? x->rb_data : NULL;
-}
-
-/* Initializes |trav| for |tree|
- and selects and returns a pointer to its greatest-valued item.
- Returns |NULL| if |tree| contains no nodes. */
-void *
-rb_t_last (struct rb_traverser *trav, struct rb_table *tree)
-{
- struct rb_node *x;
-
- assert (tree != NULL && trav != NULL);
-
- trav->rb_table = tree;
- trav->rb_height = 0;
- trav->rb_generation = tree->rb_generation;
-
- x = tree->rb_root;
- if (x != NULL)
- while (x->rb_link[1] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[1];
- }
- trav->rb_node = x;
-
- return x != NULL ? x->rb_data : NULL;
-}
-
-/* Searches for |item| in |tree|.
- If found, initializes |trav| to the item found and returns the item
- as well.
- If there is no matching item, initializes |trav| to the null item
- and returns |NULL|. */
-void *
-rb_t_find (struct rb_traverser *trav, struct rb_table *tree, void *item)
-{
- struct rb_node *p, *q;
-
- assert (trav != NULL && tree != NULL && item != NULL);
- trav->rb_table = tree;
- trav->rb_height = 0;
- trav->rb_generation = tree->rb_generation;
- for (p = tree->rb_root; p != NULL; p = q)
- {
- int cmp = tree->rb_compare (item, p->rb_data, tree->rb_param);
-
- if (cmp < 0)
- q = p->rb_link[0];
- else if (cmp > 0)
- q = p->rb_link[1];
- else /* |cmp == 0| */
- {
- trav->rb_node = p;
- return p->rb_data;
- }
-
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = p;
- }
-
- trav->rb_height = 0;
- trav->rb_node = NULL;
- return NULL;
-}
-
-/* Attempts to insert |item| into |tree|.
- If |item| is inserted successfully, it is returned and |trav| is
- initialized to its location.
- If a duplicate is found, it is returned and |trav| is initialized to
- its location. No replacement of the item occurs.
- If a memory allocation failure occurs, |NULL| is returned and |trav|
- is initialized to the null item. */
-void *
-rb_t_insert (struct rb_traverser *trav, struct rb_table *tree, void *item)
-{
- void **p;
-
- assert (trav != NULL && tree != NULL && item != NULL);
-
- p = rb_probe (tree, item);
- if (p != NULL)
- {
- trav->rb_table = tree;
- trav->rb_node =
- ((struct rb_node *)
- ((char *) p - offsetof (struct rb_node, rb_data)));
- trav->rb_generation = tree->rb_generation - 1;
- return *p;
- }
- else
- {
- rb_t_init (trav, tree);
- return NULL;
- }
-}
-
-/* Initializes |trav| to have the same current node as |src|. */
-void *
-rb_t_copy (struct rb_traverser *trav, const struct rb_traverser *src)
-{
- assert (trav != NULL && src != NULL);
-
- if (trav != src)
- {
- trav->rb_table = src->rb_table;
- trav->rb_node = src->rb_node;
- trav->rb_generation = src->rb_generation;
- if (trav->rb_generation == trav->rb_table->rb_generation)
- {
- trav->rb_height = src->rb_height;
- memcpy (trav->rb_stack, (const void *) src->rb_stack,
- sizeof *trav->rb_stack * trav->rb_height);
- }
- }
-
- return trav->rb_node != NULL ? trav->rb_node->rb_data : NULL;
-}
-
-/* Returns the next data item in inorder
- within the tree being traversed with |trav|,
- or if there are no more data items returns |NULL|. */
-void *
-rb_t_next (struct rb_traverser *trav)
-{
- struct rb_node *x;
-
- assert (trav != NULL);
-
- if (trav->rb_generation != trav->rb_table->rb_generation)
- trav_refresh (trav);
-
- x = trav->rb_node;
- if (x == NULL)
- {
- return rb_t_first (trav, trav->rb_table);
- }
- else if (x->rb_link[1] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[1];
-
- while (x->rb_link[0] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[0];
- }
- }
- else
- {
- struct rb_node *y;
-
- do
- {
- if (trav->rb_height == 0)
- {
- trav->rb_node = NULL;
- return NULL;
- }
-
- y = x;
- x = trav->rb_stack[--trav->rb_height];
- }
- while (y == x->rb_link[1]);
- }
- trav->rb_node = x;
-
- return x->rb_data;
-}
-
-/* Returns the previous data item in inorder
- within the tree being traversed with |trav|,
- or if there are no more data items returns |NULL|. */
-void *
-rb_t_prev (struct rb_traverser *trav)
-{
- struct rb_node *x;
-
- assert (trav != NULL);
-
- if (trav->rb_generation != trav->rb_table->rb_generation)
- trav_refresh (trav);
-
- x = trav->rb_node;
- if (x == NULL)
- {
- return rb_t_last (trav, trav->rb_table);
- }
- else if (x->rb_link[0] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[0];
-
- while (x->rb_link[1] != NULL)
- {
- assert (trav->rb_height < RB_MAX_HEIGHT);
- trav->rb_stack[trav->rb_height++] = x;
- x = x->rb_link[1];
- }
- }
- else
- {
- struct rb_node *y;
-
- do
- {
- if (trav->rb_height == 0)
- {
- trav->rb_node = NULL;
- return NULL;
- }
-
- y = x;
- x = trav->rb_stack[--trav->rb_height];
- }
- while (y == x->rb_link[0]);
- }
- trav->rb_node = x;
-
- return x->rb_data;
-}
-
-/* Returns |trav|'s current item. */
-void *
-rb_t_cur (struct rb_traverser *trav)
-{
- assert (trav != NULL);
-
- return trav->rb_node != NULL ? trav->rb_node->rb_data : NULL;
-}
-
-/* Replaces the current item in |trav| by |new| and returns the item replaced.
- |trav| must not have the null item selected.
- The new item must not upset the ordering of the tree. */
-void *
-rb_t_replace (struct rb_traverser *trav, void *new_)
-{
- void *old;
-
- assert (trav != NULL && trav->rb_node != NULL && new_ != NULL);
- old = trav->rb_node->rb_data;
- trav->rb_node->rb_data = new_;
- return old;
-}
-
-/* Destroys |new| with |rb_destroy (new, destroy)|,
- first setting right links of nodes in |stack| within |new|
- to null pointers to avoid touching uninitialized data. */
-static void
-copy_error_recovery (struct rb_node **stack, int height,
- struct rb_table *new_, rb_item_func *destroy)
-{
- assert (stack != NULL && height >= 0 && new_ != NULL);
-
- for (; height > 2; height -= 2)
- stack[height - 1]->rb_link[1] = NULL;
- rb_destroy (new_, destroy);
-}
-
-/* Copies |org| to a newly created tree, which is returned.
- If |copy != NULL|, each data item in |org| is first passed to |copy|,
- and the return values are inserted into the tree,
- with |NULL| return values taken as indications of failure.
- On failure, destroys the partially created new tree,
- applying |destroy|, if non-null, to each item in the new tree so far,
- and returns |NULL|.
- If |allocator != NULL|, it is used for allocation in the new tree.
- Otherwise, the same allocator used for |org| is used. */
-struct rb_table *
-rb_copy (const struct rb_table *org, rb_copy_func *copy,
- rb_item_func *destroy, struct libavl_allocator *allocator)
-{
- struct rb_node *stack[2 * (RB_MAX_HEIGHT + 1)];
- int height = 0;
-
- struct rb_table *new_;
- const struct rb_node *x;
- struct rb_node *y;
-
- assert (org != NULL);
- new_ = rb_create (org->rb_compare, org->rb_param,
- allocator != NULL ? allocator : org->rb_alloc);
- if (new_ == NULL)
- return NULL;
- new_->rb_count = org->rb_count;
- if (new_->rb_count == 0)
- return new_;
-
- x = (const struct rb_node *) &org->rb_root;
- y = (struct rb_node *) &new_->rb_root;
- for (;;)
- {
- while (x->rb_link[0] != NULL)
- {
- assert (height < 2 * (RB_MAX_HEIGHT + 1));
-
- y->rb_link[0] =
- (struct rb_node *)
- new_->rb_alloc->libavl_malloc (new_->rb_alloc,
- sizeof *y->rb_link[0]);
- if (y->rb_link[0] == NULL)
- {
- if (y != (struct rb_node *) &new_->rb_root)
- {
- y->rb_data = NULL;
- y->rb_link[1] = NULL;
- }
-
- copy_error_recovery (stack, height, new_, destroy);
- return NULL;
- }
-
- stack[height++] = (struct rb_node *) x;
- stack[height++] = y;
- x = x->rb_link[0];
- y = y->rb_link[0];
- }
- y->rb_link[0] = NULL;
-
- for (;;)
- {
- y->rb_color = x->rb_color;
- if (copy == NULL)
- y->rb_data = x->rb_data;
- else
- {
- y->rb_data = copy (x->rb_data, org->rb_param);
- if (y->rb_data == NULL)
- {
- y->rb_link[1] = NULL;
- copy_error_recovery (stack, height, new_, destroy);
- return NULL;
- }
- }
-
- if (x->rb_link[1] != NULL)
- {
- y->rb_link[1] =
- (struct rb_node *)
- new_->rb_alloc->libavl_malloc (new_->rb_alloc,
- sizeof *y->rb_link[1]);
- if (y->rb_link[1] == NULL)
- {
- copy_error_recovery (stack, height, new_, destroy);
- return NULL;
- }
-
- x = x->rb_link[1];
- y = y->rb_link[1];
- break;
- }
- else
- y->rb_link[1] = NULL;
-
- if (height <= 2)
- return new_;
-
- y = stack[--height];
- x = stack[--height];
- }
- }
-}
-
-/* Frees storage allocated for |tree|.
- If |destroy != NULL|, applies it to each data item in inorder. */
-void
-rb_destroy (struct rb_table *tree, rb_item_func *destroy)
-{
- struct rb_node *p, *q;
-
- assert (tree != NULL);
-
- for (p = tree->rb_root; p != NULL; p = q)
- if (p->rb_link[0] == NULL)
- {
- q = p->rb_link[1];
- if (destroy != NULL && p->rb_data != NULL)
- destroy (p->rb_data, tree->rb_param);
- tree->rb_alloc->libavl_free (tree->rb_alloc, p);
- }
- else
- {
- q = p->rb_link[0];
- p->rb_link[0] = q->rb_link[1];
- q->rb_link[1] = p;
- }
-
- tree->rb_alloc->libavl_free (tree->rb_alloc, tree);
-}
-
-/* Allocates |size| bytes of space using |malloc()|.
- Returns a null pointer if allocation fails. */
-void *
-rb_malloc (struct libavl_allocator *allocator, size_t size)
-{
- assert (allocator != NULL && size > 0);
- return malloc (size);
-}
-
-/* Frees |block|. */
-void
-rb_free (struct libavl_allocator *allocator, void *block)
-{
- assert (allocator != NULL && block != NULL);
- free (block);
-}
-
-/* Default memory allocator that uses |malloc()| and |free()|. */
-struct libavl_allocator rb_allocator_default =
- {
- rb_malloc,
- rb_free
- };
-
-#undef NDEBUG
-#include <assert.h>
-
-/* Asserts that |rb_insert()| succeeds at inserting |item| into |table|. */
-void
-(rb_assert_insert) (struct rb_table *table, void *item)
-{
- void **p = rb_probe (table, item);
- assert (p != NULL && *p == item);
-}
-
-/* Asserts that |rb_delete()| really removes |item| from |table|,
- and returns the removed item. */
-void *
-(rb_assert_delete) (struct rb_table *table, void *item)
-{
- void *p = rb_delete (table, item);
- assert (p != NULL);
- return p;
-}
diff --git a/rb.hpp b/rb.hpp
deleted file mode 100644
index b16feab..0000000
--- a/rb.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Produced by texiweb from libavl.w. */
-
-/* libavl - library for manipulation of binary trees.
- Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-
- The author may be contacted at <blp at gnu.org> on the Internet, or
- write to Ben Pfaff, Stanford University, Computer Science Dept., 353
- Serra Mall, Stanford CA 94305, USA.
-*/
-
-#ifndef RB_H
-#define RB_H 1
-
-#include <stddef.h>
-
-/* Function types. */
-typedef int rb_comparison_func (const void *rb_a, const void *rb_b,
- void *rb_param);
-typedef void rb_item_func (void *rb_item, void *rb_param);
-typedef void *rb_copy_func (void *rb_item, void *rb_param);
-
-#ifndef LIBAVL_ALLOCATOR
-#define LIBAVL_ALLOCATOR
-/* Memory allocator. */
-struct libavl_allocator
- {
- void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
- void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
- };
-#endif
-
-/* Default memory allocator. */
-extern struct libavl_allocator rb_allocator_default;
-void *rb_malloc (struct libavl_allocator *, size_t);
-void rb_free (struct libavl_allocator *, void *);
-
-/* Maximum RB height. */
-#ifndef RB_MAX_HEIGHT
-#define RB_MAX_HEIGHT 48
-#endif
-
-/* Tree data structure. */
-struct rb_table
- {
- struct rb_node *rb_root; /* Tree's root. */
- rb_comparison_func *rb_compare; /* Comparison function. */
- void *rb_param; /* Extra argument to |rb_compare|. */
- struct libavl_allocator *rb_alloc; /* Memory allocator. */
- size_t rb_count; /* Number of items in tree. */
- unsigned long rb_generation; /* Generation number. */
- };
-
-/* Color of a red-black node. */
-enum rb_color
- {
- RB_BLACK, /* Black. */
- RB_RED /* Red. */
- };
-
-/* A red-black tree node. */
-struct rb_node
- {
- struct rb_node *rb_link[2]; /* Subtrees. */
- void *rb_data; /* Pointer to data. */
- enum rb_color rb_color; /* Color. */
- };
-
-/* RB traverser structure. */
-struct rb_traverser
- {
- struct rb_table *rb_table; /* Tree being traversed. */
- struct rb_node *rb_node; /* Current node in tree. */
- struct rb_node *rb_stack[RB_MAX_HEIGHT];
- /* All the nodes above |rb_node|. */
- size_t rb_height; /* Number of nodes in |rb_parent|. */
- unsigned long rb_generation; /* Generation number. */
- };
-
-/* Table functions. */
-struct rb_table *rb_create (rb_comparison_func *, void *,
- struct libavl_allocator *);
-struct rb_table *rb_copy (const struct rb_table *, rb_copy_func *,
- rb_item_func *, struct libavl_allocator *);
-void rb_destroy (struct rb_table *, rb_item_func *);
-void **rb_probe (struct rb_table *, void *);
-void *rb_insert (struct rb_table *, void *);
-void *rb_replace (struct rb_table *, void *);
-void *rb_delete (struct rb_table *, const void *);
-void *rb_find (const struct rb_table *, const void *);
-void rb_assert_insert (struct rb_table *, void *);
-void *rb_assert_delete (struct rb_table *, void *);
-
-#define rb_count(table) ((size_t) (table)->rb_count)
-
-/* Table traverser functions. */
-void rb_t_init (struct rb_traverser *, struct rb_table *);
-void *rb_t_first (struct rb_traverser *, struct rb_table *);
-void *rb_t_last (struct rb_traverser *, struct rb_table *);
-void *rb_t_find (struct rb_traverser *, struct rb_table *, void *);
-void *rb_t_insert (struct rb_traverser *, struct rb_table *, void *);
-void *rb_t_copy (struct rb_traverser *, const struct rb_traverser *);
-void *rb_t_next (struct rb_traverser *);
-void *rb_t_prev (struct rb_traverser *);
-void *rb_t_cur (struct rb_traverser *);
-void *rb_t_replace (struct rb_traverser *, void *);
-
-#endif /* rb.h */
diff --git a/reprojection.cpp b/reprojection.cpp
index a2a7ebb..276f61d 100644
--- a/reprojection.cpp
+++ b/reprojection.cpp
@@ -7,11 +7,11 @@
#include "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
#include <proj_api.h>
-#include <math.h>
+#include <cmath>
#include "reprojection.hpp"
@@ -34,11 +34,6 @@ const struct Projection_Info Projection_Infos[] = {
/*proj4text*/ "+init=epsg:4326",
/*srs */ 4326,
/*option */ "-l" ),
- /*PROJ_MERC*/ Projection_Info(
- /*descr */ "WGS84 Mercator",
- /*proj4text*/ "+proj=merc +datum=WGS84 +k=1/*0 +units=m +over +no_defs",
- /*srs */ 3395,
- /*option */ "-M" ),
/*PROJ_SPHERE_MERC*/ Projection_Info(
/*descr */ "Spherical Mercator",
/*proj4text*/ "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs",
diff --git a/reprojection.hpp b/reprojection.hpp
index 0d9a03c..91093de 100644
--- a/reprojection.hpp
+++ b/reprojection.hpp
@@ -19,7 +19,7 @@ struct Projection_Info {
const char *option;
};
-enum Projection { PROJ_LATLONG = 0, PROJ_MERC, PROJ_SPHERE_MERC, PROJ_COUNT };
+enum Projection { PROJ_LATLONG = 0, PROJ_SPHERE_MERC, PROJ_COUNT };
struct reprojection : public boost::noncopyable
{
diff --git a/sanitizer.hpp b/sanitizer.hpp
index beb24a4..82ad083 100644
--- a/sanitizer.hpp
+++ b/sanitizer.hpp
@@ -1,7 +1,6 @@
#ifndef SANITIZER_H
#define SANITIZER_H
-#include <libxml/xmlstring.h>
#include <libxml/xmlreader.h>
xmlTextReaderPtr sanitizerOpen(const char *name);
diff --git a/style.lua b/style.lua
index c0a646e..c42c689 100644
--- a/style.lua
+++ b/style.lua
@@ -1,8 +1,12 @@
+-- For documentation of Lua tag transformations, see docs/lua.md.
+
+-- Objects with any of the following keys will be treated as polygon
polygon_keys = { 'building', 'landuse', 'amenity', 'harbour', 'historic', 'leisure',
'man_made', 'military', 'natural', 'office', 'place', 'power',
'public_transport', 'shop', 'sport', 'tourism', 'waterway',
'wetland', 'water', 'aeroway' }
+-- Objects without any of the following keys will be deleted
generic_keys = {'access','addr:housename','addr:housenumber','addr:interpolation','admin_level','aerialway','aeroway','amenity','area','barrier',
'bicycle','brand','bridge','boundary','building','capital','construction','covered','culvert','cutting','denomination','disused','ele',
'embarkment','foot','generation:source','harbour','highway','historic','hours','intermittent','junction','landuse','layer','leisure','lock',
@@ -10,26 +14,37 @@ generic_keys = {'access','addr:housename','addr:housenumber','addr:interpolation
'railway','ref','religion','route','service','shop','sport','surface','toll','tourism','tower:type', 'tracktype','tunnel','water','waterway',
'wetland','width','wood','type'}
+-- The following keys will be deleted
+delete_tags = { 'FIXME', 'note', 'source' }
+
+-- Array used to specify z_order per key/value combination.
+-- Each element has the form {key, value, z_order, is_road}.
+-- If is_road=1, the object will be added to planet_osm_roads.
+zordering_tags = {{ 'railway', nil, 5, 1}, { 'boundary', 'administrative', 0, 1},
+ { 'bridge', 'yes', 10, 0 }, { 'bridge', 'true', 10, 0 }, { 'bridge', 1, 10, 0 },
+ { 'tunnel', 'yes', -10, 0}, { 'tunnel', 'true', -10, 0}, { 'tunnel', 1, -10, 0},
+ { 'highway', 'minor', 3, 0}, { 'highway', 'road', 3, 0 }, { 'highway', 'unclassified', 3, 0 },
+ { 'highway', 'residential', 3, 0 }, { 'highway', 'tertiary_link', 4, 0}, { 'highway', 'tertiary', 4, 0},
+ { 'highway', 'secondary_link', 6, 1}, { 'highway', 'secondary', 6, 1},
+ { 'highway', 'primary_link', 7, 1}, { 'highway', 'primary', 7, 1},
+ { 'highway', 'trunk_link', 8, 1}, { 'highway', 'trunk', 8, 1},
+ { 'highway', 'motorway_link', 9, 1}, { 'highway', 'motorway', 9, 1},
+}
+
function add_z_order(keyvalues)
+ -- The default z_order is 0
z_order = 0
+
+ -- Add the value of the layer key times 10 to z_order
if (keyvalues["layer"] ~= nil and tonumber(keyvalues["layer"])) then
z_order = 10*keyvalues["layer"]
end
-
- zordering_tags = {{ 'railway', nil, 5, 1}, { 'boundary', 'administrative', 0, 1},
- { 'bridge', 'yes', 10, 0 }, { 'bridge', 'true', 10, 0 }, { 'bridge', 1, 10, 0 },
- { 'tunnel', 'yes', -10, 0}, { 'tunnel', 'true', -10, 0}, { 'tunnel', 1, -10, 0},
- { 'highway', 'minor', 3, 0}, { 'highway', 'road', 3, 0 }, { 'highway', 'unclassified', 3, 0 },
- { 'highway', 'residential', 3, 0 }, { 'highway', 'tertiary_link', 4, 0}, { 'highway', 'tertiary', 4, 0},
- { 'highway', 'secondary_link', 6, 1}, { 'highway', 'secondary', 6, 1},
- { 'highway', 'primary_link', 7, 1}, { 'highway', 'primary', 7, 1},
- { 'highway', 'trunk_link', 8, 1}, { 'highway', 'trunk', 8, 1},
- { 'highway', 'motorway_link', 9, 1}, { 'highway', 'motorway', 9, 1},
-}
-
+ -- Increase or decrease z_order based on the specific key/value combination as specified in zordering_tags
for i,k in ipairs(zordering_tags) do
+ -- If the value in zordering_tags is specified, match key and value. Otherwise, match key only.
if ((k[2] and keyvalues[k[1]] == k[2]) or (k[2] == nil and keyvalues[k[1]] ~= nil)) then
+ -- If the fourth component of the element of zordering_tags is 1, add the object to planet_osm_roads
if (k[4] == 1) then
roads = 1
end
@@ -37,27 +52,29 @@ function add_z_order(keyvalues)
end
end
+ -- Add z_order as key/value combination
keyvalues["z_order"] = z_order
return keyvalues, roads
-
end
-function filter_tags_generic(keyvalues, nokeys)
- filter = 0
- tagcount = 0
+-- Filtering on nodes, ways, and relations
+function filter_tags_generic(keyvalues, numberofkeys)
+ filter = 0 -- Will object be filtered out?
- if nokeys == 0 then
+ -- Filter out objects with 0 tags
+ if numberofkeys == 0 then
filter = 1
return filter, keyvalues
end
- delete_tags = { 'FIXME', 'note', 'source' }
-
+ -- Delete tags listed in delete_tags
for i,k in ipairs(delete_tags) do
keyvalues[k] = nil
end
+ -- Filter out objects that do not have any of the keys in generic_keys
+ tagcount = 0
for k,v in pairs(keyvalues) do
for i, k2 in ipairs(generic_keys) do if k2 == k then tagcount = tagcount + 1; end end
end
@@ -68,17 +85,20 @@ function filter_tags_generic(keyvalues, nokeys)
return filter, keyvalues
end
-function filter_tags_node (keyvalues, nokeys)
- return filter_tags_generic(keyvalues, nokeys)
+-- Filtering on nodes
+function filter_tags_node (keyvalues, numberofkeys)
+ return filter_tags_generic(keyvalues, numberofkeys)
end
-function filter_basic_tags_rel (keyvalues, nokeys)
-
- filter, keyvalues = filter_tags_generic(keyvalues, nokeys)
+-- Filtering on relations
+function filter_basic_tags_rel (keyvalues, numberofkeys)
+ -- Filter out objects that are filtered out by filter_tags_generic
+ filter, keyvalues = filter_tags_generic(keyvalues, numberofkeys)
if filter == 1 then
return filter, keyvalues
end
+ -- Filter out all relations except route, multipolygon and boundary relations
if ((keyvalues["type"] ~= "route") and (keyvalues["type"] ~= "multipolygon") and (keyvalues["type"] ~= "boundary")) then
filter = 1
return filter, keyvalues
@@ -87,66 +107,74 @@ function filter_basic_tags_rel (keyvalues, nokeys)
return filter, keyvalues
end
-function filter_tags_way (keyvalues, nokeys)
- filter = 0
- poly = 0
- tagcount = 0
- roads = 0
+-- Filtering on ways
+function filter_tags_way (keyvalues, numberofkeys)
+ filter = 0 -- Will object be filtered out?
+ polygon = 0 -- Will object be treated as polygon?
+ roads = 0 -- Will object be added to planet_osm_roads?
- filter, keyvalues = filter_tags_generic(keyvalues, nokeys)
+ -- Filter out objects that are filtered out by filter_tags_generic
+ filter, keyvalues = filter_tags_generic(keyvalues, numberofkeys)
if filter == 1 then
- return filter, keyvalues, poly, roads
+ return filter, keyvalues, polygon, roads
end
-
+ -- Treat objects with a key in polygon_keys as polygon
for i,k in ipairs(polygon_keys) do
if keyvalues[k] then
- poly=1
+ polygon=1
break
end
end
-
+ -- Treat objects tagged as area=yes, area=1, or area=true as polygon,
+ -- and treat objects tagged as area=no, area=0, or area=false not as polygon
if ((keyvalues["area"] == "yes") or (keyvalues["area"] == "1") or (keyvalues["area"] == "true")) then
- poly = 1;
+ polygon = 1;
elseif ((keyvalues["area"] == "no") or (keyvalues["area"] == "0") or (keyvalues["area"] == "false")) then
- poly = 0;
+ polygon = 0;
end
+ -- Add z_order key/value combination and determine if the object should also be added to planet_osm_roads
keyvalues, roads = add_z_order(keyvalues)
-
- return filter, keyvalues, poly, roads
+ return filter, keyvalues, polygon, roads
end
function filter_tags_relation_member (keyvalues, keyvaluemembers, roles, membercount)
-
- filter = 0
- boundary = 0
- polygon = 0
- roads = 0
- membersuperseeded = {}
+ filter = 0 -- Will object be filtered out?
+ linestring = 0 -- Will object be treated as linestring?
+ polygon = 0 -- Will object be treated as polygon?
+ roads = 0 -- Will object be added to planet_osm_roads?
+ membersuperseded = {}
for i = 1, membercount do
- membersuperseeded[i] = 0
+ membersuperseded[i] = 0 -- Will member be ignored when handling areas?
end
type = keyvalues["type"]
+
+ -- Remove type key
keyvalues["type"] = nil
-
+ -- Relations with type=boundary are treated as linestring
if (type == "boundary") then
- boundary = 1
+ linestring = 1
end
+ -- Relations with type=multipolygon and boundary=* are treated as linestring
if ((type == "multipolygon") and keyvalues["boundary"]) then
- boundary = 1
+ linestring = 1
+ -- For multipolygons...
elseif (type == "multipolygon") then
+ -- Treat as polygon
polygon = 1
polytagcount = 0;
+ -- Count the number of polygon tags of the object
for i,k in ipairs(polygon_keys) do
if keyvalues[k] then
polytagcount = polytagcount + 1
end
end
+ -- If there are no polygon tags, add tags from all outer elements to the multipolygon itself
if (polytagcount == 0) then
for i = 1,membercount do
if (roles[i] == "outer") then
@@ -156,23 +184,28 @@ function filter_tags_relation_member (keyvalues, keyvaluemembers, roles, memberc
end
end
end
+ -- For any member of the multipolygon, set membersuperseded to 1 (i.e. don't deal with it as area as well),
+ -- except when the member has a key/value combination such that
+ -- 1) the key occurs in generic_keys
+ -- 2) the key/value combination is not also a key/value combination of the multipolygon itself
for i = 1,membercount do
- superseeded = 1
+ superseded = 1
for k,v in pairs(keyvaluemembers[i]) do
if ((keyvalues[k] == nil) or (keyvalues[k] ~= v)) then
for j,k2 in ipairs(generic_keys) do
if (k == k2) then
- superseeded = 0;
+ superseded = 0;
break
end
end
end
end
- membersuperseeded[i] = superseeded
+ membersuperseded[i] = superseded
end
end
+ -- Add z_order key/value combination and determine if the object should also be added to planet_osm_roads
keyvalues, roads = add_z_order(keyvalues)
- return filter, keyvalues, membersuperseeded, boundary, polygon, roads
+ return filter, keyvalues, membersuperseded, linestring, polygon, roads
end
diff --git a/table.cpp b/table.cpp
index 84cd7e9..8c7a882 100644
--- a/table.cpp
+++ b/table.cpp
@@ -2,18 +2,23 @@
#include "options.hpp"
#include "util.hpp"
-#include <string.h>
+#include <exception>
+#include <algorithm>
+#include <cstring>
+#include <cstdio>
#include <utility>
+#include <time.h>
using std::string;
+typedef boost::format fmt;
#define BUFFER_SEND_SIZE 1024
table_t::table_t(const string& conninfo, const string& name, const string& type, const columns_t& columns, const hstores_t& hstore_columns,
- const int srid, const int scale, const bool append, const bool slim, const bool drop_temp, const int hstore_mode,
+ const int srid, const bool append, const bool slim, const bool drop_temp, const int hstore_mode,
const bool enable_hstore_index, const boost::optional<string>& table_space, const boost::optional<string>& table_space_index) :
- conninfo(conninfo), name(name), type(type), sql_conn(NULL), copyMode(false), srid((fmt("%1%") % srid).str()), scale(scale),
+ conninfo(conninfo), name(name), type(type), sql_conn(NULL), copyMode(false), srid((fmt("%1%") % srid).str()),
append(append), slim(slim), drop_temp(drop_temp), hstore_mode(hstore_mode), enable_hstore_index(enable_hstore_index),
columns(columns), hstore_columns(hstore_columns), table_space(table_space), table_space_index(table_space_index)
{
@@ -31,7 +36,7 @@ table_t::table_t(const string& conninfo, const string& name, const string& type,
}
table_t::table_t(const table_t& other):
- conninfo(other.conninfo), name(other.name), type(other.type), sql_conn(NULL), copyMode(false), buffer(), srid(other.srid), scale(other.scale),
+ conninfo(other.conninfo), name(other.name), type(other.type), sql_conn(NULL), copyMode(false), buffer(), srid(other.srid),
append(other.append), slim(other.slim), drop_temp(other.drop_temp), hstore_mode(other.hstore_mode), enable_hstore_index(other.enable_hstore_index),
columns(other.columns), hstore_columns(other.hstore_columns), copystr(other.copystr), table_space(other.table_space),
table_space_index(other.table_space_index), single_fmt(other.single_fmt), point_fmt(other.point_fmt), del_fmt(other.del_fmt)
@@ -295,12 +300,6 @@ void table_t::stop_copy()
void table_t::write_node(const osmid_t id, const taglist_t &tags, double lat, double lon)
{
-#ifdef FIXED_POINT
- // guarantee that we use the same values as in the node cache
- lon = util::fix_to_double(util::double_to_fix(lon, scale), scale);
- lat = util::fix_to_double(util::double_to_fix(lat, scale), scale);
-#endif
-
write_wkt(id, tags, (point_fmt % lon % lat).str().c_str());
}
diff --git a/table.hpp b/table.hpp
index c51970c..91e41ce 100644
--- a/table.hpp
+++ b/table.hpp
@@ -4,21 +4,23 @@
#include "pgsql.hpp"
#include "osmtypes.hpp"
+#include <cstddef>
#include <string>
#include <vector>
+#include <utility>
#include <boost/optional.hpp>
#include <boost/format.hpp>
+#include <boost/shared_ptr.hpp>
typedef std::vector<std::string> hstores_t;
typedef std::vector<std::pair<std::string, std::string> > columns_t;
-typedef boost::format fmt;
class table_t
{
public:
table_t(const std::string& conninfo, const std::string& name, const std::string& type, const columns_t& columns, const hstores_t& hstore_columns, const int srid,
- const int scale, const bool append, const bool slim, const bool droptemp, const int hstore_mode, const bool enable_hstore_index,
+ const bool append, const bool slim, const bool droptemp, const int hstore_mode, const bool enable_hstore_index,
const boost::optional<std::string>& table_space, const boost::optional<std::string>& table_space_index);
table_t(const table_t& other);
~table_t();
@@ -72,7 +74,6 @@ class table_t
bool copyMode;
std::string buffer;
std::string srid;
- int scale;
bool append;
bool slim;
bool drop_temp;
@@ -84,7 +85,7 @@ class table_t
boost::optional<std::string> table_space;
boost::optional<std::string> table_space_index;
- fmt single_fmt, point_fmt, del_fmt;
+ boost::format single_fmt, point_fmt, del_fmt;
};
#endif
diff --git a/tagtransform.cpp b/tagtransform.cpp
index 45bee84..208b33c 100644
--- a/tagtransform.cpp
+++ b/tagtransform.cpp
@@ -1,16 +1,24 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <stdexcept>
-#include "osmtypes.hpp"
+#include <vector>
+#include <boost/format.hpp>
+
#include "tagtransform.hpp"
-#include "output-pgsql.hpp"
#include "options.hpp"
#include "config.h"
#include "wildcmp.hpp"
#include "taginfo_impl.hpp"
+#ifdef HAVE_LUA
+extern "C" {
+ #include <lualib.h>
+ #include <lauxlib.h>
+}
+#endif
+
static const struct {
int offset;
diff --git a/tagtransform.hpp b/tagtransform.hpp
index a64b688..00547ac 100644
--- a/tagtransform.hpp
+++ b/tagtransform.hpp
@@ -2,14 +2,17 @@
#ifndef TAGTRANSFORM_H
#define TAGTRANSFORM_H
-#include "output.hpp"
-#include "taginfo.hpp"
+#include "config.h"
+#include "osmtypes.hpp"
+
+#include <string>
+
+struct options_t;
+struct export_list;
#ifdef HAVE_LUA
extern "C" {
- #include <lua.h>
- #include <lualib.h>
- #include <lauxlib.h>
+ #include <lua.h>
}
#endif
diff --git a/tests/middle-tests.cpp b/tests/middle-tests.cpp
index 0e20623..e6df830 100644
--- a/tests/middle-tests.cpp
+++ b/tests/middle-tests.cpp
@@ -4,46 +4,135 @@
#include <string.h>
#include <cassert>
#include <list>
+#include <tuple>
#include "osmtypes.hpp"
#include "tests/middle-tests.hpp"
+#define BLOCK_SHIFT 10
+#define PER_BLOCK (((osmid_t)1) << BLOCK_SHIFT)
+
+struct expected_node {
+ osmid_t id;
+ double lon;
+ double lat;
+
+ expected_node() : id(0), lon(NAN), lat(NAN) {}
+
+ expected_node(osmid_t id, double x, double y) : id(id), lon(x), lat(y) {}
+};
+
+typedef std::vector<expected_node> expected_nodelist_t;
+
+#define ALLOWED_ERROR 10e-9
+bool node_okay(osmNode node, expected_node expected) {
+ if ((node.lat > expected.lat + ALLOWED_ERROR) || (node.lat < expected.lat - ALLOWED_ERROR)) {
+ std::cerr << "ERROR: Node should have lat=" << expected.lat << ", but got back "
+ << node.lat << " from middle.\n";
+ return false;
+ }
+ if ((node.lon > expected.lon + ALLOWED_ERROR) || (node.lon < expected.lon - ALLOWED_ERROR)) {
+ std::cerr << "ERROR: Node should have lon=" << expected.lon << ", but got back "
+ << node.lon << " from middle.\n";
+ return false;
+ }
+ return true;
+}
+
int test_node_set(middle_t *mid)
{
idlist_t ids;
- osmid_t id = 1234;
- double lat = 12.3456789;
- double lon = 98.7654321;
+ expected_node expected(1234, 12.3456789, 98.7654321);
taglist_t tags;
nodelist_t nodes;
- int status = 0;
// set the node
- status = mid->nodes_set(id, lat, lon, tags);
- if (status != 0) { std::cerr << "ERROR: Unable to set node.\n"; return 1; }
+ if (mid->nodes_set(expected.id, expected.lat, expected.lon, tags) != 0) { std::cerr << "ERROR: Unable to set node.\n"; return 1; }
// get it back
- ids.push_back(id);
- int count = mid->nodes_get_list(nodes, ids);
- if (count != 1) { std::cerr << "ERROR: Unable to get node list.\n"; return 1; }
+ ids.push_back(expected.id);
+ if (mid->nodes_get_list(nodes, ids) != ids.size()) { std::cerr << "ERROR: Unable to get node list.\n"; return 1; }
+ if (nodes.size() != ids.size()) { std::cerr << "ERROR: Mismatch in returned node list size.\n"; return 1; }
// check that it's the same
- if (nodes[0].lon != lon) {
- std::cerr << "ERROR: Node should have lon=" << lon << ", but got back "
- << nodes[0].lon << " from middle.\n";
+ if (!node_okay(nodes[0], expected)) {
return 1;
}
- if (nodes[0].lat != lat) {
- std::cerr << "ERROR: Node should have lat=" << lat << ", but got back "
- << nodes[0].lat << " from middle.\n";
- return 1;
+
+ return 0;
+}
+
+inline double test_lat(osmid_t id) {
+ return 1 + 1e-5 * id;
+}
+
+int test_nodes_comprehensive_set(middle_t *mid)
+{
+ taglist_t tags;
+
+ expected_nodelist_t expected_nodes;
+ expected_nodes.reserve(PER_BLOCK*8+1);
+
+ // 2 dense blocks, the second partially filled at the star
+ for (osmid_t id = 0; id < (PER_BLOCK+(PER_BLOCK >> 1) + 1); ++id)
+ {
+ expected_nodes.emplace_back(id, test_lat(id), 0.0);
}
- // clean up for next test
- if (dynamic_cast<slim_middle_t *>(mid)) {
- dynamic_cast<slim_middle_t *>(mid)->nodes_delete(id);
+ // 1 dense block, 75% filled
+ for (osmid_t id = PER_BLOCK*2; id < PER_BLOCK*3; ++id)
+ {
+ if ((id % 4 == 0) || (id % 4 == 1) || (id % 4 == 2))
+ expected_nodes.emplace_back(id, test_lat(id), 0.0);
}
+ // 1 dense block, sparsly filled
+ for (osmid_t id = PER_BLOCK*3; id < PER_BLOCK*4; ++id)
+ {
+ if (id % 4 == 0)
+ expected_nodes.emplace_back(id, test_lat(id), 0.0);
+ }
+
+ // A lone sparse node
+ expected_nodes.emplace_back(PER_BLOCK*5, test_lat(PER_BLOCK*5), 0.0);
+
+ // A dense block of alternating positions of zero/non-zero
+ for (osmid_t id = PER_BLOCK*6; id < PER_BLOCK*7; ++id)
+ {
+ if (id % 2 == 0)
+ expected_nodes.emplace_back(id, 0.0, 0.0);
+ else
+ expected_nodes.emplace_back(id, test_lat(id), 0.0);
+ }
+ expected_nodes.emplace_back(PER_BLOCK*8, 0.0, 0.0);
+ expected_nodes.emplace_back(PER_BLOCK*8+1, 0.0, 0.0);
+
+ // Load up the nodes into the middle
+ idlist_t ids;
+ ids.reserve(expected_nodes.size());
+
+ for (expected_nodelist_t::iterator node = expected_nodes.begin(); node != expected_nodes.end(); ++node)
+ {
+ if (mid->nodes_set(node->id, node->lat, node->lon, tags) != 0)
+ {
+ std::cerr << "ERROR: Unable to set node " << node->id << "with lat="
+ << node->lat << " lon=" << node->lon << std::endl;
+ return 1;
+ }
+ ids.push_back(node->id);
+ }
+
+ nodelist_t nodes;
+ if (mid->nodes_get_list(nodes, ids) != ids.size()) { std::cerr << "ERROR: Unable to get node list.\n"; return 1; }
+
+ if (nodes.size() != ids.size()) { std::cerr << "ERROR: Mismatch in returned node list size.\n"; return 1; }
+
+ for (size_t i = 0; i < nodes.size(); ++i)
+ {
+ if (!node_okay(nodes[i], expected_nodes[i])) {
+ return 1;
+ }
+ }
return 0;
}
@@ -157,18 +246,5 @@ int test_way_set(middle_t *mid)
}
}
- // clean up for next test
- if (dynamic_cast<slim_middle_t *>(mid)) {
- slim_middle_t *slim = dynamic_cast<slim_middle_t *>(mid);
-
- for (size_t i = 0; i < nds.size(); ++i) {
- slim->nodes_delete(nds[i]);
- }
- slim->ways_delete(way_id);
- }
-
- // commit the torn-down data
- mid->commit();
-
return 0;
}
diff --git a/tests/middle-tests.hpp b/tests/middle-tests.hpp
index 0193912..a8c1b09 100644
--- a/tests/middle-tests.hpp
+++ b/tests/middle-tests.hpp
@@ -6,6 +6,9 @@
// tests that a single node can be set and retrieved. returns 0 on success.
int test_node_set(middle_t *mid);
+// tests various combinations of nodes being set and retrieved to trigger different cache strategies. returns 0 on success.
+int test_nodes_comprehensive_set(middle_t *mid);
+
// tests that a single way and supporting nodes can be set and retrieved.
// returns 0 on success.
int test_way_set(middle_t *mid);
diff --git a/tests/regression-test.py b/tests/regression-test.py
index 9244b2a..617fd50 100755
--- a/tests/regression-test.py
+++ b/tests/regression-test.py
@@ -115,7 +115,7 @@ sql_test_statements=[
( 65, 'Multipolygon non copying of tags from outer with polygon tags on relation (presence of way)',
'SELECT round(ST_Area(way)) FROM planet_osm_polygon WHERE osm_id = 83 and "landuse" = \'farmland\'', 24859),
( 66, 'Multipolygon diff moved point of outer way case (Tags from outer way)',
- 'SELECT round(ST_Area(way)) FROM planet_osm_polygon WHERE osm_id = -15 and landuse = \'residential\' and name = \'Name_way\'', 24751),
+ 'SELECT round(ST_Area(way)) FROM planet_osm_polygon WHERE osm_id = -15 and landuse = \'residential\' and name = \'Name_way\'', 24750),
( 67, 'Multipolygon diff moved point of inner way case (Tags from relation)',
'SELECT round(ST_Area(way)) FROM planet_osm_polygon WHERE osm_id = -1 and landuse = \'residential\' and name = \'Name_rel\'', 13949),
( 68, 'Multipolygon point of inner way case (Tags from relation)',
diff --git a/tests/test-expire-tiles.cpp b/tests/test-expire-tiles.cpp
index 4bc0b43..258f6fe 100644
--- a/tests/test-expire-tiles.cpp
+++ b/tests/test-expire-tiles.cpp
@@ -1,4 +1,5 @@
#include "expire-tiles.hpp"
+#include "options.hpp"
#include <stdio.h>
#include <string.h>
diff --git a/tests/test-middle-pgsql.cpp b/tests/test-middle-pgsql.cpp
index c926e12..191f81d 100644
--- a/tests/test-middle-pgsql.cpp
+++ b/tests/test-middle-pgsql.cpp
@@ -8,7 +8,6 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
#include "output-null.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
@@ -22,59 +21,83 @@
#include "tests/middle-tests.hpp"
#include "tests/common-pg.hpp"
-int main(int argc, char *argv[]) {
- boost::scoped_ptr<pg::tempdb> db;
-
- try {
- db.reset(new pg::tempdb);
- } catch (const std::exception &e) {
- std::cerr << "Unable to setup database: " << e.what() << "\n";
- return 77; // <-- code to skip this test.
- }
+void run_tests(options_t options, const std::string cache_type) {
+ options.append = 0;
+ options.create = 1;
+ {
+ middle_pgsql_t mid_pgsql;
+ output_null_t out_test(&mid_pgsql, options);
- struct middle_pgsql_t mid_pgsql;
- options_t options;
- options.conninfo = db->conninfo().c_str();
- options.scale = 10000000;
- options.num_procs = 1;
- options.prefix = "osm2pgsql_test";
- options.tblsslim_index = "tablespacetest";
- options.tblsslim_data = "tablespacetest";
- options.slim = 1;
+ mid_pgsql.start(&options);
- struct output_null_t out_test(&mid_pgsql, options);
+ if (test_node_set(&mid_pgsql) != 0) { throw std::runtime_error("test_node_set failed."); }
- try {
- // start an empty table to make the middle create the
- // tables it needs. we then run the test in "append" mode.
- mid_pgsql.start(&options);
mid_pgsql.commit();
mid_pgsql.stop();
-
- options.append = 1; /* <- needed because we're going to change the
- * data and check that the updates fire. */
+ }
+ {
+ middle_pgsql_t mid_pgsql;
+ output_null_t out_test(&mid_pgsql, options);
mid_pgsql.start(&options);
- int status = 0;
+ if (test_nodes_comprehensive_set(&mid_pgsql) != 0) { throw std::runtime_error("test_nodes_comprehensive_set failed."); }
- status = test_node_set(&mid_pgsql);
- if (status != 0) { mid_pgsql.stop(); throw std::runtime_error("test_node_set failed."); }
+ mid_pgsql.commit();
+ mid_pgsql.stop();
+ }
+ {
+ middle_pgsql_t mid_pgsql;
+ output_null_t out_test(&mid_pgsql, options);
- status = test_way_set(&mid_pgsql);
- if (status != 0) { mid_pgsql.stop(); throw std::runtime_error("test_way_set failed."); }
+ mid_pgsql.start(&options);
+ mid_pgsql.commit();
+ mid_pgsql.stop();
+ // Switch to append mode because this tests updates
+ options.append = 1;
+ options.create = 0;
+ mid_pgsql.start(&options);
+ if (test_way_set(&mid_pgsql) != 0) { throw std::runtime_error("test_way_set failed."); }
mid_pgsql.commit();
mid_pgsql.stop();
+ }
+}
+int main(int argc, char *argv[]) {
+ boost::scoped_ptr<pg::tempdb> db;
- return 0;
+ try {
+ db.reset(new pg::tempdb);
+ } catch (const std::exception &e) {
+ std::cerr << "Unable to setup database: " << e.what() << "\n";
+ return 77; // <-- code to skip this test.
+ }
+ try {
+ options_t options;
+ options.conninfo = db->conninfo().c_str();
+ options.scale = 10000000;
+ options.cache = 1;
+ options.num_procs = 1;
+ options.prefix = "osm2pgsql_test";
+ options.slim = 1;
+
+ options.alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE; // what you get with optimized
+ run_tests(options, "optimized");
+ options.alloc_chunkwise = ALLOC_SPARSE;
+ run_tests(options, "sparse");
+
+ options.alloc_chunkwise = ALLOC_DENSE;
+ run_tests(options, "dense");
+
+ options.alloc_chunkwise = ALLOC_DENSE | ALLOC_DENSE_CHUNK; // what you get with chunk
+ run_tests(options, "chunk");
} catch (const std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
-
+ return 1;
} catch (...) {
std::cerr << "UNKNOWN ERROR" << std::endl;
+ return 1;
}
-
- return 1;
+ return 0;
}
diff --git a/tests/test-middle-ram.cpp b/tests/test-middle-ram.cpp
index 59a2b63..8e51482 100644
--- a/tests/test-middle-ram.cpp
+++ b/tests/test-middle-ram.cpp
@@ -6,45 +6,69 @@
#include <stdexcept>
#include "osmtypes.hpp"
-#include "middle.hpp"
#include "output-null.hpp"
#include "options.hpp"
#include "middle-ram.hpp"
-#include "node-ram-cache.hpp"
#include "tests/middle-tests.hpp"
-int main(int argc, char *argv[]) {
- try {
- options_t options;
- options.scale = 10000000;
- options.alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE;
- options.cache = 1;
-
- struct middle_ram_t mid_ram;
- struct output_null_t out_test(&mid_ram, options);
+void run_tests(const options_t options, const std::string cache_type) {
+ {
+ middle_ram_t mid_ram;
+ output_null_t out_test(&mid_ram, options);
mid_ram.start(&options);
- int status = 0;
+ if (test_node_set(&mid_ram) != 0) { throw std::runtime_error("test_node_set failed with " + cache_type + " cache."); }
+ mid_ram.commit();
+ mid_ram.stop();
+ }
+ {
+ middle_ram_t mid_ram;
+ output_null_t out_test(&mid_ram, options);
+
+ mid_ram.start(&options);
- status = test_node_set(&mid_ram);
- if (status != 0) { throw std::runtime_error("test_node_set failed."); }
+ if (test_nodes_comprehensive_set(&mid_ram) != 0) { throw std::runtime_error("test_nodes_comprehensive_set failed with " + cache_type + " cache."); }
+ mid_ram.commit();
+ mid_ram.stop();
+ }
+ {
+ middle_ram_t mid_ram;
+ output_null_t out_test(&mid_ram, options);
- status = test_way_set(&mid_ram);
- if (status != 0) { throw std::runtime_error("test_node_set failed."); }
+ mid_ram.start(&options);
+ if (test_way_set(&mid_ram) != 0) { throw std::runtime_error("test_way_set failed with " + cache_type + " cache."); }
mid_ram.commit();
mid_ram.stop();
+ }
+}
+
+int main(int argc, char *argv[]) {
+ try {
+ options_t options;
+ options.scale = 10000000;
+ options.cache = 1; // Non-zero cache is needed to test
- return 0;
+ options.alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE; // what you get with optimized
+ run_tests(options, "optimized");
+ options.alloc_chunkwise = ALLOC_SPARSE;
+ run_tests(options, "sparse");
+
+ options.alloc_chunkwise = ALLOC_DENSE;
+ run_tests(options, "dense");
+
+ options.alloc_chunkwise = ALLOC_DENSE | ALLOC_DENSE_CHUNK; // what you get with chunk
+ run_tests(options, "chunk");
} catch (const std::exception &e) {
std::cerr << "ERROR: " << e.what() << std::endl;
-
+ return 1;
} catch (...) {
std::cerr << "UNKNOWN ERROR" << std::endl;
+ return 1;
}
- return 1;
+ return 0;
}
diff --git a/tests/test-output-multi-line-storage.cpp b/tests/test-output-multi-line-storage.cpp
index fa9d750..41541a0 100644
--- a/tests/test-output-multi-line-storage.cpp
+++ b/tests/test-output-multi-line-storage.cpp
@@ -8,10 +8,10 @@
#include <memory>
#include "osmtypes.hpp"
+#include "osmdata.hpp"
#include "middle.hpp"
#include "output-multi.hpp"
#include "options.hpp"
-#include "middle-pgsql.hpp"
#include "taginfo_impl.hpp"
#include "parse.hpp"
diff --git a/tests/test-output-multi-line.cpp b/tests/test-output-multi-line.cpp
index b740a97..cf53067 100644
--- a/tests/test-output-multi-line.cpp
+++ b/tests/test-output-multi-line.cpp
@@ -8,7 +8,7 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
+#include "osmdata.hpp"
#include "output-multi.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
diff --git a/tests/test-output-multi-point-multi-table.cpp b/tests/test-output-multi-point-multi-table.cpp
index b904075..d35f5bb 100644
--- a/tests/test-output-multi-point-multi-table.cpp
+++ b/tests/test-output-multi-point-multi-table.cpp
@@ -8,7 +8,7 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
+#include "osmdata.hpp"
#include "output-multi.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
diff --git a/tests/test-output-multi-point.cpp b/tests/test-output-multi-point.cpp
index 809717d..36e102a 100644
--- a/tests/test-output-multi-point.cpp
+++ b/tests/test-output-multi-point.cpp
@@ -8,7 +8,7 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
+#include "osmdata.hpp"
#include "output-multi.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
diff --git a/tests/test-output-multi-poly-trivial.cpp b/tests/test-output-multi-poly-trivial.cpp
index dc609cd..611ff36 100644
--- a/tests/test-output-multi-poly-trivial.cpp
+++ b/tests/test-output-multi-poly-trivial.cpp
@@ -8,10 +8,10 @@
#include <memory>
#include "osmtypes.hpp"
+#include "osmdata.hpp"
#include "middle.hpp"
#include "output-multi.hpp"
#include "options.hpp"
-#include "middle-pgsql.hpp"
#include "taginfo_impl.hpp"
#include "parse.hpp"
diff --git a/tests/test-output-multi-polygon.cpp b/tests/test-output-multi-polygon.cpp
index 067e759..38be794 100644
--- a/tests/test-output-multi-polygon.cpp
+++ b/tests/test-output-multi-polygon.cpp
@@ -8,7 +8,7 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
+#include "osmdata.hpp"
#include "output-multi.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
diff --git a/tests/test-output-multi-tags.cpp b/tests/test-output-multi-tags.cpp
index af9221b..00b6d4e 100644
--- a/tests/test-output-multi-tags.cpp
+++ b/tests/test-output-multi-tags.cpp
@@ -11,7 +11,7 @@
#include "middle.hpp"
#include "output-multi.hpp"
#include "options.hpp"
-#include "middle-pgsql.hpp"
+#include "osmdata.hpp"
#include "taginfo_impl.hpp"
#include "parse.hpp"
diff --git a/tests/test-output-pgsql.cpp b/tests/test-output-pgsql.cpp
index 1ef7eba..42f490a 100644
--- a/tests/test-output-pgsql.cpp
+++ b/tests/test-output-pgsql.cpp
@@ -8,7 +8,7 @@
#include <memory>
#include "osmtypes.hpp"
-#include "middle.hpp"
+#include "osmdata.hpp"
#include "output-pgsql.hpp"
#include "options.hpp"
#include "middle-pgsql.hpp"
@@ -264,7 +264,7 @@ void test_clone() {
options.slim = 1;
options.style = "default.style";
- struct output_pgsql_t out_test(mid_pgsql.get(), options);
+ output_pgsql_t out_test(mid_pgsql.get(), options);
//TODO: make the middle testable too
//boost::shared_ptr<middle_t> mid_clone = mid_pgsql->get_instance();
diff --git a/tests/test-parse-options.cpp b/tests/test-parse-options.cpp
index bfe910a..2efb23e 100644
--- a/tests/test-parse-options.cpp
+++ b/tests/test-parse-options.cpp
@@ -138,7 +138,6 @@ int get_random_proj(std::vector<std::string>& args)
switch(proj)
{
case PROJ_LATLONG:
- case PROJ_MERC:
case PROJ_SPHERE_MERC:
args.push_back(reprojection(proj).project_getprojinfo()->option);
break;
diff --git a/tests/test-parse-xml2.cpp b/tests/test-parse-xml2.cpp
index 00b38af..e18f2d8 100644
--- a/tests/test-parse-xml2.cpp
+++ b/tests/test-parse-xml2.cpp
@@ -7,6 +7,7 @@
#include <boost/make_shared.hpp>
#include "osmtypes.hpp"
+#include "osmdata.hpp"
#include "parse-xml2.hpp"
#include "output.hpp"
#include "options.hpp"
diff --git a/util.hpp b/util.hpp
index 06d570f..1c1f54b 100644
--- a/util.hpp
+++ b/util.hpp
@@ -2,12 +2,7 @@
#define UTIL_H
namespace util {
- inline int double_to_fix(const double x, const int scale) {
- return x * scale + 0.4;
- }
- inline double fix_to_double(const int x, const int scale) {
- return (double)x / scale;
- }
+
void exit_nicely();
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osm2pgsql.git
More information about the Pkg-grass-devel
mailing list