source: subversion/applications/rendering/osmarender4/osmarender.xsl @ 9951

Last change on this file since 9951 was 3615, checked in by frederik, 13 years ago

copy SVG attributes from OSM tags for ways and areas.

File size: 120.9 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<!--
3==============================================================================
4
5Osmarender
6
7==============================================================================
8
9Copyright (C) 2006-2007  OpenStreetMap Foundation
10
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
24
25==============================================================================
26-->
27<xsl:stylesheet xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:date="http://exslt.org/dates-and-times" xmlns:set="http://exslt.org/sets" xmlns:osma="http://wiki.openstreetmap.org/index.php/Osmarender/Frollo/1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" extension-element-prefixes="date set">
28 
29    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8"/>
30
31    <xsl:param name="osmfile" select="/rules/@data"/>
32    <xsl:param name="title" select="/rules/@title"/>
33
34    <xsl:param name="scale" select="/rules/@scale"/>
35    <xsl:param name="symbolScale" select="/rules/@symbolScale"/>
36    <xsl:param name="withOSMLayers" select="/rules/@withOSMLayers"/>
37    <xsl:param name="withUntaggedSegments" select="/rules/@withUntaggedSegments"/>
38    <xsl:param name="svgBaseProfile" select="/rules/@svgBaseProfile"/>
39    <xsl:param name="symbolsDir" select="/rules/@symbolsDir"/>
40
41    <xsl:param name="showGrid" select="/rules/@showGrid"/>
42    <xsl:param name="showBorder" select="/rules/@showBorder"/>
43    <xsl:param name="showScale" select="/rules/@showScale"/>
44    <xsl:param name="showLicense" select="/rules/@showLicense"/>
45
46    <xsl:key name="nodeById" match="/osm/node" use="@id"/>
47    <xsl:key name="segmentById" match="/osm/segment" use="@id"/>
48    <xsl:key name="segmentByFromNode" match="/osm/segment" use="@from"/>
49    <xsl:key name="segmentByToNode" match="/osm/segment" use="@to"/>
50    <xsl:key name="wayBySegment" match="/osm/way" use="seg/@id"/>
51
52    <xsl:variable name="data" select="document($osmfile)"/>
53        <xsl:variable name="bFrollo" select="$data/osm/@osma:frollo=&quot;1&quot;"/>
54
55    <!-- extra height for marginalia at top -->
56    <xsl:variable name="marginaliaTopHeight">
57        <xsl:choose>
58            <xsl:when test="$title != ''">40</xsl:when>
59            <xsl:when test="($title = '') and ($showBorder = 'yes')">1.5</xsl:when>
60            <xsl:otherwise>0</xsl:otherwise>
61        </xsl:choose>
62    </xsl:variable>
63
64    <!-- extra height for marginalia at bottom -->
65    <xsl:variable name="marginaliaBottomHeight">
66        <xsl:choose>
67            <xsl:when test="($showScale = 'yes') or ($showLicense = 'yes')">45</xsl:when>
68            <xsl:when test="($showScale != 'yes') and ($showLicense != 'yes') and ($showBorder = 'yes')">1.5</xsl:when>
69            <xsl:otherwise>0</xsl:otherwise>
70        </xsl:choose>
71    </xsl:variable>
72
73    <!-- extra width for border -->
74    <xsl:variable name="extraWidth">
75        <xsl:choose>
76            <xsl:when test="$showBorder = 'yes'">3</xsl:when>
77            <xsl:otherwise>0</xsl:otherwise>
78        </xsl:choose>
79    </xsl:variable>
80
81    <!-- extra height for border -->
82    <xsl:variable name="extraHeight">
83        <xsl:choose>
84            <xsl:when test="($title = '') and ($showBorder = 'yes')">3</xsl:when>
85            <xsl:otherwise>0</xsl:otherwise>
86        </xsl:choose>
87    </xsl:variable>
88
89    <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bllat">
90        <xsl:for-each select="$data/osm/node/@lat">
91            <xsl:sort data-type="number" order="ascending"/>
92            <xsl:if test="position()=1">
93                <xsl:value-of select="."/>
94            </xsl:if>
95        </xsl:for-each>
96    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bllon">
97        <xsl:for-each select="$data/osm/node/@lon">
98            <xsl:sort data-type="number" order="ascending"/>
99            <xsl:if test="position()=1">
100                <xsl:value-of select="."/>
101            </xsl:if>
102        </xsl:for-each>
103    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="trlat">
104        <xsl:for-each select="$data/osm/node/@lat">
105            <xsl:sort data-type="number" order="descending"/>
106            <xsl:if test="position()=1">
107                <xsl:value-of select="."/>
108            </xsl:if>
109        </xsl:for-each>
110    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="trlon">
111        <xsl:for-each select="$data/osm/node/@lon">
112            <xsl:sort data-type="number" order="descending"/>
113            <xsl:if test="position()=1">
114                <xsl:value-of select="."/>
115            </xsl:if>
116        </xsl:for-each>
117    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bottomLeftLatitude">
118        <xsl:choose>
119            <xsl:when test="/rules/bounds">
120                <xsl:value-of select="/rules/bounds/@minlat"/>
121            </xsl:when>
122            <xsl:when test="$data/osm/bounds">
123                <xsl:value-of select="$data/osm/bounds/@request_minlat"/>
124            </xsl:when>
125            <xsl:otherwise>
126                <xsl:value-of select="$bllat"/>
127            </xsl:otherwise>
128        </xsl:choose>
129    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bottomLeftLongitude">
130        <xsl:choose>
131            <xsl:when test="/rules/bounds">
132                <xsl:value-of select="/rules/bounds/@minlon"/>
133            </xsl:when>
134            <xsl:when test="$data/osm/bounds">
135                <xsl:value-of select="$data/osm/bounds/@request_minlon"/>
136            </xsl:when>
137            <xsl:otherwise>
138                <xsl:value-of select="$bllon"/>
139            </xsl:otherwise>
140        </xsl:choose>
141    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="topRightLatitude">
142        <xsl:choose>
143            <xsl:when test="/rules/bounds">
144                <xsl:value-of select="/rules/bounds/@maxlat"/>
145            </xsl:when>
146            <xsl:when test="$data/osm/bounds">
147                <xsl:value-of select="$data/osm/bounds/@request_maxlat"/>
148            </xsl:when>
149            <xsl:otherwise>
150                <xsl:value-of select="$trlat"/>
151            </xsl:otherwise>
152        </xsl:choose>
153    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="topRightLongitude">
154        <xsl:choose>
155            <xsl:when test="/rules/bounds">
156                <xsl:value-of select="/rules/bounds/@maxlon"/>
157            </xsl:when>
158            <xsl:when test="$data/osm/bounds">
159                <xsl:value-of select="$data/osm/bounds/@request_maxlon"/>
160            </xsl:when>
161            <xsl:otherwise>
162                <xsl:value-of select="$trlon"/>
163            </xsl:otherwise>
164        </xsl:choose>
165    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="middleLatitude" select="($topRightLatitude + $bottomLeftLatitude) div 2.0"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="latr" select="$middleLatitude * 3.1415926 div 180.0"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="coslat" select="1 - ($latr * $latr) div 2 + ($latr * $latr * $latr * $latr) div 24"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="projection" select="1 div $coslat"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="dataWidth" select="(number($topRightLongitude)-number($bottomLeftLongitude))*10000*$scale"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="dataHeight" select="(number($topRightLatitude)-number($bottomLeftLatitude))*10000*$scale*$projection"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="km" select="(0.0089928*$scale*10000*$projection)"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="documentWidth">
166        <xsl:choose>
167            <xsl:when test="$dataWidth &gt; (number(/rules/@minimumMapWidth) * $km)">
168                <xsl:value-of select="$dataWidth"/>
169            </xsl:when>
170            <xsl:otherwise><xsl:value-of select="number(/rules/@minimumMapWidth) * $km"/></xsl:otherwise>
171        </xsl:choose>
172    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="documentHeight">
173        <xsl:choose>
174            <xsl:when test="$dataHeight &gt; (number(/rules/@minimumMapHeight) * $km)">
175                <xsl:value-of select="$dataHeight"/>
176            </xsl:when>
177            <xsl:otherwise><xsl:value-of select="number(/rules/@minimumMapHeight) * $km"/></xsl:otherwise>
178        </xsl:choose>
179    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="width" select="($documentWidth div 2) + ($dataWidth div 2)"/><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="height" select="($documentHeight div 2) + ($dataHeight div 2)"/>
180
181    <!-- Main template -->
182    <xsl:template match="/rules">     
183
184        <!-- Include an external css stylesheet if one was specified in the rules file -->
185        <xsl:if test="@xml-stylesheet">
186            <xsl:processing-instruction name="xml-stylesheet">
187                href="<xsl:value-of select="@xml-stylesheet"/>" type="text/css"
188            </xsl:processing-instruction>
189        </xsl:if>
190
191        <xsl:variable name="svgWidth" select="$documentWidth + $extraWidth"/>
192        <xsl:variable name="svgHeight" select="$documentHeight + $marginaliaTopHeight + $marginaliaBottomHeight"/>
193
194        <svg id="main" version="1.1" baseProfile="{$svgBaseProfile}" width="{$svgWidth}px" height="{$svgHeight}px" viewBox="{-$extraWidth div 2} {-$extraHeight div 2} {$svgWidth} {$svgHeight}">
195            <xsl:if test="/rules/@interactive=&quot;yes&quot;">
196                <xsl:attribute name="onscroll">fnOnScroll(evt)</xsl:attribute>
197                <xsl:attribute name="onzoom">fnOnZoom(evt)</xsl:attribute>
198                <xsl:attribute name="onload">fnOnLoad(evt)</xsl:attribute>
199                <xsl:attribute name="onmousedown">fnOnMouseDown(evt)</xsl:attribute>
200                <xsl:attribute name="onmousemove">fnOnMouseMove(evt)</xsl:attribute>
201                <xsl:attribute name="onmouseup">fnOnMouseUp(evt)</xsl:attribute>
202            </xsl:if>
203
204            <xsl:call-template name="metadata"/>
205
206            <!-- Include javaScript functions for all the dynamic stuff --> 
207            <xsl:if test="/rules/@interactive=&quot;yes&quot;">
208                <xsl:call-template name="javaScript"/>
209            </xsl:if>
210
211            <defs id="defs-rulefile">
212                <!-- Get any <defs> and styles from the rules file -->
213                <xsl:copy-of select="defs/*"/>
214            </defs>
215
216            <xsl:if test="$symbolsDir != ''">
217                <!-- Get all symbols mentioned in the rules file from the symbolsDir -->
218                <defs id="defs-symbols">
219                    <xsl:for-each select="/rules//symbol/@ref">
220                        <xsl:copy-of select="document(concat($symbolsDir,'/', ., '.svg'))/svg:svg/svg:defs/svg:symbol"/>
221                    </xsl:for-each>
222                </defs>
223            </xsl:if>
224
225            <!-- Pre-generate named path definitions for all ways -->
226            <xsl:variable name="allWays" select="$data/osm/way"/>
227            <defs id="defs-ways">
228                <xsl:for-each select="$allWays">
229                    <xsl:call-template name="generateWayPath"/>
230                </xsl:for-each>
231            </defs>
232
233            <!-- Clipping rectangle for map -->
234            <clipPath id="map-clipping">
235                <rect id="map-clipping-rect" x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px"/>
236            </clipPath>
237
238            <g id="map" clip-path="url(#map-clipping)" inkscape:groupmode="layer" inkscape:label="Map" transform="translate(0,{$marginaliaTopHeight})">
239                <!-- Draw a nice background layer -->
240                <rect id="background" x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px" class="map-background"/>
241
242                <!-- If this is set we first draw all untagged segments not belonging to any way -->
243                <xsl:if test="$withUntaggedSegments=&quot;yes&quot;">
244                    <xsl:call-template name="drawUntaggedSegments"/>
245                </xsl:if>
246
247                <!-- Process all the rules drawing all map features -->
248                <xsl:call-template name="processRules"/>
249            </g>
250
251            <!-- Draw map decoration -->
252            <g id="map-decoration" inkscape:groupmode="layer" inkscape:label="Map decoration" transform="translate(0,{$marginaliaTopHeight})">
253                <!-- Draw a grid if required -->
254                <xsl:if test="$showGrid=&quot;yes&quot;">
255                    <xsl:call-template name="gridDraw"/>
256                </xsl:if>
257
258                <!-- Draw a border if required -->
259                <xsl:if test="$showBorder=&quot;yes&quot;">
260                    <xsl:call-template name="borderDraw"/>
261                </xsl:if>
262            </g>
263
264            <!-- Draw map marginalia -->
265            <xsl:if test="($title != '') or ($showScale = 'yes') or ($showLicense = 'yes')">
266                <g id="marginalia" inkscape:groupmode="layer" inkscape:label="Marginalia">
267                    <!-- Draw the title -->
268                    <xsl:if test="$title!=''">
269                        <xsl:call-template name="titleDraw">
270                            <xsl:with-param name="title" select="$title"/>
271                        </xsl:call-template>
272                    </xsl:if>
273
274                    <xsl:if test="($showScale = 'yes') or ($showLicense = 'yes')">
275                        <g id="marginalia-bottom" inkscape:groupmode="layer" inkscape:label="Marginalia (Bottom)" transform="translate(0,{$marginaliaTopHeight})">
276                            <!-- Draw background for marginalia at bottom -->
277                            <rect id="marginalia-background" x="0px" y="{$documentHeight + 5}px" height="40px" width="{$documentWidth}px" class="map-marginalia-background"/>
278
279                            <!-- Draw the scale in the bottom left corner -->
280                            <xsl:if test="$showScale=&quot;yes&quot;">
281                                <xsl:call-template name="scaleDraw"/>
282                            </xsl:if>
283
284                            <!-- Draw Creative commons license -->
285                            <xsl:if test="$showLicense=&quot;yes&quot;">
286                                <xsl:call-template name="in-image-license">
287                                    <xsl:with-param name="year" select="2007"/>
288                                    <xsl:with-param name="dx" select="$documentWidth"/>
289                                    <xsl:with-param name="dy" select="$documentHeight"/>
290                                </xsl:call-template>
291                            </xsl:if>
292                        </g>
293                    </xsl:if>
294                </g>
295            </xsl:if>
296
297            <!-- Draw labels and controls that are in a static position -->
298            <g id="staticElements" transform="scale(1) translate(0,0)">
299                <!-- Draw the +/- zoom controls -->
300                <xsl:if test="/rules/@interactive=&quot;yes&quot;">
301                    <xsl:call-template name="zoomControl"/>
302                </xsl:if>
303            </g>
304        </svg>
305
306    </xsl:template>
307
308    <!-- include templates from all the other files -->
309    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawLine">
310        <xsl:param name="instruction"/>
311        <xsl:param name="segment"/> <!-- The current segment element -->
312        <xsl:param name="way"/>  <!-- The current way element if applicable -->
313
314        <xsl:variable name="from" select="@from"/>
315        <xsl:variable name="to" select="@to"/>
316        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
317        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
318        <xsl:variable name="fromNodeContinuation" select="(count(key(&quot;segmentByFromNode&quot;,$fromNode/@id))+count(key(&quot;segmentByToNode&quot;,$fromNode/@id)))&gt;1"/>
319        <xsl:variable name="toNodeContinuation" select="(count(key(&quot;segmentByFromNode&quot;,$toNode/@id))+count(key(&quot;segmentByToNode&quot;,$toNode/@id)))&gt;1"/>
320
321        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
322        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
323        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
324        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
325
326        <!-- If this is not the end of a path then draw a stub line with a rounded linecap at the from-node end -->
327        <xsl:if test="$fromNodeContinuation">
328            <xsl:call-template name="drawSegmentFragment">
329                <xsl:with-param name="x1" select="$x1"/>
330                <xsl:with-param name="y1" select="$y1"/>
331                <xsl:with-param name="x2" select="number($x1)+((number($x2)-number($x1)) div 10)"/>
332                <xsl:with-param name="y2" select="number($y1)+((number($y2)-number($y1)) div 10)"/>
333            </xsl:call-template>
334        </xsl:if>
335
336        <!-- If this is not the end of a path then draw a stub line with a rounded linecap at the to-node end -->
337        <xsl:if test="$toNodeContinuation">
338            <xsl:call-template name="drawSegmentFragment">
339                <xsl:with-param name="x1" select="number($x2)-((number($x2)-number($x1)) div 10)"/>
340                <xsl:with-param name="y1" select="number($y2)-((number($y2)-number($y1)) div 10)"/>
341                <xsl:with-param name="x2" select="$x2"/>
342                <xsl:with-param name="y2" select="$y2"/>
343            </xsl:call-template>
344        </xsl:if>
345
346        <line>
347            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
348            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
349            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
350            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
351            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
352        </line>
353
354    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawSegmentFragment">
355        <xsl:param name="x1"/>
356        <xsl:param name="x2"/>
357        <xsl:param name="y1"/>
358        <xsl:param name="y2"/>
359            <line>
360                <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
361                <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
362                <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
363                <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
364                <!-- add the rounded linecap attribute -->
365                <xsl:attribute name="stroke-linecap">round</xsl:attribute>
366                <!-- suppress any markers else these could be drawn in the wrong place -->
367                <xsl:attribute name="marker-start">none</xsl:attribute>
368                <xsl:attribute name="marker-end">none</xsl:attribute>
369                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
370            </line>
371    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" name="drawWay">
372        <xsl:param name="instruction"/>
373        <xsl:param name="way"/>  <!-- The current way element if applicable -->
374        <xsl:param name="layer"/>
375        <xsl:param name="classes"/>
376
377        <xsl:variable name="tunnel" select="$way/tag[@k='tunnel']"/>
378        <xsl:variable name="railway" select="$way/tag[@k='railway' and @v='rail']"/>
379
380        <xsl:if test="not($tunnel and ($tunnel/@v = 'yes') or ($tunnel/@v = 'true'))">  <!-- if this is not a tunnel -->
381
382            <xsl:if test="not($railway)">
383
384                <!-- For the first and last segments in the way if the start or end is a continuation, then draw a round-capped stub segment
385                        that is 1/10th the length of the segment and without any markers.  TODO: do this for all sub-paths within the path.
386                    Count the number of segments that link to the from node of this segment.  Only count them if they belong to a way that
387                    has a layer tag that is greater than the layer of this way.  If there are any such segments then draw rounded
388                    end fragments. -->
389                <!-- Process the first segment in the way -->
390                <xsl:variable name="firstSegment" select="key(&quot;segmentById&quot;,$way/seg[1]/@id)"/>
391                <xsl:variable name="firstSegmentFromNode" select="key(&quot;nodeById&quot;,$firstSegment/@from)"/>
392                <xsl:variable name="firstSegmentToNode" select="key(&quot;nodeById&quot;,$firstSegment/@to)"/>
393                <xsl:variable name="firstSegmentInboundLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByToNode&quot;,$firstSegmentFromNode/@id)/@id)/tag[@k=&quot;layer&quot; and @v &gt;= $layer])"/>
394                <xsl:variable name="firstSegmentInboundNoLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByToNode&quot;,$firstSegmentFromNode/@id)/@id)[count(tag[@k=&quot;layer&quot;])=0 and $layer &lt; 1])"/>
395                <xsl:variable name="firstSegmentOutboundLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByFromNode&quot;,$firstSegmentFromNode/@id)/@id)/tag[@k=&quot;layer&quot; and @v &gt;= $layer])"/>
396                <xsl:variable name="firstSegmentOutboundNoLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByFromNode&quot;,$firstSegmentFromNode/@id)/@id)[count(tag[@k=&quot;layer&quot;])=0 and $layer &lt; 1])"/>
397                <xsl:variable name="firstSegmentLayerCount" select="($firstSegmentInboundLayerCount+$firstSegmentInboundNoLayerCount+$firstSegmentOutboundLayerCount+$firstSegmentOutboundNoLayerCount)&gt;1"/>
398
399                <xsl:if test="$firstSegmentLayerCount">
400                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($firstSegmentFromNode/@lon))*10000*$scale)"/>
401                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($firstSegmentFromNode/@lat))*10000*$scale*$projection)"/>
402                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($firstSegmentToNode/@lon))*10000*$scale)"/>
403                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($firstSegmentToNode/@lat))*10000*$scale*$projection)"/>
404                    <xsl:call-template name="drawSegmentFragment">
405                        <xsl:with-param name="x1" select="$x1"/>
406                        <xsl:with-param name="y1" select="$y1"/>
407                        <xsl:with-param name="x2" select="number($x1)+((number($x2)-number($x1)) div 10)"/>
408                        <xsl:with-param name="y2" select="number($y1)+((number($y2)-number($y1)) div 10)"/>
409                    </xsl:call-template>
410                </xsl:if>
411
412                <!-- Process the last segment in the way -->
413                <xsl:variable name="lastSegment" select="key(&quot;segmentById&quot;,$way/seg[last()]/@id)"/>
414                <xsl:variable name="lastSegmentFromNode" select="key(&quot;nodeById&quot;,$lastSegment/@from)"/>
415                <xsl:variable name="lastSegmentToNode" select="key(&quot;nodeById&quot;,$lastSegment/@to)"/>
416                <xsl:variable name="lastSegmentToNodeLayer" select="(count(key(&quot;segmentByFromNode&quot;,$lastSegmentToNode/@id)[@k=&quot;layer&quot; and @v &gt; $layer])+count(key(&quot;segmentByToNode&quot;,$lastSegmentToNode/@id)[@k=&quot;layer&quot; and @v &gt; $layer]))&gt;0"/>
417                <xsl:variable name="lastSegmentInboundLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByToNode&quot;,$lastSegmentToNode/@id)/@id)/tag[@k=&quot;layer&quot; and @v &gt;= $layer])"/>
418                <xsl:variable name="lastSegmentInboundNoLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByToNode&quot;,$lastSegmentToNode/@id)/@id)[count(tag[@k=&quot;layer&quot;])=0 and $layer &lt; 1])"/>
419                <xsl:variable name="lastSegmentOutboundLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByFromNode&quot;,$lastSegmentToNode/@id)/@id)/tag[@k=&quot;layer&quot; and @v &gt;= $layer])"/>
420                <xsl:variable name="lastSegmentOutboundNoLayerCount" select="count(key(&quot;wayBySegment&quot;,key(&quot;segmentByFromNode&quot;,$lastSegmentToNode/@id)/@id)[count(tag[@k=&quot;layer&quot;])=0 and $layer &lt; 1])"/>
421                <xsl:variable name="lastSegmentLayerCount" select="($lastSegmentInboundLayerCount+$lastSegmentInboundNoLayerCount+$lastSegmentOutboundLayerCount+$lastSegmentOutboundNoLayerCount)&gt;1"/>
422
423                <xsl:if test="$lastSegmentLayerCount">
424                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($lastSegmentFromNode/@lon))*10000*$scale)"/>
425                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($lastSegmentFromNode/@lat))*10000*$scale*$projection)"/>
426                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($lastSegmentToNode/@lon))*10000*$scale)"/>
427                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($lastSegmentToNode/@lat))*10000*$scale*$projection)"/>
428                    <xsl:call-template name="drawSegmentFragment">
429                        <xsl:with-param name="x1" select="number($x2)-((number($x2)-number($x1)) div 10)"/>
430                        <xsl:with-param name="y1" select="number($y2)-((number($y2)-number($y1)) div 10)"/>
431                        <xsl:with-param name="x2" select="$x2"/>
432                        <xsl:with-param name="y2" select="$y2"/>
433                    </xsl:call-template>
434                </xsl:if>
435            </xsl:if>
436
437            <!-- Now draw the way itself -->
438            <use xlink:href="#way_{$way/@id}">
439                <xsl:apply-templates select="$instruction/@*" mode="copyAttributes">
440                    <xsl:with-param name="classes" select="$classes"/>
441                </xsl:apply-templates>
442                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
443            </use>
444        </xsl:if>
445
446    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" name="drawTunnel">
447        <xsl:param name="instruction"/>
448        <xsl:param name="way"/>
449        <xsl:param name="layer"/>
450        <xsl:param name="classes"/>
451
452        <xsl:choose>
453            <xsl:when test="$instruction/@width &gt; 0">
454                <!-- wide tunnels use a dashed line as wide as the road casing with a mask as wide as the road core which will be
455                rendered as a double dotted line -->
456                <mask id="mask_{@id}" maskUnits="userSpaceOnUse">
457                    <use xlink:href="#way_{@id}" style="stroke:black;fill:none;" class="{$instruction/@class}-core"/>
458                    <rect x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px" style="fill:white;"/>
459                </mask>
460                <use xlink:href="#way_{$way/@id}" mask="url(#mask_{@id})" style="stroke-dasharray:0.2,0.2;" class="{$instruction/@class}-casing"/>
461                <use xlink:href="#way_{$way/@id}" class="tunnel-casing" style="stroke-width:{$instruction/@width}px;"/>
462            </xsl:when>
463            <xsl:otherwise>
464                <!-- narrow tunnels will use a single dotted line -->
465                <use xlink:href="#way_{$way/@id}">
466                    <xsl:apply-templates select="$instruction/@*" mode="copyAttributes">
467                        <xsl:with-param name="classes" select="$classes"/>
468                    </xsl:apply-templates>
469                </use>
470            </xsl:otherwise>
471        </xsl:choose>
472    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawCircle">
473        <xsl:param name="instruction"/>
474
475        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
476        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
477
478        <circle cx="{$x}" cy="{$y}">
479            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the svg attributes from the <circle> instruction -->
480        </circle>
481
482    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawSymbol">
483        <xsl:param name="instruction"/>
484
485        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
486        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
487
488        <g transform="translate({$x},{$y}) scale({$symbolScale})">
489            <use width="1" height="1">
490                <xsl:if test="$instruction/@ref">
491                    <xsl:attribute name="xlink:href">
492                        <xsl:value-of select="concat('#symbol-', $instruction/@ref)"/>
493                    </xsl:attribute>
494                </xsl:if>
495                <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the attributes from the <symbol> instruction -->
496            </use>
497        </g>
498    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="renderText">
499        <xsl:param name="instruction"/>
500
501        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
502        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
503
504        <text>
505            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
506            <xsl:attribute name="x"><xsl:value-of select="$x"/></xsl:attribute>
507            <xsl:attribute name="y"><xsl:value-of select="$y"/></xsl:attribute>
508            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
509            <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
510        </text>
511    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" name="renderTextPath">
512        <xsl:param name="instruction"/>
513        <xsl:param name="pathId"/>
514        <text>
515            <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-text"/>
516            <textPath xlink:href="#{$pathId}">
517                <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-textPath"/>
518                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
519                <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
520            </textPath>
521        </text>
522    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength|@k" mode="renderTextPath-text">
523    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-text">
524        <xsl:copy/>
525    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength" mode="renderTextPath-textPath">
526        <xsl:copy/>
527    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-textPath">
528    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" name="renderArea">
529        <xsl:param name="instruction"/>
530        <xsl:param name="pathId"/>
531
532        <use xlink:href="#{$pathId}">
533            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
534            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
535        </use>
536    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="getSvgAttributesFromOsmTags">
537        <xsl:for-each select="tag[contains(@k,&quot;svg:&quot;)]">
538            <xsl:attribute name="{substring-after(@k,&quot;svg:&quot;)}"><xsl:value-of select="@v"/></xsl:attribute>
539        </xsl:for-each>
540    </xsl:template>
541    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="drawUntaggedSegments">
542        <g id="segments" inkscape:groupmode="layer" inkscape:label="Segments">
543            <xsl:for-each select="$data/osm/segment[not(key('wayBySegment', @id))]">
544                <xsl:if test="not(tag[@key!='created_by'])">
545                    <xsl:variable name="fromNode" select="key('nodeById', @from)"/>
546                    <xsl:variable name="toNode" select="key('nodeById', @to)"/>
547                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
548                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
549                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
550                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
551                    <line class="untagged-segments" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
552                </xsl:if>
553            </xsl:for-each>
554        </g>
555    </xsl:template>
556    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="line">
557        <xsl:param name="elements"/>
558        <xsl:param name="layer"/>
559        <xsl:param name="classes"/>
560
561        <!-- This is the instruction that is currently being processed -->
562        <xsl:variable name="instruction" select="."/>
563
564        <g>
565            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
566                <xsl:with-param name="classes" select="$classes"/>
567            </xsl:apply-templates>
568
569            <!-- For each segment and way -->
570            <xsl:apply-templates select="$elements" mode="line">
571                <xsl:with-param name="instruction" select="$instruction"/>
572                <xsl:with-param name="layer" select="$layer"/>
573                <xsl:with-param name="classes" select="$classes"/>
574            </xsl:apply-templates>
575
576        </g>
577    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="*" mode="line"/><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="segment" mode="line">
578        <xsl:param name="instruction"/>
579        <xsl:param name="classes"/>
580
581        <xsl:call-template name="drawLine">
582            <xsl:with-param name="instruction" select="$instruction"/>
583            <xsl:with-param name="segment" select="."/>
584            <xsl:with-param name="classes" select="$classes"/>
585        </xsl:call-template>
586
587    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="line">
588        <xsl:param name="instruction"/>
589        <xsl:param name="layer"/>
590        <xsl:param name="classes"/>
591
592        <!-- The current <way> element -->
593        <xsl:variable name="way" select="."/>
594
595        <xsl:call-template name="drawWay">
596            <xsl:with-param name="instruction" select="$instruction"/>
597            <xsl:with-param name="way" select="$way"/>
598            <xsl:with-param name="layer" select="$layer"/>
599            <xsl:with-param name="classes" select="$classes"/>
600        </xsl:call-template>
601
602    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="tunnel">
603        <xsl:param name="elements"/>
604        <xsl:param name="layer"/>
605        <xsl:param name="classes"/>
606
607        <!-- This is the instruction that is currently being processed -->
608        <xsl:variable name="instruction" select="."/>
609
610        <g>
611            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <tunnel> instruction to the <g> element -->
612                <xsl:with-param name="classes" select="$classes"/>
613            </xsl:apply-templates>
614
615            <!-- For each segment and way -->
616            <xsl:apply-templates select="$elements" mode="tunnel">
617                <xsl:with-param name="instruction" select="$instruction"/>
618                <xsl:with-param name="layer" select="$layer"/>
619                <xsl:with-param name="classes" select="$classes"/>
620            </xsl:apply-templates>
621        </g>
622    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="tunnel">
623        <xsl:param name="instruction"/>
624        <xsl:param name="layer"/>
625        <xsl:param name="classes"/>
626
627        <!-- The current <way> element -->
628        <xsl:variable name="way" select="."/>
629
630        <xsl:call-template name="drawTunnel">
631            <xsl:with-param name="instruction" select="$instruction"/>
632            <xsl:with-param name="way" select="$way"/>
633            <xsl:with-param name="layer" select="$layer"/>
634            <xsl:with-param name="classes" select="$classes"/>
635        </xsl:call-template>
636
637    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="area">
638        <xsl:param name="elements"/>
639        <xsl:param name="classes"/>
640
641        <!-- This is the instruction that is currently being processed -->
642        <xsl:variable name="instruction" select="."/>
643
644        <g>
645            <xsl:apply-templates select="@*" mode="copyAttributes"/> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
646
647            <!-- For each segment and way -->
648            <xsl:apply-templates select="$elements" mode="area">
649                <xsl:with-param name="instruction" select="$instruction"/>
650            </xsl:apply-templates>
651        </g>
652    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="*" mode="area"/><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="area">
653        <xsl:param name="instruction"/>
654
655        <xsl:call-template name="generateAreaPath"/>
656
657        <xsl:call-template name="renderArea">
658            <xsl:with-param name="instruction" select="$instruction"/>
659            <xsl:with-param name="pathId" select="concat(&quot;area_&quot;,@id)"/>
660        </xsl:call-template>
661
662    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="circle">
663        <xsl:param name="elements"/>
664        <xsl:param name="classes"/>
665
666        <!-- This is the instruction that is currently being processed -->
667        <xsl:variable name="instruction" select="."/>
668
669        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
670            <xsl:call-template name="drawCircle">
671                <xsl:with-param name="instruction" select="$instruction"/>
672            </xsl:call-template>
673        </xsl:for-each>
674    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="symbol">
675        <xsl:param name="elements"/>
676        <xsl:param name="classes"/>
677
678        <!-- This is the instruction that is currently being processed -->
679        <xsl:variable name="instruction" select="."/>
680
681        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
682            <xsl:call-template name="drawSymbol">
683                <xsl:with-param name="instruction" select="$instruction"/>
684            </xsl:call-template>
685        </xsl:for-each>
686    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="text">
687        <xsl:param name="elements"/>
688        <xsl:param name="classes"/>
689
690        <!-- This is the instruction that is currently being processed -->
691        <xsl:variable name="instruction" select="."/>
692
693        <!-- Select all <node> elements that have a key that matches the k attribute of the text instruction -->
694        <xsl:for-each select="$elements[name()=&quot;node&quot;][tag[@k=$instruction/@k]]">
695                <xsl:call-template name="renderText">
696                    <xsl:with-param name="instruction" select="$instruction"/>
697                </xsl:call-template>
698        </xsl:for-each>
699
700        <!-- Select all <segment> and <way> elements that have a key that matches the k attribute of the text instruction -->
701        <xsl:apply-templates select="$elements[name()=&quot;segment&quot; or name()=&quot;way&quot;][tag[@k=$instruction/@k]]" mode="textPath">
702            <xsl:with-param name="instruction" select="$instruction"/>
703        </xsl:apply-templates>
704    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="*" mode="textPath"/><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="segment" mode="textPath">
705        <xsl:param name="instruction"/>
706
707        <!-- The current <segment> element -->
708        <xsl:variable name="segment" select="."/>
709
710        <!-- Generate the path for the segment -->
711        <!-- Text on segments should be relatively uncommon so only generate a <path> when one is needed -->
712        <xsl:call-template name="generateSegmentPath"/>
713
714        <xsl:call-template name="renderTextPath">
715            <xsl:with-param name="instruction" select="$instruction"/>
716            <xsl:with-param name="pathId" select="concat(&quot;segment_&quot;,@id)"/>
717        </xsl:call-template>
718
719    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="textPath">
720        <xsl:param name="instruction"/>
721
722        <!-- The current <way> element -->
723        <xsl:variable name="way" select="."/>
724
725        <xsl:call-template name="renderTextPath">
726            <xsl:with-param name="instruction" select="$instruction"/>
727            <xsl:with-param name="pathId" select="concat(&quot;way_&quot;,@id,&quot;t&quot;)"/>
728        </xsl:call-template>
729
730    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateSegmentPath">
731        <xsl:variable name="pathData">
732            <xsl:choose>
733                                <!-- Manual override -->
734                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;-1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;-1&quot;">
735                    <xsl:call-template name="segmentMoveToEnd"/>
736                    <xsl:call-template name="segmentLineToStart"/>
737                </xsl:when>
738                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;1&quot;">
739                    <xsl:call-template name="segmentMoveToStart"/>
740                    <xsl:call-template name="segmentLineToEnd"/>
741                </xsl:when>
742                <!-- Automatic direction -->
743                <xsl:when test="(key(&quot;nodeById&quot;,@from)/@lon &gt; key(&quot;nodeById&quot;,@to)/@lon)">
744                    <xsl:call-template name="segmentMoveToEnd"/>
745                    <xsl:call-template name="segmentLineToStart"/>
746                </xsl:when>
747                <xsl:otherwise>
748                    <xsl:call-template name="segmentMoveToStart"/>
749                    <xsl:call-template name="segmentLineToEnd"/>
750                </xsl:otherwise>
751            </xsl:choose>
752        </xsl:variable>
753
754        <path id="segment_{@id}" d="{$pathData}"/>
755
756    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateWayPath">
757
758        <!-- Generate the path for the way that will be used by the street
759        name rendering. This is horribly inefficient, because we will later
760        also have the path used for the rendering of the path itself. So
761        each path is twice in the SVG file. But this path here needs to
762        have the right direction for the names to render right way up
763        and the other path needs to be the right direction for rendering
764        the oneway arrows. This can probably be done better, but currently
765        I don't know how. -->
766        <xsl:variable name="pathData">
767            <xsl:choose>
768                                <!-- Manual override, reverse direction -->
769                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;-1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;-1&quot;">
770                                        <xsl:call-template name="generateWayPathReverse"/>
771                </xsl:when>
772                                <!-- Manual override, normal direction -->
773                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;1&quot;">
774                                        <xsl:call-template name="generateWayPathNormal"/>
775                </xsl:when>
776                                <!-- Automatic, reverse direction -->
777                <xsl:when test="(key(&quot;nodeById&quot;,key(&quot;segmentById&quot;,seg[1]/@id)/@from)/@lon &gt; key(&quot;nodeById&quot;,key(&quot;segmentById&quot;,seg[last()]/@id)/@to)/@lon)">
778                                        <xsl:call-template name="generateWayPathReverse"/>
779                </xsl:when>
780                                <!-- Automatic, normal direction -->
781                <xsl:otherwise>
782                                        <xsl:call-template name="generateWayPathNormal"/>
783                </xsl:otherwise>
784            </xsl:choose>
785        </xsl:variable>
786
787        <path id="way_{@id}t" d="{$pathData}"/>
788
789        <!-- Generate the path for the way itself. Used for rendering the
790        way and, possibly, oneway arrows. -->
791        <xsl:variable name="pathDataFixed">
792                        <xsl:call-template name="generateWayPathNormal"/>
793        </xsl:variable>
794
795        <path id="way_{@id}" d="{$pathDataFixed}"/>
796
797    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="generateWayPathNormal">
798                <xsl:choose>
799                        <xsl:when test="$bFrollo">                     
800                                <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
801                                    <xsl:variable name="segmentId" select="@id"/>
802                                        <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
803                                        <xsl:variable name="bSubPath" select="(position()=1) or (@osma:sub-path=&quot;1&quot;)"/>
804                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
805                                                <xsl:choose>
806                                                        <xsl:when test="$bReverseSeg">
807                                                                <xsl:if test="$bSubPath">
808                                                                    <xsl:call-template name="segmentMoveToEnd"/>
809                                                                </xsl:if>
810                                                                <xsl:call-template name="segmentLineToStart"/>
811                                                        </xsl:when>
812                                                        <xsl:otherwise>
813                                                                <xsl:if test="$bSubPath">
814                                                                    <xsl:call-template name="segmentMoveToStart"/>
815                                                                </xsl:if>
816                                                                <xsl:call-template name="segmentLineToEnd"/>
817                                                        </xsl:otherwise>                               
818                                                </xsl:choose>
819                                    </xsl:for-each>
820                                </xsl:for-each>                         
821                        </xsl:when>
822                        <xsl:otherwise> <!-- Not pre-processed by frollo -->
823                            <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
824                                        <xsl:variable name="segmentId" select="@id"/>
825                                        <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,@id)/@from=key(&quot;segmentById&quot;,preceding-sibling::seg[1]/@id)/@to"/>
826                                        <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
827                                                <xsl:if test="not($linkedSegment)">
828                                                        <xsl:call-template name="segmentMoveToStart"/>
829                                                </xsl:if>
830                                                <xsl:call-template name="segmentLineToEnd"/>
831                                        </xsl:for-each>
832                                </xsl:for-each>
833                        </xsl:otherwise>               
834                </xsl:choose>
835    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="generateWayPathReverse">
836                <xsl:choose>
837                        <xsl:when test="$bFrollo">                     
838                                <xsl:for-each select="seg">
839                                    <xsl:sort select="position()" data-type="number" order="descending"/>
840                                    <xsl:variable name="segmentId" select="@id"/>
841                                        <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
842                                        <xsl:variable name="bSubPath" select="(position()=1) or (preceding-sibling::seg/@osma:sub-path=&quot;1&quot;)"/>
843                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
844                                                <xsl:choose>
845                                                        <xsl:when test="$bReverseSeg">
846                                                                <xsl:if test="$bSubPath">
847                                                                    <xsl:call-template name="segmentMoveToStart"/>
848                                                                </xsl:if>
849                                                                <xsl:call-template name="segmentLineToEnd"/>
850                                                        </xsl:when>
851                                                        <xsl:otherwise>
852                                                                <xsl:if test="$bSubPath">
853                                                                    <xsl:call-template name="segmentMoveToEnd"/>
854                                                                </xsl:if>
855                                                                <xsl:call-template name="segmentLineToStart"/>
856                                                        </xsl:otherwise>                               
857                                                </xsl:choose>
858                                    </xsl:for-each>
859                                </xsl:for-each>   
860                        </xsl:when>
861                        <xsl:otherwise> <!-- Not pre-processed by frollo -->
862                                <xsl:for-each select="seg">
863                                    <xsl:sort select="position()" data-type="number" order="descending"/>
864                                    <xsl:variable name="segmentId" select="@id"/>
865                                    <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,following-sibling::seg[1]/@id)/@from=key(&quot;segmentById&quot;,@id)/@to"/>
866                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
867                                                <xsl:if test="not($linkedSegment)">
868                                                        <xsl:call-template name="segmentMoveToStart"/>
869                                                </xsl:if>
870                                                <xsl:call-template name="segmentLineToEnd"/>
871                                    </xsl:for-each>
872                                </xsl:for-each> 
873                        </xsl:otherwise>
874                </xsl:choose>
875    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateAreaPath">
876
877                <!-- Generate the path for the area -->
878                <xsl:variable name="pathData">
879                        <xsl:choose>
880                                <xsl:when test="$bFrollo">                     
881                                        <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
882                                                <xsl:variable name="segmentId" select="@id"/>
883                                                <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
884                                                <xsl:variable name="bSubPath" select="@osma:sub-path=&quot;1&quot;"/>                                           
885                                                <xsl:variable name="fromCount" select="@osma:fromCount"/>                                               
886                                                <xsl:variable name="segmentSequence" select="position()"/>
887                                                <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
888                                                        <xsl:choose>
889                                                                <xsl:when test="not($bReverseSeg)">
890                                                                        <xsl:choose>
891                                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
892                                                                                <xsl:when test="$segmentSequence=1">
893                                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
894                                                                                </xsl:when>
895                                                                               
896                                                                                <!-- If the segment is connected to another segment (at the from end) and is the start of a new
897                                                                                         sub-path then start a new sub-path -->
898                                                                                <xsl:when test="$fromCount&gt;0 and $bSubPath">
899                                                                                        <xsl:text>Z</xsl:text>
900                                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
901                                                                                </xsl:when>
902                                                                               
903                                                                                <!-- If the segment is the start of a new sub-path, but is not connected to any previous
904                                                                                     segment then draw an artificial line.  Typically this happens when a tile boundary chops
905                                                                                     through the middle of an area or a river is segmented into manageable chunks. -->
906                                                                                <xsl:otherwise>
907                                                                                        <xsl:call-template name="segmentLineToStart"/>
908                                                                                </xsl:otherwise>
909                                                                        </xsl:choose>
910                                                                        <xsl:call-template name="segmentLineToEnd"/>                                                           
911                                                                </xsl:when>
912                                                                <xsl:otherwise>
913                                                                        <xsl:choose>
914                                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
915                                                                                <xsl:when test="$segmentSequence=1">
916                                                                                        <xsl:call-template name="segmentMoveToEnd"/>                           
917                                                                                </xsl:when>
918                                                                               
919                                                                                <!-- If the segment is connected to another segment (at the from end) and is the start of a new
920                                                                                         sub-path then start a new sub-path -->
921                                                                                <xsl:when test="$fromCount&gt;0 and $bSubPath">
922                                                                                        <xsl:text>Z</xsl:text>
923                                                                                        <xsl:call-template name="segmentMoveToEnd"/>                           
924                                                                                </xsl:when>
925                                                                               
926                                                                                <!-- If the segment is the start of a new sub-path, but is not connected to any previous
927                                                                                     segment then draw an artificial line.  Typically this happens when a tile boundary chops
928                                                                                     through the middle of an area or a river is segmented into manageable chunks. -->
929                                                                                <xsl:otherwise>
930                                                                                        <xsl:call-template name="segmentLineToEnd"/>
931                                                                                </xsl:otherwise>
932                                                                        </xsl:choose>
933                                                                        <xsl:call-template name="segmentLineToStart"/>
934                                                                </xsl:otherwise>
935                                                        </xsl:choose>
936                                                </xsl:for-each>
937                                        </xsl:for-each>
938                                        <xsl:text>Z</xsl:text>
939                                </xsl:when>
940                                <xsl:otherwise> <!-- Not pre-processed by frollo -->
941                                        <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
942                                                <xsl:variable name="segmentId" select="@id"/>
943                                                <xsl:variable name="currentSegmentToNodeId" select="key(&quot;segmentById&quot;,@id)/@to"/>
944                                                <xsl:variable name="currentSegmentFromNodeId" select="key(&quot;segmentById&quot;,@id)/@from"/>
945                                                <xsl:variable name="previousSegmentToNodeId" select="key(&quot;segmentById&quot;,preceding-sibling::seg[1]/@id)/@to"/>
946                                               
947                                                <!-- The linkedSegment flag indicates whether the previous segment is connected to the current segment.  If it isn't
948                                                     then we will need to draw an additional line (segmentLineToStart) from the end of the previous segment to the
949                                                     start of the current segment.
950                                                -->
951                                                <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,@id)/@from=$previousSegmentToNodeId"/>
952               
953                                                <!--  Now we count the number of segments in this way that have a to node that is equal to the current segment's from node.
954                                                      We do this to find out if the current segment is connected from some other segment in the way.  If it is, and it
955                                                      is not linked to the current segment then we can assume we have the start of a new sub-path.  In this case we shouldn't
956                                                      draw an additional line between the end of the previous segment and the start of the current segment.
957                                                -->
958                                                <xsl:variable name="connectedSegmentCount" select="count(../*[key(&quot;segmentById&quot;,@id)/@to=$currentSegmentFromNodeId])"/>
959                                               
960                                                <xsl:variable name="segmentSequence" select="position()"/>
961                                                <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
962                                                        <xsl:choose>
963                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
964                                                                <xsl:when test="$segmentSequence=1">
965                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
966                                                                </xsl:when>
967                                                                <!-- If the segment is "connected" to another segment (at the from end) but is not linked to the
968                                                                         previous segment, then start a new sub-path -->
969                                                                <xsl:when test="$connectedSegmentCount&gt;0 and not($linkedSegment)">
970                                                                        <xsl:text>Z</xsl:text>
971                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
972                                                                </xsl:when>
973                                                                <!-- If the previous segment is not linked to this one we need to draw an artificial line -->
974                                                                <xsl:when test="not($linkedSegment)">
975                                                                        <xsl:call-template name="segmentLineToStart"/>                         
976                                                                </xsl:when>
977                                                        </xsl:choose>
978                                                        <xsl:call-template name="segmentLineToEnd"/>
979                                                </xsl:for-each>
980                                        </xsl:for-each>
981                                        <xsl:text>Z</xsl:text> 
982                                </xsl:otherwise>
983                        </xsl:choose>
984                </xsl:variable>
985
986                <path id="area_{@id}" d="{$pathData}"/>
987
988        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToStart">
989        <xsl:variable name="from" select="@from"/>
990        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
991
992        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
993        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
994        <xsl:text>M</xsl:text>
995        <xsl:value-of select="$x1"/>
996        <xsl:text> </xsl:text>
997        <xsl:value-of select="$y1"/>
998    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToStart">
999        <xsl:variable name="from" select="@from"/>
1000        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
1001
1002        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
1003        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
1004        <xsl:text>L</xsl:text>
1005        <xsl:value-of select="$x1"/>
1006        <xsl:text> </xsl:text>
1007        <xsl:value-of select="$y1"/>
1008    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToEnd">
1009        <xsl:variable name="to" select="@to"/>
1010        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
1011
1012        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
1013        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
1014        <xsl:text>M</xsl:text>
1015        <xsl:value-of select="$x2"/>
1016        <xsl:text> </xsl:text>
1017        <xsl:value-of select="$y2"/>
1018    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToEnd">
1019        <xsl:variable name="to" select="@to"/>
1020        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
1021
1022        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
1023        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
1024        <xsl:text>L</xsl:text>
1025        <xsl:value-of select="$x2"/>
1026        <xsl:text> </xsl:text>
1027        <xsl:value-of select="$y2"/>
1028    </xsl:template>
1029    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@class" mode="copyAttributes">
1030        <xsl:param name="classes"/>
1031        <xsl:attribute name="class">
1032            <xsl:value-of select="normalize-space(concat($classes,' ',.))"/>
1033        </xsl:attribute>
1034    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@type|@ref|@scale" mode="copyAttributes">
1035    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="copyAttributes">
1036        <xsl:param name="classes"/>
1037        <xsl:copy/>
1038    </xsl:template>
1039
1040    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processRules">
1041     
1042        <xsl:choose>
1043
1044            <!-- Process all the rules, one layer at a time -->
1045            <xsl:when test="$withOSMLayers='yes'">
1046                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-5&quot;"/></xsl:call-template>
1047                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-4&quot;"/></xsl:call-template>
1048                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-3&quot;"/></xsl:call-template>
1049                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-2&quot;"/></xsl:call-template>
1050                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-1&quot;"/></xsl:call-template>
1051                <xsl:call-template name="processLayer">
1052                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
1053                    <xsl:with-param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;) and count(tag[@k=&quot;layer&quot;])=0 or tag[@k=&quot;layer&quot; and @v=&quot;0&quot;]]"/>
1054                </xsl:call-template>
1055                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;1&quot;"/></xsl:call-template>
1056                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;2&quot;"/></xsl:call-template>
1057                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;3&quot;"/></xsl:call-template>
1058                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;4&quot;"/></xsl:call-template>
1059                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;5&quot;"/></xsl:call-template>
1060            </xsl:when>
1061
1062            <!-- Process all the rules, without looking at the layers -->
1063            <xsl:otherwise>
1064                <xsl:apply-templates select="/rules/rule">
1065                    <xsl:with-param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;)]"/>
1066                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
1067                    <xsl:with-param name="classes" select="''"/>
1068                </xsl:apply-templates>
1069            </xsl:otherwise>
1070
1071        </xsl:choose>
1072        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="processLayer">
1073        <xsl:param name="layer"/>
1074        <xsl:param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;) and tag[@k=&quot;layer&quot; and @v=$layer]]"/>
1075
1076        <g inkscape:groupmode="layer" id="layer{$layer}" inkscape:label="Layer {$layer}">
1077            <xsl:apply-templates select="/rules/rule">
1078                <xsl:with-param name="elements" select="$elements"/>
1079                <xsl:with-param name="layer" select="$layer"/>
1080                <xsl:with-param name="classes" select="''"/>
1081            </xsl:apply-templates>
1082        </g>
1083    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="rule">
1084        <xsl:param name="elements"/>
1085        <xsl:param name="layer"/>
1086        <xsl:param name="classes"/>
1087
1088        <!-- This is the rule currently being processed -->
1089        <xsl:variable name="rule" select="."/>
1090
1091        <!-- Make list of elements that this rule should be applied to -->
1092        <xsl:variable name="eBare">
1093            <xsl:choose>
1094                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
1095                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
1096                <xsl:otherwise>node|segment|way</xsl:otherwise>
1097            </xsl:choose>
1098        </xsl:variable>
1099
1100        <!-- List of keys that this rule should be applied to -->
1101        <xsl:variable name="kBare" select="$rule/@k"/>
1102
1103        <!-- List of values that this rule should be applied to -->
1104        <xsl:variable name="vBare" select="$rule/@v"/>
1105
1106        <!-- Top'n'tail selectors with | for contains usage -->
1107        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
1108        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
1109        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
1110
1111        <xsl:variable name="selectedElements" select="$elements[contains($e,concat(&quot;|&quot;,name(),&quot;|&quot;))or (contains($e,&quot;|waysegment|&quot;) and name()=&quot;segment&quot; and key(&quot;wayBySegment&quot;,@id))]"/>
1112
1113        <xsl:choose>
1114            <xsl:when test="contains($k,&quot;|*|&quot;)">
1115                <xsl:choose>
1116                    <xsl:when test="contains($v,&quot;|~|&quot;)">
1117                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
1118                        <xsl:call-template name="processElements">
1119                            <xsl:with-param name="eBare" select="$eBare"/>
1120                            <xsl:with-param name="kBare" select="$kBare"/>
1121                            <xsl:with-param name="vBare" select="$vBare"/>
1122                            <xsl:with-param name="layer" select="$layer"/>
1123                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
1124                            <xsl:with-param name="rule" select="$rule"/>
1125                            <xsl:with-param name="classes" select="$classes"/>
1126                        </xsl:call-template>
1127                    </xsl:when>
1128                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1129                        <xsl:variable name="allElements" select="$selectedElements"/>
1130                        <xsl:call-template name="processElements">
1131                            <xsl:with-param name="eBare" select="$eBare"/>
1132                            <xsl:with-param name="kBare" select="$kBare"/>
1133                            <xsl:with-param name="vBare" select="$vBare"/>
1134                            <xsl:with-param name="layer" select="$layer"/>
1135                            <xsl:with-param name="elements" select="$allElements"/>
1136                            <xsl:with-param name="rule" select="$rule"/>
1137                            <xsl:with-param name="classes" select="$classes"/>
1138                        </xsl:call-template>
1139                    </xsl:when>
1140                    <xsl:otherwise>
1141                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1142                        <xsl:call-template name="processElements">
1143                            <xsl:with-param name="eBare" select="$eBare"/>
1144                            <xsl:with-param name="kBare" select="$kBare"/>
1145                            <xsl:with-param name="vBare" select="$vBare"/>
1146                            <xsl:with-param name="layer" select="$layer"/>
1147                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1148                            <xsl:with-param name="rule" select="$rule"/>
1149                            <xsl:with-param name="classes" select="$classes"/>
1150                        </xsl:call-template>
1151                    </xsl:otherwise>
1152                </xsl:choose>
1153            </xsl:when>
1154            <xsl:when test="contains($v,&quot;|~|&quot;)">
1155                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1156                <xsl:call-template name="processElements">
1157                    <xsl:with-param name="eBare" select="$eBare"/>
1158                    <xsl:with-param name="kBare" select="$kBare"/>
1159                    <xsl:with-param name="vBare" select="$vBare"/>
1160                    <xsl:with-param name="layer" select="$layer"/>
1161                    <xsl:with-param name="elements" select="$elementsWithoutKey"/>
1162                    <xsl:with-param name="rule" select="$rule"/>
1163                    <xsl:with-param name="classes" select="$classes"/>
1164                </xsl:call-template>
1165            </xsl:when>
1166            <xsl:when test="contains($v,&quot;|*|&quot;)">
1167                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1168                <xsl:call-template name="processElements">
1169                    <xsl:with-param name="eBare" select="$eBare"/>
1170                    <xsl:with-param name="kBare" select="$kBare"/>
1171                    <xsl:with-param name="vBare" select="$vBare"/>
1172                    <xsl:with-param name="layer" select="$layer"/>
1173                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1174                    <xsl:with-param name="rule" select="$rule"/>
1175                    <xsl:with-param name="classes" select="$classes"/>
1176                </xsl:call-template>
1177            </xsl:when>
1178            <xsl:otherwise>
1179                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1180                <xsl:call-template name="processElements">
1181                    <xsl:with-param name="eBare" select="$eBare"/>
1182                    <xsl:with-param name="kBare" select="$kBare"/>
1183                    <xsl:with-param name="vBare" select="$vBare"/>
1184                    <xsl:with-param name="layer" select="$layer"/>
1185                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1186                    <xsl:with-param name="rule" select="$rule"/>
1187                    <xsl:with-param name="classes" select="$classes"/>
1188                </xsl:call-template>
1189            </xsl:otherwise>
1190        </xsl:choose>
1191    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElements">
1192        <xsl:param name="eBare"/>
1193        <xsl:param name="kBare"/>
1194        <xsl:param name="vBare"/>
1195        <xsl:param name="layer"/>
1196        <xsl:param name="elements"/>
1197        <xsl:param name="rule"/>
1198        <xsl:param name="classes"/>
1199       
1200        <xsl:if test="$elements">
1201            <xsl:message>
1202Processing &lt;rule e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1203Matched by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1204            </xsl:message>
1205
1206            <xsl:apply-templates select="*">
1207                <xsl:with-param name="layer" select="$layer"/>
1208                <xsl:with-param name="elements" select="$elements"/>
1209                <xsl:with-param name="rule" select="$rule"/>
1210                <xsl:with-param name="classes" select="$classes"/>
1211            </xsl:apply-templates>
1212        </xsl:if>
1213    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="addclass">
1214        <xsl:param name="elements"/>
1215        <xsl:param name="layer"/>
1216        <xsl:param name="classes"/>
1217
1218        <!-- This is the rule currently being processed -->
1219        <xsl:variable name="rule" select="."/>
1220
1221        <!-- Additional classes from class attribute of this rule -->
1222        <xsl:variable name="addclasses" select="@class"/>
1223
1224        <!-- Make list of elements that this rule should be applied to -->
1225        <xsl:variable name="eBare">
1226            <xsl:choose>
1227                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
1228                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
1229                <xsl:otherwise>node|segment|way</xsl:otherwise>
1230            </xsl:choose>
1231        </xsl:variable>
1232
1233        <!-- List of keys that this rule should be applied to -->
1234        <xsl:variable name="kBare" select="$rule/@k"/>
1235
1236        <!-- List of values that this rule should be applied to -->
1237        <xsl:variable name="vBare" select="$rule/@v"/>
1238
1239        <!-- Top'n'tail selectors with | for contains usage -->
1240        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
1241        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
1242        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
1243
1244        <xsl:variable name="selectedElements" select="$elements[contains($e,concat(&quot;|&quot;,name(),&quot;|&quot;))or (contains($e,&quot;|waysegment|&quot;) and name()=&quot;segment&quot; and key(&quot;wayBySegment&quot;,@id))]"/>
1245
1246        <xsl:choose>
1247            <xsl:when test="contains($k,&quot;|*|&quot;)">
1248                <xsl:choose>
1249                    <xsl:when test="contains($v,&quot;|~|&quot;)">
1250                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
1251                        <xsl:call-template name="processElementsForAddClass">
1252                            <xsl:with-param name="eBare" select="$eBare"/>
1253                            <xsl:with-param name="kBare" select="$kBare"/>
1254                            <xsl:with-param name="vBare" select="$vBare"/>
1255                            <xsl:with-param name="layer" select="$layer"/>
1256                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
1257                            <xsl:with-param name="rule" select="$rule"/>
1258                            <xsl:with-param name="classes" select="$classes"/>
1259                            <xsl:with-param name="addclasses" select="$addclasses"/>
1260                            <xsl:with-param name="allelements" select="$elements"/>
1261                        </xsl:call-template>
1262                    </xsl:when>
1263                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1264                        <xsl:variable name="allElements" select="$selectedElements"/>
1265                        <xsl:call-template name="processElementsForAddClass">
1266                            <xsl:with-param name="eBare" select="$eBare"/>
1267                            <xsl:with-param name="kBare" select="$kBare"/>
1268                            <xsl:with-param name="vBare" select="$vBare"/>
1269                            <xsl:with-param name="layer" select="$layer"/>
1270                            <xsl:with-param name="elements" select="$allElements"/>
1271                            <xsl:with-param name="rule" select="$rule"/>
1272                            <xsl:with-param name="classes" select="$classes"/>
1273                            <xsl:with-param name="addclasses" select="$addclasses"/>
1274                            <xsl:with-param name="allelements" select="$elements"/>
1275                        </xsl:call-template>
1276                    </xsl:when>
1277                    <xsl:otherwise>
1278                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1279                        <xsl:call-template name="processElementsForAddClass">
1280                            <xsl:with-param name="eBare" select="$eBare"/>
1281                            <xsl:with-param name="kBare" select="$kBare"/>
1282                            <xsl:with-param name="vBare" select="$vBare"/>
1283                            <xsl:with-param name="layer" select="$layer"/>
1284                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1285                            <xsl:with-param name="rule" select="$rule"/>
1286                            <xsl:with-param name="classes" select="$classes"/>
1287                            <xsl:with-param name="addclasses" select="$addclasses"/>
1288                            <xsl:with-param name="allelements" select="$elements"/>
1289                        </xsl:call-template>
1290                    </xsl:otherwise>
1291                </xsl:choose>
1292            </xsl:when>
1293            <xsl:when test="contains($v,&quot;|~|&quot;)">
1294                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1295                <xsl:call-template name="processElementsForAddClass">
1296                    <xsl:with-param name="eBare" select="$eBare"/>
1297                    <xsl:with-param name="kBare" select="$kBare"/>
1298                    <xsl:with-param name="vBare" select="$vBare"/>
1299                    <xsl:with-param name="layer" select="$layer"/>
1300                    <xsl:with-param name="elements" select="$elementsWithoutKey"/>
1301                    <xsl:with-param name="rule" select="$rule"/>
1302                    <xsl:with-param name="classes" select="$classes"/>
1303                    <xsl:with-param name="addclasses" select="$addclasses"/>
1304                    <xsl:with-param name="allelements" select="$elements"/>
1305                </xsl:call-template>
1306            </xsl:when>
1307            <xsl:when test="contains($v,&quot;|*|&quot;)">
1308                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1309                <xsl:call-template name="processElementsForAddClass">
1310                    <xsl:with-param name="eBare" select="$eBare"/>
1311                    <xsl:with-param name="kBare" select="$kBare"/>
1312                    <xsl:with-param name="vBare" select="$vBare"/>
1313                    <xsl:with-param name="layer" select="$layer"/>
1314                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1315                    <xsl:with-param name="rule" select="$rule"/>
1316                    <xsl:with-param name="classes" select="$classes"/>
1317                    <xsl:with-param name="addclasses" select="$addclasses"/>
1318                    <xsl:with-param name="allelements" select="$elements"/>
1319                </xsl:call-template>
1320            </xsl:when>
1321            <xsl:otherwise>
1322                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1323                <xsl:call-template name="processElementsForAddClass">
1324                    <xsl:with-param name="eBare" select="$eBare"/>
1325                    <xsl:with-param name="kBare" select="$kBare"/>
1326                    <xsl:with-param name="vBare" select="$vBare"/>
1327                    <xsl:with-param name="layer" select="$layer"/>
1328                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1329                    <xsl:with-param name="rule" select="$rule"/>
1330                    <xsl:with-param name="classes" select="$classes"/>
1331                    <xsl:with-param name="addclasses" select="$addclasses"/>
1332                    <xsl:with-param name="allelements" select="$elements"/>
1333                </xsl:call-template>
1334            </xsl:otherwise>
1335        </xsl:choose>
1336    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElementsForAddClass">
1337        <xsl:param name="eBare"/>
1338        <xsl:param name="kBare"/>
1339        <xsl:param name="vBare"/>
1340        <xsl:param name="layer"/>
1341        <xsl:param name="elements"/>
1342        <xsl:param name="allelements"/>
1343        <xsl:param name="rule"/>
1344        <xsl:param name="classes"/>
1345        <xsl:param name="addclasses"/>
1346       
1347        <xsl:variable name="newclasses" select="concat($classes,' ',$addclasses)"/>
1348        <xsl:variable name="otherelements" select="set:difference($allelements, $elements)"/>
1349
1350        <xsl:if test="$elements">
1351            <xsl:message>
1352Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1353Positive match by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1354            </xsl:message>
1355
1356            <xsl:apply-templates select="*">
1357                <xsl:with-param name="layer" select="$layer"/>
1358                <xsl:with-param name="elements" select="$elements"/>
1359                <xsl:with-param name="rule" select="$rule"/>
1360                <xsl:with-param name="classes" select="$newclasses"/>
1361            </xsl:apply-templates>
1362        </xsl:if>
1363
1364        <xsl:if test="$otherelements">
1365            <xsl:message>
1366Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1367Negative match by <xsl:value-of select="count($otherelements)"/> elements for layer <xsl:value-of select="$layer"/>.
1368            </xsl:message>
1369            <xsl:apply-templates select="*">
1370                <xsl:with-param name="layer" select="$layer"/>
1371                <xsl:with-param name="elements" select="$otherelements"/>
1372                <xsl:with-param name="rule" select="$rule"/>
1373                <xsl:with-param name="classes" select="$classes"/>
1374            </xsl:apply-templates>
1375        </xsl:if>
1376    </xsl:template>
1377    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" match="layer">
1378        <xsl:param name="elements"/>
1379        <xsl:param name="layer"/>
1380        <xsl:param name="rule"/>
1381        <xsl:param name="classes"/>
1382
1383        <xsl:message>Processing SVG layer: <xsl:value-of select="@name"/> (at OSM layer <xsl:value-of select="$layer"/>)
1384</xsl:message>
1385
1386        <xsl:variable name="opacity">
1387            <xsl:if test="@opacity">
1388                <xsl:value-of select="concat('opacity:',@opacity,';')"/>
1389            </xsl:if>
1390        </xsl:variable>
1391
1392        <xsl:variable name="display">
1393            <xsl:if test="(@display='none') or (@display='off')">
1394                <xsl:text>display:none;</xsl:text>
1395            </xsl:if>
1396        </xsl:variable>
1397
1398        <g inkscape:groupmode="layer" id="{@name}-{$layer}" inkscape:label="{@name}">
1399            <xsl:if test="concat($opacity,$display)!=''">
1400                <xsl:attribute name="style">
1401                    <xsl:value-of select="concat($opacity,$display)"/>
1402                </xsl:attribute>
1403            </xsl:if>
1404            <xsl:apply-templates select="*">
1405                <xsl:with-param name="layer" select="$layer"/>
1406                <xsl:with-param name="elements" select="$elements"/>
1407                <xsl:with-param name="classes" select="$classes"/>
1408            </xsl:apply-templates>
1409        </g>
1410
1411    </xsl:template>
1412   
1413    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="borderDraw">
1414        <!-- dasharray definitions here can be overridden in stylesheet -->
1415        <g id="border" inkscape:groupmode="layer" inkscape:label="Map Border">
1416            <line id="border-left-casing" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1417            <line id="border-top-casing" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1418            <line id="border-bottom-casing" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1419            <line id="border-right-casing" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1420
1421            <line id="border-left-core" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1422            <line id="border-top-core" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1423            <line id="border-bottom-core" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1424            <line id="border-right-core" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1425        </g>
1426    </xsl:template>
1427    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="gridDraw">
1428        <g id="grid" inkscape:groupmode="layer" inkscape:label="Grid">
1429            <xsl:call-template name="gridDrawHorizontals">
1430                <xsl:with-param name="line" select="&quot;1&quot;"/>
1431            </xsl:call-template>
1432            <xsl:call-template name="gridDrawVerticals">
1433                <xsl:with-param name="line" select="&quot;1&quot;"/>
1434            </xsl:call-template>
1435        </g>
1436    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawHorizontals">
1437        <xsl:param name="line"/>
1438        <xsl:if test="($line*$km) &lt; $documentHeight">
1439            <line id="grid-hori-{$line}" x1="0px" y1="{$line*$km}px" x2="{$documentWidth}px" y2="{$line*$km}px" class="map-grid-line"/>
1440            <xsl:call-template name="gridDrawHorizontals">
1441                <xsl:with-param name="line" select="$line+1"/>
1442            </xsl:call-template>
1443        </xsl:if>
1444    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawVerticals">
1445        <xsl:param name="line"/>
1446        <xsl:if test="($line*$km) &lt; $documentWidth">
1447            <line id="grid-vert-{$line}" x1="{$line*$km}px" y1="0px" x2="{$line*$km}px" y2="{$documentHeight}px" class="map-grid-line"/>
1448            <xsl:call-template name="gridDrawVerticals">
1449                <xsl:with-param name="line" select="$line+1"/>
1450            </xsl:call-template>
1451        </xsl:if>
1452    </xsl:template>
1453
1454    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="titleDraw">
1455        <xsl:param name="title"/>
1456
1457        <xsl:variable name="x" select="$documentWidth div 2"/>
1458        <xsl:variable name="y" select="30"/>
1459
1460        <g id="marginalia-title" inkscape:groupmode="layer" inkscape:label="Title">
1461            <rect id="marginalia-title-background" x="0px" y="0px" height="{$marginaliaTopHeight - 5}px" width="{$documentWidth}px" class="map-title-background"/>
1462            <text id="marginalia-title-text" class="map-title" x="{$x}" y="{$y}"><xsl:value-of select="$title"/></text>
1463        </g>
1464    </xsl:template>
1465    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="scaleDraw">
1466        <xsl:variable name="x1" select="14"/>
1467        <xsl:variable name="y1" select="round(($documentHeight)+((($bottomLeftLatitude)-(number($bottomLeftLatitude)))*10000*$scale*$projection))+28"/>
1468        <xsl:variable name="x2" select="$x1+$km"/>
1469        <xsl:variable name="y2" select="$y1"/>
1470
1471        <g id="marginalia-scale" inkscape:groupmode="layer" inkscape:label="Scale">
1472            <line id="marginalia-scale-casing" class="map-scale-casing" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1473
1474            <line id="marginalia-scale-core" class="map-scale-core" stroke-dasharray="{($km div 10)}" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1475
1476            <line id="marginalia-scale-bookend-from" class="map-scale-bookend" x1="{$x1}" y1="{$y1 + 2}" x2="{$x1}" y2="{$y1 - 10}"/>
1477
1478            <line id="marginalia-scale-bookend-to" class="map-scale-bookend" x1="{$x2}" y1="{$y2 + 2}" x2="{$x2}" y2="{$y2 - 10}"/>
1479
1480            <text id="marginalia-scale-text-from" class="map-scale-caption" x="{$x1}" y="{$y1 - 10}">0</text>
1481
1482            <text id="marginalia-scale-text-to" class="map-scale-caption" x="{$x2}" y="{$y2 - 10}">1km</text>
1483        </g>
1484    </xsl:template>
1485    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" name="metadata">
1486        <xsl:variable name="date" select="date:date()"/>
1487        <xsl:variable name="year" select="date:year()"/>
1488
1489        <xsl:comment>
1490
1491    Copyright (c) <xsl:value-of select="$year"/> OpenStreetMap
1492    www.openstreetmap.org
1493    This work is licensed under the
1494    Creative Commons Attribution-ShareAlike 2.0 License.
1495    http://creativecommons.org/licenses/by-sa/2.0/
1496
1497</xsl:comment>
1498        <metadata id="metadata">
1499            <rdf:RDF xmlns="http://web.resource.org/cc/">
1500                <cc:Work rdf:about="">
1501                    <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
1502                    <dc:format>image/svg+xml</dc:format>
1503                    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
1504                    <dc:title><xsl:value-of select="$title"/></dc:title>
1505                    <dc:date><xsl:value-of select="substring($date,1,10)"/></dc:date>
1506                    <dc:source>http://www.openstreetmap.org/</dc:source>
1507                </cc:Work>
1508                <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
1509                    <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
1510                    <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
1511                    <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
1512                    <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
1513                    <cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
1514                    <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
1515                </cc:License>
1516            </rdf:RDF>
1517        </metadata>
1518    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:xlink="http://www.w3.org/1999/xlink" name="in-image-license">
1519        <xsl:param name="dx"/>
1520        <xsl:param name="dy"/>
1521
1522        <xsl:variable name="year" select="date:year()"/>
1523
1524        <g id="license" inkscape:groupmode="layer" inkscape:label="Copyright" transform="translate({$dx},{$dy})">
1525            <style type="text/css"><![CDATA[
1526                .license-text {
1527                    text-anchor: left;
1528                    font-family: "DejaVu Sans",sans-serif;
1529                    font-size: 6px;
1530                    fill: black;
1531                }
1532            ]]></style>
1533            <a id="license-cc-logo-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1534                <g id="license-cc-logo" transform="scale(0.5,0.5) translate(-604,-49)">
1535                    <path id="path3817_2_" nodetypes="ccccccc" d="M                     182.23532,75.39014 L 296.29928,75.59326 C                     297.89303,75.59326 299.31686,75.35644 299.31686,78.77344 L                     299.17721,116.34033 L 179.3569,116.34033 L                     179.3569,78.63379 C 179.3569,76.94922 179.51999,75.39014                     182.23532,75.39014 z " style="fill:#aab2ab"/>
1536                    <g id="g5908_2_" transform="matrix(0.872921,0,0,0.872921,50.12536,143.2144)">
1537                        <path id="path5906_2_" type="arc" cx="296.35416" cy="264.3577" ry="22.939548" rx="22.939548" d="M                         187.20944,-55.6792 C 187.21502,-46.99896                         180.18158,-39.95825 171.50134,-39.95212 C                         162.82113,-39.94708 155.77929,-46.97998                         155.77426,-55.66016 C 155.77426,-55.66687                         155.77426,-55.67249 155.77426,-55.6792 C                         155.76922,-64.36054 162.80209,-71.40125                         171.48233,-71.40631 C 180.16367,-71.41193                         187.20441,-64.37842 187.20944,-55.69824 C                         187.20944,-55.69263 187.20944,-55.68591                         187.20944,-55.6792 z " style="fill:white"/>
1538                        <g id="g5706_2_" transform="translate(-289.6157,99.0653)">
1539                            <path id="path5708_2_" d="M 473.88455,-167.54724 C                             477.36996,-164.06128 479.11294,-159.79333                             479.11294,-154.74451 C 479.11294,-149.69513                             477.40014,-145.47303 473.9746,-142.07715 C                             470.33929,-138.50055 466.04281,-136.71283                             461.08513,-136.71283 C 456.18736,-136.71283                             451.96526,-138.48544 448.42003,-142.03238 C                             444.87419,-145.57819 443.10158,-149.81537                             443.10158,-154.74451 C 443.10158,-159.6731                             444.87419,-163.94049 448.42003,-167.54724 C                             451.87523,-171.03375 456.09728,-172.77618                             461.08513,-172.77618 C 466.13342,-172.77618                             470.39914,-171.03375 473.88455,-167.54724 z M                             450.76657,-165.20239 C 447.81982,-162.22601                             446.34701,-158.7395 446.34701,-154.74005 C                             446.34701,-150.7417 447.80529,-147.28485                             450.72125,-144.36938 C 453.63778,-141.45288                             457.10974,-139.99462 461.1383,-139.99462 C                             465.16683,-139.99462 468.66848,-141.46743                             471.64486,-144.41363 C 474.47076,-147.14947                             475.88427,-150.59069 475.88427,-154.74005 C                             475.88427,-158.85809 474.44781,-162.35297                             471.57659,-165.22479 C 468.70595,-168.09546                             465.22671,-169.53131 461.1383,-169.53131 C                             457.04993,-169.53131 453.59192,-168.08813                             450.76657,-165.20239 z M 458.52106,-156.49927 C                             458.07074,-157.4809 457.39673,-157.9715                             456.49781,-157.9715 C 454.90867,-157.9715                             454.11439,-156.90198 454.11439,-154.763 C                             454.11439,-152.62341 454.90867,-151.55389                             456.49781,-151.55389 C 457.54719,-151.55389                             458.29676,-152.07519 458.74647,-153.11901 L                             460.94923,-151.94598 C 459.8993,-150.0805                             458.32417,-149.14697 456.22374,-149.14697 C                             454.60384,-149.14697 453.30611,-149.64367                             452.33168,-150.63653 C 451.35561,-151.62994                             450.86894,-152.99926 450.86894,-154.7445 C                             450.86894,-156.46008 451.37123,-157.82159                             452.37642,-158.83013 C 453.38161,-159.83806                             454.63347,-160.34264 456.13423,-160.34264 C                             458.35435,-160.34264 459.94407,-159.46776                             460.90504,-157.71978 L 458.52106,-156.49927 z M                             468.8844,-156.49927 C 468.43353,-157.4809                             467.77292,-157.9715 466.90201,-157.9715 C                             465.28095,-157.9715 464.46988,-156.90198                             464.46988,-154.763 C 464.46988,-152.62341                             465.28095,-151.55389 466.90201,-151.55389 C                             467.95304,-151.55389 468.68918,-152.07519                             469.10925,-153.11901 L 471.36126,-151.94598 C                             470.31301,-150.0805 468.74007,-149.14697                             466.64358,-149.14697 C 465.02587,-149.14697                             463.73095,-149.64367 462.75711,-150.63653 C                             461.78494,-151.62994 461.29773,-152.99926                             461.29773,-154.7445 C 461.29773,-156.46008                             461.79221,-157.82159 462.78061,-158.83013 C                             463.76843,-159.83806 465.02588,-160.34264                             466.55408,-160.34264 C 468.77027,-160.34264                             470.35776,-159.46776 471.3154,-157.71978 L                             468.8844,-156.49927 z "/>
1540                        </g>
1541                    </g>
1542                    <path d="M 297.29639,74.91064 L 181.06688,74.91064 C                     179.8203,74.91064 178.80614,75.92529 178.80614,77.17187 L                     178.80614,116.66748 C 178.80614,116.94922                     179.03466,117.17822 179.31639,117.17822 L                     299.04639,117.17822 C 299.32813,117.17822                     299.55713,116.94922 299.55713,116.66748 L                     299.55713,77.17188 C 299.55713,75.92529 298.54297,74.91064                     297.29639,74.91064 z M 181.06688,75.93213 L                     297.29639,75.93213 C 297.97998,75.93213 298.53565,76.48828                     298.53565,77.17188 C 298.53565,77.17188 298.53565,93.09131                     298.53565,104.59034 L 215.4619,104.59034 C                     212.41698,110.09571 206.55077,113.83399 199.81835,113.83399                     C 193.083,113.83399 187.21825,110.09913 184.1748,104.59034                     L 179.82666,104.59034 C 179.82666,93.09132                     179.82666,77.17188 179.82666,77.17188 C 179.82664,76.48828                     180.38329,75.93213 181.06688,75.93213 z " id="frame"/>
1543                    <g enable-background="new" id="g2821">
1544                        <path d="M 265.60986,112.8833 C 265.68994,113.03906                         265.79736,113.16504 265.93115,113.26172 C                         266.06494,113.35791 266.22119,113.42969                         266.40088,113.47608 C 266.58154,113.52296                         266.76807,113.54639 266.96045,113.54639 C                         267.09033,113.54639 267.22998,113.53565                         267.3794,113.51368 C 267.52784,113.4922                         267.66749,113.44972 267.79835,113.3877 C                         267.92823,113.32569 268.03761,113.23975                         268.12355,113.13086 C 268.21144,113.02197                         268.25441,112.88379 268.25441,112.71533 C                         268.25441,112.53515 268.19679,112.38916                         268.08156,112.27685 C 267.9673,112.16455                         267.81594,112.07177 267.62941,111.99658 C                         267.44386,111.92236 267.23195,111.85693                         266.9966,111.80078 C 266.76027,111.74463                         266.52101,111.68262 266.27883,111.61377 C                         266.02981,111.55176 265.78762,111.47559                         265.55129,111.38525 C 265.31594,111.29541                         265.10402,111.17822 264.9175,111.03515 C                         264.73098,110.89208 264.58059,110.71337                         264.46535,110.49853 C 264.35109,110.28369                         264.29347,110.02392 264.29347,109.71923 C                         264.29347,109.37646 264.36671,109.07958                         264.51222,108.82763 C 264.6587,108.57568                         264.85011,108.36572 265.08644,108.19726 C                         265.32179,108.02929 265.58937,107.90478                         265.8882,107.82372 C 266.18605,107.74315                         266.48488,107.70263 266.78273,107.70263 C                         267.13136,107.70263 267.46535,107.74169                         267.78566,107.81982 C 268.105,107.89746                         268.39015,108.02392 268.6382,108.19824 C                         268.88722,108.37256 269.08449,108.59521                         269.23097,108.86621 C 269.37648,109.13721                         269.44972,109.46582 269.44972,109.85156 L                         268.02784,109.85156 C 268.01514,109.65234                         267.97315,109.4873 267.90284,109.35693 C                         267.83155,109.22607 267.73682,109.12353                         267.61964,109.04834 C 267.50148,108.97412                         267.36671,108.9209 267.21534,108.89014 C                         267.063,108.85889 266.89796,108.84326                         266.71827,108.84326 C 266.60108,108.84326                         266.48292,108.85596 266.36573,108.88037 C                         266.24757,108.90576 266.14112,108.94922                         266.04542,109.01123 C 265.94874,109.07373                         265.86964,109.15137 265.80812,109.24463 C                         265.7466,109.33838 265.71535,109.45654                         265.71535,109.59961 C 265.71535,109.73047                         265.73976,109.83643 265.78957,109.91699 C                         265.83937,109.99804 265.93801,110.07275                         266.08352,110.14111 C 266.22903,110.20947                         266.43118,110.27832 266.68899,110.34668 C                         266.9468,110.41504 267.28372,110.50244                         267.70071,110.60791 C 267.82473,110.63281                         267.99661,110.67822 268.21731,110.74365 C                         268.43801,110.80908 268.65676,110.91308                         268.87454,111.05615 C 269.09231,111.1997                         269.27981,111.39111 269.43899,111.63037 C                         269.59719,111.87012 269.67629,112.17676                         269.67629,112.55029 C 269.67629,112.85547                         269.61672,113.13867 269.49856,113.3999 C                         269.3804,113.66162 269.20461,113.8872                         268.97122,114.07666 C 268.73782,114.26709                         268.44876,114.41455 268.10403,114.52051 C                         267.75833,114.62647 267.35794,114.6792                         266.90481,114.6792 C 266.53762,114.6792                         266.18118,114.63379 265.83547,114.54346 C                         265.49074,114.45313 265.18508,114.31104                         264.92043,114.11768 C 264.65676,113.92432                         264.4468,113.67774 264.29055,113.37891 C                         264.13528,113.07959 264.06106,112.7251                         264.06692,112.31397 L 265.4888,112.31397 C                         265.48877,112.53809 265.52881,112.72803                         265.60986,112.8833 z " id="path2823" style="fill:white"/>
1545                        <path d="M 273.8667,107.8667 L                         276.35986,114.53076 L 274.8374,114.53076 L                         274.33349,113.04638 L 271.84033,113.04638 L                         271.31787,114.53076 L 269.84326,114.53076 L                         272.36377,107.8667 L 273.8667,107.8667 z M                         273.95068,111.95264 L 273.11084,109.50928 L                         273.09229,109.50928 L 272.22315,111.95264 L                         273.95068,111.95264 z " id="path2825" style="fill:white"/>
1546                    </g>
1547                    <g enable-background="new" id="g2827">
1548                        <path d="M 239.17821,107.8667 C 239.49559,107.8667                         239.78563,107.89502 240.04735,107.95068 C                         240.30907,108.00683 240.53368,108.09863                         240.72118,108.22607 C 240.9077,108.35351                         241.05321,108.52295 241.15575,108.73437 C                         241.25829,108.94579 241.31005,109.20703                         241.31005,109.51806 C 241.31005,109.854                         241.23388,110.13329 241.08056,110.35742 C                         240.92822,110.58154 240.70165,110.76465                         240.40283,110.90771 C 240.81494,111.02587                         241.12256,111.23291 241.32568,111.5288 C                         241.5288,111.82469 241.63037,112.18114                         241.63037,112.59814 C 241.63037,112.93408                         241.56494,113.22509 241.43408,113.47119 C                         241.30322,113.7168 241.12646,113.91748                         240.90576,114.07324 C 240.68408,114.229                         240.43115,114.34424 240.14795,114.41845 C                         239.86377,114.49365 239.57275,114.53075                         239.27295,114.53075 L 236.03662,114.53075 L                         236.03662,107.86669 L 239.17821,107.86669 L                         239.17821,107.8667 z M 238.99071,110.56201 C                         239.25243,110.56201 239.46727,110.5 239.63622,110.37597                         C 239.80419,110.25146 239.88817,110.05029                         239.88817,109.77099 C 239.88817,109.61572                         239.85985,109.48828 239.80419,109.38915 C                         239.74755,109.28954 239.67333,109.21239                         239.57958,109.15624 C 239.48583,109.10058                         239.37841,109.06151 239.25731,109.04003 C                         239.13524,109.01806 239.00926,109.00732                         238.8784,109.00732 L 237.50535,109.00732 L                         237.50535,110.56201 L 238.99071,110.56201 z M                         239.07664,113.39014 C 239.22019,113.39014                         239.35691,113.37647 239.48777,113.34815 C                         239.61863,113.32032 239.73484,113.27344                         239.83445,113.2085 C 239.93406,113.14307                         240.01316,113.0542 240.07273,112.94239 C                         240.1323,112.83058 240.1616,112.68751                         240.1616,112.51319 C 240.1616,112.17139                         240.06492,111.92725 239.87156,111.78126 C                         239.6782,111.63527 239.42234,111.56202                         239.10496,111.56202 L 237.50535,111.56202 L                         237.50535,113.39014 L 239.07664,113.39014 z " id="path2829" style="fill:white"/>
1549                        <path d="M 241.88914,107.8667 L 243.53269,107.8667 L                         245.09324,110.49854 L 246.64402,107.8667 L                         248.27781,107.8667 L 245.80418,111.97315 L                         245.80418,114.53077 L 244.33543,114.53077 L                         244.33543,111.93604 L 241.88914,107.8667 z " id="path2831" style="fill:white"/>
1550                    </g>
1551                    <g id="g6316_1_" transform="matrix(0.624995,0,0,0.624995,391.2294,176.9332)">
1552                        <path id="path6318_1_" type="arc" cx="475.97119" cy="252.08646" ry="29.209877" rx="29.209877" d="M                         -175.0083,-139.1153 C -175.00204,-129.7035                         -182.62555,-122.06751 -192.03812,-122.06049 C                         -201.44913,-122.05341 -209.08512,-129.67774                         -209.09293,-139.09028 C -209.09293,-139.09809                         -209.09293,-139.10749 -209.09293,-139.1153 C                         -209.09919,-148.52784 -201.47413,-156.1623                         -192.06311,-156.17011 C -182.65054,-156.17713                         -175.01456,-148.55207 -175.0083,-139.14026 C                         -175.0083,-139.13092 -175.0083,-139.1239                         -175.0083,-139.1153 z " style="fill:white"/>
1553                        <g id="g6320_1_" transform="translate(-23.9521,-89.72962)">
1554                            <path id="path6322_1_" d="M -168.2204,-68.05536 C                             -173.39234,-68.05536 -177.76892,-66.25067                             -181.35175,-62.64203 C -185.02836,-58.90759                             -186.86588,-54.48883 -186.86588,-49.38568 C                             -186.86588,-44.28253 -185.02836,-39.89416                             -181.35175,-36.22308 C -177.67673,-32.55114                             -173.29859,-30.71521 -168.2204,-30.71521 C                             -163.07974,-30.71521 -158.62503,-32.56677                             -154.85312,-36.26996 C -151.30307,-39.78558                             -149.52652,-44.15827 -149.52652,-49.38568 C                             -149.52652,-54.6123 -151.33432,-59.03265                             -154.94843,-62.64203 C -158.5625,-66.25067                             -162.98599,-68.05536 -168.2204,-68.05536 z M                             -168.17352,-64.69519 C -163.936,-64.69519                             -160.33752,-63.20221 -157.37655,-60.21466 C                             -154.38748,-57.25836 -152.89214,-53.64899                             -152.89214,-49.38568 C -152.89214,-45.09186                             -154.35466,-41.52856 -157.28438,-38.69653 C                             -160.36876,-35.64727 -163.99849,-34.12304                             -168.17351,-34.12304 C -172.34856,-34.12304                             -175.94701,-35.63244 -178.96892,-38.64965 C                             -181.9908,-41.66918 -183.50176,-45.24657                             -183.50176,-49.38567 C -183.50176,-53.52398                             -181.97518,-57.13414 -178.92205,-60.21465 C                             -175.9939,-63.20221 -172.41107,-64.69519                             -168.17352,-64.69519 z "/>
1555                            <path id="path6324_1_" d="M -176.49548,-52.02087 C                             -175.75171,-56.71856 -172.44387,-59.22949                             -168.30008,-59.22949 C -162.33911,-59.22949                             -158.70783,-54.90448 -158.70783,-49.1372 C                             -158.70783,-43.50982 -162.57194,-39.13793                             -168.39383,-39.13793 C -172.39856,-39.13793                             -175.98297,-41.60277 -176.63611,-46.43877 L                             -171.93292,-46.43877 C -171.7923,-43.92778                             -170.1626,-43.04418 -167.83447,-43.04418 C                             -165.1813,-43.04418 -163.4563,-45.50908                             -163.4563,-49.27709 C -163.4563,-53.22942                             -164.94693,-55.32244 -167.74228,-55.32244 C                             -169.79074,-55.32244 -171.55948,-54.57787                             -171.93292,-52.02087 L -170.56418,-52.02789 L                             -174.26734,-48.32629 L -177.96894,-52.02789 L                             -176.49548,-52.02087 z "/>
1556                        </g>
1557                    </g>
1558                    <g id="g2838">
1559                        <circle cx="242.56226" cy="90.224609" r="10.8064" id="circle2840" style="fill:white"/>
1560                        <g id="g2842">
1561                            <path d="M 245.68994,87.09766 C 245.68994,86.68116                             245.35205,86.34424 244.93603,86.34424 L                             240.16357,86.34424 C 239.74755,86.34424                             239.40966,86.68115 239.40966,87.09766 L                             239.40966,91.87061 L 240.74071,91.87061 L                             240.74071,97.52295 L 244.3579,97.52295 L                             244.3579,91.87061 L 245.68993,91.87061 L                             245.68993,87.09766 L 245.68994,87.09766 z " id="path2844"/>
1562                            <circle cx="242.5498" cy="84.083008" r="1.63232" id="circle2846"/>
1563                        </g>
1564                        <path clip-rule="evenodd" d="M 242.53467,78.31836 C                         239.30322,78.31836 236.56641,79.4458 234.32715,81.70215                         C 232.0293,84.03516 230.88086,86.79736                         230.88086,89.98633 C 230.88086,93.1753                         232.0293,95.91846 234.32715,98.21338 C                         236.625,100.50781 239.36133,101.65527                         242.53467,101.65527 C 245.74756,101.65527                         248.53272,100.49853 250.88819,98.18359 C                         253.10889,95.98681 254.21827,93.2539 254.21827,89.98632                         C 254.21827,86.71874 253.08936,83.95751                         250.83057,81.70214 C 248.57178,79.4458                         245.80615,78.31836 242.53467,78.31836 z M                         242.56396,80.41797 C 245.2124,80.41797                         247.46142,81.35156 249.31103,83.21875 C                         251.18115,85.06592 252.11572,87.32227                         252.11572,89.98633 C 252.11572,92.66992                         251.20068,94.89746 249.36963,96.66699 C                         247.4419,98.57275 245.17334,99.52539 242.56397,99.52539                         C 239.9546,99.52539 237.70557,98.58252                         235.81739,96.6958 C 233.92774,94.80957                         232.98389,92.57324 232.98389,89.98633 C                         232.98389,87.3999 233.93799,85.14404 235.84619,83.21875                         C 237.67676,81.35156 239.9165,80.41797                         242.56396,80.41797 z " id="path2848" style="fill-rule:evenodd"/>
1565                    </g>
1566                </g>
1567            </a>
1568            <a id="license-osm-link" xlink:href="http://www.openstreetmap.org/">
1569                <g transform="translate(-210,10)" id="license-osm-text">
1570                    <text class="license-text" dx="0" dy="0">Copyright © <xsl:value-of select="$year"/> OpenStreetMap (openstreetmap.org)</text>
1571                </g>
1572            </a>
1573            <a id="license-cc-text-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1574                <g transform="translate(-150,18)" id="license-cc-text">
1575                    <text class="license-text" dx="0" dy="0">This work is licensed under the Creative</text>
1576                    <text class="license-text" dx="0" dy="8">Commons Attribution-ShareAlike 2.0 License.</text>
1577                    <text class="license-text" dx="0" dy="16">http://creativecommons.org/licenses/by-sa/2.0/</text>
1578                </g>
1579            </a>
1580        </g>
1581    </xsl:template>
1582
1583    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" name="zoomControl">
1584        <defs>
1585
1586            <style type="text/css">
1587              .fancyButton {
1588                stroke: #8080ff;
1589                stroke-width: 2px;
1590                fill: #fefefe;
1591                }
1592              .fancyButton:hover {
1593                stroke: red;
1594                }
1595            </style>
1596
1597            <filter id="fancyButton" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="350">
1598                <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
1599                <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
1600                <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" specularExponent="20" lighting-color="white" result="specOut">
1601                    <fePointLight x="-5000" y="-10000" z="7000"/>
1602                </feSpecularLighting>
1603                <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
1604                <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
1605                <feMerge>
1606                    <feMergeNode in="offsetBlur"/>
1607                    <feMergeNode in="litPaint"/>
1608                </feMerge>
1609            </filter>
1610            <symbol id="panDown" viewBox="0 0 19 19" class="fancyButton">
1611                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1612                <path d="M 9.5,5 L 9.5,14"/>
1613            </symbol>
1614            <symbol id="panUp" viewBox="0 0 19 19" class="fancyButton">
1615                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1616                <path d="M 9.5,5 L 9.5,14"/>
1617            </symbol>
1618            <symbol id="panLeft" viewBox="0 0 19 19" class="fancyButton">
1619                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1620                <path d="M 5,9.5 L 14,9.5"/>
1621            </symbol>
1622            <symbol id="panRight" viewBox="0 0 19 19" class="fancyButton">
1623                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1624                <path d="M 5,9.5 L 14,9.5"/>
1625            </symbol>
1626            <symbol id="zoomIn" viewBox="0 0 19 19" class="fancyButton">
1627                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1628                <path d="M 5,9.5 L 14,9.5 M 9.5,5 L 9.5,14"/>
1629            </symbol>
1630            <symbol id="zoomOut" viewBox="0 0 19 19" class="fancyButton">
1631                <path d="M 17 9.5 A 7 7 0 1 1 2,9.5 A 7 7 0 1 1 17 9.5 z"/>
1632                <path d="M 5,9.5 L 14,9.5"/>
1633            </symbol>
1634
1635        </defs>
1636
1637        <g id="gPanDown" filter="url(#fancyButton)" onclick="fnPan(&quot;down&quot;)">
1638            <use x="18px" y="60px" xlink:href="#panDown" width="14px" height="14px"/>
1639        </g>
1640        <g id="gPanRight" filter="url(#fancyButton)" onclick="fnPan(&quot;right&quot;)">
1641            <use x="8px" y="70px" xlink:href="#panRight" width="14px" height="14px"/>
1642        </g>
1643        <g id="gPanLeft" filter="url(#fancyButton)" onclick="fnPan(&quot;left&quot;)">
1644            <use x="28px" y="70px" xlink:href="#panLeft" width="14px" height="14px"/>
1645        </g>
1646        <g id="gPanUp" filter="url(#fancyButton)" onclick="fnPan(&quot;up&quot;)">
1647            <use x="18px" y="80px" xlink:href="#panUp" width="14px" height="14px"/>
1648        </g>
1649
1650        <xsl:variable name="x1" select="25"/>
1651        <xsl:variable name="y1" select="105"/>
1652        <xsl:variable name="x2" select="25"/>
1653        <xsl:variable name="y2" select="300"/>
1654
1655        <line style="stroke-width: 10; stroke-linecap: butt; stroke: #8080ff;">
1656            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1657            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1658            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1659            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1660        </line>
1661
1662        <line style="stroke-width: 8; stroke-linecap: butt; stroke: white; stroke-dasharray: 10,1;">
1663            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1664            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1665            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1666            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1667        </line>
1668
1669        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1670        <g id="gZoomIn" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;in&quot;)">
1671            <use x="15.5px" y="100px" xlink:href="#zoomIn" width="19px" height="19px"/>
1672        </g>
1673
1674        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1675        <g id="gZoomOut" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;out&quot;)">
1676            <use x="15.5px" y="288px" xlink:href="#zoomOut" width="19px" height="19px"/>
1677        </g>
1678    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" xmlns:xi="http://www.w3.org/2001/XInclude" name="javaScript">
1679        <script>
1680            /*
1681
1682Osmarender
1683
1684interactive.js
1685
1686*/
1687
1688function fnResize() {
1689    fnResizeElement("gAttribution")
1690    fnResizeElement("gLicense")
1691    fnResizeElement("gZoomIn")
1692    fnResizeElement("gZoomOut")
1693}
1694
1695
1696function fnResizeElement(e) {
1697    //
1698    var oSVG,scale,currentTranslateX,currentTranslateY,oe
1699    //
1700    oSVG=document.rootElement
1701    scale=1/oSVG.currentScale
1702    currentTranslateX=oSVG.currentTranslate.x
1703    currentTranslateY=oSVG.currentTranslate.y
1704    oe=document.getElementById(e)
1705    if (oe) oe.setAttributeNS(null,"transform","scale("+scale+","+scale+") translate("+(-currentTranslateX)+","+(-currentTranslateY)+")")
1706}
1707
1708
1709function fnToggleImage(osmImage) {
1710    var xlink = 'http://www.w3.org/1999/xlink';
1711    ogThumbnail=document.getElementById('gThumbnail')
1712    if (ogThumbnail.getAttributeNS(null,"visibility")=="visible") fnHideImage()
1713    else {
1714        ogThumbnail.setAttributeNS(null,"visibility","visible")
1715        oThumbnail=document.getElementById('thumbnail')
1716        oThumbnail.setAttributeNS(xlink,"href",osmImage)
1717    }
1718}
1719
1720function fnHideImage() {
1721    ogThumbnail=document.getElementById('gThumbnail')
1722    ogThumbnail.setAttributeNS(null,"visibility","hidden")
1723}
1724
1725
1726/* The following code originally written by Jonathan Watt (http://jwatt.org/), Aug. 2005 */
1727
1728if (!window)
1729window = this;
1730
1731
1732function fnOnLoad(evt) {
1733    if (!document) window.document = evt.target.ownerDocument
1734}
1735
1736
1737/**
1738  * Event handlers to change the current user space for the zoom and pan
1739  * controls to make them appear to be scale invariant.
1740  */
1741
1742function fnOnZoom(evt) {
1743    try {
1744        if (evt.newScale === undefined) throw 'bad interface'
1745        // update the transform list that adjusts for zoom and pan
1746        var tlist = document.getElementById('staticElements').transform.baseVal
1747        tlist.getItem(0).setScale(1/evt.newScale, 1/evt.newScale)
1748        tlist.getItem(1).setTranslate(-evt.newTranslate.x, -evt.newTranslate.y)
1749        }
1750    catch (e) {
1751        // work around difficiencies in non-moz implementations (some don't
1752        // implement the SVGZoomEvent or SVGAnimatedTransform interfaces)
1753        var de = document.documentElement
1754        var tform = 'scale(' + 1/de.currentScale + ') ' + 'translate(' + (-de.currentTranslate.x) + ', ' + (-de.currentTranslate.y) + ')'
1755        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1756        }
1757    }
1758
1759
1760function fnOnScroll(evt) {
1761    var ct = document.documentElement.currentTranslate
1762    try {
1763        // update the transform list that adjusts for zoom and pan
1764        var tlist = document.getElementById('staticElements').transform.baseVal
1765        tlist.getItem(1).setTranslate(-ct.x, -ct.y)
1766        }
1767    catch (e) {
1768        // work around difficiencies in non-moz implementations (some don't
1769        // implement the SVGAnimatedTransform interface)
1770        var tform = 'scale(' + 1/document.documentElement.currentScale + ') ' + 'translate(' + (-ct.x) + ', ' + (-ct.y) + ')';
1771        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1772        }
1773    }
1774
1775
1776function fnZoom(type) {
1777    var de = document.documentElement;
1778    var oldScale = de.currentScale;
1779    var oldTranslate = { x: de.currentTranslate.x, y: de.currentTranslate.y };
1780    var s = 2;
1781    if (type == 'in') {de.currentScale *= 1.5;}
1782    if (type == 'out') {de.currentScale /= 1.4;}
1783    // correct currentTranslate so zooming is to the center of the viewport:
1784
1785    var vp_width, vp_height;
1786    try {
1787        vp_width = de.viewport.width;
1788        vp_height = de.viewport.height;
1789    }
1790    catch (e) {
1791        // work around difficiency in moz ('viewport' property not implemented)
1792        vp_width = window.innerWidth;
1793        vp_height = window.innerHeight;
1794    }
1795    de.currentTranslate.x = vp_width/2 - ((de.currentScale/oldScale) * (vp_width/2 - oldTranslate.x));
1796    de.currentTranslate.y = vp_height/2 - ((de.currentScale/oldScale) * (vp_height/2 - oldTranslate.y));
1797
1798}
1799
1800
1801function fnPan(type) {
1802    var de = document.documentElement;
1803    var ct = de.currentTranslate;
1804    var t = 150;
1805    if (type == 'right') ct.x += t;
1806    if (type == 'down') ct.y += t;
1807    if (type == 'left') ct.x -= t;
1808    if (type == 'up') ct.y -= t;
1809}
1810
1811
1812var gCurrentX,gCurrentY
1813var gDeltaX,gDeltaY
1814var gMouseDown=false
1815var gCurrentTranslate=document.documentElement.currentTranslate
1816
1817function fnOnMouseDown(evt) {
1818    gCurrentX=gCurrentTranslate.x
1819    gCurrentY=gCurrentTranslate.y
1820    gDeltaX=evt.clientX
1821    gDeltaY=evt.clientY
1822    gMouseDown=true
1823    evt.target.ownerDocument.rootElement.setAttributeNS(null,"cursor","move")
1824}
1825
1826
1827function fnOnMouseUp(evt) {
1828    gMouseDown=false
1829    evt.target.ownerDocument.rootElement.setAttribute("cursor","default")
1830}
1831
1832
1833function fnOnMouseMove(evt) {
1834    var id
1835    if (gMouseDown) {
1836        gCurrentTranslate.x=gCurrentX+evt.clientX-gDeltaX
1837        gCurrentTranslate.y=gCurrentY+evt.clientY-gDeltaY
1838    }
1839}
1840
1841
1842        </script>
1843    </xsl:template>
1844
1845</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.