Smrender - A rule-based Renderer for OSM Data
Bernhard R. Fischer
Contents
1 Release Notes
2 Name
3 Synopsis
4 Description
4.1 Rendering Window
4.2 Options
5 Ruleset Definition
5.1 Match Operations
5.2 Rule Actions
5.2.1 Captions
5.2.2 Drawing and Filling
5.2.3 Calling External Functions
5.2.4 Placing Images
5.2.5 Output of OSM Data
5.2.6 Adding Tags to Objects
5.2.7 Standard Shapes
5.2.8 Create Formatted Strings
5.2.9 Concatenating Split Ways
5.2.10 Executing Programs and Scripts
5.2.11 Special Purpose Actions
6 Signals
7 Extensions
7.1 Libsmfilter and Smfilter
7.1.1 Generating Light Sectors with vsector()
7.1.2 Compatibility to Smfilter
7.1.3 Generating Light Description Strings
7.1.4 Generating Circles around Depth Soundings
8 Examples
8.1 Generating a PDF
8.2 Generating a KAP File
9 Files
10 Bugs and Caveats
11 Author
12 Copyright
A Compiling and Installing
B Writing Own Rendering Functions
C FAQ
C.1 Why is Smrender not written in C++?
C.2 Is it possible to create other maps, such as road maps?
D Todo
Figure
0 Release Notes
This document describes the current (2013/06/03) version of Smrender which
is tagged as version 3.0 and corresponds to the internal SVN revision number
1535. Starting with version 3.0 Smrender supports
libcairo1 instead of
libgd as its graphical library.
There are some major changes after SVN revision 1240, thus this document
does not apply to revisions 1240 and earlier. The format of the ruleset changed
and are not compatible.
Unfortunately, this documentation is not complete yet, but I will continue to
work on it.
Smrender
contains several functions which are experimental. Those functions
are namely the auto-rotation and the polygon-size dependent captions (see
Section 5.2.1).
0 Name
Smrender is a universal rule-based rendering engine for OSM data. Because
smrender is a very generic and flexible OSM processing engine, it may be used
for different tasks such as data filtering or data modification.
0 Synopsis
smrender [OPTIONS] [window]
0 Description
Smrender reads an OSM file and applies a set of rules to this input data to
create an output image. The input is an OSM file and a second file containing
the rule set. The output (currently) is a PNG image having the desired
resolution and density and probably additional output files. The latter is
explained later.
The primary goal of Smrender is to create a sea chart which is well-suited for
print-out on paper. Nevertheless, it is a universal rendering engine and may be
used for different tasks.
The input file should be an OSM/XML file as defined by the OSM standard. The
file is required to be well-formed in that sense because Smrender itself does
no XML validation, thus the rendering process might fail if the file is not
well-formed. The data should also be complete. This means that it should
contain all nodes to which is referred by the ways. Smrender will remove nodes
from ways which are missing.
The rules are also defined in OSM format (see Section 5). The
rules are applied iteratively in a loop depending on their version.
Within the loop, Smrender always applies first all relation rules, then way rules, and then all node
rules of the same version. All rules of the same version are applied in the
order of their id.
Invisible objects are ignored by the renderer. Invisible objects are such which
have set the attribute visible="false". If objects have no such
attribute Smrender sets it to "true" by default.
0.0 Rendering Window
Smrender renders an area which is specified by the window. It is a compound
argument as defined below.
<window> := <center> | <bbox>
<bbox> := <left lower>:<right upper>
<left lower> := <coords>
<right upper> := <coords>
<center> := <coords> ':' <size>
<coords> := <dec_coords> | <naut_coords>
<dec_coords> := <lat> ':' <lon>
<naut_coords> := ( <naut_lat> ':' <naut_lon ) |
( <naut_lon> ':' <naut_lat> )
<size> := <scale> | <length> 'd' | <length> 'm'
The choice to select to area to be rendered is either to specify the center point of the
are or to specify a bounding box.
If it is chosen to use a center point specification then
lat and lon set the center coordinates in latitude and longitude
in degrees in WGS84 reference system. Although it can be any valid
coordinate, it is suggested to choose an "even" value rounded to 10 minutes
(e.g. 43.666667 which is 43° 40').
Alternatively, the coordinates can be given in nautical notation which is
dd C mm.m where dd is degrees as integer value, C is one of
'N', 'S', 'E', or 'W', and mm.m are minutes, for example
43N40. In case of nautical notation, Smrender automatically detects
which of the the values is the latitude and which is the longitude dependent on
the character used for the cardinal direction.
Length
defines the length of the mean latitude (parallel) in degrees if
'd' is appended or in nautical miles if 'm' is appended.
Alternatively, the scale of the chart can be specified. Smrender
calculates the size of the area to meet the scale. Obviously, this depends on the size
of the output image. The height (the length of the mean longitude) is
calculated automatically by Smrender in such a way that the output image is
projected correctly using a spherical transversal Mercartor projection. The height depends on the size
of the output image (page format).
If it is chosen to use a bounding box specification then the coordinates of the
left lower (southern western) and the right upper (northern eastern) point
shall be specified. Because of the projection the bounding box must not
necessarily fit to the page dimension in which case Smrender will
automatically resize the bounding box to fit to the page. If a fixed bounding
box is desired the option -P is needed with either the width or the
height set to zero. In this case Smrender will calculate a page dimension
which fits to the bounding box according to the projection.
If this argument is omitted The value 0:0:100000 is chosen as default and the
option -a is set implicitly.
0.0 Options
-a
Smrender
usually processes just those nodes which are located within
the window of rendering (see 4.1). This behavior is new with
version 3.0. With this option set Smrender processes all nodes
independently of their location.
-b color
This option allows to set a background color. The color may be define either as a color preset
or an HTML-style definition (see 5.2.1). The default color is white.
Please note that some Shells (such as the bash) interpret the
# character if the color is specified in HTML-style. In this
case you have to put the color specification under single or double quotes, e.g. -b '#8080ff'.
-D
Smrender
outputs a lot of information to stderr to watch the progress of
rendering. It uses the same log levels as defined for syslog (see
syslog(3)). By default it logs all messages of the log level
LOG_INFO and above. With this option also debug messages are
printed. This may be useful if something goes wrong.
-d density
Set the density of the output image. The default value is 300 which
is typically used for print-outs in good
quality.
-f
Filter data while loading the input file.
With this option a bounding box is used to load just those nodes and ways
which are within the selection. The bounding box is 10% larger then the
area which resumes from the selected window.
This option is useful if huge input data sets are used, such as the planet
file.
Please note that this option works only correctly if the nodes and ways are
stored in that order in the input file (first all nodes and then all
ways).
-g d[:t[:s]]
This option defines the distance d of the grid lines in minutes. The
border of the chart (latitude and longitude axis) also depends on this
setting. As it is usual for sea charts, there is a major and a minor axis
scale, called ticks and subticks. The ticks are defined by t and the subticks
are defined by s in minutes. For a correct result, t as well
as d should be integral multiples of s.
Note that Smrender internally uses a precision of hundreds of a minute while doing
the grid calculation. Thus, the smallest granularity for the grid paramters is 0.01 minutes.
If this option is omitted, Smrender will choose a grid setting dependent
on the scale of the output image. For scales below 1:150000 it chooses
5:1:0.2, for scales below 1:250000 it chooses 10:1:0.25, and for scales
above 1:250000 it is set to 20:2:0.5.
A grid may optionally be generated with the action grid. See
Section 5.2.11.
-G
Do not generate grid nodes/ways. Smrender actually does not render the grid directly onto the output
image but rather generates regular OSM nodes and ways. These objects are then rendered in a way as
it is defined by the regular rule set.
All ways of the grid are tagged with grid=*. Part of the grid are also labels on the border
showing degrees in latitude an longitude. The labels are nodes which are tagged with grid=text
and the tag name=* containing the value.
-h
Output the list of available options and a short description to stdout and
exit.
-i file
This option specifies the name of the input file. If this option is omitted, Smrender reads
from stdin.
-k file
With this option Smrender will write a KAP/BSB file to file
which can be used with most navigation applications and GPS devices. See Section 8.2 for
more details.
-K file
This is similar to option -k but it generates only a KAP/BSB header
instead of a complete file. This is useful if you want to use an external
tool such as imgkap to create the KAP file from the PNG.
-l
Output page has landscape format rather than portrait, which is default. This option is used only in conjunction
with option -P if a literal page format is used.
-o file
Set the filename of the output image. The image will be saved as PNG file.
If this option is omitted no image file will be generated.
-O file
Create output PDF file.
-P fmt geom
Select the page format of the output image. The format can be set either named format fmt which
has a specific dimension or as geometry geom which contains the width and height of the page
in millimeters in the format widthxheight.
Fmt currently supports the values A4 up to A0.
If this option is omitted, A3 format is selected by default.
If the area to be rendered is specified as bounding box (see Section
4.1) this will most probably colide with the dimension of the
page because of the requirements of the projection in which case Smrender
will resize the bounding box appropriately. If either the width or
the height (but never both) is set to zero then Smrender will
calculate the missing dimension according to the bounding box and the
projection.
-m Disable memory mapping (see option -M).
-M
This option is mandatory if the input file is larger than the amount of memory available on the rendering system.
If the system has enough memory this option can be omitted. Using memory mapping probably is a little
bit slower but heavily depends on the operating system. On Linux kernel 2.6.32 there is no significant
difference in speed.
In any case, files which are larger then 2 GBytes are only supported on 64 bit operating systems.
This option is now on by default.
-n Some actions of Smrender generate new objects. Negative ids
are added to those objects. If this data created by Smrender is fed to
another OSM tool negative ids may cause problems. With this option all
negative ids are output as positive values.
-r file
This option specifies the file name of the rules file. If it is omitted, Smrender expects the
rules file to be named rules.osm.
If file is a directory Smrender will scan it and read all files
which match "*osm". The files are read in alphabetical order,
simply compared with strcmp(3). Thus, it is suggested to create
symbolic links to the files in name it in an appropriate way similar to SysV
init scripts.
If you need a more specific order of rule execution you should consider to
use the version and/or id fields of the OSM objects (see
Section 4).
-R file
This option may be used to save the rules again to another OSM file. This fill will be well-formed in terms of OSM/XML
format and may be loaded into JOSM.
-s f
This option is deprecated and is just kept for compatibility. It has no
effect. It may be removed in future releases.
-t title
This option generates a descriptional title node which can be rendered onto the
final chart. It is as well used as a title for KAP files (see option -k).
-T z ':' dir [ ':' ftype ]
Create tiles suitable for an online viewer into the directory dir.
The zoom levels are specified by z which can be either a single value
or a range, e.g. 10-15.
The optional parameter ftype sets the file type of the tile images
which can be either png (which is default) or jpg.
-u
With this option Smrender will output a set of URLs which are suitable for
OSM data download for the area of rendering specified by the window.
-V
With this option set, Smrender parses all arguments, and calculates and
prints the rendering parameters to stderr. Then it exits immediately.
-v
With this option Smrender will output the version information of
Smrender and libcairo to stdout and exit immediately.
-w file
This option specifies the file name of an output OSM file. Smrender will dump all nodes/ways to this file that have been
selected by the import process and all nodes/ways which have been generated during the rendering process.
These nodes/ways include the objects generated for the grid and also the close coastline ways.
Thus the output depends on the options -f, -C, and -G.
If this option is omitted, no output will be generated.
0 Ruleset Definition
The rule set is also defined in OSM format. It contains nodes, ways, and relations together
with tags. Nodes are considered to be rules for rendering nodes and ways are
rules applied to ways. Each object (node, way, or relation) has a list of tags. These
tags represent patterns which are matched against the tags of the objects which
are to be rendered. The values of a tag's key (k="...") and/or value
(v="...") may be either just a string which is directly matched in a
case-sensitive manner or a special match operation (see Section 5.1).
The match operations can be used for the key as well as for the value.
Each object has to have a special tag which defines the action that should
be carried out in case of a match. This tag has the form _action_=*. The actions are described
below in Section 5.2.
The match algorithm always applies all tags to match, and all of them have to match in order
to execute the action. If just a single tag does not match, the node is skipped.
As defined by the OSM
specification2 all
objects (nodes, ways, relations, also called elements) have common
attributes. Smrender uses the attributes version and id
to determine the order of rule execution. All rules of the same version are
rendered in the order of their id ascendingly. This is repeated for each
version ascendingly until the last rule (highest version and highes id).
Rules with a version greater or equal to 216 = 0x10000 = 65536 are ignored.
The number of iterations, i.e. the number of different versions is limited to
MAX_ITER which is defined in rdata.h. Run Smrender with
option -V to see its value.
If the version attribute is missing it is set to 1 by default. All
objects without id are numbered ascendingly in the order in which they
occur in the rules file starting with some low negative value.
The attribute visible can be set to either true (which is
default if omitted) or false. Rules which are "invisible" are not
executed. This can be used to enable or disable a rule by default and can
further be used for conditional rendering (see enable_rule in Section
5.2.11).
0.0 Match Operations
Basically there are the four different match operations string compare,
regular expression match, greater than, and less than.
Additionally, all of them may be inverted, or excluded.
- String compare is the most basic match operation. It does an exact case-sensitive string compare.
The following tag matches all objects
which own the tag seamark:light_character=*.
<tag k='seamark:light_character' v=''/> |
The empty value v='' represents a wildcard match. It matches any string.
-
Regular expressions are invoked by enclosing the expression within two slashes /.../
as it is usual in Perl and several other languages. The expression is interpreted as a POSIX extended regular expression (see manpages
regex(3) and regex(7)). The following expression matches any object
which is tagged with either highway=primary or highway=secondary.
<tag k='highway' v='/^(secondary|primary)$/'/> |
- Smrender can interpret tag values as numerical values. Thus, it can do arithmetical comparisons
which is less than ( < ) and greater than ( > ).
The rule has to contain a number enclosed in square brackets. The direction of the brackets denotes the
comparison operation; [x] means that the value of the tag should be lower than x and ]x[
matches if the tag value is greater than x. The tag value as well as x are always
interpreted as decimal number with double precision.
Square brackets are used deliberately instead of angle brackets to avoid possible conflicts with
the XML format or buggy parsers.
The following rule matches all objects whose seamark:light:range-value is greater than 7.5.
<tag k='seamark:light:range' v=']7.5['/> |
- Match inversion is done by enclosing the match expression within exclamation marks.
This inverts the match if and only if the expression matched. This means that if a tag would match
the expression, the inversion would return "false" (no match). But it would not return
"true" (match) if the expression would not match.
The following expression would match all objects which have a tag with the key seamark:type
but its value is neither landmark nor light_major.
<tag k='seamark:type' v='!/landmark|light_major/!'/> |
- Match exclusion is denoted by enclosing the match expression within tildes. It does not match objects
with certain tags.
The following rule avoid matching of objects which have a tag seamark=*.
<tag k='~seamark~' v=''/> |
0.0 Rule Actions
Smrender
supports a few powerful built-in actions which are carried out upon
successful match. As already mentioned at the beginning of this Section,
actions are defined simply with the tag _action_=*. The actions are
actually function calls either within the code of Smrender or externally from a
dynamic library. Thus, there is an unlimited range of extendability of
smrender. A number of paramters may optionally be passed to the function. The order
of the parameters do not matter.
The following example shows an action which places an image at the position of
a node.
<tag k='_action_' v='img:file=icons/Light_Minor.png'/> |
The basic format of an action is defined as follows.
<action> := <ref> [ ':' <param> [ ';' <param> [ ... ] ] ]
<ref> := <func> [ '@' <library> ]
<param> := <tparam> | <bparam>
<tparam> := [ SEP ] <name> [ SEP ] '=' [ SEP ] <value> [ SEP ]
<bparam> := [ SEP ] <name> [ SEP ] '=' [ SEP ] <bool> [ SEP ]
<bool> := 'yes' | 'no' | 'true' | 'false' | <num>
<num> := any decimal number
SEP := '`' | '"'
Every action contains of a symbol name ref which is used to find the
appropriate function in the code or in a shared object and an optional set of
parameters. These are attribute/value pairs. The names of the attributes are
case-sensitive. A special type exists which is the boolean type. It can
be set to the case-insensitive strings 'yes', 'no', 'true', or 'false', or to
any decimal number. 0 is interpreted as false all other values are considered
to be true.
Smrender
is shipped with a set of basic functions for rendering. Those are
capable to place captions (Section 5.2.1), drawing and filling (Section
5.2.2), placing icons (Section 5.2.4), generating OSM files
(Section 5.2.5), do some special purpose operations (Section
5.2.11), and calling external library functions (Section
5.2.3). The latter is thought to be a simple but powerful interface
for third-party modules.
The following sections describe these actions.
0.0.0 Captions
The action type cap is used to place a caption. If the action is carried out in a node-rule,
the caption is placed at the node's position with the specified properties. The formal definition
looks like the following.
<action> := 'cap:' <param>
<param> := <name> '=' <value>
<name> := 'font' | 'size' | 'key' | 'color' | 'angle' |
'weight' | 'phase' | 'valign' | 'halign' |
'anglekey'
The parameters font, size, and key are mandatory, the others
are optional.
If fontconfig is available, font is defined as specified by
fontconfig (see fontconfig documentation). This is e.g.
"font=serif:bold". If fontconfig is not available,
font must be a full path to a TTF font file.
Size
defines the size of the font in millimeters as a deciaml value, for example
"size=2.4".
Key
specifies the key of the tag whose value should be printed.
If a caption rule is applied to a node which does not have such a key, the rule
simply does nothing. If the key is preceded by an asterisk '*',
all letters are capitalized.
Valign
and halign specify the alignment of the caption in respect to its
center point which is given by the coordinates of the node. There is a
horizontal alignment (halign) which could be either east or
west and a vertical alignment (valign) which is
one of north or south. If no alignment is specified the caption will be centered.
Color
defines the color in which the caption should be set. This is
either an X11 color preset3 such as "white", "yellow", "darkgreen" ...,
or a color definition similar to the HTML standard.
The color presets reflect the colors of traditional sea charts. The HTML-style color definition has the pattern
#[aa]rrggbb. The values rr, gg, and bb reflect the RGB values as a hexadecimal
number from 00 to ff. Optionally a transparency may be specified with aa. It ranges from
00 (opaque) to 7f which is absolute transparent. The most signifficant bit is always cleared, hence,
setting values greater than 7f has no effect.
The angle defines how the caption should be rotated. It is given
as usual in trigonometrics which is degrees counterclockwise from 0 to 360
being 0 the regular left-to-write orientation.4
Alternatively, the angle may be set to
"auto". This causes Smrender to try to find an angle in
such a way that it does not colide (or at least as little as possible)
possible which other objects that
have already been rendered. In case of auto-rotation, the additional parameters weight,
and phase may be set.
Smrender
virtually rotates the caption from 0 to 360 degrees and calculates
the color difference between the foreground (the caption) and the background
for each angle. It then chooses the angle with the greatest color difference
which should be the place where it is best visible. If the angle is between 90
and 270 degrees, Smrender automatically flips the caption that it does not
read upside-down.
The parameters weight and phase may influence the auto-rotation
if specified. The weight is a decimal value between 0 and 1 (1 is
default) which allows to weight the angles of 90 plus phase and 270 plus
phase less than the others (a phase of 0 is default). This allows to
e.g. prefer left-right angles above top-bottom angles. This makes sense because
reading left-right is more easy than reading top-bottom.
For example if "weight=0.7" is defined, northerly and southerly test samples
are taken into account only with 70% which leads to the fact that the
the caption tends to be rather east-west aligned.
The parameter 'anglekey' defines a key which can be used if the
caption shall be rotated based on the value of a tag. The value of the
parameter angle is added additionally. The parameter
angle=auto is ignored if a anglekey is set.
Captions on ways are handled a little bit different from captions
on nodes. Actually, captions on ways (polylines) are not supported yet but
captions on areas (closed polygons) are supported very well, although it is still
in development.
Smrender
will calculate the centroid and the area of the polygon. The
caption is than placed at the position of the centroid5. If the parameter size is omitted or
set to 0, the font size is chosen dependent on the square root of the area.
Thus, larger polygons get larger captions and smaller ones get smaller
captions.
0.0.0 Drawing and Filling
The draw action is used to draw lines of various styles and fill polygons. This action uses solid colors for its operation. If you wish to fill an area with an image as pattern please have a look at Section 5.2.4.
The following shows the basic rule format.
<action> := 'draw:' <param> [ ';' <param> ... ]
<param> := <name> '=' <value>
<name> := 'color' | 'width' | 'style' |
'bcolor' | 'bwidth' | 'bstyle' |
'directional' | 'ignore_open'
The action behaves a little bit different if it is a polyline (open way, e.g. a
river) or a polygon (closed way, i.e. an area, e.g. a lake).
Independently if it is an open or a closed polygon there is always a filled part which is enclosed with a border.
The filled part is defined by color, width, and style at which just color is honored
for closed polygons.
The border part is defined by bcolor, bwidth, and bstyle.
The arguments to style and bstyle are one of dashed or dotted. If a style parameter
is omitted, a solid line is drawn.
Width
and bwidth are given in millimeters. A width of 0 draws the thinnest
possible line with a width of one pixel.
If ignore_open is set to "1", the rule is applied to closed polygons only.
r55mm
A special fill mode is used if directional is set to "1". Usually,
Smrender always fills the inner part of a polygon independently of its
direction, i.e. if the nodes of the polygon (way) are ordered clockwise or
counterclockwise. This mode is useful if areas of same type (same tags) are
enclosed within each other. This may result in unexpected rendering results.
The main reason for that is that OSM is just a two-dimensional database.
OpenStreetmap provides special tagging facilities to handle such cases, for
example multi-poly relations.
A typical application for the directional fill mode on sea charts is the
rendering of depth contours, in particular if they are filled in shallow
inshore areas. Smrender takes care on the direction of the
polygons.6
It always fills the portion which is left of the way. Figure 1
shows an example. Shallow water with a depth less than 10 meters is rendered
blue, deeper areas are white (transparent). The white area northeast of the islet
Radelj is such a 20 meters area which is enclosed by a more shallow area and than
again by a deeper area on the west side of this chart detail.
Filling polygons using this mode works only if the polygons are edited correctly, i.e.
their direction is correct. Furthermore it is slightly slower than the regular fill mode.
0.0.0 Calling External Functions
Smrender
has the ability to call user-defined library functions. This feature provides
modularity and the flexibility to be extended on the fly without modifying the core.
Thus, Smrender can be used for nearly every kind of rule-based OSM file processing.
The library calls dlopen(3) and dlsym(3) are used to dynamically import those
functions.
The basic rule format is defined in the following.
<definition> := <function> '@' <library> [':' <param>
[ ';' <param> ... ]]
<library> := path/name of shared library
<param> := <name> '=' <value>
Function
is the name of the function as it is exported by the shared
object library. In particular, the exported symbol has to be named
act_function_main(), i.e. it has to be prefixed by
"act_" and suffixed by "_main". If library contains a '/', the path is
resolved and the shared object loaded from that location. Otherwise the
dynamic linker tries to find the library in the appropriate system
directories.7
Beside linking the function itself, Smrender tries to import the optional
functions act_function_ini() and
act_function_fini(). These two functions may be
used for initialization and finalization of the main function.
The function is called on each match of an OSM node. The initialization
function act_function_ini() is called once directly
after the rules file was parsed before the first match. The finalization
function act_function_fini() is called onced
directly after the last match.
The prototypes are defined as follows.
int (*act_function_ini)(smrule_t*);
int (*act_function_main)(smrule_t*, osm_obj_t*);
int (*act_function_fini)(smrule_t*);
Act_function_main() gets a pointer to the rule structure and the OSM
object which matched the rule. The object can be either a node,
a way, or a relation.
typedef struct smrule smrule_t;
typedef struct action action_t;
struct smrule
{
osm_obj_t *oo;
void *data; // arbitrary data
action_t *act;
};
char *get_param(const char*, double*, const action_t*);
char *get_parami(const char*, int*, const action_t*);
The rule structure contains three pointers. The first one points to the OSM object of the rule
as defined in the ruleset. The _action_ tag was removed by the rules parser.
The Second pointer is initialized to NULL by Smrender and is not touched any further.
It is thought to be used by the external functions to store arbitrary data.
Please note that all resources that have been claimed by the _ini() function (such as heap memory)
have to be freed again by the finalization function _fini().
The third pointer of type action_t contains all data which needs Smrender
for rule processing. Its contents should not be touched except you know what you are doing.
It is important that the action structure (action_t) contains the paramters which
may have been passed to the function through the ruleset. The function get_param() shall
be used to retrieve their values. The first parameter is a constant string to the name
of the parameter. The second parameter is a pointer to a double variable which will
receive the converted value of the parameter. Of course this works only if the
parameter contains a decimal value. This pointer may be set to NULL if it is not used.
The third parameter to get_param() is a pointer to the action structure of the rule.
typedef struct osm_obj
{
// type of object: {OSM_NODE, OSM_WAY, OSM_REL}
short type;
// visibility: {0, 1}
short vis;
// OSM id
int64_t id;
// version, changeset, user id
int ver, cs, uid;
// Unix timestamp
time_t tim;
// number of tags
short tag_cnt;
// Pointer to tags
struct otag *otag;
} osm_obj_t;
The type of object can be determined on examination of
osm_obj_t.type. The variable may be set to either of
OSM_NODE, OSM_WAY, or OSM_REL. The object can
then be type-casted to either a osm_node_t, a osm_way_t,
or a osm_rel_t. All those OSM types are defined in
osm_inplace.h.
The return value of the function controls the further behavior of Smrender
while applying this same rule. A return value of 0 means no error. Smrender
will call the function again at the next matching object. If the return value
is greater than 0 it behaves similar but outputs a message in the log file. The
message contains the return value. If a negative value is returned, Smrender
immediately stops applying this rule, calls the _fini() function and
processes the next rule.
Section B explains how to write own (rendering) functions more in
detail.
Security Implications
This feature basically allows any user to call arbitrary functions on the
system. Thus, Smrender should never ever be installed with file modes
SUID/GUID-root! This would be a potential security risk and might allow an
attacker with access to your system to compromise it.
0.0.0 Placing Images
Smrender allows to place images at the position of nodes or to fill areas using
an image as pattern.
<definition> := 'img:' [ <param> [ ';' <param> ... ]]
<param> := <name> '=' <value>
<name> := 'file' | 'angle' | 'scale' | 'mkarea'
The parameter file is mandatory and contains a path to a PNG file.
The image is placed with its center directly at the position of the matching node without any modifications.
The parameter angle specifies an angle between 0 and 360 degrees to which to image may be rotated before it is placed
onto the map.
if angle is set to "auto",
Smrender tries to find a rotation angle. This works as described
in Section 5.2.1. The rotation function does not take the image itself into account except its size.
The rotation test starts at direction East and rotates counterclockwise.
Obviously, this makes only sense if it is applied to asymmetric non-centered images, such as light flares.
On areas, "auto" has no effect.
The parameter scale allows to scale the image. A value greater than 1
will enlarge the image, if scale is less than 1 it will shrink the image.
The parameter mkarea is a boolean parameter. If set to yes, the
auto-rotation function will add nodes and ways to the data which indicate the
level priority of the angles around the node. This is mainly intended for
debugging.
0.0.0 Output of OSM Data
With the action out it is possible to create an OSM file which contains all the
objects which match.
Smrender will create one file for each action. This means that if the same
file name is used in several out actions, the latter will overwrite the earlier ones.
The action takes just one argument, the path to the file.
<definition> := 'out:' [ <param> [ ';' <param> ... ]]
<param> := <name> '=' <value>
<name> := 'file'
0.0.0 Adding Tags to Objects
The action set_tags allows to add an arbitrary number of OSM tags to an
object. The tags have to be defined through an object within the rules file.
This object may have no action tag. The template should have an id because
the action set_tags needs to have a reference to it. To format simple
looks like the following.
<action> := 'settags:' <param>
<param> := <name> '=' <value>
<name> := 'id'
Please note that the object type of the rule must be the same as the object
type of the template.
0.0.0 Standard Shapes
Smrender
is able to generate standard shapes like triangles, or circles using this action.
The formal definition looks like the following.
<action> := 'shape:' <param>
<param> := <name> '=' <value>
<name> := 'nodes' | 'style' | 'radius' | 'angle' |
'key' | 'weight' | 'phase'
This action internally generates an ellipse8
with the given radius (the semi-major axis a) and places a
number of nodes on its circumference.
Because OSM does
not support any kind of arcs natively, they are constructed using ways with a specific
number of nodes. The parameter nodes specifies this number of nodes.
Thus, for example, if nodes is set to 3, the result will be a
triangle.
The parameter weight is set to 1 by default if it is omitted. It is a multiplier
which is used to calculate the semi-minor axis b = weight ×a. Thus, if weight = 1 a circle
is generated. The parameter phase shifts the points along the circumference in a counterclockwise order.
Thus, the following action creates a rectangle of the dimension
4×1.2 millimeters which is rotated by 20 degrees counterclockwise.
<tag k='_action_'
v='shape:nodes=4;radius=2;angle=20;weight=0.3;phase=45'/>
One of the parameters nodes or style is mandatory. The latter
argument is a preset for a specific number of nodes. Currently the styles
triangle (= 3 nodes), square (= 4 nodes), and circle
(= maximum nodes) are supported.
The radius is given in millimeters and the optional parameter
angle may be used to rotate the shape at any degrees counterclockwise.
If radius is omitted 1 millimeter is used as a default value.
With key the shape may be rotated dependent on the value of a tag of a
node. Key defines the key of this tag.
This action does not render anything itself. It generates an according set of
new nodes which are connected together with a way. All these nodes and the way
get the tag generator=smrender. The way additionally inherits all
tags of the original node which was matched by the rule set to invoke this
action. These tags can then be used to render the shape with a way rule. See
the following snippet as an example.
<node version='-1'>
<tag k='natural' v='peak'/>
<tag k='_action_' v='shape:style=triangle;radius=.7'/>
</node>
<way>
<tag k='natural' v='peak'/>
<tag k='_action_' v='draw:color=#906030'/>
</way>
0.0.0 Create Formatted Strings
This action is intended to create formatted strings out of a set of tags. It
works in a similar but yet more simple manner as printf(3) does. The
newly constructed string will be added as a new tag to the OSM object. This
tag may then be used to match on in subsequent rules.
<action> := 'strfmt:' <param>
<param> := <name> '=' <value>
<name> := 'addtag' | 'format' | 'key'
Strfmt() has two mandatory arguments. The first one is addtag
which contains the name for the new tag which will be added to this object.
The second parameter is format which specifies a format string. It may
contain any characters and a set of format symbols. The format symbols are the
% character followed by one of the following characters.
s The string of the value of the tag specified by the
respective key is copied to the output string.
f The string of the value of the tag specified by the
respective key is interpreted as a floating point number and
copied to the output string.
d The string of the value of the tag specified by the
respective key is interpreted as an integer number and copied to
the output string.
% The percent character is literally copied to the output
string.
All regular characters are directly copied to the output string without conversion.
The action must contain a key for each format symbol in the
format string. The keys are used exactly in the order as they appear in the
action line of ruleset.
Format String Example
The following example shows how to create a new string for all peaks. It shows
the name of the peak and its elevation in parentheses. This string is then
rendered in the second rule.
<node>
<tag k='natural' v='peak'/>
<tag k='_action_' v='strfmt:format=%s (%s);
addtag=peak_string;key=name;key=ele'/>
</node>
<node>
<tag k='peak_string' v=''/>
<tag k='_action_' v='cap:font=serif;size=2;key=peak_string'/>
</node>
0.0.0 Concatenating Split Ways
This function closes open polygons. To have closed polygons is
highly important because just such polygons can be filled with a
background color.
Polygons which are literally closed, such as the coastline or lakes are
very often found as a set of open ways whose beginning and end share the
same nodes. This is because different tags may be attached to different
parts of the polygon. Furthermore, just partial data sets are used as
input because typically just a small area out of the world's data is
selected.
Cat_poly has three optional parameters: ign_incomplete,
no_corner, and copy. The first two can both be set to either 0 or 1. If these
parameters are omitted, both are internally set to 0 by default.
If ign_incomplete is set to 1, cat_poly will only
close such polygons which are formed by a collection of ways where the
end point of each way directly is the starting point of the next way.
If ign_incomplete is set to 0 (which is the default)
cat_poly will also close polygons which are still open even if
all ways which have direct neighbors are connected by inserting
artificial ways. This is done by connecting the end of each way to the
beginning of the next way in the clockwise order of the bearing from the
center point of the image to the start/end nodes of the ways.
Please note that the insertion of artificial ways only works properly if the ways have a
specific direction. This is true at least for the ways which are tagged
with natural=coastline.
The parameter copy can occur multiple times and it is used to
specify the keys of the tags of the ways which should be copied to the
newly joined long way. If the values of these keys differ than
Smrender takes just the first one. All others are ignored. This is
because OSM defines that a tag can appear just excatly one time in an OSM
object.
If cat_poly is applied in a way rule than Smrender tries to
close all ways which match the criteria of the rule. The function finds all
adjacent ways and closes them properly. The original data is not changed
furthermore it creates and inserts new ways. Those new ways are tagged
with all tags that where defined in the rule set plus the tag
generator=smrender plus all tags which have been specified by
the copy parameters.
As already mentioned, a typical application for this function is to close
the coastline which will be open in most cases. The coastline is always
tagged with natural=coastline.
If cat_poly is applied to a relation then Smrender closes all
ways of each relation separately. It creates a new closed way which will
receive all tags of the relation, respectively. Additionally, it adds
the tag generator=smrender. The tags of the way segments are join
to the new way if they are listed with the parameter copy as
explained above.
Cat_poly applied to relations is useful for example in the
Agean Sea, where all partial ways of an island are grouped together using
relations. The tags of this relation contains global information about
each island, such as its name or population.
Please note that cat_poly() may create ways with more the 2000
nodes which violates the OSM standard definition.9. This may cause
problems if an output file is created (e.g. with option -w) and
used in other OSM applications. Smrender supports ways of up to
231 nodes. It is assumed that most other OSM processing tools do
not care about this artifical boundary.
0.0.0 Executing Programs and Scripts
Smrender
is able to run external 3rd-party programs and scripts. Smrender
communicates through stdin, stdout, and stderr of the program. The new
process is executed by the system call execvp(3) or
execvpe(3) if available.
<action> := 'exec:' <param>
<param> := <name> '=' <value>
<name> := 'cmd' | 'arg' | 'env' | 'osmhdr'
The mandatory parameter cmd defines the path to program. Optionally, one
or more arguments can be passed to the program by multiply specifying
arg. The arguments are passed exactly in the same order as in the
action.
The optional parameter env can be used to set environmant variables. By
default, the program is executed with an empty environment.
Smrender provides an interactive interface to communicate with the process.
The parameter osmhdr is an optional boolean argument and influences the
communication protocol as explained in the following Section.
The Communication Protocol
is an interactive hybrid command line protocol. All information from
Smrender to the process is sent in XML format. In turn for simplicity, the
process can use simple commands.
The communication is initiated by Smrender with an XML header and the
Smrender header. The latter contains the version of the protocol and the
a string for the XML generator, similar to the OSM format.
<?xml version='1.0' encoding='UTF-8'?>
<smrender version='0.1' generator='smrender 3.0.r1535'>
After this header all OSM objects which machted the rule are sent, one after
the other in OSM format version 0.6. If the action has the parameter
osmhdr set, each object is included in an OSM header as well. The
following shows an example of an object including the OSM header, i.e.
osmhdr=yes.
<osm version='0.6' generator='smrender'>
<node id="39273652" version="5" timestamp="2009-02-05T06:45:28Z"
uid="67265" visible="true" lat="44.2128480" lon="15.4482687">
<tag k="created_by" v="Merkaartor 0.13"/>
</node>
</osm>
If osmhdr is omitted or set to no, the first and the last line of
the above stanza are suppressed. After each OSM object, Smrender waits for
commands of the process. Every command will generate some output and finally
send a status code. The status code may be used by the process determine if a
command could be executed successfully.
<status code="200">OK</status>
The following commands are currently implemented:
- . [<code>]
A single period on a line will provoke Smrender to send the next
object which matches the rule. Optionally a numeric code between -128 and
127 can be supplied. 0 is default (if omitted) and simply means success.
Smrender appends the status code 200 to each object. If no more
objects are available, status code 404 is sent. In that case Smrender
waits for a last confirmation through a single period.
A positiv number indicates an error.
Smrender will stop further processing of objects of this rule. The
process has the chance to finalize and has to commit this with a single
period again. Smrender will close all streams and continue executing
the next rule.
If A negative number is returned, Smrender interpretes this as a fatal
error. As a consequence it will imediately stop further processing.
- get (node - way - relation) <id>
Additional OSM objects can be retrieved with this command.
0.0.0 Special Purpose Actions
Currently, Smrender provides the following functions.
- diff ( EXPERIMENTAL)
This function takes the argument file (exactly like in the
function out. See Section 5.2.5.) and infile.
It compares the ids of all objects in infile with all objects wich
have been loaded by Smrender (option -i) and writes all objects
which do not exist to file.
- disable
This function disables the object to which it is applied. This is done by
setting the attribute visible="false". It is intended to be
used to completely ignore certain objects during the rendering process.
Please note that disabled objects cannot be re-enabled again because the
rendering engine completely ignores invisible objects.
- dist_median ( EXPERIMENTAL)
This function calculates the median of the length of the edges of a way.
The result is added to the way within the tag
smrender:dist_median=*.
- enable_rule and disable_rule
These actions take the mandatory argument id which specifies the
id of the rule to be enabled or disabled. They actually set the visibility to
either true or false (see Section 5). Please note that enabling
a rule which would have been rendered before this one according to its
version and id is not executed it again.
- exit
This function forces Smrender to stop. No further rules will be
processed and Smrender will create the output files according to the
command line options. It behaves exactly like sending the INT
signal (pressing ^C, see Section 6).
This function is mainly intended for debugging rule sets.
- grid
This action creates a grid exactly like the command line option -g
but it provides more options. It provides the parameters margin,
tickswidth, and subtickswith to adjust the size of the axis
rulers. Values are given in milimeters. Furthermore it provides the
parameters grid, ticks, and subticks which work
exactly like the command line option (see Section 4.2).
Missing parameters are initialized with default values.
- incomplete ( EXPERIMENTAL)
This action can be applied to relations only.
It takes the single parameter file which specifies the
name of the output file to which it will write the types and ids of all
objects which are listed as members of the relation but are not found in
the input data. This may be useful to download this objects to complete
the input data if necessary.
Please note that this currently may not work properly if you specify the
same file name in several incomplete-rules.
- inherit_tags ( EXPERIMENTAL)
This action copies tags from objects to their parent objects. A
relation is considered as the parent of all of its members and a way is
the parent of all of its nodes.
There may be a list of one or more key parameters and optionally
the parameters object and force. The keys specify
which tags from the child (which is to object to which this rule is
applied) are copied to its parents. If object is not defined, the
tags are copied to all parents of any type. The parameter object
may be set to either way or relation in which only the
parents of those types are taken into consideration.
The parameter force may be set to 0 (which is default) or 1. In
the latter case inherit_tags will overwrite tags in the parent
if they do already exist.
- ins_eqdist ( EXPERIMENTAL)
This function inserts nodes along a way with equal distances. The
distance is given with the parameter distance in nautical miles.
The newly inserted nodes inherit all tags from the way and additionally
the tags generator=smrender, and distance=*, and
bearing=* are added. The latter two tags are set to the
appropriate values. The bearing my be used by the function shape
(see Section 5.2.7) to create appropriate rotated shapes.
- neighbortile ( EXPERIMENTAL)
This is a special function which may be handy in the tile creation
process. It creates a directory named "neighbor_tiles" and within
this a tile directory tree (zoom/x/y.conf). The files created
within this will contain several variables suitable for being sourced in
a shell script. The variables in the files specifies the bounding boxes
of the tiles in zoom level 10. This function will be improved in future
and the file format may change.
- poly_area
This function calculates the area of closed polygons in nautical square miles. It
adds the tag smrender:area=* to the way. The value of the tag contains
the area.
- poly_centroid
This function calculates the centroid of a closed polygon. It then adds a new node
at this position. The node will inherit all tags of the polygon. Additionally,
the tag smrender:id:way=* is added whose value is set to the ID of the
way, respectively.
- poly_len
This function calculates the length of a polygon in nautical miles. It
adds the tag smrender:length=* to the way.
- ruler
This function allows to generate a metric ruler. It is thought to be used
for land maps. It takes the arguments section and count.
Section is the length of one section of the ruler in kilometers.
Count sets the number of sections.
- set_ccw and set_cw
Those functions set the direction of a closed way to either clockwise
("cw") or counterclockwise ("ccw").
- split
This action can be applied to nodes only. It splits all ways at the
matching node into two parts.
- refine_poly
This function smooths the edges of polygons. It may take the function
arguments iteration and deviation. The first defines
the number of loops of the iterative refinement process (default = 3).
The latter defines the maximum deviation of the original polyline in
meters (default = 50). This avoids too high distortion of the polylines.
- reverse_way
This function always reverses a way independent of its current direction.
- zeroway ( EXPERIMENTAL)
Insert an artificial way of length zero at the matching node. Such a way
is a way with two nodes where both nodes have the same position.
0 Signals
Smrender
installs two signal handlers, one for SIGUSR1 and one
for SIGINT.
If Smrender receives a USR1 signal during the process of reading
OSM input data, it outputs some statistics about the current position of
reading and data throughput. It may be used as progress indicator if huge files
are used as input. If Smrender receives a INT signal (which is typically generated by pressing ^C) during
rendering, it immediately aborts rendering of further objects and saves the image
in its current state and exits normally. If SIGINT is caught twice, Smrender
exits immediately.
0 Extensions
As explained in Section 5.2.3, Smrender is able to call functions
of shared objects through dynamic linking at runtime. Thus it is very easy to
extend the core functionality of Smrender. Currently, it comes with one
additional library which is libsmfilter.
0.0 Libsmfilter and Smfilter
Smfilter10 is
a preprocessor for Osmarender. It adds some sea chart specific virtual nodes
and ways to simplify the rendering process. The functionality of
smfilter is now integrated into Smrender with
libsmfilter. As a result, smfilter is no longer supported.
Libsmfilter exports three functions: vsector(), pchar(), and sounding().
The first is the replacement for smfilter, the next is a new function which
generates combined strings for light descriptions, and the latter generates nodes and ways for
depth soundings as used in sea charts.
0.0.0 Generating Light Sectors with vsector()
This function is a full replacement for smfilter.
Smfilter took several options11 to adjust the
rendering behavior. These are the options -a, -b, -d, and
-r in particular. Libsmfilter now takes exactly the same
parameters since it is just a port. The parameters must be fed to it within
the rules file. This was commonly described in Section 5.2.3.
In detail the format looks like the following.
<param-str> := <a-v-pair>[';' <a-v-pair>[';' ...]]
<a-v-pair> := <attribute> '=' <value>
<attribute> := 'a' | 'b' | 'd' | 'r'
<value> := decimal number
a
This sets the maximum distance of arc nodes. Basically, the distance is
scaled with the radius; the smaller the radius the smaller the distance and
vice versa. With large radii the distance of nodes is limited to dist. The
value is given in nautical miles.
b
Leading and directional lights are rendered with a bearing line and a small
arc at its end. deg sets the angle of this arc to one side which means it
is drawn def degrees clockwise and def degress counterclockwise from the
bearing line.
d
This defines the arc divisor which is used to determine the distance of the
arc nodes. Thus, the node distance equals the radius divided by div. (see
also option -a).
r
I light may not have any radius specified since the tag is optional. In
such cases smfilter picks radius as default value.
This is an example for calling vsector() from the rule set.
<node>
<tag k='seamark:type' v=''/>
<tag
k='_action_'
v='vsector@libsmfilter.so:a=0.05;d=20;r=0.5'
/>
</node>
A full description of the output produced by vsector() is found in the
smfilter(1) man
page12 and in the
OSM wiki.13
0.0.0 Compatibility to Smfilter
The function vsector() does exactly the same as the original smfilter tool.
Thus, they are considered to be nearly 100% compatible.
The functionality is exactly the same but the file structure will still be different because
Smrender processes the OSM file in a different way than smfilter.
The following shows two exchangable command lines, the first for smfilter and
the second for Smrender.
smfilter -a 0.05 -d 20 -r 0.5 < in.osm > out.osm |
smrender -i in.osm -o /dev/null -M -G -w out.osm |
The following rules file has to be used in conjunction with Smrender to be a
replacement for smfilter. Of course, the file may be extended with
other rendering rules.
<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6'>
<node>
<tag k='seamark:type' v=''/>
<tag k='_action_'
v='func:vsector@./libsmfilter.so?a=0.05,d=20,r=0.5'/>
</node>
</osm>
0.0.0 Generating Light Description Strings
Pchar() generates a string which contains the characteristics of the
light as it is used in official sea charts and the List of Lights. See
Section P and P.16 in particular if the Chart No.
1.14
The function analyzes the tags of an object. If it contains valid
OpenSeamap tags15 it
generates the light string and adds the new OSM tag
seamark:ligh_character=* to the object. The value of the tag contains
the string which may be rendered by a subsequent rule.
0.0.0 Generating Circles around Depth Soundings
Libsmfilter provides the function sounding() which generates
small circles around depth soundings.
It generates symbols such as I.4 of Chart No. 1 and circles with a dashed line used for approximate
depths (I.31).
Tags use for it is seamark:sounding=* containing the depth in meters,
and optional seamark:sounding: quality = {approx | reported_unconfirmed}.
See "Rendering Depths with Smrender"16 for
more details.
0 Examples
There is a very simple example for your first rendered map. Before, download,
compile, and install Smrender as explained in Section A.
Create a working directory somewhere.
From the Smrender download URL17 get the seamap icons package (icons.tbz2) and
extract it.
tar xvfj icons.tbz2
Now we have to get some OSM data. We just use the Overpass API18 to get a small window.
wget -O cr.osm \
'http://www.overpass-api.de/api/xapi?map?bbox=15,43.7,15.4,44'
Now we can start Smrender by using the rule set rules.osm which comes
with the Smrender package. Copy it to your working directory. By default it is installed into /usr/local/share/smrender.
0.0 Generating a PDF
PDF files are the best choice if you intend to print something.
The following command line renders the OSM file cr.osm
to the output image cr.png having the dimension of an A4 landscape page. 43° N 52.8'
15° E 12.8' are the center coordinates and the scale is chosen to be 1:100000 which is typical for sea charts.
smrender -i cr.osm -o cr.png -P A4 -l 43N52.8:15E12.8:100000
The result is the PNG image cr.png. You may look at it using your
favorite image viewer. To get a correct non-distorted print-out it usually is a
good idea to use the PDF format instead. If you try to print the image with a
graphics program it most probably will be rescaled to fit the print margins.
This will usually not happen if you print a PDF which has valid paper
dimensions.
To create a PDF file use the option -O instead.
smrender -i cr.osm -O cr.pdf -P A4 -l 43N52.8:15E12.8:100000
0.0 Generating a KAP File
KAP files are used by many applications that deal with marine navigation (e.g.
OpenCPN, http://opencpn.org/) or GPS chart plotters or smart
phones (e.g. Marine Navigator for Android,
https://play.google.com/store/apps/details?id=de.kemiro.marinenavigator).
Very often those files are also referred to as BSB files or also RNC files.
The following command generates a KAP file. It assumes
that you have an input OSM file cr.osm. See the beginning of this
Section (Section 8) on how to retrieve it. The density is
reduced to 200 dpi (option -d) to save resources of your smart phone or
chart plotter. Option -G disables the grid since most applications are
able to generate a grid on their own. The KAP file is saved to cr.kap.
The option -s 1 disables antialiasing. This also reduces resource
usage because it limits the color space. Many plotting applications may have
their built-in antialiasing.
smrender -i cr.osm -d 200 -G -k cr.kap -s 1 43N52.8:15E12.8:100000
Please note that a PNG file and a KAP file may be generated at the same time by simply adding option -o.
The file cr.kap can be used by your favorite application. If you use
e.g. Marine Navigator on Android you have to copy the file to a folder
named BSB_ROOT in the root directory of your SD card.
0 Files
The Smrender package contains all source C files and headers. A
configure script is provided to create appropriate Makefiles
and build Smrender (see Section A). It contains all sources
for the smfilter library (see Section 7.1) in the
directory libsmfilter/ and a skeleton libary in the directory
libskel/ which may be used as a starting point for own functions (see
Section B). Due to an internal code reorganization many general
purpose functions are moved to the separate library libsmrender. All
respective sources are found in the directory libsmrender/.
The package contains futhermore different rule sets which may also be used as a basis for
own rule sets. The main ruleset is found in the directory rules_100000 which is actively maintained.
Older files are rules.osm, rulesbig.osm, and rules_land.osm which are still
provided with Smrender.
0 Bugs and Caveats
Smrender
does not validate the well-formedness of the OSM files. Thus, you may get unexpected rendering results if the file
format is incorrect.
For more information please look at the project homepage at http://www.abenteuerland.at/smrender/.
0 Author
Smrender
is written by Bernhard R. Fischer, mailto:bf@abenteuerland.at. The idea of the project was born
in summer of 2010. The actual development started in October of 2011.
0 Copyright
Copyright 2011-2013 Bernhard R. Fischer.
This file is part of Smrender.
Smrender
is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, version 3 of the License.
Smrender
is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public
License along with Smrender. If not, see < http://www.gnu.org/licenses/ > .
@ Compiling and Installing
Smrender
should be simple to compile. It depends on
libcairo19 if it is used
to render charts. If libcairo is not installed, Smrender will
still compile and it can be used for OSM data processing but not for rendering
images.
Download the most recent Smrender package from http://www.abenteuerland.at/download/smrender/
and extract the package with tar xvfj smrender-rxxxx.tbz2. Change into the newly extracted
directory.
Then run the configure script ./configure, then build it with make. It should compile fine. Finally, there is the executable smrender and
the libsmfilter.so. The latter is not mandatory for running Smrender since it
may just be loaded dynamically by the rule set (see Section 7.1). Those files
may be installed into the appropriate directories on your system with sudo make install.20
Smrender
is known to compile with gcc 4.x on Debian Linux (Lenny
and Squeeze), FreeBSD version 8.x, OpenBSD 5.x, and Mac OSX. It should compile on most Unixoid
plattforms without further troubles, maybe even on Windows with Cygwin.
@ Writing Own Rendering Functions
The Smrender package includes a skeleton library in the directory libskel/.
It implements the library constructor and destructor, and the actual rule function together
with its initialization and de-initialization functions.
The directory contains also a Makefile which shows how to compile the library.
Smrender
exports several functions which may be called by the library. The following list
shows the most imported ones. The prototypes are defined in smrender.h, smlog.h, or
osm_inplace.h.
// Use smrender's standard logging. This function is defined in 'smlog.h' and
// works similar to syslog(3).
void log_msg(int, const char*, ...);
// Get an OSM object (OSM_NODE, OSM_WAY, OSM_REL) with the specifed id. This
// function returns a pointer to either an osm_node_t or osm_way_t or_osm_rel_t
// structure on success, or NULL on error.
void *get_object(int, int64_t);
// Add an OSM object to the memory. The function returns 0 on success,
// otherwise -1 is returned. Preexisting objects with the same id are simply
// overwritten.
int put_object(osm_obj_t*);
// These functions return unique ids for nodes and ways.
int64_t unique_node_id(void);
int64_t unique_way_id(void);
// Initialize an OSM object. The number of tags (type short) and the number of
// node references (type int) must be supplied. Currently, the functions always
// return a valid pointer to an object. The objects returned are just partially
// initialized (see 'osm_func.c').
osm_node_t *malloc_node(short);
osm_way_t *malloc_way(short, int);
osm_rel_t *malloc_rel(short, short);
@ FAQ
This section covers some questions and answer which might arise.
@.0 Why is Smrender not written in C++?
On closer examination, the software architecture suggests an object-oriented
programming language such as C++ but Smrender is written in C. The short
answer is that C is always my first choice and the code was already too mature
to switch to C++ without a high effort. The long answer is that Smrender is
able to dynamically link libraries at runtime. Interfacing from C++ to a
library written in C (currently) seems to be difficult (although not
impossible).
But I still have in mind to rewrite Smrender in C++ when time comes.
@.0 Is it possible to create other maps, such as road maps?
Yes of course! The appearance of the map solely depends on the ruleset. A very simple
first "land" ruleset is found in the rules directory.
The
only thing which is fixed is that Smrender uses a transversal Mercartor
projection which typically is not used for "land maps".
@ Todo
- Rendering of rotated (not North-up) maps.
- Dynamic rules; these are rules which are generated during the rendering itself and are applied
subsequently.
Footnotes:
1 h t t p : / / w w w . c a i r o g r a p h i c s . o r g /
2 h t t p : / / w i k i . o p e n s t r e e t m a p . o r g / w i k i / E l e m e n t s
3 h t t p : / / e n . w i k i p e d i a . o r g / w i k i / X 1 1 _ c o l o r _ n a m e s
4 P l e a s e n o t e t h a t t h i s i s d i f f e r e n t
t o t h e a n g l e d e f i n i t i o n o f m a r i t i m e n a v i g a t i o n w h i c h i s d e g r e e s c l o c k w i s e f r o m
0 t o 3 6 0 b e i n g 0 u p w a r d s ( N o r t h ) .
5 T h i s i s s i m i l a r
t o w h a t O s m a r e n d e r d o e s .
6 A f e w f e a t u r e s e x i s t i n O S M a s w e l l o f w h i c h t h e r e n d e r i n g
d e p e n d s o n t h e d i r e c t i o n . M o s t i m p o r t a n t l y t h i s i s
n a t u r a l = c o a s t l i n e .
O t h e r e x a m p l e s a r e
w a t e r w a y = c a n a l
a n d
n a t u r a l = c l i f f .
7 S e e d l o p e n ( 3 ) f o r d e t a i l s .
8 W i k i p e d i a : E l l i p s e , h t t p : / / e n . w i k i p e d i a . o r g / w i k i / E l l i p s e .
9 S e e
h t t p : / / w i k i . o p e n s t r e e t m a p . o r g / w i k i / W a y .
1 0 S e e h t t p : / / w w w . a b e n t e u e r l a n d . a t / s m f i l t e r /
1 1 S e e
h t t p : / / w w w . a b e n t e u e r l a n d . a t / s m f i l t e r / s m f i l t e r . h t m l
1 2 h t t p : / / w w w . a b e n t e u e r l a n d . a t / s m f i l t e r / s m f i l t e r . h t m l
1 3 h t t p : / / w i k i . o p e n s t r e e t m a p . o r g / w i k i / O p e n S e a M a p / s m f i l t e r
1 4 h t t p : / / w w w . n a u t i c a l c h a r t s . n o a a . g o v / m c d / c h a r t 1 / C h a r t N o 1 . p d f
1 5 S e e
h t t p : / / w i k i . o p e n s t r e e t m a p . o r g / w i k i / O p e n S e a M a p / L i g h t s _ D a t a _ M o d e l .
1 6 h t t p : / / w w w . c y p h e r p u n k . a t / 2 0 1 2 / 0 3 / 1 1 / r e n d e r i n g - d e p t h s - w i t h - s m r e n d e r /
1 7 h t t p : / / w w w . a b e n t e u e r l a n d . a t / s m r e n d e r / d o w n l o a d /
1 8 h t t p : / / w i k i . o p e n s t r e e t m a p . o r g / w i k i / O v e r p a s s _ A P I .
1 9 h t t p : / / w w w . c a i r o g r a p h i c s . o r g /
2 0 R o o t p r i v i l e g e s a r e r e q u i r e d t o i n s t a l l .
File translated from
TEX
by
TTH,
version 4.03.
On 13 Nov 2013, 22:43.