#!/usr/bin/python
import sys, re, xml.sax
from xml.sax.handler import ContentHandler
from cElementTree import Element, SubElement, ElementTree
import bsddb
import pickle

exportTags = ["name", "class", "highway", "oneway", "surface", "lanes"]
exportWays = 1 
segments = bsddb.hashopen("/tmp/segments.db")
class osm2gml (ContentHandler):
    def __init__ (self, fh):
        ContentHandler.__init__(self)
        self.fh = fh

    def startDocument (self):
        self.node = bsddb.hashopen("/tmp/nodes.db") 
        self.fields = {}
        self.current = None

    def startElement (self, name, attr):
        if name == 'node':
            self.node[attr["id"].encode("us-ascii")] = "%s,%s" % (attr["lon"], attr["lat"])
        elif name == 'segment':
            from_node = self.node[str(attr["from"])].split(",")
	    from_node = (from_node[0], from_node[1])
            to_node   = self.node[str(attr["to"])].split(",")
	    to_node = (to_node[0], to_node[1])
            self.current = [ [from_node, to_node], {"id": attr["id"]} ]
            if (exportWays):
                segments[str(attr['id'])] = pickle.dumps([from_node, to_node]) 
        elif name == 'tag' and self.current:
            try:
                self.current[-1][attr["k"].replace(":","_").replace(" ","_")] = attr["v"]
            except:
                self.current[attr["k"].replace(":", "_").replace(" ","_")] = attr["v"]
            self.fields[attr["k"]] = True
        elif name == 'way' and exportWays:
            self.current = {'id': attr["id"], 'segments': []}
        elif name =='seg' and self.current:
            if segments.has_key(str(attr["id"])):
                self.current['segments'].append(pickle.loads(segments[str(attr["id"])]))
            
    def endElement (self, name):
        if name == 'segment':
            self.generateSegment(*self.current)
            self.current = None
        elif name == 'way' and exportWays:
            self.generateMultiWay(self.current)
            self.current = None
    
    def generateMultiWay (self, attr):
        featureMember = Element("gml:featureMember")
        feature = SubElement(featureMember, "way")
        FID = SubElement(feature, "FID")
        FID.text = str(attr["id"])
        geometryProperty = SubElement(feature, "gml:geometryProperty")
        lineString = SubElement(geometryProperty, "gml:MultiLineString")
        data = []
        for i in attr['segments']:
             lsm = SubElement(lineString, "gml:lineStringMember")
             ls = SubElement(lsm, "gml:LineString")
             coordinates = SubElement(ls, "gml:coordinates")
             coordinates.text = " ".join(map(lambda x: "%s,%s" % x, i))
        for k, v in attr.iteritems():
            if k != "segments":
                SubElement(feature, "" + k).text = v
        ElementTree(featureMember).write(self.fh, "utf-8")
        self.fh.write("\n")
    def generateWay (self, attr):
        featureMember = Element("gml:featureMember")
        feature = SubElement(featureMember, "way")
        FID = SubElement(feature, "FID")
        FID.text = str(attr["id"])
        geometryProperty = SubElement(feature, "gml:geometryProperty")
        lineString = SubElement(geometryProperty, "gml:LineString")
        coordinates = SubElement(lineString, "gml:coordinates")
        coordinates.text = " ".join(map(lambda x: "%s,%s" % x, attr['segments']))
        for k, v in attr.iteritems():
            if k != "segments":
                SubElement(feature, "" + k).text = v
        ElementTree(featureMember).write(self.fh, "utf-8")
        self.fh.write("\n")

    def generateSegment (self, coords, attr):
        featureMember = Element("gml:featureMember")
        feature = SubElement(featureMember, "segment")
        feature.set("gml:fid", str(attr["id"]))
        FID = SubElement(feature, "FID")
        FID.text = str(attr["id"])
        geometryProperty = SubElement(feature, "gml:geometryProperty")
        lineString = SubElement(geometryProperty, "gml:LineString")
        coordinates = SubElement(lineString, "gml:coordinates")
	coordinates.text = " ".join(map(lambda x: "%s,%s" % x, coords))
        for k, v in attr.iteritems():
            if k in exportTags:
                SubElement(feature, "" + k).text = v
        ElementTree(featureMember).write(self.fh, "utf-8")
        self.fh.write("\n")

if __name__ == "__main__":
    osmParser = osm2gml(sys.stdout)
    print '<?xml version="1.0"?>'
    print '<gml:FeatureCollection xmlns:gml="http://www.opengis.net/gml"'
    print '    xmlns="http://www.openstreetmap.org/gml/">'
    xml.sax.parse( sys.stdin, osmParser )
    print '</gml:FeatureCollection>'
