source: subversion/applications/rendering/osmarender/osmAtHome/osmarender.xsl @ 22129

Last change on this file since 22129 was 13622, checked in by stephankn, 11 years ago

text-anchor can not be left

File size: 114.3 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: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: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="withOSMLayers" select="/rules/@withOSMLayers"/>
36    <xsl:param name="withUntaggedSegments" select="/rules/@withUntaggedSegments"/>
37    <xsl:param name="svgBaseProfile" select="/rules/@svgBaseProfile"/>
38
39    <xsl:param name="showGrid" select="/rules/@showGrid"/>
40    <xsl:param name="showBorder" select="/rules/@showBorder"/>
41    <xsl:param name="showScale" select="/rules/@showScale"/>
42    <xsl:param name="showLicense" select="/rules/@showLicense"/>
43
44    <xsl:key name="nodeById" match="/osm/node" use="@id"/>
45    <xsl:key name="segmentById" match="/osm/segment" use="@id"/>
46    <xsl:key name="segmentByFromNode" match="/osm/segment" use="@from"/>
47    <xsl:key name="segmentByToNode" match="/osm/segment" use="@to"/>
48    <xsl:key name="wayBySegment" match="/osm/way" use="seg/@id"/>
49
50    <xsl:variable name="data" select="document($osmfile)"/>
51
52    <!-- extra height for marginalia at top -->
53    <xsl:variable name="marginaliaTopHeight">
54        <xsl:choose>
55            <xsl:when test="$title != ''">40</xsl:when>
56            <xsl:when test="($title = '') and ($showBorder = 'yes')">1.5</xsl:when>
57            <xsl:otherwise>0</xsl:otherwise>
58        </xsl:choose>
59    </xsl:variable>
60
61    <!-- extra height for marginalia at bottom -->
62    <xsl:variable name="marginaliaBottomHeight">
63        <xsl:choose>
64            <xsl:when test="($showScale = 'yes') or ($showLicense = 'yes')">45</xsl:when>
65            <xsl:when test="($showScale != 'yes') and ($showLicense != 'yes') and ($showBorder = 'yes')">1.5</xsl:when>
66            <xsl:otherwise>0</xsl:otherwise>
67        </xsl:choose>
68    </xsl:variable>
69
70    <!-- extra width for border -->
71    <xsl:variable name="extraWidth">
72        <xsl:choose>
73            <xsl:when test="$showBorder = 'yes'">3</xsl:when>
74            <xsl:otherwise>0</xsl:otherwise>
75        </xsl:choose>
76    </xsl:variable>
77
78    <!-- extra height for border -->
79    <xsl:variable name="extraHeight">
80        <xsl:choose>
81            <xsl:when test="($title = '') and ($showBorder = 'yes')">3</xsl:when>
82            <xsl:otherwise>0</xsl:otherwise>
83        </xsl:choose>
84    </xsl:variable>
85
86    <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bllat">
87        <xsl:for-each select="$data/osm/node/@lat">
88            <xsl:sort data-type="number" order="ascending"/>
89            <xsl:if test="position()=1">
90                <xsl:value-of select="."/>
91            </xsl:if>
92        </xsl:for-each>
93    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bllon">
94        <xsl:for-each select="$data/osm/node/@lon">
95            <xsl:sort data-type="number" order="ascending"/>
96            <xsl:if test="position()=1">
97                <xsl:value-of select="."/>
98            </xsl:if>
99        </xsl:for-each>
100    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="trlat">
101        <xsl:for-each select="$data/osm/node/@lat">
102            <xsl:sort data-type="number" order="descending"/>
103            <xsl:if test="position()=1">
104                <xsl:value-of select="."/>
105            </xsl:if>
106        </xsl:for-each>
107    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="trlon">
108        <xsl:for-each select="$data/osm/node/@lon">
109            <xsl:sort data-type="number" order="descending"/>
110            <xsl:if test="position()=1">
111                <xsl:value-of select="."/>
112            </xsl:if>
113        </xsl:for-each>
114    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bottomLeftLatitude">
115        <xsl:choose>
116            <xsl:when test="/rules/bounds">
117                <xsl:value-of select="/rules/bounds/@minlat"/>
118            </xsl:when>
119            <xsl:when test="$data/osm/bounds">
120                <xsl:value-of select="$data/osm/bounds/@request_minlat"/>
121            </xsl:when>
122            <xsl:otherwise>
123                <xsl:value-of select="$bllat"/>
124            </xsl:otherwise>
125        </xsl:choose>
126    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="bottomLeftLongitude">
127        <xsl:choose>
128            <xsl:when test="/rules/bounds">
129                <xsl:value-of select="/rules/bounds/@minlon"/>
130            </xsl:when>
131            <xsl:when test="$data/osm/bounds">
132                <xsl:value-of select="$data/osm/bounds/@request_minlon"/>
133            </xsl:when>
134            <xsl:otherwise>
135                <xsl:value-of select="$bllon"/>
136            </xsl:otherwise>
137        </xsl:choose>
138    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="topRightLatitude">
139        <xsl:choose>
140            <xsl:when test="/rules/bounds">
141                <xsl:value-of select="/rules/bounds/@maxlat"/>
142            </xsl:when>
143            <xsl:when test="$data/osm/bounds">
144                <xsl:value-of select="$data/osm/bounds/@request_maxlat"/>
145            </xsl:when>
146            <xsl:otherwise>
147                <xsl:value-of select="$trlat"/>
148            </xsl:otherwise>
149        </xsl:choose>
150    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="topRightLongitude">
151        <xsl:choose>
152            <xsl:when test="/rules/bounds">
153                <xsl:value-of select="/rules/bounds/@maxlon"/>
154            </xsl:when>
155            <xsl:when test="$data/osm/bounds">
156                <xsl:value-of select="$data/osm/bounds/@request_maxlon"/>
157            </xsl:when>
158            <xsl:otherwise>
159                <xsl:value-of select="$trlon"/>
160            </xsl:otherwise>
161        </xsl:choose>
162    </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">
163        <xsl:choose>
164            <xsl:when test="$dataWidth &gt; (number(/rules/@minimumMapWidth) * $km)">
165                <xsl:value-of select="$dataWidth"/>
166            </xsl:when>
167            <xsl:otherwise><xsl:value-of select="number(/rules/@minimumMapWidth) * $km"/></xsl:otherwise>
168        </xsl:choose>
169    </xsl:variable><xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="documentHeight">
170        <xsl:choose>
171            <xsl:when test="$dataHeight &gt; (number(/rules/@minimumMapHeight) * $km)">
172                <xsl:value-of select="$dataHeight"/>
173            </xsl:when>
174            <xsl:otherwise><xsl:value-of select="number(/rules/@minimumMapHeight) * $km"/></xsl:otherwise>
175        </xsl:choose>
176    </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)"/>
177
178    <!-- Main template -->
179    <xsl:template match="/rules">     
180
181        <!-- Include an external css stylesheet if one was specified in the rules file -->
182        <xsl:if test="@xml-stylesheet">
183            <xsl:processing-instruction name="xml-stylesheet">
184                href="<xsl:value-of select="@xml-stylesheet"/>" type="text/css"
185            </xsl:processing-instruction>
186        </xsl:if>
187
188        <xsl:variable name="svgWidth" select="$documentWidth + $extraWidth"/>
189        <xsl:variable name="svgHeight" select="$documentHeight + $marginaliaTopHeight + $marginaliaBottomHeight"/>
190
191        <svg id="main" version="1.1" baseProfile="{$svgBaseProfile}" width="{$svgWidth}px" height="{$svgHeight}px" viewBox="{-$extraWidth div 2} {-$extraHeight div 2} {$svgWidth} {$svgHeight}">
192            <xsl:if test="/rules/@interactive=&quot;yes&quot;">
193                <xsl:attribute name="onscroll">fnOnScroll(evt)</xsl:attribute>
194                <xsl:attribute name="onzoom">fnOnZoom(evt)</xsl:attribute>
195                <xsl:attribute name="onload">fnOnLoad(evt)</xsl:attribute>
196                <xsl:attribute name="onmousedown">fnOnMouseDown(evt)</xsl:attribute>
197                <xsl:attribute name="onmousemove">fnOnMouseMove(evt)</xsl:attribute>
198                <xsl:attribute name="onmouseup">fnOnMouseUp(evt)</xsl:attribute>
199            </xsl:if>
200
201            <xsl:call-template name="metadata"/>
202
203            <!-- Include javaScript functions for all the dynamic stuff --> 
204            <xsl:if test="/rules/@interactive=&quot;yes&quot;">
205                <xsl:call-template name="javaScript"/>
206            </xsl:if>
207
208            <defs id="defs-rulefile">
209                <!-- Get any <defs> and styles from the rules file -->
210                <xsl:copy-of select="defs/*"/>
211            </defs>
212
213            <!-- Pre-generate named path definitions for all ways -->
214            <xsl:variable name="allWays" select="$data/osm/way"/>
215            <defs id="paths-of-ways">
216                <xsl:for-each select="$allWays">
217                    <xsl:call-template name="generateWayPath"/>
218                </xsl:for-each>
219            </defs>
220
221            <!-- Clipping rectangle for map -->
222            <clipPath id="map-clipping">
223                <rect id="map-clipping-rect" x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px"/>
224            </clipPath>
225
226            <g id="map" clip-path="url(#map-clipping)" inkscape:groupmode="layer" inkscape:label="Map" transform="translate(0,{$marginaliaTopHeight})">
227                <!-- Draw a nice background layer -->
228                <rect id="background" x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px" class="map-background"/>
229
230                <!-- If this is set we first draw all untagged segments not belonging to any way -->
231                <xsl:if test="$withUntaggedSegments=&quot;yes&quot;">
232                    <xsl:call-template name="drawUntaggedSegments"/>
233                </xsl:if>
234
235                <!-- Process all the rules drawing all map features -->
236                <xsl:call-template name="processRules"/>
237            </g>
238
239            <!-- Draw map decoration -->
240            <g id="map-decoration" inkscape:groupmode="layer" inkscape:label="Map decoration" transform="translate(0,{$marginaliaTopHeight})">
241                <!-- Draw a grid if required -->
242                <xsl:if test="$showGrid=&quot;yes&quot;">
243                    <xsl:call-template name="gridDraw"/>
244                </xsl:if>
245
246                <!-- Draw a border if required -->
247                <xsl:if test="$showBorder=&quot;yes&quot;">
248                    <xsl:call-template name="borderDraw"/>
249                </xsl:if>
250            </g>
251
252            <!-- Draw map marginalia -->
253            <xsl:if test="($title != '') or ($showScale = 'yes') or ($showLicense = 'yes')">
254                <g id="marginalia" inkscape:groupmode="layer" inkscape:label="Marginalia">
255                    <!-- Draw the title -->
256                    <xsl:if test="$title!=''">
257                        <xsl:call-template name="titleDraw">
258                            <xsl:with-param name="title" select="$title"/>
259                        </xsl:call-template>
260                    </xsl:if>
261
262                    <xsl:if test="($showScale = 'yes') or ($showLicense = 'yes')">
263                        <g id="marginalia-bottom" inkscape:groupmode="layer" inkscape:label="Marginalia (Bottom)" transform="translate(0,{$marginaliaTopHeight})">
264                            <!-- Draw background for marginalia at bottom -->
265                            <rect id="marginalia-background" x="0px" y="{$documentHeight + 5}px" height="40px" width="{$documentWidth}px" class="map-marginalia-background"/>
266
267                            <!-- Draw the scale in the bottom left corner -->
268                            <xsl:if test="$showScale=&quot;yes&quot;">
269                                <xsl:call-template name="scaleDraw"/>
270                            </xsl:if>
271
272                            <!-- Draw Creative commons license -->
273                            <xsl:if test="$showLicense=&quot;yes&quot;">
274                                <xsl:call-template name="in-image-license">
275                                    <xsl:with-param name="year" select="2007"/>
276                                    <xsl:with-param name="dx" select="$documentWidth"/>
277                                    <xsl:with-param name="dy" select="$documentHeight"/>
278                                </xsl:call-template>
279                            </xsl:if>
280                        </g>
281                    </xsl:if>
282                </g>
283            </xsl:if>
284
285            <!-- Draw labels and controls that are in a static position -->
286            <g id="staticElements" transform="scale(1) translate(0,0)">
287                <!-- Draw the +/- zoom controls -->
288                <xsl:if test="/rules/@interactive=&quot;yes&quot;">
289                    <xsl:call-template name="zoomControl"/>
290                </xsl:if>
291            </g>
292        </svg>
293
294    </xsl:template>
295
296    <!-- include templates from all the other files -->
297    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawLine">
298        <xsl:param name="instruction"/>
299        <xsl:param name="segment"/> <!-- The current segment element -->
300        <xsl:param name="way"/>  <!-- The current way element if applicable -->
301
302        <xsl:variable name="from" select="@from"/>
303        <xsl:variable name="to" select="@to"/>
304        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
305        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
306        <xsl:variable name="fromNodeContinuation" select="(count(key(&quot;segmentByFromNode&quot;,$fromNode/@id))+count(key(&quot;segmentByToNode&quot;,$fromNode/@id)))&gt;1"/>
307        <xsl:variable name="toNodeContinuation" select="(count(key(&quot;segmentByFromNode&quot;,$toNode/@id))+count(key(&quot;segmentByToNode&quot;,$toNode/@id)))&gt;1"/>
308
309        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
310        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
311        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
312        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
313
314        <!-- If this is not the end of a path then draw a stub line with a rounded linecap at the from-node end -->
315        <xsl:if test="$fromNodeContinuation">
316            <xsl:call-template name="drawSegmentFragment">
317                <xsl:with-param name="x1" select="$x1"/>
318                <xsl:with-param name="y1" select="$y1"/>
319                <xsl:with-param name="x2" select="number($x1)+((number($x2)-number($x1)) div 10)"/>
320                <xsl:with-param name="y2" select="number($y1)+((number($y2)-number($y1)) div 10)"/>
321            </xsl:call-template>
322        </xsl:if>
323
324        <!-- If this is not the end of a path then draw a stub line with a rounded linecap at the to-node end -->
325        <xsl:if test="$toNodeContinuation">
326            <xsl:call-template name="drawSegmentFragment">
327                <xsl:with-param name="x1" select="number($x2)-((number($x2)-number($x1)) div 10)"/>
328                <xsl:with-param name="y1" select="number($y2)-((number($y2)-number($y1)) div 10)"/>
329                <xsl:with-param name="x2" select="$x2"/>
330                <xsl:with-param name="y2" select="$y2"/>
331            </xsl:call-template>
332        </xsl:if>
333
334        <line>
335            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
336            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
337            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
338            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
339            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
340        </line>
341
342    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawSegmentFragment">
343        <xsl:param name="x1"/>
344        <xsl:param name="x2"/>
345        <xsl:param name="y1"/>
346        <xsl:param name="y2"/>
347            <line>
348                <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
349                <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
350                <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
351                <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
352                <!-- add the rounded linecap attribute -->
353                <xsl:attribute name="stroke-linecap">round</xsl:attribute>
354                <!-- suppress any markers else these could be drawn in the wrong place -->
355                <xsl:attribute name="marker-start">none</xsl:attribute>
356                <xsl:attribute name="marker-end">none</xsl:attribute>
357                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
358            </line>
359    </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">
360        <xsl:param name="instruction"/>
361        <xsl:param name="way"/>  <!-- The current way element if applicable -->
362        <xsl:param name="layer"/>
363        <xsl:param name="classes"/>
364
365        <xsl:variable name="tunnel" select="$way/tag[@k='tunnel']"/>
366        <xsl:variable name="railway" select="$way/tag[@k='railway' and @v='rail']"/>
367
368        <xsl:if test="not($tunnel and ($tunnel/@v = 'yes') or ($tunnel/@v = 'true'))">  <!-- if this is not a tunnel -->
369
370            <xsl:if test="not($railway)">
371
372                <!-- For the first and last segments in the way if the start or end is a continuation, then draw a round-capped stub segment
373                        that is 1/10th the length of the segment and without any markers.  TODO: do this for all sub-paths within the path.
374                    Count the number of segments that link to the from node of this segment.  Only count them if they belong to a way that
375                    has a layer tag that is greater than the layer of this way.  If there are any such segments then draw rounded
376                    end fragments. -->
377                <!-- Process the first segment in the way -->
378                <xsl:variable name="firstSegment" select="key(&quot;segmentById&quot;,$way/seg[1]/@id)"/>
379                <xsl:variable name="firstSegmentFromNode" select="key(&quot;nodeById&quot;,$firstSegment/@from)"/>
380                <xsl:variable name="firstSegmentToNode" select="key(&quot;nodeById&quot;,$firstSegment/@to)"/>
381                <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])"/>
382                <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])"/>
383                <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])"/>
384                <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])"/>
385                <xsl:variable name="firstSegmentLayerCount" select="($firstSegmentInboundLayerCount+$firstSegmentInboundNoLayerCount+$firstSegmentOutboundLayerCount+$firstSegmentOutboundNoLayerCount)&gt;1"/>
386
387                <xsl:if test="$firstSegmentLayerCount">
388                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($firstSegmentFromNode/@lon))*10000*$scale)"/>
389                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($firstSegmentFromNode/@lat))*10000*$scale*$projection)"/>
390                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($firstSegmentToNode/@lon))*10000*$scale)"/>
391                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($firstSegmentToNode/@lat))*10000*$scale*$projection)"/>
392                    <xsl:call-template name="drawSegmentFragment">
393                        <xsl:with-param name="x1" select="$x1"/>
394                        <xsl:with-param name="y1" select="$y1"/>
395                        <xsl:with-param name="x2" select="number($x1)+((number($x2)-number($x1)) div 10)"/>
396                        <xsl:with-param name="y2" select="number($y1)+((number($y2)-number($y1)) div 10)"/>
397                    </xsl:call-template>
398                </xsl:if>
399
400                <!-- Process the last segment in the way -->
401                <xsl:variable name="lastSegment" select="key(&quot;segmentById&quot;,$way/seg[last()]/@id)"/>
402                <xsl:variable name="lastSegmentFromNode" select="key(&quot;nodeById&quot;,$lastSegment/@from)"/>
403                <xsl:variable name="lastSegmentToNode" select="key(&quot;nodeById&quot;,$lastSegment/@to)"/>
404                <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"/>
405                <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])"/>
406                <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])"/>
407                <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])"/>
408                <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])"/>
409                <xsl:variable name="lastSegmentLayerCount" select="($lastSegmentInboundLayerCount+$lastSegmentInboundNoLayerCount+$lastSegmentOutboundLayerCount+$lastSegmentOutboundNoLayerCount)&gt;1"/>
410
411                <xsl:if test="$lastSegmentLayerCount">
412                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($lastSegmentFromNode/@lon))*10000*$scale)"/>
413                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($lastSegmentFromNode/@lat))*10000*$scale*$projection)"/>
414                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($lastSegmentToNode/@lon))*10000*$scale)"/>
415                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($lastSegmentToNode/@lat))*10000*$scale*$projection)"/>
416                    <xsl:call-template name="drawSegmentFragment">
417                        <xsl:with-param name="x1" select="number($x2)-((number($x2)-number($x1)) div 10)"/>
418                        <xsl:with-param name="y1" select="number($y2)-((number($y2)-number($y1)) div 10)"/>
419                        <xsl:with-param name="x2" select="$x2"/>
420                        <xsl:with-param name="y2" select="$y2"/>
421                    </xsl:call-template>
422                </xsl:if>
423            </xsl:if>
424
425            <!-- Now draw the way itself -->
426            <use xlink:href="#way_{$way/@id}">
427                <xsl:apply-templates select="$instruction/@*" mode="copyAttributes">
428                    <xsl:with-param name="classes" select="$classes"/>
429                </xsl:apply-templates>
430            </use>
431        </xsl:if>
432
433    </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">
434        <xsl:param name="instruction"/>
435        <xsl:param name="way"/>
436        <xsl:param name="layer"/>
437        <xsl:param name="classes"/>
438
439        <xsl:choose>
440            <xsl:when test="$instruction/@width &gt; 0">
441                <!-- wide tunnels use a dashed line as wide as the road casing with a mask as wide as the road core which will be
442                rendered as a double dotted line -->
443                <mask id="mask_{@id}" maskUnits="userSpaceOnUse">
444                    <use xlink:href="#way_{@id}" style="stroke:black;fill:none;" class="{$instruction/@class}-core"/>
445                    <rect x="0px" y="0px" height="{$documentHeight}px" width="{$documentWidth}px" style="fill:white;"/>
446                </mask>
447                <use xlink:href="#way_{$way/@id}" mask="url(#mask_{@id})" style="stroke-dasharray:0.2,0.2;" class="{$instruction/@class}-casing"/>
448                <use xlink:href="#way_{$way/@id}" class="tunnel-casing" style="stroke-width:{$instruction/@width}px;"/>
449            </xsl:when>
450            <xsl:otherwise>
451                <!-- narrow tunnels will use a single dotted line -->
452                <use xlink:href="#way_{$way/@id}">
453                    <xsl:apply-templates select="$instruction/@*" mode="copyAttributes">
454                        <xsl:with-param name="classes" select="$classes"/>
455                    </xsl:apply-templates>
456                </use>
457            </xsl:otherwise>
458        </xsl:choose>
459    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawCircle">
460        <xsl:param name="instruction"/>
461
462        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
463        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
464
465        <circle cx="{$x}" cy="{$y}">
466            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the svg attributes from the <circle> instruction -->
467        </circle>
468
469    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="drawSymbol">
470        <xsl:param name="instruction"/>
471
472        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
473        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
474
475        <use x="{$x}" y="{$y}">
476            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/> <!-- Copy all the attributes from the <symbol> instruction -->
477        </use>
478    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="renderText">
479        <xsl:param name="instruction"/>
480
481        <xsl:variable name="x" select="($width)-((($topRightLongitude)-(@lon))*10000*$scale)"/>
482        <xsl:variable name="y" select="($height)+((($bottomLeftLatitude)-(@lat))*10000*$scale*$projection)"/>
483
484        <text>
485            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
486            <xsl:attribute name="x"><xsl:value-of select="$x"/></xsl:attribute>
487            <xsl:attribute name="y"><xsl:value-of select="$y"/></xsl:attribute>
488            <xsl:call-template name="getSvgAttributesFromOsmTags"/>
489            <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
490        </text>
491    </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">
492        <xsl:param name="instruction"/>
493        <xsl:param name="pathId"/>
494        <text>
495            <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-text"/>
496            <textPath xlink:href="#{$pathId}">
497                <xsl:apply-templates select="$instruction/@*" mode="renderTextPath-textPath"/>
498                <xsl:call-template name="getSvgAttributesFromOsmTags"/>
499                <xsl:value-of select="tag[@k=$instruction/@k]/@v"/>
500            </textPath>
501        </text>
502    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength|@k" mode="renderTextPath-text">
503    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-text">
504        <xsl:copy/>
505    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@startOffset|@method|@spacing|@lengthAdjust|@textLength" mode="renderTextPath-textPath">
506        <xsl:copy/>
507    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="renderTextPath-textPath">
508    </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">
509        <xsl:param name="instruction"/>
510        <xsl:param name="pathId"/>
511
512        <use xlink:href="#{$pathId}">
513            <xsl:apply-templates select="$instruction/@*" mode="copyAttributes"/>
514        </use>
515    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="getSvgAttributesFromOsmTags">
516        <xsl:for-each select="tag[contains(@k,&quot;svg:&quot;)]">
517            <xsl:attribute name="{substring-after(@k,&quot;svg:&quot;)}"><xsl:value-of select="@v"/></xsl:attribute>
518        </xsl:for-each>
519    </xsl:template>
520    <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">
521        <g id="segments" inkscape:groupmode="layer" inkscape:label="Segments">
522            <xsl:for-each select="$data/osm/segment[not(key('wayBySegment', @id))]">
523                <xsl:if test="not(tag[@key!='created_by'])">
524                    <xsl:variable name="fromNode" select="key('nodeById', @from)"/>
525                    <xsl:variable name="toNode" select="key('nodeById', @to)"/>
526                    <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
527                    <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
528                    <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
529                    <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
530                    <line class="untagged-segments" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
531                </xsl:if>
532            </xsl:for-each>
533        </g>
534    </xsl:template>
535    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="line">
536        <xsl:param name="elements"/>
537        <xsl:param name="layer"/>
538        <xsl:param name="classes"/>
539
540        <!-- This is the instruction that is currently being processed -->
541        <xsl:variable name="instruction" select="."/>
542
543        <g>
544            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
545                <xsl:with-param name="classes" select="$classes"/>
546            </xsl:apply-templates>
547
548            <!-- For each segment and way -->
549            <xsl:apply-templates select="$elements" mode="line">
550                <xsl:with-param name="instruction" select="$instruction"/>
551                <xsl:with-param name="layer" select="$layer"/>
552                <xsl:with-param name="classes" select="$classes"/>
553            </xsl:apply-templates>
554
555        </g>
556    </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">
557        <xsl:param name="instruction"/>
558        <xsl:param name="classes"/>
559
560        <xsl:call-template name="drawLine">
561            <xsl:with-param name="instruction" select="$instruction"/>
562            <xsl:with-param name="segment" select="."/>
563            <xsl:with-param name="classes" select="$classes"/>
564        </xsl:call-template>
565
566    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="line">
567        <xsl:param name="instruction"/>
568        <xsl:param name="layer"/>
569        <xsl:param name="classes"/>
570
571        <!-- The current <way> element -->
572        <xsl:variable name="way" select="."/>
573
574        <xsl:call-template name="drawWay">
575            <xsl:with-param name="instruction" select="$instruction"/>
576            <xsl:with-param name="way" select="$way"/>
577            <xsl:with-param name="layer" select="$layer"/>
578            <xsl:with-param name="classes" select="$classes"/>
579        </xsl:call-template>
580
581    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="tunnel">
582        <xsl:param name="elements"/>
583        <xsl:param name="layer"/>
584        <xsl:param name="classes"/>
585
586        <!-- This is the instruction that is currently being processed -->
587        <xsl:variable name="instruction" select="."/>
588
589        <g>
590            <xsl:apply-templates select="@*" mode="copyAttributes"> <!-- Add all the svg attributes of the <tunnel> instruction to the <g> element -->
591                <xsl:with-param name="classes" select="$classes"/>
592            </xsl:apply-templates>
593
594            <!-- For each segment and way -->
595            <xsl:apply-templates select="$elements" mode="tunnel">
596                <xsl:with-param name="instruction" select="$instruction"/>
597                <xsl:with-param name="layer" select="$layer"/>
598                <xsl:with-param name="classes" select="$classes"/>
599            </xsl:apply-templates>
600        </g>
601    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="tunnel">
602        <xsl:param name="instruction"/>
603        <xsl:param name="layer"/>
604        <xsl:param name="classes"/>
605
606        <!-- The current <way> element -->
607        <xsl:variable name="way" select="."/>
608
609        <xsl:call-template name="drawTunnel">
610            <xsl:with-param name="instruction" select="$instruction"/>
611            <xsl:with-param name="way" select="$way"/>
612            <xsl:with-param name="layer" select="$layer"/>
613            <xsl:with-param name="classes" select="$classes"/>
614        </xsl:call-template>
615
616    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" match="area">
617        <xsl:param name="elements"/>
618        <xsl:param name="classes"/>
619
620        <!-- This is the instruction that is currently being processed -->
621        <xsl:variable name="instruction" select="."/>
622
623        <g>
624            <xsl:apply-templates select="@*" mode="copyAttributes"/> <!-- Add all the svg attributes of the <line> instruction to the <g> element -->
625
626            <!-- For each segment and way -->
627            <xsl:apply-templates select="$elements" mode="area">
628                <xsl:with-param name="instruction" select="$instruction"/>
629            </xsl:apply-templates>
630        </g>
631    </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">
632        <xsl:param name="instruction"/>
633
634        <xsl:call-template name="generateAreaPath"/>
635
636        <xsl:call-template name="renderArea">
637            <xsl:with-param name="instruction" select="$instruction"/>
638            <xsl:with-param name="pathId" select="concat(&quot;area_&quot;,@id)"/>
639        </xsl:call-template>
640
641    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="circle">
642        <xsl:param name="elements"/>
643        <xsl:param name="classes"/>
644
645        <!-- This is the instruction that is currently being processed -->
646        <xsl:variable name="instruction" select="."/>
647
648        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
649            <xsl:call-template name="drawCircle">
650                <xsl:with-param name="instruction" select="$instruction"/>
651            </xsl:call-template>
652        </xsl:for-each>
653    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="symbol">
654        <xsl:param name="elements"/>
655        <xsl:param name="classes"/>
656
657        <!-- This is the instruction that is currently being processed -->
658        <xsl:variable name="instruction" select="."/>
659
660        <xsl:for-each select="$elements[name()=&quot;node&quot;]">
661            <xsl:call-template name="drawSymbol">
662                <xsl:with-param name="instruction" select="$instruction"/>
663            </xsl:call-template>
664        </xsl:for-each>
665    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="text">
666        <xsl:param name="elements"/>
667        <xsl:param name="classes"/>
668
669        <!-- This is the instruction that is currently being processed -->
670        <xsl:variable name="instruction" select="."/>
671
672        <!-- Select all <node> elements that have a key that matches the k attribute of the text instruction -->
673        <xsl:for-each select="$elements[name()=&quot;node&quot;][tag[@k=$instruction/@k]]">
674                <xsl:call-template name="renderText">
675                    <xsl:with-param name="instruction" select="$instruction"/>
676                </xsl:call-template>
677        </xsl:for-each>
678
679        <!-- Select all <segment> and <way> elements that have a key that matches the k attribute of the text instruction -->
680        <xsl:apply-templates select="$elements[name()=&quot;segment&quot; or name()=&quot;way&quot;][tag[@k=$instruction/@k]]" mode="textPath">
681            <xsl:with-param name="instruction" select="$instruction"/>
682        </xsl:apply-templates>
683    </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">
684        <xsl:param name="instruction"/>
685
686        <!-- The current <segment> element -->
687        <xsl:variable name="segment" select="."/>
688
689        <!-- Generate the path for the segment -->
690        <!-- Text on segments should be relatively uncommon so only generate a <path> when one is needed -->
691        <xsl:call-template name="generateSegmentPath"/>
692
693        <xsl:call-template name="renderTextPath">
694            <xsl:with-param name="instruction" select="$instruction"/>
695            <xsl:with-param name="pathId" select="concat(&quot;segment_&quot;,@id)"/>
696        </xsl:call-template>
697
698    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="way" mode="textPath">
699        <xsl:param name="instruction"/>
700
701        <!-- The current <way> element -->
702        <xsl:variable name="way" select="."/>
703
704        <xsl:call-template name="renderTextPath">
705            <xsl:with-param name="instruction" select="$instruction"/>
706            <xsl:with-param name="pathId" select="concat(&quot;way_&quot;,@id,&quot;t&quot;)"/>
707        </xsl:call-template>
708
709    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateSegmentPath">
710        <xsl:variable name='pathData'>
711            <xsl:choose>
712                                <!-- Manual override -->
713                <xsl:when test='tag[@k="name_direction"]/@v="-1" or tag[@k="osmarender:nameDirection"]/@v="-1"'>
714                    <xsl:call-template name='segmentMoveToEnd'/>
715                    <xsl:call-template name='segmentLineToStart'/>
716                </xsl:when>
717                <xsl:when test='tag[@k="name_direction"]/@v="1" or tag[@k="osmarender:nameDirection"]/@v="1"'>
718                    <xsl:call-template name='segmentMoveToStart'/>
719                    <xsl:call-template name='segmentLineToEnd'/>
720                </xsl:when>
721                <!-- Automatic direction -->
722                <xsl:when test='(key("nodeById",@from)/@lon &gt; key("nodeById",@to)/@lon)'>
723                    <xsl:call-template name='segmentMoveToEnd'/>
724                    <xsl:call-template name='segmentLineToStart'/>
725                </xsl:when>
726                <xsl:otherwise>
727                    <xsl:call-template name='segmentMoveToStart'/>
728                    <xsl:call-template name='segmentLineToEnd'/>
729                </xsl:otherwise>
730            </xsl:choose>
731        </xsl:variable>
732
733        <path id="segment_{@id}" d="{$pathData}"/>
734
735    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateWayPath">
736
737        <!-- Generate the path for the way that will be used by the street
738        name rendering. This is horribly inefficient, because we will later
739        also have the path used for the rendering of the path itself. So
740        each path is twice in the SVG file. But this path here needs to
741        have the right direction for the names to render right way up
742        and the other path needs to be the right direction for rendering
743        the oneway arrows. This can probably be done better, but currently
744        I don't know how. -->
745        <xsl:variable name='pathData'>
746            <xsl:choose>
747                                <!-- Manual override, reverse direction -->
748                <xsl:when test='tag[@k="name_direction"]/@v="-1" or tag[@k="osmarender:nameDirection"]/@v="-1"'>
749                                        <xsl:call-template name='generateWayPathReverse'/>
750                </xsl:when>
751                                <!-- Manual override, normal direction -->
752                <xsl:when test='tag[@k="name_direction"]/@v="1" or tag[@k="osmarender:nameDirection"]/@v="1"'>
753                                        <xsl:call-template name='generateWayPathNormal'/>
754                </xsl:when>
755                                <!-- Automatic, reverse direction -->
756                <xsl:when test='(key("nodeById",key("segmentById",seg[1]/@id)/@from)/@lon &gt; key("nodeById",key("segmentById",seg[last()]/@id)/@to)/@lon)'>
757                                        <xsl:call-template name='generateWayPathReverse'/>
758                </xsl:when>
759                                <!-- Automatic, normal direction -->
760                <xsl:otherwise>
761                                        <xsl:call-template name='generateWayPathNormal'/>
762                </xsl:otherwise>
763            </xsl:choose>
764        </xsl:variable>
765
766        <path id="way_{@id}t" d="{$pathData}"/>
767
768        <!-- Generate the path for the way itself. Used for rendering the
769        way and, possibly, oneway arrows. -->
770        <xsl:variable name="pathDataFixed">
771                        <xsl:call-template name='generateWayPathNormal'/>
772        </xsl:variable>
773
774        <path id="way_{@id}" d="{$pathDataFixed}"/>
775
776    </xsl:template>
777   
778   
779    <!-- Generate a way path in the normal order of the segments in the way -->
780    <xsl:template name="generateWayPathNormal">
781        <xsl:for-each select='seg[key("segmentById",@id)]'>
782            <xsl:variable name='segmentId' select='@id'/>
783            <xsl:variable name='linkedSegment' select='key("segmentById",@id)/@from=key("segmentById",preceding-sibling::seg[1]/@id)/@to'/>
784            <xsl:for-each select='key("segmentById",$segmentId)'>
785                <xsl:if test='not($linkedSegment)'>
786                    <xsl:call-template name='segmentMoveToStart'/>
787                </xsl:if>
788                    <xsl:call-template name='segmentLineToEnd'/>
789            </xsl:for-each>
790        </xsl:for-each>
791    </xsl:template>
792
793
794    <!-- Generate a way path in the reverse order of the segments in the way -->
795    <xsl:template name="generateWayPathReverse">
796                <xsl:for-each select='seg'>
797                    <xsl:sort select='position()' data-type='number' order='descending'/>
798                    <xsl:variable name='segmentId' select='@id'/>
799                    <xsl:variable name='linkedSegment' select='key("segmentById",following-sibling::seg[1]/@id)/@from=key("segmentById",@id)/@to'/>
800                    <xsl:for-each select='key("segmentById",$segmentId)'>
801                        <xsl:if test='not($linkedSegment)'>
802                            <xsl:call-template name='segmentMoveToEnd'/>
803                        </xsl:if>
804                            <xsl:call-template name='segmentLineToStart'/>
805                    </xsl:for-each>
806                </xsl:for-each>   
807    </xsl:template>
808   
809   
810    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="generateAreaPath">
811
812                <!-- Generate the path for the area -->
813                <xsl:variable name='pathData'>
814                        <xsl:for-each select='seg[key("segmentById",@id)]'>
815                                <xsl:variable name='segmentId' select='@id'/>
816                                <xsl:variable name='currentSegmentToNodeId' select='key("segmentById",@id)/@to' />
817                                <xsl:variable name='currentSegmentFromNodeId' select='key("segmentById",@id)/@from' />
818                                <xsl:variable name='previousSegmentToNodeId' select='key("segmentById",preceding-sibling::seg[1]/@id)/@to' />
819                               
820                                <!-- The linkedSegment flag indicates whether the previous segment is connected to the current segment.  If it isn't
821                                     then we will need to draw an additional line (segmentLineToStart) from the end of the previous segment to the
822                                     start of the current segment.
823                                -->
824                                <xsl:variable name='linkedSegment' select='key("segmentById",@id)/@from=$previousSegmentToNodeId'/>
825               
826                                <!--  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.
827                                      We do this to find out if the current segment is connected from some other segment in the way.  If it is, and it
828                                      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
829                                      draw an additional line between the end of the previous segment and the start of the current segment.
830                                -->
831                                <xsl:variable name='connectedSegmentCount' select='count(../*[key("segmentById",@id)/@to=$currentSegmentFromNodeId])' />
832                               
833                                <xsl:variable name='segmentSequence' select='position()'/>
834                                <xsl:for-each select='key("segmentById",$segmentId)'>
835                                        <xsl:choose>
836                                                <!-- If this is the start of the way then we always have to move to the start of the segment. -->
837                                                <xsl:when test='$segmentSequence=1'>
838                                                        <xsl:call-template name='segmentMoveToStart'/>                         
839                                                </xsl:when>
840                                                <!-- If the segment is "connected" to another segment (at the from end) but is not linked to the
841                                                         previous segment, then start a new sub-path -->
842                                                <xsl:when test='$connectedSegmentCount>0 and not($linkedSegment)'>
843                                                        <xsl:text>Z</xsl:text>
844                                                        <xsl:call-template name='segmentMoveToStart'/>                         
845                                                </xsl:when>
846                                                <!-- If the previous segment is not linked to this one we need to draw an artificial line -->
847                                                <xsl:when test='not($linkedSegment)'>
848                                                        <xsl:call-template name='segmentLineToStart'/>                         
849                                                </xsl:when>
850                                        </xsl:choose>
851                                        <xsl:call-template name='segmentLineToEnd'/>
852                                </xsl:for-each>
853                        </xsl:for-each>
854                        <xsl:text>Z</xsl:text>
855                </xsl:variable>
856
857                <path id="area_{@id}" d="{$pathData}"/>
858
859        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToStart">
860        <xsl:variable name="from" select="@from"/>
861        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
862
863        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
864        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
865        <xsl:text>M</xsl:text>
866        <xsl:value-of select="$x1"/>
867        <xsl:text> </xsl:text>
868        <xsl:value-of select="$y1"/>
869    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToStart">
870        <xsl:variable name="from" select="@from"/>
871        <xsl:variable name="fromNode" select="key(&quot;nodeById&quot;,$from)"/>
872
873        <xsl:variable name="x1" select="($width)-((($topRightLongitude)-($fromNode/@lon))*10000*$scale)"/>
874        <xsl:variable name="y1" select="($height)+((($bottomLeftLatitude)-($fromNode/@lat))*10000*$scale*$projection)"/>
875        <xsl:text>L</xsl:text>
876        <xsl:value-of select="$x1"/>
877        <xsl:text> </xsl:text>
878        <xsl:value-of select="$y1"/>
879    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentMoveToEnd">
880        <xsl:variable name="to" select="@to"/>
881        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
882
883        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
884        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
885        <xsl:text>M</xsl:text>
886        <xsl:value-of select="$x2"/>
887        <xsl:text> </xsl:text>
888        <xsl:value-of select="$y2"/>
889    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="segmentLineToEnd">
890        <xsl:variable name="to" select="@to"/>
891        <xsl:variable name="toNode" select="key(&quot;nodeById&quot;,$to)"/>
892
893        <xsl:variable name="x2" select="($width)-((($topRightLongitude)-($toNode/@lon))*10000*$scale)"/>
894        <xsl:variable name="y2" select="($height)+((($bottomLeftLatitude)-($toNode/@lat))*10000*$scale*$projection)"/>
895        <xsl:text>L</xsl:text>
896        <xsl:value-of select="$x2"/>
897        <xsl:text> </xsl:text>
898        <xsl:value-of select="$y2"/>
899    </xsl:template>
900    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@class" mode="copyAttributes">
901        <xsl:param name="classes"/>
902        <xsl:attribute name="class">
903            <xsl:value-of select="normalize-space(concat($classes,' ',.))"/>
904        </xsl:attribute>
905    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@type" mode="copyAttributes">
906    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="@*" mode="copyAttributes">
907        <xsl:param name="classes"/>
908        <xsl:copy/>
909    </xsl:template>
910
911    <xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processRules">
912     
913        <xsl:choose>
914
915            <!-- Process all the rules, one layer at a time -->
916            <xsl:when test="$withOSMLayers='yes'">
917                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-5&quot;"/></xsl:call-template>
918                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-4&quot;"/></xsl:call-template>
919                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-3&quot;"/></xsl:call-template>
920                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-2&quot;"/></xsl:call-template>
921                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;-1&quot;"/></xsl:call-template>
922                <xsl:call-template name="processLayer">
923                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
924                    <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;]]"/>
925                </xsl:call-template>
926                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;1&quot;"/></xsl:call-template>
927                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;2&quot;"/></xsl:call-template>
928                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;3&quot;"/></xsl:call-template>
929                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;4&quot;"/></xsl:call-template>
930                <xsl:call-template name="processLayer"><xsl:with-param name="layer" select="&quot;5&quot;"/></xsl:call-template>
931            </xsl:when>
932
933            <!-- Process all the rules, without looking at the layers -->
934            <xsl:otherwise>
935                <xsl:apply-templates select="/rules/rule">
936                    <xsl:with-param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;)]"/>
937                    <xsl:with-param name="layer" select="&quot;0&quot;"/>
938                    <xsl:with-param name="classes" select="''"/>
939                </xsl:apply-templates>
940            </xsl:otherwise>
941
942        </xsl:choose>
943        </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" name="processLayer">
944        <xsl:param name="layer"/>
945        <xsl:param name="elements" select="$data/osm/*[not(@action=&quot;delete&quot;) and tag[@k=&quot;layer&quot; and @v=$layer]]"/>
946
947        <g inkscape:groupmode="layer" id="layer{$layer}" inkscape:label="Layer {$layer}">
948            <xsl:apply-templates select="/rules/rule">
949                <xsl:with-param name="elements" select="$elements"/>
950                <xsl:with-param name="layer" select="$layer"/>
951                <xsl:with-param name="classes" select="''"/>
952            </xsl:apply-templates>
953        </g>
954    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="rule">
955        <xsl:param name="elements"/>
956        <xsl:param name="layer"/>
957        <xsl:param name="classes"/>
958
959        <!-- This is the rule currently being processed -->
960        <xsl:variable name="rule" select="."/>
961
962        <!-- Make list of elements that this rule should be applied to -->
963        <xsl:variable name="eBare">
964            <xsl:choose>
965                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
966                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
967                <xsl:otherwise>node|segment|way</xsl:otherwise>
968            </xsl:choose>
969        </xsl:variable>
970
971        <!-- List of keys that this rule should be applied to -->
972        <xsl:variable name="kBare" select="$rule/@k"/>
973
974        <!-- List of values that this rule should be applied to -->
975        <xsl:variable name="vBare" select="$rule/@v"/>
976
977        <!-- Top'n'tail selectors with | for contains usage -->
978        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
979        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
980        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
981
982        <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))]"/>
983
984        <xsl:choose>
985            <xsl:when test="contains($k,&quot;|*|&quot;)">
986                <xsl:choose>
987                    <xsl:when test="contains($v,&quot;|~|&quot;)">
988                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
989                        <xsl:call-template name="processElements">
990                            <xsl:with-param name="eBare" select="$eBare"/>
991                            <xsl:with-param name="kBare" select="$kBare"/>
992                            <xsl:with-param name="vBare" select="$vBare"/>
993                            <xsl:with-param name="layer" select="$layer"/>
994                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
995                            <xsl:with-param name="rule" select="$rule"/>
996                            <xsl:with-param name="classes" select="$classes"/>
997                        </xsl:call-template>
998                    </xsl:when>
999                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1000                        <xsl:variable name="allElements" select="$selectedElements"/>
1001                        <xsl:call-template name="processElements">
1002                            <xsl:with-param name="eBare" select="$eBare"/>
1003                            <xsl:with-param name="kBare" select="$kBare"/>
1004                            <xsl:with-param name="vBare" select="$vBare"/>
1005                            <xsl:with-param name="layer" select="$layer"/>
1006                            <xsl:with-param name="elements" select="$allElements"/>
1007                            <xsl:with-param name="rule" select="$rule"/>
1008                            <xsl:with-param name="classes" select="$classes"/>
1009                        </xsl:call-template>
1010                    </xsl:when>
1011                    <xsl:otherwise>
1012                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1013                        <xsl:call-template name="processElements">
1014                            <xsl:with-param name="eBare" select="$eBare"/>
1015                            <xsl:with-param name="kBare" select="$kBare"/>
1016                            <xsl:with-param name="vBare" select="$vBare"/>
1017                            <xsl:with-param name="layer" select="$layer"/>
1018                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1019                            <xsl:with-param name="rule" select="$rule"/>
1020                            <xsl:with-param name="classes" select="$classes"/>
1021                        </xsl:call-template>
1022                    </xsl:otherwise>
1023                </xsl:choose>
1024            </xsl:when>
1025            <xsl:when test="contains($v,&quot;|~|&quot;)">
1026                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1027                <xsl:call-template name="processElements">
1028                    <xsl:with-param name="eBare" select="$eBare"/>
1029                    <xsl:with-param name="kBare" select="$kBare"/>
1030                    <xsl:with-param name="vBare" select="$vBare"/>
1031                    <xsl:with-param name="layer" select="$layer"/>
1032                    <xsl:with-param name="elements" select="$elementsWithoutKey"/>
1033                    <xsl:with-param name="rule" select="$rule"/>
1034                    <xsl:with-param name="classes" select="$classes"/>
1035                </xsl:call-template>
1036            </xsl:when>
1037            <xsl:when test="contains($v,&quot;|*|&quot;)">
1038                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1039                <xsl:call-template name="processElements">
1040                    <xsl:with-param name="eBare" select="$eBare"/>
1041                    <xsl:with-param name="kBare" select="$kBare"/>
1042                    <xsl:with-param name="vBare" select="$vBare"/>
1043                    <xsl:with-param name="layer" select="$layer"/>
1044                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1045                    <xsl:with-param name="rule" select="$rule"/>
1046                    <xsl:with-param name="classes" select="$classes"/>
1047                </xsl:call-template>
1048            </xsl:when>
1049            <xsl:otherwise>
1050                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1051                <xsl:call-template name="processElements">
1052                    <xsl:with-param name="eBare" select="$eBare"/>
1053                    <xsl:with-param name="kBare" select="$kBare"/>
1054                    <xsl:with-param name="vBare" select="$vBare"/>
1055                    <xsl:with-param name="layer" select="$layer"/>
1056                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1057                    <xsl:with-param name="rule" select="$rule"/>
1058                    <xsl:with-param name="classes" select="$classes"/>
1059                </xsl:call-template>
1060            </xsl:otherwise>
1061        </xsl:choose>
1062    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElements">
1063        <xsl:param name="eBare"/>
1064        <xsl:param name="kBare"/>
1065        <xsl:param name="vBare"/>
1066        <xsl:param name="layer"/>
1067        <xsl:param name="elements"/>
1068        <xsl:param name="rule"/>
1069        <xsl:param name="classes"/>
1070       
1071        <xsl:if test="$elements">
1072            <xsl:message>
1073Processing &lt;rule e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1074Matched by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1075            </xsl:message>
1076
1077            <xsl:apply-templates select="*">
1078                <xsl:with-param name="layer" select="$layer"/>
1079                <xsl:with-param name="elements" select="$elements"/>
1080                <xsl:with-param name="rule" select="$rule"/>
1081                <xsl:with-param name="classes" select="$classes"/>
1082            </xsl:apply-templates>
1083        </xsl:if>
1084    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" match="addclass">
1085        <xsl:param name="elements"/>
1086        <xsl:param name="layer"/>
1087        <xsl:param name="classes"/>
1088
1089        <!-- This is the rule currently being processed -->
1090        <xsl:variable name="rule" select="."/>
1091
1092        <!-- Additional classes from class attribute of this rule -->
1093        <xsl:variable name="addclasses" select="@class"/>
1094
1095        <!-- Make list of elements that this rule should be applied to -->
1096        <xsl:variable name="eBare">
1097            <xsl:choose>
1098                <xsl:when test="$rule/@e=&quot;*&quot;">node|segment|way</xsl:when>
1099                <xsl:when test="$rule/@e"><xsl:value-of select="$rule/@e"/></xsl:when>
1100                <xsl:otherwise>node|segment|way</xsl:otherwise>
1101            </xsl:choose>
1102        </xsl:variable>
1103
1104        <!-- List of keys that this rule should be applied to -->
1105        <xsl:variable name="kBare" select="$rule/@k"/>
1106
1107        <!-- List of values that this rule should be applied to -->
1108        <xsl:variable name="vBare" select="$rule/@v"/>
1109
1110        <!-- Top'n'tail selectors with | for contains usage -->
1111        <xsl:variable name="e">|<xsl:value-of select="$eBare"/>|</xsl:variable>
1112        <xsl:variable name="k">|<xsl:value-of select="$kBare"/>|</xsl:variable>
1113        <xsl:variable name="v">|<xsl:value-of select="$vBare"/>|</xsl:variable>
1114
1115        <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))]"/>
1116
1117        <xsl:choose>
1118            <xsl:when test="contains($k,&quot;|*|&quot;)">
1119                <xsl:choose>
1120                    <xsl:when test="contains($v,&quot;|~|&quot;)">
1121                        <xsl:variable name="elementsWithNoTags" select="$selectedElements[count(tag)=0]"/>
1122                        <xsl:call-template name="processElementsForAddClass">
1123                            <xsl:with-param name="eBare" select="$eBare"/>
1124                            <xsl:with-param name="kBare" select="$kBare"/>
1125                            <xsl:with-param name="vBare" select="$vBare"/>
1126                            <xsl:with-param name="layer" select="$layer"/>
1127                            <xsl:with-param name="elements" select="$elementsWithNoTags"/>
1128                            <xsl:with-param name="rule" select="$rule"/>
1129                            <xsl:with-param name="classes" select="$classes"/>
1130                            <xsl:with-param name="addclasses" select="$addclasses"/>
1131                            <xsl:with-param name="allelements" select="$elements"/>
1132                        </xsl:call-template>
1133                    </xsl:when>
1134                    <xsl:when test="contains($v,&quot;|*|&quot;)">
1135                        <xsl:variable name="allElements" select="$selectedElements"/>
1136                        <xsl:call-template name="processElementsForAddClass">
1137                            <xsl:with-param name="eBare" select="$eBare"/>
1138                            <xsl:with-param name="kBare" select="$kBare"/>
1139                            <xsl:with-param name="vBare" select="$vBare"/>
1140                            <xsl:with-param name="layer" select="$layer"/>
1141                            <xsl:with-param name="elements" select="$allElements"/>
1142                            <xsl:with-param name="rule" select="$rule"/>
1143                            <xsl:with-param name="classes" select="$classes"/>
1144                            <xsl:with-param name="addclasses" select="$addclasses"/>
1145                            <xsl:with-param name="allelements" select="$elements"/>
1146                        </xsl:call-template>
1147                    </xsl:when>
1148                    <xsl:otherwise>
1149                        <xsl:variable name="allElementsWithValue" select="$selectedElements[tag[contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1150                        <xsl:call-template name="processElementsForAddClass">
1151                            <xsl:with-param name="eBare" select="$eBare"/>
1152                            <xsl:with-param name="kBare" select="$kBare"/>
1153                            <xsl:with-param name="vBare" select="$vBare"/>
1154                            <xsl:with-param name="layer" select="$layer"/>
1155                            <xsl:with-param name="elements" select="$allElementsWithValue"/>
1156                            <xsl:with-param name="rule" select="$rule"/>
1157                            <xsl:with-param name="classes" select="$classes"/>
1158                            <xsl:with-param name="addclasses" select="$addclasses"/>
1159                            <xsl:with-param name="allelements" select="$elements"/>
1160                        </xsl:call-template>
1161                    </xsl:otherwise>
1162                </xsl:choose>
1163            </xsl:when>
1164            <xsl:when test="contains($v,&quot;|~|&quot;)">
1165                <xsl:variable name="elementsWithoutKey" select="$selectedElements[count(tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))])=0]"/>
1166                <xsl:call-template name="processElementsForAddClass">
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="$elementsWithoutKey"/>
1172                    <xsl:with-param name="rule" select="$rule"/>
1173                    <xsl:with-param name="classes" select="$classes"/>
1174                    <xsl:with-param name="addclasses" select="$addclasses"/>
1175                    <xsl:with-param name="allelements" select="$elements"/>
1176                </xsl:call-template>
1177            </xsl:when>
1178            <xsl:when test="contains($v,&quot;|*|&quot;)">
1179                <xsl:variable name="allElementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;))]]"/>
1180                <xsl:call-template name="processElementsForAddClass">
1181                    <xsl:with-param name="eBare" select="$eBare"/>
1182                    <xsl:with-param name="kBare" select="$kBare"/>
1183                    <xsl:with-param name="vBare" select="$vBare"/>
1184                    <xsl:with-param name="layer" select="$layer"/>
1185                    <xsl:with-param name="elements" select="$allElementsWithKey"/>
1186                    <xsl:with-param name="rule" select="$rule"/>
1187                    <xsl:with-param name="classes" select="$classes"/>
1188                    <xsl:with-param name="addclasses" select="$addclasses"/>
1189                    <xsl:with-param name="allelements" select="$elements"/>
1190                </xsl:call-template>
1191            </xsl:when>
1192            <xsl:otherwise>
1193                <xsl:variable name="elementsWithKey" select="$selectedElements[tag[contains($k,concat(&quot;|&quot;,@k,&quot;|&quot;)) and contains($v,concat(&quot;|&quot;,@v,&quot;|&quot;))]]"/>
1194                <xsl:call-template name="processElementsForAddClass">
1195                    <xsl:with-param name="eBare" select="$eBare"/>
1196                    <xsl:with-param name="kBare" select="$kBare"/>
1197                    <xsl:with-param name="vBare" select="$vBare"/>
1198                    <xsl:with-param name="layer" select="$layer"/>
1199                    <xsl:with-param name="elements" select="$elementsWithKey"/>
1200                    <xsl:with-param name="rule" select="$rule"/>
1201                    <xsl:with-param name="classes" select="$classes"/>
1202                    <xsl:with-param name="addclasses" select="$addclasses"/>
1203                    <xsl:with-param name="allelements" select="$elements"/>
1204                </xsl:call-template>
1205            </xsl:otherwise>
1206        </xsl:choose>
1207    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="processElementsForAddClass">
1208        <xsl:param name="eBare"/>
1209        <xsl:param name="kBare"/>
1210        <xsl:param name="vBare"/>
1211        <xsl:param name="layer"/>
1212        <xsl:param name="elements"/>
1213        <xsl:param name="allelements"/>
1214        <xsl:param name="rule"/>
1215        <xsl:param name="classes"/>
1216        <xsl:param name="addclasses"/>
1217       
1218        <xsl:variable name="newclasses" select="concat($classes,' ',$addclasses)"/>
1219        <xsl:variable name="otherelements" select="set:difference($allelements, $elements)"/>
1220
1221        <xsl:if test="$elements">
1222            <xsl:message>
1223Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1224Positive match by <xsl:value-of select="count($elements)"/> elements for layer <xsl:value-of select="$layer"/>.
1225            </xsl:message>
1226
1227            <xsl:apply-templates select="*">
1228                <xsl:with-param name="layer" select="$layer"/>
1229                <xsl:with-param name="elements" select="$elements"/>
1230                <xsl:with-param name="rule" select="$rule"/>
1231                <xsl:with-param name="classes" select="$newclasses"/>
1232            </xsl:apply-templates>
1233        </xsl:if>
1234
1235        <xsl:if test="$otherelements">
1236            <xsl:message>
1237Processing &lt;addclass e="<xsl:value-of select="$eBare"/>" k="<xsl:value-of select="$kBare"/>" v="<xsl:value-of select="$vBare"/>" &gt; 
1238Negative match by <xsl:value-of select="count($otherelements)"/> elements for layer <xsl:value-of select="$layer"/>.
1239            </xsl:message>
1240            <xsl:apply-templates select="*">
1241                <xsl:with-param name="layer" select="$layer"/>
1242                <xsl:with-param name="elements" select="$otherelements"/>
1243                <xsl:with-param name="rule" select="$rule"/>
1244                <xsl:with-param name="classes" select="$classes"/>
1245            </xsl:apply-templates>
1246        </xsl:if>
1247    </xsl:template>
1248    <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">
1249        <xsl:param name="elements"/>
1250        <xsl:param name="layer"/>
1251        <xsl:param name="rule"/>
1252        <xsl:param name="classes"/>
1253
1254        <xsl:message>Processing SVG layer: <xsl:value-of select="@name"/> (at OSM layer <xsl:value-of select="$layer"/>)
1255</xsl:message>
1256
1257        <xsl:variable name="opacity">
1258            <xsl:if test="@opacity">
1259                <xsl:value-of select="concat('opacity:',@opacity,';')"/>
1260            </xsl:if>
1261        </xsl:variable>
1262
1263        <xsl:variable name="display">
1264            <xsl:if test="(@display='none') or (@display='off')">
1265                <xsl:text>display:none;</xsl:text>
1266            </xsl:if>
1267        </xsl:variable>
1268
1269        <g inkscape:groupmode="layer" id="{@name}-{$layer}" inkscape:label="{@name}">
1270            <xsl:if test="concat($opacity,$display)!=''">
1271                <xsl:attribute name="style">
1272                    <xsl:value-of select="concat($opacity,$display)"/>
1273                </xsl:attribute>
1274            </xsl:if>
1275            <xsl:apply-templates select="*">
1276                <xsl:with-param name="layer" select="$layer"/>
1277                <xsl:with-param name="elements" select="$elements"/>
1278                <xsl:with-param name="classes" select="$classes"/>
1279            </xsl:apply-templates>
1280        </g>
1281
1282    </xsl:template>
1283   
1284    <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">
1285        <!-- dasharray definitions here can be overridden in stylesheet -->
1286        <g id="border" inkscape:groupmode="layer" inkscape:label="Map Border">
1287            <line id="border-left-casing" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1288            <line id="border-top-casing" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1289            <line id="border-bottom-casing" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1290            <line id="border-right-casing" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-casing" stroke-dasharray="{($km div 10) - 1},1"/>
1291
1292            <line id="border-left-core" x1="0" y1="0" x2="0" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1293            <line id="border-top-core" x1="0" y1="0" x2="{$documentWidth}" y2="0" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1294            <line id="border-bottom-core" x1="0" y1="{$documentHeight}" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1295            <line id="border-right-core" x1="{$documentWidth}" y1="0" x2="{$documentWidth}" y2="{$documentHeight}" class="map-border-core" stroke-dasharray="{($km div 10) - 1},1"/>
1296        </g>
1297    </xsl:template>
1298    <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">
1299        <g id="grid" inkscape:groupmode="layer" inkscape:label="Grid">
1300            <xsl:call-template name="gridDrawHorizontals">
1301                <xsl:with-param name="line" select="&quot;1&quot;"/>
1302            </xsl:call-template>
1303            <xsl:call-template name="gridDrawVerticals">
1304                <xsl:with-param name="line" select="&quot;1&quot;"/>
1305            </xsl:call-template>
1306        </g>
1307    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawHorizontals">
1308        <xsl:param name="line"/>
1309        <xsl:if test="($line*$km) &lt; $documentHeight">
1310            <line id="grid-hori-{$line}" x1="0px" y1="{$line*$km}px" x2="{$documentWidth}px" y2="{$line*$km}px" class="map-grid-line"/>
1311            <xsl:call-template name="gridDrawHorizontals">
1312                <xsl:with-param name="line" select="$line+1"/>
1313            </xsl:call-template>
1314        </xsl:if>
1315    </xsl:template><xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/2000/svg" name="gridDrawVerticals">
1316        <xsl:param name="line"/>
1317        <xsl:if test="($line*$km) &lt; $documentWidth">
1318            <line id="grid-vert-{$line}" x1="{$line*$km}px" y1="0px" x2="{$line*$km}px" y2="{$documentHeight}px" class="map-grid-line"/>
1319            <xsl:call-template name="gridDrawVerticals">
1320                <xsl:with-param name="line" select="$line+1"/>
1321            </xsl:call-template>
1322        </xsl:if>
1323    </xsl:template>
1324
1325    <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">
1326        <xsl:param name="title"/>
1327
1328        <xsl:variable name="x" select="$documentWidth div 2"/>
1329        <xsl:variable name="y" select="30"/>
1330
1331        <g id="marginalia-title" inkscape:groupmode="layer" inkscape:label="Title">
1332            <rect id="marginalia-title-background" x="0px" y="0px" height="{$marginaliaTopHeight - 5}px" width="{$documentWidth}px" class="map-title-background"/>
1333            <text id="marginalia-title-text" class="map-title" x="{$x}" y="{$y}"><xsl:value-of select="$title"/></text>
1334        </g>
1335    </xsl:template>
1336    <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">
1337        <xsl:variable name="x1" select="14"/>
1338        <xsl:variable name="y1" select="round(($documentHeight)+((($bottomLeftLatitude)-(number($bottomLeftLatitude)))*10000*$scale*$projection))+28"/>
1339        <xsl:variable name="x2" select="$x1+$km"/>
1340        <xsl:variable name="y2" select="$y1"/>
1341
1342        <g id="marginalia-scale" inkscape:groupmode="layer" inkscape:label="Scale">
1343            <line id="marginalia-scale-casing" class="map-scale-casing" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1344
1345            <line id="marginalia-scale-core" class="map-scale-core" stroke-dasharray="{($km div 10)}" x1="{$x1}" y1="{$y1}" x2="{$x2}" y2="{$y2}"/>
1346
1347            <line id="marginalia-scale-bookend-from" class="map-scale-bookend" x1="{$x1}" y1="{$y1 + 2}" x2="{$x1}" y2="{$y1 - 10}"/>
1348
1349            <line id="marginalia-scale-bookend-to" class="map-scale-bookend" x1="{$x2}" y1="{$y2 + 2}" x2="{$x2}" y2="{$y2 - 10}"/>
1350
1351            <text id="marginalia-scale-text-from" class="map-scale-caption" x="{$x1}" y="{$y1 - 10}">0</text>
1352
1353            <text id="marginalia-scale-text-to" class="map-scale-caption" x="{$x2}" y="{$y2 - 10}">1km</text>
1354        </g>
1355    </xsl:template>
1356    <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">
1357        <xsl:variable name="date" select="date:date()"/>
1358        <xsl:variable name="year" select="date:year()"/>
1359
1360        <xsl:comment>
1361
1362    Copyright (c) <xsl:value-of select="$year"/> OpenStreetMap
1363    www.openstreetmap.org
1364    This work is licensed under the
1365    Creative Commons Attribution-ShareAlike 2.0 License.
1366    http://creativecommons.org/licenses/by-sa/2.0/
1367
1368</xsl:comment>
1369        <metadata id="metadata">
1370            <rdf:RDF xmlns="http://web.resource.org/cc/">
1371                <cc:Work rdf:about="">
1372                    <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
1373                    <dc:format>image/svg+xml</dc:format>
1374                    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
1375                    <dc:title><xsl:value-of select="$title"/></dc:title>
1376                    <dc:date><xsl:value-of select="substring($date,1,10)"/></dc:date>
1377                    <dc:source>http://www.openstreetmap.org/</dc:source>
1378                </cc:Work>
1379                <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
1380                    <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
1381                    <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
1382                    <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
1383                    <cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
1384                    <cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
1385                    <cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
1386                </cc:License>
1387            </rdf:RDF>
1388        </metadata>
1389    </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">
1390        <xsl:param name="dx"/>
1391        <xsl:param name="dy"/>
1392
1393        <xsl:variable name="year" select="date:year()"/>
1394
1395        <g id="license" inkscape:groupmode="layer" inkscape:label="Copyright" transform="translate({$dx},{$dy})">
1396            <style type="text/css"><![CDATA[
1397                .license-text {
1398                    text-anchor: start;
1399                    font-family: "DejaVu Sans",sans-serif;
1400                    font-size: 6px;
1401                    fill: black;
1402                }
1403            ]]></style>
1404            <a id="license-cc-logo-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1405                <g id="license-cc-logo" transform="scale(0.5,0.5) translate(-604,-49)">
1406                    <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"/>
1407                    <g id="g5908_2_" transform="matrix(0.872921,0,0,0.872921,50.12536,143.2144)">
1408                        <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"/>
1409                        <g id="g5706_2_" transform="translate(-289.6157,99.0653)">
1410                            <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 "/>
1411                        </g>
1412                    </g>
1413                    <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"/>
1414                    <g enable-background="new" id="g2821">
1415                        <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"/>
1416                        <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"/>
1417                    </g>
1418                    <g enable-background="new" id="g2827">
1419                        <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"/>
1420                        <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"/>
1421                    </g>
1422                    <g id="g6316_1_" transform="matrix(0.624995,0,0,0.624995,391.2294,176.9332)">
1423                        <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"/>
1424                        <g id="g6320_1_" transform="translate(-23.9521,-89.72962)">
1425                            <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 "/>
1426                            <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 "/>
1427                        </g>
1428                    </g>
1429                    <g id="g2838">
1430                        <circle cx="242.56226" cy="90.224609" r="10.8064" id="circle2840" style="fill:white"/>
1431                        <g id="g2842">
1432                            <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"/>
1433                            <circle cx="242.5498" cy="84.083008" r="1.63232" id="circle2846"/>
1434                        </g>
1435                        <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"/>
1436                    </g>
1437                </g>
1438            </a>
1439            <a id="license-osm-link" xlink:href="http://www.openstreetmap.org/">
1440                <g transform="translate(-210,10)" id="license-osm-text">
1441                    <text class="license-text" dx="0" dy="0">Copyright © <xsl:value-of select="$year"/> OpenStreetMap (openstreetmap.org)</text>
1442                </g>
1443            </a>
1444            <a id="license-cc-text-link" xlink:href="http://creativecommons.org/licenses/by-sa/2.0/">
1445                <g transform="translate(-150,18)" id="license-cc-text">
1446                    <text class="license-text" dx="0" dy="0">This work is licensed under the Creative</text>
1447                    <text class="license-text" dx="0" dy="8">Commons Attribution-ShareAlike 2.0 License.</text>
1448                    <text class="license-text" dx="0" dy="16">http://creativecommons.org/licenses/by-sa/2.0/</text>
1449                </g>
1450            </a>
1451        </g>
1452    </xsl:template>
1453
1454    <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">
1455        <defs>
1456
1457            <style type="text/css">
1458              .fancyButton {
1459                stroke: #8080ff;
1460                stroke-width: 2px;
1461                fill: #fefefe;
1462                }
1463              .fancyButton:hover {
1464                stroke: red;
1465                }
1466            </style>
1467
1468            <filter id="fancyButton" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="350">
1469                <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
1470                <feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
1471                <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" specularExponent="20" lighting-color="white" result="specOut">
1472                    <fePointLight x="-5000" y="-10000" z="7000"/>
1473                </feSpecularLighting>
1474                <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
1475                <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
1476                <feMerge>
1477                    <feMergeNode in="offsetBlur"/>
1478                    <feMergeNode in="litPaint"/>
1479                </feMerge>
1480            </filter>
1481            <symbol id="panDown" viewBox="0 0 19 19" class="fancyButton">
1482                <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"/>
1483                <path d="M 9.5,5 L 9.5,14"/>
1484            </symbol>
1485            <symbol id="panUp" viewBox="0 0 19 19" class="fancyButton">
1486                <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"/>
1487                <path d="M 9.5,5 L 9.5,14"/>
1488            </symbol>
1489            <symbol id="panLeft" viewBox="0 0 19 19" class="fancyButton">
1490                <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"/>
1491                <path d="M 5,9.5 L 14,9.5"/>
1492            </symbol>
1493            <symbol id="panRight" viewBox="0 0 19 19" class="fancyButton">
1494                <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"/>
1495                <path d="M 5,9.5 L 14,9.5"/>
1496            </symbol>
1497            <symbol id="zoomIn" viewBox="0 0 19 19" class="fancyButton">
1498                <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"/>
1499                <path d="M 5,9.5 L 14,9.5 M 9.5,5 L 9.5,14"/>
1500            </symbol>
1501            <symbol id="zoomOut" viewBox="0 0 19 19" class="fancyButton">
1502                <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"/>
1503                <path d="M 5,9.5 L 14,9.5"/>
1504            </symbol>
1505
1506        </defs>
1507
1508        <g id="gPanDown" filter="url(#fancyButton)" onclick="fnPan(&quot;down&quot;)">
1509            <use x="18px" y="60px" xlink:href="#panDown" width="14px" height="14px"/>
1510        </g>
1511        <g id="gPanRight" filter="url(#fancyButton)" onclick="fnPan(&quot;right&quot;)">
1512            <use x="8px" y="70px" xlink:href="#panRight" width="14px" height="14px"/>
1513        </g>
1514        <g id="gPanLeft" filter="url(#fancyButton)" onclick="fnPan(&quot;left&quot;)">
1515            <use x="28px" y="70px" xlink:href="#panLeft" width="14px" height="14px"/>
1516        </g>
1517        <g id="gPanUp" filter="url(#fancyButton)" onclick="fnPan(&quot;up&quot;)">
1518            <use x="18px" y="80px" xlink:href="#panUp" width="14px" height="14px"/>
1519        </g>
1520
1521        <xsl:variable name="x1" select="25"/>
1522        <xsl:variable name="y1" select="105"/>
1523        <xsl:variable name="x2" select="25"/>
1524        <xsl:variable name="y2" select="300"/>
1525
1526        <line style="stroke-width: 10; stroke-linecap: butt; stroke: #8080ff;">
1527            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1528            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1529            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1530            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1531        </line>
1532
1533        <line style="stroke-width: 8; stroke-linecap: butt; stroke: white; stroke-dasharray: 10,1;">
1534            <xsl:attribute name="x1"><xsl:value-of select="$x1"/></xsl:attribute>
1535            <xsl:attribute name="y1"><xsl:value-of select="$y1"/></xsl:attribute>
1536            <xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
1537            <xsl:attribute name="y2"><xsl:value-of select="$y2"/></xsl:attribute>
1538        </line>
1539
1540        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1541        <g id="gZoomIn" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;in&quot;)">
1542            <use x="15.5px" y="100px" xlink:href="#zoomIn" width="19px" height="19px"/>
1543        </g>
1544
1545        <!-- Need to use onmousedown because onclick is interfered with by the onmousedown handler for panning -->
1546        <g id="gZoomOut" filter="url(#fancyButton)" onmousedown="fnZoom(&quot;out&quot;)">
1547            <use x="15.5px" y="288px" xlink:href="#zoomOut" width="19px" height="19px"/>
1548        </g>
1549    </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">
1550        <script>
1551            /*
1552
1553Osmarender
1554
1555interactive.js
1556
1557*/
1558
1559function fnResize() {
1560    fnResizeElement("gAttribution")
1561    fnResizeElement("gLicense")
1562    fnResizeElement("gZoomIn")
1563    fnResizeElement("gZoomOut")
1564}
1565
1566
1567function fnResizeElement(e) {
1568    //
1569    var oSVG,scale,currentTranslateX,currentTranslateY,oe
1570    //
1571    oSVG=document.rootElement
1572    scale=1/oSVG.currentScale
1573    currentTranslateX=oSVG.currentTranslate.x
1574    currentTranslateY=oSVG.currentTranslate.y
1575    oe=document.getElementById(e)
1576    if (oe) oe.setAttributeNS(null,"transform","scale("+scale+","+scale+") translate("+(-currentTranslateX)+","+(-currentTranslateY)+")")
1577}
1578
1579
1580function fnToggleImage(osmImage) {
1581    var xlink = 'http://www.w3.org/1999/xlink';
1582    ogThumbnail=document.getElementById('gThumbnail')
1583    if (ogThumbnail.getAttributeNS(null,"visibility")=="visible") fnHideImage()
1584    else {
1585        ogThumbnail.setAttributeNS(null,"visibility","visible")
1586        oThumbnail=document.getElementById('thumbnail')
1587        oThumbnail.setAttributeNS(xlink,"href",osmImage)
1588    }
1589}
1590
1591function fnHideImage() {
1592    ogThumbnail=document.getElementById('gThumbnail')
1593    ogThumbnail.setAttributeNS(null,"visibility","hidden")
1594}
1595
1596
1597/* The following code originally written by Jonathan Watt (http://jwatt.org/), Aug. 2005 */
1598
1599if (!window)
1600window = this;
1601
1602
1603function fnOnLoad(evt) {
1604    if (!document) window.document = evt.target.ownerDocument
1605}
1606
1607
1608/**
1609  * Event handlers to change the current user space for the zoom and pan
1610  * controls to make them appear to be scale invariant.
1611  */
1612
1613function fnOnZoom(evt) {
1614    try {
1615        if (evt.newScale === undefined) throw 'bad interface'
1616        // update the transform list that adjusts for zoom and pan
1617        var tlist = document.getElementById('staticElements').transform.baseVal
1618        tlist.getItem(0).setScale(1/evt.newScale, 1/evt.newScale)
1619        tlist.getItem(1).setTranslate(-evt.newTranslate.x, -evt.newTranslate.y)
1620        }
1621    catch (e) {
1622        // work around difficiencies in non-moz implementations (some don't
1623        // implement the SVGZoomEvent or SVGAnimatedTransform interfaces)
1624        var de = document.documentElement
1625        var tform = 'scale(' + 1/de.currentScale + ') ' + 'translate(' + (-de.currentTranslate.x) + ', ' + (-de.currentTranslate.y) + ')'
1626        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1627        }
1628    }
1629
1630
1631function fnOnScroll(evt) {
1632    var ct = document.documentElement.currentTranslate
1633    try {
1634        // update the transform list that adjusts for zoom and pan
1635        var tlist = document.getElementById('staticElements').transform.baseVal
1636        tlist.getItem(1).setTranslate(-ct.x, -ct.y)
1637        }
1638    catch (e) {
1639        // work around difficiencies in non-moz implementations (some don't
1640        // implement the SVGAnimatedTransform interface)
1641        var tform = 'scale(' + 1/document.documentElement.currentScale + ') ' + 'translate(' + (-ct.x) + ', ' + (-ct.y) + ')';
1642        document.getElementById('staticElements').setAttributeNS(null, 'transform', tform)
1643        }
1644    }
1645
1646
1647function fnZoom(type) {
1648    var de = document.documentElement;
1649    var oldScale = de.currentScale;
1650    var oldTranslate = { x: de.currentTranslate.x, y: de.currentTranslate.y };
1651    var s = 2;
1652    if (type == 'in') {de.currentScale *= 1.5;}
1653    if (type == 'out') {de.currentScale /= 1.4;}
1654    // correct currentTranslate so zooming is to the center of the viewport:
1655
1656    var vp_width, vp_height;
1657    try {
1658        vp_width = de.viewport.width;
1659        vp_height = de.viewport.height;
1660    }
1661    catch (e) {
1662        // work around difficiency in moz ('viewport' property not implemented)
1663        vp_width = window.innerWidth;
1664        vp_height = window.innerHeight;
1665    }
1666    de.currentTranslate.x = vp_width/2 - ((de.currentScale/oldScale) * (vp_width/2 - oldTranslate.x));
1667    de.currentTranslate.y = vp_height/2 - ((de.currentScale/oldScale) * (vp_height/2 - oldTranslate.y));
1668
1669}
1670
1671
1672function fnPan(type) {
1673    var de = document.documentElement;
1674    var ct = de.currentTranslate;
1675    var t = 150;
1676    if (type == 'right') ct.x += t;
1677    if (type == 'down') ct.y += t;
1678    if (type == 'left') ct.x -= t;
1679    if (type == 'up') ct.y -= t;
1680}
1681
1682
1683var gCurrentX,gCurrentY
1684var gDeltaX,gDeltaY
1685var gMouseDown=false
1686var gCurrentTranslate=document.documentElement.currentTranslate
1687
1688function fnOnMouseDown(evt) {
1689    gCurrentX=gCurrentTranslate.x
1690    gCurrentY=gCurrentTranslate.y
1691    gDeltaX=evt.clientX
1692    gDeltaY=evt.clientY
1693    gMouseDown=true
1694    evt.target.ownerDocument.rootElement.setAttributeNS(null,"cursor","move")
1695}
1696
1697
1698function fnOnMouseUp(evt) {
1699    gMouseDown=false
1700    evt.target.ownerDocument.rootElement.setAttribute("cursor","default")
1701}
1702
1703
1704function fnOnMouseMove(evt) {
1705    var id
1706    if (gMouseDown) {
1707        gCurrentTranslate.x=gCurrentX+evt.clientX-gDeltaX
1708        gCurrentTranslate.y=gCurrentY+evt.clientY-gDeltaY
1709    }
1710}
1711
1712
1713        </script>
1714    </xsl:template>
1715
1716</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.