From: Michael Orlitzky Date: Sun, 25 Oct 2009 22:23:53 +0000 (-0400) Subject: Added the first draft of drag_wkt_along_kml_path, most of which is basically cut... X-Git-Url: https://gitweb.michael.orlitzky.com/?a=commitdiff_plain;h=2807a5f39a5950822e02ea14a7161d6c3dfc7add;p=dead%2Fcensus-tools.git Added the first draft of drag_wkt_along_kml_path, most of which is basically cut-and-pasted from the wkt2kml script. --- diff --git a/bin/drag_wkt_along_kml_path b/bin/drag_wkt_along_kml_path new file mode 100755 index 0000000..072d72a --- /dev/null +++ b/bin/drag_wkt_along_kml_path @@ -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] ' + +# -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 +# ... 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()