]> gitweb.michael.orlitzky.com - dead/census-tools.git/commitdiff
Added the first draft of drag_wkt_along_kml_path, most of which is basically cut...
authorMichael Orlitzky <michael@orlitzky.com>
Sun, 25 Oct 2009 22:23:53 +0000 (18:23 -0400)
committerMichael Orlitzky <michael@orlitzky.com>
Sun, 25 Oct 2009 22:23:53 +0000 (18:23 -0400)
bin/drag_wkt_along_kml_path [new file with mode: 0755]

diff --git a/bin/drag_wkt_along_kml_path b/bin/drag_wkt_along_kml_path
new file mode 100755 (executable)
index 0000000..072d72a
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+
+"""
+We take a Well-Known Text string and a KML file as parameters. The WKT
+string is converted into a polygon (hopefully), and the KML file is
+parsed for a linestring, which defines a path. We then drag the
+polygon along the linestring, and return the resulting polygon as KML.
+"""
+
+import pgdb
+import os
+import site
+import sys
+from optparse import OptionParser
+
+# Basically, add '../src' and '../lib/Shapely' to our path.
+# Needed for the imports that follow.
+site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../src')
+site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../lib/Shapely')
+
+import Configuration.Defaults
+import ExitCodes
+import Geometry
+import KML
+
+usage = '%prog [options] <well-known text> <kml filename>'
+
+# -h (help) Conflicts with -h HOSTNAME
+parser = OptionParser(usage=usage, 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('-n',
+                  '--name',
+                  help='Name to give the geometry object in the KML document.',
+                  default='WKT Object')
+
+parser.add_option('-s',
+                  '--srid',
+                  type="int",
+                  help="SRID of the input geometry. Defaults to %s." % Configuration.Defaults.SRID,
+                  default=Configuration.Defaults.SRID)
+
+(options, args) = parser.parse_args()
+
+if len(args) < 2:
+    print """
+ERROR: You must supply both a Well-Known Text string, and a KML file
+       containing a linestring.
+"""
+    parser.print_help()
+    print '' # Print a newline
+    raise SystemExit(ExitCodes.NOT_ENOUGH_ARGS)
+
+
+wkt_string = args[0]
+kml_filename = args[1]
+
+f = open(kml_filename, 'r')
+kml = f.read()
+f.close()
+
+coords = KML.LineString.tuples_from_kml(kml)
+p = Geometry.Polygon.from_wkt(wkt_string)
+
+death_tube = None
+
+for i in range(len(coords) - 1):
+    # For each coordinate (except the last), we want to:
+    # a) Translate our polygon to the coordinate.
+    # b) Drag the polygon to the next coordinate.
+    this_coord = Geometry.TwoVector(coords[i][0], coords[i][1])
+    next_coord = Geometry.TwoVector(coords[i+1][0], coords[i+1][1])
+    drag_vector = (next_coord - this_coord)
+    tp = p.translate(this_coord)
+
+    if (death_tube == None):
+        death_tube = tp.drag(drag_vector)
+    else:
+        death_tube = death_tube.union(tp.drag(drag_vector))
+
+    
+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))" % (death_tube.wkt(), options.srid)
+
+cursor.execute(kml_query)
+rows = cursor.fetchall()
+kml_representation = rows[0][0]
+conn.close()
+
+
+doc = KML.Document()
+
+# Create a semi-transparent blue polygon style, and add it to the
+# document.
+hex_value = "b0ff0000"
+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()