From: Michael Orlitzky Date: Tue, 22 Sep 2009 06:50:28 +0000 (-0400) Subject: Added a script which converts an OGC Well-Known Text string to a KML document. X-Git-Url: http://gitweb.michael.orlitzky.com/?p=dead%2Fcensus-tools.git;a=commitdiff_plain;h=9a1f0d95adff6a2ee308f417b2788735d88c03b8 Added a script which converts an OGC Well-Known Text string to a KML document. --- diff --git a/bin/wkt2kml b/bin/wkt2kml new file mode 100755 index 0000000..77f8887 --- /dev/null +++ b/bin/wkt2kml @@ -0,0 +1,150 @@ +#!/usr/bin/env python + +""" +Convert an OGC Well-Known Text[1] string to a Keyhole Markup Language +(KML) file. +""" + +""" +We take a Well-Known Text 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()