source: subversion/rendering/osmarender4/osmarender.xsl @ 2486

Last change on this file since 2486 was 2361, checked in by jochen, 13 years ago

Reverted fix from 80n in draw.xsl as it breaks symbol rendering

File size: 120.7 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            </use>
443        </xsl:if>
444
445    </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">
446        <xsl:param name="instruction"/>
447        <xsl:param name="way"/>
448        <xsl:param name="layer"/>
449        <xsl:param name="classes"/>
450
451        <xsl:choose>
452            <xsl:when test="$instruction/@width &gt; 0">
453                <!-- wide tunnels use a dashed line as wide as the road casing with a mask as wide as the road core which will be
454                rendered as a double dotted line -->
455                <mask id="mask_{@id}" maskUnits="userSpaceOnUse">
456                    <use xlink:href="#way_{@id}" style="stroke:black;fill:none;" class="{$instruction/@class}-core"/>
457                    <rect x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px" style="fill:white;"/>
458                </mask>
459                <use xlink:href="#way_{$way/@id}" mask="url(#mask_{@id})" style="stroke-dasharray:0.2,0.2;" class="{$instruction/@class}-casing"/>
460                <use xlink:href="#way_{$way/@id}" class="tunnel-casing" style="stroke-width:{$instruction/@width}px;"/>
461            </xsl:when>
462            <xsl:otherwise>
463                <!-- narrow tunnels will use a single dotted line -->
464                <use xlink:href="#way_{$way/@id}">
465                    <xsl:apply-templates select="$instruction/@*" mode="copyAttributes">
466                        <xsl:with-param name="classes" select="$classes"/>
467                    </xsl:apply-templates>
468                </use>
469            </xsl:otherwise>
470        </xsl:choose>
471    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawCircle">
472        <xsl:param name="instruction"/>
473
474        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
475        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
476
477        <circle cx="{$x}" cy="{$y}">
478            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the svg attributes from the <circle> instruction -->
479        </circle>
480
481    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawSymbol">
482        <xsl:param name="instruction"/>
483
484        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
485        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
486
487        <g transform="translate({$x},{$y}) scale({$symbolScale})">
488            <use width="1" height="1">
489                <xsl:if test="$instruction/@ref">
490                    <xsl:attribute name="xlink:href">
491                        <xsl:value-of select="concat('#symbol-', $instruction/@ref)"/>
492                    </xsl:attribute>
493                </xsl:if>
494                <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the attributes from the <symbol> instruction -->
495            </use>
496        </g>
497    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="renderText">
498        <xsl:param name="instruction"/>
499
500        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
501        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
502
503        <text>
504            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
505            <xsl:attribute name="x"><xsl:value-of select="$x"/></xsl:attribute>
506            <xsl:attribute name="y"><xsl:value-of select="$y"/></xsl:attribute>
507            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
508            <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
509        </text>
510    </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">
511        <xsl:param name="instruction"/>
512        <xsl:param name="pathId"/>
513        <text>
514            <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-text"/>
515            <textPath xlink:href="#{$pathId}">
516                <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-textPath"/>
517                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
518                <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
519            </textPath>
520        </text>
521    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength|@k" mode="renderTextPath-text">
522    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-text">
523        <xsl:copy/>
524    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength" mode="renderTextPath-textPath">
525        <xsl:copy/>
526    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-textPath">
527    </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">
528        <xsl:param name="instruction"/>
529        <xsl:param name="pathId"/>
530
531        <use xlink:href="#{$pathId}">
532            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
533        </use>
534    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="getSvgAttributesFromOsmTags">
535        <xsl:for-each select="tag[contains(@k,&quot;svg:&quot;)]">
536            <xsl:attribute name="{substring-after(@k,&quot;svg:&quot;)}"><xsl:value-of select="@v"/></xsl:attribute>
537        </xsl:for-each>
538    </xsl:template>
539    <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">
540        <g id="segments" inkscape:groupmode="layer" inkscape:label="Segments">
541            <xsl:for-each select="$data/osm/segment[not(key('wayBySegment', @id))]">
542                <xsl:if test="not(tag[@key!='created_by'])">
543                    <xsl:variable name="fromNode" select="key('nodeById', @from)"/>
544                    <xsl:variable name="toNode" select="key('nodeById', @to)"/>
545                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
546                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
547                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
548                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
549                    <line class="untagged-segments" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
550                </xsl:if>
551            </xsl:for-each>
552        </g>
553    </xsl:template>
554    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="line">
555        <xsl:param name="elements"/>
556        <xsl:param name="layer"/>
557        <xsl:param name="classes"/>
558
559        <!-- This is the instruction that is currently being processed -->
560        <xsl:variable name="instruction" select="."/>
561
562        <g>
563            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
564                <xsl:with-param name="classes" select="$classes"/>
565            </xsl:apply-templates>
566
567            <!-- For each segment and way -->
568            <xsl:apply-templates select="$elements" mode="line">
569                <xsl:with-param name="instruction" select="$instruction"/>
570                <xsl:with-param name="layer" select="$layer"/>
571                <xsl:with-param name="classes" select="$classes"/>
572            </xsl:apply-templates>
573
574        </g>
575    </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">
576        <xsl:param name="instruction"/>
577        <xsl:param name="classes"/>
578
579        <xsl:call-template name="drawLine">
580            <xsl:with-param name="instruction" select="$instruction"/>
581            <xsl:with-param name="segment" select="."/>
582            <xsl:with-param name="classes" select="$classes"/>
583        </xsl:call-template>
584
585    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="line">
586        <xsl:param name="instruction"/>
587        <xsl:param name="layer"/>
588        <xsl:param name="classes"/>
589
590        <!-- The current <way> element -->
591        <xsl:variable name="way" select="."/>
592
593        <xsl:call-template name="drawWay">
594            <xsl:with-param name="instruction" select="$instruction"/>
595            <xsl:with-param name="way" select="$way"/>
596            <xsl:with-param name="layer" select="$layer"/>
597            <xsl:with-param name="classes" select="$classes"/>
598        </xsl:call-template>
599
600    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="tunnel">
601        <xsl:param name="elements"/>
602        <xsl:param name="layer"/>
603        <xsl:param name="classes"/>
604
605        <!-- This is the instruction that is currently being processed -->
606        <xsl:variable name="instruction" select="."/>
607
608        <g>
609            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <tunnel> instruction to the <g> element -->
610                <xsl:with-param name="classes" select="$classes"/>
611            </xsl:apply-templates>
612
613            <!-- For each segment and way -->
614            <xsl:apply-templates select="$elements" mode="tunnel">
615                <xsl:with-param name="instruction" select="$instruction"/>
616                <xsl:with-param name="layer" select="$layer"/>
617                <xsl:with-param name="classes" select="$classes"/>
618            </xsl:apply-templates>
619        </g>
620    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="tunnel">
621        <xsl:param name="instruction"/>
622        <xsl:param name="layer"/>
623        <xsl:param name="classes"/>
624
625        <!-- The current <way> element -->
626        <xsl:variable name="way" select="."/>
627
628        <xsl:call-template name="drawTunnel">
629            <xsl:with-param name="instruction" select="$instruction"/>
630            <xsl:with-param name="way" select="$way"/>
631            <xsl:with-param name="layer" select="$layer"/>
632            <xsl:with-param name="classes" select="$classes"/>
633        </xsl:call-template>
634
635    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="area">
636        <xsl:param name="elements"/>
637        <xsl:param name="classes"/>
638
639        <!-- This is the instruction that is currently being processed -->
640        <xsl:variable name="instruction" select="."/>
641
642        <g>
643            <xsl:apply-templates select="@*" mode="copyAttributes"/> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
644
645            <!-- For each segment and way -->
646            <xsl:apply-templates select="$elements" mode="area">
647                <xsl:with-param name="instruction" select="$instruction"/>
648            </xsl:apply-templates>
649        </g>
650    </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">
651        <xsl:param name="instruction"/>
652
653        <xsl:call-template name="generateAreaPath"/>
654
655        <xsl:call-template name="renderArea">
656            <xsl:with-param name="instruction" select="$instruction"/>
657            <xsl:with-param name="pathId" select="concat(&quot;area_&quot;,@id)"/>
658        </xsl:call-template>
659
660    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="circle">
661        <xsl:param name="elements"/>
662        <xsl:param name="classes"/>
663
664        <!-- This is the instruction that is currently being processed -->
665        <xsl:variable name="instruction" select="."/>
666
667        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
668            <xsl:call-template name="drawCircle">
669                <xsl:with-param name="instruction" select="$instruction"/>
670            </xsl:call-template>
671        </xsl:for-each>
672    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="symbol">
673        <xsl:param name="elements"/>
674        <xsl:param name="classes"/>
675
676        <!-- This is the instruction that is currently being processed -->
677        <xsl:variable name="instruction" select="."/>
678
679        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
680            <xsl:call-template name="drawSymbol">
681                <xsl:with-param name="instruction" select="$instruction"/>
682            </xsl:call-template>
683        </xsl:for-each>
684    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="text">
685        <xsl:param name="elements"/>
686        <xsl:param name="classes"/>
687
688        <!-- This is the instruction that is currently being processed -->
689        <xsl:variable name="instruction" select="."/>
690
691        <!-- Select all <node> elements that have a key that matches the k attribute of the text instruction -->
692        <xsl:for-each select="$elements[name()=&quot;node&quot;][tag[@k=$instruction/@k]]">
693                <xsl:call-template name="renderText">
694                    <xsl:with-param name="instruction" select="$instruction"/>
695                </xsl:call-template>
696        </xsl:for-each>
697
698        <!-- Select all <segment> and <way> elements that have a key that matches the k attribute of the text instruction -->
699        <xsl:apply-templates select="$elements[name()=&quot;segment&quot; or name()=&quot;way&quot;][tag[@k=$instruction/@k]]" mode="textPath">
700            <xsl:with-param name="instruction" select="$instruction"/>
701        </xsl:apply-templates>
702    </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">
703        <xsl:param name="instruction"/>
704
705        <!-- The current <segment> element -->
706        <xsl:variable name="segment" select="."/>
707
708        <!-- Generate the path for the segment -->
709        <!-- Text on segments should be relatively uncommon so only generate a <path> when one is needed -->
710        <xsl:call-template name="generateSegmentPath"/>
711
712        <xsl:call-template name="renderTextPath">
713            <xsl:with-param name="instruction" select="$instruction"/>
714            <xsl:with-param name="pathId" select="concat(&quot;segment_&quot;,@id)"/>
715        </xsl:call-template>
716
717    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="textPath">
718        <xsl:param name="instruction"/>
719
720        <!-- The current <way> element -->
721        <xsl:variable name="way" select="."/>
722
723        <xsl:call-template name="renderTextPath">
724            <xsl:with-param name="instruction" select="$instruction"/>
725            <xsl:with-param name="pathId" select="concat(&quot;way_&quot;,@id,&quot;t&quot;)"/>
726        </xsl:call-template>
727
728    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateSegmentPath">
729        <xsl:variable name="pathData">
730            <xsl:choose>
731                                <!-- Manual override -->
732                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;-1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;-1&quot;">
733                    <xsl:call-template name="segmentMoveToEnd"/>
734                    <xsl:call-template name="segmentLineToStart"/>
735                </xsl:when>
736                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;1&quot;">
737                    <xsl:call-template name="segmentMoveToStart"/>
738                    <xsl:call-template name="segmentLineToEnd"/>
739                </xsl:when>
740                <!-- Automatic direction -->
741                <xsl:when test="(key(&quot;nodeById&quot;,@from)/@lon &gt; key(&quot;nodeById&quot;,@to)/@lon)">
742                    <xsl:call-template name="segmentMoveToEnd"/>
743                    <xsl:call-template name="segmentLineToStart"/>
744                </xsl:when>
745                <xsl:otherwise>
746                    <xsl:call-template name="segmentMoveToStart"/>
747                    <xsl:call-template name="segmentLineToEnd"/>
748                </xsl:otherwise>
749            </xsl:choose>
750        </xsl:variable>
751
752        <path id="segment_{@id}" d="{$pathData}"/>
753
754    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateWayPath">
755
756        <!-- Generate the path for the way that will be used by the street
757        name rendering. This is horribly inefficient, because we will later
758        also have the path used for the rendering of the path itself. So
759        each path is twice in the SVG file. But this path here needs to
760        have the right direction for the names to render right way up
761        and the other path needs to be the right direction for rendering
762        the oneway arrows. This can probably be done better, but currently
763        I don't know how. -->
764        <xsl:variable name="pathData">
765            <xsl:choose>
766                                <!-- Manual override, reverse direction -->
767                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;-1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;-1&quot;">
768                                        <xsl:call-template name="generateWayPathReverse"/>
769                </xsl:when>
770                                <!-- Manual override, normal direction -->
771                <xsl:when test="tag[@k=&quot;name_direction&quot;]/@v=&quot;1&quot; or tag[@k=&quot;osmarender:nameDirection&quot;]/@v=&quot;1&quot;">
772                                        <xsl:call-template name="generateWayPathNormal"/>
773                </xsl:when>
774                                <!-- Automatic, reverse direction -->
775                <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)">
776                                        <xsl:call-template name="generateWayPathReverse"/>
777                </xsl:when>
778                                <!-- Automatic, normal direction -->
779                <xsl:otherwise>
780                                        <xsl:call-template name="generateWayPathNormal"/>
781                </xsl:otherwise>
782            </xsl:choose>
783        </xsl:variable>
784
785        <path id="way_{@id}t" d="{$pathData}"/>
786
787        <!-- Generate the path for the way itself. Used for rendering the
788        way and, possibly, oneway arrows. -->
789        <xsl:variable name="pathDataFixed">
790                        <xsl:call-template name="generateWayPathNormal"/>
791        </xsl:variable>
792
793        <path id="way_{@id}" d="{$pathDataFixed}"/>
794
795    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="generateWayPathNormal">
796                <xsl:choose>
797                        <xsl:when test="$bFrollo">                     
798                                <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
799                                    <xsl:variable name="segmentId" select="@id"/>
800                                        <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
801                                        <xsl:variable name="bSubPath" select="(position()=1) or (@osma:sub-path=&quot;1&quot;)"/>
802                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
803                                                <xsl:choose>
804                                                        <xsl:when test="$bReverseSeg">
805                                                                <xsl:if test="$bSubPath">
806                                                                    <xsl:call-template name="segmentMoveToEnd"/>
807                                                                </xsl:if>
808                                                                <xsl:call-template name="segmentLineToStart"/>
809                                                        </xsl:when>
810                                                        <xsl:otherwise>
811                                                                <xsl:if test="$bSubPath">
812                                                                    <xsl:call-template name="segmentMoveToStart"/>
813                                                                </xsl:if>
814                                                                <xsl:call-template name="segmentLineToEnd"/>
815                                                        </xsl:otherwise>                               
816                                                </xsl:choose>
817                                    </xsl:for-each>
818                                </xsl:for-each>                         
819                        </xsl:when>
820                        <xsl:otherwise> <!-- Not pre-processed by frollo -->
821                            <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
822                                        <xsl:variable name="segmentId" select="@id"/>
823                                        <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,@id)/@from=key(&quot;segmentById&quot;,preceding-sibling::seg[1]/@id)/@to"/>
824                                        <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
825                                                <xsl:if test="not($linkedSegment)">
826                                                        <xsl:call-template name="segmentMoveToStart"/>
827                                                </xsl:if>
828                                                <xsl:call-template name="segmentLineToEnd"/>
829                                        </xsl:for-each>
830                                </xsl:for-each>
831                        </xsl:otherwise>               
832                </xsl:choose>
833    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="generateWayPathReverse">
834                <xsl:choose>
835                        <xsl:when test="$bFrollo">                     
836                                <xsl:for-each select="seg">
837                                    <xsl:sort select="position()" data-type="number" order="descending"/>
838                                    <xsl:variable name="segmentId" select="@id"/>
839                                        <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
840                                        <xsl:variable name="bSubPath" select="(position()=1) or (preceding-sibling::seg/@osma:sub-path=&quot;1&quot;)"/>
841                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
842                                                <xsl:choose>
843                                                        <xsl:when test="$bReverseSeg">
844                                                                <xsl:if test="$bSubPath">
845                                                                    <xsl:call-template name="segmentMoveToStart"/>
846                                                                </xsl:if>
847                                                                <xsl:call-template name="segmentLineToEnd"/>
848                                                        </xsl:when>
849                                                        <xsl:otherwise>
850                                                                <xsl:if test="$bSubPath">
851                                                                    <xsl:call-template name="segmentMoveToEnd"/>
852                                                                </xsl:if>
853                                                                <xsl:call-template name="segmentLineToStart"/>
854                                                        </xsl:otherwise>                               
855                                                </xsl:choose>
856                                    </xsl:for-each>
857                                </xsl:for-each>   
858                        </xsl:when>
859                        <xsl:otherwise> <!-- Not pre-processed by frollo -->
860                                <xsl:for-each select="seg">
861                                    <xsl:sort select="position()" data-type="number" order="descending"/>
862                                    <xsl:variable name="segmentId" select="@id"/>
863                                    <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,following-sibling::seg[1]/@id)/@from=key(&quot;segmentById&quot;,@id)/@to"/>
864                                    <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
865                                                <xsl:if test="not($linkedSegment)">
866                                                        <xsl:call-template name="segmentMoveToStart"/>
867                                                </xsl:if>
868                                                <xsl:call-template name="segmentLineToEnd"/>
869                                    </xsl:for-each>
870                                </xsl:for-each> 
871                        </xsl:otherwise>
872                </xsl:choose>
873    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateAreaPath">
874
875                <!-- Generate the path for the area -->
876                <xsl:variable name="pathData">
877                        <xsl:choose>
878                                <xsl:when test="$bFrollo">                     
879                                        <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
880                                                <xsl:variable name="segmentId" select="@id"/>
881                                                <xsl:variable name="bReverseSeg" select="@osma:reverse=&quot;1&quot;"/>
882                                                <xsl:variable name="bSubPath" select="@osma:sub-path=&quot;1&quot;"/>                                           
883                                                <xsl:variable name="fromCount" select="@osma:fromCount"/>                                               
884                                                <xsl:variable name="segmentSequence" select="position()"/>
885                                                <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
886                                                        <xsl:choose>
887                                                                <xsl:when test="not($bReverseSeg)">
888                                                                        <xsl:choose>
889                                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
890                                                                                <xsl:when test="$segmentSequence=1">
891                                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
892                                                                                </xsl:when>
893                                                                               
894                                                                                <!-- If the segment is connected to another segment (at the from end) and is the start of a new
895                                                                                         sub-path then start a new sub-path -->
896                                                                                <xsl:when test="$fromCount&gt;0 and $bSubPath">
897                                                                                        <xsl:text>Z</xsl:text>
898                                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
899                                                                                </xsl:when>
900                                                                               
901                                                                                <!-- If the segment is the start of a new sub-path, but is not connected to any previous
902                                                                                     segment then draw an artificial line.  Typically this happens when a tile boundary chops
903                                                                                     through the middle of an area or a river is segmented into manageable chunks. -->
904                                                                                <xsl:otherwise>
905                                                                                        <xsl:call-template name="segmentLineToStart"/>
906                                                                                </xsl:otherwise>
907                                                                        </xsl:choose>
908                                                                        <xsl:call-template name="segmentLineToEnd"/>                                                           
909                                                                </xsl:when>
910                                                                <xsl:otherwise>
911                                                                        <xsl:choose>
912                                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
913                                                                                <xsl:when test="$segmentSequence=1">
914                                                                                        <xsl:call-template name="segmentMoveToEnd"/>                           
915                                                                                </xsl:when>
916                                                                               
917                                                                                <!-- If the segment is connected to another segment (at the from end) and is the start of a new
918                                                                                         sub-path then start a new sub-path -->
919                                                                                <xsl:when test="$fromCount&gt;0 and $bSubPath">
920                                                                                        <xsl:text>Z</xsl:text>
921                                                                                        <xsl:call-template name="segmentMoveToEnd"/>                           
922                                                                                </xsl:when>
923                                                                               
924                                                                                <!-- If the segment is the start of a new sub-path, but is not connected to any previous
925                                                                                     segment then draw an artificial line.  Typically this happens when a tile boundary chops
926                                                                                     through the middle of an area or a river is segmented into manageable chunks. -->
927                                                                                <xsl:otherwise>
928                                                                                        <xsl:call-template name="segmentLineToEnd"/>
929                                                                                </xsl:otherwise>
930                                                                        </xsl:choose>
931                                                                        <xsl:call-template name="segmentLineToStart"/>
932                                                                </xsl:otherwise>
933                                                        </xsl:choose>
934                                                </xsl:for-each>
935                                        </xsl:for-each>
936                                        <xsl:text>Z</xsl:text>
937                                </xsl:when>
938                                <xsl:otherwise> <!-- Not pre-processed by frollo -->
939                                        <xsl:for-each select="seg[key(&quot;segmentById&quot;,@id)]">
940                                                <xsl:variable name="segmentId" select="@id"/>
941                                                <xsl:variable name="currentSegmentToNodeId" select="key(&quot;segmentById&quot;,@id)/@to"/>
942                                                <xsl:variable name="currentSegmentFromNodeId" select="key(&quot;segmentById&quot;,@id)/@from"/>
943                                                <xsl:variable name="previousSegmentToNodeId" select="key(&quot;segmentById&quot;,preceding-sibling::seg[1]/@id)/@to"/>
944                                               
945                                                <!-- The linkedSegment flag indicates whether the previous segment is connected to the current segment.  If it isn't
946                                                     then we will need to draw an additional line (segmentLineToStart) from the end of the previous segment to the
947                                                     start of the current segment.
948                                                -->
949                                                <xsl:variable name="linkedSegment" select="key(&quot;segmentById&quot;,@id)/@from=$previousSegmentToNodeId"/>
950               
951                                                <!--  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.
952                                                      We do this to find out if the current segment is connected from some other segment in the way.  If it is, and it
953                                                      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
954                                                      draw an additional line between the end of the previous segment and the start of the current segment.
955                                                -->
956                                                <xsl:variable name="connectedSegmentCount" select="count(../*[key(&quot;segmentById&quot;,@id)/@to=$currentSegmentFromNodeId])"/>
957                                               
958                                                <xsl:variable name="segmentSequence" select="position()"/>
959                                                <xsl:for-each select="key(&quot;segmentById&quot;,$segmentId)">
960                                                        <xsl:choose>
961                                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
962                                                                <xsl:when test="$segmentSequence=1">
963                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
964                                                                </xsl:when>
965                                                                <!-- If the segment is "connected" to another segment (at the from end) but is not linked to the
966                                                                         previous segment, then start a new sub-path -->
967                                                                <xsl:when test="$connectedSegmentCount&gt;0 and not($linkedSegment)">
968                                                                        <xsl:text>Z</xsl:text>
969                                                                        <xsl:call-template name="segmentMoveToStart"/>                         
970                                                                </xsl:when>
971                                                                <!-- If the previous segment is not linked to this one we need to draw an artificial line -->
972                                                                <xsl:when test="not($linkedSegment)">
973                                                                        <xsl:call-template name="segmentLineToStart"/>                         
974                                                                </xsl:when>
975                                                        </xsl:choose>
976                                                        <xsl:call-template name="segmentLineToEnd"/>
977                                                </xsl:for-each>
978                                        </xsl:for-each>
979                                        <xsl:text>Z</xsl:text> 
980                                </xsl:otherwise>
981                        </xsl:choose>
982                </xsl:variable>
983
984                <path id="area_{@id}" d="{$pathData}"/>
985
986        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToStart">
987        <xsl:variable name="from" select="@from"/>
988        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
989
990        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
991        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
992        <xsl:text>M</xsl:text>
993        <xsl:value-of select="$x1"/>
994        <xsl:text> </xsl:text>
995        <xsl:value-of select="$y1"/>
996    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToStart">
997        <xsl:variable name="from" select="@from"/>
998        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
999
1000        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
1001        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
1002        <xsl:text>L</xsl:text>
1003        <xsl:value-of select="$x1"/>
1004        <xsl:text> </xsl:text>
1005        <xsl:value-of select="$y1"/>
1006    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToEnd">
1007        <xsl:variable name="to" select="@to"/>
1008        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
1009
1010        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
1011        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
1012        <xsl:text>M</xsl:text>
1013        <xsl:value-of select="$x2"/>
1014        <xsl:text> </xsl:text>
1015        <xsl:value-of select="$y2"/>
1016    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToEnd">
1017        <xsl:variable name="to" select="@to"/>
1018        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
1019
1020        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
1021        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
1022        <xsl:text>L</xsl:text>
1023        <xsl:value-of select="$x2"/>
1024        <xsl:text> </xsl:text>
1025        <xsl:value-of select="$y2"/>
1026    </xsl:template>
1027    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@class" mode="copyAttributes">
1028        <xsl:param name="classes"/>
1029        <xsl:attribute name="class">
1030            <xsl:value-of select="normalize-space(concat($classes,' ',.))"/>
1031        </xsl:attribute>
1032    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@type|@ref|@scale" mode="copyAttributes">
1033    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="copyAttributes">
1034        <xsl:param name="classes"/>
1035        <xsl:copy/>
1036    </xsl:template>
1037
1038    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processRules">
1039     
1040        <xsl:choose>
1041
1042            <!-- Process all the rules, one layer at a time -->
1043            <xsl:when test="$withOSMLayers='yes'">
1044                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-5&quot;"/></xsl:call-template>
1045                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-4&quot;"/></xsl:call-template>
1046                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-3&quot;"/></xsl:call-template>
1047                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-2&quot;"/></xsl:call-template>
1048                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-1&quot;"/></xsl:call-template>
1049                <xsl:call-template name="processLayer">
1050                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
1051                    <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;]]"/>
1052                </xsl:call-template>
1053                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;1&quot;"/></xsl:call-template>
1054                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;2&quot;"/></xsl:call-template>
1055                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;3&quot;"/></xsl:call-template>
1056                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;4&quot;"/></xsl:call-template>
1057                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;5&quot;"/></xsl:call-template>
1058            </xsl:when>
1059
1060            <!-- Process all the rules, without looking at the layers -->
1061            <xsl:otherwise>
1062                <xsl:apply-templates select="/rules/rule">
1063                    <xsl:with-param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;)]"/>
1064                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
1065                    <xsl:with-param name="classes" select="''"/>
1066                </xsl:apply-templates>
1067            </xsl:otherwise>
1068
1069        </xsl:choose>
1070        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="processLayer">
1071        <xsl:param name="layer"/>
1072        <xsl:param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;) and tag[@k=&quot;layer&quot; and @v=$layer]]"/>
1073
1074        <g inkscape:groupmode="layer" id="layer{$layer}" inkscape:label="Layer {$layer}">
1075            <xsl:apply-templates select="/rules/rule">
1076                <xsl:with-param name="elements" select="$elements"/>
1077                <xsl:with-param name="layer" select="$layer"/>
1078                <xsl:with-param name="classes" select="''"/>
1079            </xsl:apply-templates>
1080        </g>
1081    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="rule">
1082        <xsl:param name="elements"/>
1083        <xsl:param name="layer"/>
1084        <xsl:param name="classes"/>
1085
1086        <!-- This is the rule currently being processed -->
1087        <xsl:variable name="rule" select="."/>
1088
1089        <!-- Make list of elements that this rule should be applied to -->
1090        <xsl:variable name="eBare">
1091            <xsl:choose>
1092                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
1093                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
1094                <xsl:otherwise>node|segment|way</xsl:otherwise>
1095            </xsl:choose>
1096        </xsl:variable>
1097
1098        <!-- List of keys that this rule should be applied to -->
1099        <xsl:variable name="kBare" select="$rule/@k"/>
1100
1101        <!-- List of values that this rule should be applied to -->
1102        <xsl:variable name="vBare" select="$rule/@v"/>
1103
1104        <!-- Top'n'tail selectors with | for contains usage -->
1105        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
1106        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
1107        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
1108
1109        <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))]"/>
1110
1111        <xsl:choose>
1112            <xsl:when test="contains($k,&quot;|*|&quot;)">
1113                <xsl:choose>
1114                    <xsl:when test="contains($v,&quot;|~|&quot;)">
1115                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
1116                        <xsl:call-template name="processElements">
1117                            <xsl:with-param name="eBare" select="$eBare"/>
1118                            <xsl:with-param name="kBare" select="$kBare"/>
1119                            <xsl:with-param name="vBare" select="$vBare"/>
1120                            <xsl:with-param name="layer" select="$layer"/>
1121                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
1122                            <xsl:with-param name="rule" select="$rule"/>
1123                            <xsl:with-param name="classes" select="$classes"/>
1124                        </xsl:call-template>
1125                    </xsl:when>
1126                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1127                        <xsl:variable name="allElements" select="$selectedElements"/>
1128                        <xsl:call-template name="processElements">
1129                            <xsl:with-param name="eBare" select="$eBare"/>
1130                            <xsl:with-param name="kBare" select="$kBare"/>
1131                            <xsl:with-param name="vBare" select="$vBare"/>
1132                            <xsl:with-param name="layer" select="$layer"/>
1133                            <xsl:with-param name="elements" select="$allElements"/>
1134                            <xsl:with-param name="rule" select="$rule"/>
1135                            <xsl:with-param name="classes" select="$classes"/>
1136                        </xsl:call-template>
1137                    </xsl:when>
1138                    <xsl:otherwise>
1139                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1140                        <xsl:call-template name="processElements">
1141                            <xsl:with-param name="eBare" select="$eBare"/>
1142                            <xsl:with-param name="kBare" select="$kBare"/>
1143                            <xsl:with-param name="vBare" select="$vBare"/>
1144                            <xsl:with-param name="layer" select="$layer"/>
1145                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1146                            <xsl:with-param name="rule" select="$rule"/>
1147                            <xsl:with-param name="classes" select="$classes"/>
1148                        </xsl:call-template>
1149                    </xsl:otherwise>
1150                </xsl:choose>
1151            </xsl:when>
1152            <xsl:when test="contains($v,&quot;|~|&quot;)">
1153                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1154                <xsl:call-template name="processElements">
1155                    <xsl:with-param name="eBare" select="$eBare"/>
1156                    <xsl:with-param name="kBare" select="$kBare"/>
1157                    <xsl:with-param name="vBare" select="$vBare"/>
1158                    <xsl:with-param name="layer" select="$layer"/>
1159                    <xsl:with-param name="elements" select="$elementsWithoutKey"/>
1160                    <xsl:with-param name="rule" select="$rule"/>
1161                    <xsl:with-param name="classes" select="$classes"/>
1162                </xsl:call-template>
1163            </xsl:when>
1164            <xsl:when test="contains($v,&quot;|*|&quot;)">
1165                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1166                <xsl:call-template name="processElements">
1167                    <xsl:with-param name="eBare" select="$eBare"/>
1168                    <xsl:with-param name="kBare" select="$kBare"/>
1169                    <xsl:with-param name="vBare" select="$vBare"/>
1170                    <xsl:with-param name="layer" select="$layer"/>
1171                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1172                    <xsl:with-param name="rule" select="$rule"/>
1173                    <xsl:with-param name="classes" select="$classes"/>
1174                </xsl:call-template>
1175            </xsl:when>
1176            <xsl:otherwise>
1177                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1178                <xsl:call-template name="processElements">
1179                    <xsl:with-param name="eBare" select="$eBare"/>
1180                    <xsl:with-param name="kBare" select="$kBare"/>
1181                    <xsl:with-param name="vBare" select="$vBare"/>
1182                    <xsl:with-param name="layer" select="$layer"/>
1183                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1184                    <xsl:with-param name="rule" select="$rule"/>
1185                    <xsl:with-param name="classes" select="$classes"/>
1186                </xsl:call-template>
1187            </xsl:otherwise>
1188        </xsl:choose>
1189    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElements">
1190        <xsl:param name="eBare"/>
1191        <xsl:param name="kBare"/>
1192        <xsl:param name="vBare"/>
1193        <xsl:param name="layer"/>
1194        <xsl:param name="elements"/>
1195        <xsl:param name="rule"/>
1196        <xsl:param name="classes"/>
1197       
1198        <xsl:if test="$elements">
1199            <xsl:message>
1200Processing &lt;rule e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1201Matched by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1202            </xsl:message>
1203
1204            <xsl:apply-templates select="*">
1205                <xsl:with-param name="layer" select="$layer"/>
1206                <xsl:with-param name="elements" select="$elements"/>
1207                <xsl:with-param name="rule" select="$rule"/>
1208                <xsl:with-param name="classes" select="$classes"/>
1209            </xsl:apply-templates>
1210        </xsl:if>
1211    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="addclass">
1212        <xsl:param name="elements"/>
1213        <xsl:param name="layer"/>
1214        <xsl:param name="classes"/>
1215
1216        <!-- This is the rule currently being processed -->
1217        <xsl:variable name="rule" select="."/>
1218
1219        <!-- Additional classes from class attribute of this rule -->
1220        <xsl:variable name="addclasses" select="@class"/>
1221
1222        <!-- Make list of elements that this rule should be applied to -->
1223        <xsl:variable name="eBare">
1224            <xsl:choose>
1225                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
1226                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
1227                <xsl:otherwise>node|segment|way</xsl:otherwise>
1228            </xsl:choose>
1229        </xsl:variable>
1230
1231        <!-- List of keys that this rule should be applied to -->
1232        <xsl:variable name="kBare" select="$rule/@k"/>
1233
1234        <!-- List of values that this rule should be applied to -->
1235        <xsl:variable name="vBare" select="$rule/@v"/>
1236
1237        <!-- Top'n'tail selectors with | for contains usage -->
1238        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
1239        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
1240        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
1241
1242        <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))]"/>
1243
1244        <xsl:choose>
1245            <xsl:when test="contains($k,&quot;|*|&quot;)">
1246                <xsl:choose>
1247                    <xsl:when test="contains($v,&quot;|~|&quot;)">
1248                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
1249                        <xsl:call-template name="processElementsForAddClass">
1250                            <xsl:with-param name="eBare" select="$eBare"/>
1251                            <xsl:with-param name="kBare" select="$kBare"/>
1252                            <xsl:with-param name="vBare" select="$vBare"/>
1253                            <xsl:with-param name="layer" select="$layer"/>
1254                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
1255                            <xsl:with-param name="rule" select="$rule"/>
1256                            <xsl:with-param name="classes" select="$classes"/>
1257                            <xsl:with-param name="addclasses" select="$addclasses"/>
1258                            <xsl:with-param name="allelements" select="$elements"/>
1259                        </xsl:call-template>
1260                    </xsl:when>
1261                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1262                        <xsl:variable name="allElements" select="$selectedElements"/>
1263                        <xsl:call-template name="processElementsForAddClass">
1264                            <xsl:with-param name="eBare" select="$eBare"/>
1265                            <xsl:with-param name="kBare" select="$kBare"/>
1266                            <xsl:with-param name="vBare" select="$vBare"/>
1267                            <xsl:with-param name="layer" select="$layer"/>
1268                            <xsl:with-param name="elements" select="$allElements"/>
1269                            <xsl:with-param name="rule" select="$rule"/>
1270                            <xsl:with-param name="classes" select="$classes"/>
1271                            <xsl:with-param name="addclasses" select="$addclasses"/>
1272                            <xsl:with-param name="allelements" select="$elements"/>
1273                        </xsl:call-template>
1274                    </xsl:when>
1275                    <xsl:otherwise>
1276                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1277                        <xsl:call-template name="processElementsForAddClass">
1278                            <xsl:with-param name="eBare" select="$eBare"/>
1279                            <xsl:with-param name="kBare" select="$kBare"/>
1280                            <xsl:with-param name="vBare" select="$vBare"/>
1281                            <xsl:with-param name="layer" select="$layer"/>
1282                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1283                            <xsl:with-param name="rule" select="$rule"/>
1284                            <xsl:with-param name="classes" select="$classes"/>
1285                            <xsl:with-param name="addclasses" select="$addclasses"/>
1286                            <xsl:with-param name="allelements" select="$elements"/>
1287                        </xsl:call-template>
1288                    </xsl:otherwise>
1289                </xsl:choose>
1290            </xsl:when>
1291            <xsl:when test="contains($v,&quot;|~|&quot;)">
1292                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1293                <xsl:call-template name="processElementsForAddClass">
1294                    <xsl:with-param name="eBare" select="$eBare"/>
1295                    <xsl:with-param name="kBare" select="$kBare"/>
1296                    <xsl:with-param name="vBare" select="$vBare"/>
1297                    <xsl:with-param name="layer" select="$layer"/>
1298                    <xsl:with-param name="elements" select="$elementsWithoutKey"/>
1299                    <xsl:with-param name="rule" select="$rule"/>
1300                    <xsl:with-param name="classes" select="$classes"/>
1301                    <xsl:with-param name="addclasses" select="$addclasses"/>
1302                    <xsl:with-param name="allelements" select="$elements"/>
1303                </xsl:call-template>
1304            </xsl:when>
1305            <xsl:when test="contains($v,&quot;|*|&quot;)">
1306                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1307                <xsl:call-template name="processElementsForAddClass">
1308                    <xsl:with-param name="eBare" select="$eBare"/>
1309                    <xsl:with-param name="kBare" select="$kBare"/>
1310                    <xsl:with-param name="vBare" select="$vBare"/>
1311                    <xsl:with-param name="layer" select="$layer"/>
1312                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1313                    <xsl:with-param name="rule" select="$rule"/>
1314                    <xsl:with-param name="classes" select="$classes"/>
1315                    <xsl:with-param name="addclasses" select="$addclasses"/>
1316                    <xsl:with-param name="allelements" select="$elements"/>
1317                </xsl:call-template>
1318            </xsl:when>
1319            <xsl:otherwise>
1320                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1321                <xsl:call-template name="processElementsForAddClass">
1322                    <xsl:with-param name="eBare" select="$eBare"/>
1323                    <xsl:with-param name="kBare" select="$kBare"/>
1324                    <xsl:with-param name="vBare" select="$vBare"/>
1325                    <xsl:with-param name="layer" select="$layer"/>
1326                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1327                    <xsl:with-param name="rule" select="$rule"/>
1328                    <xsl:with-param name="classes" select="$classes"/>
1329                    <xsl:with-param name="addclasses" select="$addclasses"/>
1330                    <xsl:with-param name="allelements" select="$elements"/>
1331                </xsl:call-template>
1332            </xsl:otherwise>
1333        </xsl:choose>
1334    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElementsForAddClass">
1335        <xsl:param name="eBare"/>
1336        <xsl:param name="kBare"/>
1337        <xsl:param name="vBare"/>
1338        <xsl:param name="layer"/>
1339        <xsl:param name="elements"/>
1340        <xsl:param name="allelements"/>
1341        <xsl:param name="rule"/>
1342        <xsl:param name="classes"/>
1343        <xsl:param name="addclasses"/>
1344       
1345        <xsl:variable name="newclasses" select="concat($classes,' ',$addclasses)"/>
1346        <xsl:variable name="otherelements" select="set:difference($allelements, $elements)"/>
1347
1348        <xsl:if test="$elements">
1349            <xsl:message>
1350Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1351Positive match by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1352            </xsl:message>
1353
1354            <xsl:apply-templates select="*">
1355                <xsl:with-param name="layer" select="$layer"/>
1356                <xsl:with-param name="elements" select="$elements"/>
1357                <xsl:with-param name="rule" select="$rule"/>
1358                <xsl:with-param name="classes" select="$newclasses"/>
1359            </xsl:apply-templates>
1360        </xsl:if>
1361
1362        <xsl:if test="$otherelements">
1363            <xsl:message>
1364Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1365Negative match by <xsl:value-of select="count($otherelements)"/> elements for layer <xsl:value-of select="$layer"/>.
1366            </xsl:message>
1367            <xsl:apply-templates select="*">
1368                <xsl:with-param name="layer" select="$layer"/>
1369                <xsl:with-param name="elements" select="$otherelements"/>
1370                <xsl:with-param name="rule" select="$rule"/>
1371                <xsl:with-param name="classes" select="$classes"/>
1372            </xsl:apply-templates>
1373        </xsl:if>
1374    </xsl:template>
1375    <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">
1376        <xsl:param name="elements"/>
1377        <xsl:param name="layer"/>
1378        <xsl:param name="rule"/>
1379        <xsl:param name="classes"/>
1380
1381        <xsl:message>Processing SVG layer: <xsl:value-of select="@name"/> (at OSM layer <xsl:value-of select="$layer"/>)
1382</xsl:message>
1383
1384        <xsl:variable name="opacity">
1385            <xsl:if test="@opacity">
1386                <xsl:value-of select="concat('opacity:',@opacity,';')"/>
1387            </xsl:if>
1388        </xsl:variable>
1389
1390        <xsl:variable name="display">
1391            <xsl:if test="(@display='none') or (@display='off')">
1392                <xsl:text>display:none;</xsl:text>
1393            </xsl:if>
1394        </xsl:variable>
1395
1396        <g inkscape:groupmode="layer" id="{@name}-{$layer}" inkscape:label="{@name}">
1397            <xsl:if test="concat($opacity,$display)!=''">
1398                <xsl:attribute name="style">
1399                    <xsl:value-of select="concat($opacity,$display)"/>
1400                </xsl:attribute>
1401            </xsl:if>
1402            <xsl:apply-templates select="*">
1403                <xsl:with-param name="layer" select="$layer"/>
1404                <xsl:with-param name="elements" select="$elements"/>
1405                <xsl:with-param name="classes" select="$classes"/>
1406            </xsl:apply-templates>
1407        </g>
1408
1409    </xsl:template>
1410   
1411    <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">
1412        <!-- dasharray definitions here can be overridden in stylesheet -->
1413        <g id="border" inkscape:groupmode="layer" inkscape:label="Map Border">
1414            <line id="border-left-casing" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1415            <line id="border-top-casing" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1416            <line id="border-bottom-casing" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1417            <line id="border-right-casing" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1418
1419            <line id="border-left-core" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1420            <line id="border-top-core" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1421            <line id="border-bottom-core" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1422            <line id="border-right-core" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1423        </g>
1424    </xsl:template>
1425    <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">
1426        <g id="grid" inkscape:groupmode="layer" inkscape:label="Grid">
1427            <xsl:call-template name="gridDrawHorizontals">
1428                <xsl:with-param name="line" select="&quot;1&quot;"/>
1429            </xsl:call-template>
1430            <xsl:call-template name="gridDrawVerticals">
1431                <xsl:with-param name="line" select="&quot;1&quot;"/>
1432            </xsl:call-template>
1433        </g>
1434    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawHorizontals">
1435        <xsl:param name="line"/>
1436        <xsl:if test="($line*$km) &lt; $documentHeight">
1437            <line id="grid-hori-{$line}" x1="0px" y1="{$line*$km}px" x2="{$documentWidth}px" y2="{$line*$km}px" class="map-grid-line"/>
1438            <xsl:call-template name="gridDrawHorizontals">
1439                <xsl:with-param name="line" select="$line+1"/>
1440            </xsl:call-template>
1441        </xsl:if>
1442    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawVerticals">
1443        <xsl:param name="line"/>
1444        <xsl:if test="($line*$km) &lt; $documentWidth">
1445            <line id="grid-vert-{$line}" x1="{$line*$km}px" y1="0px" x2="{$line*$km}px" y2="{$documentHeight}px" class="map-grid-line"/>
1446            <xsl:call-template name="gridDrawVerticals">
1447                <xsl:with-param name="line" select="$line+1"/>
1448            </xsl:call-template>
1449        </xsl:if>
1450    </xsl:template>
1451
1452    <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">
1453        <xsl:param name="title"/>
1454
1455        <xsl:variable name="x" select="$documentWidth div 2"/>
1456        <xsl:variable name="y" select="30"/>
1457
1458        <g id="marginalia-title" inkscape:groupmode="layer" inkscape:label="Title">
1459            <rect id="marginalia-title-background" x="0px" y="0px" height="{$marginaliaTopHeight - 5}px" width="{$documentWidth}px" class="map-title-background"/>
1460            <text id="marginalia-title-text" class="map-title" x="{$x}" y="{$y}"><xsl:value-of select="$title"/></text>
1461        </g>
1462    </xsl:template>
1463    <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">
1464        <xsl:variable name="x1" select="14"/>
1465        <xsl:variable name="y1" select="round(($documentHeight)+((($bottomLeftLatitude)-(number($bottomLeftLatitude)))*10000*$scale*$projection))+28"/>
1466        <xsl:variable name="x2" select="$x1+$km"/>
1467        <xsl:variable name="y2" select="$y1"/>
1468
1469        <g id="marginalia-scale" inkscape:groupmode="layer" inkscape:label="Scale">
1470            <line id="marginalia-scale-casing" class="map-scale-casing" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1471
1472            <line id="marginalia-scale-core" class="map-scale-core" stroke-dasharray="{($km div 10)}" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1473
1474            <line id="marginalia-scale-bookend-from" class="map-scale-bookend" x1="{$x1}" y1="{$y1 + 2}" x2="{$x1}" y2="{$y1 - 10}"/>
1475
1476            <line id="marginalia-scale-bookend-to" class="map-scale-bookend" x1="{$x2}" y1="{$y2 + 2}" x2="{$x2}" y2="{$y2 - 10}"/>
1477
1478            <text id="marginalia-scale-text-from" class="map-scale-caption" x="{$x1}" y="{$y1 - 10}">0</text>
1479
1480            <text id="marginalia-scale-text-to" class="map-scale-caption" x="{$x2}" y="{$y2 - 10}">1km</text>
1481        </g>
1482    </xsl:template>
1483    <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">
1484        <xsl:variable name="date" select="date:date()"/>
1485        <xsl:variable name="year" select="date:year()"/>
1486
1487        <xsl:comment>
1488
1489    Copyright (c) <xsl:value-of select="$year"/> OpenStreetMap
1490    www.openstreetmap.org
1491    This work is licensed under the
1492    Creative Commons Attribution-ShareAlike 2.0 License.
1493    http://creativecommons.org/licenses/by-sa/2.0/
1494
1495</xsl:comment>
1496        <metadata id="metadata">
1497            <rdf:RDF xmlns="http://web.resource.org/cc/">
1498                <cc:Work rdf:about="">
1499                    <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
1500                    <dc:format>image/svg+xml</dc:format>
1501                    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
1502                    <dc:title><xsl:value-of select="$title"/></dc:title>
1503                    <dc:date><xsl:value-of select="substring($date,1,10)"/></dc:date>
1504                    <dc:source>http://www.openstreetmap.org/</dc:source>
1505                </cc:Work>
1506                <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
1507                    <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
1508                    <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
1509                    <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
1510                    <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
1511                    <cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
1512                    <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
1513                </cc:License>
1514            </rdf:RDF>
1515        </metadata>
1516    </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">
1517        <xsl:param name="dx"/>
1518        <xsl:param name="dy"/>
1519
1520        <xsl:variable name="year" select="date:year()"/>
1521
1522        <g id="license" inkscape:groupmode="layer" inkscape:label="Copyright" transform="translate({$dx},{$dy})">
1523            <style type="text/css"><![CDATA[
1524                .license-text {
1525                    text-anchor: left;
1526                    font-family: "DejaVu Sans",sans-serif;
1527                    font-size: 6px;
1528                    fill: black;
1529                }
1530            ]]></style>
1531            <a id="license-cc-logo-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1532                <g id="license-cc-logo" transform="scale(0.5,0.5) translate(-604,-49)">
1533                    <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"/>
1534                    <g id="g5908_2_" transform="matrix(0.872921,0,0,0.872921,50.12536,143.2144)">
1535                        <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"/>
1536                        <g id="g5706_2_" transform="translate(-289.6157,99.0653)">
1537                            <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 "/>
1538                        </g>
1539                    </g>
1540                    <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"/>
1541                    <g enable-background="new" id="g2821">
1542                        <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"/>
1543                        <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"/>
1544                    </g>
1545                    <g enable-background="new" id="g2827">
1546                        <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"/>
1547                        <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"/>
1548                    </g>
1549                    <g id="g6316_1_" transform="matrix(0.624995,0,0,0.624995,391.2294,176.9332)">
1550                        <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"/>
1551                        <g id="g6320_1_" transform="translate(-23.9521,-89.72962)">
1552                            <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 "/>
1553                            <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 "/>
1554                        </g>
1555                    </g>
1556                    <g id="g2838">
1557                        <circle cx="242.56226" cy="90.224609" r="10.8064" id="circle2840" style="fill:white"/>
1558                        <g id="g2842">
1559                            <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"/>
1560                            <circle cx="242.5498" cy="84.083008" r="1.63232" id="circle2846"/>
1561                        </g>
1562                        <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"/>
1563                    </g>
1564                </g>
1565            </a>
1566            <a id="license-osm-link" xlink:href="http://www.openstreetmap.org/">
1567                <g transform="translate(-210,10)" id="license-osm-text">
1568                    <text class="license-text" dx="0" dy="0">Copyright © <xsl:value-of select="$year"/> OpenStreetMap (openstreetmap.org)</text>
1569                </g>
1570            </a>
1571            <a id="license-cc-text-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1572                <g transform="translate(-150,18)" id="license-cc-text">
1573                    <text class="license-text" dx="0" dy="0">This work is licensed under the Creative</text>
1574                    <text class="license-text" dx="0" dy="8">Commons Attribution-ShareAlike 2.0 License.</text>
1575                    <text class="license-text" dx="0" dy="16">http://creativecommons.org/licenses/by-sa/2.0/</text>
1576                </g>
1577            </a>
1578        </g>
1579    </xsl:template>
1580
1581    <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">
1582        <defs>
1583
1584            <style type="text/css">
1585              .fancyButton {
1586                stroke: #8080ff;
1587                stroke-width: 2px;
1588                fill: #fefefe;
1589                }
1590              .fancyButton:hover {
1591                stroke: red;
1592                }
1593            </style>
1594
1595            <filter id="fancyButton" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="350">
1596                <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
1597                <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
1598                <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" specularExponent="20" lighting-color="white" result="specOut">
1599                    <fePointLight x="-5000" y="-10000" z="7000"/>
1600                </feSpecularLighting>
1601                <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
1602                <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
1603                <feMerge>
1604                    <feMergeNode in="offsetBlur"/>
1605                    <feMergeNode in="litPaint"/>
1606                </feMerge>
1607            </filter>
1608            <symbol id="panDown" viewBox="0 0 19 19" class="fancyButton">
1609                <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"/>
1610                <path d="M 9.5,5 L 9.5,14"/>
1611            </symbol>
1612            <symbol id="panUp" viewBox="0 0 19 19" class="fancyButton">
1613                <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"/>
1614                <path d="M 9.5,5 L 9.5,14"/>
1615            </symbol>
1616            <symbol id="panLeft" viewBox="0 0 19 19" class="fancyButton">
1617                <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"/>
1618                <path d="M 5,9.5 L 14,9.5"/>
1619            </symbol>
1620            <symbol id="panRight" viewBox="0 0 19 19" class="fancyButton">
1621                <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"/>
1622                <path d="M 5,9.5 L 14,9.5"/>
1623            </symbol>
1624            <symbol id="zoomIn" viewBox="0 0 19 19" class="fancyButton">
1625                <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"/>
1626                <path d="M 5,9.5 L 14,9.5 M 9.5,5 L 9.5,14"/>
1627            </symbol>
1628            <symbol id="zoomOut" viewBox="0 0 19 19" class="fancyButton">
1629                <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"/>
1630                <path d="M 5,9.5 L 14,9.5"/>
1631            </symbol>
1632
1633        </defs>
1634
1635        <g id="gPanDown" filter="url(#fancyButton)" onclick="fnPan(&quot;down&quot;)">
1636            <use x="18px" y="60px" xlink:href="#panDown" width="14px" height="14px"/>
1637        </g>
1638        <g id="gPanRight" filter="url(#fancyButton)" onclick="fnPan(&quot;right&quot;)">
1639            <use x="8px" y="70px" xlink:href="#panRight" width="14px" height="14px"/>
1640        </g>
1641        <g id="gPanLeft" filter="url(#fancyButton)" onclick="fnPan(&quot;left&quot;)">
1642            <use x="28px" y="70px" xlink:href="#panLeft" width="14px" height="14px"/>
1643        </g>
1644        <g id="gPanUp" filter="url(#fancyButton)" onclick="fnPan(&quot;up&quot;)">
1645            <use x="18px" y="80px" xlink:href="#panUp" width="14px" height="14px"/>
1646        </g>
1647
1648        <xsl:variable name="x1" select="25"/>
1649        <xsl:variable name="y1" select="105"/>
1650        <xsl:variable name="x2" select="25"/>
1651        <xsl:variable name="y2" select="300"/>
1652
1653        <line style="stroke-width: 10; stroke-linecap: butt; stroke: #8080ff;">
1654            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1655            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1656            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1657            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1658        </line>
1659
1660        <line style="stroke-width: 8; stroke-linecap: butt; stroke: white; stroke-dasharray: 10,1;">
1661            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1662            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1663            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1664            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1665        </line>
1666
1667        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1668        <g id="gZoomIn" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;in&quot;)">
1669            <use x="15.5px" y="100px" xlink:href="#zoomIn" width="19px" height="19px"/>
1670        </g>
1671
1672        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1673        <g id="gZoomOut" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;out&quot;)">
1674            <use x="15.5px" y="288px" xlink:href="#zoomOut" width="19px" height="19px"/>
1675        </g>
1676    </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">
1677        <script>
1678            /*
1679
1680Osmarender
1681
1682interactive.js
1683
1684*/
1685
1686function fnResize() {
1687    fnResizeElement("gAttribution")
1688    fnResizeElement("gLicense")
1689    fnResizeElement("gZoomIn")
1690    fnResizeElement("gZoomOut")
1691}
1692
1693
1694function fnResizeElement(e) {
1695    //
1696    var oSVG,scale,currentTranslateX,currentTranslateY,oe
1697    //
1698    oSVG=document.rootElement
1699    scale=1/oSVG.currentScale
1700    currentTranslateX=oSVG.currentTranslate.x
1701    currentTranslateY=oSVG.currentTranslate.y
1702    oe=document.getElementById(e)
1703    if (oe) oe.setAttributeNS(null,"transform","scale("+scale+","+scale+") translate("+(-currentTranslateX)+","+(-currentTranslateY)+")")
1704}
1705
1706
1707function fnToggleImage(osmImage) {
1708    var xlink = 'http://www.w3.org/1999/xlink';
1709    ogThumbnail=document.getElementById('gThumbnail')
1710    if (ogThumbnail.getAttributeNS(null,"visibility")=="visible") fnHideImage()
1711    else {
1712        ogThumbnail.setAttributeNS(null,"visibility","visible")
1713        oThumbnail=document.getElementById('thumbnail')
1714        oThumbnail.setAttributeNS(xlink,"href",osmImage)
1715    }
1716}
1717
1718function fnHideImage() {
1719    ogThumbnail=document.getElementById('gThumbnail')
1720    ogThumbnail.setAttributeNS(null,"visibility","hidden")
1721}
1722
1723
1724/* The following code originally written by Jonathan Watt (http://jwatt.org/), Aug. 2005 */
1725
1726if (!window)
1727window = this;
1728
1729
1730function fnOnLoad(evt) {
1731    if (!document) window.document = evt.target.ownerDocument
1732}
1733
1734
1735/**
1736  * Event handlers to change the current user space for the zoom and pan
1737  * controls to make them appear to be scale invariant.
1738  */
1739
1740function fnOnZoom(evt) {
1741    try {
1742        if (evt.newScale === undefined) throw 'bad interface'
1743        // update the transform list that adjusts for zoom and pan
1744        var tlist = document.getElementById('staticElements').transform.baseVal
1745        tlist.getItem(0).setScale(1/evt.newScale, 1/evt.newScale)
1746        tlist.getItem(1).setTranslate(-evt.newTranslate.x, -evt.newTranslate.y)
1747        }
1748    catch (e) {
1749        // work around difficiencies in non-moz implementations (some don't
1750        // implement the SVGZoomEvent or SVGAnimatedTransform interfaces)
1751        var de = document.documentElement
1752        var tform = 'scale(' + 1/de.currentScale + ') ' + 'translate(' + (-de.currentTranslate.x) + ', ' + (-de.currentTranslate.y) + ')'
1753        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1754        }
1755    }
1756
1757
1758function fnOnScroll(evt) {
1759    var ct = document.documentElement.currentTranslate
1760    try {
1761        // update the transform list that adjusts for zoom and pan
1762        var tlist = document.getElementById('staticElements').transform.baseVal
1763        tlist.getItem(1).setTranslate(-ct.x, -ct.y)
1764        }
1765    catch (e) {
1766        // work around difficiencies in non-moz implementations (some don't
1767        // implement the SVGAnimatedTransform interface)
1768        var tform = 'scale(' + 1/document.documentElement.currentScale + ') ' + 'translate(' + (-ct.x) + ', ' + (-ct.y) + ')';
1769        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1770        }
1771    }
1772
1773
1774function fnZoom(type) {
1775    var de = document.documentElement;
1776    var oldScale = de.currentScale;
1777    var oldTranslate = { x: de.currentTranslate.x, y: de.currentTranslate.y };
1778    var s = 2;
1779    if (type == 'in') {de.currentScale *= 1.5;}
1780    if (type == 'out') {de.currentScale /= 1.4;}
1781    // correct currentTranslate so zooming is to the center of the viewport:
1782
1783    var vp_width, vp_height;
1784    try {
1785        vp_width = de.viewport.width;
1786        vp_height = de.viewport.height;
1787    }
1788    catch (e) {
1789        // work around difficiency in moz ('viewport' property not implemented)
1790        vp_width = window.innerWidth;
1791        vp_height = window.innerHeight;
1792    }
1793    de.currentTranslate.x = vp_width/2 - ((de.currentScale/oldScale) * (vp_width/2 - oldTranslate.x));
1794    de.currentTranslate.y = vp_height/2 - ((de.currentScale/oldScale) * (vp_height/2 - oldTranslate.y));
1795
1796}
1797
1798
1799function fnPan(type) {
1800    var de = document.documentElement;
1801    var ct = de.currentTranslate;
1802    var t = 150;
1803    if (type == 'right') ct.x += t;
1804    if (type == 'down') ct.y += t;
1805    if (type == 'left') ct.x -= t;
1806    if (type == 'up') ct.y -= t;
1807}
1808
1809
1810var gCurrentX,gCurrentY
1811var gDeltaX,gDeltaY
1812var gMouseDown=false
1813var gCurrentTranslate=document.documentElement.currentTranslate
1814
1815function fnOnMouseDown(evt) {
1816    gCurrentX=gCurrentTranslate.x
1817    gCurrentY=gCurrentTranslate.y
1818    gDeltaX=evt.clientX
1819    gDeltaY=evt.clientY
1820    gMouseDown=true
1821    evt.target.ownerDocument.rootElement.setAttributeNS(null,"cursor","move")
1822}
1823
1824
1825function fnOnMouseUp(evt) {
1826    gMouseDown=false
1827    evt.target.ownerDocument.rootElement.setAttribute("cursor","default")
1828}
1829
1830
1831function fnOnMouseMove(evt) {
1832    var id
1833    if (gMouseDown) {
1834        gCurrentTranslate.x=gCurrentX+evt.clientX-gDeltaX
1835        gCurrentTranslate.y=gCurrentY+evt.clientY-gDeltaY
1836    }
1837}
1838
1839
1840        </script>
1841    </xsl:template>
1842
1843</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.