+2010-10-30 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ Version 1.5 released
+
+2010-10-30 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * doc/README.txt, doc/NEWS.txt: Updated for version 1.5.
+
+2010-10-18 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/profiles.c:
+ Use sqrt() function to reduce the effect of property preferences close to 50%.
+ Ensure that preferences cannot equal zero (error on division).
+
+ * doc/ALGORITHM.txt, doc/INSTALL.txt, doc/USAGE.txt:
+ Updated with information about the new features.
+
+ * doc/CONFIGURATION.txt, doc/TAGGING.txt:
+ Add in the footroute and bicycleroute configuration options and route relation
+ tag processing.
+
+2010-10-16 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/files.c: Fixed some comments for recent changes.
+
+2010-10-09 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-profiles.xml:
+ Add footroute and bicycleroute to the profiles.
+
+ * src/files.c, src/files.h, src/relationsx.c:
+ The ReOpenFile() function cannot be read/write because it stops the router
+ running with read-only access to the database.
+
+ * src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/superx.c:
+ Fix previous check-in on this set of files.
+
+ * src/xmlparse.l: Ensure that comparisons are made with unsigned chars.
+
+2010-10-03 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/superx.c:
+ Don't try mapping a file if it is zero length (e.g. no super-segments).
+
+ * src/files.c, src/files.h, src/relationsx.c:
+ Add a function to map a file writeable and use it for updating the ways when
+ processing route relations.
+
+ * src/relationsx.c:
+ Avoid self-recursion and adding route information to relations that already have
+ it.
+
+2010-09-25 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/osmparser.c, src/relationsx.c, src/relationsx.h, src/waysx.h:
+ Apply the route=bicycle or route=foot tags from the relation to all ways
+ contained in it and to all ways in all sub-relations of it (including recursion
+ to depth 5). This requires all relations to be stored even if not routes
+ because they might be included by another relation that is.
+
+ * src/segmentsx.c: Don't sort the (super-)segments if there are none.
+
+ * src/nodesx.c, src/functions.h, src/sorting.c:
+ Rename the heapsort() function to filesort_heapsort().
+
+2010-09-19 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/files.c, src/files.h, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/waysx.c:
+ Change the names of the functions used to open files, change the ReOpen function
+ to open R/W.
+
+ * src/relationsx.c: Remove the sorting of the route relations.
+
+2010-09-17 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/nodesx.c, src/segmentsx.c:
+ Zero the NodesFile and SegmentsFile data structures before writing them (zeros
+ unused bytes).
+
+ * src/planetsplitter.c, src/waysx.c, src/waysx.h:
+ Split the sorting of waysx from the compacting so that the route relation
+ information can be included before compacting.
+
+ * xml/routino-tagging.xml, src/functionsx.h, src/osmparser.c, src/planetsplitter.c:
+ Parse relations and extract foot and bicycle routes to be added as properties to
+ the ways.
+
+ * src/types.c, src/types.h: Add footroute and bicycleroute properties.
+
+ * src/relationsx.c, src/relationsx.h: New file.
+
+ * src/typesx.h, src/Makefile:
+ Add files and datatypes for processing relations.
+
+ * xml/routino-tagging-nomodify.xml, xml/routino-tagging.xsd, src/tagging.c:
+ Process tags for relations.
+
+2010-09-16 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/waysx.c, src/segmentsx.c, src/nodesx.c:
+ Fix the comment for the Append...() function.
+
+2010-09-15 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-profiles.xml, xml/routino-tagging.xml, xml/routino-translations.xml,
+ src/output.c, src/translations.c, src/types.c, src/types.h:
+ Add routing on ferries.
+
+ * src/filedumper.c, src/planetsplitter.c, src/router.c:
+ Bug fix for last change.
+
+ * src/filedumper.c, src/planetsplitter.c, src/router.c:
+ Improve the usage information to tell which command line argument was in error.
+
+ * src/profiles.c:
+ Fix --help-profile-perl option and make perl and JSON outputs more pretty.
+
+ * src/router.c, src/planetsplitter.c:
+ Usage message has wrong option name.
+
+ * src/xmlparse.l:
+ Fix last change to make UTF-8 parsing more strict, also added strict conversion
+ to XML-safe character references.
+
+ * src/translations.c:
+ Convert translations read from file into XML-safe encodings before using them.
+
+ * src/output.c: HTML file has UTF-8 meta-tag.
+
+ * xml/routino-translations.xml:
+ Revert to UTF-8 multi-byte representations instead of character references.
+
+2010-09-14 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/xmlparse.l: Stricter checking on XML data (Unicode).
+
+2010-09-05 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/Makefile, src/Makefile, doc/Makefile, Makefile:
+ Move all of the installation pathnames to the top level Makefile and include it
+ into the lower level makefiles.
+
+ * src/planetsplitter.c, src/router.c, src/tagmodifier.c:
+ Use the installed tagging.xml, profiles.xml or translations.xml files as the
+ fallback option if no other given.
+
+2010-09-04 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-translations.xml:
+ Change German translations from named HTML character encodings to numeric ones
+ (works in GPX files as well as HTML).
+
+ * xml/routino-translations.xml:
+ Added Dutch translations (from Jan Jansen).
+
+2010-08-30 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-translations.xml:
+ Change German translation to UTF-8, add comments indicating the origin of the
+ two translations.
+
+ * xml/routino-tagging-nomodify.xml:
+ Relation rules are not allowed at all.
+
+ * xml/Makefile, src/Makefile, doc/Makefile, Makefile:
+ Added 'install' to top level (and lower) Makefiles.
+
+ * src/ways.h, src/output.c:
+ Change the names of the functions used to get the highway names.
+
+ * src/filedumper.c:
+ Only print the way name in OSM output when the way has a name.
+ Change the names of the functions used to get the highway names.
+
+ * src/profiles.c: Fix bug with writing out JSON profile information.
+
+2010-08-30 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/ways.h, src/output.c:
+ Change the names of the functions used to get the highway names.
+
+ * src/filedumper.c:
+ Only print the way name in OSM output when the way has a name.
+ Change the names of the functions used to get the highway names.
+
+ * src/profiles.c: Fix bug with writing out JSON profile information.
+
+2010-08-04 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/output.c, src/segmentsx.c, src/types.h, src/fakes.c, src/functions.h, src/nodesx.c,
+ src/optimiser.c:
+ Change the way that fake nodes and segments are recognised (allows nearly 4G
+ nodes to be stored instead of 2G nodes).
+
+2010-08-03 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/filedumper.c, src/nodes.h, src/nodesx.c, src/optimiser.c, src/types.h:
+ Rename the variables that hold the node allowed transports and flags.
+
+2010-08-02 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-tagging-nomodify.xml, xml/routino-tagging.xml, xml/routino-tagging.xsd,
+ src/filedumper.c, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/osmparser.c,
+ src/superx.c, src/tagging.c, src/types.h:
+ Understand node traffic type restrictions.
+
+2010-07-31 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/profiles.h, src/types.c, src/types.h, src/ways.h, src/waysx.c:
+ Rename the wayallow_t type to allow_t (since it applies to nodes as well now).
+
+ * src/filedumper.c, src/nodes.h, src/nodesx.c, src/segmentsx.c, src/types.h:
+ Add extra information to a node to store turn restrictions and properties.
+ (Move the super-node bit from the first segment to here.)
+
+ * src/nodesx.c, src/segmentsx.c, src/waysx.c:
+ Assert if the number of nodes, segments or ways exceeds the legal range of the
+ index counters.
+
+ * src/nodes.h, src/nodesx.h, src/segments.h, src/segmentsx.h, src/ways.h, src/waysx.h:
+ Change the data types to index_t where they are counting nodes/segments/ways.
+
+ * src/nodes.h, src/nodesx.h, src/segments.h, src/segmentsx.h, src/ways.h, src/waysx.c,
+ src/waysx.h:
+ Ensure that seeking within a file uses a 64-bit offset.
+
+ * src/nodesx.c, src/segmentsx.c, src/superx.c, src/waysx.c:
+ Remove the assert statements that check the order of calling the functions.
+
+2010-07-26 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/filedumper.c, src/nodes.c, src/nodes.h, src/visualiser.c:
+ Final part of slim mode for the router (node offsets).
+
+2010-07-24 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/nodesx.c, src/segmentsx.c, src/waysx.c:
+ Some tidying up of the writing of the file headers.
+
+ * src/ways.c, src/ways.h, src/waysx.c, src/filedumper.c, src/nodes.c, src/optimiser.c,
+ src/output.c, src/profiles.c, src/visualiser.c:
+ Finished slim mode for the router by adding ways.
+
+2010-07-23 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/filedumper.c, src/nodes.c, src/nodes.h, src/output.c, src/segments.c, src/segments.h,
+ src/segmentsx.c:
+ Added slim mode to the router for segments.
+
+ * src/Makefile: Add the fakes.c file.
+
+ * src/optimiser.c, src/results.c, src/results.h:
+ Change the results structure to hold the index of the segment instead of a
+ pointer to it.
+
+ * src/types.h, src/router.c, src/functions.h:
+ Move the fake nodes and segments to a new file.
+
+ * src/fakes.c: New file.
+
+2010-07-19 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * xml/routino-profiles.xml:
+ Reduce the "multilane" preference for motor vehicles. Gives too much bias with
+ previous setting.
+
+2010-07-15 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/Makefile, src/filedumper.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/visualiser.c:
+ Added a slim mode to the router (just for nodes to start with).
+
+2010-07-14 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h, src/Makefile, src/nodesx.c,
+ src/nodesx.h, src/planetsplitter.c, src/segmentsx.c:
+ Replaced the runtime selection of slim mode / non-slim mode with compile time
+ selection that gives no runtime overhead but gives two executables.
+
+2010-07-13 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/nodesx.c, src/nodesx.h, src/segmentsx.c, src/segmentsx.h, src/waysx.c, src/waysx.h:
+ Move the functions for slim mode out into the header file and make it inline.
+
+2010-07-12 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/files.h: New file.
+
+ * src/segmentsx.h, src/sorting.c, src/superx.c, src/tagging.c, src/tagmodifier.c,
+ src/translations.c, src/ways.c, src/waysx.c, src/waysx.h, src/filedumper.c, src/files.c,
+ src/functions.h, src/nodes.c, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/output.c,
+ src/planetsplitter.c, src/profiles.c, src/router.c, src/segments.c, src/segmentsx.c:
+ Create a files.h header and put some of the most heavily used files.c functions
+ into it and make them inline.
+
+2010-07-11 Andrew M. Bishop <amb@gedanken.demon.co.uk>
+
+ * src/segmentsx.c, src/segmentsx.h, src/files.c, src/nodesx.c, src/nodesx.h:
+ Made the planetsplitter slim mode handle the output node and segment data in a
+ slim way as well as in the input data.
+
+ * src/nodesx.c, src/segmentsx.c, src/waysx.c:
+ Change the names of the temporary files.
+
2010-07-10 Andrew M. Bishop <amb@gedanken.demon.co.uk>
Version 1.4.1 released
-# $Header: /home/amb/routino/RCS/Makefile,v 1.3 2010/05/31 12:44:43 amb Exp $
+# $Header: /home/amb/routino/RCS/Makefile,v 1.5 2010/09/05 18:26:57 amb Exp $
#
# Makefile
#
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-FILES=$(wildcard */Makefile)
-DIRS=$(foreach f,$(FILES),$(dir $f))
+# Installation locations
+
+prefix=/usr/local
+bindir=$(prefix)/bin
+docdir=$(prefix)/doc/routino
+datadir=$(prefix)/share/routino
+
+# Sub-directories and sub-makefiles
+
+TOPFILES=$(wildcard */Makefile)
+TOPDIRS=$(foreach f,$(TOPFILES),$(dir $f))
+
+########
+
+all$(top):
+ for dir in $(TOPDIRS); do \
+ ( cd $$dir && $(MAKE) $@ ); \
+ done
########
-all:
- for dir in $(DIRS); do \
+install$(top): all$(top)
+ for dir in $(TOPDIRS); do \
( cd $$dir && $(MAKE) $@ ); \
done
+ @echo "Note: web directory is not installed automatically"
########
-clean:
- for dir in $(DIRS); do \
+clean$(top):
+ for dir in $(TOPDIRS); do \
( cd $$dir && $(MAKE) $@ ); \
done
########
-distclean: clean
- for dir in $(DIRS); do \
+distclean$(top): clean$(top)
+ for dir in $(TOPDIRS); do \
( cd $$dir && $(MAKE) $@ ); \
done
The other highway properties are specified by the user as a
percentage and each highway either has that property or not. The
user's property preference is scaled into the range 0.0 (for 0%)
- to 2.0 (for 100%) to give a weighted preference, a second
+ to 1.0 (for 100%) to give a weighted preference, a second
"non-property" weighted preference is calcuated in the same way
after subtracting the user's preference from 100%. If a segment
- has this property then the calculated score is divided by the
- weighted preference, if the segment does not have this property
- then it is divided by the non-property weighted preference.
+ has a particular property then the calculated score is divided
+ by the weighted preference for that property, if the segment
+ does not have this property then it is divided by the
+ non-property weighted preference. To ensure that setting
+ property preferences near 50% do not cause large variations in
+ routes the highway's preference is found by taking the square
+ root of the property preference.
Implementation
--------------
<preference highway="steps" percent="80" />
</preferences>
<properties>
- <property type="paved" percent="50" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="50" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="55" />
+ <property type="bicycleroute" percent="55" />
</properties>
<restrictions>
<oneway obey="0" />
example web pages but is also a useful location to copy the files from
for normal use.
- The executable files are called 'planetsplitter', 'router' and 'filedumper'
- (also 'tagmodifier' for debugging tag modifications). They can be copied
- to any location and need no special installation environment.
+ The executable files are called 'planetsplitter', 'router' and
+ 'filedumper' (also 'tagmodifier' for debugging tag modifications). They
+ can be copied to any location and need no special installation
+ environment.
- The default configuration files are called 'profiles.xml', 'tagging.xml'
- and 'translations.xml'. The names of the configuration files can be
- specified on the command line but by default are also looked for in the
- directory that contains the routing database.
+ The default configuration files are called 'profiles.xml',
+ 'tagging.xml' and 'translations.xml'. The names of the configuration
+ files can be specified on the command line but by default are also
+ looked for in the directory that contains the routing database.
Example Web Page
----------------
- The directory 'web' contains a set of files that can be used to create a
- working set of web pages with interfaces to the routing algorithm.
+ The directory 'web' contains a set of files that can be used to create
+ a working set of web pages with interfaces to the routing algorithm.
- The files in the 'web' directory will require copying to a location that
- is accessible by a web server. After copying the files some of them
- need to be edited; search through the files for lines that contain the
- words "EDIT THIS" and make appropriate edits. The files that need
+ The files in the 'web' directory will require copying to a location
+ that is accessible by a web server. After copying the files some of
+ them need to be edited; search through the files for lines that contain
+ the words "EDIT THIS" and make appropriate edits. The files that need
editing are 'paths.pl' (to set the directory paths) and 'router.js' and
'visualiser.js' to limit the range of the visible map (latitude,
longitude and zoom).
+ /openlayers/ <- A directory to hold the OpenLayers scripts.
|
+ /routino/ <- The main HTML, Javascript, CSS and CGI files.
+ |
+ + /documentation/ <- The HTML version of the Routino documentation.
The directory 'bin' will be filled by running the compilation process.
For a secure installation the 'bin' directory should be outside of the
- web server, the file 'www/routino/paths.pl' contains the path to the 'bin'
- directory.
+ web server, the file 'www/routino/paths.pl' contains the path to the
+ 'bin' directory.
The directory 'data' must contain the Routino database and is also the
default location for the configuration files. The routing database is
created by downloading the OSM files for the region of interest and
- running the 'planetsplitter' program. There is a script in the directory
- that will download the OSM files and create the required database. The
- script should be edited to set the names of the files to be downloaded.
- For a secure installation the 'data' directory should be outside of the
- web server, the file 'www/routino/paths.pl' contains the path to the 'data'
- directory.
-
- The directory 'results' is a temporary directory that it used to hold the
- GPX and text files generated by the Routino router. The directory must
- be writable by the web server process since it is the CGI scripts that
- are run by the web server that writes the results here. For a secure
- installation the results directory should be outside of the web server,
- the file 'www/routino/paths.pl' contains the path to the results
- directory.
+ running the 'planetsplitter' program. There is a script in the
+ directory that will download the OSM files and create the required
+ database. The script should be edited to set the names of the files to
+ be downloaded. For a secure installation the 'data' directory should
+ be outside of the web server, the file 'www/routino/paths.pl' contains
+ the path to the 'data' directory.
+
+ The directory 'results' is a temporary directory that it used to hold
+ the GPX and text files generated by the Routino router. The directory
+ must be writable by the web server process since it is the CGI scripts
+ that are run by the web server that writes the results here. For a
+ secure installation the results directory should be outside of the web
+ server, the file 'www/routino/paths.pl' contains the path to the
+ results directory.
The directory 'www' and its sub-directories are the only ones that need
to be within the web server accessible directory.
The directory 'www/openlayers' must be filled with the openlayers
Javascript library that can be downloaded from
- http://www.openlayers.org/. (This version of Routino has been tested
- with OpenLayers library version 2.8). The files must be installed so
+ http://www.openlayers.org/. (This version of Routino has been tested
+ with OpenLayers library version 2.9.1). The files must be installed so
that the file 'www/openlayers/OpenLayers.js' and the directories
- 'www/openlayers/img/', 'www/openlayers/theme/' all exist. There is a script
- in the directory that will automatically download and organise the
- files.
+ 'www/openlayers/img/', 'www/openlayers/theme/' all exist. There is a
+ script in the directory that will automatically download and the files,
+ create an optimised "OpenLayers.js" and copy the files to the required
+ locations.
The directory 'www/routino' contains the main HTML, Javascript and CSS
- files as well as the CGI scripts that perform the server-side
+ files as well as the CGI scripts that perform the server-side routing
functions. The description below lists all of the files that contain
editable information.
visualiser.js
The same parameters as in router.js are in this file.
+ The directory www/routino/documentation contains the HTML version of
+ the Routino documentation.
Configuration of web server
---------------------------
- The file 'www/routino/.htaccess' contains all of the Apache configuration
- options that are required to get the example web pages running. The
- only problem is that because of the way that the "AllowOverride" option
- works one of the configuration options has been commented out. This
- must be enabled in the main Apache server configuration file.
+ The file 'www/routino/.htaccess' contains all of the Apache
+ configuration options that are required to get the example web pages
+ running. The only problem is that because of the way that the
+ "AllowOverride" option works one of the configuration options has been
+ commented out. This must be enabled in the main Apache server
+ configuration file.
--------
-# $Header: /home/amb/routino/doc/RCS/Makefile,v 1.2 2010/07/07 17:27:03 amb Exp $
+# $Header: /home/amb/routino/doc/RCS/Makefile,v 1.4 2010/09/05 18:27:07 amb Exp $
#
# Documentation directory Makefile
#
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+# Web file paths
+
WEBDIR=../web/www/routino/documentation
-FILES=html/*
+# Files to install
+
+HTML_FILES=html/*
+TXT_FILES=*.txt
########
all :
-@[ -d $(WEBDIR) ] && \
- for file in $(FILES); do \
+ for file in $(HTML_FILES); do \
if [ ! -f $(WEBDIR)/`basename $$file` ] || [ $$file -nt $(WEBDIR)/`basename $$file` ]; then \
echo cp $$file $(WEBDIR) ;\
cp -f $$file $(WEBDIR) ;\
########
+install: all
+ -[ -d $(DESTDIR)$(docdir) ] || mkdir -p $(DESTDIR)$(docdir)
+ @[ -d $(DESTDIR)$(docdir) ] && \
+ for file in $(TXT_FILES); do \
+ echo cp $$file $(DESTDIR)$(docdir) ;\
+ cp -f $$file $(DESTDIR)$(docdir) ;\
+ done
+ -[ -d $(DESTDIR)$(docdir)/html ] || mkdir -p $(DESTDIR)$(docdir)/html
+ @[ -d $(DESTDIR)$(docdir)/html ] && \
+ for file in $(HTML_FILES); do \
+ echo cp $$file $(DESTDIR)$(docdir)/html ;\
+ cp -f $$file $(DESTDIR)$(docdir)/html ;\
+ done
+
+########
+
clean:
rm -f *~
rm -f html/*~
distclean: clean
rm -f $(WEBDIR)/*
+
+########
+
+top=-top
+include ../Makefile
+Version 1.5 of Routino released : Sat Oct 30 2010
+-------------------------------------------------
+
+Bug fixes:
+ Check that number of nodes/segments/ways doesn't exceed numerical limits.
+ Allow 32-bit systems to seek within files larger than 4GB.
+ Allow nearly 4G nodes to be stored instead of 2G before.
+ Added rules to makefile for installation (paths specified in top-level).
+ Stricter checking of UTF-8 in XML files and better UTF-8 output.
+ Improve error message if parsing of command line options fail.
+ Fix bugs in router's --help-profile-json and --help-profile-perl options.
+ Rename heapsort function to allow compilation on Mac OS with no change.
+ Reduce impact of property preferences close to 50% by using sqrt().
+
+Documentation:
+ Update documentation to reflect changes in program usage and function.
+
+OSM tagging
+ Traffic restrictions on nodes are now included in default tagging file.
+ Added processing for ferry routes (as pseudo-highway type 'ferry').
+ Process foot and bicycle route relations to create new properties.
+
+Configuration Files:
+ Added Dutch output translations.
+ Added ferry information to profiles.
+ Added foot and bicycle route relation processing.
+
+planetsplitter
+ The slim mode now includes the output data as well as the temporary data.
+ The slim mode is now a separate executable and not a command line option.
+ Traffic restrictions on nodes are now understood when parsing OSM files.
+ Falls back to installed tagging.xml configuration file as last resort.
+
+router:
+ Added a slim mode (as a separate executable and not a command line option).
+ Traffic will not be routed through a node that does not allow it.
+ Falls back to installed profiles.xml & translations.xml files as last resort.
+
+filedumper:
+ Added a slim mode (as a separate executable and not a command line option).
+
+Web pages:
+ Added Dutch translation of router.html.
+
+
Version 1.4.1 of Routino released : Sat Jul 10 2010
---------------------------------------------------
Change URL for website to http://www.routino.org/.
Configuration Files:
- Added German translations.
+ Added German output translations.
planetsplitter
Slight change to algorithm for finding super-nodes.
Version 1.2 of Routino was released on 21st October 2009.
Version 1.3 of Routino was released on 21st January 2010.
Version 1.4 of Routino was released on 31st May 2010.
+ Version 1.4.1 of Routino was released on 10th July 2010.
+ Version 1.5 of Routino was released on 30th October 2010.
+
+ The full version history is available in the NEWS.txt file.
License
Node Tags And Attributes
------------------------
- None of the node tags are used but the node attributes id, latitude and
- longitude of the node. The id atribute is required to associate the
- node with the ways and the position attributes are required to locate
- the node.
+ The node attributes id, latitude and longitude are used. The id
+ atribute is required to associate the node with the ways and the
+ position attributes are required to locate the node.
+Transport Specific Tags
+- - - - - - - - - - - -
+
+ One tag is recognised for each of the different modes of transport:
+ foot, horse, bicycle, wheelchair, moped, motorbike, motorcar, goods,
+ hgv and psv. These indicate whether the specific type of transport is
+ allowed to pass through the node or not.
+
+ By default for nodes all types of transport are allowed to pass through
+ a node and specific tags must be used to remove the permissions for the
+ transport.
Way Tags And Attributes
-----------------------
hgv and psv. These indicate whether the specific type of transport is
allowed on the highway or not.
+ By default for ways no types of transport are allowed to pass along a
+ highway and specific tags must be used to add the permissions for the
+ transport.
+
The name Tag
- - - - - -
The tunnel tag is used to identify whether a highway is a tunnel and
therefore set one of the available properties.
+The footroute Tag
+- - - - - - - - -
+
+ The footroute tag is used to identify whether a highway is part of a
+ walking route and therefore set one of the available properties. This
+ is not a standard OSM tag and is normally added to the individual
+ highways by looking for route relations that are designated for foot
+ access.
+
+The bicycleroute Tag
+- - - - - - - - - -
+
+ The bicycleroute tag is used to identify whether a highway is part of a
+ bicycle route and therefore set one of the available properties. This
+ is not a standard OSM tag and is normally added to the individual
+ highways by looking for route relations that are designated for bicycle
+ access.
+
The oneway Tag
- - - - - - -
- - - - - - - - -
The maxweight tag is used to specify the maximum weight of any traffic
- on the way. In other words this must be set to the heaviest weight
- allowed on the way (for example a bridge) in tonnes. If the tag value
- contains "kg" then it is assumed that the value is in these units and
- converted to tonnes.
+ on the highway. In other words this must be set to the heaviest weight
+ allowed on the highway (for example a bridge) in tonnes. If the tag
+ value contains "kg" then it is assumed that the value is in these units
+ and converted to tonnes.
The maxheight Tag
- - - - - - - - -
The maxheight tag is used to specify the maximum height of any traffic
- on the way. In other words this must be set to the lowest height of
- anything above the way (like a bridge) in metres. If the tag value
+ on the highway. In other words this must be set to the lowest height of
+ anything above the highway (like a bridge) in metres. If the tag value
contains a measurement in feet or feet and inches then attempts are
made to convert this to metres.
- - - - - - - -
The maxwidth tag is used to specify the maximum width of any traffic on
- the way. This must be set to the minimum width of the contraints at the
- wayside in metres. If the tag value contains a measurement in feet or
- feet and inches then attempts are made to convert this to metres.
+ the highway. This must be set to the minimum width of the contraints at
+ the wayside in metres. If the tag value contains a measurement in feet
+ or feet and inches then attempts are made to convert this to metres.
The maxlength Tag
- - - - - - - - -
The maxlength tag is used to specify the maximum length of any traffic
- on the way (usually from a traffic sign) in metres. If the tag value
- contains a measurement in feet or feet and inches then attempts are
- made to convert this to metres.
-
+ on the highway (usually from a traffic sign) in metres. If the tag
+ value contains a measurement in feet or feet and inches then attempts
+ are made to convert this to metres.
Relation Tags And Attributes
----------------------------
- Currently no relation tags or attributes are used.
+ The tags from the relations are used to associate more properties with
+ the highways that are part of that relation. The id attribute is used
+ so that relations that are members of other relations can be
+ identified.
+
+The footroute Tag
+- - - - - - - - -
+
+ The footroute tag is used to identify whether a relation defines a
+ walking route and therefore should be applied to the individual member
+ highways.
+
+The bicycleroute Tag
+- - - - - - - - - -
+
+ The bicycleroute tag is used to identify whether a relation defines a
+ bicycle route and therefore should be applied to the individual member
+ highways.
Tag Transformations
Node Tag Transformations
------------------------
- No transformations are applicable since no node tags are recognised.
+Barrier Defaults
+- - - - - - - -
+
+ The first part of the tag transformations is to decide on defaults for
+ each type of node. This uses the barrier tag in the OSM file and
+ converts it into a default set of disallowed transport types.
+
+ Barrier foot horse wheelchair bicycle moped motorbike motorcar goods hgv psv
+ ------- ---- ----- ---------- ------- ----- --------- -------- ----- --- ---
+ bollard yes yes yes yes yes yes no no no no
+ kissing_gate yes no no no no no no no no no
+ stile yes no no no no no no no no no
+ turnstile yes no no no no no no no no no
+Generic Access Permissions
+- - - - - - - - - - - - -
+
+ The access tag is used to specify the default access restrictions
+ through the node. If the tag value is no or private then all transport
+ types are denied access (later tag transformation rules may add
+ specific transport types back again).
+
+Other Access Permissions
+- - - - - - - - - - - -
+
+ A tag named vehicle means any of the bicycle, moped, motorbike,
+ motorcar, goods, hgv and psv transport types. A tag named motor_vehicle
+ is transformed to mean any vehicle except a bicycle.
+
+Specific Access Permissions
+- - - - - - - - - - - - - -
+
+ The final part of the access permissions is to use the specific
+ transport type tags.
+
+ One tag is recognised for each of the different modes of transport:
+ foot, horse, bicycle, wheelchair, moped, motorbike, motorcar, goods,
+ hgv and psv. These indicate whether the specific type of transport is
+ allowed through the node or not.
Way Tag Transformations
-----------------------
- - - - - - - - - - - - -
The access tag is used to specify the default access restrictions on
- the way. If the tag value is "no" or "private" then all transport types
- are denied access (later tag transformation rules may add specific
- transport types back again).
+ the highway. If the tag value is "no" or "private" then all transport
+ types are denied access (later tag transformation rules may add
+ specific transport types back again).
Other Access Permissions
- - - - - - - - - - - -
Relation Tag Transformations
----------------------------
- No transformations are applicable since no relation tags are recognised.
+Routes
+- - -
+
+ The route tag can be used to determine whether a relation is part of a
+ walking of bicycle route so that the footroute and bicycleroute
+ properties can be applied to the highways that make up that relation.
+
+ The tag transformations that are applied for route relations are
+ defined in the table below.
+
+ Relation Tag footroute Property bicycleroute Property
+ foot yes no
+ walking yes no
+ hiking yes no
+ bicycle no yes
+ bicycle;foot or foot;bicycle yes yes
--------
Usage: planetsplitter [--help]
[--dir=<dirname>] [--prefix=<name>]
- [--slim] [--sort-ram-size=<size>]
+ [--sort-ram-size=<size>]
[--tmpdir=<dirname>]
[--parse-only | --process-only]
[--max-iterations=<number>]
Sets the filename prefix for the files that are created.
Defaults to no prefix.
- --slim
- Selects a mode of operation that uses less memory and will
- therefore work where virtual memory is very limited or
- unavailable. Selecting this option will cause raw data to be
- held in disk files with only indexes in RAM. Not using this
- option will still use disk files but only for sequential access
- and the files are memory mapped for random access.
-
--sort-ram-size=<size>
Specifies the amount of RAM (in MB) to use for sorting the data.
- If not specified then 64 MB will be used if the '--slim' option
- is specified or 256 MB otherwise.
+ If not specified then 64 MB will be used in slim mode or 256 MB
+ otherwise.
--tmpdir=<dirname>
Specifies the name of the directory to store the temporary disk
enough.
--tagging=<filename>
- The name of the XML file containing the tagging rules (defaults
- to 'tagging.xml' with '--dirname' and '--prefix' options).
+ Sets the filename containing the list of tagging rules in XML
+ format for the parsing the input files. If the file doesn't
+ exist then dirname, prefix and "profiles.xml" will be combined
+ and used, if that doesn't exist then the file
+ '/usr/local/share/routino/profiles.xml' (or custom installation
+ location) will be used.
<filename.osm> ...
Specifies the filename(s) to read data from, by default data is
achieved by editing the tagging rules file to not output unwwanted
data.
+ Note: In version 1.5 of Routino the --slim option has been removed but
+ at compilation time a separate program called planetsplitter-slim is
+ created that operates in slim mode. In slim mode the temporary files
+ and database files are read as needed rather than being mapped into
+ memory. This allows a database size greater than 2 GB on 32-bit
+ machines or usage with little or no virtual memory (e.g. some virtual
+ machines). The penalty for this is that the program takes about four
+ times as long to run.
+
Example usage:
./planetsplitter --dir=data --prefix=gb great_britain.osm
Defaults to no prefix.
--profiles=<filename>
- Sets the filename containing the list of profiles in XML format.
- If the file doesn't exist then dirname, prefix and
+ Sets the filename containing the list of routing profiles in XML
+ format. If the file doesn't exist then dirname, prefix and
"profiles.xml" will be combined and used, if that doesn't exist
- then the command line must contain all relevant profile
- information.
+ then the file '/usr/local/share/routino/profiles.xml' (or custom
+ installation location) will be used.
--translations=<filename>
Sets the filename containing the list of translations in XML
format for the output files. If the file doesn't exist then
dirname, prefix and "translations.xml" will be combined and
- used, if that doesn't exist then no file will be read and no
- language can be selected.
+ used, if that doesn't exist then the file
+ '/usr/local/share/routino/translations.xml' (or custom
+ installation location) will be used.
--exact-nodes-only
When processing the specified latitude and longitude points only
+ cycleway = Cycleway
+ path = Path
+ steps = Steps
+ + ferry = Ferry
Default value depends on the profile selected by the --transport
option.
+ multilane = Multiple lanes
+ bridge = Bridge
+ tunnel = Tunnel
+ + footroute = A route marked for foot travel
+ + bicycleroute = A route marked for bicycle travel
Default value depends on the profile selected by the --transport
option.
that the length limit on the highway is not exceeded. Default
value depends on the profile selected by the --transport option.
+ Note: In version 1.5 of Routino a slim option has been added and at
+ compilation time a separate program called router-slim is created that
+ operates in slim mode. In slim mode the database files are read as
+ needed rather than being mapped into memory.
+
The meaning of the <preference> parameter in the command line options
is slightly different for the highway preferences and the property
preferences. For the highway preference consider the choice between two
shortest route. If highway A has a preference of 100% and highway B has
a preference of 90% then highway A will be chosen even if it is up to
11% longer (100/90 = 111%). For the highway properties each highway
- either has a particular property or not. If the preference for highways
- with the property is 60% then the preference for highways without the
- property is 40%. The overall preference for the highway is the product
- of the highway preference and the preference for highways with (or
- without) each property that the highway has (or doesn't have).
+ either has a particular property or not. If the preference for the
+ property is 60% then a highway with the property has a preference of
+ 77% (sqrt(60%)) and one without has a preference of 63%
+ (sqrt(100-60%)). A highway with the property will be chosen even if it
+ is up to 22% longer than one without the property (77/63 = 122%). The
+ overall preference for each highway segment is the product of the
+ preference for the highway type and all of the preferences for the
+ highway properties.
Example usage (motorbike journey, scenic route, not very fast):
--lonmin=<lonmin> --lonmax=<lonmax>
The range of longitudes to dump the data for.
+ Note: In version 1.5 of Routino a slim option has been added and at
+ compilation time a separate program called filedumper-slim is created
+ that operates in slim mode. In slim mode the database files are read as
+ needed rather than being mapped into memory.
+
tagmodifier
-----------
<dt>Highway properties
<dd>The other highway properties are specified by the user as a percentage and
each highway either has that property or not. The user's property preference
- is scaled into the range 0.0 (for 0%) to 2.0 (for 100%) to give a weighted
+ is scaled into the range 0.0 (for 0%) to 1.0 (for 100%) to give a weighted
preference, a second "non-property" weighted preference is calcuated in the
same way after subtracting the user's preference from 100%. If a segment has
- this property then the calculated score is divided by the weighted preference,
- if the segment does not have this property then it is divided by the
- non-property weighted preference.
+ a particular property then the calculated score is divided by the weighted
+ preference for that property, if the segment does not have this property then
+ it is divided by the non-property weighted preference. To ensure that setting
+ property preferences near 50% do not cause large variations in routes the
+ highway's preference is found by taking the square root of the property
+ preference.
</dl>
<h3><a name="H_1_1_5"></a>Implementation</h3>
<h2><a name="H_1_1"></a>XML Configuration Files</h2>
-New in version 1.4 of Routino are the use of configuration files to allow more
+New in version 1.4 of Routino is the use of configuration files to allow more
information to be provided to the programs at run-time. The configuration files
that are used are:
<ul>
<preference highway="steps" percent="80" />
</preferences>
<properties>
- <property type="paved" percent="50" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="50" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="55" />
+ <property type="bicycleroute" percent="55" />
</properties>
<restrictions>
<oneway obey="0" />
<h3><a name="H_1_2_1" title="Nodes"></a>Node Tags And Attributes</h3>
-None of the node tags are used but the node attributes <em>id</em>, <em>latitude</em>
-and <em>longitude</em> of the node. The id atribute is required to associate the
-node with the ways and the position attributes are required to locate the node.
+The node attributes <em>id</em>, <em>latitude</em> and <em>longitude</em> are
+used. The id atribute is required to associate the node with the ways and the
+position attributes are required to locate the node.
+
+
+<h4><a name="H_1_2_1_1" title="transport tags"></a>Transport Specific Tags</h4>
+
+One tag is recognised for each of the different modes of transport: <em>foot</em>,
+<em>horse</em>, <em>bicycle</em>, <em>wheelchair</em>, <em>moped</em>,
+<em>motorbike</em>, <em>motorcar</em>, <em>goods</em>, <em>hgv</em>
+and <em>psv</em>. These indicate whether the specific type of transport is
+allowed to pass through the node or not.
+
+<p>
+
+By default for nodes all types of transport are allowed to pass through a node
+and specific tags must be used to remove the permissions for the transport.
<h3><a name="H_1_2_2" title="Ways"></a>Way Tags And Attributes</h3>
and <em>psv</em>. These indicate whether the specific type of transport is
allowed on the highway or not.
+<p>
+
+By default for ways no types of transport are allowed to pass along a highway
+and specific tags must be used to add the permissions for the transport.
+
<h4><a name="H_1_2_2_3" title="name"></a>The name Tag</h4>
therefore set one of the available properties.
-<h4><a name="H_1_2_2_10" title="oneway"></a>The oneway Tag</h4>
+<h4><a name="H_1_2_2_10" title="footroute"></a>The footroute Tag</h4>
+
+The <em>footroute</em> tag is used to identify whether a highway is part of a
+walking route and therefore set one of the available properties. This is not a
+standard OSM tag and is normally added to the individual highways by looking for
+route relations that are designated for foot access.
+
+
+<h4><a name="H_1_2_2_11" title="bicycleroute"></a>The bicycleroute Tag</h4>
+
+The <em>bicycleroute</em> tag is used to identify whether a highway is part of a
+bicycle route and therefore set one of the available properties. This is not a
+standard OSM tag and is normally added to the individual highways by looking for
+route relations that are designated for bicycle access.
+
+
+<h4><a name="H_1_2_2_12" title="oneway"></a>The oneway Tag</h4>
The <em>oneway</em> tag is used to specify that traffic is only allowed to
travel in one direction.
-<h4><a name="H_1_2_2_11" title="maxspeed"></a>The maxspeed Tag</h4>
+<h4><a name="H_1_2_2_13" title="maxspeed"></a>The maxspeed Tag</h4>
The <em>maxspeed</em> tag is used to specify the maximum speed limit on the
highway; this is always measured in km/hr in OpenStreetMap data. If the tag
converted to km/hr.
-<h4><a name="H_1_2_2_12" title="maxweight"></a>The maxweight Tag</h4>
+<h4><a name="H_1_2_2_14" title="maxweight"></a>The maxweight Tag</h4>
The <em>maxweight</em> tag is used to specify the maximum weight of any traffic
-on the way. In other words this must be set to the heaviest weight allowed on
-the way (for example a bridge) in tonnes. If the tag value contains "kg" then
-it is assumed that the value is in these units and converted to tonnes.
+on the highway. In other words this must be set to the heaviest weight allowed
+on the highway (for example a bridge) in tonnes. If the tag value contains "kg"
+then it is assumed that the value is in these units and converted to tonnes.
-<h4><a name="H_1_2_2_13" title="maxheight"></a>The maxheight Tag</h4>
+<h4><a name="H_1_2_2_15" title="maxheight"></a>The maxheight Tag</h4>
The <em>maxheight</em> tag is used to specify the maximum height of any traffic
-on the way. In other words this must be set to the lowest height of anything
-above the way (like a bridge) in metres. If the tag value contains a
-measurement in feet or feet and inches then attempts are made to convert this to
-metres.
+on the highway. In other words this must be set to the lowest height of
+anything above the highway (like a bridge) in metres. If the tag value contains
+a measurement in feet or feet and inches then attempts are made to convert this
+to metres.
-<h4><a name="H_1_2_2_14" title="maxwidth"></a>The maxwidth Tag</h4>
+<h4><a name="H_1_2_2_16" title="maxwidth"></a>The maxwidth Tag</h4>
The <em>maxwidth</em> tag is used to specify the maximum width of any traffic on
-the way. This must be set to the minimum width of the contraints at the wayside
-in metres. If the tag value contains a measurement in feet or feet and inches
-then attempts are made to convert this to metres.
+the highway. This must be set to the minimum width of the contraints at the
+wayside in metres. If the tag value contains a measurement in feet or feet and
+inches then attempts are made to convert this to metres.
-<h4><a name="H_1_2_2_15" title="maxlength"></a>The maxlength Tag</h4>
+<h4><a name="H_1_2_2_17" title="maxlength"></a>The maxlength Tag</h4>
The <em>maxlength</em> tag is used to specify the maximum length of any traffic
-on the way (usually from a traffic sign) in metres. If the tag value contains a
-measurement in feet or feet and inches then attempts are made to convert this to
-metres.
+on the highway (usually from a traffic sign) in metres. If the tag value
+contains a measurement in feet or feet and inches then attempts are made to
+convert this to metres.
<h3><a name="H_1_2_3" title="Relations"></a>Relation Tags And Attributes</h3>
-Currently no relation tags or attributes are used.
+The tags from the relations are used to associate more properties with the
+highways that are part of that relation. The <em>id</em> attribute is used so
+that relations that are members of other relations can be identified.
+
+
+<h4><a name="H_1_2_3_1" title="footroute"></a>The footroute Tag</h4>
+
+The <em>footroute</em> tag is used to identify whether a relation defines a
+walking route and therefore should be applied to the individual member highways.
+
+
+<h4><a name="H_1_2_3_2" title="bicycleroute"></a>The bicycleroute Tag</h4>
+
+The <em>bicycleroute</em> tag is used to identify whether a relation defines a
+bicycle route and therefore should be applied to the individual member highways.
<h2><a name="H_1_3" title="Tag Transformations"></a>Tag Transformations</h2>
<h3><a name="H_1_3_1" title="Nodes"></a>Node Tag Transformations</h3>
-No transformations are applicable since no node tags are recognised.
+<h4><a name="H_1_3_1_1" title="Barrier Defaults"></a>Barrier Defaults</h4>
+
+The first part of the tag transformations is to decide on defaults for each type
+of node. This uses the <em>barrier</em> tag in the OSM file and converts it into
+a default set of disallowed transport types.
+
+<p>
+
+<table>
+ <caption>Transport types through different barrier types</caption>
+ <tr>
+ <th class="left">Barrier
+ <th class="center">foot
+ <th class="center">horse
+ <th class="center">bicycle
+ <th class="center">wheelchair
+ <th class="center">moped
+ <th class="center">motorbike
+ <th class="center">motorcar
+ <th class="center">goods
+ <th class="center">hgv
+ <th class="center">psv
+ <tr>
+ <td class="left">bollard
+ <td class="center">yes
+ <td class="center">yes
+ <td class="center">yes
+ <td class="center">yes
+ <td class="center">yes
+ <td class="center">yes
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <tr>
+ <td class="left">kissing_gate
+ <td class="center">yes
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <tr>
+ <td class="left">stile
+ <td class="center">yes
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <tr>
+ <td class="left">turnstile
+ <td class="center">yes
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+ <td class="center">no
+</table>
+
+<h4><a name="H_1_3_1_2" title="Generic access"></a>Generic Access Permissions</h4>
+
+The <em>access</em> tag is used to specify the default access restrictions
+through the node. If the tag value is <em>no</em> or <em>private</em> then all
+transport types are denied access (later tag transformation rules may add
+specific transport types back again).
+
+
+<h4><a name="H_1_3_1_3" title="Other access"></a>Other Access Permissions</h4>
+
+A tag named <em>vehicle</em> means any of the <em>bicycle</em>, <em>moped</em>,
+<em>motorbike</em>, <em>motorcar</em>, <em>goods</em>, <em>hgv</em>
+and <em>psv</em> transport types. A tag named <em>motor_vehicle</em> is
+transformed to mean any vehicle except a <em>bicycle</em>.
+
+
+<h4><a name="H_1_3_1_4" title="Specific access"></a>Specific Access Permissions</h4>
+
+The final part of the access permissions is to use the specific transport type
+tags.
+
+<p>
+
+One tag is recognised for each of the different modes of transport: <em>foot</em>,
+<em>horse</em>, <em>bicycle</em>, <em>wheelchair</em>, <em>moped</em>,
+<em>motorbike</em>, <em>motorcar</em>, <em>goods</em>, <em>hgv</em>
+and <em>psv</em>. These indicate whether the specific type of transport is
+allowed through the node or not.
<h3><a name="H_1_3_2" title="Ways"></a>Way Tag Transformations</h3>
<h4><a name="H_1_3_2_1" title="Highway Defaults"></a>Highway Defaults</h4>
The first part of the tag transformations is to decide on defaults for each type
-of highway. This uses the highway tag in the OSM file and maps it into one of
-the highway tags that are recognised by Routino, defining the default allowed
-transport types and adding a number of properties.
+of highway. This uses the <em>highway</em> tag in the OSM file and maps it into
+one of the <em>highway</em> tags that are recognised by Routino, defining the
+default allowed transport types and adding a number of properties.
<p>
<h4><a name="H_1_3_2_2" title="Generic access"></a>Generic Access Permissions</h4>
The <em>access</em> tag is used to specify the default access restrictions on
-the way. If the tag value is "no" or "private" then all transport types are
+the highway. If the tag value is "no" or "private" then all transport types are
denied access (later tag transformation rules may add specific transport types
back again).
<h3><a name="H_1_3_3" title="Relations"></a>Relation Tag Transformations</h3>
-No transformations are applicable since no relation tags are recognised.
+<h4><a name="H_1_3_3_1" title="Routes"></a>Routes</h4>
+
+The <em>route</em> tag can be used to determine whether a relation is part of a
+walking of bicycle route so that the footroute and bicycleroute properties can
+be applied to the highways that make up that relation.
+
+<p>
+
+The tag transformations that are applied for route relations are defined in the
+table below.
+
+<p>
+
+<table>
+ <caption>Route properties from different route types</caption>
+ <tr>
+ <th class="center">Relation Tag
+ <th class="center">footroute Property
+ <th class="center">bicycleroute Property
+ <tr>
+ <td class="center">foot
+ <td class="center">yes
+ <td class="center">no
+ <tr>
+ <td class="center">walking
+ <td class="center">yes
+ <td class="center">no
+ <tr>
+ <td class="center">hiking
+ <td class="center">yes
+ <td class="center">no
+ <tr>
+ <td class="center">bicycle
+ <td class="center">no
+ <td class="center">yes
+ <tr>
+ <td class="center">bicycle;foot or foot;bicycle
+ <td class="center">yes
+ <td class="center">yes
+</table>
</div>
<pre class="boxed">
Usage: planetsplitter [--help]
[--dir=<dirname>] [--prefix=<name>]
- [--slim] [--sort-ram-size=<size>]
+ [--sort-ram-size=<size>]
[--tmpdir=<dirname>]
[--parse-only | --process-only]
[--max-iterations=<number>]
<dt>--prefix=<name>
<dd>Sets the filename prefix for the files that are created.
Defaults to no prefix.
- <dt>--slim
- <dd>Selects a mode of operation that uses less memory and will therefore work
- where virtual memory is very limited or unavailable. Selecting this option
- will cause raw data to be held in disk files with only indexes in RAM. Not
- using this option will still use disk files but only for sequential access
- and the files are memory mapped for random access.
<dt>--sort-ram-size=<size>
<dd>Specifies the amount of RAM (in MB) to use for sorting the data. If not
- specified then 64 MB will be used if the '--slim' option is specified or 256
- MB otherwise.
+ specified then 64 MB will be used in slim mode or 256 MB otherwise.
<dt>--tmpdir=<dirname>
<dd>Specifies the name of the directory to store the temporary disk files. If
not specified then it defaults to either the value of the --dir option or the
<dd>The maximum number of iterations to use when generating super-nodes and
super-segments. Defaults to 10 which is normally enough.
<dt>--tagging=<filename>
- <dd>The name of the XML file containing the tagging rules (defaults to
- 'tagging.xml' with '--dirname' and '--prefix' options).
+ <dd>Sets the filename containing the list of tagging rules in XML format for
+ the parsing the input files. If the file doesn't exist then dirname, prefix
+ and "profiles.xml" will be combined and used, if that doesn't exist then the
+ file '/usr/local/share/routino/profiles.xml' (or custom installation
+ location) will be used.
<dt><filename.osm> ...
<dd>Specifies the filename(s) to read data from, by default data is read from
the standard input.
achieved by editing the tagging rules file to not output unwwanted data.</i>
<p>
+<i>Note: In version 1.5 of Routino the --slim option has been removed but at
+compilation time a separate program called <em>planetsplitter-slim</em> is
+created that operates in slim mode. In slim mode the temporary files and
+database files are read as needed rather than being mapped into memory. This
+allows a database size greater than 2 GB on 32-bit machines or usage with little
+or no virtual memory (e.g. some virtual machines). The penalty for this is that
+the program takes about four times as long to run.</i>
+
+<p>
Example usage:
<pre class="boxed">
<dd>Sets the filename prefix for the files in the local database.
Defaults to no prefix.
<dt>--profiles=<filename>
- <dd>Sets the filename containing the list of profiles in XML format. If the
- file doesn't exist then dirname, prefix and "profiles.xml" will be combined
- and used, if that doesn't exist then the command line must contain all
- relevant profile information.
+ <dd>Sets the filename containing the list of routing profiles in XML format.
+ If the file doesn't exist then dirname, prefix and "profiles.xml" will be
+ combined and used, if that doesn't exist then the file
+ '/usr/local/share/routino/profiles.xml' (or custom installation location)
+ will be used.
<dt>--translations=<filename>
<dd>Sets the filename containing the list of translations in XML format for
the output files. If the file doesn't exist then dirname, prefix and
- "translations.xml" will be combined and used, if that doesn't exist then no
- file will be read and no language can be selected.
+ "translations.xml" will be combined and used, if that doesn't exist then the
+ file '/usr/local/share/routino/translations.xml' (or custom installation
+ location) will be used.
<dt>--exact-nodes-only
<dd>When processing the specified latitude and longitude points only select
the nearest node instead of finding the nearest point within a segment
property
The value of <property> can be selected from:
<ul>
- <li>paved = Paved (suitable for normal wheels)
- <li>multilane = Multiple lanes
- <li>bridge = Bridge
- <li>tunnel = Tunnel
+ <li>paved = Paved (suitable for normal wheels)
+ <li>multilane = Multiple lanes
+ <li>bridge = Bridge
+ <li>tunnel = Tunnel
+ <li>footroute = A route marked for foot travel
+ <li>bicycleroute = A route marked for bicycle travel
</ul>
Default value depends on the profile selected by the --transport option.
<dt>--oneway=[0|1]
</dl>
<p>
+<i>Note: In version 1.5 of Routino a slim option has been added and at
+compilation time a separate program called <em>router-slim</em> is created that
+operates in slim mode. In slim mode the database files are read as needed
+rather than being mapped into memory.</i>
+
+<p>
The meaning of the <preference> parameter in the command line options is
slightly different for the highway preferences and the property preferences.
For the highway preference consider the choice between two possible highways
has a preference of 100% and highway B has a preference of 90% then highway A
will be chosen even if it is up to 11% longer (100/90 = 111%). For the highway
properties each highway either has a particular property or not. If the
-preference for highways with the property is 60% then the preference for
-highways without the property is 40%. The overall preference for the highway is
-the product of the highway preference and the preference for highways with (or
-without) each property that the highway has (or doesn't have).
+preference for the property is 60% then a highway with the property has a
+preference of 77% (sqrt(60%)) and one without has a preference of 63%
+(sqrt(100-60%)). A highway with the property will be chosen even if it is up to
+22% longer than one without the property (77/63 = 122%). The overall preference
+for each highway segment is the product of the preference for the highway type
+and all of the preferences for the highway properties.
<p>
Example usage (motorbike journey, scenic route, not very fast):
</dl>
</dl>
+<p>
+<i>Note: In version 1.5 of Routino a slim option has been added and at
+compilation time a separate program called <em>filedumper-slim</em> is created
+that operates in slim mode. In slim mode the database files are read as needed
+rather than being mapped into memory.</i>
+
<h3><a name="H_1_1_4"></a>tagmodifier</h3>
-# $Header: /home/amb/routino/src/RCS/Makefile,v 1.36 2010/07/09 17:43:00 amb Exp $
+# $Header: /home/amb/routino/src/RCS/Makefile,v 1.42 2010/09/17 17:42:20 amb Exp $
#
# Source code Makefile
#
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-# Programs
+# Web file paths
+
+WEBDIR=../web/bin
+
+# Compilation programs
CC=gcc
LD=gcc
LEX=flex
-# Program options
+# Compilation program options
CFLAGS=-Wall -Wmissing-prototypes
#CFLAGS+= -Wextra -pedantic -std=c99
LDFLAGS=-lm -lc
CFLAGS+= -O3
-#CFLAGS+= -O0 -g
+CFLAGS+= -O0 -g
#CFLAGS+= -pg
#CFLAGS+= --coverage
C=$(wildcard *.c)
D=$(foreach f,$(C),$(addprefix .deps/,$(addsuffix .d,$(basename $f))))
-EXE=planetsplitter router filedumper tagmodifier
-
-WEBDIR=../web/bin
+EXE=planetsplitter planetsplitter-slim router router-slim filedumper filedumper-slim tagmodifier
########
########
PLANETSPLITTER_OBJ=planetsplitter.o \
- nodesx.o segmentsx.o waysx.o superx.o \
+ nodesx.o segmentsx.o waysx.o relationsx.o superx.o \
ways.o types.o \
files.o \
results.o queue.o sorting.o \
########
+PLANETSPLITTER_SLIM_OBJ=planetsplitter-slim.o \
+ nodesx-slim.o segmentsx-slim.o waysx-slim.o relationsx-slim.o superx-slim.o \
+ ways.o types.o \
+ files.o \
+ results.o queue.o sorting.o \
+ xmlparse.o tagging.o osmparser.o
+
+planetsplitter-slim : $(PLANETSPLITTER_SLIM_OBJ)
+ $(LD) $(PLANETSPLITTER_SLIM_OBJ) -o $@ $(LDFLAGS)
+
+########
+
ROUTER_OBJ=router.o \
- nodes.o segments.o ways.o types.o \
+ nodes.o segments.o ways.o types.o fakes.o \
+ optimiser.o output.o \
files.o profiles.o xmlparse.o \
- optimiser.o output.o results.o queue.o translations.o
+ results.o queue.o translations.o
router : $(ROUTER_OBJ)
$(LD) $(ROUTER_OBJ) -o $@ $(LDFLAGS)
########
+ROUTER_SLIM_OBJ=router-slim.o \
+ nodes-slim.o segments-slim.o ways-slim.o types.o fakes.o \
+ optimiser-slim.o output-slim.o \
+ files.o profiles.o xmlparse.o \
+ results.o queue.o translations.o
+
+router-slim : $(ROUTER_SLIM_OBJ)
+ $(LD) $(ROUTER_SLIM_OBJ) -o $@ $(LDFLAGS)
+
+########
+
FILEDUMPER_OBJ=filedumper.o \
nodes.o segments.o ways.o types.o \
- files.o xmlparse.o \
- visualiser.o
+ visualiser.o \
+ files.o xmlparse.o
filedumper : $(FILEDUMPER_OBJ)
$(LD) $(FILEDUMPER_OBJ) -o $@ $(LDFLAGS)
########
+FILEDUMPER_SLIM_OBJ=filedumper-slim.o \
+ nodes-slim.o segments-slim.o ways-slim.o types.o \
+ visualiser-slim.o \
+ files.o xmlparse.o
+
+filedumper-slim : $(FILEDUMPER_SLIM_OBJ)
+ $(LD) $(FILEDUMPER_SLIM_OBJ) -o $@ $(LDFLAGS)
+
+########
+
TAGMODIFIER_OBJ=tagmodifier.o \
files.o \
xmlparse.o tagging.o
########
%.o : %.c
- $(CC) -c $(CFLAGS) $(FLAGS64) $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $<)))
+ $(CC) -c $(CFLAGS) $(FLAGS64) -DSLIM=0 -DDATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $<)))
+
+%-slim.o : %.c
+ $(CC) -c $(CFLAGS) $(FLAGS64) -DSLIM=1 -DDATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $<)))
+
+########
+
+install: all
+ -[ -d $(DESTDIR)$(bindir) ] || mkdir -p $(DESTDIR)$(bindir)
+ @[ -d $(DESTDIR)$(bindir) ] && \
+ for file in $(EXE); do \
+ echo cp $$file $(DESTDIR)$(bindir) ;\
+ cp -f $$file $(DESTDIR)$(bindir) ;\
+ done
########
########
.FORCE :
+
+########
+
+top=-top
+include ../Makefile
--- /dev/null
+/***************************************
+ $Header: /home/amb/routino/src/RCS/fakes.c,v 1.2 2010/08/04 16:44:51 amb Exp $
+
+ Fake node and segment generation.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2008-2010 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#include "types.h"
+#include "nodes.h"
+#include "segments.h"
+
+#include "functions.h"
+
+
+/*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/
+#define MINSEGMENT 0.005
+
+
+/*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
+static Segment fake_segments[2*NWAYPOINTS];
+
+/*+ A set of fake node latitudes and longitudes. +*/
+static double fake_lon[NWAYPOINTS+1],fake_lat[NWAYPOINTS+1];
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Create a pair of fake segments corresponding to the given segment split in two.
+
+ index_t CreateFakes Returns the fake node index (or a real one in special cases).
+
+ Nodes *nodes The set of nodes to use.
+
+ int point Which of the waypoints is this.
+
+ Segment *segment The segment to split.
+
+ index_t node1 The first node at the end of this segment.
+
+ index_t node2 The second node at the end of this segment.
+
+ distance_t dist1 The distance to the first node.
+
+ distance_t dist2 The distance to the second node.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2)
+{
+ index_t fakenode;
+ double lat1,lon1,lat2,lon2;
+
+ /* Check if we are actually close enough to an existing node */
+
+ if(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
+ return(node1);
+
+ if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
+ return(node2);
+
+ if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
+ {
+ if(dist1<dist2)
+ return(node1);
+ else
+ return(node2);
+ }
+
+ /* Create the fake node */
+
+ fakenode=NODE_FAKE+point;
+
+ GetLatLong(nodes,node1,&lat1,&lon1);
+ GetLatLong(nodes,node2,&lat2,&lon2);
+
+ if(lat1>3 && lat2<-3)
+ lat2+=2*M_PI;
+ else if(lat1<-3 && lat2>3)
+ lat1+=2*M_PI;
+
+ fake_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2);
+ fake_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2);
+
+ if(fake_lat[point]>M_PI) fake_lat[point]-=2*M_PI;
+
+ /* Create the first fake segment */
+
+ fake_segments[2*point-2]=*segment;
+
+ if(segment->node1==node1)
+ fake_segments[2*point-2].node1=fakenode;
+ else
+ fake_segments[2*point-2].node2=fakenode;
+
+ fake_segments[2*point-2].distance=DISTANCE(dist1)|DISTFLAG(segment->distance);
+
+ /* Create the second fake segment */
+
+ fake_segments[2*point-1]=*segment;
+
+ if(segment->node1==node2)
+ fake_segments[2*point-1].node1=fakenode;
+ else
+ fake_segments[2*point-1].node2=fakenode;
+
+ fake_segments[2*point-1].distance=DISTANCE(dist2)|DISTFLAG(segment->distance);
+
+ return(fakenode);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup the latitude and longitude of a fake node.
+
+ index_t fakenode The node to lookup.
+
+ double *latitude Returns the latitude
+
+ double *longitude Returns the longitude.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude)
+{
+ index_t realnode=fakenode-NODE_FAKE;
+
+ *latitude =fake_lat[realnode];
+ *longitude=fake_lon[realnode];
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Finds the first fake segment associated to a fake node.
+
+ Segment *FirstFakeSegment Returns the first fake segment.
+
+ index_t fakenode The node to lookup.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+Segment *FirstFakeSegment(index_t fakenode)
+{
+ index_t realnode=fakenode-NODE_FAKE;
+
+ return(&fake_segments[2*realnode-2]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Finds the next (there can only be two) fake segment associated to a fake node.
+
+ Segment *NextFakeSegment Returns the second fake segment.
+
+ Segment *segment The first fake segment.
+
+ index_t fakenode The node to lookup.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+Segment *NextFakeSegment(Segment *segment,index_t fakenode)
+{
+ index_t realnode=fakenode-NODE_FAKE;
+
+ if(segment==&fake_segments[2*realnode-2])
+ return(&fake_segments[2*realnode-1]);
+ else
+ return(NULL);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Finds the fake segment between a node and a fake node.
+
+ Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists.
+
+ index_t node The real node.
+
+ index_t fakenode The fake node to lookup.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+Segment *ExtraFakeSegment(index_t node,index_t fakenode)
+{
+ index_t realnode=fakenode-NODE_FAKE;
+
+ if(fake_segments[2*realnode-2].node1==node || fake_segments[2*realnode-2].node2==node)
+ return(&fake_segments[2*realnode-2]);
+
+ if(fake_segments[2*realnode-1].node1==node || fake_segments[2*realnode-1].node2==node)
+ return(&fake_segments[2*realnode-1]);
+
+ return(NULL);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a fake segment given its index.
+
+ Segment *LookupFakeSegment Returns a pointer to the segment.
+
+ index_t fakesegment The index of the fake segment.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+Segment *LookupFakeSegment(index_t fakesegment)
+{
+ index_t realsegment=fakesegment-SEGMENT_FAKE;
+
+ return(&fake_segments[realsegment]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the fake index of a fake segment.
+
+ index_t IndexFakeSegment Returns the fake segment.
+
+ Segment *segment The segment to look for.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+index_t IndexFakeSegment(Segment *segment)
+{
+ index_t realsegment=segment-&fake_segments[0];
+
+ return(realsegment+SEGMENT_FAKE);
+}
/***************************************
- $Header: /home/amb/routino/src/RCS/filedumper.c,v 1.43 2010/05/30 12:52:16 amb Exp $
+ $Header: /home/amb/routino/src/RCS/filedumper.c,v 1.54 2010/09/15 18:19:36 amb Exp $
Memory file dumper.
#include <time.h>
#include "types.h"
-#include "functions.h"
-#include "visualiser.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+
+#include "files.h"
+#include "visualiser.h"
#include "xmlparse.h"
static char *RFC822Date(time_t t);
-static void print_usage(int detail);
+static void print_usage(int detail,const char *argerr,const char *err);
/*++++++++++++++++++++++++++++++++++++++
for(arg=1;arg<argc;arg++)
{
if(!strcmp(argv[arg],"--help"))
- print_usage(1);
+ print_usage(1,NULL,NULL);
else if(!strncmp(argv[arg],"--dir=",6))
dirname=&argv[arg][6];
else if(!strncmp(argv[arg],"--prefix=",9))
else if(!strncmp(argv[arg],"--way=",6))
;
else
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
}
- if(!option_statistics && !option_visualiser && !option_dump && !option_dump_osm)
- print_usage(0);
+ if((option_statistics + option_visualiser + option_dump + option_dump_osm)!=1)
+ print_usage(0,NULL,"Must choose --visualiser, --statistics, --dump or --dump-osm.");
/* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */
if(option_visualiser)
{
if(coordcount!=4)
- {
- fprintf(stderr,"The --visualiser option must have --latmin, --latmax, --lonmin, --lonmax.\n");
- exit(1);
- }
+ print_usage(0,NULL,"The --visualiser option must have --latmin, --latmax, --lonmin, --lonmax.\n");
if(!option_data)
- {
- fprintf(stderr,"The --visualiser option must have --data.\n");
- exit(1);
- }
+ print_usage(0,NULL,"The --visualiser option must have --data.\n");
if(!strcmp(option_data,"junctions"))
OutputJunctions(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
else if(!strcmp(option_data,"length"))
OutputLengthLimits(OSMNodes,OSMSegments,OSMWays,latmin,latmax,lonmin,lonmax);
else
- {
- fprintf(stderr,"Unrecognised data option '%s' with --visualiser.\n",option_data);
- exit(1);
- }
+ print_usage(0,option_data,NULL);
}
/* Print out statistics */
printf("\n");
printf("sizeof(Node) =%9d Bytes\n",sizeof(Node));
- printf("Number =%9d\n",OSMNodes->number);
- printf("Number(super)=%9d\n",OSMNodes->snumber);
+ printf("Number =%9d\n",OSMNodes->file.number);
+ printf("Number(super)=%9d\n",OSMNodes->file.snumber);
printf("\n");
- printf("Lat bins= %4d\n",OSMNodes->latbins);
- printf("Lon bins= %4d\n",OSMNodes->lonbins);
+ printf("Lat bins= %4d\n",OSMNodes->file.latbins);
+ printf("Lon bins= %4d\n",OSMNodes->file.lonbins);
printf("\n");
- printf("Lat zero=%5d (%8.4f deg)\n",OSMNodes->latzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->latzero))));
- printf("Lon zero=%5d (%8.4f deg)\n",OSMNodes->lonzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->lonzero))));
+ printf("Lat zero=%5d (%8.4f deg)\n",OSMNodes->file.latzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero))));
+ printf("Lon zero=%5d (%8.4f deg)\n",OSMNodes->file.lonzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero))));
/* Examine the segments */
printf("\n");
printf("sizeof(Segment)=%9d Bytes\n",sizeof(Segment));
- printf("Number(total) =%9d\n",OSMSegments->number);
- printf("Number(super) =%9d\n",OSMSegments->snumber);
- printf("Number(normal) =%9d\n",OSMSegments->nnumber);
+ printf("Number(total) =%9d\n",OSMSegments->file.number);
+ printf("Number(super) =%9d\n",OSMSegments->file.snumber);
+ printf("Number(normal) =%9d\n",OSMSegments->file.nnumber);
/* Examine the ways */
printf("\n");
printf("sizeof(Way) =%9d Bytes\n",sizeof(Way));
- printf("Number(compacted)=%9d\n",OSMWays->number);
- printf("Number(original) =%9d\n",OSMWays->onumber);
+ printf("Number(compacted)=%9d\n",OSMWays->file.number);
+ printf("Number(original) =%9d\n",OSMWays->file.onumber);
printf("\n");
- printf("Total names =%9ld Bytes\n",(long)buf.st_size-sizeof(Ways)-OSMWays->number*sizeof(Way));
+ printf("Total names =%9ld Bytes\n",(long)buf.st_size-sizeof(Ways)-OSMWays->file.number*sizeof(Way));
printf("\n");
- printf("Included transports: %s\n",AllowedNameList(OSMWays->allow));
- printf("Included properties: %s\n",PropertiesNameList(OSMWays->props));
+ printf("Included transports: %s\n",AllowedNameList(OSMWays->file.allow));
+ printf("Included properties: %s\n",PropertiesNameList(OSMWays->file.props));
}
/* Print out internal data */
for(arg=1;arg<argc;arg++)
if(!strcmp(argv[arg],"--node=all"))
{
- for(item=0;item<OSMNodes->number;item++)
+ for(item=0;item<OSMNodes->file.number;item++)
print_node(OSMNodes,item);
}
else if(!strncmp(argv[arg],"--node=",7))
{
item=atoi(&argv[arg][7]);
- if(item>=0 && item<OSMNodes->number)
+ if(item>=0 && item<OSMNodes->file.number)
print_node(OSMNodes,item);
else
- printf("Invalid node number; minimum=0, maximum=%d.\n",OSMNodes->number-1);
+ printf("Invalid node number; minimum=0, maximum=%d.\n",OSMNodes->file.number-1);
}
else if(!strcmp(argv[arg],"--segment=all"))
{
- for(item=0;item<OSMSegments->number;item++)
+ for(item=0;item<OSMSegments->file.number;item++)
print_segment(OSMSegments,item);
}
else if(!strncmp(argv[arg],"--segment=",10))
{
item=atoi(&argv[arg][10]);
- if(item>=0 && item<OSMSegments->number)
+ if(item>=0 && item<OSMSegments->file.number)
print_segment(OSMSegments,item);
else
- printf("Invalid segment number; minimum=0, maximum=%d.\n",OSMSegments->number-1);
+ printf("Invalid segment number; minimum=0, maximum=%d.\n",OSMSegments->file.number-1);
}
else if(!strcmp(argv[arg],"--way=all"))
{
- for(item=0;item<OSMWays->number;item++)
+ for(item=0;item<OSMWays->file.number;item++)
print_way(OSMWays,item);
}
else if(!strncmp(argv[arg],"--way=",6))
{
item=atoi(&argv[arg][6]);
- if(item>=0 && item<OSMWays->number)
+ if(item>=0 && item<OSMWays->file.number)
print_way(OSMWays,item);
else
- printf("Invalid way number; minimum=0, maximum=%d.\n",OSMWays->number-1);
+ printf("Invalid way number; minimum=0, maximum=%d.\n",OSMWays->file.number-1);
}
}
if(option_dump_osm)
{
if(coordcount>0 && coordcount!=4)
- {
- fprintf(stderr,"The --dump-osm option must have all of --latmin, --latmax, --lonmin, --lonmax or none.\n");
- exit(1);
- }
+ print_usage(0,NULL,"The --dump-osm option must have all of --latmin, --latmax, --lonmin, --lonmax or none.\n");
print_head_osm();
if(coordcount)
{
- int32_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-OSMNodes->latzero;
- int32_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-OSMNodes->latzero;
- int32_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-OSMNodes->lonzero;
- int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-OSMNodes->lonzero;
+ int32_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-OSMNodes->file.latzero;
+ int32_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-OSMNodes->file.latzero;
+ int32_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-OSMNodes->file.lonzero;
+ int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-OSMNodes->file.lonzero;
int latb,lonb,llbin;
- index_t node;
+ index_t item,index1,index2;
/* Loop through all of the nodes. */
for(latb=latminbin;latb<=latmaxbin;latb++)
for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
{
- llbin=lonb*OSMNodes->latbins+latb;
+ llbin=lonb*OSMNodes->file.latbins+latb;
- if(llbin<0 || llbin>(OSMNodes->latbins*OSMNodes->lonbins))
+ if(llbin<0 || llbin>(OSMNodes->file.latbins*OSMNodes->file.lonbins))
continue;
- for(node=OSMNodes->offsets[llbin];node<OSMNodes->offsets[llbin+1];node++)
+ index1=LookupNodeOffset(OSMNodes,llbin);
+ index2=LookupNodeOffset(OSMNodes,llbin+1);
+
+ for(item=index1;item<index2;item++)
{
- double lat=latlong_to_radians(bin_to_latlong(OSMNodes->latzero+latb)+off_to_latlong(OSMNodes->nodes[node].latoffset));
- double lon=latlong_to_radians(bin_to_latlong(OSMNodes->lonzero+lonb)+off_to_latlong(OSMNodes->nodes[node].lonoffset));
+ Node *node=LookupNode(OSMNodes,item,1);
+ double lat=latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon=latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
if(lat>latmin && lat<latmax && lon>lonmin && lon<lonmax)
{
Segment *segment;
- print_node_osm(OSMNodes,node);
+ print_node_osm(OSMNodes,item);
- segment=FirstSegment(OSMSegments,OSMNodes,node);
+ segment=FirstSegment(OSMSegments,OSMNodes,item);
while(segment)
{
- if(node>OtherNode(segment,node))
+ if(item>OtherNode(segment,item))
if(!option_no_super || IsNormalSegment(segment))
print_segment_osm(OSMSegments,IndexSegment(OSMSegments,segment),OSMWays);
- segment=NextSegment(OSMSegments,segment,node);
+ segment=NextSegment(OSMSegments,segment,item);
}
}
}
{
index_t item;
- for(item=0;item<OSMNodes->number;item++)
+ for(item=0;item<OSMNodes->file.number;item++)
print_node_osm(OSMNodes,item);
- for(item=0;item<OSMSegments->number;item++)
- if(!option_no_super || IsNormalSegment(LookupSegment(OSMSegments,item)))
+ for(item=0;item<OSMSegments->file.number;item++)
+ if(!option_no_super || IsNormalSegment(LookupSegment(OSMSegments,item,1)))
print_segment_osm(OSMSegments,item,OSMWays);
}
static void print_node(Nodes* nodes,index_t item)
{
- Node *node=LookupNode(nodes,item);
+ Node *node=LookupNode(nodes,item,1);
double latitude,longitude;
GetLatLong(nodes,item,&latitude,&longitude);
printf("Node %d\n",item);
- printf(" firstseg=%d\n",SEGMENT(node->firstseg));
+ printf(" firstseg=%d\n",node->firstseg);
printf(" latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",node->latoffset,node->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude));
+ printf(" allow=%02x (%s)\n",node->allow,AllowedNameList(node->allow));
if(IsSuperNode(nodes,item))
printf(" Super-Node\n");
}
static void print_segment(Segments *segments,index_t item)
{
- Segment *segment=LookupSegment(segments,item);
+ Segment *segment=LookupSegment(segments,item,1);
printf("Segment %d\n",item);
printf(" node1=%d node2=%d\n",segment->node1,segment->node2);
static void print_way(Ways *ways,index_t item)
{
- Way *way=LookupWay(ways,item);
+ Way *way=LookupWay(ways,item,1);
printf("Way %d\n",item);
- printf(" name=%s\n",WayNameHighway(ways,way));
+ if(*WayName(ways,way))
+ printf(" name=%s\n",WayName(ways,way));
printf(" type=%02x (%s%s%s)\n",way->type,HighwayName(HIGHWAY(way->type)),way->type&Way_OneWay?",One-Way":"",way->type&Way_Roundabout?",Roundabout":"");
printf(" allow=%02x (%s)\n",way->allow,AllowedNameList(way->allow));
if(way->props)
static void print_node_osm(Nodes* nodes,index_t item)
{
+ Node *node=LookupNode(nodes,item,1);
double latitude,longitude;
GetLatLong(nodes,item,&latitude,&longitude);
if(IsSuperNode(nodes,item))
{
+ int i;
+
printf(" <node id='%lu' lat='%.7f' lon='%.7f' version='1'>\n",(unsigned long)item+1,radians_to_degrees(latitude),radians_to_degrees(longitude));
printf(" <tag k='routino:super' v='yes' />\n");
+
+ for(i=1;i<Transport_Count;i++)
+ if(!(node->allow & ALLOWED(i)))
+ printf(" <tag k='%s' v='no' />\n",TransportName(i));
+
printf(" </node>\n");
}
else
static void print_segment_osm(Segments *segments,index_t item,Ways *ways)
{
- Segment *segment=LookupSegment(segments,item);
- Way *way=LookupWay(ways,segment->way);
+ Segment *segment=LookupSegment(segments,item,1);
+ Way *way=LookupWay(ways,segment->way,1);
int i;
printf(" <way id='%lu' version='1'>\n",(unsigned long)item+1);
printf(" <tag k='highway' v='%s' />\n",HighwayName(HIGHWAY(way->type)));
- if(IsNormalSegment(segment) && WayNamed(ways,way))
- printf(" <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(WayNameHighway(ways,way)));
+ if(IsNormalSegment(segment) && *WayName(ways,way))
+ printf(" <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(WayName(ways,way)));
for(i=1;i<Transport_Count;i++)
if(way->allow & ALLOWED(i))
Print out the usage information.
int detail The level of detail to use - 0 = low, 1 = high.
+
+ const char *argerr The argument that gave the error (if there is one).
+
+ const char *err Other error message (if there is one).
++++++++++++++++++++++++++++++++++++++*/
-static void print_usage(int detail)
+static void print_usage(int detail,const char *argerr,const char *err)
{
fprintf(stderr,
"Usage: filedumper [--help]\n"
" [--latmin=<latmin> --latmax=<latmax>\n"
" --lonmin=<lonmin> --lonmax=<lonmax>]]\n");
+ if(argerr)
+ fprintf(stderr,
+ "\n"
+ "Error with command line parameter: %s\n",argerr);
+
+ if(err)
+ fprintf(stderr,
+ "\n"
+ "Error: %s\n",err);
+
if(detail)
fprintf(stderr,
"\n"
/***************************************
- $Header: /home/amb/routino/src/RCS/files.c,v 1.18 2010/03/29 18:20:06 amb Exp $
+ $Header: /home/amb/routino/src/RCS/files.c,v 1.24 2010/10/16 10:59:18 amb Exp $
Functions to handle files.
along with this program. If not, see <http://www.gnu.org/licenses/>.
***************************************/
+#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
-#include "functions.h"
+#include "files.h"
/*+ A structure to contain the list of memory mapped files. +*/
{
close(fd);
- fprintf(stderr,"Cannot mmap file '%s' [%s].\n",filename,strerror(errno));
+ assert(0);
+
+ fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo));
+
+ mappedfiles[nmappedfiles].filename=filename;
+ mappedfiles[nmappedfiles].fd=fd;
+ mappedfiles[nmappedfiles].address=address;
+ mappedfiles[nmappedfiles].length=size;
+
+ nmappedfiles++;
+
+ return(address);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Open a file and map it into memory.
+
+ void *MapFileWriteable Returns the address of the file or exits in case of an error.
+
+ const char *filename The name of the file to open.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void *MapFileWriteable(const char *filename)
+{
+ int fd;
+ off_t size;
+ void *address;
+
+ /* Open the file and get its size */
+
+ fd=ReOpenFileWriteable(filename);
+
+ size=SizeFile(filename);
+
+ /* Map the file */
+
+ address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
+
+ if(address==MAP_FAILED)
+ {
+ close(fd);
+
+ fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno));
exit(EXIT_FAILURE);
}
/*++++++++++++++++++++++++++++++++++++++
Open a new file on disk for writing to.
- int OpenFile Returns the file descriptor if OK or exits in case of an error.
+ int OpenFileNew Returns the file descriptor if OK or exits in case of an error.
const char *filename The name of the file to create.
++++++++++++++++++++++++++++++++++++++*/
-int OpenFile(const char *filename)
+int OpenFileNew(const char *filename)
{
int fd;
/* Open the file */
- fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if(fd<0)
{
/*++++++++++++++++++++++++++++++++++++++
- Open a new file on disk for reading and appending.
+ Open a new file on disk for reading from and appending.
- int AppendFile Returns the file descriptor if OK or exits in case of an error.
+ int OpenFileAppend Returns the file descriptor if OK or exits in case of an error.
const char *filename The name of the file to create.
++++++++++++++++++++++++++++++++++++++*/
-int AppendFile(const char *filename)
+int OpenFileAppend(const char *filename)
{
int fd;
/*++++++++++++++++++++++++++++++++++++++
- Open an existing file on disk for reading from.
+ Open an existing file on disk for reading.
int ReOpenFile Returns the file descriptor if OK or exits in case of an error.
/*++++++++++++++++++++++++++++++++++++++
- Write data to a file on disk.
-
- int WriteFile Returns 0 if OK or something else in case of an error.
+ Open an existing file on disk for reading from or writing to.
- int fd The file descriptor to write to.
+ int ReOpenFileWriteable Returns the file descriptor if OK or exits in case of an error.
- const void *address The address of the data to be written from.
-
- size_t length The length of data to write.
+ const char *filename The name of the file to open.
++++++++++++++++++++++++++++++++++++++*/
-int WriteFile(int fd,const void *address,size_t length)
+int ReOpenFileWriteable(const char *filename)
{
- /* Write the data */
-
- if(write(fd,address,length)!=length)
- return(-1);
-
- return(0);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
- Read data from a file on disk.
-
- int ReadFile Returns 0 if OK or something else in case of an error.
-
- int fd The file descriptor to read from.
-
- void *address The address of the data to be read into.
+ int fd;
- size_t length The length of data to read.
- ++++++++++++++++++++++++++++++++++++++*/
+ /* Open the file */
-int ReadFile(int fd,void *address,size_t length)
-{
- /* Read the data */
+ fd=open(filename,O_RDWR);
- if(read(fd,address,length)!=length)
- return(-1);
+ if(fd<0)
+ {
+ fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno));
+ exit(EXIT_FAILURE);
+ }
- return(0);
+ return(fd);
}
/*++++++++++++++++++++++++++++++++++++++
- Seek to a position in a file on disk.
-
- int SeekFile Returns 0 if OK or something else in case of an error.
-
- int fd The file descriptor to seek within.
-
- off_t position The position to seek to.
- ++++++++++++++++++++++++++++++++++++++*/
-
-int SeekFile(int fd,off_t position)
-{
- /* Seek the data */
-
- if(lseek(fd,position,SEEK_SET)!=position)
- return(-1);
-
- return(0);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Close a file on disk.
int fd The file descriptor to close.
--- /dev/null
+/***************************************
+ $Header: /home/amb/routino/src/RCS/files.h,v 1.4 2010/10/09 18:20:18 amb Exp $
+
+ Header file for file function prototypes
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2008-2010 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#ifndef FILES_H
+#define FILES_H /*+ To stop multiple inclusions. +*/
+
+#include <unistd.h>
+#include <sys/types.h>
+
+
+/* In files.c */
+
+char *FileName(const char *dirname,const char *prefix, const char *name);
+
+void *MapFile(const char *filename);
+void *MapFileWriteable(const char *filename);
+void *UnmapFile(const char *filename);
+
+int OpenFileNew(const char *filename);
+int OpenFileAppend(const char *filename);
+int ReOpenFile(const char *filename);
+int ReOpenFileWriteable(const char *filename);
+
+static int WriteFile(int fd,const void *address,size_t length);
+static int ReadFile(int fd,void *address,size_t length);
+
+off_t SizeFile(const char *filename);
+int ExistsFile(const char *filename);
+
+static int SeekFile(int fd,off_t position);
+
+void CloseFile(int fd);
+
+int DeleteFile(char *filename);
+
+
+/* Inline the frequently called functions */
+
+/*++++++++++++++++++++++++++++++++++++++
+ Write data to a file on disk.
+
+ int WriteFile Returns 0 if OK or something else in case of an error.
+
+ int fd The file descriptor to write to.
+
+ const void *address The address of the data to be written from.
+
+ size_t length The length of data to write.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline int WriteFile(int fd,const void *address,size_t length)
+{
+ /* Write the data */
+
+ if(write(fd,address,length)!=length)
+ return(-1);
+
+ return(0);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Read data from a file on disk.
+
+ int ReadFile Returns 0 if OK or something else in case of an error.
+
+ int fd The file descriptor to read from.
+
+ void *address The address of the data to be read into.
+
+ size_t length The length of data to read.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline int ReadFile(int fd,void *address,size_t length)
+{
+ /* Read the data */
+
+ if(read(fd,address,length)!=length)
+ return(-1);
+
+ return(0);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Seek to a position in a file on disk.
+
+ int SeekFile Returns 0 if OK or something else in case of an error.
+
+ int fd The file descriptor to seek within.
+
+ off_t position The position to seek to.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline int SeekFile(int fd,off_t position)
+{
+ /* Seek the data */
+
+ if(lseek(fd,position,SEEK_SET)!=position)
+ return(-1);
+
+ return(0);
+}
+
+
+#endif /* FILES_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/functions.h,v 1.54 2010/04/24 16:47:56 amb Exp $
+ $Header: /home/amb/routino/src/RCS/functions.h,v 1.58 2010/09/25 13:54:18 amb Exp $
Header file for function prototypes
#ifndef FUNCTIONS_H
#define FUNCTIONS_H /*+ To stop multiple inclusions. +*/
-#include <sys/types.h>
-#include <stdio.h>
-
#include "types.h"
+
#include "profiles.h"
#include "results.h"
-/* In router.c */
+/*+ The number of waypoints allowed to be specified. +*/
+#define NWAYPOINTS 99
+
+
+/* In fakes.c */
/*+ Return true if this is a fake node. +*/
-#define IsFakeNode(xxx) ((xxx)&NODE_SUPER)
+#define IsFakeNode(xxx) ((xxx)>=NODE_FAKE)
+
+/*+ Return true if this is a fake segment. +*/
+#define IsFakeSegment(xxx) ((xxx)>=SEGMENT_FAKE)
index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2);
Segment *NextFakeSegment(Segment *segment,index_t node);
Segment *ExtraFakeSegment(index_t node,index_t fakenode);
-
-/* In files.c */
-
-char *FileName(const char *dirname,const char *prefix, const char *name);
-
-void *MapFile(const char *filename);
-void *UnmapFile(const char *filename);
-
-int OpenFile(const char *filename);
-int AppendFile(const char *filename);
-int ReOpenFile(const char *filename);
-
-int WriteFile(int fd,const void *address,size_t length);
-int ReadFile(int fd,void *address,size_t length);
-
-off_t SizeFile(const char *filename);
-int ExistsFile(const char *filename);
-
-int SeekFile(int fd,off_t position);
-
-void CloseFile(int fd);
-
-int DeleteFile(char *filename);
+Segment *LookupFakeSegment(index_t index);
+index_t IndexFakeSegment(Segment *segment);
/* In optimiser.c */
void filesort_vary(int fd_in,int fd_out,int (*compare)(const void*,const void*),int (*buildindex)(void*,index_t));
-void heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*));
+void filesort_heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*));
#endif /* FUNCTIONS_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/functionsx.h,v 1.5 2010/05/22 18:40:47 amb Exp $
+ $Header: /home/amb/routino/src/RCS/functionsx.h,v 1.6 2010/09/17 17:44:15 amb Exp $
Header file for function prototypes for extended data types.
/* In osmparser.c */
-int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays);
+int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations);
#endif /* FUNCTIONSX_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/nodes.c,v 1.39 2010/07/08 17:54:54 amb Exp $
+ $Header: /home/amb/routino/src/RCS/nodes.c,v 1.44 2010/07/26 18:17:20 amb Exp $
Node data type functions.
#include <stdlib.h>
#include <math.h>
-#include "profiles.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
-#include "functions.h"
+
+#include "files.h"
+#include "profiles.h"
/*++++++++++++++++++++++++++++++++++++++
Nodes *LoadNodeList(const char *filename)
{
- void *data;
Nodes *nodes;
nodes=(Nodes*)malloc(sizeof(Nodes));
- data=MapFile(filename);
+#if !SLIM
+
+ nodes->data=MapFile(filename);
+
+ /* Copy the NodesFile header structure from the loaded data */
+
+ nodes->file=*((NodesFile*)nodes->data);
+
+ /* Set the pointers in the Nodes structure. */
+
+ nodes->offsets=(index_t*)(nodes->data+sizeof(NodesFile));
+ nodes->nodes =(Node* )(nodes->data+sizeof(NodesFile)+(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t));
+
+#else
+
+ nodes->fd=ReOpenFile(filename);
- /* Copy the Nodes structure from the loaded data */
+ /* Copy the NodesFile header structure from the loaded data */
- *nodes=*((Nodes*)data);
+ ReadFile(nodes->fd,&nodes->file,sizeof(NodesFile));
- /* Adjust the pointers in the Nodes structure. */
+ nodes->nodesoffset=sizeof(NodesFile)+(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t);
- nodes->data=data;
- nodes->offsets=(index_t*)(data+sizeof(Nodes));
- nodes->nodes=(Node*)(data+(sizeof(Nodes)+(nodes->latbins*nodes->lonbins+1)*sizeof(index_t)));
+ nodes->incache[0]=NO_NODE;
+ nodes->incache[1]=NO_NODE;
+ nodes->incache[2]=NO_NODE;
+
+#endif
return(nodes);
}
index_t FindClosestNode(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
distance_t distance,Profile *profile,distance_t *bestdist)
{
- ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->latzero;
- ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->lonzero;
+ ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->file.latzero;
+ ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero;
int delta=0,count;
- index_t i,bestn=NO_NODE;
+ index_t i,index1,index2;
+ index_t bestn=NO_NODE;
distance_t bestd=INF_DISTANCE;
/* Start with the bin containing the location, then spiral outwards. */
int latb,lonb,llbin;
count=0;
-
+
for(latb=latbin-delta;latb<=latbin+delta;latb++)
{
- if(latb<0 || latb>=nodes->latbins)
+ if(latb<0 || latb>=nodes->file.latbins)
continue;
for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++)
{
- if(lonb<0 || lonb>=nodes->lonbins)
+ if(lonb<0 || lonb>=nodes->file.lonbins)
continue;
if(abs(latb-latbin)<delta && abs(lonb-lonbin)<delta)
continue;
- llbin=lonb*nodes->latbins+latb;
+ llbin=lonb*nodes->file.latbins+latb;
/* Check if this grid square has any hope of being close enough */
if(delta>0)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb));
- double lat2=latlong_to_radians(bin_to_latlong(nodes->latzero+latb+1));
- double lon2=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb+1));
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb));
+ double lat2=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb+1));
+ double lon2=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb+1));
if(latb==latbin)
{
/* Check every node in this grid square. */
- for(i=nodes->offsets[llbin];i<nodes->offsets[llbin+1];i++)
+ index1=LookupNodeOffset(nodes,llbin);
+ index2=LookupNodeOffset(nodes,llbin+1);
+
+ for(i=index1;i<index2;i++)
{
- double lat=latlong_to_radians(bin_to_latlong(nodes->latzero+latb)+off_to_latlong(nodes->nodes[i].latoffset));
- double lon=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb)+off_to_latlong(nodes->nodes[i].lonoffset));
+ Node *node=LookupNode(nodes,i,1);
+ double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
distance_t dist=Distance(lat,lon,latitude,longitude);
do
{
- Way *way=LookupWay(ways,segment->way);
+ Way *way=LookupWay(ways,segment->way,1);
if(way->allow&profile->allow)
break;
/*++++++++++++++++++++++++++++++++++++++
Find the closest segment to a latitude, longitude and optionally profile.
- Segment *FindClosestSegment Returns the closest segment.
+ index_t FindClosestSegment Returns the closest segment index.
Nodes* nodes The set of nodes to search.
distance_t *bestdist2 Returns the distance to the best node at the other end.
++++++++++++++++++++++++++++++++++++++*/
-Segment *FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
- distance_t distance,Profile *profile, distance_t *bestdist,
- index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2)
+index_t FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
+ distance_t distance,Profile *profile, distance_t *bestdist,
+ index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2)
{
- ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->latzero;
- ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->lonzero;
+ ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->file.latzero;
+ ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero;
int delta=0,count;
- index_t i,bestn1=NO_NODE,bestn2=NO_NODE;
+ index_t i,index1,index2;
+ index_t bestn1=NO_NODE,bestn2=NO_NODE;
distance_t bestd=INF_DISTANCE,bestd1=INF_DISTANCE,bestd2=INF_DISTANCE;
- Segment *bests=NULL;
+ index_t bests=NO_SEGMENT;
/* Start with the bin containing the location, then spiral outwards. */
int latb,lonb,llbin;
count=0;
-
+
for(latb=latbin-delta;latb<=latbin+delta;latb++)
{
- if(latb<0 || latb>=nodes->latbins)
+ if(latb<0 || latb>=nodes->file.latbins)
continue;
for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++)
{
- if(lonb<0 || lonb>=nodes->lonbins)
+ if(lonb<0 || lonb>=nodes->file.lonbins)
continue;
if(abs(latb-latbin)<delta && abs(lonb-lonbin)<delta)
continue;
- llbin=lonb*nodes->latbins+latb;
+ llbin=lonb*nodes->file.latbins+latb;
/* Check if this grid square has any hope of being close enough */
if(delta>0)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb));
- double lat2=latlong_to_radians(bin_to_latlong(nodes->latzero+latb+1));
- double lon2=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb+1));
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb));
+ double lat2=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb+1));
+ double lon2=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb+1));
if(latb==latbin)
{
/* Check every node in this grid square. */
- for(i=nodes->offsets[llbin];i<nodes->offsets[llbin+1];i++)
+ index1=LookupNodeOffset(nodes,llbin);
+ index2=LookupNodeOffset(nodes,llbin+1);
+
+ for(i=index1;i<index2;i++)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb)+off_to_latlong(nodes->nodes[i].latoffset));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb)+off_to_latlong(nodes->nodes[i].lonoffset));
+ Node *node=LookupNode(nodes,i,1);
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
distance_t dist1;
dist1=Distance(lat1,lon1,latitude,longitude);
Way *way=NULL;
if(profile)
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!profile || way->allow&profile->allow)
{
if(distp<(double)bestd)
{
- bests=segment;
+ bests=IndexSegment(segments,segment);
bestn1=i;
bestn2=OtherNode(segment,i);
bestd1=(distance_t)dist3a;
void GetLatLong(Nodes *nodes,index_t index,double *latitude,double *longitude)
{
- Node *node=&nodes->nodes[index];
+ Node *node=LookupNode(nodes,index,2);
int latbin=-1,lonbin=-1;
int start,end,mid;
+ index_t offset;
/* Binary search - search key closest below is required.
*
/* Search for longitude */
start=0;
- end=nodes->lonbins-1;
+ end=nodes->file.lonbins-1;
do
{
- mid=(start+end)/2; /* Choose mid point */
+ mid=(start+end)/2; /* Choose mid point */
- if(nodes->offsets[nodes->latbins*mid]<index) /* Mid point is too low */
+ offset=LookupNodeOffset(nodes,nodes->file.latbins*mid);
+
+ if(offset<index) /* Mid point is too low */
start=mid;
- else if(nodes->offsets[nodes->latbins*mid]>index) /* Mid point is too high */
+ else if(offset>index) /* Mid point is too high */
end=mid-1;
- else /* Mid point is correct */
+ else /* Mid point is correct */
{lonbin=mid;break;}
}
while((end-start)>1);
if(lonbin==-1)
{
- if(nodes->offsets[nodes->latbins*end]>index)
+ offset=LookupNodeOffset(nodes,nodes->file.latbins*end);
+
+ if(offset>index)
lonbin=start;
else
lonbin=end;
}
- while(lonbin<nodes->lonbins && nodes->offsets[lonbin*nodes->latbins]==nodes->offsets[(lonbin+1)*nodes->latbins])
+ while(lonbin<nodes->file.lonbins &&
+ LookupNodeOffset(nodes,lonbin*nodes->file.latbins)==LookupNodeOffset(nodes,(lonbin+1)*nodes->file.latbins))
lonbin++;
/* Search for latitude */
start=0;
- end=nodes->latbins-1;
+ end=nodes->file.latbins-1;
do
{
- mid=(start+end)/2; /* Choose mid point */
+ mid=(start+end)/2; /* Choose mid point */
- if(nodes->offsets[lonbin*nodes->latbins+mid]<index) /* Mid point is too low */
+ offset=LookupNodeOffset(nodes,lonbin*nodes->file.latbins+mid);
+
+ if(offset<index) /* Mid point is too low */
start=mid;
- else if(nodes->offsets[lonbin*nodes->latbins+mid]>index) /* Mid point is too high */
+ else if(offset>index) /* Mid point is too high */
end=mid-1;
- else /* Mid point is correct */
+ else /* Mid point is correct */
{latbin=mid;break;}
}
while((end-start)>1);
if(latbin==-1)
{
- if(nodes->offsets[lonbin*nodes->latbins+end]>index)
+ offset=LookupNodeOffset(nodes,lonbin*nodes->file.latbins+end);
+
+ if(offset>index)
latbin=start;
else
latbin=end;
}
- while(latbin<nodes->latbins && nodes->offsets[lonbin*nodes->latbins+latbin]==nodes->offsets[lonbin*nodes->latbins+latbin+1])
+ while(latbin<nodes->file.latbins &&
+ LookupNodeOffset(nodes,lonbin*nodes->file.latbins+latbin)==LookupNodeOffset(nodes,lonbin*nodes->file.latbins+latbin+1))
latbin++;
/* Return the values */
- *latitude =latlong_to_radians(bin_to_latlong(nodes->latzero+latbin)+off_to_latlong(node->latoffset));
- *longitude=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonbin)+off_to_latlong(node->lonoffset));
+ *latitude =latlong_to_radians(bin_to_latlong(nodes->file.latzero+latbin)+off_to_latlong(node->latoffset));
+ *longitude=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonbin)+off_to_latlong(node->lonoffset));
}
/***************************************
- $Header: /home/amb/routino/src/RCS/nodes.h,v 1.30 2009/11/14 19:39:19 amb Exp $
+ $Header: /home/amb/routino/src/RCS/nodes.h,v 1.37 2010/08/03 18:28:30 amb Exp $
A header file for the nodes.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2008,2009 Andrew M. Bishop
+ This file Copyright 2008-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
#include <stdint.h>
#include "types.h"
+
+#include "files.h"
#include "profiles.h"
ll_off_t latoffset; /*+ The node latitude offset within its bin. +*/
ll_off_t lonoffset; /*+ The node longitude offset within its bin. +*/
+
+ allow_t allow; /*+ The types of transport that are allowed through the node. +*/
+ uint16_t flags; /*+ Flags containing extra information (super-node, turn restriction). +*/
};
-/*+ A structure containing a set of nodes (mmap format). +*/
-struct _Nodes
+/*+ A structure containing the header from the file. +*/
+typedef struct _NodesFile
{
- uint32_t number; /*+ How many nodes in total? +*/
- uint32_t snumber; /*+ How many super-nodes? +*/
+ index_t number; /*+ How many nodes in total? +*/
+ index_t snumber; /*+ How many super-nodes? +*/
- uint32_t latbins; /*+ The number of bins containing latitude. +*/
- uint32_t lonbins; /*+ The number of bins containing longitude. +*/
+ index_t latbins; /*+ The number of bins containing latitude. +*/
+ index_t lonbins; /*+ The number of bins containing longitude. +*/
ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/
ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/
+}
+ NodesFile;
- index_t *offsets; /*+ An array of offset to the first node in each bin. +*/
- Node *nodes; /*+ An array of nodes. +*/
+/*+ A structure containing a set of nodes (and pointers to mmap file). +*/
+struct _Nodes
+{
+ NodesFile file; /*+ The header data from the file. +*/
- void *data; /*+ The memory mapped data. +*/
-};
+#if !SLIM
+ void *data; /*+ The memory mapped data. +*/
-/* Macros */
+ index_t *offsets; /*+ An array of offsets to the first node in each bin. +*/
-/*+ Return a Node pointer given a set of nodes and an index. +*/
-#define LookupNode(xxx,yyy) (&(xxx)->nodes[yyy])
+ Node *nodes; /*+ An array of nodes. +*/
-/*+ Return a Segment points given a Node pointer and a set of segments. +*/
-#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),SEGMENT((yyy)->nodes[zzz].firstseg))
+#else
-/*+ Return true if this is a super-node. +*/
-#define IsSuperNode(xxx,yyy) (((xxx)->nodes[yyy].firstseg)&NODE_SUPER)
+ int fd; /*+ The file descriptor for the file. +*/
+ off_t nodesoffset; /*+ The offset of the nodes within the file. +*/
+ Node cached[3]; /*+ The cached nodes. +*/
+ index_t incache[3]; /*+ The indexes of the cached nodes. +*/
-/* Functions */
+#endif
+};
+/* Functions */
+
Nodes *LoadNodeList(const char *filename);
index_t FindClosestNode(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
distance_t distance,Profile *profile,distance_t *bestdist);
-Segment *FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
- distance_t distance,Profile *profile, distance_t *bestdist,
- index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2);
+index_t FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
+ distance_t distance,Profile *profile, distance_t *bestdist,
+ index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2);
void GetLatLong(Nodes *nodes,index_t index,double *latitude,double *longitude);
+/* Macros and inline functions */
+
+#if !SLIM
+
+/*+ Return a Node pointer given a set of nodes and an index. +*/
+#define LookupNode(xxx,yyy,zzz) (&(xxx)->nodes[yyy])
+
+/*+ Return a Segment points given a Node pointer and a set of segments. +*/
+#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),(yyy)->nodes[zzz].firstseg,1)
+
+/*+ Return true if this is a super-node. +*/
+#define IsSuperNode(xxx,yyy) (((xxx)->nodes[yyy].flags)&NODE_SUPER)
+
+/*+ Return the offset of a geographical region given a set of nodes and an index. +*/
+#define LookupNodeOffset(xxx,yyy) ((xxx)->offsets[yyy])
+
+#else
+
+static Node *LookupNode(Nodes *nodes,index_t index,int position);
+
+#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),FirstSegment_internal(yyy,zzz),1)
+
+static index_t FirstSegment_internal(Nodes *nodes,index_t index);
+
+static int IsSuperNode(Nodes *nodes,index_t index);
+
+static index_t LookupNodeOffset(Nodes *nodes,index_t index);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the Node information for a particular node.
+
+ Node *LookupNode Returns a pointer to the cached node information.
+
+ Nodes *nodes The nodes structure to use.
+
+ index_t index The index of the node.
+
+ int position The position in the cache to store the value.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline Node *LookupNode(Nodes *nodes,index_t index,int position)
+{
+ SeekFile(nodes->fd,nodes->nodesoffset+(off_t)index*sizeof(Node));
+
+ ReadFile(nodes->fd,&nodes->cached[position-1],sizeof(Node));
+
+ nodes->incache[position-1]=index;
+
+ return(&nodes->cached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the index of the first segment of a node (called by FirstSegment() macro).
+
+ index_t FirstSegment_internal Returns the index of the first segment.
+
+ Nodes *nodes The nodes structure to use.
+
+ index_t index The index of the node.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline index_t FirstSegment_internal(Nodes *nodes,index_t index)
+{
+ if(nodes->incache[0]==index)
+ return(nodes->cached[0].firstseg);
+ else if(nodes->incache[1]==index)
+ return(nodes->cached[1].firstseg);
+ else if(nodes->incache[2]==index)
+ return(nodes->cached[2].firstseg);
+ else
+ {
+ Node *node=LookupNode(nodes,index,3);
+
+ return(node->firstseg);
+ }
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Decide if a node is a super-node.
+
+ int IsSuperNode Return true if it is a supernode.
+
+ Nodes *nodes The nodes structure to use.
+
+ index_t index The index of the node.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline int IsSuperNode(Nodes *nodes,index_t index)
+{
+ if(nodes->incache[0]==index)
+ return(nodes->cached[0].flags&NODE_SUPER);
+ else if(nodes->incache[1]==index)
+ return(nodes->cached[1].flags&NODE_SUPER);
+ else if(nodes->incache[2]==index)
+ return(nodes->cached[2].flags&NODE_SUPER);
+ else
+ {
+ Node *node=LookupNode(nodes,index,3);
+
+ return(node->flags&NODE_SUPER);
+ }
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the offset of nodes in a geographical region.
+
+ index_t LookupNodeOffset Returns the value of the index offset.
+
+ Nodes *nodes The nodes structure to use.
+
+ index_t index The index of the offset.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline index_t LookupNodeOffset(Nodes *nodes,index_t index)
+{
+ index_t offset;
+
+ SeekFile(nodes->fd,sizeof(NodesFile)+(off_t)index*sizeof(index_t));
+
+ ReadFile(nodes->fd,&offset,sizeof(index_t));
+
+ return(offset);
+}
+
+#endif
+
+
#endif /* NODES_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/nodesx.c,v 1.56 2010/04/28 17:27:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/nodesx.c,v 1.75 2010/10/09 14:14:42 amb Exp $
Extented Node data type functions.
#include <sys/stat.h>
#include "types.h"
-#include "functions.h"
+#include "nodes.h"
+#include "segments.h"
+
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
-#include "segments.h"
-#include "nodes.h"
+#include "types.h"
+
+#include "files.h"
+#include "functions.h"
-/* Variables */
-/*+ The command line '--slim' option. +*/
-extern int option_slim;
+/* Variables */
/*+ The command line '--tmpdir' option or its default value. +*/
extern char *option_tmpdirname;
nodesx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
if(append)
- sprintf(nodesx->filename,"%s/nodes.input.tmp",option_tmpdirname);
+ sprintf(nodesx->filename,"%s/nodesx.input.tmp",option_tmpdirname);
else
- sprintf(nodesx->filename,"%s/nodes.%p.tmp",option_tmpdirname,nodesx);
+ sprintf(nodesx->filename,"%s/nodesx.%p.tmp",option_tmpdirname,nodesx);
+
+#if SLIM
+ nodesx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32);
+
+ sprintf(nodesx->nfilename,"%s/nodes.%p.tmp",option_tmpdirname,nodesx);
+#endif
if(append)
{
off_t size;
- nodesx->fd=AppendFile(nodesx->filename);
+ nodesx->fd=OpenFileAppend(nodesx->filename);
size=SizeFile(nodesx->filename);
nodesx->xnumber=size/sizeof(NodeX);
}
else
- nodesx->fd=OpenFile(nodesx->filename);
+ nodesx->fd=OpenFileNew(nodesx->filename);
return(nodesx);
}
if(nodesx->idata)
free(nodesx->idata);
+#if !SLIM
if(nodesx->ndata)
free(nodesx->ndata);
+#endif
+
+#if SLIM
+ DeleteFile(nodesx->nfilename);
+
+ free(nodesx->nfilename);
+#endif
if(nodesx->super)
free(nodesx->super);
/*++++++++++++++++++++++++++++++++++++++
- Append a node to a newly created node list (unsorted).
+ Append a single node to an unsorted node list.
NodesX* nodesx The set of nodes to process.
double latitude The latitude of the node.
double longitude The longitude of the node.
+
+ allow_t allow The allowed traffic types through the node.
++++++++++++++++++++++++++++++++++++++*/
-void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude)
+void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude,allow_t allow)
{
NodeX nodex;
- assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
-
nodex.id=id;
nodex.latitude =radians_to_latlong(latitude);
nodex.longitude=radians_to_latlong(longitude);
+ nodex.allow=allow;
WriteFile(nodesx->fd,&nodex,sizeof(NodeX));
nodesx->xnumber++;
+
+ assert(nodesx->xnumber<NODE_FAKE); /* NODE_FAKE marks the high-water mark for real nodes. */
}
{
int fd;
- /* Check the start conditions */
-
- assert(!nodesx->idata); /* Must not have idata filled in => unsorted */
-
/* Print the start message */
printf("Sorting Nodes");
DeleteFile(nodesx->filename);
- fd=OpenFile(nodesx->filename);
+ fd=OpenFileNew(nodesx->filename);
/* Allocate the array of indexes */
DeleteFile(nodesx->filename);
- fd=OpenFile(nodesx->filename);
+ fd=OpenFileNew(nodesx->filename);
/* Sort geographically */
else
{
#ifdef REGRESSION_TESTING
- // Need this for regression testing because heapsort() is not order
+ // Need this for regression testing because filesort_heapsort() is not order
// preserving like qsort() is (or was when tested).
index_t a_id=a->id;
int end=nodesx->number-1;
int mid;
- assert(nodesx->idata); /* Must have idata filled in => sorted by id */
-
/* Binary search - search key exact match only is required.
*
* # <- start | Check mid and move start or end if it doesn't match
/*++++++++++++++++++++++++++++++++++++++
- Lookup a particular node.
-
- NodeX *LookupNodeX Returns a pointer to the extended node with the specified id.
-
- NodesX* nodesx The set of nodes to process.
-
- index_t index The node index to look for.
-
- int position The position in the cache to use.
- ++++++++++++++++++++++++++++++++++++++*/
-
-NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position)
-{
- assert(index!=NO_NODE); /* Must be a valid node */
-
- if(option_slim)
- {
- SeekFile(nodesx->fd,index*sizeof(NodeX));
-
- ReadFile(nodesx->fd,&nodesx->cached[position-1],sizeof(NodeX));
-
- return(&nodesx->cached[position-1]);
- }
- else
- {
- return(&nodesx->xdata[index]);
- }
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Remove any nodes that are not part of a highway.
NodesX *nodesx The complete node list.
latlong_t lat_min,lat_max,lon_min,lon_max;
int fd;
- /* Check the start conditions */
-
- assert(nodesx->idata); /* Must have idata filled in => data sorted */
-
/* Print the start message */
printf("Checking: Nodes=0");
DeleteFile(nodesx->filename);
- fd=OpenFile(nodesx->filename);
+ fd=OpenFileNew(nodesx->filename);
SeekFile(nodesx->fd,0);
while(!ReadFile(nodesx->fd,&nodex,sizeof(NodeX)))
{
index_t i;
- /* Check the start conditions */
-
- assert(!nodesx->ndata); /* Must not have ndata filled in => no real nodes */
-
/* Print the start message */
printf("Creating Real Nodes: Nodes=0");
/* Map into memory */
- if(!option_slim)
- nodesx->xdata=MapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+#endif
- /* Allocate the memory */
+ /* Allocate the memory (or open the file) */
+#if !SLIM
nodesx->ndata=(Node*)malloc(nodesx->number*sizeof(Node));
assert(nodesx->ndata); /* Check malloc() worked */
+#else
+ nodesx->nfd=OpenFileNew(nodesx->nfilename);
+#endif
/* Loop through and allocate. */
for(i=0;i<nodesx->number;i++)
{
NodeX *nodex=LookupNodeX(nodesx,i,1);
+ Node *node =LookupNodeXNode(nodesx,nodex->id,1);
- nodesx->ndata[nodex->id].latoffset=latlong_to_off(nodex->latitude);
- nodesx->ndata[nodex->id].lonoffset=latlong_to_off(nodex->longitude);
- nodesx->ndata[nodex->id].firstseg=SEGMENT(NO_SEGMENT);
+ node->latoffset=latlong_to_off(nodex->latitude);
+ node->lonoffset=latlong_to_off(nodex->longitude);
+ node->firstseg=NO_SEGMENT;
+ node->allow=nodex->allow;
+ node->flags=0;
if(nodesx->super[nodex->id]==iteration)
- nodesx->ndata[nodex->id].firstseg|=NODE_SUPER;
+ node->flags|=NODE_SUPER;
+
+#if SLIM
+ PutBackNodeXNode(nodesx,nodex->id,1);
+#endif
if(!((i+1)%10000))
{
/* Unmap from memory */
- if(!option_slim)
- nodesx->xdata=UnmapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+#endif
/* Print the final message */
{
index_t i;
- /* Check the start conditions */
-
- assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
- assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
+ if(nodesx->number==0 || segmentsx->number==0)
+ return;
/* Print the start message */
/* Map into memory */
- if(!option_slim)
- {
- nodesx->xdata=MapFile(nodesx->filename);
- segmentsx->xdata=MapFile(segmentsx->filename);
- }
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+ segmentsx->xdata=MapFile(segmentsx->filename);
+#endif
/* Index the nodes */
SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
node_t id1=segmentx->node1;
node_t id2=segmentx->node2;
- Node *node1=&nodesx->ndata[id1];
- Node *node2=&nodesx->ndata[id2];
+ Node *node1=LookupNodeXNode(nodesx,id1,1);
+ Node *node2=LookupNodeXNode(nodesx,id2,2);
/* Check node1 */
- if(SEGMENT(node1->firstseg)==SEGMENT(NO_SEGMENT))
+ if(node1->firstseg==NO_SEGMENT)
{
- node1->firstseg^=SEGMENT(NO_SEGMENT);
- node1->firstseg|=i;
+ node1->firstseg=i;
+
+#if SLIM
+ PutBackNodeXNode(nodesx,id1,1);
+#endif
}
else
{
- index_t index=SEGMENT(node1->firstseg);
+ index_t index=node1->firstseg;
do
{
}
else
{
- if(segmentsx->sdata[index].next2==NO_NODE)
+ Segment *segment=LookupSegmentXSegment(segmentsx,index,1);
+
+ if(segment->next2==NO_NODE)
{
- segmentsx->sdata[index].next2=i;
+ segment->next2=i;
+
+#if SLIM
+ PutBackSegmentXSegment(segmentsx,index,1);
+#endif
+
break;
}
else
- index=segmentsx->sdata[index].next2;
+ index=segment->next2;
}
}
while(1);
/* Check node2 */
- if(SEGMENT(node2->firstseg)==SEGMENT(NO_SEGMENT))
+ if(node2->firstseg==NO_SEGMENT)
{
- node2->firstseg^=SEGMENT(NO_SEGMENT);
- node2->firstseg|=i;
+ node2->firstseg=i;
+
+#if SLIM
+ PutBackNodeXNode(nodesx,id2,2);
+#endif
}
else
{
- index_t index=SEGMENT(node2->firstseg);
+ index_t index=node2->firstseg;
do
{
}
else
{
- if(segmentsx->sdata[index].next2==NO_NODE)
+ Segment *segment=LookupSegmentXSegment(segmentsx,index,1);
+
+ if(segment->next2==NO_NODE)
{
- segmentsx->sdata[index].next2=i;
+ segment->next2=i;
+
+#if SLIM
+ PutBackSegmentXSegment(segmentsx,index,1);
+#endif
+
break;
}
else
- index=segmentsx->sdata[index].next2;
+ index=segment->next2;
}
}
while(1);
/* Unmap from memory */
- if(!option_slim)
- {
- nodesx->xdata=UnmapFile(nodesx->filename);
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- }
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+#endif
/* Print the final message */
{
index_t i;
int fd;
- Nodes *nodes;
+ NodesFile nodesfile={0};
int super_number=0;
- /* Check the start conditions */
-
- assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
-
/* Print the start message */
printf("Writing Nodes: Nodes=0");
/* Map into memory */
- if(!option_slim)
- nodesx->xdata=MapFile(nodesx->filename);
-
- /* Count the number of super-nodes */
-
- for(i=0;i<nodesx->number;i++)
- if(nodesx->ndata[i].firstseg&NODE_SUPER)
- super_number++;
-
- /* Fill in a Nodes structure with the offset of the real data in the file after
- the Node structure itself. */
-
- nodes=calloc(1,sizeof(Nodes));
-
- assert(nodes); /* Check calloc() worked */
-
- nodes->number=nodesx->number;
- nodes->snumber=super_number;
-
- nodes->latbins=nodesx->latbins;
- nodes->lonbins=nodesx->lonbins;
-
- nodes->latzero=nodesx->latzero;
- nodes->lonzero=nodesx->lonzero;
-
- nodes->data=NULL;
- nodes->offsets=NULL;
- nodes->nodes=NULL;
-
- /* Write out the Nodes structure and then the real data. */
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+#endif
- fd=OpenFile(filename);
+ /* Write out the nodes data */
- WriteFile(fd,nodes,sizeof(Nodes));
+ fd=OpenFileNew(filename);
+ SeekFile(fd,sizeof(NodesFile));
WriteFile(fd,nodesx->offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t));
- for(i=0;i<nodes->number;i++)
+ for(i=0;i<nodesx->number;i++)
{
NodeX *nodex=LookupNodeX(nodesx,i,1);
- Node *node=&nodesx->ndata[nodex->id];
+ Node *node=LookupNodeXNode(nodesx,nodex->id,1);
+
+ if(node->flags&NODE_SUPER)
+ super_number++;
WriteFile(fd,node,sizeof(Node));
}
}
+ /* Write out the header structure */
+
+ nodesfile.number=nodesx->number;
+ nodesfile.snumber=super_number;
+
+ nodesfile.latbins=nodesx->latbins;
+ nodesfile.lonbins=nodesx->lonbins;
+
+ nodesfile.latzero=nodesx->latzero;
+ nodesfile.lonzero=nodesx->lonzero;
+
+ SeekFile(fd,0);
+ WriteFile(fd,&nodesfile,sizeof(NodesFile));
+
CloseFile(fd);
/* Unmap from memory */
- if(!option_slim)
- nodesx->xdata=UnmapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+#endif
/* Print the final message */
- printf("\rWrote Nodes: Nodes=%d \n",nodes->number);
+ printf("\rWrote Nodes: Nodes=%d \n",nodesx->number);
fflush(stdout);
-
- /* Free the fake Nodes */
-
- free(nodes);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/nodesx.h,v 1.23 2010/03/19 19:47:09 amb Exp $
+ $Header: /home/amb/routino/src/RCS/nodesx.h,v 1.30 2010/08/02 18:44:54 amb Exp $
A header file for the extended nodes.
#include <stdint.h>
-#include "typesx.h"
#include "types.h"
+#include "nodes.h"
+
+#include "typesx.h"
+
+#include "files.h"
/* Data structures */
latlong_t latitude; /*+ The node latitude. +*/
latlong_t longitude; /*+ The node longitude. +*/
+
+ allow_t allow; /*+ The node allowed traffic. +*/
};
/*+ A structure containing a set of nodes (memory format). +*/
char *filename; /*+ The name of the temporary file. +*/
int fd; /*+ The file descriptor of the temporary file. +*/
- uint32_t xnumber; /*+ The number of unsorted extended nodes. +*/
+ index_t xnumber; /*+ The number of unsorted extended nodes. +*/
+
+#if !SLIM
NodeX *xdata; /*+ The extended node data (sorted). +*/
- NodeX cached[2]; /*+ Two cached nodes read from the file in slim mode. +*/
- uint32_t number; /*+ How many entries are still useful? +*/
+#else
+
+ NodeX xcached[2]; /*+ Two cached nodes read from the file in slim mode. +*/
+
+#endif
+
+ index_t number; /*+ How many entries are still useful? +*/
node_t *idata; /*+ The extended node IDs (sorted by ID). +*/
uint8_t *super; /*+ A marker for super nodes (same order sorted nodes). +*/
+#if !SLIM
+
Node *ndata; /*+ The actual nodes (same order as geographically sorted nodes). +*/
- uint32_t latbins; /*+ The number of bins containing latitude. +*/
- uint32_t lonbins; /*+ The number of bins containing longitude. +*/
+#else
+
+ char *nfilename; /*+ The name of the temporary file for nodes in slim mode. +*/
+ int nfd; /*+ The file descriptor of the temporary file. +*/
+
+ Node ncached[2]; /*+ Two cached nodes read from the file in slim mode. +*/
+
+#endif
+
+ index_t latbins; /*+ The number of bins containing latitude. +*/
+ index_t lonbins; /*+ The number of bins containing longitude. +*/
ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/
ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/
- uint32_t latlonbin; /*+ A temporary index into the offsets array. +*/
+ index_t latlonbin; /*+ A temporary index into the offsets array. +*/
index_t *offsets; /*+ An array of offset to the first node in each bin. +*/
};
void SaveNodeList(NodesX *nodesx,const char *filename);
index_t IndexNodeX(NodesX* nodesx,node_t id);
-NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position);
-void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude);
+void AppendNode(NodesX* nodesx,node_t id,double latitude,double longitude,allow_t allow);
void SortNodeList(NodesX *nodesx);
void IndexNodes(NodesX *nodesx,SegmentsX *segmentsx);
+/* Macros / inline functions */
+
+#if !SLIM
+
+#define LookupNodeX(nodesx,index,position) &(nodesx)->xdata[index]
+
+#define LookupNodeXNode(nodesx,index,position) &(nodesx)->ndata[index]
+
+#else
+
+static NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position);
+
+static Node *LookupNodeXNode(NodesX* nodesx,index_t index,int position);
+
+static void PutBackNodeXNode(NodesX* nodesx,index_t index,int position);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a particular extended node.
+
+ NodeX *LookupNodeX Returns a pointer to the extended node with the specified id.
+
+ NodesX* nodesx The set of nodes to process.
+
+ index_t index The node index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline NodeX *LookupNodeX(NodesX* nodesx,index_t index,int position)
+{
+ SeekFile(nodesx->fd,(off_t)index*sizeof(NodeX));
+
+ ReadFile(nodesx->fd,&nodesx->xcached[position-1],sizeof(NodeX));
+
+ return(&nodesx->xcached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a particular extended node's normal node.
+
+ Node *LookupNodeXNode Returns a pointer to the node with the specified id.
+
+ NodesX* nodesx The set of nodes to process.
+
+ index_t index The node index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline Node *LookupNodeXNode(NodesX* nodesx,index_t index,int position)
+{
+ SeekFile(nodesx->nfd,(off_t)index*sizeof(Node));
+
+ ReadFile(nodesx->nfd,&nodesx->ncached[position-1],sizeof(Node));
+
+ return(&nodesx->ncached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Put back an extended node's normal node.
+
+ NodesX* nodesx The set of nodes to process.
+
+ index_t index The node index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline void PutBackNodeXNode(NodesX* nodesx,index_t index,int position)
+{
+ SeekFile(nodesx->nfd,(off_t)index*sizeof(Node));
+
+ WriteFile(nodesx->nfd,&nodesx->ncached[position-1],sizeof(Node));
+}
+
+#endif /* SLIM */
+
+
#endif /* NODESX_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/optimiser.c,v 1.87 2010/07/08 17:33:09 amb Exp $
+ $Header: /home/amb/routino/src/RCS/optimiser.c,v 1.93 2010/08/04 16:44:51 amb Exp $
Routing optimiser.
#include <stdio.h>
#include "types.h"
-#include "functions.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+
+#include "functions.h"
#include "results.h"
Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,index_t start,index_t finish,Profile *profile)
{
Results *results;
- Queue *queue;
+ Queue *queue;
index_t node1,node2;
score_t finish_score;
double finish_lat,finish_lon;
- Result *result1,*result2;
+ Result *result1,*result2;
+ Node *node;
Segment *segment;
- Way *way;
+ Way *way;
/* Set up the finish conditions */
if(node2!=finish && !IsFakeNode(node2) && IsSuperNode(nodes,node2))
goto endloop;
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!(way->allow&profile->allow))
goto endloop;
segment_pref=profile->highway[HIGHWAY(way->type)];
for(i=1;i<Property_Count;i++)
- if(ways->props & PROPERTIES(i))
+ if(ways->file.props & PROPERTIES(i))
{
if(way->props & PROPERTIES(i))
segment_pref*=profile->props_yes[i];
if(segment_pref==0)
goto endloop;
+ if(!IsFakeNode(node2))
+ {
+ node=LookupNode(nodes,node2,1);
+
+ if(!(node->allow&profile->allow))
+ goto endloop;
+ }
+
if(option_quickest==0)
segment_score=(score_t)DISTANCE(segment->distance)/segment_pref;
else
result2->prev=node1;
result2->next=NO_NODE;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(node2==finish)
{
{
result2->prev=node1;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(node2==finish)
{
Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Results *begin,Results *end,Profile *profile)
{
Results *results;
- Queue *queue;
+ Queue *queue;
index_t node1,node2;
index_t end_prev;
score_t finish_score;
double finish_lat,finish_lon;
- Result *result1,*result2,*result3;
+ Result *result1,*result2,*result3;
+ Node *node;
Segment *segment;
- Way *way;
+ Way *way;
if(!option_quiet)
{
if(result1->prev==node2)
goto endloop;
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!(way->allow&profile->allow))
goto endloop;
segment_pref=profile->highway[HIGHWAY(way->type)];
for(i=1;i<Property_Count;i++)
- if(ways->props & PROPERTIES(i))
+ if(ways->file.props & PROPERTIES(i))
{
if(way->props & PROPERTIES(i))
segment_pref*=profile->props_yes[i];
if(segment_pref==0)
goto endloop;
+ node=LookupNode(nodes,node2,1);
+
+ if(!(node->allow&profile->allow))
+ goto endloop;
+
if(option_quickest==0)
segment_score=(score_t)DISTANCE(segment->distance)/segment_pref;
else
result2->prev=node1;
result2->next=NO_NODE;
result2->score=cumulative_score;
- result2->segment=segment;
+ result2->segment=IndexSegment(segments,segment);
if((result3=FindResult(end,node2)))
{
{
result2->prev=node1;
result2->score=cumulative_score;
- result2->segment=segment;
+ result2->segment=IndexSegment(segments,segment);
if((result3=FindResult(end,node2)))
{
Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t start,Profile *profile)
{
Results *results;
- Queue *queue;
+ Queue *queue;
index_t node1,node2;
- Result *result1,*result2;
+ Result *result1,*result2;
+ Node *node;
Segment *segment;
- Way *way;
+ Way *way;
/* Insert the first node into the queue */
if(result1->prev==node2)
goto endloop;
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!(way->allow&profile->allow))
goto endloop;
segment_pref=profile->highway[HIGHWAY(way->type)];
for(i=1;i<Property_Count;i++)
- if(ways->props & PROPERTIES(i))
+ if(ways->file.props & PROPERTIES(i))
{
if(way->props & PROPERTIES(i))
segment_pref*=profile->props_yes[i];
if(segment_pref==0)
goto endloop;
+ if(!IsFakeNode(node2))
+ {
+ node=LookupNode(nodes,node2,1);
+
+ if(!(node->allow&profile->allow))
+ goto endloop;
+ }
+
if(option_quickest==0)
segment_score=(score_t)DISTANCE(segment->distance)/segment_pref;
else
result2->prev=node1;
result2->next=NO_NODE;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(!IsFakeNode(node2) && !IsSuperNode(nodes,node2))
{
{
result2->prev=node1;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(!IsFakeNode(node2) && !IsSuperNode(nodes,node2))
{
Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,index_t finish,Profile *profile)
{
Results *results;
- Queue *queue;
+ Queue *queue;
index_t node1,node2;
- Result *result1,*result2;
+ Result *result1,*result2;
+ Node *node;
Segment *segment;
- Way *way;
+ Way *way;
/* Insert the first node into the queue */
if(result1->next==node2)
goto endloop;
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!(way->allow&profile->allow))
goto endloop;
segment_pref=profile->highway[HIGHWAY(way->type)];
for(i=1;i<Property_Count;i++)
- if(ways->props & PROPERTIES(i))
+ if(ways->file.props & PROPERTIES(i))
{
if(way->props & PROPERTIES(i))
segment_pref*=profile->props_yes[i];
if(segment_pref==0)
goto endloop;
+ if(!IsFakeNode(node2))
+ {
+ node=LookupNode(nodes,node2,1);
+
+ if(!(node->allow&profile->allow))
+ goto endloop;
+ }
+
if(option_quickest==0)
segment_score=(score_t)DISTANCE(segment->distance)/segment_pref;
else
result2->prev=NO_NODE;
result2->next=node1;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(!IsFakeNode(node2) && !IsSuperNode(nodes,node2))
{
{
result2->next=node1;
result2->score=cumulative_score;
- result2->segment=segment;
+ if(IsFakeNode(node1) || IsFakeNode(node2))
+ result2->segment=IndexFakeSegment(segment);
+ else
+ result2->segment=IndexSegment(segments,segment);
if(!IsFakeNode(node2) && !IsSuperNode(nodes,node2))
{
/***************************************
- $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.69 2010/05/29 13:54:23 amb Exp $
+ $Header: /home/amb/routino/src/RCS/osmparser.c,v 1.72 2010/09/25 18:47:32 amb Exp $
OSM XML file parser (either JOSM or planet)
#include "typesx.h"
#include "functionsx.h"
+
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
+#include "relationsx.h"
+
#include "xmlparse.h"
#include "tagging.h"
static node_t *way_nodes=NULL;
static int way_nnodes=0;
-static NodesX *nodes;
-static SegmentsX *segments;
-static WaysX *ways;
+static node_t *relation_nodes=NULL;
+static int relation_nnodes=0;
+static way_t *relation_ways=NULL;
+static int relation_nways=0;
+static relation_t *relation_relations=NULL;
+static int relation_nrelations=0;
+
+static NodesX *nodes;
+static SegmentsX *segments;
+static WaysX *ways;
+static RelationsX *relations;
/* Local functions */
+static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude);
static void process_way_tags(TagList *tags,way_t id);
+static void process_relation_tags(TagList *tags,relation_t id);
/* The XML tag processing function prototypes */
//static int osmType_function(const char *_tag_,int _type_);
static int relationType_function(const char *_tag_,int _type_,const char *id);
static int wayType_function(const char *_tag_,int _type_,const char *id);
-//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
+static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role);
static int ndType_function(const char *_tag_,int _type_,const char *ref);
static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon);
static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v);
static xmltag memberType_tag=
{"member",
3, {"type","ref","role"},
- NULL,
+ memberType_function,
{NULL}};
/*+ The wayType type tag. +*/
static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon)
{
+ static node_t node_id;
+ static double latitude,longitude;
+
if(_type_&XMLPARSE_TAG_START)
{
- node_t node_id;
- double latitude,longitude;
-
nnodes++;
if(!(nnodes%1000))
fflush(stdout);
}
+ current_tags=NewTagList();
+
/* Handle the node information */
XMLPARSE_ASSERT_STRING(_tag_,id); node_id=atoll(id); /* need long long conversion */
XMLPARSE_ASSERT_FLOATING(_tag_,lat,latitude);
XMLPARSE_ASSERT_FLOATING(_tag_,lon,longitude);
+ }
- AppendNode(nodes,node_id,degrees_to_radians(latitude),degrees_to_radians(longitude));
+ if(_type_&XMLPARSE_TAG_END)
+ {
+ TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
-// current_tags=NewTagList();
- current_tags=NULL;
- }
+ process_node_tags(result,node_id,latitude,longitude);
-// if(_type_&XMLPARSE_TAG_END)
-// {
-// TagList *result=ApplyTaggingRules(&NodeRules,current_tags);
-//
-// DeleteTagList(current_tags);
-// DeleteTagList(result);
-// }
+ DeleteTagList(current_tags);
+ DeleteTagList(result);
+ }
return(0);
}
XMLPARSE_ASSERT_STRING(_tag_,ref); node_id=atoll(ref); /* need long long conversion */
- if((way_nnodes%256)==0)
+ if(way_nnodes && (way_nnodes%256)==0)
way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t));
way_nodes[way_nnodes++]=node_id;
const char *role The contents of the 'role' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-//static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
-//{
-// return(0);
-//}
+static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role)
+{
+ if(_type_&XMLPARSE_TAG_START)
+ {
+ XMLPARSE_ASSERT_STRING(_tag_,type);
+ XMLPARSE_ASSERT_STRING(_tag_,ref);
+
+ if(!strcmp(type,"node"))
+ {
+ node_t node_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nnodes && (relation_nnodes%256)==0)
+ relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t));
+
+ relation_nodes[relation_nnodes++]=node_id;
+ }
+ else if(!strcmp(type,"way"))
+ {
+ way_t way_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nways && (relation_nways%256)==0)
+ relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t));
+
+ relation_ways[relation_nways++]=way_id;
+ }
+ else if(!strcmp(type,"relation"))
+ {
+ relation_t relation_id=atoll(ref); /* need long long conversion */
+
+ if(relation_nrelations && (relation_nrelations%256)==0)
+ relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t));
+
+ relation_relations[relation_nrelations++]=relation_id;
+ }
+ }
+
+ return(0);
+}
/*++++++++++++++++++++++++++++++++++++++
}
current_tags=NewTagList();
+
way_nnodes=0;
/* Handle the way information */
static int relationType_function(const char *_tag_,int _type_,const char *id)
{
+ static relation_t relation_id;
+
if(_type_&XMLPARSE_TAG_START)
{
nrelations++;
fflush(stdout);
}
-// current_tags=NewTagList();
- current_tags=NULL;
+ current_tags=NewTagList();
+
+ relation_nnodes=relation_nways=relation_nrelations=0;
+
+ /* Handle the relation information */
+
+ XMLPARSE_ASSERT_STRING(_tag_,id); relation_id=atoll(id); /* need long long conversion */
}
-// if(_type_&XMLPARSE_TAG_END)
-// {
-// TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
-//
-// DeleteTagList(current_tags);
-// DeleteTagList(result);
-// }
+ if(_type_&XMLPARSE_TAG_END)
+ {
+ TagList *result=ApplyTaggingRules(&RelationRules,current_tags);
+
+ process_relation_tags(result,relation_id);
+
+ DeleteTagList(current_tags);
+ DeleteTagList(result);
+ }
return(0);
}
FILE *file The file to read from.
- NodesX *OSMNodes The array of nodes to fill in.
+ NodesX *OSMNodes The data structure of nodes to fill in.
+
+ SegmentsX *OSMSegments The data structure of segments to fill in.
- SegmentsX *OSMSegments The array of segments to fill in.
+ WaysX *OSMWays The data structure of ways to fill in.
- WaysX *OSMWays The arrray of ways to fill in.
+ RelationsX *OSMRelations The data structure of relations to fill in.
++++++++++++++++++++++++++++++++++++++*/
-int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays)
+int ParseOSM(FILE *file,NodesX *OSMNodes,SegmentsX *OSMSegments,WaysX *OSMWays,RelationsX *OSMRelations)
{
int retval;
- /* Parse the file */
+ /* Copy the function parameters and initialise the variables. */
nodes=OSMNodes;
segments=OSMSegments;
ways=OSMWays;
+ relations=OSMRelations;
+
+ way_nodes=(node_t*)malloc(256*sizeof(node_t));
+
+ relation_nodes =(node_t *)malloc(256*sizeof(node_t));
+ relation_ways =(way_t *)malloc(256*sizeof(way_t));
+ relation_relations=(relation_t*)malloc(256*sizeof(relation_t));
+
+ /* Parse the file */
nnodes=0,nways=0,nrelations=0;
/*++++++++++++++++++++++++++++++++++++++
+ Process the tags associated with a node.
+
+ TagList *tags The list of node tags.
+
+ node_t id The id of the node.
+
+ double latitude The latitude of the node.
+
+ double longitude The longitude of the node.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static void process_node_tags(TagList *tags,node_t id,double latitude,double longitude)
+{
+ allow_t allow=Allow_ALL;
+
+ int i;
+
+ /* Parse the tags */
+
+ for(i=0;i<tags->ntags;i++)
+ {
+ char *k=tags->k[i];
+ char *v=tags->v[i];
+
+ switch(*k)
+ {
+ case 'b':
+ if(!strcmp(k,"bicycle"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Bicycle;
+
+ break;
+
+ case 'f':
+ if(!strcmp(k,"foot"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Foot;
+
+ break;
+
+ case 'g':
+ if(!strcmp(k,"goods"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Goods;
+
+ break;
+
+ case 'h':
+ if(!strcmp(k,"horse"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Horse;
+
+ if(!strcmp(k,"hgv"))
+ if(!ISTRUE(v))
+ allow&=~Allow_HGV;
+
+ break;
+
+ case 'm':
+ if(!strcmp(k,"moped"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Moped;
+
+ if(!strcmp(k,"motorbike"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Motorbike;
+
+ if(!strcmp(k,"motorcar"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Motorcar;
+
+ break;
+
+ case 'p':
+ if(!strcmp(k,"psv"))
+ if(!ISTRUE(v))
+ allow&=~Allow_PSV;
+
+ break;
+
+ case 'w':
+ if(!strcmp(k,"wheelchair"))
+ if(!ISTRUE(v))
+ allow&=~Allow_Wheelchair;
+
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ /* Create the node */
+
+ AppendNode(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
Process the tags associated with a way.
TagList *tags The list of way tags.
if(ISTRUE(v))
way.allow|= Allow_Bicycle;
+ if(!strcmp(k,"bicycleroute"))
+ if(ISTRUE(v))
+ way.props|=Properties_BicycleRoute;
+
if(!strcmp(k,"bridge"))
if(ISTRUE(v))
way.props|=Properties_Bridge;
if(ISTRUE(v))
way.allow|= Allow_Foot;
+ if(!strcmp(k,"footroute"))
+ if(ISTRUE(v))
+ way.props|=Properties_FootRoute;
+
break;
case 'g':
}
}
}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Process the tags associated with a relation.
+
+ TagList *tags The list of relation tags.
+
+ relation_t id The id of the relation.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static void process_relation_tags(TagList *tags,relation_t id)
+{
+ allow_t routes=Allow_None;
+ int i;
+
+ /* Parse the tags */
+
+ for(i=0;i<tags->ntags;i++)
+ {
+ char *k=tags->k[i];
+ char *v=tags->v[i];
+
+ switch(*k)
+ {
+ case 'b':
+ if(!strcmp(k,"bicycleroute"))
+ if(ISTRUE(v))
+ routes|=Allow_Bicycle;
+
+ break;
+
+ case 'f':
+ if(!strcmp(k,"footroute"))
+ if(ISTRUE(v))
+ routes|=Allow_Foot;
+
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ /* Create the route relation (must store all relations that have ways or
+ relations even if they are not routes because they might be referenced by
+ other relations that are routes) */
+
+ if(relation_nways || relation_nrelations)
+ AppendRouteRelation(relations,id,routes,
+ relation_ways,relation_nways,
+ relation_relations,relation_nrelations);
+}
/***************************************
- $Header: /home/amb/routino/src/RCS/output.c,v 1.33 2010/07/07 17:31:06 amb Exp $
+ $Header: /home/amb/routino/src/RCS/output.c,v 1.40 2010/09/15 18:30:08 amb Exp $
Routing output generator.
#include <unistd.h>
#include "types.h"
-#include "functions.h"
-#include "translations.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+
+#include "files.h"
+#include "functions.h"
+#include "translations.h"
#include "results.h"
#include "xmlparse.h"
/*+ Heuristics for determining if a junction is important. +*/
static char junction_other_way[Way_Count][Way_Count]=
- { /* M, T, P, S, T, U, R, S, T, C, P, S = Way type of route not taken */
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Motorway */
- { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Trunk */
- { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Primary */
- { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, /* Secondary */
- { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, /* Tertiary */
- { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }, /* Unclassified */
- { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, /* Residential */
- { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, /* Service */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, /* Track */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, /* Cycleway */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
- { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */
+ { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway */
+ { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk */
+ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Primary */
+ { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Secondary */
+ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Tertiary */
+ { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 }, /* Unclassified */
+ { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, /* Residential */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, /* Service */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 }, /* Track */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, /* Cycleway */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Ferry */
};
fprintf(htmlfile,"<TITLE>");
fprintf(htmlfile,translate_html_title,option_quickest?translate_route_quickest:translate_route_shortest);
fprintf(htmlfile,"</TITLE>\n");
- fprintf(htmlfile,"<STYLE type='text/css'>\n");
+ fprintf(htmlfile,"<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
+ fprintf(htmlfile,"<STYLE type=\"text/css\">\n");
fprintf(htmlfile,"<!--\n");
fprintf(htmlfile," table {table-layout: fixed; border: none; border-collapse: collapse;}\n");
fprintf(htmlfile," table.c {color: grey; font-size: x-small;} /* copyright */\n");
{
double latitude,longitude;
Result *nextresult;
+ Segment *nextresultsegment;
if(result->node==results[point]->start)
{latitude=start_lat; longitude=start_lon;}
break;
}
+ if(nextresult)
+ {
+ if(IsFakeSegment(nextresult->segment))
+ nextresultsegment=LookupFakeSegment(nextresult->segment);
+ else
+ nextresultsegment=LookupSegment(segments,nextresult->segment,2);
+ }
+ else
+ nextresultsegment=NULL;
+
if(result->node!=results[point]->start)
{
distance_t seg_distance=0;
duration_t seg_duration=0;
+ Segment *resultsegment;
Way *resultway;
int important=0;
/* Cache the values to be printed rather than calculating them repeatedly for each output format */
- char *waynameraw=NULL,*wayname=NULL,*waynamexml=NULL;
+ char *waynameraw=NULL,*waynamexml=NULL;
+ const char *wayname=NULL;
int bearing_int=0,bearing_next_int=0,turn_int=0;
char *bearing_str=NULL,*bearing_next_str=NULL,*turn_str=NULL;
/* Get the properties of this segment */
- resultway=LookupWay(ways,result->segment->way);
+ if(IsFakeSegment(result->segment))
+ resultsegment=LookupFakeSegment(result->segment);
+ else
+ resultsegment=LookupSegment(segments,result->segment,3);
+ resultway=LookupWay(ways,resultsegment->way,1);
- seg_distance+=DISTANCE(result->segment->distance);
- seg_duration+=Duration(result->segment,resultway,profile);
+ seg_distance+=DISTANCE(resultsegment->distance);
+ seg_duration+=Duration(resultsegment,resultway,profile);
junc_distance+=seg_distance;
junc_duration+=seg_duration;
cum_distance+=seg_distance;
{
index_t othernode=OtherNode(segment,result->node);
- if(othernode!=result->prev && segment!=result->segment)
+ if(othernode!=result->prev && segment!=resultsegment)
if(IsNormalSegment(segment) && (!profile->oneway || !IsOnewayTo(segment,result->node)))
{
- Way *way=LookupWay(ways,segment->way);
+ Way *way=LookupWay(ways,segment->way,2);
if(othernode==result->next) /* the next segment that we follow */
{
if(!waynameraw)
{
- waynameraw=WayNameRaw(ways,resultway);
+ waynameraw=WayName(ways,resultway);
if(!*waynameraw)
waynameraw=translate_highway[HIGHWAY(resultway->type)];
}
{
if(!turn_str)
{
- turn_int=turn_angle(nodes,result->segment,nextresult->segment,result->node);
+ turn_int=turn_angle(nodes,resultsegment,nextresultsegment,result->node);
turn_str=translate_turn[(4+(22+turn_int)/45)%8];
}
if(!bearing_next_str)
{
- bearing_next_int=bearing_angle(nodes,nextresult->segment,nextresult->node);
+ bearing_next_int=bearing_angle(nodes,nextresultsegment,nextresult->node);
bearing_next_str=translate_heading[(4+(22+bearing_next_int)/45)%8];
}
{
if(!waynameraw)
{
- waynameraw=WayNameRaw(ways,resultway);
+ waynameraw=WayName(ways,resultway);
if(!*waynameraw)
waynameraw=translate_highway[HIGHWAY(resultway->type)];
}
if(!bearing_str)
{
- bearing_int=bearing_angle(nodes,result->segment,result->node);
+ bearing_int=bearing_angle(nodes,resultsegment,result->node);
bearing_str=translate_heading[(4+(22+bearing_int)/45)%8];
}
type="Junct";
if(!wayname)
- wayname=(char*)WayNameHighway(ways,resultway);
+ {
+ wayname=WayName(ways,resultway);
+ if(!*wayname)
+ wayname=HighwayName(HIGHWAY(resultway->type));
+ }
if(nextresult)
{
if(!turn_str)
{
- turn_int=turn_angle(nodes,result->segment,nextresult->segment,result->node);
+ turn_int=turn_angle(nodes,resultsegment,nextresultsegment,result->node);
turn_str=translate_turn[(4+(22+turn_int)/45)%8];
}
if(!bearing_next_str)
{
- bearing_next_int=bearing_angle(nodes,nextresult->segment,nextresult->node);
+ bearing_next_int=bearing_angle(nodes,nextresultsegment,nextresult->node);
bearing_next_str=translate_heading[(4+(22+bearing_next_int)/45)%8];
}
type="Inter";
if(!wayname)
- wayname=(char*)WayNameHighway(ways,resultway);
+ {
+ wayname=WayName(ways,resultway);
+ if(!*wayname)
+ wayname=HighwayName(HIGHWAY(resultway->type));
+ }
if(!bearing_str)
{
- bearing_int=bearing_angle(nodes,result->segment,result->node);
+ bearing_int=bearing_angle(nodes,resultsegment,result->node);
bearing_str=translate_heading[(4+(22+bearing_int)/45)%8];
}
fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n",
radians_to_degrees(latitude),radians_to_degrees(longitude),
- IsFakeNode(result->node)?-(result->node&(~NODE_SUPER)):result->node,
+ IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
(!IsFakeNode(result->node) && IsSuperNode(nodes,result->node))?'*':' ',type,
distance_to_km(seg_distance),duration_to_minutes(seg_duration),
distance_to_km(cum_distance),duration_to_minutes(cum_duration),
}
else if(!cum_distance)
{
- int bearing_next_int=bearing_angle(nodes,nextresult->segment,nextresult->node);
+ int bearing_next_int=bearing_angle(nodes,nextresultsegment,nextresult->node);
char *bearing_next_str=translate_heading[(4+(22+bearing_next_int)/45)%8];
/* Print out the very first start point */
if(textallfile)
fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t\t\t\n",
radians_to_degrees(latitude),radians_to_degrees(longitude),
- IsFakeNode(result->node)?-(result->node&(~NODE_SUPER)):result->node,
+ IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node,
(!IsFakeNode(result->node) && IsSuperNode(nodes,result->node))?'*':' ',"Waypt",
0.0,0.0,0.0,0.0);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/planetsplitter.c,v 1.73 2010/05/22 18:40:47 amb Exp $
+ $Header: /home/amb/routino/src/RCS/planetsplitter.c,v 1.81 2010/09/17 18:38:39 amb Exp $
OSM planet file splitter.
#include <string.h>
#include <errno.h>
-#include "typesx.h"
#include "types.h"
-#include "functionsx.h"
-#include "functions.h"
+#include "ways.h"
+
+#include "typesx.h"
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
+#include "relationsx.h"
#include "superx.h"
-#include "ways.h"
+
+#include "files.h"
+#include "functions.h"
+#include "functionsx.h"
#include "tagging.h"
/* Global variables */
-/*+ The option to use a slim mode with file-backed read-only intermediate storage. +*/
-int option_slim=0;
-
/*+ The name of the temporary directory. +*/
char *option_tmpdirname=NULL;
/* Local functions */
-static void print_usage(int detail);
+static void print_usage(int detail,const char *argerr,const char *err);
/*++++++++++++++++++++++++++++++++++++++
int main(int argc,char** argv)
{
- NodesX *Nodes;
- SegmentsX *Segments,*SuperSegments=NULL,*MergedSegments=NULL;
- WaysX *Ways;
- int iteration=0,quit=0;
- int max_iterations=10;
- char *dirname=NULL,*prefix=NULL,*tagging=NULL;
- int option_parse_only=0,option_process_only=0;
- int option_filenames=0;
- int arg;
+ NodesX *Nodes;
+ SegmentsX *Segments,*SuperSegments=NULL,*MergedSegments=NULL;
+ WaysX *Ways;
+ RelationsX *Relations;
+ int iteration=0,quit=0;
+ int max_iterations=10;
+ char *dirname=NULL,*prefix=NULL,*tagging=NULL;
+ int option_parse_only=0,option_process_only=0;
+ int option_filenames=0;
+ int arg;
/* Parse the command line arguments */
for(arg=1;arg<argc;arg++)
{
if(!strcmp(argv[arg],"--help"))
- print_usage(1);
- else if(!strcmp(argv[arg],"--slim"))
- option_slim=1;
+ print_usage(1,NULL,NULL);
else if(!strncmp(argv[arg],"--sort-ram-size=",16))
option_filesort_ramsize=atoi(&argv[arg][16]);
else if(!strncmp(argv[arg],"--dir=",6))
else if(!strncmp(argv[arg],"--tagging=",10))
tagging=&argv[arg][10];
else if(argv[arg][0]=='-' && argv[arg][1]=='-')
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
else
option_filenames++;
}
/* Check the specified command line options */
if(option_parse_only && option_process_only)
- print_usage(0);
+ print_usage(0,NULL,"Cannot use '--parse-only' and '--process-only' at the same time.");
if(option_filenames && option_process_only)
- print_usage(0);
+ print_usage(0,NULL,"Cannot use '--process-only' and filenames at the same time.");
if(!option_filesort_ramsize)
{
- if(option_slim)
+#if SLIM
option_filesort_ramsize=64*1024*1024;
- else
+#else
option_filesort_ramsize=256*1024*1024;
+#endif
}
else
option_filesort_ramsize*=1024*1024;
option_tmpdirname=dirname;
}
- if(tagging && ExistsFile(tagging))
- ;
- else if(!tagging && ExistsFile(FileName(dirname,prefix,"tagging.xml")))
- tagging=FileName(dirname,prefix,"tagging.xml");
-
- if(tagging && ParseXMLTaggingRules(tagging))
+ if(tagging)
{
- fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
- return(1);
+ if(!ExistsFile(tagging))
+ {
+ fprintf(stderr,"Error: The '--tagging' option specifies a file that does not exist.\n");
+ return(1);
+ }
+ }
+ else
+ {
+ if(ExistsFile(FileName(dirname,prefix,"tagging.xml")))
+ tagging=FileName(dirname,prefix,"tagging.xml");
+ else if(ExistsFile(FileName(DATADIR,NULL,"tagging.xml")))
+ tagging=FileName(DATADIR,NULL,"tagging.xml");
+ else
+ {
+ fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
+ return(1);
+ }
}
- if(!tagging)
+ if(ParseXMLTaggingRules(tagging))
{
- fprintf(stderr,"Error: Cannot run without reading some tagging rules.\n");
+ fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
return(1);
}
- /* Create new node, segment and way variables */
+ /* Create new node, segment, way and relation variables */
Nodes=NewNodeList(option_parse_only||option_process_only);
Ways=NewWayList(option_parse_only||option_process_only);
+ Relations=NewRelationList(option_parse_only||option_process_only);
+
/* Parse the file */
if(option_filenames)
printf("\nParse OSM Data [%s]\n==============\n\n",argv[arg]);
fflush(stdout);
- if(ParseOSM(file,Nodes,Segments,Ways))
+ if(ParseOSM(file,Nodes,Segments,Ways,Relations))
exit(EXIT_FAILURE);
fclose(file);
printf("\nParse OSM Data\n==============\n\n");
fflush(stdout);
- if(ParseOSM(stdin,Nodes,Segments,Ways))
+ if(ParseOSM(stdin,Nodes,Segments,Ways,Relations))
exit(EXIT_FAILURE);
}
FreeNodeList(Nodes,1);
FreeSegmentList(Segments,1);
FreeWayList(Ways,1);
+ FreeRelationList(Relations,1);
return(0);
}
printf("\nProcess OSM Data\n================\n\n");
fflush(stdout);
- /* Sort the nodes, segments and ways */
+ /* Sort the nodes, segments, ways and relations */
SortNodeList(Nodes);
SortWayList(Ways);
+ SortRelationList(Relations);
+
+ /* Process the route relations (must be before compacting the ways) */
+
+ ProcessRouteRelations(Relations,Ways);
+
+ FreeRelationList(Relations,0);
+
+ /* Compact the ways (must be before measuring the segments) */
+
+ CompactWayList(Ways);
+
/* Remove bad segments (must be after sorting the nodes and segments) */
RemoveBadSegments(Nodes,Segments);
Print out the usage information.
int detail The level of detail to use - 0 = low, 1 = high.
+
+ const char *argerr The argument that gave the error (if there is one).
+
+ const char *err Other error message (if there is one).
++++++++++++++++++++++++++++++++++++++*/
-static void print_usage(int detail)
+static void print_usage(int detail,const char *argerr,const char *err)
{
fprintf(stderr,
"Usage: planetsplitter [--help]\n"
" [--dir=<dirname>] [--prefix=<name>]\n"
- " [--slim] [--sort-ram-size=<size>]\n"
+ " [--sort-ram-size=<size>]\n"
" [--tmpdir=<dirname>]\n"
" [--parse-only | --process-only]\n"
" [--max-iterations=<number>]\n"
" [--tagging=<filename>]\n"
" [<filename.osm> ...]\n");
+ if(argerr)
+ fprintf(stderr,
+ "\n"
+ "Error with command line parameter: %s\n",argerr);
+
+ if(err)
+ fprintf(stderr,
+ "\n"
+ "Error: %s\n",err);
+
if(detail)
fprintf(stderr,
"\n"
"--dir=<dirname> The directory containing the routing database.\n"
"--prefix=<name> The filename prefix for the routing database.\n"
"\n"
- "--slim Use less RAM and more temporary files.\n"
"--sort-ram-size=<size> The amount of RAM (in MB) to use for data sorting\n"
- " (defaults to 64MB with '--slim' or 256MB otherwise.)\n"
+#if SLIM
+ " (defaults to 64MB otherwise.)\n"
+#else
+ " (defaults to 256MB otherwise.)\n"
+#endif
"--tmpdir=<dirname> The directory name for temporary files.\n"
" (defaults to the '--dir' option directory.)\n"
"\n"
"--max-iterations=<number> The number of iterations for finding super-nodes.\n"
"\n"
"--tagging=<filename> The name of the XML file containing the tagging rules\n"
- " (defaults to 'tagging.xml' with '--dirname' and\n"
- " '--prefix' options).\n"
+ " (defaults to 'tagging.xml' with '--dir' and\n"
+ " '--prefix' options or the file installed in\n"
+ " '" DATADIR "').\n"
"\n"
"<filename.osm> ... The name(s) of the file(s) to process (by default\n"
" data is read from standard input).\n"
/***************************************
- $Header: /home/amb/routino/src/RCS/profiles.c,v 1.42 2010/05/29 10:37:12 amb Exp $
+ $Header: /home/amb/routino/src/RCS/profiles.c,v 1.47 2010/10/18 17:40:34 amb Exp $
Load the profiles from a file and the functions for handling them.
#include <string.h>
#include <stdlib.h>
-#include "profiles.h"
#include "types.h"
#include "ways.h"
-#include "xmlparse.h"
+
+#include "files.h"
+#include "profiles.h"
#include "functions.h"
+#include "xmlparse.h"
/*+ The profiles that have been loaded from file. +*/
profile->allow=ALLOWED(profile->transport);
- if(!(profile->allow & ways->allow))
+ if(!(profile->allow & ways->file.allow))
return(1);
- /* Normalise the highway preferences into the range 0 -> 1 */
+ /* Normalise the highway preferences into the range ~0 -> 1 */
for(i=1;i<Way_Count;i++)
{
return(1);
for(i=1;i<Way_Count;i++)
+ {
profile->highway[i]/=hmax;
- /* Normalise the property preferences into the range 0 -> 2 */
+ if(profile->highway[i]<0.0001)
+ profile->highway[i]=0.0001;
+ }
+
+ /* Normalise the property preferences into the range ~0 -> 1 */
for(i=1;i<Property_Count;i++)
{
if(profile->props_yes[i]>100)
profile->props_yes[i]=100;
- profile->props_yes[i]/=50;
- profile->props_no [i] =2-profile->props_yes[i];
+ profile->props_yes[i]/=100;
+ profile->props_no [i] =1-profile->props_yes[i];
+
+ /* Squash the properties; selecting 60% preference without the sqrt() allows
+ routes 50% longer on highways with the property compared to ones without.
+ With the sqrt() function the ratio is only 22% allowing finer control. */
+
+ profile->props_yes[i] =sqrt(profile->props_yes[i]);
+ profile->props_no [i] =sqrt(profile->props_no[i] );
+
+ if(profile->props_yes[i]<0.0001)
+ profile->props_yes[i]=0.0001;
+
+ if(profile->props_no[i]<0.0001)
+ profile->props_no[i]=0.0001;
}
/* Find the fastest preferred speed */
profile->max_pref=1; /* since highway prefs were normalised to 1 */
for(i=1;i<Property_Count;i++)
- if(ways->props & PROPERTIES(i))
+ if(ways->file.props & PROPERTIES(i))
{
if(profile->props_yes[i]>profile->props_no[i])
profile->max_pref*=profile->props_yes[i];
printf("\n");
printf(" // Transport types\n");
- printf(" transports: {");
+ printf(" transports: { ");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j);
- printf("},\n");
+ printf("%s%s: %d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),j+1);
+ printf(" },\n");
printf("\n");
printf(" // Highway types\n");
- printf(" highways: {");
+ printf(" highways: { ");
for(i=1;i<Way_Count;i++)
printf("%s%s: %d",i==1?"":", ",HighwayName(i),i);
- printf("},\n");
+ printf(" },\n");
printf("\n");
printf(" // Property types\n");
- printf(" properties: {");
+ printf(" properties: { ");
for(i=1;i<Property_Count;i++)
printf("%s%s: %d",i==1?"":", ",PropertyName(i),i);
- printf("},\n");
+ printf(" },\n");
printf("\n");
printf(" // Restriction types\n");
- printf(" restrictions: {oneway: 1, weight: 2, height: 3, width: 4, length: 5},\n");
+ printf(" restrictions: { oneway: 1, weight: 2, height: 3, width: 4, length: 5 },\n");
printf("\n");
printf(" // Allowed highways\n");
printf(" profile_highway: {\n");
for(i=1;i<Way_Count;i++)
{
- printf(" %12s: {",HighwayName(i));
+ printf(" %12s: { ",HighwayName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
- printf("}%s\n",i==(Way_Count-1)?"":",");
+ printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
+ printf(" }%s\n",i==(Way_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
printf(" profile_speed: {\n");
for(i=1;i<Way_Count;i++)
{
- printf(" %12s: {",HighwayName(i));
+ printf(" %12s: { ",HighwayName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
- printf("}%s\n",i==(Way_Count-1)?"":",");
+ printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
+ printf(" }%s\n",i==(Way_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
printf(" profile_property: {\n");
for(i=1;i<Property_Count;i++)
{
- printf(" %12s: {",PropertyName(i));
+ printf(" %12s: { ",PropertyName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
- printf("}%s\n",i==(Property_Count-1)?"":",");
+ printf("%s%s: %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
+ printf(" }%s\n",i==(Property_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
printf(" // Restrictions\n");
printf(" profile_restrictions: {\n");
- printf(" %12s: {","oneway");
+ printf(" %12s: { ","oneway");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
- printf("},\n");
- printf(" %12s: {","weight");
+ printf("%s%s: %4d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
+ printf(" },\n");
+ printf(" %12s: { ","weight");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
- printf("},\n");
- printf(" %12s: {","height");
+ printf("%s%s: %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
+ printf(" },\n");
+ printf(" %12s: { ","height");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
- printf("},\n");
- printf(" %12s: {","width");
+ printf("%s%s: %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
+ printf(" },\n");
+ printf(" %12s: { ","width");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
- printf("},\n");
- printf(" %12s: {","length");
+ printf("%s%s: %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
+ printf(" },\n");
+ printf(" %12s: { ","length");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s: %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
- printf("}\n");
+ printf("%s%s: %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
+ printf(" }\n");
printf(" }\n");
printf("\n");
printf("\n");
printf(" # Transport types\n");
- printf(" transports => {");
+ printf(" transports => { ");
for(j=0;j<nloaded_profiles;j++)
- printf("%s%s => %d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),j);
- printf("},\n");
+ printf("%s%s => %d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),j+1);
+ printf(" },\n");
printf("\n");
printf(" # Highway types\n");
- printf(" highways => {");
+ printf(" highways => { ");
for(i=1;i<Way_Count;i++)
printf("%s%s => %d",i==1?"":", ",HighwayName(i),i);
- printf("},\n");
+ printf(" },\n");
printf("\n");
printf(" # Property types\n");
- printf(" properties => {");
+ printf(" properties => { ");
for(i=1;i<Property_Count;i++)
printf("%s%s => %d",i==1?"":", ",PropertyName(i),i);
- printf("},\n");
+ printf(" },\n");
printf("\n");
printf(" # Restriction types\n");
- printf(" restrictions => {oneway => 1, weight => 2, height => 3, width => 4, length => 5},\n");
+ printf(" restrictions => { oneway => 1, weight => 2, height => 3, width => 4, length => 5 },\n");
printf("\n");
printf(" # Allowed highways\n");
{
printf(" %12s => {",HighwayName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
- printf("}%s\n",i==(Way_Count-1)?"":",");
+ printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->highway[i]);
+ printf(" }%s\n",i==(Way_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
{
printf(" %12s => {",HighwayName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
- printf("}%s\n",i==(Way_Count-1)?"":",");
+ printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]);
+ printf(" }%s\n",i==(Way_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
{
printf(" %12s => {",PropertyName(i));
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %3d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
- printf("}%s\n",i==(Property_Count-1)?"":",");
+ printf("%s %s => %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)loaded_profiles[j]->props_yes[i]);
+ printf(" }%s\n",i==(Property_Count-1)?"":",");
}
printf(" },\n");
printf("\n");
printf(" profile_restrictions => {\n");
printf(" %12s => {","oneway");
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %4d",j==1?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
- printf("},\n");
+ printf("%s %s => %4d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway);
+ printf(" },\n");
printf(" %12s => {","weight");
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
- printf("},\n");
+ printf("%s %s => %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight));
+ printf(" },\n");
printf(" %12s => {","height");
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
- printf("},\n");
+ printf("%s %s => %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height));
+ printf(" },\n");
printf(" %12s => {","width");
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
- printf("},\n");
+ printf("%s %s => %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width));
+ printf(" },\n");
printf(" %12s => {","length");
for(j=0;j<nloaded_profiles;j++)
- printf("%s %s => %4.1f",j==1?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
- printf("}\n");
- printf(" },\n");
+ printf("%s %s => %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length));
+ printf(" }\n");
+ printf(" }\n");
printf("\n");
printf("}; # end of routino variable\n");
/***************************************
- $Header: /home/amb/routino/src/RCS/profiles.h,v 1.16 2010/05/29 10:37:12 amb Exp $
+ $Header: /home/amb/routino/src/RCS/profiles.h,v 1.17 2010/07/31 18:21:18 amb Exp $
A header file for the profiles.
Transport transport; /*+ The type of transport. +*/
- wayallow_t allow; /*+ The type of transport expressed as what must be allowed on a way. +*/
+ allow_t allow; /*+ The type of transport expressed as what must be allowed. +*/
score_t highway[Way_Count]; /*+ A floating point preference for travel on the highway. +*/
score_t max_pref; /*+ The maximum preference for any highway type. +*/
--- /dev/null
+/***************************************
+ $Header: /home/amb/routino/src/RCS/relationsx.c,v 1.8 2010/10/09 18:20:18 amb Exp $
+
+ Extended Relation data type functions.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2010 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "waysx.h"
+#include "relationsx.h"
+
+#include "files.h"
+#include "functions.h"
+
+
+/* Variables */
+
+/*+ The command line '--tmpdir' option or its default value. +*/
+extern char *option_tmpdirname;
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Allocate a new relation list (create a new file or open an existing one).
+
+ RelationsX *NewRelationList Returns the relation list.
+
+ int append Set to 1 if the file is to be opened for appending (now or later).
+ ++++++++++++++++++++++++++++++++++++++*/
+
+RelationsX *NewRelationList(int append)
+{
+ RelationsX *relationsx;
+
+ relationsx=(RelationsX*)calloc(1,sizeof(RelationsX));
+
+ assert(relationsx); /* Check calloc() worked */
+
+ relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32);
+
+ if(append)
+ sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname);
+ else
+ sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx);
+
+ if(append)
+ {
+ off_t size,position=0;
+
+ relationsx->rfd=OpenFileAppend(relationsx->rfilename);
+
+ size=SizeFile(relationsx->rfilename);
+
+ while(position<size)
+ {
+ FILESORT_VARINT relationsize;
+
+ SeekFile(relationsx->rfd,position);
+ ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE);
+
+ relationsx->rxnumber++;
+ position+=relationsize+FILESORT_VARSIZE;
+ }
+
+ SeekFile(relationsx->rfd,size);
+ }
+ else
+ relationsx->rfd=OpenFileNew(relationsx->rfilename);
+
+ return(relationsx);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Free a relation list.
+
+ RelationsX *relationsx The list to be freed.
+
+ int keep Set to 1 if the file is to be kept.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void FreeRelationList(RelationsX *relationsx,int keep)
+{
+ if(!keep)
+ DeleteFile(relationsx->rfilename);
+
+ free(relationsx->rfilename);
+
+ free(relationsx);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Append a single relation to an unsorted route relation list.
+
+ RelationsX* relationsx The set of relations to process.
+
+ relation_t id The ID of the relation.
+
+ allow_t routes The types of routes that this relation is for.
+
+ way_t *ways The array of ways that are members of the relation.
+
+ int nways The number of ways that are members of the relation.
+
+ relation_t *relations The array of relations that are members of the relation.
+
+ int nrelations The number of relations that are members of the relation.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void AppendRouteRelation(RelationsX* relationsx,relation_t id,allow_t routes,
+ way_t *ways,int nways,
+ relation_t *relations,int nrelations)
+{
+ RouteRelX relationx;
+ FILESORT_VARINT size;
+ way_t zeroway=0;
+ relation_t zerorelation=0;
+
+ relationx.id=id;
+ relationx.routes=routes;
+
+ size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t);
+
+ WriteFile(relationsx->rfd,&size,FILESORT_VARSIZE);
+ WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
+
+ WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t));
+ WriteFile(relationsx->rfd,&zeroway, sizeof(way_t));
+
+ WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t));
+ WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t));
+
+ relationsx->rxnumber++;
+
+ assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Sort the list of relations.
+
+ RelationsX* relationsx The set of relations to process.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void SortRelationList(RelationsX* relationsx)
+{
+ /* Don't need to sort route relations */
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Process the route relations and apply the information to the ways.
+
+ RelationsX *relationsx The set of relations to process.
+
+ WaysX *waysx The set of ways to update.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx)
+{
+ RouteRelX *unmatched=NULL,*lastunmatched=NULL;
+ int nunmatched=0,lastnunmatched=0,iteration=0;
+ int i,j;
+
+ if(waysx->number==0)
+ return;
+
+ /* Map into memory */
+
+#if !SLIM
+ waysx->xdata=MapFileWriteable(waysx->filename);
+#endif
+
+ /* Re-open the ways file read/write */
+
+#if SLIM
+ CloseFile(waysx->fd);
+ waysx->fd=ReOpenFileWriteable(waysx->filename);
+#endif
+
+ /* Open the file and read through it */
+
+ relationsx->rfd=ReOpenFile(relationsx->rfilename);
+
+ do
+ {
+ SeekFile(relationsx->rfd,0);
+
+ /* Print the start message */
+
+ printf("Processing Route Relations: Iteration=%d Relations=0",iteration);
+ fflush(stdout);
+
+ for(i=0;i<relationsx->rxnumber;i++)
+ {
+ FILESORT_VARINT size;
+ RouteRelX relationx;
+ way_t wayid;
+ relation_t relationid;
+ allow_t routes=Allow_None;
+
+ /* Read each route relation */
+
+ ReadFile(relationsx->rfd,&size,FILESORT_VARSIZE);
+ ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
+
+ /* Decide what type of route it is */
+
+ if(iteration==0)
+ routes=relationx.routes;
+ else
+ {
+ if((lastunmatched[j].routes|relationx.routes)==relationx.routes)
+ routes=0; /* Nothing new to add */
+ else
+ for(j=0;j<lastnunmatched;j++)
+ if(lastunmatched[j].id==relationx.id)
+ {
+ routes=lastunmatched[j].routes;
+ break;
+ }
+ }
+
+ /* Loop through the ways */
+
+ do
+ {
+ ReadFile(relationsx->rfd,&wayid,sizeof(way_t));
+
+ /* Update the ways that are listed for the relation */
+
+ if(wayid && routes)
+ {
+ index_t way=IndexWayX(waysx,wayid);
+
+ if(way!=NO_WAY)
+ {
+ WayX *wayx=LookupWayX(waysx,way,1);
+
+ if(routes&Allow_Foot)
+ wayx->way.props|=Properties_FootRoute;
+
+ if(routes&Allow_Bicycle)
+ wayx->way.props|=Properties_BicycleRoute;
+
+#if SLIM
+ PutBackWayX(waysx,way,1);
+#endif
+ }
+ }
+ }
+ while(wayid);
+
+ /* Loop through the relations */
+
+ do
+ {
+ ReadFile(relationsx->rfd,&relationid,sizeof(relation_t));
+
+ /* Add the relations that are listed for this relation to the list for next time */
+
+ if(relationid && routes && relationid!=relationx.id)
+ {
+ if(nunmatched%256==0)
+ unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX));
+
+ unmatched[nunmatched].id=relationid;
+ unmatched[nunmatched].routes=routes;
+
+ nunmatched++;
+ }
+ }
+ while(relationid);
+
+ if(!((i+1)%10000))
+ {
+ printf("\rProcessing Route Relations: Iteration=%d Relations=%d",iteration,i+1);
+ fflush(stdout);
+ }
+ }
+
+ if(lastunmatched)
+ free(lastunmatched);
+
+ lastunmatched=unmatched;
+ lastnunmatched=nunmatched;
+
+ unmatched=NULL;
+ nunmatched=0;
+
+ /* Print the final message */
+
+ printf("\rProcessed Route Relations: Iteration=%d Relations=%d \n",iteration,relationsx->rxnumber);
+ fflush(stdout);
+ }
+ while(lastnunmatched && ++iteration<5);
+
+ if(lastunmatched)
+ free(lastunmatched);
+
+ CloseFile(relationsx->rfd);
+
+ /* Unmap from memory */
+
+#if !SLIM
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
+
+ /* Re-open the ways file read only */
+
+#if SLIM
+ CloseFile(waysx->fd);
+ waysx->fd=ReOpenFile(waysx->filename);
+#endif
+}
--- /dev/null
+/***************************************
+ $Header: /home/amb/routino/src/RCS/relationsx.h,v 1.2 2010/09/25 18:47:32 amb Exp $
+
+ A header file for the extended Relations structure.
+
+ Part of the Routino routing software.
+ ******************/ /******************
+ This file Copyright 2010 Andrew M. Bishop
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ***************************************/
+
+
+#ifndef RELATIONSX_H
+#define RELATIONSX_H /*+ To stop multiple inclusions. +*/
+
+#include <stdint.h>
+
+#include "types.h"
+
+#include "typesx.h"
+
+
+/* Data structures */
+
+
+/*+ An extended structure containing a single route relation. +*/
+struct _RouteRelX
+{
+ relation_t id; /*+ The relation identifier. +*/
+
+ allow_t routes; /*+ The types of route that this relation belongs to. +*/
+};
+
+
+/*+ A structure containing a set of relations. +*/
+struct _RelationsX
+{
+ /* Route relations */
+
+ char *rfilename; /*+ The name of the temporary file (for the RouteRelX). +*/
+ int rfd; /*+ The file descriptor of the temporary file (for the RouteRelX). +*/
+
+ index_t rxnumber; /*+ The number of unsorted extended route relations. +*/
+};
+
+
+/* Functions */
+
+
+RelationsX *NewRelationList(int append);
+void FreeRelationList(RelationsX *relationsx,int keep);
+
+void AppendRouteRelation(RelationsX* relationsx,relation_t id,allow_t routes,
+ way_t *ways,int nways,
+ relation_t *relations,int nrelations);
+
+void SortRelationList(RelationsX *relationsx);
+
+void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx);
+
+
+#endif /* RELATIONSX_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/results.c,v 1.21 2010/07/07 19:04:18 amb Exp $
+ $Header: /home/amb/routino/src/RCS/results.c,v 1.22 2010/07/23 14:32:16 amb Exp $
Result data type functions.
void ZeroResult(Result *result)
{
+ result->segment=NO_SEGMENT;
+
result->prev=NO_NODE;
result->next=NO_NODE;
result->score=0;
result->sortby=0;
-
- result->segment=NULL;
}
/***************************************
- $Header: /home/amb/routino/src/RCS/results.h,v 1.17 2009/11/13 19:24:11 amb Exp $
+ $Header: /home/amb/routino/src/RCS/results.h,v 1.18 2010/07/23 14:32:16 amb Exp $
A header file for the results.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2008,2009 Andrew M. Bishop
+ This file Copyright 2008-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
typedef struct _Result
{
index_t node; /*+ The node for which this result applies. +*/
+ index_t segment; /*+ The segment for the path to here (from prev). +*/
index_t prev; /*+ The previous node following the best path. +*/
index_t next; /*+ The next node following the best path. +*/
score_t sortby; /*+ The best possible weighted distance or duration score from the start to the finish. +*/
uint32_t queued; /*+ The position of this result in the queue. +*/
-
- Segment *segment; /*+ The segment for the path to here (from prev). +*/
}
Result;
/***************************************
- $Header: /home/amb/routino/src/RCS/router.c,v 1.83 2010/06/28 17:56:26 amb Exp $
+ $Header: /home/amb/routino/src/RCS/router.c,v 1.89 2010/09/15 18:19:36 amb Exp $
OSM router.
#include <ctype.h>
#include "types.h"
-#include "functions.h"
-#include "translations.h"
-#include "profiles.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+#include "files.h"
+#include "functions.h"
+#include "translations.h"
+#include "profiles.h"
-/*+ The number of waypoints allowed to be specified. +*/
-#define NWAYPOINTS 99
/*+ The maximum distance from the specified point to search for a node or segment (in km). +*/
#define MAXSEARCH 1
-/*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/
-#define MINSEGMENT 0.005
-
-
-/*+ A set of fake segments to allow start/finish in the middle of a segment. +*/
-static Segment fake_segments[2*NWAYPOINTS];
-/*+ A set of fake node latitudes and longitudes. +*/
+/*+ A set of waypoint latitudes and longitudes. +*/
static double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1];
/*+ The option not to print any progress information. +*/
/* Local functions */
-static void print_usage(int detail);
+static void print_usage(int detail,const char *argerr,const char *err);
/*++++++++++++++++++++++++++++++++++++++
/* Parse the command line arguments */
if(argc<2)
- print_usage(0);
+ print_usage(0,NULL,NULL);
/* Get the non-routing, general program options */
for(arg=1;arg<argc;arg++)
{
if(!strcmp(argv[arg],"--help"))
- print_usage(1);
+ print_usage(1,NULL,NULL);
else if(!strcmp(argv[arg],"--help-profile"))
help_profile=1;
else if(!strcmp(argv[arg],"--help-profile-xml"))
transport=TransportType(&argv[arg][12]);
if(transport==Transport_None)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
}
else
continue;
{
if(ExistsFile(FileName(dirname,prefix,"profiles.xml")))
profiles=FileName(dirname,prefix,"profiles.xml");
+ else if(ExistsFile(FileName(DATADIR,NULL,"tagging.xml")))
+ profiles=FileName(DATADIR,NULL,"profiles.xml");
else
{
fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
}
}
- if(profiles && ParseXMLProfiles(profiles))
+ if(ParseXMLProfiles(profiles))
{
fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
return(1);
char *p=&argv[arg][6];
while(isdigit(*p)) p++;
if(*p++!='=')
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
point=atoi(&argv[arg][5]);
if(point>NWAYPOINTS || point_used[point]&1)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
point_lon[point]=degrees_to_radians(atof(p));
point_used[point]+=1;
char *p=&argv[arg][6];
while(isdigit(*p)) p++;
if(*p++!='=')
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
point=atoi(&argv[arg][5]);
if(point>NWAYPOINTS || point_used[point]&2)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
point_lat[point]=degrees_to_radians(atof(p));
point_used[point]+=2;
char *string;
if(!equal)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10);
string[equal-argv[arg]-10]=0;
highway=HighwayType(string);
if(highway==Way_Count)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
profile->highway[highway]=atof(equal+1);
char *string;
if(!equal)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8);
string[equal-argv[arg]-8]=0;
highway=HighwayType(string);
if(highway==Way_Count)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
profile->speed[highway]=kph_to_speed(atof(equal+1));
char *string;
if(!equal)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+11);
string[equal-argv[arg]-11]=0;
property=PropertyType(string);
if(property==Way_Count)
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
profile->props_yes[property]=atof(equal+1);
else if(!strncmp(argv[arg],"--length=",9))
profile->length=metres_to_length(atof(&argv[arg][9]));
else
- print_usage(0);
+ print_usage(0,argv[arg],NULL);
}
for(point=1;point<=NWAYPOINTS;point++)
if(point_used[point]==1 || point_used[point]==2)
- print_usage(0);
+ print_usage(0,NULL,"All waypoints must have latitude and longitude.");
if(help_profile)
{
if(option_html || option_gpx_route || option_gpx_track)
{
- if(translations && ExistsFile(translations))
- ;
- else if(!translations && ExistsFile(FileName(dirname,prefix,"translations.xml")))
- translations=FileName(dirname,prefix,"translations.xml");
-
- if(!translations && language)
+ if(translations)
{
- fprintf(stderr,"Error: Cannot use '--language' option without reading some translations.\n");
- return(1);
+ if(!ExistsFile(translations))
+ {
+ fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n");
+ return(1);
+ }
+ }
+ else
+ {
+ if(ExistsFile(FileName(dirname,prefix,"translations.xml")))
+ translations=FileName(dirname,prefix,"translations.xml");
+ else if(ExistsFile(FileName(DATADIR,NULL,"translations.xml")))
+ translations=FileName(DATADIR,NULL,"translations.xml");
+ else
+ {
+ fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n");
+ return(1);
+ }
}
- if(translations && ParseXMLTranslations(translations,language))
+ if(ParseXMLTranslations(translations,language))
{
fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations);
return(1);
Results *begin,*end;
distance_t distmax=km_to_distance(MAXSEARCH);
distance_t distmin;
- Segment *segment=NULL;
+ index_t segment=NO_SEGMENT;
index_t node1,node2;
if(point_used[point]!=3)
{
distance_t dist1,dist2;
- if((segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2)))
- finish=CreateFakes(OSMNodes,point,segment,node1,node2,dist1,dist2);
+ segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2);
+
+ if(segment!=NO_SEGMENT)
+ finish=CreateFakes(OSMNodes,point,LookupSegment(OSMSegments,segment,1),node1,node2,dist1,dist2);
else
finish=NO_NODE;
}
GetLatLong(OSMNodes,finish,&lat,&lon);
if(IsFakeNode(finish))
- printf("Point %d is segment %d (node %d -> %d): %3.6f %4.6f = %2.3f km\n",point,IndexSegment(OSMSegments,segment),node1,node2,
+ printf("Point %d is segment %d (node %d -> %d): %3.6f %4.6f = %2.3f km\n",point,segment,node1,node2,
radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin));
else
printf("Point %d is node %d: %3.6f %4.6f = %2.3f km\n",point,finish,
/*++++++++++++++++++++++++++++++++++++++
- Create a pair of fake segments corresponding to the given segment split in two.
-
- index_t CreateFakes Returns the fake node index (or a real one in special cases).
-
- Nodes *nodes The set of nodes to use.
-
- int point Which of the waypoints is this.
-
- Segment *segment The segment to split.
-
- index_t node1 The first node at the end of this segment.
-
- index_t node2 The second node at the end of this segment.
-
- distance_t dist1 The distance to the first node.
-
- distance_t dist2 The distance to the second node.
- ++++++++++++++++++++++++++++++++++++++*/
-
-index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2)
-{
- index_t fakenode;
- double lat1,lon1,lat2,lon2;
-
- /* Check if we are actually close enough to an existing node */
-
- if(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
- return(node1);
-
- if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
- return(node2);
-
- if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
- {
- if(dist1<dist2)
- return(node1);
- else
- return(node2);
- }
-
- /* Create the fake node */
-
- fakenode=point|NODE_SUPER;
-
- GetLatLong(nodes,node1,&lat1,&lon1);
- GetLatLong(nodes,node2,&lat2,&lon2);
-
- if(lat1>3 && lat2<-3)
- lat2+=2*M_PI;
- else if(lat1<-3 && lat2>3)
- lat1+=2*M_PI;
-
- point_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2);
- point_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2);
-
- if(point_lat[point]>M_PI) point_lat[point]-=2*M_PI;
-
- /* Create the first fake segment */
-
- fake_segments[2*point-2]=*segment;
-
- if(segment->node1==node1)
- fake_segments[2*point-2].node1=fakenode;
- else
- fake_segments[2*point-2].node2=fakenode;
-
- fake_segments[2*point-2].distance=DISTANCE(dist1)|DISTFLAG(segment->distance);
-
- /* Create the second fake segment */
-
- fake_segments[2*point-1]=*segment;
-
- if(segment->node1==node2)
- fake_segments[2*point-1].node1=fakenode;
- else
- fake_segments[2*point-1].node2=fakenode;
-
- fake_segments[2*point-1].distance=DISTANCE(dist2)|DISTFLAG(segment->distance);
-
- return(fakenode);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
- Lookup the latitude and longitude of a fake node.
-
- index_t fakenode The node to lookup.
-
- double *latitude Returns the latitude
-
- double *longitude Returns the longitude.
- ++++++++++++++++++++++++++++++++++++++*/
-
-void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude)
-{
- index_t realnode=fakenode&(~NODE_SUPER);
-
- *latitude =point_lat[realnode];
- *longitude=point_lon[realnode];
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
- Finds the first fake segment associated to a fake node.
-
- Segment *FirstFakeSegment Returns the first fake segment.
-
- index_t fakenode The node to lookup.
- ++++++++++++++++++++++++++++++++++++++*/
-
-Segment *FirstFakeSegment(index_t fakenode)
-{
- index_t realnode=fakenode&(~NODE_SUPER);
-
- return(&fake_segments[2*realnode-2]);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
- Finds the next (there can only be two) fake segment associated to a fake node.
-
- Segment *NextFakeSegment Returns the second fake segment.
-
- Segment *segment The first fake segment.
-
- index_t fakenode The node to lookup.
- ++++++++++++++++++++++++++++++++++++++*/
-
-Segment *NextFakeSegment(Segment *segment,index_t fakenode)
-{
- index_t realnode=fakenode&(~NODE_SUPER);
-
- if(segment==&fake_segments[2*realnode-2])
- return(&fake_segments[2*realnode-1]);
- else
- return(NULL);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
- Finds the next (there can only be two) fake segment associated to a fake node.
-
- Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists.
-
- index_t node The real node.
-
- index_t fakenode The fake node to lookup.
- ++++++++++++++++++++++++++++++++++++++*/
-
-Segment *ExtraFakeSegment(index_t node,index_t fakenode)
-{
- index_t realnode=fakenode&(~NODE_SUPER);
-
- if(fake_segments[2*realnode-2].node1==node || fake_segments[2*realnode-2].node2==node)
- return(&fake_segments[2*realnode-2]);
-
- if(fake_segments[2*realnode-1].node1==node || fake_segments[2*realnode-1].node2==node)
- return(&fake_segments[2*realnode-1]);
-
- return(NULL);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Print out the usage information.
int detail The level of detail to use - 0 = low, 1 = high.
+
+ const char *argerr The argument that gave the error (if there is one).
+
+ const char *err Other error message (if there is one).
++++++++++++++++++++++++++++++++++++++*/
-static void print_usage(int detail)
+static void print_usage(int detail,const char *argerr,const char *err)
{
fprintf(stderr,
"Usage: router [--help | --help-profile | --help-profile-xml |\n"
" [--weight=<weight>]\n"
" [--height=<height>] [--width=<width>] [--length=<length>]\n");
+ if(argerr)
+ fprintf(stderr,
+ "\n"
+ "Error with command line parameter: %s\n",argerr);
+
+ if(err)
+ fprintf(stderr,
+ "\n"
+ "Error: %s\n",err);
+
if(detail)
fprintf(stderr,
"\n"
"\n"
"--dir=<dirname> The directory containing the routing database.\n"
"--prefix=<name> The filename prefix for the routing database.\n"
- "--profiles=<filename> The name of the profiles (defaults to 'profiles.xml'\n"
- " with '--dirname' and '--prefix' options).\n"
- "--translations=<fname> The filename of the translations (defaults to\n"
- " 'translations.xml' with '--dirname' and '--prefix').\n"
+ "--profiles=<filename> The name of the XML file containing the profiles\n"
+ " (defaults to 'profiles.xml' with '--dir' and\n"
+ " '--prefix' options or the file installed in\n"
+ " '" DATADIR "').\n"
+ "--translations=<fname> The name of the XML file containing the translations\n"
+ " (defaults to 'translations.xml' with '--dir' and\n"
+ " '--prefix' options or the file installed in\n"
+ " '" DATADIR "').\n"
"\n"
"--exact-nodes-only Only route between nodes (don't find closest segment).\n"
"\n"
/***************************************
- $Header: /home/amb/routino/src/RCS/segments.c,v 1.45 2010/04/28 17:27:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/segments.c,v 1.47 2010/07/23 14:35:27 amb Exp $
Segment data type functions.
#include <stdlib.h>
#include "types.h"
-#include "functions.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+
+#include "files.h"
#include "profiles.h"
Segments *LoadSegmentList(const char *filename)
{
- void *data;
Segments *segments;
segments=(Segments*)malloc(sizeof(Segments));
- data=MapFile(filename);
+#if !SLIM
+
+ segments->data=MapFile(filename);
+
+ /* Copy the SegmentsFile structure from the loaded data */
+
+ segments->file=*((SegmentsFile*)segments->data);
+
+ /* Set the pointers in the Segments structure. */
+
+ segments->segments=(Segment*)(segments->data+sizeof(SegmentsFile));
+
+#else
- /* Copy the Segments structure from the loaded data */
+ segments->fd=ReOpenFile(filename);
- *segments=*((Segments*)data);
+ /* Copy the SegmentsFile header structure from the loaded data */
- /* Adjust the pointers in the Segments structure. */
+ ReadFile(segments->fd,&segments->file,sizeof(SegmentsFile));
- segments->data=data;
- segments->segments=(Segment*)(data+sizeof(Segments));
+ segments->incache[0]=NO_SEGMENT;
+ segments->incache[1]=NO_SEGMENT;
+ segments->incache[2]=NO_SEGMENT;
+
+#endif
return(segments);
}
{
if(segment->node1==node)
{
+#if SLIM
+ index_t index=IndexSegment(segments,segment);
+ index++;
+
+ if(index>=segments->file.number)
+ return(NULL);
+ segment=LookupSegment(segments,index,1);
+ if(segment->node1!=node)
+ return(NULL);
+ else
+ return(segment);
+#else
segment++;
- if((segment-segments->segments)>=segments->number || segment->node1!=node)
+ if(IndexSegment(segments,segment)>=segments->file.number || segment->node1!=node)
return(NULL);
else
return(segment);
+#endif
}
else
{
if(segment->next2==NO_NODE)
return(NULL);
else
- return(LookupSegment(segments,segment->next2));
+ return(LookupSegment(segments,segment->next2,1));
}
}
/***************************************
- $Header: /home/amb/routino/src/RCS/segments.h,v 1.34 2009/11/14 19:39:20 amb Exp $
+ $Header: /home/amb/routino/src/RCS/segments.h,v 1.37 2010/07/31 14:36:15 amb Exp $
A header file for the segments.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2008,2009 Andrew M. Bishop
+ This file Copyright 2008-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
#include <stdint.h>
#include "types.h"
+
+#include "files.h"
#include "profiles.h"
};
-/*+ A structure containing a set of segments (mmap format). +*/
+/*+ A structure containing the header from the file. +*/
+typedef struct _SegmentsFile
+{
+ index_t number; /*+ How many segments in total? +*/
+ index_t snumber; /*+ How many super-segments? +*/
+ index_t nnumber; /*+ How many normal segments? +*/
+}
+ SegmentsFile;
+
+
+/*+ A structure containing a set of segments (and pointers to mmap file). +*/
struct _Segments
{
- uint32_t number; /*+ How many segments in total? +*/
- uint32_t snumber; /*+ How many super-segments? +*/
- uint32_t nnumber; /*+ How many normal segments? +*/
+ SegmentsFile file; /*+ The header data from the file. +*/
+
+#if !SLIM
+
+ void *data; /*+ The memory mapped data. +*/
- Segment *segments; /*+ An array of segments. +*/
+ Segment *segments; /*+ An array of segments. +*/
- void *data; /*+ The memory mapped data. +*/
+#else
+
+ int fd; /*+ The file descriptor for the file. +*/
+
+ Segment cached[3]; /*+ The cached segments. +*/
+ index_t incache[3]; /*+ The indexes of the cached segments. +*/
+
+#endif
};
-/* Macros */
+/* Functions */
+Segments *LoadSegmentList(const char *filename);
-/*+ Return a segment pointer given a set of segments and an index. +*/
-#define LookupSegment(xxx,yyy) (&(xxx)->segments[yyy])
+Segment *NextSegment(Segments* segments,Segment *segment,index_t node);
+
+distance_t Distance(double lat1,double lon1,double lat2,double lon2);
+
+duration_t Duration(Segment *segment,Way *way,Profile *profile);
-/*+ Return a segment index given a set of segments and a pointer. +*/
-#define IndexSegment(xxx,yyy) ((yyy)-&(xxx)->segments[0])
+
+/* Macros and inline functions */
/*+ Return true if this is a normal segment. +*/
#define IsNormalSegment(xxx) (((xxx)->distance)&SEGMENT_NORMAL)
#define OtherNode(xxx,yyy) ((xxx)->node1==(yyy)?(xxx)->node2:(xxx)->node1)
-/* Functions */
+#if !SLIM
+/*+ Return a segment pointer given a set of segments and an index. +*/
+#define LookupSegment(xxx,yyy,zzz) (&(xxx)->segments[yyy])
-Segments *LoadSegmentList(const char *filename);
+/*+ Return a segment index given a set of segments and a pointer. +*/
+#define IndexSegment(xxx,yyy) ((yyy)-&(xxx)->segments[0])
-Segment *NextSegment(Segments* segments,Segment *segment,index_t node);
+#else
-distance_t Distance(double lat1,double lon1,double lat2,double lon2);
+static Segment *LookupSegment(Segments *segments,index_t index,int position);
-duration_t Duration(Segment *segment,Way *way,Profile *profile);
+static index_t IndexSegment(Segments *segments,Segment *segment);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the Segment information for a particular segment.
+
+ Segment *LookupSegment Returns a pointer to the cached segment information.
+
+ Segments *segments The segments structure to use.
+
+ index_t index The index of the segment.
+
+ int position The position in the cache to store the value.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline Segment *LookupSegment(Segments *segments,index_t index,int position)
+{
+ SeekFile(segments->fd,sizeof(SegmentsFile)+(off_t)index*sizeof(Segment));
+
+ ReadFile(segments->fd,&segments->cached[position-1],sizeof(Segment));
+
+ segments->incache[position-1]=index;
+
+ return(&segments->cached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the segment index for a particular segment pointer.
+
+ index_t IndexSegment Returns the index of the segment in the list.
+
+ Segments *segments The segments structure to use.
+
+ Segment *segment The segment whose index is to be found.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline index_t IndexSegment(Segments *segments,Segment *segment)
+{
+ int i;
+
+ for(i=0;i<sizeof(segments->cached)/sizeof(segments->cached[0]);i++)
+ if(&segments->cached[i]==segment)
+ return(segments->incache[i]);
+
+ return(NO_SEGMENT);
+}
+
+#endif
#endif /* SEGMENTS_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/segmentsx.c,v 1.51 2010/04/28 17:27:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/segmentsx.c,v 1.68 2010/10/09 14:14:42 amb Exp $
Extended Segment data type functions.
#include <sys/stat.h>
#include "types.h"
-#include "functions.h"
-#include "nodesx.h"
-#include "segmentsx.h"
-#include "waysx.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
+#include "nodesx.h"
+#include "segmentsx.h"
+#include "waysx.h"
+
+#include "types.h"
+
+#include "files.h"
+#include "functions.h"
-/* Variables */
-/*+ The command line '--slim' option. +*/
-extern int option_slim;
+/* Variables */
/*+ The command line '--tmpdir' option or its default value. +*/
extern char *option_tmpdirname;
segmentsx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
if(append)
- sprintf(segmentsx->filename,"%s/segments.input.tmp",option_tmpdirname);
+ sprintf(segmentsx->filename,"%s/segmentsx.input.tmp",option_tmpdirname);
else
- sprintf(segmentsx->filename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
+ sprintf(segmentsx->filename,"%s/segmentsx.%p.tmp",option_tmpdirname,segmentsx);
+
+#if SLIM
+ segmentsx->sfilename=(char*)malloc(strlen(option_tmpdirname)+32);
+
+ sprintf(segmentsx->sfilename,"%s/segments.%p.tmp",option_tmpdirname,segmentsx);
+#endif
if(append)
{
off_t size;
- segmentsx->fd=AppendFile(segmentsx->filename);
+ segmentsx->fd=OpenFileAppend(segmentsx->filename);
size=SizeFile(segmentsx->filename);
segmentsx->xnumber=size/sizeof(SegmentX);
}
else
- segmentsx->fd=OpenFile(segmentsx->filename);
+ segmentsx->fd=OpenFileNew(segmentsx->filename);
return(segmentsx);
}
if(segmentsx->firstnode)
free(segmentsx->firstnode);
+#if !SLIM
if(segmentsx->sdata)
free(segmentsx->sdata);
+#endif
+
+#if SLIM
+ DeleteFile(segmentsx->sfilename);
+
+ free(segmentsx->sfilename);
+#endif
free(segmentsx);
}
/*++++++++++++++++++++++++++++++++++++++
- Append a single segment to a segment list.
+ Append a single segment to an unsorted segment list.
SegmentsX* segmentsx The set of segments to process.
{
SegmentX segmentx;
- assert(!segmentsx->idata); /* Must not have idata filled in => unsorted */
-
segmentx.node1=node1;
segmentx.node2=node2;
segmentx.way=way;
WriteFile(segmentsx->fd,&segmentx,sizeof(SegmentX));
segmentsx->xnumber++;
+
+ assert(segmentsx->xnumber<SEGMENT_FAKE); /* SEGMENT_FAKE marks the high-water mark for real segments. */
}
{
int fd;
- /* Check the start conditions */
-
- assert(!segmentsx->idata); /* Must not have idata filled in => unsorted */
+ if(segmentsx->xnumber==0)
+ return;
/* Print the start message */
DeleteFile(segmentsx->filename);
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
/* Sort by node indexes */
return(index);
}
- assert(segmentsx->idata); /* Must have idata filled in => sorted by node 1 */
-
/* Binary search - search key exact match only is required.
*
* # <- start | Check mid and move start or end if it doesn't match
index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeindex)
{
- assert(segmentsx->firstnode); /* Must have firstnode filled in => segments updated */
-
if(++segindex==segmentsx->firstnode[nodeindex+1])
return(NO_SEGMENT);
else
/*++++++++++++++++++++++++++++++++++++++
- Lookup a particular segment.
-
- SegmentX *LookupSegmentX Returns a pointer to the extended segment with the specified id.
-
- SegmentsX* segmentsx The set of segments to process.
-
- index_t index The segment index to look for.
-
- int position The position in the cache to use.
- ++++++++++++++++++++++++++++++++++++++*/
-
-SegmentX *LookupSegmentX(SegmentsX* segmentsx,index_t index,int position)
-{
- assert(index!=NO_SEGMENT); /* Must be a valid segment */
-
- if(option_slim)
- {
- SeekFile(segmentsx->fd,index*sizeof(SegmentX));
-
- ReadFile(segmentsx->fd,&segmentsx->cached[position-1],sizeof(SegmentX));
-
- return(&segmentsx->cached[position-1]);
- }
- else
- {
- return(&segmentsx->xdata[index]);
- }
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Remove bad segments (duplicated, zero length or missing nodes).
NodesX *nodesx The nodes to check.
DeleteFile(segmentsx->filename);
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
SeekFile(segmentsx->fd,0);
while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
/* Map into memory */
- if(!option_slim)
- nodesx->xdata=MapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+#endif
/* Free the now-unneeded index */
DeleteFile(segmentsx->filename);
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
SeekFile(segmentsx->fd,0);
while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
/* Unmap from memory */
- if(!option_slim)
- nodesx->xdata=UnmapFile(nodesx->filename);
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+#endif
/* Print the final message */
int fd;
SegmentX segmentx;
- /* Check the start conditions */
-
- assert(!segmentsx->idata); /* Must not have idata filled in => not sorted by node 1 */
-
/* Print the start message */
printf("Rotating Segments: Segments=0 Rotated=0");
DeleteFile(segmentsx->filename);
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
/* Modify the file contents */
/* Map into memory */
- if(!option_slim)
- waysx->xdata=MapFile(waysx->filename);
+#if !SLIM
+ waysx->xdata=MapFile(waysx->filename);
+#endif
/* Allocate the array of indexes */
DeleteFile(segmentsx->filename);
- fd=OpenFile(segmentsx->filename);
+ fd=OpenFileNew(segmentsx->filename);
SeekFile(segmentsx->fd,0);
while(!ReadFile(segmentsx->fd,&segmentx,sizeof(SegmentX)))
/* Unmap from memory */
- if(!option_slim)
- waysx->xdata=UnmapFile(waysx->filename);
+#if !SLIM
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
/* Print the final message */
{
index_t i;
- /* Check the start conditions */
-
- assert(!segmentsx->sdata); /* Must not have sdata filled in => no real segments */
+ if(segmentsx->number==0 || waysx->number==0)
+ return;
/* Print the start message */
/* Map into memory */
- if(!option_slim)
- {
- segmentsx->xdata=MapFile(segmentsx->filename);
- waysx->xdata=MapFile(waysx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=MapFile(segmentsx->filename);
+ waysx->xdata=MapFile(waysx->filename);
+#endif
/* Free the unneeded memory */
free(segmentsx->firstnode);
segmentsx->firstnode=NULL;
- /* Allocate the memory */
+ /* Allocate the memory (or open the file) */
+#if !SLIM
segmentsx->sdata=(Segment*)malloc(segmentsx->number*sizeof(Segment));
assert(segmentsx->sdata); /* Check malloc() worked */
+#else
+ segmentsx->sfd=OpenFileNew(segmentsx->sfilename);
+#endif
/* Loop through and fill */
for(i=0;i<segmentsx->number;i++)
{
SegmentX *segmentx=LookupSegmentX(segmentsx,i,1);
- WayX *wayx=LookupWayX(waysx,segmentx->way,1);
+ Segment *segment =LookupSegmentXSegment(segmentsx,i,1);
+ WayX *wayx=LookupWayX(waysx,segmentx->way,1);
- segmentsx->sdata[i].node1=0;
- segmentsx->sdata[i].node2=0;
- segmentsx->sdata[i].next2=NO_NODE;
- segmentsx->sdata[i].way=wayx->prop;
- segmentsx->sdata[i].distance=segmentx->distance;
+ segment->node1=0;
+ segment->node2=0;
+ segment->next2=NO_NODE;
+ segment->way=wayx->prop;
+ segment->distance=segmentx->distance;
+
+#if SLIM
+ PutBackSegmentXSegment(segmentsx,i,1);
+#endif
if(!((i+1)%10000))
{
/* Unmap from memory */
- if(!option_slim)
- {
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- waysx->xdata=UnmapFile(waysx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
/* Print the final message */
{
index_t i;
- /* Check the start conditions */
-
- assert(nodesx->ndata); /* Must have ndata filled in => real nodes exist */
- assert(segmentsx->sdata); /* Must have sdata filled in => real segments exist */
+ if(nodesx->number==0 || segmentsx->number==0)
+ return;
/* Print the start message */
/* Map into memory */
- if(!option_slim)
- {
- nodesx->xdata=MapFile(nodesx->filename);
- segmentsx->xdata=MapFile(segmentsx->filename);
- }
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+ segmentsx->xdata=MapFile(segmentsx->filename);
+#endif
/* Index the segments */
for(i=0;i<nodesx->number;i++)
{
NodeX *nodex=LookupNodeX(nodesx,i,1);
- Node *node =&nodesx->ndata[nodex->id];
- index_t index=SEGMENT(node->firstseg);
+ Node *node =LookupNodeXNode(nodesx,nodex->id,1);
+ index_t index=node->firstseg;
do
{
SegmentX *segmentx=LookupSegmentX(segmentsx,index,1);
+ Segment *segment =LookupSegmentXSegment(segmentsx,index,1);
if(segmentx->node1==nodex->id)
{
- segmentsx->sdata[index].node1=i;
+ segment->node1=i;
+
+#if SLIM
+ PutBackSegmentXSegment(segmentsx,index,1);
+#endif
index++;
}
else
{
- segmentsx->sdata[index].node2=i;
+ segment->node2=i;
- if(segmentsx->sdata[index].next2==NO_NODE)
+#if SLIM
+ PutBackSegmentXSegment(segmentsx,index,1);
+#endif
+
+ if(segment->next2==NO_NODE)
break;
else
- index=segmentsx->sdata[index].next2;
+ index=segment->next2;
}
}
while(1);
/* Unmap from memory */
- if(!option_slim)
- {
- nodesx->xdata=UnmapFile(nodesx->filename);
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- }
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+#endif
/* Print the final message */
{
index_t i;
int fd;
- Segments *segments;
+ SegmentsFile segmentsfile={0};
int super_number=0,normal_number=0;
- /* Check the start conditions */
-
- assert(segmentsx->sdata); /* Must have sdata filled in => real segments */
-
/* Print the start message */
printf("Writing Segments: Segments=0");
fflush(stdout);
- /* Count the number of super-segments and normal segments */
+ /* Write out the segments data */
+
+ fd=OpenFileNew(filename);
+
+ SeekFile(fd,sizeof(SegmentsFile));
for(i=0;i<segmentsx->number;i++)
{
- if(IsSuperSegment(&segmentsx->sdata[i]))
+ Segment *segment=LookupSegmentXSegment(segmentsx,i,1);
+
+ if(IsSuperSegment(segment))
super_number++;
- if(IsNormalSegment(&segmentsx->sdata[i]))
+ if(IsNormalSegment(segment))
normal_number++;
- }
-
- /* Fill in a Segments structure with the offset of the real data in the file after
- the Segment structure itself. */
-
- segments=calloc(1,sizeof(Segments));
-
- assert(segments); /* Check calloc() worked */
-
- segments->number=segmentsx->number;
- segments->snumber=super_number;
- segments->nnumber=normal_number;
-
- segments->data=NULL;
- segments->segments=NULL;
- /* Write out the Segments structure and then the real data. */
-
- fd=OpenFile(filename);
-
- WriteFile(fd,segments,sizeof(Segments));
-
- for(i=0;i<segments->number;i++)
- {
- WriteFile(fd,&segmentsx->sdata[i],sizeof(Segment));
+ WriteFile(fd,segment,sizeof(Segment));
if(!((i+1)%10000))
{
}
}
+ /* Write out the header structure */
+
+ segmentsfile.number=segmentsx->number;
+ segmentsfile.snumber=super_number;
+ segmentsfile.nnumber=normal_number;
+
+ SeekFile(fd,0);
+ WriteFile(fd,&segmentsfile,sizeof(SegmentsFile));
+
CloseFile(fd);
/* Print the final message */
- printf("\rWrote Segments: Segments=%d \n",segments->number);
+ printf("\rWrote Segments: Segments=%d \n",segmentsx->number);
fflush(stdout);
-
- /* Free the fake Segments */
-
- free(segments);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/segmentsx.h,v 1.20 2010/03/19 19:47:09 amb Exp $
+ $Header: /home/amb/routino/src/RCS/segmentsx.h,v 1.26 2010/07/31 14:36:15 amb Exp $
A header file for the extended segments.
#include <stdint.h>
-#include "typesx.h"
#include "types.h"
+#include "segments.h"
+
+#include "typesx.h"
+
+#include "files.h"
/* Data structures */
char *filename; /*+ The name of the temporary file. +*/
int fd; /*+ The file descriptor of the temporary file. +*/
- uint32_t xnumber; /*+ The number of unsorted extended nodes. +*/
+ index_t xnumber; /*+ The number of unsorted extended nodes. +*/
+
+#if !SLIM
SegmentX *xdata; /*+ The extended segment data (unsorted). +*/
- SegmentX cached[2]; /*+ Two cached segments read from the file in slim mode. +*/
- uint32_t number; /*+ How many entries are still useful? +*/
+#else
+
+ SegmentX xcached[2]; /*+ Two cached segments read from the file in slim mode. +*/
+
+#endif
+
+ index_t number; /*+ How many entries are still useful? +*/
node_t *idata; /*+ The extended segment data (sorted by node1 then node2). +*/
index_t *firstnode; /*+ The first segment index for each node. +*/
+#if !SLIM
+
Segment *sdata; /*+ The segment data (same order as n1data). +*/
+
+#else
+
+ char *sfilename; /*+ The name of the temporary file for segments in slim mode. +*/
+ int sfd; /*+ The file descriptor of the temporary file. +*/
+
+ Segment scached[2]; /*+ Two cached segments read from the file in slim mode. +*/
+
+#endif
};
void SaveSegmentList(SegmentsX *segmentsx,const char *filename);
-SegmentX *LookupSegmentX(SegmentsX* segmentsx,index_t index,int position);
-
index_t IndexFirstSegmentX(SegmentsX* segmentsx,node_t node);
index_t IndexNextSegmentX(SegmentsX* segmentsx,index_t segindex,index_t nodeindex);
void IndexSegments(SegmentsX* segmentsx,NodesX *nodesx);
+/* Macros / inline functions */
+
+
+#if !SLIM
+
+#define LookupSegmentX(segmentsx,index,position) &(segmentsx)->xdata[index]
+
+#define LookupSegmentXSegment(segmentsx,index,position) &(segmentsx)->sdata[index]
+
+#else
+
+static SegmentX *LookupSegmentX(SegmentsX* segmentsx,index_t index,int position);
+
+static Segment *LookupSegmentXSegment(SegmentsX* segmentsx,index_t index,int position);
+
+static void PutBackSegmentXSegment(SegmentsX* segmentsx,index_t index,int position);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a particular extended segment.
+
+ SegmentX *LookupSegmentX Returns a pointer to the extended segment with the specified id.
+
+ SegmentsX* segmentsx The set of segments to process.
+
+ index_t index The segment index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline SegmentX *LookupSegmentX(SegmentsX* segmentsx,index_t index,int position)
+{
+ SeekFile(segmentsx->fd,(off_t)index*sizeof(SegmentX));
+
+ ReadFile(segmentsx->fd,&segmentsx->xcached[position-1],sizeof(SegmentX));
+
+ return(&segmentsx->xcached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a particular extended segment's normal segment.
+
+ Segment *LookupSegmentXSegment Returns a pointer to the segment with the specified id.
+
+ SegmentsX* segmentsx The set of segments to process.
+
+ index_t index The segment index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline Segment *LookupSegmentXSegment(SegmentsX* segmentsx,index_t index,int position)
+{
+ SeekFile(segmentsx->sfd,(off_t)index*sizeof(Segment));
+
+ ReadFile(segmentsx->sfd,&segmentsx->scached[position-1],sizeof(Segment));
+
+ return(&segmentsx->scached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Put back an extended segment's normal segment.
+
+ SegmentsX* segmentsx The set of segments to process.
+
+ index_t index The segment index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline void PutBackSegmentXSegment(SegmentsX* segmentsx,index_t index,int position)
+{
+ SeekFile(segmentsx->sfd,(off_t)index*sizeof(Segment));
+
+ WriteFile(segmentsx->sfd,&segmentsx->scached[position-1],sizeof(Segment));
+}
+
+#endif /* SLIM */
+
+
#endif /* SEGMENTSX_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/sorting.c,v 1.8 2010/04/09 15:15:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/sorting.c,v 1.11 2010/09/25 13:54:18 amb Exp $
Merge sort functions.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2009 Andrew M. Bishop
+ This file Copyright 2009-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
#include <string.h>
#include <assert.h>
+#include "files.h"
#include "functions.h"
/* Sort the data pointers using a heap sort */
- heapsort(datap,n,compare);
+ filesort_heapsort(datap,n,compare);
/* Shortcut if all read in and sorted at once */
sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles);
- fd=OpenFile(filename);
+ fd=OpenFileNew(filename);
for(i=0;i<n;i++)
WriteFile(fd,datap[i],itemsize);
/* Sort the data pointers using a heap sort */
- heapsort(datap,n,compare);
+ filesort_heapsort(datap,n,compare);
/* Shortcut if all read in and sorted at once */
sprintf(filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles);
- fd=OpenFile(filename);
+ fd=OpenFileNew(filename);
for(i=0;i<n;i++)
{
data to be sorted was an array of things not pointers).
++++++++++++++++++++++++++++++++++++++*/
-void heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*))
+void filesort_heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*))
{
int i;
/***************************************
- $Header: /home/amb/routino/src/RCS/superx.c,v 1.38 2010/07/05 19:05:51 amb Exp $
+ $Header: /home/amb/routino/src/RCS/superx.c,v 1.44 2010/10/09 14:14:42 amb Exp $
Super-Segment data type functions.
***************************************/
-#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
-#include "results.h"
-#include "functions.h"
+#include "ways.h"
+
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
#include "superx.h"
-#include "ways.h"
+#include "files.h"
+#include "results.h"
-/* Variables */
-
-/*+ The command line '--slim' option. +*/
-extern int option_slim;
/* Local Functions */
index_t i;
int nnodes=0;
- /* Check the start conditions */
-
- assert(segmentsx->firstnode); /* Must have firstnode filled in => segments are updated */
+ if(nodesx->number==0 || segmentsx->number==0 || waysx->number==0)
+ return;
/* Print the start message */
/* Map into memory */
- if(!option_slim)
- {
- segmentsx->xdata=MapFile(segmentsx->filename);
- waysx->xdata=MapFile(waysx->filename);
- }
+#if !SLIM
+ nodesx->xdata=MapFile(nodesx->filename);
+ segmentsx->xdata=MapFile(segmentsx->filename);
+ waysx->xdata=MapFile(waysx->filename);
+#endif
/* Find super-nodes */
for(i=0;i<nodesx->number;i++)
{
+ NodeX *nodex=LookupNodeX(nodesx,i,1);
int difference=0;
index_t index1,index2;
index1=IndexNextSegmentX(segmentsx,index1,i);
index2=index1;
+ /* If the node allows less traffic types than any connecting way ... */
+
+ if((wayx1->way.allow&nodex->allow)!=wayx1->way.allow)
+ {
+ difference=1;
+ break;
+ }
+
while(index2!=NO_SEGMENT)
{
SegmentX *segmentx2=LookupSegmentX(segmentsx,index2,2);
WayX *wayx2=LookupWayX(waysx,segmentx2->way,2);
- /* If the ways are different in any way and there is a type of traffic that can use both ... */
+ /* If the ways are different in any attribute and there is a type of traffic that can use both ... */
if(WaysCompare(&wayx1->way,&wayx2->way))
if(wayx1->way.allow & wayx2->way.allow)
/* Unmap from memory */
- if(!option_slim)
- {
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- waysx->xdata=UnmapFile(waysx->filename);
- }
+#if !SLIM
+ nodesx->xdata=UnmapFile(nodesx->filename);
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
/* Print the final message */
SegmentsX *supersegmentsx;
int sn=0,ss=0;
- /* Check the start conditions */
+ supersegmentsx=NewSegmentList(0);
- assert(segmentsx->firstnode); /* Must have firstnode filled in => segments are updated */
+ if(segmentsx->number==0 || waysx->number==0)
+ return(supersegmentsx);
/* Print the start message */
/* Map into memory */
- if(!option_slim)
- {
- segmentsx->xdata=MapFile(segmentsx->filename);
- waysx->xdata=MapFile(waysx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=MapFile(segmentsx->filename);
+ waysx->xdata=MapFile(waysx->filename);
+#endif
/* Create super-segments for each super-node. */
- supersegmentsx=NewSegmentList(0);
-
for(i=0;i<nodesx->number;i++)
{
if(nodesx->super[i]>iteration)
/* Unmap from memory */
- if(!option_slim)
- {
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- waysx->xdata=UnmapFile(waysx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
/* Print the final message */
int m=0,a=0;
SegmentsX* mergedsegmentsx;
+ mergedsegmentsx=NewSegmentList(0);
+
+ if(segmentsx->number==0 || supersegmentsx->number==0)
+ return(mergedsegmentsx);
+
/* Print the start message */
printf("Merging: Segments=0 Super-Segments=0 Merged=0 Added=0");
/* Map into memory */
- if(!option_slim)
- {
- segmentsx->xdata=MapFile(segmentsx->filename);
- supersegmentsx->xdata=MapFile(supersegmentsx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=MapFile(segmentsx->filename);
+ supersegmentsx->xdata=MapFile(supersegmentsx->filename);
+#endif
/* Loop through and create a new list of combined segments */
- mergedsegmentsx=NewSegmentList(0);
-
for(i=0,j=0;i<segmentsx->number;i++)
{
int super=0;
/* Unmap from memory */
- if(!option_slim)
- {
- segmentsx->xdata=UnmapFile(segmentsx->filename);
- supersegmentsx->xdata=UnmapFile(supersegmentsx->filename);
- }
+#if !SLIM
+ segmentsx->xdata=UnmapFile(segmentsx->filename);
+ supersegmentsx->xdata=UnmapFile(supersegmentsx->filename);
+#endif
/* Print the final message */
/***************************************
- $Header: /home/amb/routino/src/RCS/tagging.c,v 1.2 2010/05/23 10:18:59 amb Exp $
+ $Header: /home/amb/routino/src/RCS/tagging.c,v 1.5 2010/09/17 17:40:41 amb Exp $
Load the tagging rules from a file and the functions for handling them.
#include <string.h>
#include <stdlib.h>
-#include "functions.h"
+#include "files.h"
#include "tagging.h"
#include "xmlparse.h"
//static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding);
//static int RoutinoTaggingType_function(const char *_tag_,int _type_);
static int WayType_function(const char *_tag_,int _type_);
-static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v);
+static int NodeType_function(const char *_tag_,int _type_);
static int RelationType_function(const char *_tag_,int _type_);
+static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v);
static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v);
static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v);
-static int NodeType_function(const char *_tag_,int _type_);
/* The XML tag definitions */
-/*+ The NodeType type tag. +*/
-static xmltag NodeType_tag=
- {"node",
- 0, {NULL},
- NodeType_function,
- {NULL}};
-
/*+ The SetType type tag. +*/
static xmltag SetType_tag=
{"set",
OutputType_function,
{NULL}};
-/*+ The RelationType type tag. +*/
-static xmltag RelationType_tag=
- {"relation",
- 0, {NULL},
- RelationType_function,
- {NULL}};
-
/*+ The IfType type tag. +*/
static xmltag IfType_tag=
{"if",
IfType_function,
{&SetType_tag,&OutputType_tag,NULL}};
+/*+ The RelationType type tag. +*/
+static xmltag RelationType_tag=
+ {"relation",
+ 0, {NULL},
+ RelationType_function,
+ {&IfType_tag,NULL}};
+
+/*+ The NodeType type tag. +*/
+static xmltag NodeType_tag=
+ {"node",
+ 0, {NULL},
+ NodeType_function,
+ {&IfType_tag,NULL}};
+
/*+ The WayType type tag. +*/
static xmltag WayType_tag=
{"way",
/*++++++++++++++++++++++++++++++++++++++
- The function that is called when the NodeType XSD type is seen
+ The function that is called when the SetType XSD type is seen
- int NodeType_function Returns 0 if no error occured or something else otherwise.
+ int SetType_function Returns 0 if no error occured or something else otherwise.
const char *_tag_ Set to the name of the element tag that triggered this function call.
int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
+
+ const char *k The contents of the 'k' attribute (or NULL if not defined).
+
+ const char *v The contents of the 'v' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-static int NodeType_function(const char *_tag_,int _type_)
+static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v)
{
if(_type_&XMLPARSE_TAG_START)
- current_list=&NodeRules;
+ AppendTaggingAction(current_rule,k,v,0);
return(0);
}
/*++++++++++++++++++++++++++++++++++++++
- The function that is called when the SetType XSD type is seen
+ The function that is called when the OutputType XSD type is seen
- int SetType_function Returns 0 if no error occured or something else otherwise.
+ int OutputType_function Returns 0 if no error occured or something else otherwise.
const char *_tag_ Set to the name of the element tag that triggered this function call.
const char *v The contents of the 'v' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v)
+static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v)
{
if(_type_&XMLPARSE_TAG_START)
- AppendTaggingAction(current_rule,k,v,0);
+ AppendTaggingAction(current_rule,k,v,1);
return(0);
}
/*++++++++++++++++++++++++++++++++++++++
- The function that is called when the OutputType XSD type is seen
+ The function that is called when the IfType XSD type is seen
- int OutputType_function Returns 0 if no error occured or something else otherwise.
+ int IfType_function Returns 0 if no error occured or something else otherwise.
const char *_tag_ Set to the name of the element tag that triggered this function call.
const char *v The contents of the 'v' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v)
+static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v)
{
if(_type_&XMLPARSE_TAG_START)
- AppendTaggingAction(current_rule,k,v,1);
+ {
+ current_rule=AppendTaggingRule(current_list,k,v);
+ }
return(0);
}
/*++++++++++++++++++++++++++++++++++++++
- The function that is called when the IfType XSD type is seen
+ The function that is called when the NodeType XSD type is seen
- int IfType_function Returns 0 if no error occured or something else otherwise.
+ int NodeType_function Returns 0 if no error occured or something else otherwise.
const char *_tag_ Set to the name of the element tag that triggered this function call.
int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.
-
- const char *k The contents of the 'k' attribute (or NULL if not defined).
-
- const char *v The contents of the 'v' attribute (or NULL if not defined).
++++++++++++++++++++++++++++++++++++++*/
-static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v)
+static int NodeType_function(const char *_tag_,int _type_)
{
if(_type_&XMLPARSE_TAG_START)
- {
- current_rule=AppendTaggingRule(current_list,k,v);
- }
+ current_list=&NodeRules;
return(0);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/tagmodifier.c,v 1.5 2010/05/30 18:18:54 amb Exp $
+ $Header: /home/amb/routino/src/RCS/tagmodifier.c,v 1.7 2010/09/05 18:26:01 amb Exp $
Test application for OSM XML file parser / tagging rule testing.
#include <ctype.h>
#include <errno.h>
-#include "functions.h"
+#include "files.h"
#include "xmlparse.h"
#include "tagging.h"
/* Check the specified command line options */
- if(tagging && ExistsFile(tagging))
- ;
- else if(!tagging && ExistsFile("tagging.xml"))
- tagging="tagging.xml";
-
- if(tagging && ParseXMLTaggingRules(tagging))
+ if(tagging)
{
- fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
- return(1);
+ if(!ExistsFile(tagging))
+ {
+ fprintf(stderr,"Error: The '--tagging' option specifies a file that does not exist.\n");
+ return(1);
+ }
+ }
+ else
+ {
+ if(ExistsFile("tagging.xml"))
+ tagging="tagging.xml";
+ else
+ {
+ fprintf(stderr,"Error: The '--tagging' option was not used and the default 'tagging.xml' does not exist.\n");
+ return(1);
+ }
}
- if(!tagging)
+ if(ParseXMLTaggingRules(tagging))
{
- fprintf(stderr,"Error: Cannot run without reading some tagging rules.\n");
+ fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging);
return(1);
}
+ /* Open the input file */
+
if(filename)
{
file=fopen(filename,"rb");
/***************************************
- $Header: /home/amb/routino/src/RCS/translations.c,v 1.10 2010/07/03 10:58:37 amb Exp $
+ $Header: /home/amb/routino/src/RCS/translations.c,v 1.13 2010/09/15 18:30:08 amb Exp $
Load the translations from a file and the functions for handling them.
#include <string.h>
#include <stdlib.h>
-#include "functions.h"
+#include "files.h"
#include "translations.h"
#include "xmlparse.h"
-/* Global variables - default English values */
+/* Global variables - default English values - Must not require any UTF-8 encoding */
char *translate_copyright_creator[2]={"Creator","Routino - http://www.routino.org/"};
char *translate_copyright_source[2] ={NULL,NULL};
char *translate_heading[9]={"South","South-West","West","North-West","North","North-East","East","South-East","South"};
char *translate_turn[9] ={"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"};
-char *translate_highway[Way_Count]={"","motorway","trunk road","primary road","secondary road","tertiary road","unclassified road","residential road","service road","track","cycleway","path","steps"};
+char *translate_highway[Way_Count]={"","motorway","trunk road","primary road","secondary road","tertiary road","unclassified road","residential road","service road","track","cycleway","path","steps","ferry"};
char *translate_route_shortest="Shortest";
char *translate_route_quickest="Quickest";
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_copyright_creator[0]=strcpy(malloc(strlen(string)+1),string);
- translate_copyright_creator[1]=strcpy(malloc(strlen(text)+1),text);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_copyright_creator[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_copyright_creator[1]=strcpy(malloc(strlen(xmltext)+1) ,xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_copyright_source[0]=strcpy(malloc(strlen(string)+1),string);
- translate_copyright_source[1]=strcpy(malloc(strlen(text)+1),text);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_copyright_source[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_copyright_source[1]=strcpy(malloc(strlen(xmltext)+1) ,xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_copyright_license[0]=strcpy(malloc(strlen(string)+1),string);
- translate_copyright_license[1]=strcpy(malloc(strlen(text)+1),text);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_copyright_license[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_copyright_license[1]=strcpy(malloc(strlen(xmltext)+1) ,xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
+
int d;
XMLPARSE_ASSERT_INTEGER(_tag_,direction,d);
if(d<0 || d>8)
XMLPARSE_INVALID(_tag_,direction);
- translate_turn[d]=strcpy(malloc(strlen(string)+1),string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
+ translate_turn[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
int d;
XMLPARSE_ASSERT_INTEGER(_tag_,direction,d);
if(d<0 || d>8)
XMLPARSE_INVALID(_tag_,direction);
- translate_heading[d]=strcpy(malloc(strlen(string)+1),string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
+ translate_heading[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
Highway highway;
XMLPARSE_ASSERT_STRING(_tag_,type);
if(highway==Way_Count)
XMLPARSE_INVALID(_tag_,type);
- translate_highway[highway]=strcpy(malloc(strlen(string)+1),string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
+ translate_highway[highway]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
+
XMLPARSE_ASSERT_STRING(_tag_,type);
XMLPARSE_ASSERT_STRING(_tag_,string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
if(!strcmp(type,"shortest"))
- translate_route_shortest=strcpy(malloc(strlen(string)+1),string);
+ translate_route_shortest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else if(!strcmp(type,"quickest"))
- translate_route_quickest=strcpy(malloc(strlen(string)+1),string);
+ translate_route_quickest=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else
XMLPARSE_INVALID(_tag_,type);
}
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
+
XMLPARSE_ASSERT_STRING(_tag_,type);
XMLPARSE_ASSERT_STRING(_tag_,string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
if(!strcmp(type,"waypoint"))
{
- translate_html_waypoint=malloc(strlen(string)+1+sizeof("<span class='w'>")+sizeof("</span>"));
- sprintf(translate_html_waypoint,"<span class='w'>%s</span>",string);
+ translate_html_waypoint=malloc(strlen(xmlstring)+1+sizeof("<span class='w'>")+sizeof("</span>"));
+ sprintf(translate_html_waypoint,"<span class='w'>%s</span>",xmlstring);
}
else if(!strcmp(type,"junction"))
- translate_html_junction=strcpy(malloc(strlen(string)+1),string);
+ translate_html_junction=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else
XMLPARSE_INVALID(_tag_,type);
}
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring;
+
XMLPARSE_ASSERT_STRING(_tag_,type);
XMLPARSE_ASSERT_STRING(_tag_,string);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+
if(!strcmp(type,"start"))
- translate_gpx_start=strcpy(malloc(strlen(string)+1),string);
+ translate_gpx_start=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else if(!strcmp(type,"inter"))
- translate_gpx_inter=strcpy(malloc(strlen(string)+1),string);
+ translate_gpx_inter=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else if(!strcmp(type,"trip"))
- translate_gpx_trip=strcpy(malloc(strlen(string)+1),string);
+ translate_gpx_trip=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else if(!strcmp(type,"finish"))
- translate_gpx_finish=strcpy(malloc(strlen(string)+1),string);
+ translate_gpx_finish=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
else
XMLPARSE_INVALID(_tag_,type);
}
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_title=strcpy(malloc(strlen(text)+1),text);
+ xmltext=ParseXML_Encode_Safe_XML(text);
+
+ translate_html_title=strcpy(malloc(strlen(xmltext)+1),xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_start[0]=strcpy(malloc(strlen(string)+1),string);
- translate_html_start[1]=malloc(strlen(text)+1+sizeof("<span class='b'>")+sizeof("</span>"));
- sprintf(translate_html_start[1],text,"%s","<span class='b'>%s</span>");
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_html_start[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_html_start[1]=malloc(strlen(xmltext)+1+sizeof("<span class='b'>")+sizeof("</span>"));
+ sprintf(translate_html_start[1],xmltext,"%s","<span class='b'>%s</span>");
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_node[0]=strcpy(malloc(strlen(string)+1),string);
- translate_html_node[1]=malloc(strlen(text)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
- sprintf(translate_html_node[1],text,"%s","<span class='t'>%s</span>","<span class='b'>%s</span>");
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_html_node[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_html_node[1]=malloc(strlen(xmltext)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
+ sprintf(translate_html_node[1],xmltext,"%s","<span class='t'>%s</span>","<span class='b'>%s</span>");
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
const char *p;
char *q;
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_segment[0]=strcpy(malloc(strlen(string)+1),string);
- translate_html_segment[1]=malloc(strlen(text)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_html_segment[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_html_segment[1]=malloc(strlen(xmltext)+1+2*sizeof("<span class='b'>")+2*sizeof("</span>"));
- p=text;
+ p=xmltext;
q=translate_html_segment[1];
while(*p!='%' && *(p+1)!='s')
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_stop[0]=strcpy(malloc(strlen(string)+1),string);
- translate_html_stop[1]=strcpy(malloc(strlen(text)+1),text);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_html_stop[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_html_stop[1]=strcpy(malloc(strlen(xmltext)+1) ,xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmlstring,*xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,string);
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_html_total[0]=strcpy(malloc(strlen(string)+1),string);
- translate_html_total[1]=strcpy(malloc(strlen(text)+1),text);
+ xmlstring=ParseXML_Encode_Safe_XML(string);
+ xmltext =ParseXML_Encode_Safe_XML(text);
+
+ translate_html_total[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring);
+ translate_html_total[1]=strcpy(malloc(strlen(xmltext)+1) ,xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_gpx_desc=strcpy(malloc(strlen(text)+1),text);
+ xmltext=ParseXML_Encode_Safe_XML(text);
+
+ translate_gpx_desc=strcpy(malloc(strlen(xmltext)+1),xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_gpx_name=strcpy(malloc(strlen(text)+1),text);
+ xmltext=ParseXML_Encode_Safe_XML(text);
+
+ translate_gpx_name=strcpy(malloc(strlen(xmltext)+1),xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_gpx_step=strcpy(malloc(strlen(text)+1),text);
+ xmltext=ParseXML_Encode_Safe_XML(text);
+
+ translate_gpx_step=strcpy(malloc(strlen(xmltext)+1),xmltext);
}
return(0);
{
if(_type_&XMLPARSE_TAG_START && store)
{
+ char *xmltext;
+
XMLPARSE_ASSERT_STRING(_tag_,text);
- translate_gpx_final=strcpy(malloc(strlen(text)+1),text);
+ xmltext=ParseXML_Encode_Safe_XML(text);
+
+ translate_gpx_final=strcpy(malloc(strlen(xmltext)+1),xmltext);
}
return(0);
/***************************************
- $Header: /home/amb/routino/src/RCS/types.c,v 1.3 2010/05/27 17:25:23 amb Exp $
+ $Header: /home/amb/routino/src/RCS/types.c,v 1.6 2010/09/17 17:43:41 amb Exp $
Functions for handling the data types.
if(!strcmp(highway,"cycleway")) return(Way_Cycleway);
return(Way_Count);
+ case 'f':
+ if(!strcmp(highway,"ferry")) return(Way_Ferry);
+ return(Way_Count);
+
case 'm':
if(!strcmp(highway,"motorway")) return(Way_Motorway);
return(Way_Count);
switch(*property)
{
case 'b':
+ if(!strcmp(property,"bicycleroute"))
+ return(Property_BicycleRoute);
+
if(!strcmp(property,"bridge"))
return(Property_Bridge);
break;
+ case 'f':
+ if(!strcmp(property,"footroute"))
+ return(Property_FootRoute);
+ break;
+
case 'm':
if(!strcmp(property,"multilane"))
return(Property_Multilane);
return("path");
case Way_Steps:
return("steps");
+ case Way_Ferry:
+ return("ferry");
case Way_Count:
;
case Property_Tunnel:
return("tunnel");
+ case Property_FootRoute:
+ return("footroute");
+
+ case Property_BicycleRoute:
+ return("bicycleroute");
+
case Property_Count:
;
}
const char *AllowedNameList Returns the list of names.
- wayallow_t allowed The allowed type.
+ allow_t allowed The allowed type.
++++++++++++++++++++++++++++++++++++++*/
-const char *AllowedNameList(wayallow_t allowed)
+const char *AllowedNameList(allow_t allowed)
{
static char string[256];
strcat(string,"tunnel");
}
+ if(properties & Properties_FootRoute)
+ {
+ if(*string) strcat(string,", ");
+ strcat(string,"footroute");
+ }
+
+ if(properties & Properties_BicycleRoute)
+ {
+ if(*string) strcat(string,", ");
+ strcat(string,"bicycleroute");
+ }
+
return(string);
}
" cycleway = Cycleway\n"
" path = Path\n"
" steps = Steps\n"
+ " ferry = Ferry\n"
;
}
const char *PropertyList(void)
{
- return " paved = Paved (suitable for normal wheels)\n"
- " multilane = Multiple lanes\n"
- " bridge = Bridge\n"
- " Tunnel = Tunnel\n"
+ return " paved = Paved (suitable for normal wheels)\n"
+ " multilane = Multiple lanes\n"
+ " bridge = Bridge\n"
+ " tunnel = Tunnel\n"
+ " footroute = A route marked for foot travel\n"
+ " bicycleroute = A route marked for bicycle travel\n"
;
}
/***************************************
- $Header: /home/amb/routino/src/RCS/types.h,v 1.40 2010/05/27 17:25:23 amb Exp $
+ $Header: /home/amb/routino/src/RCS/types.h,v 1.48 2010/09/17 17:43:41 amb Exp $
Type definitions
/* Constants and macros for handling them */
+/*+ An undefined node index. +*/
+#define NO_NODE (~(index_t)0)
-/*+ The latitude and longitude conversion factor from floating point (radians) to integer. +*/
-#define LAT_LONG_SCALE (1024*65536)
+/*+ An undefined segment index. +*/
+#define NO_SEGMENT (~(index_t)0)
-/*+ The latitude and longitude integer range within each bin. +*/
-#define LAT_LONG_BIN 65536
+/*+ An undefined way index. +*/
+#define NO_WAY (~(index_t)0)
-/*+ A flag to mark a node as a super-node. +*/
-#define NODE_SUPER ((index_t)0x80000000)
+/*+ The lowest number allowed for a fake node. +*/
+#define NODE_FAKE ((index_t)0xffff0000)
-/*+ A segment index excluding the super-node flag. +*/
-#define SEGMENT(xxx) (index_t)((xxx)&(~NODE_SUPER))
+/*+ The lowest number allowed for a fake segment. +*/
+#define SEGMENT_FAKE ((index_t)0xffff0000)
-/*+ An undefined node index. +*/
-#define NO_NODE (~(index_t)0)
+/*+ The latitude and longitude conversion factor from floating point (radians) to integer. +*/
+#define LAT_LONG_SCALE (1024*65536)
-/*+ An undefined segment index. +*/
-#define NO_SEGMENT (~(index_t)0)
+/*+ The latitude and longitude integer range within each bin. +*/
+#define LAT_LONG_BIN 65536
-/*+ An undefined way index. +*/
-#define NO_WAY (~(index_t)0)
+/*+ A flag to mark a node as a super-node. +*/
+#define NODE_SUPER ((uint16_t)0x8000)
/*+ A flag to mark a segment as one-way from node1 to node2. +*/
#define SEGMENT_NORMAL ((distance_t)0x10000000)
/*+ The real distance ignoring the ONEWAY_* and SEGMENT_* flags. +*/
-#define DISTANCE(xx) ((distance_t)(xx)&(~(ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL)))
+#define DISTANCE(xx) ((distance_t)((xx)&(~(ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL))))
/*+ The distance flags selecting only the ONEWAY_* and SEGMENT_* flags. +*/
-#define DISTFLAG(xx) ((distance_t)(xx)&(ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL))
+#define DISTFLAG(xx) ((distance_t)((xx)&(ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL)))
/*+ A very large almost infinite distance. +*/
Way_Cycleway =10,
Way_Path =11,
Way_Steps =12,
+ Way_Ferry =13,
- Way_Count =13, /* One more than the number of highway types. */
+ Way_Count =14, /* One more than the number of highway types. */
Way_OneWay =32,
Way_Roundabout =64
/*+ The allowed traffic on a way. +*/
-typedef uint16_t wayallow_t;
+typedef uint16_t allow_t;
#define ALLOWED(xx) (1<<((xx)-1))
/*+ The different allowed traffic on a way. +*/
typedef enum _Allowed
{
+ Allow_None = 0,
+
Allow_Foot = ALLOWED(Transport_Foot ),
Allow_Horse = ALLOWED(Transport_Horse ),
Allow_Wheelchair = ALLOWED(Transport_Wheelchair),
/*+ The individual properties of a highway. +*/
typedef enum _Property
{
- Property_None = 0,
+ Property_None = 0,
- Property_Paved = 1,
- Property_Multilane = 2,
- Property_Bridge = 3,
- Property_Tunnel = 4,
+ Property_Paved = 1,
+ Property_Multilane = 2,
+ Property_Bridge = 3,
+ Property_Tunnel = 4,
+ Property_FootRoute = 5,
+ Property_BicycleRoute = 6,
- Property_Count = 5 /* One more than the number of property types. */
+ Property_Count = 7 /* One more than the number of property types. */
}
Property;
/*+ The different properties of a way. +*/
typedef enum _Properties
{
- Properties_Paved = PROPERTIES(Property_Paved),
- Properties_Multilane = PROPERTIES(Property_Multilane),
- Properties_Bridge = PROPERTIES(Property_Bridge),
- Properties_Tunnel = PROPERTIES(Property_Tunnel),
+ Properties_None = 0,
+
+ Properties_Paved = PROPERTIES(Property_Paved),
+ Properties_Multilane = PROPERTIES(Property_Multilane),
+ Properties_Bridge = PROPERTIES(Property_Bridge),
+ Properties_Tunnel = PROPERTIES(Property_Tunnel),
+ Properties_FootRoute = PROPERTIES(Property_FootRoute),
+ Properties_BicycleRoute = PROPERTIES(Property_BicycleRoute),
- Properties_ALL = 255
+ Properties_ALL = 255
}
Properties;
const char *TransportName(Transport transport);
const char *PropertyName(Property property);
-const char *AllowedNameList(wayallow_t allowed);
+const char *AllowedNameList(allow_t allowed);
const char *PropertiesNameList(wayprop_t properties);
const char *HighwayList(void);
/***************************************
- $Header: /home/amb/routino/src/RCS/typesx.h,v 1.3 2009/10/09 18:47:40 amb Exp $
+ $Header: /home/amb/routino/src/RCS/typesx.h,v 1.4 2010/09/17 17:42:21 amb Exp $
Type definitions for eXtended types.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2008,2009 Andrew M. Bishop
+ This file Copyright 2008-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
/*+ A way identifier - must be at least as large as index_t. +*/
typedef uint32_t way_t;
+/*+ A relation identifier - must be at least as large as index_t. +*/
+typedef uint32_t relation_t;
+
/* Data structures */
typedef struct _WaysX WaysX;
+typedef struct _RouteRelX RouteRelX;
+
+typedef struct _RelationsX RelationsX;
+
#endif /* TYPESX_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/visualiser.c,v 1.7 2009/07/09 18:34:38 amb Exp $
+ $Header: /home/amb/routino/src/RCS/visualiser.c,v 1.10 2010/07/26 18:17:20 amb Exp $
Extract data from Routino.
Part of the Routino routing software.
******************/ /******************
- This file Copyright 2008,2009 Andrew M. Bishop
+ This file Copyright 2008-2010 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
int count=0,difference=0;
segment=FirstSegment(OSMSegments,OSMNodes,node);
- firstway=LookupWay(OSMWays,segment->way);
+ firstway=LookupWay(OSMWays,segment->way,1);
do
{
- Way *way=LookupWay(OSMWays,segment->way);
+ Way *way=LookupWay(OSMWays,segment->way,2);
if(IsNormalSegment(segment))
count++;
{
if(IsNormalSegment(segment) && count<16)
{
- ways [count]=LookupWay(OSMWays,segment->way);
+ ways [count]=LookupWay(OSMWays,segment->way,1);
segments[count]=segment;
switch(limit_type)
static void find_all_nodes(Nodes *nodes,callback_t callback)
{
- int32_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->latzero;
- int32_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->latzero;
- int32_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->lonzero;
- int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->lonzero;
+ int32_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->file.latzero;
+ int32_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero;
+ int32_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero;
+ int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero;
int latb,lonb,llbin;
- index_t node;
+ index_t i,index1,index2;
/* Loop through all of the nodes. */
for(latb=latminbin;latb<=latmaxbin;latb++)
for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
{
- llbin=lonb*nodes->latbins+latb;
+ llbin=lonb*nodes->file.latbins+latb;
- if(llbin<0 || llbin>(nodes->latbins*nodes->lonbins))
+ if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins))
continue;
- for(node=nodes->offsets[llbin];node<nodes->offsets[llbin+1];node++)
+ index1=LookupNodeOffset(nodes,llbin);
+ index2=LookupNodeOffset(nodes,llbin+1);
+
+ for(i=index1;i<index2;i++)
{
- double lat=latlong_to_radians(bin_to_latlong(nodes->latzero+latb)+off_to_latlong(nodes->nodes[node].latoffset));
- double lon=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb)+off_to_latlong(nodes->nodes[node].lonoffset));
+ Node *node=LookupNode(nodes,i,1);
+
+ double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
if(lat>LatMin && lat<LatMax && lon>LonMin && lon<LonMax)
- (*callback)(node,lat,lon);
+ (*callback)(i,lat,lon);
}
}
}
/***************************************
- $Header: /home/amb/routino/src/RCS/ways.c,v 1.44 2010/04/28 17:27:02 amb Exp $
+ $Header: /home/amb/routino/src/RCS/ways.c,v 1.46 2010/07/24 10:09:07 amb Exp $
Way data type functions.
#include <stdlib.h>
-#include "functions.h"
#include "ways.h"
+#include "files.h"
+
/*++++++++++++++++++++++++++++++++++++++
Load in a way list from a file.
Ways *LoadWayList(const char *filename)
{
- void *data;
Ways *ways;
ways=(Ways*)malloc(sizeof(Ways));
- data=MapFile(filename);
+#if !SLIM
+
+ ways->data=MapFile(filename);
+
+ /* Copy the WaysFile structure from the loaded data */
+
+ ways->file=*((WaysFile*)ways->data);
+
+ /* Set the pointers in the Ways structure. */
+
+ ways->ways =(Way *)(ways->data+sizeof(WaysFile));
+ ways->names=(char*)(ways->data+sizeof(WaysFile)+ways->file.number*sizeof(Way));
+
+#else
+
+ ways->fd=ReOpenFile(filename);
+
+ /* Copy the WaysFile header structure from the loaded data */
- /* Copy the Ways structure from the loaded data */
+ ReadFile(ways->fd,&ways->file,sizeof(WaysFile));
- *ways=*((Ways*)data);
+ ways->namesoffset=sizeof(WaysFile)+ways->file.number*sizeof(Way);
- /* Adjust the pointers in the Ways structure. */
+ ways->nincache=~0;
+ ways->ncached=NULL;
- ways->data =data;
- ways->ways =(Way *)(data+sizeof(Ways));
- ways->names=(char*)(data+(sizeof(Ways)+ways->number*sizeof(Way)));
+#endif
return(ways);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/ways.h,v 1.37 2010/05/29 13:54:24 amb Exp $
+ $Header: /home/amb/routino/src/RCS/ways.h,v 1.42 2010/08/30 12:32:07 amb Exp $
A header file for the ways.
#define WAYS_H /*+ To stop multiple inclusions. +*/
#include <stdint.h>
+#include <stdlib.h>
#include "types.h"
+#include "files.h"
+
/* Data structures */
{
index_t name; /*+ The offset of the name of the way in the names array. +*/
- wayallow_t allow; /*+ The type of traffic allowed on the way. +*/
+ allow_t allow; /*+ The type of traffic allowed on the way. +*/
waytype_t type; /*+ The highway type of the way. +*/
};
-/*+ A structure containing a set of ways (mmap format). +*/
-struct _Ways
+/*+ A structure containing the header from the file. +*/
+typedef struct _WaysFile
{
- uint32_t number; /*+ How many ways are stored? +*/
- uint32_t onumber; /*+ How many ways were there originally? +*/
+ index_t number; /*+ How many ways are stored? +*/
+ index_t onumber; /*+ How many ways were there originally? +*/
- wayallow_t allow; /*+ The types of traffic that were seen when parsing. +*/
+ allow_t allow; /*+ The types of traffic that were seen when parsing. +*/
wayprop_t props; /*+ The properties that were seen when parsing. +*/
+}
+ WaysFile;
+
+
+/*+ A structure containing a set of ways (and pointers to mmap file). +*/
+struct _Ways
+{
+ WaysFile file; /*+ The header data from the file. +*/
+
+#if !SLIM
+
+ void *data; /*+ The memory mapped data. +*/
Way *ways; /*+ An array of ways. +*/
char *names; /*+ An array of characters containing the names. +*/
- void *data; /*+ The memory mapped data. +*/
+#else
+
+ int fd; /*+ The file descriptor for the file. +*/
+ off_t namesoffset; /*+ The offset of the names within the file. +*/
+
+ Way wcached[2]; /*+ The cached ways. +*/
+
+ char *ncached; /*+ The cached way name. +*/
+ index_t nincache; /*+ The index of the cached way name. +*/
+ int nalloc; /*+ The amount of memory allocated for the way name. +*/
+
+#endif
};
-/* Macros */
+/* Functions */
+
+Ways *LoadWayList(const char *filename);
+
+int WaysCompare(Way *way1,Way *way2);
+
+
+/* Macros and inline functions */
+#if !SLIM
/*+ Return a Way* pointer given a set of ways and an index. +*/
-#define LookupWay(xxx,yyy) (&(xxx)->ways[yyy])
+#define LookupWay(xxx,yyy,zzz) (&(xxx)->ways[yyy])
-/*+ Return the raw name of a way given the Way pointer and a set of ways. +*/
-#define WayNameRaw(xxx,yyy) (&(xxx)->names[(yyy)->name])
+/*+ Return the name of a way given the Way pointer and a set of ways. +*/
+#define WayName(xxx,yyy) (&(xxx)->names[(yyy)->name])
-/*+ Decide if a way has a name or not. +*/
-#define WayNamed(xxx,yyy) ((xxx)->names[(yyy)->name])
+#else
-/*+ Return the name of a way if it has one or the name of the highway type otherwise. +*/
-#define WayNameHighway(xxx,yyy) (WayNamed(xxx,yyy)?WayNameRaw(xxx,yyy):HighwayName(HIGHWAY(yyy->type)))
+static Way *LookupWay(Ways *ways,index_t index,int position);
+static char *WayName(Ways *ways,Way *way);
-/* Functions */
+/*++++++++++++++++++++++++++++++++++++++
+ Find the Way information for a particular way.
-Ways *LoadWayList(const char *filename);
+ Way *LookupWay Returns a pointer to the cached way information.
-int WaysCompare(Way *way1,Way *way2);
+ Ways *ways The ways structure to use.
+
+ index_t index The index of the way.
+
+ int position The position in the cache to store the value.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline Way *LookupWay(Ways *ways,index_t index,int position)
+{
+ SeekFile(ways->fd,sizeof(WaysFile)+(off_t)index*sizeof(Way));
+
+ ReadFile(ways->fd,&ways->wcached[position-1],sizeof(Way));
+
+ return(&ways->wcached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Find the name of a way.
+
+ char *WayName Returns a pointer to the name of the way.
+
+ Ways *ways The ways structure to use.
+
+ Way *way The Way pointer.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline char *WayName(Ways *ways,Way *way)
+{
+ int n=0;
+
+ if(way->name==ways->nincache)
+ return(ways->ncached);
+
+ SeekFile(ways->fd,ways->namesoffset+way->name);
+
+ if(!ways->ncached)
+ ways->ncached=(char*)malloc(32);
+
+ while(1)
+ {
+ int i;
+ int m=ReadFile(ways->fd,ways->ncached+n,32);
+
+ if(m<0)
+ break;
+
+ for(i=n;i<n+32;i++)
+ if(ways->ncached[i]==0)
+ goto exitloop;
+
+ n+=32;
+
+ ways->ncached=(char*)realloc((void*)ways->ncached,n+32);
+ }
+
+ exitloop:
+
+ return(ways->ncached);
+}
+
+#endif
#endif /* WAYS_H */
/***************************************
- $Header: /home/amb/routino/src/RCS/waysx.c,v 1.38 2010/05/22 18:40:47 amb Exp $
+ $Header: /home/amb/routino/src/RCS/waysx.c,v 1.51 2010/09/19 16:17:45 amb Exp $
Extended Way data type functions.
#include <assert.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
-#include "functions.h"
-#include "waysx.h"
#include "ways.h"
+#include "waysx.h"
+
+#include "files.h"
+#include "functions.h"
-/* Variables */
-/*+ The command line '--slim' option. +*/
-extern int option_slim;
+/* Variables */
/*+ The command line '--tmpdir' option or its default value. +*/
extern char *option_tmpdirname;
/* Functions */
+static int sort_by_id(WayX *a,WayX *b);
+static int sort_by_name_and_id(WayX *a,WayX *b);
static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
-static int deduplicate_by_id(WayX *wayx,index_t index);
-static int sort_by_id(WayX *a,WayX *b);
-static int index_by_id(WayX *wayx,index_t index);
+static int deduplicate_and_index_by_id(WayX *wayx,index_t index);
/*++++++++++++++++++++++++++++++++++++++
waysx->filename=(char*)malloc(strlen(option_tmpdirname)+32);
if(append)
- sprintf(waysx->filename,"%s/ways.input.tmp",option_tmpdirname);
+ sprintf(waysx->filename,"%s/waysx.input.tmp",option_tmpdirname);
else
- sprintf(waysx->filename,"%s/ways.%p.tmp",option_tmpdirname,waysx);
+ sprintf(waysx->filename,"%s/waysx.%p.tmp",option_tmpdirname,waysx);
if(append)
{
off_t size,position=0;
- waysx->fd=AppendFile(waysx->filename);
+ waysx->fd=OpenFileAppend(waysx->filename);
size=SizeFile(waysx->filename);
SeekFile(waysx->fd,size);
}
else
- waysx->fd=OpenFile(waysx->filename);
+ waysx->fd=OpenFileNew(waysx->filename);
waysx->nfilename=(char*)malloc(strlen(option_tmpdirname)+32);
sprintf(waysx->nfilename,"%s/waynames.%p.tmp",option_tmpdirname,waysx);
/*++++++++++++++++++++++++++++++++++++++
- Append a way to a way list.
-
- void AppendWay Returns the newly appended way.
+ Append a single way to an unsorted way list.
WaysX* waysx The set of ways to process.
WayX wayx;
FILESORT_VARINT size;
- assert(!waysx->idata); /* Must not have idata filled in => unsorted */
-
wayx.id=id;
wayx.prop=0;
wayx.way=*way;
WriteFile(waysx->fd,name,strlen(name)+1);
waysx->xnumber++;
+
+ assert(!(waysx->xnumber==0)); /* Zero marks the high-water mark for ways. */
}
int fd,nfd;
char *names[2]={NULL,NULL};
int namelen[2]={0,0};
- int nnames=0,nprops=0;
+ int nnames=0;
uint32_t lastlength=0;
- Way lastway;
-
- /* Check the start conditions */
-
- assert(!waysx->idata); /* Must not have idata filled in => unsorted */
/* Print the start message */
- printf("Sorting Ways");
+ printf("Sorting Ways by Name");
fflush(stdout);
/* Close the file and re-open it (finished appending) */
DeleteFile(waysx->filename);
- fd=OpenFile(waysx->filename);
+ fd=OpenFileNew(waysx->filename);
- /* Sort the ways to allow compacting them and remove duplicates */
+ /* Sort the ways to allow separating the names */
- sortwaysx=waysx;
-
- filesort_vary(waysx->fd,fd,(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,(int (*)(void*,index_t))deduplicate_by_id);
+ filesort_vary(waysx->fd,fd,(int (*)(const void*,const void*))sort_by_name_and_id,NULL);
/* Close the files */
/* Print the final message */
- printf("\rSorted Ways: Ways=%d Duplicates=%d\n",waysx->xnumber,waysx->xnumber-waysx->number);
+ printf("\rSorted Ways by Name: Ways=%d\n",waysx->xnumber);
fflush(stdout);
/* Print the start message */
- printf("Compacting Ways: Ways=0 Names=0 Properties=0");
+ printf("Separating Way Names: Ways=0 Names=0");
fflush(stdout);
/* Open the files */
DeleteFile(waysx->filename);
- fd=OpenFile(waysx->filename);
- nfd=OpenFile(waysx->nfilename);
+ fd=OpenFileNew(waysx->filename);
+ nfd=OpenFileNew(waysx->nfilename);
- /* Copy from the single file into two files and index as we go. */
+ /* Copy from the single file into two files */
- for(i=0;i<waysx->number;i++)
+ for(i=0;i<waysx->xnumber;i++)
{
WayX wayx;
FILESORT_VARINT size;
wayx.way.name=lastlength;
- if(nprops==0 || wayx.way.name!=lastway.name || WaysCompare(&lastway,&wayx.way))
- {
- lastway=wayx.way;
-
- waysx->cnumber++;
-
- nprops++;
- }
-
- wayx.prop=nprops-1;
-
WriteFile(fd,&wayx,sizeof(WayX));
if(!((i+1)%10000))
{
- printf("\rCompacting Ways: Ways=%d Names=%d Properties=%d",i+1,nnames,nprops);
+ printf("\rSeparating Way Names: Ways=%d Names=%d",i+1,nnames);
fflush(stdout);
}
}
/* Print the final message */
- printf("\rCompacted Ways: Ways=%d Names=%d Properties=%d \n",waysx->number,nnames,nprops);
+ printf("\rSeparated Way Names: Ways=%d Names=%d \n",waysx->xnumber,nnames);
fflush(stdout);
DeleteFile(waysx->filename);
- fd=OpenFile(waysx->filename);
+ fd=OpenFileNew(waysx->filename);
/* Allocate the array of indexes */
- waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
+ waysx->idata=(way_t*)malloc(waysx->xnumber*sizeof(way_t));
assert(waysx->idata); /* Check malloc() worked */
/* Sort the ways by index and index them */
+ waysx->number=0;
+
sortwaysx=waysx;
- filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))index_by_id);
+ filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,(int (*)(void*,index_t))deduplicate_and_index_by_id);
+
+ /* Close the files and re-open them */
+
+ CloseFile(waysx->fd);
+ CloseFile(fd);
+
+ waysx->fd=ReOpenFile(waysx->filename);
+
+ /* Print the final message */
+
+ printf("\rSorted Ways: Ways=%d Duplicates=%d\n",waysx->number,waysx->xnumber-waysx->number);
+ fflush(stdout);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Compact the list of ways.
+
+ WaysX* waysx The set of ways to process.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+void CompactWayList(WaysX* waysx)
+{
+ index_t i;
+ int fd;
+ Way lastway;
+
+ /* Print the start message */
+
+ printf("Sorting Ways by Properties");
+ fflush(stdout);
+
+ /* Close the file and re-open it */
+
+ CloseFile(waysx->fd);
+ waysx->fd=ReOpenFile(waysx->filename);
+
+ DeleteFile(waysx->filename);
+
+ fd=OpenFileNew(waysx->filename);
+
+ /* Sort the ways to allow compacting according to he properties */
+
+ filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,NULL);
+
+ /* Close the files */
+
+ CloseFile(waysx->fd);
+ CloseFile(fd);
+
+ /* Print the final message */
+
+ printf("\rSorted Ways by Properties: Ways=%d\n",waysx->number);
+ fflush(stdout);
+
+
+ /* Print the start message */
+
+ printf("Compacting Ways: Ways=0 Properties=0");
+ fflush(stdout);
+
+ /* Open the files */
+
+ waysx->fd=ReOpenFile(waysx->filename);
+
+ DeleteFile(waysx->filename);
+
+ fd=OpenFileNew(waysx->filename);
+
+ /* Update the way as we go using the sorted index */
+
+ waysx->cnumber=0;
+
+ for(i=0;i<waysx->number;i++)
+ {
+ WayX wayx;
+
+ ReadFile(waysx->fd,&wayx,sizeof(WayX));
+
+ if(waysx->cnumber==0 || wayx.way.name!=lastway.name || WaysCompare(&lastway,&wayx.way))
+ {
+ lastway=wayx.way;
+
+ waysx->cnumber++;
+ }
+
+ wayx.prop=waysx->cnumber-1;
+
+ WriteFile(fd,&wayx,sizeof(WayX));
+
+ if(!((i+1)%10000))
+ {
+ printf("\rCompacting Ways: Ways=%d Properties=%d",i+1,waysx->cnumber);
+ fflush(stdout);
+ }
+ }
+
+ /* Close the files */
+
+ CloseFile(waysx->fd);
+ CloseFile(fd);
+
+ /* Print the final message */
+
+ printf("\rCompacted Ways: Ways=%d Properties=%d \n",waysx->number,waysx->cnumber);
+ fflush(stdout);
+
+
+ /* Print the start message */
+
+ printf("Sorting Ways");
+ fflush(stdout);
+
+ /* Open the files */
+
+ waysx->fd=ReOpenFile(waysx->filename);
+
+ DeleteFile(waysx->filename);
+
+ fd=OpenFileNew(waysx->filename);
+
+ /* Sort the ways by index */
+
+ filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(const void*,const void*))sort_by_id,NULL);
/* Close the files and re-open them */
/*++++++++++++++++++++++++++++++++++++++
- Sort the ways into name, properties and id order.
+ Sort the ways into name and id order.
- int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
+ int sort_by_name_and_id Returns the comparison of the name and id fields.
WayX *a The first extended Way.
WayX *b The second extended Way.
++++++++++++++++++++++++++++++++++++++*/
-static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
+static int sort_by_name_and_id(WayX *a,WayX *b)
{
int compare;
char *a_name=(char*)a+sizeof(WayX);
if(compare)
return(compare);
+ return(sort_by_id(a,b));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Sort the ways into name, properties and id order.
+
+ int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
+
+ WayX *a The first extended Way.
+
+ WayX *b The second extended Way.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
+{
+ int compare;
+ index_t a_name=a->way.name;
+ index_t b_name=b->way.name;
+
+ if(a_name<b_name)
+ return(-1);
+ else if(a_name>b_name)
+ return(1);
+
compare=WaysCompare(&a->way,&b->way);
if(compare)
/*++++++++++++++++++++++++++++++++++++++
- Deduplicate the extended ways using the id after sorting.
+ Deduplicate the extended ways using the id after sorting and create the index.
- int deduplicate_by_id Return 1 if the value is to be kept, otherwise zero.
+ int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise zero.
WayX *wayx The extended way.
index_t index The index of this way in the total.
++++++++++++++++++++++++++++++++++++++*/
-static int deduplicate_by_id(WayX *wayx,index_t index)
+static int deduplicate_and_index_by_id(WayX *wayx,index_t index)
{
static way_t previd;
sortwaysx->number++;
+ sortwaysx->idata[index]=wayx->id;
+
return(1);
}
/*++++++++++++++++++++++++++++++++++++++
- Index the ways after sorting.
-
- int index_by_id Return 1 if the value is to be kept, otherwise zero.
-
- WayX *wayx The extended way.
-
- index_t index The index of this way in the total.
- ++++++++++++++++++++++++++++++++++++++*/
-
-static int index_by_id(WayX *wayx,index_t index)
-{
- sortwaysx->idata[index]=wayx->id;
-
- return(1);
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Find a particular way index.
index_t IndexWayX Returns the index of the extended way with the specified id.
int end=waysx->number-1;
int mid;
- assert(waysx->idata); /* Must have idata filled in => sorted */
-
/* Binary search - search key exact match only is required.
*
* # <- start | Check mid and move start or end if it doesn't match
/*++++++++++++++++++++++++++++++++++++++
- Lookup a particular way.
-
- WayX *LookupWayX Returns a pointer to the extended way with the specified id.
-
- WaysX* waysx The set of ways to process.
-
- index_t index The way index to look for.
-
- int position The position in the cache to use.
- ++++++++++++++++++++++++++++++++++++++*/
-
-WayX *LookupWayX(WaysX* waysx,index_t index,int position)
-{
- assert(index!=NO_WAY); /* Must be a valid way */
-
- if(option_slim)
- {
- SeekFile(waysx->fd,index*sizeof(WayX));
-
- ReadFile(waysx->fd,&waysx->cached[position-1],sizeof(WayX));
-
- return(&waysx->cached[position-1]);
- }
- else
- {
- return(&waysx->xdata[index]);
- }
-}
-
-
-/*++++++++++++++++++++++++++++++++++++++
Save the way list to a file.
WaysX* waysx The set of ways to save.
index_t i;
int fd,nfd;
int position=0;
- Ways *ways;
+ WaysFile waysfile={0};
+ allow_t allow=0;
+ wayprop_t props=0;
+
+ /* Print the start message */
printf("Writing Ways: Ways=0");
fflush(stdout);
- if(!option_slim)
- waysx->xdata=MapFile(waysx->filename);
-
- /* Fill in a Ways structure with the offset of the real data in the file after
- the Way structure itself. */
-
- ways=calloc(1,sizeof(Ways));
-
- assert(ways); /* Check calloc() worked */
+ /* Map into memory */
- ways->number=waysx->cnumber;
- ways->onumber=waysx->number;
+#if !SLIM
+ waysx->xdata=MapFile(waysx->filename);
+#endif
- ways->allow=0;
- ways->props=0;
+ /* Write out the ways data */
- ways->data=NULL;
- ways->ways=NULL;
- ways->names=NULL;
+ fd=OpenFileNew(filename);
- /* Write out the Ways structure and then the real data. */
-
- fd=OpenFile(filename);
+ SeekFile(fd,sizeof(WaysFile));
for(i=0;i<waysx->number;i++)
{
WayX *wayx=LookupWayX(waysx,i,1);
- ways->allow|=wayx->way.allow;
- ways->props|=wayx->way.props;
+ allow|=wayx->way.allow;
+ props|=wayx->way.props;
- SeekFile(fd,sizeof(Ways)+wayx->prop*sizeof(Way));
+ SeekFile(fd,sizeof(WaysFile)+(off_t)wayx->prop*sizeof(Way));
WriteFile(fd,&wayx->way,sizeof(Way));
if(!((i+1)%10000))
}
}
- SeekFile(fd,0);
- WriteFile(fd,ways,sizeof(Ways));
+ /* Unmap from memory */
+
+#if !SLIM
+ waysx->xdata=UnmapFile(waysx->filename);
+#endif
- if(!option_slim)
- waysx->xdata=UnmapFile(waysx->filename);
+ /* Write out the ways names */
- SeekFile(fd,sizeof(Ways)+ways->number*sizeof(Way));
+ SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->cnumber*sizeof(Way));
nfd=ReOpenFile(waysx->nfilename);
CloseFile(nfd);
+ /* Write out the header structure */
+
+ waysfile.number=waysx->cnumber;
+ waysfile.onumber=waysx->number;
+
+ waysfile.allow=allow;
+ waysfile.props=props;
+
+ SeekFile(fd,0);
+ WriteFile(fd,&waysfile,sizeof(WaysFile));
+
CloseFile(fd);
+ /* Print the final message */
+
printf("\rWrote Ways: Ways=%d \n",waysx->number);
fflush(stdout);
-
- /* Free the fake Ways */
-
- free(ways);
}
/***************************************
- $Header: /home/amb/routino/src/RCS/waysx.h,v 1.21 2010/05/22 18:40:47 amb Exp $
+ $Header: /home/amb/routino/src/RCS/waysx.h,v 1.28 2010/09/25 18:47:32 amb Exp $
A header file for the extended Ways structure.
#include <stdint.h>
-#include "typesx.h"
#include "types.h"
+
+#include "typesx.h"
#include "ways.h"
+#include "files.h"
+
/* Data structures */
char *filename; /*+ The name of the temporary file (for the WaysX). +*/
int fd; /*+ The file descriptor of the temporary file (for the WaysX). +*/
- uint32_t xnumber; /*+ The number of unsorted extended ways. +*/
+ index_t xnumber; /*+ The number of unsorted extended ways. +*/
+
+#if !SLIM
WayX *xdata; /*+ The extended data for the Ways (sorted). +*/
- WayX cached[2]; /*+ Two cached ways read from the file in slim mode. +*/
- uint32_t number; /*+ How many entries are still useful? +*/
+#else
- uint32_t cnumber; /*+ How many entries are there after compacting? +*/
+ WayX xcached[2]; /*+ Two cached ways read from the file in slim mode. +*/
+
+#endif
+
+ index_t number; /*+ How many entries are still useful? +*/
+
+ index_t cnumber; /*+ How many entries are there after compacting? +*/
index_t *idata; /*+ The index of the extended data for the Ways (sorted by ID). +*/
void SaveWayList(WaysX *waysx,const char *filename);
index_t IndexWayX(WaysX* waysx,way_t id);
-WayX *LookupWayX(WaysX* waysx,index_t index,int position);
void AppendWay(WaysX* waysx,way_t id,Way *way,const char *name);
void SortWayList(WaysX *waysx);
+void CompactWayList(WaysX *waysx);
+
+
+/* Macros / inline functions */
+
+#if !SLIM
+
+#define LookupWayX(waysx,index,position) &(waysx)->xdata[index]
+
+#else
+
+static WayX *LookupWayX(WaysX* waysx,index_t index,int position);
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Lookup a particular extended way.
+
+ WayX *LookupWayX Returns a pointer to the extended way with the specified id.
+
+ WaysX* waysx The set of ways to process.
+
+ index_t index The way index to look for.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline WayX *LookupWayX(WaysX* waysx,index_t index,int position)
+{
+ SeekFile(waysx->fd,(off_t)index*sizeof(WayX));
+
+ ReadFile(waysx->fd,&waysx->xcached[position-1],sizeof(WayX));
+
+ return(&waysx->xcached[position-1]);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++
+ Put back an extended way.
+
+ WaysX* waysx The set of ways to process.
+
+ index_t index The way index to put back.
+
+ int position The position in the cache to use.
+ ++++++++++++++++++++++++++++++++++++++*/
+
+static inline void PutBackWayX(WaysX* waysx,index_t index,int position)
+{
+ SeekFile(waysx->fd,(off_t)index*sizeof(WayX));
+
+ WriteFile(waysx->fd,&waysx->xcached[position-1],sizeof(WayX));
+}
+
+#endif /* SLIM */
+
+
#endif /* WAYSX_H */
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!-- good comment -->
+
+<test>
+
+ <level1 attr1="value1 \ 3 value2">
+ <level2>
+ </level2>
+ </level1>
+
+</test>
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!-- good comment -->
+
+<test>
+
+ <level1 attr1="value1 õ value2">
+ <level2>
+ </level2>
+ </level1>
+
+</test>
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!-- good comment -->
+
+<test>
+
+ <level1 attr1='value1 \ 3 value2'>
+ <level2>
+ </level2>
+ </level1>
+
+</test>
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+
+<!-- good comment -->
+
+<test>
+
+ <level1 attr1='value1 õ value2'>
+ <level2>
+ </level2>
+ </level1>
+
+</test>
%{
/***************************************
- $Header: /home/amb/routino/src/RCS/xmlparse.l,v 1.17 2010/05/25 18:24:20 amb Exp $
+ $Header: /home/amb/routino/src/RCS/xmlparse.l,v 1.20 2010/10/09 11:05:28 amb Exp $
A simple generic XML parser where the structure comes from the function parameters.
Not intended to be fully conforming to XML staandard or a validating parser but
%option nounput
- /* Grammar based on http://www.w3.org/TR/2004/REC-xml-20040204/ but for ASCII not Unicode. */
+ /* Grammar based on http://www.w3.org/TR/2004/REC-xml-20040204/ but for ASCII tags not Unicode. */
S [ \t\r\n]
+U1 [\x09\x0A\x0D\x20-\x7F]
+U2 [\xC2-\xDF][\x80-\xBF]
+U3a \xE0[\xA0-\xBF][\x80-\xBF]
+U3b [\xE1-\xEC][\x80-\xBF][\x80-\xBF]
+U3c \xED[\x80-\x9F][\x80-\xBF]
+U3d [\xEE-\xEF][\x80-\xBF][\x80-\xBF]
+U3 {U3a}|{U3b}|{U3c}|{U3d}
+U4a \xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF]
+U4b [\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
+U4c \xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF]
+U4 {U4a}|{U4b}|{U4c}
+
+U ({U1}|{U2}|{U3}|{U4})
+UquotedS ([\x09\x0A\x0D\x20-\x25\x28-\x3B\x3D\x3F-\x7F]|{U2}|{U3}|{U4})
+UquotedD ([\x09\x0A\x0D\x20-\x21\x23-\x25\x27-\x3B\x3D\x3F-\x7F]|{U2}|{U3}|{U4})
+
+N (\n|\r\n)
+
letter [a-zA-Z]
digit [0-9]
xdigit [a-fA-F0-9]
/* XML Declaration start */
-<XML_DECL_START>{name} { BEGIN(XML_DECL); yylval=yytext; return(LEX_XML_DECL_BEGIN); }
-<XML_DECL_START>.|\n { return(LEX_ERROR_XML_DECL_START); }
+<XML_DECL_START>xml { BEGIN(XML_DECL); yylval=yytext; return(LEX_XML_DECL_BEGIN); }
+<XML_DECL_START>.|{N} { return(LEX_ERROR_XML_DECL_START); }
/* Tag middle */
<XML_DECL>"?>" { BEGIN(INITIAL); return(LEX_XML_DECL_FINISH); }
<XML_DECL>{S}+ { }
<XML_DECL>{name} { after_attr=XML_DECL; BEGIN(ATTR_KEY); yylval=yytext; return(LEX_ATTR_KEY); }
-<XML_DECL>.|\n { return(LEX_ERROR_XML_DECL); }
+<XML_DECL>.|{N} { return(LEX_ERROR_XML_DECL); }
/* Any tag start */
<TAG_START>{name} { BEGIN(TAG); yylval=yytext; return(LEX_TAG_BEGIN); }
-<TAG_START>.|\n { return(LEX_ERROR_TAG_START); }
+<TAG_START>.|{N} { return(LEX_ERROR_TAG_START); }
/* End-tag start */
<END_TAG1>{name} { BEGIN(END_TAG2); yylval=yytext; return(LEX_TAG_POP); }
-<END_TAG1>.|\n { return(LEX_ERROR_END_TAG); }
+<END_TAG1>.|{N} { return(LEX_ERROR_END_TAG); }
<END_TAG2>">" { BEGIN(INITIAL); }
-<END_TAG2>.|\n { return(LEX_ERROR_END_TAG); }
+<END_TAG2>.|{N} { return(LEX_ERROR_END_TAG); }
/* Any tag middle */
<TAG>">" { BEGIN(INITIAL); return(LEX_TAG_PUSH); }
<TAG>{S}+ { }
<TAG>{name} { after_attr=TAG; BEGIN(ATTR_KEY); yylval=yytext; return(LEX_ATTR_KEY); }
-<TAG>.|\n { return(LEX_ERROR_TAG); }
+<TAG>.|{N} { return(LEX_ERROR_TAG); }
/* Attributes */
<ATTR_KEY>= { BEGIN(ATTR_VAL); }
-<ATTR_KEY>.|\n { return(LEX_ERROR_ATTR); }
+<ATTR_KEY>.|{N} { return(LEX_ERROR_ATTR); }
<ATTR_VAL>\" { BEGIN(DQUOTED); reset_string; }
<ATTR_VAL>\' { BEGIN(SQUOTED); reset_string; }
-<ATTR_VAL>.|\n { return(LEX_ERROR_ATTR); }
+<ATTR_VAL>.|{N} { return(LEX_ERROR_ATTR); }
/* Quoted strings */
else { const char *str=ParseXML_Decode_Entity_Ref(yytext); if(str) {append_string(str);} else {yylval=yytext; return(LEX_ERROR_ENTITY_REF);} } }
<DQUOTED>{charref} { if(xmlparse_options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);}
else { const char *str=ParseXML_Decode_Char_Ref(yytext); if(str) {append_string(str);} else {yylval=yytext; return(LEX_ERROR_CHAR_REF);} } }
-<DQUOTED>[<>&] { yylval=yytext; return(LEX_ERROR_ATTR_VAL); }
-<DQUOTED>[^<>&\"]+ { append_string(yytext); }
+<DQUOTED>[<>&\"] { yylval=yytext; return(LEX_ERROR_ATTR_VAL); }
+<DQUOTED>{UquotedD}+ { append_string(yytext); }
+<DQUOTED>. { yylval=yytext; return(LEX_ERROR_ATTR_VAL); }
<SQUOTED>\' { BEGIN(after_attr); yylval=string; return(LEX_ATTR_VAL); }
<SQUOTED>{entityref} { if(xmlparse_options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);}
<SQUOTED>{charref} { if(xmlparse_options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);}
else { const char *str=ParseXML_Decode_Char_Ref(yytext); if(str) {append_string(str);} else {yylval=yytext; return(LEX_ERROR_CHAR_REF);} } }
<SQUOTED>[<>&] { yylval=yytext; return(LEX_ERROR_ATTR_VAL); }
-<SQUOTED>[^<>&\']+ { append_string(yytext); }
+<SQUOTED>{UquotedS}+ { append_string(yytext); }
+<SQUOTED>. { yylval=yytext; return(LEX_ERROR_ATTR_VAL); }
/* End of file */
char *result;
for(i=0;string[i];i++)
- if(string[i]=='<' || string[i]=='>' || string[i]=='&' || string[i]=='\'' || string[i]=='"' || string[i]<32 || string[i]>126)
+ if(string[i]=='<' || string[i]=='>' || string[i]=='&' || string[i]=='\'' || string[i]=='"' || string[i]<32 || (unsigned char)string[i]>127)
break;
if(!string[i])
result[j++]='t';
result[j++]=';';
}
- else if(string[i]<32 || string[i]>126)
+ else if(string[i]>=32 && (unsigned char)string[i]<=127)
+ result[j++]=string[i];
+ else
{
+ unsigned int unicode;
+
+ /* Decode the UTF-8 */
+
+ if((string[i]&0xE0)==0xC0 && (string[i]&0x1F)>=2 && (string[i+1]&0xC0)==0x80)
+ {
+ /* 0000 0080-0000 07FF 110xxxxx 10xxxxxx */
+ unicode =(string[i++]&0x1F)<<6;
+ unicode|= string[i ]&0x3F;
+ }
+ else if((string[i]&0xF0)==0xE0 && (string[i+1]&0xC0)==0x80 && (string[i+2]&0xC0)==0x80)
+ {
+ /* 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx */
+ unicode =(string[i++]&0x0F)<<12;
+ unicode|=(string[i++]&0x3F)<<6;
+ unicode|= string[i ]&0x3F;
+ }
+ else if((string[i]&0xF8)==0xF0 && (string[i+1]&0xC0)==0x80 && (string[i+2]&0xC0)==0x80 && (string[i+3]&0xC0)==0x80)
+ {
+ /* 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ unicode =(string[i++]&0x07)<<18;
+ unicode|=(string[i++]&0x3F)<<12;
+ unicode|=(string[i++]&0x3F)<<6;
+ unicode|= string[i ]&0x3F;
+ }
+ else
+ unicode=0xFFFD;
+
+ /* Output the character entity */
+
result[j++]='&';
result[j++]='#';
result[j++]='x';
- result[j++]=hexstring[(string[i]&0xf0)>>4];
- result[j++]=hexstring[ string[i]&0x0f ];
+
+ if(unicode&0x00FF0000)
+ {
+ result[j++]=hexstring[((unicode>>16)&0xf0)>>4];
+ result[j++]=hexstring[((unicode>>16)&0x0f) ];
+ }
+ if(unicode&0x00FFFF00)
+ {
+ result[j++]=hexstring[((unicode>>8)&0xf0)>>4];
+ result[j++]=hexstring[((unicode>>8)&0x0f) ];
+ }
+ result[j++]=hexstring[(unicode&0xf0)>>4];
+ result[j++]=hexstring[(unicode&0x0f) ];
+
result[j++]=';';
}
- else
- result[j++]=string[i];
if(string[i]) /* Not finished */
{
"length" => "[0-9.]+",
"length" => "[0-9.]+",
- "language" => "[-a-zA-Z]+"
+ "language" => "[-a-zA-Z]+",
"submit" => "(shortest|quickest|link)",
"format" => "(html|gpx-route|gpx-track|text|text-all|form)"
);
<td class="left" >%
<td class="right" ><input name="speed-steps" type="text" size=3 class="right"><!-- speed-steps -->
<td class="left" >km/hr
+ <tr>
+ <td class="left" >Ferry:
+ <td class="right" ><input name="highway-ferry" type="text" size=3 class="right"><!-- highway-ferry -->
+ <td class="left" >%
+ <td class="right" ><input name="speed-ferry" type="text" size=3 class="right"><!-- speed-ferry -->
+ <td class="left" >km/hr
</table>
<p>
<th class="left" colspan=2><b>Preference</b><br>
<tr>
<td class="left" >Paved:
- <td class="right" ><input name="paved" type="text" size=3 class="right"><!-- property-paved -->
+ <td class="right" ><input name="paved" type="text" size=3 class="right"><!-- property-paved -->
<td class="left" >%
<tr>
<td class="left" >Multiple Lanes:
- <td class="right" ><input name="multilane" type="text" size=3 class="right"><!-- property-multilane -->
+ <td class="right" ><input name="multilane" type="text" size=3 class="right"><!-- property-multilane -->
<td class="left" >%
<tr>
<td class="left" >Bridge:
- <td class="right" ><input name="bridge" type="text" size=3 class="right"><!-- property-bridge -->
+ <td class="right" ><input name="bridge" type="text" size=3 class="right"><!-- property-bridge -->
<td class="left" >%
<tr>
<td class="left" >Tunnel:
- <td class="right" ><input name="tunnel" type="text" size=3 class="right"><!-- property-tunnel -->
+ <td class="right" ><input name="tunnel" type="text" size=3 class="right"><!-- property-tunnel -->
+ <td class="left" >%
+ <tr>
+ <td class="left" >Walking Route:
+ <td class="right" ><input name="footroute" type="text" size=3 class="right"><!-- property-footroute -->
+ <td class="left" >%
+ <tr>
+ <td class="left" >Bicycle Route:
+ <td class="right" ><input name="bicycleroute" type="text" size=3 class="right"><!-- property-bicycleroute -->
<td class="left" >%
</table>
# EDIT THIS to set the root directory for the non-web data files.
$root_dir="../..";
-# EDIT THIS if you want to change the location of the individual directories.
+# EDIT THIS to change the location of the individual directories.
$bin_dir="$root_dir/bin";
$data_dir="$root_dir/data";
$results_dir="$root_dir/results";
+# EDIT THIS to change the names of the executables (enables easy selection of slim mode).
+$router_exe="router";
+$filedumper_exe="filedumper";
+
1;
<div id="hideshow_language_div" style="display: none;">
<table>
<tr>
- <td><a href="router.html.en" title="English language web page">English</a> (en)
+ <td><a href="router.html.en" title="English language web page">English</a>
+ <td>(EN)
<td><input name="language" type="radio" value="en" onchange="formSetLanguage('en')" checked><!-- language -->
+ <tr>
+ <td>German
+ <td>(DE)
+ <td><input name="language" type="radio" value="de" onchange="formSetLanguage('de')"><!-- language -->
+ <tr>
+ <td><a href="router.html.nl" title="Dutch language web page">Dutch</a>
+ <td>(NL)
+ <td><input name="language" type="radio" value="nl" onchange="formSetLanguage('nl')"><!-- language -->
</table>
</div>
</div>
<tr><td>Cycleway: <td><input name="highway-cycleway" type="text" size=3 onchange="formSetHighway('cycleway' )"><!-- highway-cycleway --><td>%
<tr><td>Path: <td><input name="highway-path" type="text" size=3 onchange="formSetHighway('path' )"><!-- highway-path --><td>%
<tr><td>Steps: <td><input name="highway-steps" type="text" size=3 onchange="formSetHighway('steps' )"><!-- highway-steps --><td>%
+ <tr><td>Ferry: <td><input name="highway-ferry" type="text" size=3 onchange="formSetHighway('ferry' )"><!-- highway-ferry --><td>%
</table>
</div>
</div>
<tr><td>Cycleway: <td><input name="speed-cycleway" type="text" size=3 onchange="formSetSpeed('cycleway' )"><!-- speed-cycleway --><td>km/hr
<tr><td>Path: <td><input name="speed-path" type="text" size=3 onchange="formSetSpeed('path' )"><!-- speed-path --><td>km/hr
<tr><td>Steps: <td><input name="speed-steps" type="text" size=3 onchange="formSetSpeed('steps' )"><!-- speed-steps --><td>km/hr
+ <tr><td>Ferry: <td><input name="speed-ferry" type="text" size=3 onchange="formSetSpeed('ferry' )"><!-- speed-ferry --><td>km/hr
</table>
</div>
</div>
<span class="hideshow_title">Property Preferences</span>
<div id="hideshow_property_div" style="display: none;">
<table>
- <tr><td>Paved: <td><input name="property-paved" type="text" size=3 onchange="formSetProperty('paved' )"><!-- property-paved --><td>%
- <tr><td>Multiple Lanes: <td><input name="property-multilane" type="text" size=3 onchange="formSetProperty('multilane')"><!-- property-multilane --><td>%
- <tr><td>Bridge: <td><input name="property-bridge" type="text" size=3 onchange="formSetProperty('bridge' )"><!-- property-bridge --><td>%
- <tr><td>Tunnel: <td><input name="property-tunnel" type="text" size=3 onchange="formSetProperty('tunnel' )"><!-- property-tunnel --><td>%
+ <tr><td>Paved: <td><input name="property-paved" type="text" size=3 onchange="formSetProperty('paved' )"><!-- property-paved --><td>%
+ <tr><td>Multiple Lanes:<td><input name="property-multilane" type="text" size=3 onchange="formSetProperty('multilane' )"><!-- property-multilane --><td>%
+ <tr><td>Bridge: <td><input name="property-bridge" type="text" size=3 onchange="formSetProperty('bridge' )"><!-- property-bridge --><td>%
+ <tr><td>Tunnel: <td><input name="property-tunnel" type="text" size=3 onchange="formSetProperty('tunnel' )"><!-- property-tunnel --><td>%
+ <tr><td>Walking Route: <td><input name="property-footroute" type="text" size=3 onchange="formSetProperty('footroute' )"><!-- property-footroute --><td>%
+ <tr><td>Bicycle Route: <td><input name="property-bicycleroute" type="text" size=3 onchange="formSetProperty('bicycleroute')"><!-- property-bicycleroute --><td>%
</table>
</div>
</div>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML>
+
+<!--
+ Routino router web page.
+
+ Part of the Routino routing software.
+
+ This file Copyright 2008-2010 Andrew M. Bishop
+
+ Dutch translation by Jan Jansen (August 2010).
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+-->
+
+<HEAD>
+<TITLE>Routino : Route Planner for OpenStreetMap Data</TITLE>
+<META name="keywords" content="openstreetmap routing route planner">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+<!-- OpenLayers Javascript library -->
+<script src="../openlayers/OpenLayers.js" type="text/javascript"></script>
+
+<!-- Page elements -->
+<script src="page-elements.js" type="text/javascript"></script>
+<link href="page-elements.css" type="text/css" rel="stylesheet">
+
+<!-- Router and visualiser shared features -->
+<link href="maplayout.css" type="text/css" rel="stylesheet">
+<!--[if IE 6]>
+ <link href="maplayout-ie6-bugfixes.css" type="text/css" rel="stylesheet">
+<![endif]-->
+<!--[if IE 7]>
+ <link href="maplayout-ie7-bugfixes.css" type="text/css" rel="stylesheet">
+<![endif]-->
+
+<!-- Router specific features -->
+<script src="router.js" type="text/javascript"></script>
+<link href="router.css" type="text/css" rel="stylesheet">
+
+</HEAD>
+<BODY onload="map_init('lat','lon','zoom');form_init();block_return_key();">
+
+<!-- Left hand side of window - data panel -->
+
+<div class="left_panel">
+
+ <div class="tab_box">
+ <span id="tab_options" onclick="tab_select('options');" class="tab_selected" title="Set routing options">Opties</span>
+ <span id="tab_results" onclick="tab_select('results');" class="tab_unselected" title="See routing results">Resultaten</span>
+ <span id="tab_data" onclick="tab_select('data');" class="tab_unselected" title="View database information">Data</span>
+ </div>
+
+ <div class="tab_content" id="tab_options_div">
+
+ <form name="form" id="form" action="router.cgi" method="get">
+ <div class="hideshow_box">
+ <span class="hideshow_title">Routino OpenStreetMap Router</span>
+ Zoom naar straatniveau.
+ Selecteer start- and eindpunten onder Coordinaten. (click op het marker
+ icoon links, schuif het op map naar gewenste positie).
+ <div align="center">
+ <a target="other" href="http://www.routino.org/">Routino Website</a>
+ |
+ <a target="other" href="documentation/">Documentation</a>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_language_show" onclick="hideshow_show('language');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_language_hide" onclick="hideshow_hide('language');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Taal (Language)</span>
+
+ <!-- Note for translations: Only this HTML file needs to be translated, the Javascript has
+ no language specific information in it. Only the body text and title attributes should
+ be changed, the values passed to the JavaScript and the element names must not be changed.
+ The selection below changes the language option passed to the router and selects the
+ output language not the web page language, the links are for that. The router itself uses
+ the translations.xml file for the translated versions of the output. -->
+
+ <div id="hideshow_language_div" style="display: none;">
+ <table>
+ <tr>
+ <td><a href="router.html.nl" title="Nederlandse web pagina">Nederlands</a>
+ <td>(NL)
+ <td><input name="language" type="radio" value="nl" onchange="formSetLanguage('nl')" checked><!-- language -->
+ <tr>
+ <td><a href="router.html.en" title="Engelstalige web pagina">English</a>
+ <td>(EN)
+ <td><input name="language" type="radio" value="en" onchange="formSetLanguage('en')" ><!-- language -->
+ <tr>
+ <td>German
+ <td>(DE)
+ <td><input name="language" type="radio" value="de" onchange="formSetLanguage('de')"><!-- language -->
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_waypoint_show" onclick="hideshow_show('waypoint');" class="hideshow_hide">Laat zien</span>
+ <span id="hideshow_waypoint_hide" onclick="hideshow_hide('waypoint');" class="hideshow_show">Verberg</span>
+ <span class="hideshow_title">Coordinaten (waypoints)</span>
+ <div id="hideshow_waypoint_div">
+ <table>
+ <tr id="point1">
+ <td>
+ <img name="waypoint1" src="icons/marker-1-grey.png" title="Waypoint 1 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 1" onmousedown="markerToggleMap(1)">
+ <td>
+ <input name="lon1" type="text" size=7 title="Waypoint 1 Longitude" onchange="formSetCoords(1);"><!-- lon1 --> E
+ <td>
+ <input name="lat1" type="text" size=7 title="Waypoint 1 Latitude" onchange="formSetCoords(1);"><!-- lat1 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(1);" >
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(1);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(1);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(1);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(1);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(1);" >
+ <tr id="point2">
+ <td>
+ <img name="waypoint2" src="icons/marker-2-grey.png" title="Waypoint 2 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 2" onmousedown="markerToggleMap(2)">
+ <td>
+ <input name="lon2" type="text" size=7 title="Waypoint 2 Longitude" onchange="formSetCoords(2);"><!-- lon2 --> E
+ <td>
+ <input name="lat2" type="text" size=7 title="Waypoint 2 Latitude" onchange="formSetCoords(2);"><!-- lat2 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(2);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(2);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(2);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(2);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(2);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(2);" >
+ <tr id="point3">
+ <td>
+ <img name="waypoint3" src="icons/marker-3-grey.png" title="Waypoint 3 Position - (click voor plaatsen/verwijderen on map)" alt="Waypoint 3" onmousedown="markerToggleMap(3)">
+ <td>
+ <input name="lon3" type="text" size=7 title="Waypoint 3 Longitude" onchange="formSetCoords(3);"><!-- lon3 --> E
+ <td>
+ <input name="lat3" type="text" size=7 title="Waypoint 3 Latitude" onchange="formSetCoords(3);"><!-- lat3 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(3);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(3);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(3);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(3);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(3);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(3);" >
+ <tr id="point4">
+ <td>
+ <img name="waypoint4" src="icons/marker-4-grey.png" title="Waypoint 4 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 4" onmousedown="markerToggleMap(4)">
+ <td>
+ <input name="lon4" type="text" size=7 title="Waypoint 4 Longitude" onchange="formSetCoords(4);"><!-- lon4 --> E
+ <td>
+ <input name="lat4" type="text" size=7 title="Waypoint 4 Latitude" onchange="formSetCoords(4);"><!-- lat4 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(4);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(4);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(4);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(4);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(4);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(4);" >
+ <tr id="point5">
+ <td>
+ <img name="waypoint5" src="icons/marker-5-grey.png" title="Waypoint 5 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 5" onmousedown="markerToggleMap(5)">
+ <td>
+ <input name="lon5" type="text" size=7 title="Waypoint 5 Longitude" onchange="formSetCoords(5);"><!-- lon5 --> E
+ <td>
+ <input name="lat5" type="text" size=7 title="Waypoint 5 Latitude" onchange="formSetCoords(5);"><!-- lat5 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(5);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(5);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(5);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(5);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(5);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(5);" >
+ <tr id="point6">
+ <td>
+ <img name="waypoint6" src="icons/marker-6-grey.png" title="Waypoint 6 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 6" onmousedown="markerToggleMap(6)">
+ <td>
+ <input name="lon6" type="text" size=7 title="Waypoint 6 Longitude" onchange="formSetCoords(6);"><!-- lon6 --> E
+ <td>
+ <input name="lat6" type="text" size=7 title="Waypoint 6 Latitude" onchange="formSetCoords(6);"><!-- lat6 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(6);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(6);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(6);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(6);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(6);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(6);" >
+ <tr id="point7">
+ <td>
+ <img name="waypoint7" src="icons/marker-7-grey.png" title="Waypoint 7 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 7" onmousedown="markerToggleMap(7)">
+ <td>
+ <input name="lon7" type="text" size=7 title="Waypoint 7 Longitude" onchange="formSetCoords(7);"><!-- lon7 --> E
+ <td>
+ <input name="lat7" type="text" size=7 title="Waypoint 7 Latitude" onchange="formSetCoords(7);"><!-- lat7 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(7);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(7);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(7);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(7);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(7);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(7);" >
+ <tr id="point8">
+ <td>
+ <img name="waypoint8" src="icons/marker-8-grey.png" title="Waypoint 8 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 8" onmousedown="markerToggleMap(8)">
+ <td>
+ <input name="lon8" type="text" size=7 title="Waypoint 8 Longitude" onchange="formSetCoords(8);"><!-- lon8 --> E
+ <td>
+ <input name="lat8" type="text" size=7 title="Waypoint 8 Latitude" onchange="formSetCoords(8);"><!-- lat8 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(8);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(8);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(8);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(8);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(8);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(8);" >
+ <tr id="point9">
+ <td>
+ <img name="waypoint9" src="icons/marker-9-grey.png" title="Waypoint 9 Position - (click voor plaatsen/verwijderen op map)" alt="Waypoint 9" onmousedown="markerToggleMap(9)">
+ <td>
+ <input name="lon9" type="text" size=7 title="Waypoint 9 Longitude" onchange="formSetCoords(9);"><!-- lon9 --> E
+ <td>
+ <input name="lat9" type="text" size=7 title="Waypoint 9 Latitude" onchange="formSetCoords(9);"><!-- lat9 --> N
+ <td>
+ <img alt="o" src="icons/waypoint-centre.png" title="Centreer dit punt op map" onmousedown="markerCentre(9);">
+ <img alt="^" src="icons/waypoint-up.png" title="Beweeg dit punt naar boven" onmousedown="markerMoveUp(9);" >
+ <img alt="+" src="icons/waypoint-add.png" title="Voeg hierna punt toe" onmousedown="markerAddAfter(9);"><br>
+ <img alt="~" src="icons/waypoint-home.png" title="Toggle als thuis locatie" onmousedown="markerHome(9);" >
+ <img alt="v" src="icons/waypoint-down.png" title="Beweeg dit punt naar beneden" onmousedown="markerMoveDown(9);">
+ <img alt="-" src="icons/waypoint-remove.png" title="Verwijder dit punt" onmousedown="markerRemove(9);" >
+ <!-- Up to 99 markers can be included here in the HTML -->
+ <tr>
+ <td colspan="4" align="center"><input type="button" title="Keer volgorde punten om" value="Keer volgorde punten om" onmousedown="markersReverse();">
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_transport_show" onclick="hideshow_show('transport');" class="hideshow_hide">Laat zien</span>
+ <span id="hideshow_transport_hide" onclick="hideshow_hide('transport');" class="hideshow_show">Verberg</span>
+ <span class="hideshow_title">Transport Type</span>
+ <div id="hideshow_transport_div">
+ <table>
+ <tr><td>Te voet <td><input name="transport" type="radio" value="foot" onchange="formSetTransport('foot' )"><!-- transport -->
+ <tr><td>Paard <td><input name="transport" type="radio" value="horse" onchange="formSetTransport('horse' )"><!-- transport -->
+ <tr><td>Rolstoel <td><input name="transport" type="radio" value="wheelchair" onchange="formSetTransport('wheelchair')"><!-- transport -->
+ <tr><td>Fiets <td><input name="transport" type="radio" value="bicycle" onchange="formSetTransport('bicycle' )"><!-- transport -->
+ <tr><td>Brommer <td><input name="transport" type="radio" value="moped" onchange="formSetTransport('moped' )"><!-- transport -->
+ <tr><td>Motorfiets <td><input name="transport" type="radio" value="motorbike" onchange="formSetTransport('motorbike' )"><!-- transport -->
+ <tr><td>Auto <td><input name="transport" type="radio" value="motorcar" onchange="formSetTransport('motorcar' )"><!-- transport -->
+ <tr><td>Goederen <td><input name="transport" type="radio" value="goods" onchange="formSetTransport('goods' )"><!-- transport -->
+ <tr><td>Zwaar transport <td><input name="transport" type="radio" value="hgv" onchange="formSetTransport('hgv' )"><!-- transport -->
+ <tr><td>Publiek transport<td><input name="transport" type="radio" value="psv" onchange="formSetTransport('psv' )"><!-- transport -->
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_highway_show" onclick="hideshow_show('highway');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_highway_hide" onclick="hideshow_hide('highway');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Voorkeur Wegtype</span>
+ <div id="hideshow_highway_div" style="display: none;">
+ <table>
+ <tr><td>Autostrade <td><input name="highway-motorway" type="text" size=3 onchange="formSetHighway('motorway' )"><!-- highway-motorway --><td>%
+ <tr><td>Autoweg: <td><input name="highway-trunk" type="text" size=3 onchange="formSetHighway('trunk' )"><!-- highway-trunk --><td>%
+ <tr><td>Provinciale wegen: <td><input name="highway-primary" type="text" size=3 onchange="formSetHighway('primary' )"><!-- highway-primary --><td>%
+ <tr><td>Nationale wegen: <td><input name="highway-secondary" type="text" size=3 onchange="formSetHighway('secondary' )"><!-- highway-secondary --><td>%
+ <tr><td>Doorgangsweg: <td><input name="highway-tertiary" type="text" size=3 onchange="formSetHighway('tertiary' )"><!-- highway-tertiary --><td>%
+ <tr><td>Niet geclassificeerd:<td><input name="highway-unclassified" type="text" size=3 onchange="formSetHighway('unclassified')"><!-- highway-unclassified --><td>%
+ <tr><td>Woongebied: <td><input name="highway-residential" type="text" size=3 onchange="formSetHighway('residential' )"><!-- highway-residential --><td>%
+ <tr><td>Toegangsweg: <td><input name="highway-service" type="text" size=3 onchange="formSetHighway('service' )"><!-- highway-service --><td>%
+ <tr><td>Veldweg: <td><input name="highway-track" type="text" size=3 onchange="formSetHighway('track' )"><!-- highway-track --><td>%
+ <tr><td>Fietspad: <td><input name="highway-cycleway" type="text" size=3 onchange="formSetHighway('cycleway' )"><!-- highway-cycleway --><td>%
+ <tr><td>Pad: <td><input name="highway-path" type="text" size=3 onchange="formSetHighway('path' )"><!-- highway-path --><td>%
+ <tr><td>Trap: <td><input name="highway-steps" type="text" size=3 onchange="formSetHighway('steps' )"><!-- highway-steps --><td>%
+ <tr><td>Ferry: <td><input name="highway-ferry" type="text" size=3 onchange="formSetHighway('ferry' )"><!-- highway-ferry --><td>%
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_speed_show" onclick="hideshow_show('speed');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_speed_hide" onclick="hideshow_hide('speed');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Snelheidslimieten</span>
+ <div id="hideshow_speed_div" style="display: none;">
+ <table>
+ <tr><td>Autostrade <td><input name="speed-motorway" type="text" size=3 onchange="formSetSpeed('motorway' )"><!-- speed-motorway --><td>km/hr
+ <tr><td>Autoweg: <td><input name="speed-trunk" type="text" size=3 onchange="formSetSpeed('trunk' )"><!-- speed-trunk --><td>km/hr
+ <tr><td>Provinciale wegen: <td><input name="speed-primary" type="text" size=3 onchange="formSetSpeed('primary' )"><!-- speed-primary --><td>km/hr
+ <tr><td>Nationale wegen: <td><input name="speed-secondary" type="text" size=3 onchange="formSetSpeed('secondary' )"><!-- speed-secondary --><td>km/hr
+ <tr><td>Doorgangsweg: <td><input name="speed-tertiary" type="text" size=3 onchange="formSetSpeed('tertiary' )"><!-- speed-tertiary --><td>km/hr
+ <tr><td>Niet geclassificeerd:<td><input name="speed-unclassified" type="text" size=3 onchange="formSetSpeed('unclassified')"><!-- speed-unclassified --><td>km/hr
+ <tr><td>Woongebied: <td><input name="speed-residential" type="text" size=3 onchange="formSetSpeed('residential' )"><!-- speed-residential --><td>km/hr
+ <tr><td>Toegangsweg: <td><input name="speed-service" type="text" size=3 onchange="formSetSpeed('service' )"><!-- speed-service --><td>km/hr
+ <tr><td>Veldweg: <td><input name="speed-track" type="text" size=3 onchange="formSetSpeed('track' )"><!-- speed-track --><td>km/hr
+ <tr><td>Fietspad: <td><input name="speed-cycleway" type="text" size=3 onchange="formSetSpeed('cycleway' )"><!-- speed-cycleway --><td>km/hr
+ <tr><td>Pad: <td><input name="speed-path" type="text" size=3 onchange="formSetSpeed('path' )"><!-- speed-path --><td>km/hr
+ <tr><td>Trap: <td><input name="speed-steps" type="text" size=3 onchange="formSetSpeed('steps' )"><!-- speed-steps --><td>km/hr
+ <tr><td>Ferry: <td><input name="speed-ferry" type="text" size=3 onchange="formSetSpeed('ferry' )"><!-- speed-ferry --><td>km/hr
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_property_show" onclick="hideshow_show('property');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_property_hide" onclick="hideshow_hide('property');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Weg Eigenschappen</span>
+ <div id="hideshow_property_div" style="display: none;">
+ <table>
+ <tr><td>Verhard: <td><input name="property-paved" type="text" size=3 onchange="formSetProperty('paved' )"><!-- property-paved --><td>%
+ <tr><td>Meerdere Stroken:<td><input name="property-multilane" type="text" size=3 onchange="formSetProperty('multilane' )"><!-- property-multilane --><td>%
+ <tr><td>Brug: <td><input name="property-bridge" type="text" size=3 onchange="formSetProperty('bridge' )"><!-- property-bridge --><td>%
+ <tr><td>Tunnel: <td><input name="property-tunnel" type="text" size=3 onchange="formSetProperty('tunnel' )"><!-- property-tunnel --><td>%
+ <tr><td>Walking Route: <td><input name="property-footroute" type="text" size=3 onchange="formSetProperty('footroute' )"><!-- property-footroute --><td>%
+ <tr><td>Bicycle Route: <td><input name="property-bicycleroute" type="text" size=3 onchange="formSetProperty('bicycleroute')"><!-- property-bicycleroute --><td>%
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_restriction_show" onclick="hideshow_show('restriction');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_restriction_hide" onclick="hideshow_hide('restriction');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Andere Beperkingen</span>
+ <div id="hideshow_restriction_div" style="display: none;">
+ <table>
+ <tr><td>Volg Eenrichtingsverkeer:<td><input name="restrict-oneway" type="checkbox" onchange="formSetRestriction('oneway')"><!-- oneway --><td>
+ <tr><td>Gewicht: <td><input name="restrict-weight" type="text" size=3 onchange="formSetRestriction('weight')"><!-- weight --><td> ton
+ <tr><td>Hoogte: <td><input name="restrict-height" type="text" size=3 onchange="formSetRestriction('height')"><!-- height --><td> meter
+ <tr><td>Breedte: <td><input name="restrict-width" type="text" size=3 onchange="formSetRestriction('width' )"><!-- width --><td> meter
+ <tr><td>Lengte: <td><input name="restrict-length" type="text" size=3 onchange="formSetRestriction('length')"><!-- length --><td> meter
+ </table>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span class="hideshow_title">Zoek Route</span>
+ <input type="button" title="Zoek de kortste route" id="shortest" value="Kortste" onclick="findRoute('shortest');">
+ <input type="button" title="Zoek de snelste route" id="quickest" value="Snelste" onclick="findRoute('quickest');">
+ </div>
+
+ <div class="hideshow_box">
+ <span class="hideshow_title">Links</span>
+ <a id="link_url" href="router.html">Permanente link naar deze parameters</a>
+ <br>
+ <a id="edit_url" target="other" href="http://wiki.openstreetmap.org/wiki/NL:Mapper">Lees hoe je OSM data kan inbrengen met Potlatch</a>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_help_options_show" onclick="hideshow_show('help_options');" class="hideshow_hide">Laat zien</span>
+ <span id="hideshow_help_options_hide" onclick="hideshow_hide('help_options');" class="hideshow_show">Verberg</span>
+ <span class="hideshow_title">Help</span>
+ <div id="hideshow_help_options_div">
+ <div class="scrollable">
+ <p>
+ <b>Quick Start</b>
+ <br>
+ Click op marker-icoontje (Waypoints) om ze op de map te plaatsen (rechts).
+ Sleep ze vervolgens naar de gewenste positie.
+ Het is best om eerst naar straat niveau te zoomen op de kaart.
+ Selecteer het transport type, toegestane weg-types,
+ snelheidslimieten, wegeigenschappen en andere restricties uit de
+ opties.
+ Selecteer "Kortste" of "Snelste" om de route te berekenen en te tekenen op de map.
+ <p>
+ <b>Coordinaten (Waypoints)</b>
+ <br>
+ Click op het marker icoontje, nog eens clicken voor aan/uit.
+ Wanneer de route berekend wordt, zal dit nauwkeurig aansluiten bij de volgorde van deze punten. (rekening houdend met transport type)
+ <p>
+ <b>Transport Type</b>
+ <br>
+ Wanneer je een bepaald transport type kiest wordt bij berekenen
+ route hiermede rekening gehouden.
+ Het transport type bestaat uit een lijst met default waarden voor
+ ieder wegtype.
+ Deze percentages kunnen ook nog eens manueel aangepast worden.
+ <p>
+ <b>Voorkeur Wegtype</b>
+ <br>
+ De voorkeur voor een bepaald type weg wordt uitgedrukt in een percentage.
+ Bijvoorbeeld wanneer u het Transport Type "Fiets" kiest, dan zal er
+ voor Autostrade 0% staan, en voor Fietspad 100%.
+ Wanneer u Autowegen, Nationale wegen wil vermijden of beperken bij
+ het maken van een fietsroute, kan u percentage naar beneden
+ aanpassen.
+ <p>
+ <b>Snelheid limieten</b>
+ <br>
+ De snelheidslimieten worden afgeleid van het type weg. Het is
+ mogelijk dat er voor een bepaalde weg andere beperkingen gelden. In
+ dat geval worden die gekoezen. (het geval dat deze lager zijn dan de
+ default)
+ <p>
+ <b>Weg Eigenschappen</b>
+ <br>
+ Voor het berekenen van de route, kan de de voorkeur gegeven worden
+ aan een bepaalde wegeigenschap.
+ Wanneer u kiest voor 25% verhard, zal er automatisch de voorkeur aan
+ 75% onverhard worden gegeven.
+ Ook al is het onverharde stuk 3 X langer, toch kan er dan de
+ voorkeur aan gegeven worden.
+ <p>
+ <b>Andere Beperkingen</b>
+ <br>
+ Deze zullen toelaten dat er een route berekend wordt die rekening
+ houdt met gewicht, hoogte, breedte of lengte.
+ Het is ook mogelijk geen rekening te houden met eenrichtingsverkeer
+ (bijvoorbeeld als voetganger of fietser)
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+
+
+ <div class="tab_content" id="tab_results_div" style="display: none;">
+
+ <div class="hideshow_box">
+ <span class="hideshow_title">Status</span>
+ <div id="result_status">
+ <span id="result_status_not_run" ><b><i>Router niet in gebruik</i></b></span>
+ <span id="result_status_running" style="display: none;"><b>Router werkt...</b></span>
+ <span id="result_status_complete" style="display: none;"><b>Routing voltooid</b></span>
+ <span id="result_status_error" style="display: none;"><b>Router error</b></span>
+ <span id="result_status_failed" style="display: none;"><b>Router werkt niet</b></span>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_shortest_show" onclick="hideshow_show('shortest');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_shortest_hide" onclick="hideshow_hide('shortest');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Kortste Route</span>
+ <div id="shortest_status">
+ <span id="shortest_status_no_info" ><b><i>No Information</i></b></span>
+ <span id="shortest_status_info" style="display: none;"></span>
+ </div>
+ <div id="hideshow_shortest_div" style="display: none;">
+ <div id="shortest_links" style="display: none;">
+ <table>
+ <tr><td>HTML directions: <td><a id="shortest_html" target="shortest_html" href="#">Open Popup</a>
+ <tr><td>GPX track bestand:<td><a id="shortest_gpx_track" target="shortest_gpx_track" href="#">Open Popup</a>
+ <tr><td>GPX route bestand:<td><a id="shortest_gpx_route" target="shortest_gpx_route" href="#">Open Popup</a>
+ <tr><td>Full text bestand:<td><a id="shortest_text_all" target="shortest_text_all" href="#">Open Popup</a>
+ <tr><td>Text bestand: <td><a id="shortest_text" target="shortest_text" href="#">Open Popup</a>
+ </table>
+ <hr>
+ </div>
+ <div id="shortest_route">
+ </div>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_quickest_show" onclick="hideshow_show('quickest');" class="hideshow_show">Laat zien</span>
+ <span id="hideshow_quickest_hide" onclick="hideshow_hide('quickest');" class="hideshow_hide">Verberg</span>
+ <span class="hideshow_title">Snelste Route</span>
+ <div id="quickest_status">
+ <span id="quickest_status_no_info" ><b><i>No Information</i></b></span>
+ <span id="quickest_status_info" style="display: none;"></span>
+ </div>
+ <div id="hideshow_quickest_div" style="display: none;">
+ <div id="quickest_links" style="display: none;">
+ <table>
+ <tr><td>HTML directions: <td><a id="quickest_html" target="quickest_html" href="#">Open Popup</a>
+ <tr><td>GPX track bestand:<td><a id="quickest_gpx_track" target="quickest_gpx_track" href="#">Open Popup</a>
+ <tr><td>GPX route bestand:<td><a id="quickest_gpx_route" target="quickest_gpx_route" href="#">Open Popup</a>
+ <tr><td>Full text bestand:<td><a id="quickest_text_all" target="quickest_text_all" href="#">Open Popup</a>
+ <tr><td>Text bestand: <td><a id="quickest_text" target="quickest_text" href="#">Open Popup</a>
+ </table>
+ <hr>
+ </div>
+ <div id="quickest_route">
+ </div>
+ </div>
+ </div>
+
+ <div class="hideshow_box">
+ <span id="hideshow_help_route_show" onclick="hideshow_show('help_route');" class="hideshow_hide">Laat zien</span>
+ <span id="hideshow_help_route_hide" onclick="hideshow_hide('help_route');" class="hideshow_show">Verberg</span>
+ <span class="hideshow_title">Help</span>
+ <div id="hideshow_help_route_div">
+ <div class="scrollable">
+ <p>
+ <b>Quick Start</b>
+ <br>
+ Na het berekenen van een route, kan het GPX bestand, of de beschrijving als tekstbestand downloaden.
+ Door met muis over de beschrijving te bewegen, ziet u die ook op de kaart gesitueerd.
+ <p style="margin-bottom: 0px">
+ <b>Problem Solving</b>
+ <br>
+ Als de router eindigt met een fout, dan is de meest waarschijnlijke
+ oorzaak, dat er geen route mogelijk is tussen de gekozen punten.
+ Het verplaatsen van de punten, of het aanpassen van weg-eigenschappen
+ of voertuigtype kan een oplossing bieden.
+ <p style="margin-bottom: 0px">
+ <b>Output Formats</b>
+ <br>
+ <dl style="margin-top: 0px">
+ <dt>HTML instructies
+ <dd>Een beschrijving van de route, met de te nemen afslag aan iedere splitsing.
+ <dt>GPX track bestand
+ <dd>Dezelfde informatie die op de kaart wordt weergegeven. Met
+ coordinaten voor ieder knooppunt, en een track voor ieder segment.
+ <dt>GPX route bestand
+ <dd>Dezelfde informatie dat is opgenomen in de tekst van de route,
+ met een coordinaat voor iedere belangrijke splitsing.
+ <dt>Full text bestand
+ <dd>Een lijst met alle coordinaten, met de afstand hier tussen. En
+ een cumulatieve afstand voor iedere stap op de route.
+ <dt>Text bestand
+ <dd>Dezelfde informatie als wordt weergegeven in de tekst voor de route.
+ </dl>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <div class="tab_content" id="tab_data_div" style="display: none;">
+ <div class="hideshow_box">
+ <span class="hideshow_title">Statistics</span>
+ <div id="statistics_data"></div>
+ <a id="statistics_link" href="statistics.cgi" onclick="displayStatistics();return(false);">Display data statistics</a>
+ </div>
+
+ <div class="hideshow_box">
+ <span class="hideshow_title">Visualiser</span>
+ Om te kijken hoe routino omgaat met de basisdata, is er een tooltje dat de onderliggende data toont op verschillende manieren.
+ <br>
+ <a id="visualiser_url" target="other" href="visualiser.html">Custom link to this map view</a>
+ </div>
+ </div>
+
+</div>
+
+<!-- Right hand side of window - map -->
+
+<div class="right_panel">
+ <div class="map" id="map">
+ <noscript>
+ Javascript is <em>required</em> to use this web page because of the
+ interactive map.
+ </noscript>
+ </div>
+ <div class="attribution">
+ <a target="other" href="http://www.routino.org/" title="Routino">Router: Routino</a>
+ |
+ <a target="other" href="http://www.openstreetmap.org/" title="Copyright: OpenStreetMap.org; License: Creative Commons Attribution-Share Alike 2.0">Geo Data: OpenStreetMap</a>
+ </div>
+</div>
+
+</BODY>
+</HTML>
/////////////////////////// Routino default profile ////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-var routino={ // contains all default Routino options (generated using "--help-profile-js").
+var routino={ // contains all default Routino options (generated using "--help-profile-json").
// Default transport type
transport: 'motorcar',
// Transport types
- transports: {foot: 1, horse: 2, wheelchair: 3, bicycle: 4, moped: 5, motorbike: 6, motorcar: 7, goods: 8, hgv: 9, psv: 10},
+ transports: { foot: 1, horse: 2, wheelchair: 3, bicycle: 4, moped: 5, motorbike: 6, motorcar: 7, goods: 8, hgv: 9, psv: 10 },
// Highway types
- highways: {motorway: 1, trunk: 2, primary: 3, secondary: 4, tertiary: 5, unclassified: 6, residential: 7, service: 8, track: 9, cycleway: 10, path: 11, steps: 12},
+ highways: { motorway: 1, trunk: 2, primary: 3, secondary: 4, tertiary: 5, unclassified: 6, residential: 7, service: 8, track: 9, cycleway: 10, path: 11, steps: 12, ferry: 13 },
// Property types
- properties: {paved: 1, multilane: 2, bridge: 3, tunnel: 4},
+ properties: { paved: 1, multilane: 2, bridge: 3, tunnel: 4, footroute: 5, bicycleroute: 6 },
// Restriction types
- restrictions: {oneway: 1, weight: 2, height: 3, width: 4, length: 5},
+ restrictions: { oneway: 1, weight: 2, height: 3, width: 4, length: 5 },
// Allowed highways
profile_highway: {
- motorway: {foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100},
- trunk: {foot: 40, horse: 25, wheelchair: 40, bicycle: 30, moped: 90, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100},
- primary: {foot: 50, horse: 50, wheelchair: 50, bicycle: 70, moped: 100, motorbike: 90, motorcar: 90, goods: 90, hgv: 90, psv: 90},
- secondary: {foot: 60, horse: 50, wheelchair: 60, bicycle: 80, moped: 90, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80},
- tertiary: {foot: 70, horse: 75, wheelchair: 70, bicycle: 90, moped: 80, motorbike: 70, motorcar: 70, goods: 70, hgv: 70, psv: 70},
- unclassified: {foot: 80, horse: 75, wheelchair: 80, bicycle: 90, moped: 70, motorbike: 60, motorcar: 60, goods: 60, hgv: 60, psv: 60},
- residential: {foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 60, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50},
- service: {foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 80, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80},
- track: {foot: 95, horse: 100, wheelchair: 95, bicycle: 90, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0},
- cycleway: {foot: 95, horse: 90, wheelchair: 95, bicycle: 100, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0},
- path: {foot: 100, horse: 100, wheelchair: 100, bicycle: 90, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0},
- steps: {foot: 80, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0}
+ motorway: { foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+ trunk: { foot: 40, horse: 25, wheelchair: 40, bicycle: 30, moped: 90, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+ primary: { foot: 50, horse: 50, wheelchair: 50, bicycle: 70, moped: 100, motorbike: 90, motorcar: 90, goods: 90, hgv: 90, psv: 90 },
+ secondary: { foot: 60, horse: 50, wheelchair: 60, bicycle: 80, moped: 90, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 },
+ tertiary: { foot: 70, horse: 75, wheelchair: 70, bicycle: 90, moped: 80, motorbike: 70, motorcar: 70, goods: 70, hgv: 70, psv: 70 },
+ unclassified: { foot: 80, horse: 75, wheelchair: 80, bicycle: 90, moped: 70, motorbike: 60, motorcar: 60, goods: 60, hgv: 60, psv: 60 },
+ residential: { foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 60, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 },
+ service: { foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 80, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 },
+ track: { foot: 95, horse: 100, wheelchair: 95, bicycle: 90, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ cycleway: { foot: 95, horse: 90, wheelchair: 95, bicycle: 100, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ path: { foot: 100, horse: 100, wheelchair: 100, bicycle: 90, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ steps: { foot: 80, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ ferry: { foot: 20, horse: 20, wheelchair: 20, bicycle: 20, moped: 20, motorbike: 20, motorcar: 20, goods: 20, hgv: 20, psv: 20 }
},
// Speed limits
profile_speed: {
- motorway: {foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 48, motorbike: 112, motorcar: 112, goods: 96, hgv: 89, psv: 89},
- trunk: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80},
- primary: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80},
- secondary: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 88, motorcar: 88, goods: 88, hgv: 80, psv: 80},
- tertiary: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80},
- unclassified: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 64, motorcar: 64, goods: 64, hgv: 64, psv: 64},
- residential: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 48, motorcar: 48, goods: 48, hgv: 48, psv: 48},
- service: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 32, motorbike: 32, motorcar: 32, goods: 32, hgv: 32, psv: 32},
- track: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 16, motorbike: 16, motorcar: 16, goods: 16, hgv: 16, psv: 16},
- cycleway: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0},
- path: {foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0},
- steps: {foot: 4, horse: 0, wheelchair: 4, bicycle: 0, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0}
+ motorway: { foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 48, motorbike: 112, motorcar: 112, goods: 96, hgv: 89, psv: 89 },
+ trunk: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80 },
+ primary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80 },
+ secondary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 88, motorcar: 88, goods: 88, hgv: 80, psv: 80 },
+ tertiary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 },
+ unclassified: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 64, motorcar: 64, goods: 64, hgv: 64, psv: 64 },
+ residential: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorbike: 48, motorcar: 48, goods: 48, hgv: 48, psv: 48 },
+ service: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 32, motorbike: 32, motorcar: 32, goods: 32, hgv: 32, psv: 32 },
+ track: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 16, motorbike: 16, motorcar: 16, goods: 16, hgv: 16, psv: 16 },
+ cycleway: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ path: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ steps: { foot: 4, horse: 0, wheelchair: 4, bicycle: 0, moped: 0, motorbike: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 },
+ ferry: { foot: 10, horse: 10, wheelchair: 10, bicycle: 10, moped: 10, motorbike: 10, motorcar: 10, goods: 10, hgv: 10, psv: 10 }
},
// Highway properties
profile_property: {
- paved: {foot: 50, horse: 20, wheelchair: 90, bicycle: 50, moped: 100, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100},
- multilane: {foot: 25, horse: 25, wheelchair: 25, bicycle: 25, moped: 25, motorbike: 75, motorcar: 75, goods: 75, hgv: 75, psv: 75},
- bridge: {foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50},
- tunnel: {foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50}
+ paved: { foot: 50, horse: 20, wheelchair: 90, bicycle: 50, moped: 100, motorbike: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 },
+ multilane: { foot: 25, horse: 25, wheelchair: 25, bicycle: 25, moped: 35, motorbike: 60, motorcar: 60, goods: 60, hgv: 60, psv: 60 },
+ bridge: { foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 },
+ tunnel: { foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorbike: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 },
+ footroute: { foot: 55, horse: 50, wheelchair: 55, bicycle: 50, moped: 50, motorbike: 50, motorcar: 45, goods: 45, hgv: 45, psv: 45 },
+ bicycleroute: { foot: 55, horse: 50, wheelchair: 55, bicycle: 60, moped: 50, motorbike: 50, motorcar: 45, goods: 45, hgv: 45, psv: 45 }
},
// Restrictions
profile_restrictions: {
- oneway: {foot: 0, horse: 1, wheelchair: 0, bicycle: 1, moped: 1, motorbike: 1, motorcar: 1, goods: 1, hgv: 1, psv: 1},
- weight: {foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 5.0, hgv: 10.0, psv: 15.0},
- height: {foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 2.5, hgv: 3.0, psv: 3.0},
- width: {foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 2.0, hgv: 2.5, psv: 2.5},
- length: {foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 5.0, hgv: 6.0, psv: 6.0}
+ oneway: { foot: 0, horse: 1, wheelchair: 0, bicycle: 1, moped: 1, motorbike: 1, motorcar: 1, goods: 1, hgv: 1, psv: 1 },
+ weight: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 5.0, hgv: 10.0, psv: 15.0 },
+ height: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 2.5, hgv: 3.0, psv: 3.0 },
+ width: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 2.0, hgv: 2.5, psv: 2.5 },
+ length: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorbike: 0.0, motorcar: 0.0, goods: 5.0, hgv: 6.0, psv: 6.0 }
}
}; // end of routino variable
$data_prefix="";
-$routino={ # contains all default Routino options (generated using "--help-profile-pl").
+################################################################################
+########################### Routino default profile ############################
+################################################################################
+
+$routino={ # contains all default Routino options (generated using "--help-profile-perl").
# Default transport type
transport => 'motorcar',
# Transport types
- transports => {foot => 1, horse => 2, wheelchair => 3, bicycle => 4, moped => 5, motorbike => 6, motorcar => 7, goods => 8, hgv => 9, psv => 10},
+ transports => { foot => 1, horse => 2, wheelchair => 3, bicycle => 4, moped => 5, motorbike => 6, motorcar => 7, goods => 8, hgv => 9, psv => 10 },
# Highway types
- highways => {motorway => 1, trunk => 2, primary => 3, secondary => 4, tertiary => 5, unclassified => 6, residential => 7, service => 8, track => 9, cycleway => 10, path => 11, steps => 12},
+ highways => { motorway => 1, trunk => 2, primary => 3, secondary => 4, tertiary => 5, unclassified => 6, residential => 7, service => 8, track => 9, cycleway => 10, path => 11, steps => 12, ferry => 13 },
# Property types
- properties => {paved => 1, multilane => 2, bridge => 3, tunnel => 4},
+ properties => { paved => 1, multilane => 2, bridge => 3, tunnel => 4, footroute => 5, bicycleroute => 6 },
# Restriction types
- restrictions => {oneway => 1, weight => 2, height => 3, width => 4, length => 5},
+ restrictions => { oneway => 1, weight => 2, height => 3, width => 4, length => 5 },
# Allowed highways
profile_highway => {
- motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100},
- trunk => { foot => 40, horse => 25, wheelchair => 40, bicycle => 30, moped => 90, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100},
- primary => { foot => 50, horse => 50, wheelchair => 50, bicycle => 70, moped => 100, motorbike => 90, motorcar => 90, goods => 90, hgv => 90, psv => 90},
- secondary => { foot => 60, horse => 50, wheelchair => 60, bicycle => 80, moped => 90, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80},
- tertiary => { foot => 70, horse => 75, wheelchair => 70, bicycle => 90, moped => 80, motorbike => 70, motorcar => 70, goods => 70, hgv => 70, psv => 70},
- unclassified => { foot => 80, horse => 75, wheelchair => 80, bicycle => 90, moped => 70, motorbike => 60, motorcar => 60, goods => 60, hgv => 60, psv => 60},
- residential => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 60, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50},
- service => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 80, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80},
- track => { foot => 95, horse => 100, wheelchair => 95, bicycle => 90, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0},
- cycleway => { foot => 95, horse => 90, wheelchair => 95, bicycle => 100, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0},
- path => { foot => 100, horse => 100, wheelchair => 100, bicycle => 90, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0},
- steps => { foot => 80, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0}
+ motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 },
+ trunk => { foot => 40, horse => 25, wheelchair => 40, bicycle => 30, moped => 90, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 },
+ primary => { foot => 50, horse => 50, wheelchair => 50, bicycle => 70, moped => 100, motorbike => 90, motorcar => 90, goods => 90, hgv => 90, psv => 90 },
+ secondary => { foot => 60, horse => 50, wheelchair => 60, bicycle => 80, moped => 90, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 },
+ tertiary => { foot => 70, horse => 75, wheelchair => 70, bicycle => 90, moped => 80, motorbike => 70, motorcar => 70, goods => 70, hgv => 70, psv => 70 },
+ unclassified => { foot => 80, horse => 75, wheelchair => 80, bicycle => 90, moped => 70, motorbike => 60, motorcar => 60, goods => 60, hgv => 60, psv => 60 },
+ residential => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 60, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 },
+ service => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 80, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 },
+ track => { foot => 95, horse => 100, wheelchair => 95, bicycle => 90, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ cycleway => { foot => 95, horse => 90, wheelchair => 95, bicycle => 100, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ path => { foot => 100, horse => 100, wheelchair => 100, bicycle => 90, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ steps => { foot => 80, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ ferry => { foot => 20, horse => 20, wheelchair => 20, bicycle => 20, moped => 20, motorbike => 20, motorcar => 20, goods => 20, hgv => 20, psv => 20 }
},
# Speed limits
profile_speed => {
- motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 48, motorbike => 112, motorcar => 112, goods => 96, hgv => 89, psv => 89},
- trunk => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80},
- primary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80},
- secondary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 88, motorcar => 88, goods => 88, hgv => 80, psv => 80},
- tertiary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80},
- unclassified => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 64, motorcar => 64, goods => 64, hgv => 64, psv => 64},
- residential => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 48, motorcar => 48, goods => 48, hgv => 48, psv => 48},
- service => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 32, motorbike => 32, motorcar => 32, goods => 32, hgv => 32, psv => 32},
- track => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 16, motorbike => 16, motorcar => 16, goods => 16, hgv => 16, psv => 16},
- cycleway => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0},
- path => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0},
- steps => { foot => 4, horse => 0, wheelchair => 4, bicycle => 0, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0}
+ motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 48, motorbike => 112, motorcar => 112, goods => 96, hgv => 89, psv => 89 },
+ trunk => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80 },
+ primary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80 },
+ secondary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 88, motorcar => 88, goods => 88, hgv => 80, psv => 80 },
+ tertiary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 },
+ unclassified => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 64, motorcar => 64, goods => 64, hgv => 64, psv => 64 },
+ residential => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorbike => 48, motorcar => 48, goods => 48, hgv => 48, psv => 48 },
+ service => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 32, motorbike => 32, motorcar => 32, goods => 32, hgv => 32, psv => 32 },
+ track => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 16, motorbike => 16, motorcar => 16, goods => 16, hgv => 16, psv => 16 },
+ cycleway => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ path => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ steps => { foot => 4, horse => 0, wheelchair => 4, bicycle => 0, moped => 0, motorbike => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 },
+ ferry => { foot => 10, horse => 10, wheelchair => 10, bicycle => 10, moped => 10, motorbike => 10, motorcar => 10, goods => 10, hgv => 10, psv => 10 }
},
# Highway properties
profile_property => {
- paved => { foot => 50, horse => 20, wheelchair => 90, bicycle => 50, moped => 100, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100},
- multilane => { foot => 25, horse => 25, wheelchair => 25, bicycle => 25, moped => 25, motorbike => 75, motorcar => 75, goods => 75, hgv => 75, psv => 75},
- bridge => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50},
- tunnel => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50}
+ paved => { foot => 50, horse => 20, wheelchair => 90, bicycle => 50, moped => 100, motorbike => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 },
+ multilane => { foot => 25, horse => 25, wheelchair => 25, bicycle => 25, moped => 35, motorbike => 60, motorcar => 60, goods => 60, hgv => 60, psv => 60 },
+ bridge => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 },
+ tunnel => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorbike => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 },
+ footroute => { foot => 55, horse => 50, wheelchair => 55, bicycle => 50, moped => 50, motorbike => 50, motorcar => 45, goods => 45, hgv => 45, psv => 45 },
+ bicycleroute => { foot => 55, horse => 50, wheelchair => 55, bicycle => 60, moped => 50, motorbike => 50, motorcar => 45, goods => 45, hgv => 45, psv => 45 }
},
# Restrictions
profile_restrictions => {
- oneway => { foot => 0, horse => 1, wheelchair => 0, bicycle => 1, moped => 1, motorbike => 1, motorcar => 1, goods => 1, hgv => 1, psv => 1},
- weight => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 5.0, hgv => 10.0, psv => 15.0},
- height => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 2.5, hgv => 3.0, psv => 3.0},
- width => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 2.0, hgv => 2.5, psv => 2.5},
- length => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 5.0, hgv => 6.0, psv => 6.0}
- },
+ oneway => { foot => 0, horse => 1, wheelchair => 0, bicycle => 1, moped => 1, motorbike => 1, motorcar => 1, goods => 1, hgv => 1, psv => 1 },
+ weight => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 5.0, hgv => 10.0, psv => 15.0 },
+ height => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 2.5, hgv => 3.0, psv => 3.0 },
+ width => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 2.0, hgv => 2.5, psv => 2.5 },
+ length => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorbike => 0.0, motorcar => 0.0, goods => 5.0, hgv => 6.0, psv => 6.0 }
+ }
}; # end of routino variable
$params.=" --prefix=$data_prefix" if($data_prefix);
$params.=" --quiet";
- $message=`$bin_dir/router $params 2>&1`;
+ $message=`$bin_dir/$router_exe $params 2>&1`;
(undef,undef,$cuser,$csystem) = times;
$time=sprintf "time: %.3f CPU / %.3f elapsed",$cuser+$csystem,tv_interval($t0);
#
# Part of the Routino routing software.
#
-# This file Copyright 2008,2009 Andrew M. Bishop
+# This file Copyright 2008-2010 Andrew M. Bishop
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
$params.=" --prefix=$data_prefix" if($data_prefix);
$params.=" --statistics";
-system "$bin_dir/filedumper $params 2>&1";
+system "$bin_dir/$filedumper_exe $params 2>&1";
#
# Part of the Routino routing software.
#
-# This file Copyright 2008,2009 Andrew M. Bishop
+# This file Copyright 2008-2010 Andrew M. Bishop
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
$params.=" --visualiser --data=$data";
$params.=" --latmin=$latmin --latmax=$latmax --lonmin=$lonmin --lonmax=$lonmax";
-system "$bin_dir/filedumper $params 2>&1";
+system "$bin_dir/$filedumper_exe $params 2>&1";
-# $Header: /home/amb/routino/xml/RCS/Makefile,v 1.6 2010/07/07 17:25:51 amb Exp $
+# $Header: /home/amb/routino/xml/RCS/Makefile,v 1.8 2010/09/05 18:27:17 amb Exp $
#
# XML directory Makefile
#
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+# Web file paths
+
WEBDIR=../web/data
+# Files to install
+
FILES=profiles.xml \
translations.xml \
tagging.xml
########
+install: all
+ -[ -d $(DESTDIR)$(datadir) ] || mkdir -p $(DESTDIR)$(datadir)
+ @[ -d $(DESTDIR)$(datadir) ] && \
+ for file in $(FILES); do \
+ echo cp routino-$$file $(DESTDIR)$(datadir)/$$file ;\
+ cp -f routino-$$file $(DESTDIR)$(datadir)/$$file ;\
+ done
+
+########
+
clean:
rm -f *~
distclean: clean
rm -f $(WEBDIR)/*.xml
+
+########
+
+top=-top
+include ../Makefile
<?xml version="1.0" encoding="UTF-8" ?>
<!-- ============================================================
- $Header: /home/amb/routino/xml/RCS/routino-profiles.xml,v 1.2 2010/06/26 19:26:47 amb Exp $
+ $Header: /home/amb/routino/xml/RCS/routino-profiles.xml,v 1.5 2010/10/09 18:20:45 amb Exp $
An XML format file containing Routino routing profiles
<speed highway="cycleway" kph="4" />
<speed highway="path" kph="4" />
<speed highway="steps" kph="4" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="0" />
<preference highway="cycleway" percent="95" />
<preference highway="path" percent="100" />
<preference highway="steps" percent="80" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="50" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="50" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="55" />
+ <property type="bicycleroute" percent="55" />
</properties>
<restrictions>
<oneway obey="0" />
<speed highway="cycleway" kph="8" />
<speed highway="path" kph="8" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="0" />
<preference highway="cycleway" percent="90" />
<preference highway="path" percent="100" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="20" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="20" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="50" />
+ <property type="bicycleroute" percent="50" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="4" />
<speed highway="path" kph="4" />
<speed highway="steps" kph="4" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="0" />
<preference highway="cycleway" percent="95" />
<preference highway="path" percent="100" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="90" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="90" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="55" />
+ <property type="bicycleroute" percent="55" />
</properties>
<restrictions>
<oneway obey="0" />
<speed highway="cycleway" kph="20" />
<speed highway="path" kph="20" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="0" />
<preference highway="cycleway" percent="100" />
<preference highway="path" percent="90" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="50" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="50" />
+ <property type="multilane" percent="25" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="50" />
+ <property type="bicycleroute" percent="60" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="0" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="25" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="35" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="50" />
+ <property type="bicycleroute" percent="50" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="100" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="75" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="60" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="50" />
+ <property type="bicycleroute" percent="50" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="100" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="75" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="60" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="45" />
+ <property type="bicycleroute" percent="45" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="100" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="75" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="60" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="45" />
+ <property type="bicycleroute" percent="45" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="100" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="75" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="60" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="45" />
+ <property type="bicycleroute" percent="45" />
</properties>
<restrictions>
<oneway obey="1" />
<speed highway="cycleway" kph="0" />
<speed highway="path" kph="0" />
<speed highway="steps" kph="0" />
+ <speed highway="ferry" kph="10" />
</speeds>
<preferences>
<preference highway="motorway" percent="100" />
<preference highway="cycleway" percent="0" />
<preference highway="path" percent="0" />
<preference highway="steps" percent="0" />
+ <preference highway="ferry" percent="20" />
</preferences>
<properties>
- <property type="paved" percent="100" />
- <property type="multilane" percent="75" />
- <property type="bridge" percent="50" />
- <property type="tunnel" percent="50" />
+ <property type="paved" percent="100" />
+ <property type="multilane" percent="60" />
+ <property type="bridge" percent="50" />
+ <property type="tunnel" percent="50" />
+ <property type="footroute" percent="45" />
+ <property type="bicycleroute" percent="45" />
</properties>
<restrictions>
<oneway obey="1" />
<?xml version="1.0" encoding="UTF-8" ?>
<!-- ============================================================
- $Header: /home/amb/routino/xml/RCS/routino-tagging-nomodify.xml,v 1.2 2010/06/26 19:26:47 amb Exp $
+ $Header: /home/amb/routino/xml/RCS/routino-tagging-nomodify.xml,v 1.5 2010/09/17 17:40:55 amb Exp $
An XML format file containing Routino tagging rules - copy the input file
directly to the output with no modifications (e.g. importing a file dumped
<routino-tagging xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-tagging.xsd">
- <!-- Node rules are not currently used -->
+ <!-- -------------------- Node rules -------------------- -->
<node>
+
+ <!-- Copy everything from input to output -->
+
+ <if>
+ <output />
+ </if>
+
</node>
- <!-- Way rules (copy everything from input to output) -->
+ <!-- -------------------- Way rules -------------------- -->
<way>
+ <!-- Copy everything from input to output -->
+
<if>
<output />
</if>
</way>
- <!-- Relation rules are not currently used -->
+ <!-- -------------------- Relation rules -------------------- -->
<relation>
+
+ <!-- Copy everything from input to output -->
+
+ <if>
+ <output />
+ </if>
+
</relation>
</routino-tagging>
<?xml version="1.0" encoding="UTF-8" ?>
<!-- ============================================================
- $Header: /home/amb/routino/xml/RCS/routino-tagging.xml,v 1.2 2010/06/26 19:26:47 amb Exp $
+ $Header: /home/amb/routino/xml/RCS/routino-tagging.xml,v 1.5 2010/09/17 17:44:25 amb Exp $
An XML format file containing Routino tagging rules
<routino-tagging xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-tagging.xsd">
- <!-- Node rules are not currently used -->
+ <!-- -------------------- Node rules -------------------- -->
<node>
+
+ <!-- Note: The default is that all transport types are allowed past a barrier;
+ access must be specified to disallow each transport type. -->
+
+ <!-- Barriers -->
+
+ <if k="barrier" v="bollard">
+ <output k="motorcar" v="no"/>
+ <output k="goods" v="no"/>
+ <output k="hgv" v="no"/>
+ <output k="psv" v="no"/>
+ </if>
+
+ <if k="barrier" v="kissing_gate">
+ <output k="horse" v="no"/>
+ <output k="wheelchair" v="no"/>
+ <output k="bicycle" v="no"/>
+ <output k="moped" v="no"/>
+ <output k="motorbike" v="no"/>
+ <output k="motorcar" v="no"/>
+ <output k="goods" v="no"/>
+ <output k="hgv" v="no"/>
+ <output k="psv" v="no"/>
+ </if>
+
+ <if k="barrier" v="stile">
+ <output k="horse" v="no"/>
+ <output k="wheelchair" v="no"/>
+ <output k="bicycle" v="no"/>
+ <output k="moped" v="no"/>
+ <output k="motorbike" v="no"/>
+ <output k="motorcar" v="no"/>
+ <output k="goods" v="no"/>
+ <output k="hgv" v="no"/>
+ <output k="psv" v="no"/>
+ </if>
+
+ <if k="barrier" v="turnstile">
+ <output k="horse" v="no"/>
+ <output k="wheelchair" v="no"/>
+ <output k="bicycle" v="no"/>
+ <output k="moped" v="no"/>
+ <output k="motorbike" v="no"/>
+ <output k="motorcar" v="no"/>
+ <output k="goods" v="no"/>
+ <output k="hgv" v="no"/>
+ <output k="psv" v="no"/>
+ </if>
+
+ <!-- Normalisation of access tags -->
+
+ <if v="designated" ><set v="yes"/></if>
+ <if v="permissive" ><set v="yes"/></if>
+ <if v="destination"><set v="yes"/></if>
+ <if v="true" ><set v="yes"/></if>
+
+ <if v="private" ><set v="no"/></if>
+
+ <!-- Generic access permissions for all transport types (to override defaults) -->
+
+ <if k="access">
+ <set k="noaccess" v="yes"/>
+ </if>
+
+ <if k="access" v="yes">
+ <set k="noaccess" v="no"/>
+ </if>
+
+ <if k="noaccess" v="yes">
+ <output k="foot" v="no"/>
+ <output k="horse" v="no"/>
+ <output k="wheelchair" v="no"/>
+ <output k="bicycle" v="no"/>
+ <output k="moped" v="no"/>
+ <output k="motorbike" v="no"/>
+ <output k="motorcar" v="no"/>
+ <output k="goods" v="no"/>
+ <output k="hgv" v="no"/>
+ <output k="psv" v="no"/>
+ </if>
+
+ <!-- Generic access permissions for classes of transport types -->
+
+ <if k="motor_vehicle">
+ <output k="moped"/>
+ <output k="motorbike"/>
+ <output k="motorcar"/>
+ <output k="goods"/>
+ <output k="hgv"/>
+ <output k="psv"/>
+ </if>
+
+ <if k="vehicle">
+ <output k="bicycle"/>
+ <output k="moped"/>
+ <output k="motorbike"/>
+ <output k="motorcar"/>
+ <output k="goods"/>
+ <output k="hgv"/>
+ <output k="psv"/>
+ </if>
+
+ <!-- Specific access rules (to override the generic ones) -->
+
+ <if k="foot" ><output/></if>
+ <if k="horse" ><output/></if>
+ <if k="wheelchair"><output/></if>
+ <if k="bicycle" ><output/></if>
+ <if k="moped" ><output/></if>
+ <if k="motorbike" ><output/></if>
+ <if k="motorcar" ><output/></if>
+ <if k="goods" ><output/></if>
+ <if k="hgv" ><output/></if>
+ <if k="psv" ><output/></if>
+
</node>
- <!-- Way rules -->
+ <!-- -------------------- Way rules -------------------- -->
<way>
+ <!-- Note: The default is that no transport type is allowed on any highway;
+ access must be specified to allow each transport type. -->
+
<!-- Highway types (includes default access and default properties) -->
<if k="highway" v="motorway_link">
<output k="oneway" v="yes"/>
</if>
+ <if k="route" v="ferry">
+ <set k="highway" v="ferry"/>
+ </if>
+
<!-- Normalisation of access tags -->
<if v="designated" ><set v="yes"/></if>
<if v="permissive" ><set v="yes"/></if>
<if v="destination"><set v="yes"/></if>
+ <if v="true" ><set v="yes"/></if>
- <if v="private"><set v="no"/></if>
+ <if v="private" ><set v="no"/></if>
<!-- Generic access permissions for all transport types (to override defaults) -->
<set k="noaccess" v="yes"/>
</if>
- <if k="access" v="true">
- <set k="noaccess" v="no"/>
- </if>
-
<if k="access" v="yes">
<set k="noaccess" v="no"/>
</if>
<if k="bridge" ><output/></if>
<if k="tunnel" ><output/></if>
+ <!-- The "footroute" and "bicycleroute" properties can be set here,
+ but normally they are set by the relation rules. -->
+
<!-- Output the restriction tags -->
<if k="oneway"><output/></if>
<!-- Relation rules are not currently used -->
<relation>
+
+ <!-- Copy route relations -->
+
+ <if k="route" v="foot">
+ <output k="footroute" v="yes"/>
+ </if>
+
+ <if k="route" v="walking">
+ <output k="footroute" v="yes"/>
+ </if>
+
+ <if k="route" v="hiking">
+ <output k="footroute" v="yes"/>
+ </if>
+
+ <if k="route" v="foot;bicycle">
+ <output k="footroute" v="yes"/>
+ <output k="bicycleroute" v="yes"/>
+ </if>
+
+ <if k="route" v="bicycle;foot">
+ <output k="footroute" v="yes"/>
+ <output k="bicycleroute" v="yes"/>
+ </if>
+
+ <if k="route" v="bicycle">
+ <output k="bicycleroute" v="yes"/>
+ </if>
+
</relation>
</routino-tagging>
<?xml version="1.0" encoding="utf-8"?>
<!-- ============================================================
- $Header: /home/amb/routino/xml/RCS/routino-tagging.xsd,v 1.1 2010/05/18 18:35:01 amb Exp $
+ $Header: /home/amb/routino/xml/RCS/routino-tagging.xsd,v 1.3 2010/09/17 17:40:55 amb Exp $
An XML Schema Definition for the Routino tagging rules XML format
<!-- The second level node, way and relation tagging rules -->
<xsd:complexType name="NodeType">
+ <xsd:sequence>
+ <xsd:element name="if" type="IfType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="WayType">
</xsd:complexType>
<xsd:complexType name="RelationType">
+ <xsd:sequence>
+ <xsd:element name="if" type="IfType" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
</xsd:complexType>
<!-- The if tag and its contents -->
<?xml version="1.0" encoding="utf-8"?>
<!-- ============================================================
- $Header: /home/amb/routino/xml/RCS/routino-translations.xml,v 1.5 2010/07/03 11:27:37 amb Exp $
+ $Header: /home/amb/routino/xml/RCS/routino-translations.xml,v 1.10 2010/09/15 18:30:37 amb Exp $
An XML format file containing Routino output translations.
<routino-translations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-translations.xsd">
+ <!-- Original English language version by Andrew M. Bishop -->
+
<language lang="en">
<!-- Copyright of the data being routed, not of this file -->
<highway type="cycleway" string="cycleway" />
<highway type="path" string="path" />
<highway type="steps" string="steps" />
+ <highway type="ferry" string="ferry" />
<!-- The type of route -->
<route type="shortest" string="Shortest" /> <!-- For the description and route name -->
</language>
+ <!-- German translation by Christoph Eckert (July 2010) -->
+
<language lang="de">
<!-- Copyright of the data being routed, not of this file -->
<highway type="cycleway" string="Radweg" />
<highway type="path" string="Weg" />
<highway type="steps" string="Treppe" />
+ <highway type="ferry" string="ferry" /> <!-- FIXME - needs translation -->
<!-- The type of route -->
<route type="shortest" string="Kürzeste" /> <!-- For the description and route name -->
<!-- HTML output -->
<output-html>
- <waypoint type="waypoint" string="Wegpunkt" /> <!-- For the chosen waypoints -->
+ <waypoint type="waypoint" string="Wegpunkt" /> <!-- For the chosen waypoints -->
<waypoint type="junction" string="Anschlussstelle" /> <!-- For the interesting junctions -->
<title text="%s Route" /> <!-- %s = [shortest|quickest] -->
<waypoint type="trip" string="TRIP" /> <!-- For the other route points -->
<waypoint type="finish" string="FINISH"/> <!-- For the last route waypoint -->
- <desc text="%s Strecke zwischen 'Start' und 'Ziel'" /> <!-- %s = [shortest|quickest] -->
- <name text="%s Strecke" /> <!-- %s = [shortest|quickest] -->
- <step text="%s auf '%s' für %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name -->
+ <desc text="%s Strecke zwischen 'Start' und 'Ziel'" /> <!-- %s = [shortest|quickest] -->
+ <name text="%s Strecke" /> <!-- %s = [shortest|quickest] -->
+ <step text="%s auf '%s' für %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name -->
<final text="Gesamtstrecke %.1f km, %.0f minuten" />
</output-gpx>
</language>
+ <!-- Dutch translation by Jan Jansen (August 2010) -->
+
+ <language lang="nl">
+
+ <!-- Copyright of the data being routed, not of this file -->
+ <copyright>
+ <creator string="Creator" text="Routino - http://www.routino.org/" />
+ <source string="Source" text="Basierend auf OpenStreetMap-Daten, erhältlich via http://www.openstreetmap.org/" />
+ <license string="License" text="http://creativecommons.org/licenses/by-sa/2.0/" />
+ </copyright>
+
+ <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right -->
+ <turn direction="-4" string="Haarspeld naar links" />
+ <turn direction="-3" string="Scherp links" />
+ <turn direction="-2" string="Links" />
+ <turn direction="-1" string="Half links" />
+ <turn direction="0" string="Rechtdoor" />
+ <turn direction="1" string="Half rechts" />
+ <turn direction="2" string="Rechts" />
+ <turn direction="3" string="Scherp rechts" />
+ <turn direction="4" string="Haarspeld naar rechts" />
+
+ <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East -->
+ <heading direction="-4" string="Zuid" />
+ <heading direction="-3" string="Zuid-West" />
+ <heading direction="-2" string="West" />
+ <heading direction="-1" string="Noord-West" />
+ <heading direction="0" string="Noord" />
+ <heading direction="1" string="Noord-Oost" />
+ <heading direction="2" string="Oost" />
+ <heading direction="3" string="Zuid-Oost" />
+ <heading direction="4" string="Zuid" />
+
+ <!-- Highway names -->
+ <highway type="motorway" string="Autostrade" />
+ <highway type="trunk" string="Autoweg" />
+ <highway type="primary" string="Provinciale weg" />
+ <highway type="secondary" string="Nationale weg" />
+ <highway type="tertiary" string="Doorgangsweg" />
+ <highway type="unclassified" string="Niet geclassificeerd" />
+ <highway type="residential" string="Woongebiet" />
+ <highway type="service" string="Toegangsweg" />
+ <highway type="track" string="Veldweg" />
+ <highway type="cycleway" string="Fietspad" />
+ <highway type="path" string="Pad" />
+ <highway type="steps" string="Trap" />
+ <highway type="ferry" string="ferry" /> <!-- FIXME - needs translation -->
+
+ <!-- The type of route -->
+ <route type="shortest" string="Kortste" /> <!-- For the description and route name -->
+ <route type="quickest" string="Snelste" /> <!-- For the description and route name -->
+
+ <!-- HTML output -->
+ <output-html>
+ <waypoint type="waypoint" string="Punt" /> <!-- For the chosen waypoints -->
+ <waypoint type="junction" string="de splitsing" /> <!-- For the interesting junctions -->
+
+ <title text="%s Route" /> <!-- %s = [shortest|quickest] -->
+
+ <start string="Start" text="Bij %s neemt u de richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] -->
+ <node string="Bij" text="Bij %s gaat u %s richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] -->
+ <segment string="Volg" text="Volgt u de %s voor %.3f km %.1f min" /> <!-- 1st %s = street name -->
+ <stop string="Stop" text="U bent bij %s aangekomen" /> <!-- 1st %s = [waypoint|junction] -->
+ <total string="Totaal" text="%.1f km, %.0f minuten" />
+ </output-html>
+
+ <!-- GPX output -->
+ <output-gpx>
+ <waypoint type="start" string="START" /> <!-- For the first route waypoint -->
+ <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints -->
+ <waypoint type="trip" string="TRIP" /> <!-- For the other route points -->
+ <waypoint type="finish" string="FINISH"/> <!-- For the last route waypoint -->
+
+ <desc text="%s Route tussen 'Start' und 'Finish'" /> <!-- %s = [shortest|quickest] -->
+ <name text="%s Route " /> <!-- %s = [shortest|quickest] -->
+ <step text="%s op '%s' voor %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name -->
+ <final text="Totaal trip %.1f km, %.0f minuten" />
+ </output-gpx>
+
+ </language>
+
</routino-translations>