source: subversion/applications/utils/export/osmgoogleearth/osm2kml.xsl @ 4426

Last change on this file since 4426 was 3451, checked in by jochen, 13 years ago

changed img ref

File size: 13.2 KB
Line 
1<?xml version='1.0' encoding='iso-8859-1' ?>
2<xsl:stylesheet 
3    version="1.0"
4    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
5
6<!--
7
8Copyright (C) 2006, 2007  Jochen Topf <jochen@topf.org>
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
23
24-->
25
26        <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
27
28    <xsl:param name="osmfile" select="/rules/@data"/>
29
30        <xsl:key name='nodeById' match='/osm/node' use='@id'/>
31        <xsl:key name='segmentById' match='/osm/segment' use='@id'/>
32        <xsl:key name='segmentByFromNode' match='/osm/segment' use='@from'/>
33        <xsl:key name='segmentByToNode' match='/osm/segment' use='@to'/>
34        <xsl:key name='wayBySegment' match='/osm/way' use='seg/@id'/>
35       
36        <xsl:variable name='data' select='document($osmfile)'/>
37        <xsl:variable name='defs' select='/rules/defs'/>
38        <xsl:variable name='overlays' select='/rules/overlays'/>
39
40    <xsl:template match="/">
41        <kml>
42            <Document>
43                <name>OpenStreetMap</name>
44                <description>OpenStreetMap Data. See http://www.openstreetmap.org/</description>
45
46                <xsl:copy-of select="$defs/*"/>
47                <xsl:copy-of select="$overlays/*"/>
48
49                <xsl:apply-templates select="/rules/rule">
50                    <xsl:with-param name='elements' select='$data/osm/*' />
51                </xsl:apply-templates>
52            </Document>
53        </kml>
54           
55    </xsl:template>
56
57    <xsl:template match="rule">
58                <xsl:param name='elements'/>
59
60                <!-- This is the rule currently being processed -->
61                <xsl:variable name='rule' select='.'/>
62
63                <!-- Make list of elements that this rule should be applied to -->
64                <xsl:variable name='eBare'>
65                        <xsl:choose>
66                                <xsl:when test='$rule/@e="*"'>node|segment|way|area</xsl:when>
67                                <xsl:when test='$rule/@e'><xsl:value-of select='$rule/@e'/></xsl:when>
68                                <xsl:otherwise>node|segment|way|area</xsl:otherwise>
69                        </xsl:choose>
70                </xsl:variable>
71
72                <!-- List of keys that this rule should be applied to -->
73                <xsl:variable name='kBare' select='$rule/@k' />
74
75                <!-- List of values that this rule should be applied to -->
76                <xsl:variable name='vBare' select='$rule/@v' />
77
78                <!-- Top'n'tail selectors with | for contains usage -->
79                <xsl:variable name='e'>|<xsl:value-of select='$eBare'/>|</xsl:variable>
80                <xsl:variable name='k'>|<xsl:value-of select='$kBare'/>|</xsl:variable>
81                <xsl:variable name='v'>|<xsl:value-of select='$vBare'/>|</xsl:variable>
82
83
84                <xsl:variable name='selectedElements' select='$elements[contains($e,concat("|",name(),"|"))or (contains($e,"|waysegment|") and name()="segment" and key("wayBySegment",@id))]'/>
85
86                <xsl:choose>
87                        <xsl:when test='contains($k,"|*|")'>
88                                <xsl:choose>
89                                        <xsl:when test='contains($v,"|~|")'>
90                                                <xsl:variable name='elementsWithNoTags' select='$selectedElements[count(tag)=0]'/>
91                                                <xsl:call-template name='processElements'>
92                                                        <xsl:with-param name='eBare' select='$eBare'/>
93                                                        <xsl:with-param name='kBare' select='$kBare'/>
94                                                        <xsl:with-param name='vBare' select='$vBare'/>
95                                                        <xsl:with-param name='elements' select='$elementsWithNoTags'/>
96                                                        <xsl:with-param name='rule' select='$rule'/>
97                                                </xsl:call-template>
98                                        </xsl:when>
99                                        <xsl:when test='contains($v,"|*|")'>
100                                                <xsl:variable name='allElements' select='$selectedElements'/>
101                                                <xsl:call-template name='processElements'>
102                                                        <xsl:with-param name='eBare' select='$eBare'/>
103                                                        <xsl:with-param name='kBare' select='$kBare'/>
104                                                        <xsl:with-param name='vBare' select='$vBare'/>
105                                                        <xsl:with-param name='elements' select='$allElements'/>
106                                                        <xsl:with-param name='rule' select='$rule'/>
107                                                </xsl:call-template>
108                                        </xsl:when>
109                                        <xsl:otherwise>
110                                                <xsl:variable name='allElementsWithValue' select='$selectedElements[tag[contains($v,concat("|",@v,"|"))]]'/>
111                                                <xsl:call-template name='processElements'>
112                                                        <xsl:with-param name='eBare' select='$eBare'/>
113                                                        <xsl:with-param name='kBare' select='$kBare'/>
114                                                        <xsl:with-param name='vBare' select='$vBare'/>
115                                                        <xsl:with-param name='elements' select='$allElementsWithValue'/>
116                                                        <xsl:with-param name='rule' select='$rule'/>
117                                                </xsl:call-template>
118                                        </xsl:otherwise>
119                                </xsl:choose>
120                        </xsl:when>
121                        <xsl:when test='contains($v,"|~|")'>
122                                <xsl:variable name='elementsWithoutKey' select='$selectedElements[count(tag[contains($k,concat("|",@k,"|"))])=0]'/>
123                                <xsl:call-template name='processElements'>
124                                        <xsl:with-param name='eBare' select='$eBare'/>
125                                        <xsl:with-param name='kBare' select='$kBare'/>
126                                        <xsl:with-param name='vBare' select='$vBare'/>
127                                        <xsl:with-param name='elements' select='$elementsWithoutKey'/>
128                                        <xsl:with-param name='rule' select='$rule'/>
129                                </xsl:call-template>
130                        </xsl:when>
131                        <xsl:when test='contains($v,"|*|")'>
132                                <xsl:variable name='allElementsWithKey' select='$selectedElements[tag[contains($k,concat("|",@k,"|"))]]'/>
133                                <xsl:call-template name='processElements'>
134                                        <xsl:with-param name='eBare' select='$eBare'/>
135                                        <xsl:with-param name='kBare' select='$kBare'/>
136                                        <xsl:with-param name='vBare' select='$vBare'/>
137                                        <xsl:with-param name='elements' select='$allElementsWithKey'/>
138                                        <xsl:with-param name='rule' select='$rule'/>
139                                </xsl:call-template>
140                        </xsl:when>
141                        <xsl:otherwise>
142                                <xsl:variable name='elementsWithKey' select='$selectedElements[tag[contains($k,concat("|",@k,"|")) and contains($v,concat("|",@v,"|"))]]'/>
143                                <xsl:call-template name='processElements'>
144                                        <xsl:with-param name='eBare' select='$eBare'/>
145                                        <xsl:with-param name='kBare' select='$kBare'/>
146                                        <xsl:with-param name='vBare' select='$vBare'/>
147                                        <xsl:with-param name='elements' select='$elementsWithKey'/>
148                                        <xsl:with-param name='rule' select='$rule'/>
149                                </xsl:call-template>
150                        </xsl:otherwise>
151                </xsl:choose>
152    </xsl:template>
153
154        <!-- Process a set of elements selected by a rule  -->
155        <xsl:template name='processElements'>
156                <xsl:param name='eBare'/>
157                <xsl:param name='kBare'/>
158                <xsl:param name='vBare'/>
159                <xsl:param name='elements'/>
160                <xsl:param name='rule'/>
161               
162                <xsl:if test='$elements'>
163                        <xsl:message>
164Processing &lt;rule e="<xsl:value-of select='$eBare'/>" k="<xsl:value-of select='$kBare'/>" v="<xsl:value-of select='$vBare'/>" &gt; 
165Matched by <xsl:value-of select='count($elements)'/> elements.
166                        </xsl:message>
167
168                        <xsl:apply-templates select='*'>
169                                <xsl:with-param name='elements' select='$elements' />
170                                <xsl:with-param name='rule' select='$rule'/>
171                        </xsl:apply-templates>
172                </xsl:if>
173        </xsl:template>
174
175    <xsl:template match="point|city">
176                <xsl:param name='elements'/>
177                <xsl:param name='rule'/>
178
179                <!-- This is the instruction that is currently being processed -->
180                <xsl:variable name='instruction' select='.'/>
181
182        <!-- For each point or city -->
183        <xsl:apply-templates select='$elements' mode='point'>
184            <xsl:with-param name='instruction' select='$instruction' />
185        </xsl:apply-templates>
186        </xsl:template>
187
188    <xsl:template match="folder">
189                <xsl:param name='elements'/>
190        <Folder>
191            <name><xsl:value-of select="@name"/></name>
192            <xsl:apply-templates>
193                        <xsl:with-param name='elements' select="$elements"/>
194            </xsl:apply-templates>
195        </Folder> 
196        </xsl:template>
197
198    <xsl:template match="polyline|polygon">
199                <xsl:param name='elements'/>
200                <xsl:param name='rule'/>
201
202                <!-- This is the instruction that is currently being processed -->
203                <xsl:variable name='instruction' select='.'/>
204
205        <Placemark>
206            <xsl:if test="$instruction/@name">
207                <name><xsl:value-of select="$instruction/@name"/></name>
208            </xsl:if>
209            <styleUrl>#<xsl:value-of select="$instruction/@class"/></styleUrl>
210            <MultiGeometry>
211                <!-- For each segment and way -->
212                <xsl:apply-templates select='$elements' mode='line'>
213                    <xsl:with-param name='instruction' select='$instruction' />
214                </xsl:apply-templates>
215            </MultiGeometry>
216        </Placemark>
217        </xsl:template>
218
219        <!-- Suppress output of any unhandled elements -->
220        <xsl:template match='*' mode='line'/>
221        <xsl:template match='*' mode='point'/>
222
223        <!-- Draw points -->
224    <xsl:template match="node" mode="point">
225                <xsl:param name='instruction' />
226
227        <Placemark>
228            <xsl:if test="tag[(@k='name')and(@v!='')]">
229                <name><xsl:value-of select="tag[@k='name']/@v"/></name>
230            </xsl:if>
231            <styleUrl>#<xsl:value-of select="$instruction/@class"/></styleUrl>
232            <Point>
233                <coordinates>
234                    <xsl:value-of select="@lon"/><xsl:text>,</xsl:text>
235                    <xsl:value-of select="@lat"/><xsl:text>,0
236</xsl:text>
237                </coordinates>
238            </Point>
239        </Placemark>
240        </xsl:template>
241
242        <!-- Draw lines for a segment -->
243    <xsl:template match="segment" mode="line">
244                <xsl:param name='instruction' />
245
246                <xsl:call-template name='drawLine'>
247                        <xsl:with-param name='instruction' select='$instruction'/>
248                        <xsl:with-param name='segment' select='.'/>
249                </xsl:call-template>
250        </xsl:template>
251
252        <!-- Draw lines for a way (draw all the segments that belong to the way) -->
253        <xsl:template match='way' mode='line'>
254                <xsl:param name='instruction' />
255
256                <!-- The current <way> element -->
257                <xsl:variable name='way' select='.' />
258               
259                <xsl:call-template name='drawWay'>
260                        <xsl:with-param name='instruction' select='$instruction'/>
261                        <xsl:with-param name='way' select='$way'/>
262                </xsl:call-template>
263        </xsl:template>
264       
265        <!-- ============================================================================= -->
266        <!-- Drawing templates                                                             -->
267        <!-- ============================================================================= -->
268
269        <!-- Draw a line for the current <segment> element using the formatting of the current <line> instruction -->
270        <xsl:template name='drawLine'>
271                <xsl:param name='instruction'/>
272                <xsl:param name='segment'/> <!-- The current segment element -->
273                <xsl:param name='way'/>  <!-- The current way element if applicable -->
274
275                <xsl:variable name='from' select='@from'/>
276                <xsl:variable name='to' select='@to'/>
277                <xsl:variable name='fromNode' select='key("nodeById",$from)'/>
278                <xsl:variable name='toNode' select='key("nodeById",$to)'/>
279
280            <LineString>
281                <coordinates>
282                    <xsl:value-of select="$fromNode/@lon"/>,<xsl:value-of select="$fromNode/@lat"/>
283                    <xsl:text>,0
284</xsl:text>
285                    <xsl:value-of select="$toNode/@lon"/>,<xsl:value-of select="$toNode/@lat"/>
286                    <xsl:text>,0
287</xsl:text>
288                </coordinates>
289            </LineString>
290        </xsl:template>
291
292        <!-- Draw a line for the current <way> element using the formatting of the current <line> instruction -->       
293        <xsl:template name='drawWay'>
294                <xsl:param name='instruction'/>
295                <xsl:param name='way'/>  <!-- The current way element if applicable -->
296
297        <xsl:choose>
298            <xsl:when test="name($instruction)='polyline'">
299                <LineString>
300                    <xsl:call-template name="coordinates">
301                        <xsl:with-param name="way" select="$way"/>
302                    </xsl:call-template>
303                </LineString>
304            </xsl:when>
305            <xsl:otherwise>
306                <Polygon>
307                    <altitudeMode>relativeToGround</altitudeMode>
308                    <outerBoundaryIs>
309                        <LinearRing>
310                            <xsl:call-template name="coordinates">
311                                <xsl:with-param name="way" select="$way"/>
312                            </xsl:call-template>
313                        </LinearRing>
314                    </outerBoundaryIs>
315                </Polygon>
316            </xsl:otherwise>
317        </xsl:choose>
318
319        </xsl:template>
320
321    <xsl:template name="coordinates">
322                <xsl:param name='way'/>  <!-- The current way element if applicable -->
323        <coordinates>
324            <xsl:for-each select="$way/seg">
325                <xsl:variable name="segment" select='key("segmentById", @id)'/>
326                <xsl:variable name='from' select='$segment/@from'/>
327                <xsl:variable name='to' select='$segment/@to'/>
328                <xsl:variable name='fromNode' select='key("nodeById",$from)'/>
329                <xsl:variable name='toNode' select='key("nodeById",$to)'/>
330                <xsl:if test="$fromNode/@lat!=''">
331                    <xsl:value-of select="$fromNode/@lon"/>,<xsl:value-of select="$fromNode/@lat"/>
332            <xsl:text>,0
333</xsl:text>
334                    <xsl:value-of select="$toNode/@lon"/>,<xsl:value-of select="$toNode/@lat"/>
335            <xsl:text>,0
336</xsl:text>
337                </xsl:if>
338            </xsl:for-each>
339
340        </coordinates>
341        </xsl:template>
342
343</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.