X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FKML.py;h=9b589ad582c0ac4f11c16a775222716bf7fa1d2f;hb=3a1235a834118bb52c5d92fce9c7182c04a44e0b;hp=890021da4167d13b0e9f7f56ae984a3c76f50f51;hpb=18b00503e26e51db44a6b3d9b279162f8278b868;p=dead%2Fcensus-tools.git diff --git a/src/KML.py b/src/KML.py index 890021d..9b589ad 100644 --- a/src/KML.py +++ b/src/KML.py @@ -3,6 +3,7 @@ Utility classes for working with the Keyhole Markup Language (KML). """ import sys +from xml.sax.saxutils import escape class KmlObject(object): @@ -21,6 +22,9 @@ class KmlObject(object): generate a closing tag. A call to render() generally returns the element's text, and renders its children recursively. """ + + OPEN_TAG = '' + CLOSE_TAG = '' def __init__(self, initial_text=''): self.children = [] @@ -28,49 +32,56 @@ class KmlObject(object): def to_kml(self): - return self.render() + kml = self.OPEN_TAG + kml += self.render() + kml += self.CLOSE_TAG + "\n" + return kml def render(self): - kml = self.text + kml = escape(self.text) for c in self.children: kml += c.to_kml() - + return kml + def print_kml(self): + print self.OPEN_TAG + self.render_to_stdout() + print self.CLOSE_TAG + + + def render_to_stdout(self): + if (len(self.text) > 0): + print escape(self.text) + + for c in self.children: + c.print_kml() + + class Color(KmlObject): - def to_kml(self): - kml = '' - kml += self.render() - kml += "\n" - return kml + OPEN_TAG = '' + CLOSE_TAG = '' - class Document(KmlObject): + + OPEN_TAG = """ + +""" + + CLOSE_TAG = """ +""" def __init__(self, initial_text=''): super(Document, self).__init__(initial_text) self.styles = [] - def to_kml(self): - kml = "\n" - kml += "\n" - kml += "\n" - - kml += self.render() - - kml += "\n" - kml += "\n" - - return kml - - def render(self): kml = '' @@ -83,78 +94,150 @@ class Document(KmlObject): return kml + def render_to_stdout(self): + for s in self.styles: + s.print_kml() + + for c in self.children: + c.print_kml() + + class Description(KmlObject): - def to_kml(self): - kml = '' - kml += self.render() - kml += "\n" - return kml - + OPEN_TAG = '' + CLOSE_TAG = '' -class Name(KmlObject): - - def to_kml(self): - kml = '' - kml += self.render() - kml += "\n" - return kml +class Coordinates(KmlObject): + OPEN_TAG = '' + CLOSE_TAG = '' -class Placemark(KmlObject): - def to_kml(self): - kml = "\n" - kml += self.render() - kml += "\n" - return kml +class LineString(KmlObject): + OPEN_TAG = '' + CLOSE_TAG = '' + @classmethod + def parse_linestrings(self, kml): + """ + Parse each ... block from the KML. + """ + linestrings = [] -class PolyStyle(KmlObject): + search_idx = kml.find(self.OPEN_TAG, 0) - def to_kml(self): - kml = "\n" - kml += self.render() - kml += "\n" - return kml + while (search_idx != -1): + # No reason to keep the tag around. + ls_start = search_idx + len(self.OPEN_TAG) + ls_tag_end = kml.find(self.CLOSE_TAG, ls_start) + ls = kml[ ls_start : ls_tag_end ] + linestrings.append(ls) + search_idx = kml.find(self.OPEN_TAG, (ls_tag_end + len(self.CLOSE_TAG))) + + return linestrings + + + @classmethod + def parse_coordinates_from_linestrings(self, linestrings): + coords = [] + + for ls in linestrings: + c_tag_start = ls.find(Coordinates.OPEN_TAG) + c_start = c_tag_start + len(Coordinates.OPEN_TAG) + c_end = ls.find(Coordinates.CLOSE_TAG) + c = ls[ c_start : c_end ] + coords.append(c) + + return coords + + + @classmethod + def tuples_from_kml(self, kml): + """ + Parse one or more linestrings from a KML document. + Return a list of tuples. + """ + ls = self.parse_linestrings(kml) + cs = self.parse_coordinates_from_linestrings(ls) + + tuples = [] + + for c in cs: + pointstrings = c.strip().split() + for point in pointstrings: + components = point.strip().split(',') + if (len(components) >= 2): + # Project the three-dimensional vector onto the + # x-y plane. I don't think we're going to run + # in to any linestrings in 3d. + tuples.append( (float(components[0]), float(components[1])) ) + + return tuples + + +class Name(KmlObject): + + OPEN_TAG = '' + CLOSE_TAG = '' + + + +class Placemark(KmlObject): + + OPEN_TAG = '' + CLOSE_TAG = '' + + +class PolyStyle(KmlObject): + + OPEN_TAG = '' + CLOSE_TAG = '' + class Style(KmlObject): - - def __init__(self, initial_text='', initial_id=None): + + OPEN_TAG = "' + + def __init__(self, initial_text='', initial_id=''): super(Style, self).__init__(initial_text) self.id = initial_id def to_kml(self): kml = '' - - if (self.id == None): - kml += "\n" + kml += self.CLOSE_TAG + "\n" return kml + def print_kml(self): + print (self.OPEN_TAG % self.id) + self.render_to_stdout() + print self.CLOSE_TAG -class StyleUrl(KmlObject): - - def to_kml(self): - kml = '' - kml += self.render() - kml += "\n" - return kml + +class StyleUrl(KmlObject): + + OPEN_TAG = '' + CLOSE_TAG = '' + class RawText(KmlObject): - pass + + def to_kml(self): + return self.text + + def print_kml(self): + if (len(self.text) > 0): + print self.text