#!/usr/bin/env python """ Convert an OGC Well-Known Text string to a Keyhole Markup Language (KML) file. """ """ We take a Well-Known Text[1] string as input, and optionally a filename to which to write the output. While we shouldn't technically *need* access to a PostGIS database to perform this conversion, it makes everything a lot easier, so we require it. There is prior art[2] (written in Perl) should we ever desire to do the conversions correctly, sans-database. [1] http://en.wikipedia.org/wiki/Well-known_text [2] http://search.cpan.org/dist/Geo-Converter-WKT2KML/ """ from optparse import OptionParser import os import pgdb import site import sys # Basically, add '../src' to our path. # Needed for the imports that follow. site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../src') import Configuration.Defaults import ExitCodes import GPS import SummaryFile1 import KML """ Parse the command line options. All of these are optional; defaults are provided for the database information and the output is written to stdout unless otherwise specified via '-o'. We take an SRID too, in case there's ever a reason to override the default. The name option is available in case the user would like to e.g. see the object name in Google Earth. """ # -h (help) Conflicts with -h HOSTNAME parser = OptionParser(add_help_option = False) # Use this module's docstring as the description. parser.description = __doc__.strip() parser.add_option('-h', '--host', help='The hostname/address where the database is located.', default=Configuration.Defaults.DATABASE_HOST) parser.add_option('-d', '--database', help='The database in which the population data are stored.', default=Configuration.Defaults.DATABASE_NAME) parser.add_option('-U', '--username', help='The username who has access to the database.', default=Configuration.Defaults.DATABASE_USERNAME) parser.add_option('-o', '--outfile', help='Optional output file path. Defaults to stdout.') parser.add_option('-s', '--srid', help="SRID of the input geometry. Defaults to %s." % Configuration.Defaults.SRID, default=Configuration.Defaults.SRID) parser.add_option('-n', '--name', help='Name to give the geometry object in the KML document.', default='WKT Object') (options, args) = parser.parse_args() if len(args) < 1: print 'ERROR: You must provide a geometry object in Well-Known Text (WKT) format.' parser.print_help() print '' # Print a newline. Durrrr. raise SystemExit(ExitCodes.NOT_ENOUGH_ARGS) conn = pgdb.connect(host=options.host, database=options.database, user=options.username) # We'll use this cursor for all of our queries. cursor = conn.cursor() # We use one query that basically just imports the WKT string and # immediately exports it as KML. The geometry must have an SRID when # ST_AsKml is called, so we provide one to ST_GeomFromText. kml_query = "SELECT ST_AsKml(ST_GeomFromText('%s', %s))" % (args[0], options.srid) cursor.execute(kml_query) rows = cursor.fetchall() kml_representation = rows[0][0] conn.close() doc = KML.Document() # Create a semi-transparent red polygon style, and add it to the # document. hex_value = "900000ff" s = KML.Style(initial_id=('default')) poly_style = KML.PolyStyle() color = KML.Color(hex_value) poly_style.children.append(color) s.children.append(poly_style) doc.styles.append(s) # We're only going to have one placemark -- the object defined by our # input WKT. placemark = KML.Placemark() name = KML.Name(options.name) placemark.children.append(name) # This applies the red polygon style defined earlier to our placemark. styleurl = KML.StyleUrl('default') placemark.children.append(styleurl) # The database query is going to give us raw KML. For example, if our # input WKT represents a polygon, the output of ST_AsKml will contain # ... and everything therein. rawkml = KML.RawText(kml_representation) placemark.children.append(rawkml) doc.children.append(placemark) # Default the output file to sys.stdout. If we were passed an outfile # as an argument, use that instead. output_file = sys.stdout if (options.outfile != None): output_file = open(options.outfile, 'w') # Write the KML and get out of here. output_file.write(doc.to_kml()) output_file.close()