]> gitweb.michael.orlitzky.com - dead/census-tools.git/commitdiff
Added a script which converts an OGC Well-Known Text string to a KML document.
authorMichael Orlitzky <michael@orlitzky.com>
Tue, 22 Sep 2009 06:50:28 +0000 (02:50 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Tue, 22 Sep 2009 06:50:28 +0000 (02:50 -0400)
bin/wkt2kml [new file with mode: 0755]

diff --git a/bin/wkt2kml b/bin/wkt2kml
new file mode 100755 (executable)
index 0000000..77f8887
--- /dev/null
@@ -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
+# <Polygon>...</Polygon> 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()