]>
gitweb.michael.orlitzky.com - dead/census-tools.git/blob - src/KML.py
2 Utility classes for working with the Keyhole Markup Language (KML).
6 from xml
.sax
.saxutils
import escape
9 class KmlObject(object):
11 The base class of all KML elements, according to the reference:
13 http://code.google.com/apis/kml/documentation/kmlreference.html
15 Every other class in this module should derive from
16 KmlObject. This class provides a default constructor which creates
17 some necessary attributes, and default implementations of to_kml()
20 The to_kml() methods of our subclasses will, in general, generate
21 an opening tag, render themselves (whatever that means), and then
22 generate a closing tag. A call to render() generally returns the
23 element's text, and renders its children recursively.
29 def __init__(self
, initial_text
=''):
31 self
.text
= initial_text
37 kml
+= self
.CLOSE_TAG
+ "\n"
42 kml
= escape(self
.text
)
44 for c
in self
.children
:
52 self
.render_to_stdout()
56 def render_to_stdout(self
):
57 if (len(self
.text
) > 0):
58 print escape(self
.text
)
60 for c
in self
.children
:
65 class Color(KmlObject
):
68 CLOSE_TAG
= '</color>'
71 class Document(KmlObject
):
73 OPEN_TAG
= """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
74 <kml xmlns=\"http://www.opengis.net/kml/2.2\">
77 CLOSE_TAG
= """</Document>
80 def __init__(self
, initial_text
=''):
81 super(Document
, self
).__init
__(initial_text
)
91 for c
in self
.children
:
97 def render_to_stdout(self
):
101 for c
in self
.children
:
106 class Description(KmlObject
):
108 OPEN_TAG
= '<description>'
109 CLOSE_TAG
= '</description>'
113 class LineString(KmlObject
):
115 OPEN_TAG
= '<LineString>'
116 CLOSE_TAG
= '</LineString>'
119 def parse_linestrings(self
, kml
):
121 Parse each <LineString>...</LineString> block from the KML.
125 search_idx
= kml
.find(self
.OPEN_TAG
, 0)
127 while (search_idx
!= -1):
128 # No reason to keep the tag around.
129 ls_start
= search_idx
+ len(self
.OPEN_TAG
)
130 ls_tag_end
= kml
.find(self
.CLOSE_TAG
, ls_start
)
131 ls
= kml
[ ls_start
: ls_tag_end
]
132 linestrings
.append(ls
)
133 search_idx
= kml
.find(self
.OPEN_TAG
, (ls_tag_end
+ len(self
.CLOSE_TAG
)))
139 def parse_coordinates_from_linestrings(self
, linestrings
):
142 for ls
in linestrings
:
143 c_tag_start
= ls
.find('<coordinates>')
144 c_start
= c_tag_start
+ len('<coordinates>')
145 c_end
= ls
.find('</coordinates>')
146 c
= ls
[ c_start
: c_end
]
153 def tuples_from_kml(self
, kml
):
155 Parse one or more linestrings from a KML document.
156 Return a list of tuples.
158 ls
= self
.parse_linestrings(kml
)
159 cs
= self
.parse_coordinates_from_linestrings(ls
)
164 pointstrings
= c
.strip().split()
165 for point
in pointstrings
:
166 components
= point
.strip().split(',')
167 if (len(components
) >= 2):
168 # Project the three-dimensional vector onto the
169 # x-y plane. I don't think we're going to run
170 # in to any linestrings in 3d.
171 tuples
.append( (float(components
[0]), float(components
[1])) )
176 class Name(KmlObject
):
179 CLOSE_TAG
= '</name>'
183 class Placemark(KmlObject
):
185 OPEN_TAG
= '<Placemark>'
186 CLOSE_TAG
= '</Placemark>'
190 class PolyStyle(KmlObject
):
192 OPEN_TAG
= '<PolyStyle>'
193 CLOSE_TAG
= '</PolyStyle>'
197 class Style(KmlObject
):
199 OPEN_TAG
= "<Style id=\"%s\">"
200 CLOSE_TAG
= '</Style>'
202 def __init__(self
, initial_text
='', initial_id
=''):
203 super(Style
, self
).__init
__(initial_text
)
209 kml
+= (self
.OPEN_TAG
% self
.id + "\n")
211 kml
+= self
.CLOSE_TAG
+ "\n"
217 print (self
.OPEN_TAG
% self
.id)
218 self
.render_to_stdout()
223 class StyleUrl(KmlObject
):
225 OPEN_TAG
= '<styleUrl>'
226 CLOSE_TAG
= '</styleUrl>'
230 class RawText(KmlObject
):
236 if (len(self
.text
) > 0):