]> gitweb.michael.orlitzky.com - dead/census-tools.git/blob - bin/drag_wkt_along_kml_path
Set a default usage=None for the CLI.default_option_parser() function.
[dead/census-tools.git] / bin / drag_wkt_along_kml_path
1 #!/usr/bin/env python
2
3 """
4 We take a Well-Known Text string and a KML file as parameters. The WKT
5 string is converted into a polygon (hopefully), and the KML file is
6 parsed for a linestring, which defines a path. We then drag the
7 polygon along the linestring, and return the resulting polygon as KML.
8 """
9
10 import pgdb
11 import os
12 import site
13 import sys
14
15 # Basically, add '../src' and '../lib/Shapely' to our path.
16 # Needed for the imports that follow.
17 site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../src')
18 site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../lib/Shapely')
19
20 import CLI
21 import Configuration.Defaults
22 import ExitCodes
23 import Geometry
24 import KML
25
26 usage = '%prog [options] <well-known text> <kml filename>'
27
28 # -h (help) Conflicts with -h HOSTNAME
29 parser = CLI.default_option_parser(usage)
30
31 # Use this module's docstring as the description.
32 parser.description = __doc__.strip()
33
34 parser.add_option('-o',
35 '--outfile',
36 help='Optional output file path. Defaults to stdout.')
37
38 parser.add_option('-n',
39 '--name',
40 help='Name to give the geometry object in the KML document.',
41 default='WKT Object')
42
43 parser.add_option('-s',
44 '--srid',
45 type="int",
46 help="SRID of the input geometry. Defaults to %s." % Configuration.Defaults.SRID,
47 default=Configuration.Defaults.SRID)
48
49 (options, args) = parser.parse_args()
50
51 if len(args) < 2:
52 print """
53 ERROR: You must supply both a Well-Known Text string, and a KML file
54 containing a linestring.
55 """
56 parser.print_help()
57 print '' # Print a newline
58 raise SystemExit(ExitCodes.NOT_ENOUGH_ARGS)
59
60
61 wkt_string = args[0]
62 kml_filename = args[1]
63
64 f = open(kml_filename, 'r')
65 kml = f.read()
66 f.close()
67
68 coords = KML.LineString.tuples_from_kml(kml)
69 p = Geometry.Polygon.from_wkt(wkt_string)
70
71 death_tube = None
72
73 for i in range(len(coords) - 1):
74 # For each coordinate (except the last), we want to:
75 # a) Translate our polygon to the coordinate.
76 # b) Drag the polygon to the next coordinate.
77 this_coord = Geometry.TwoVector(coords[i][0], coords[i][1])
78 next_coord = Geometry.TwoVector(coords[i+1][0], coords[i+1][1])
79 drag_vector = (next_coord - this_coord)
80 tp = p.translate(this_coord)
81
82 if (death_tube == None):
83 death_tube = tp.drag(drag_vector)
84 else:
85 death_tube = death_tube.union(tp.drag(drag_vector))
86
87
88 conn = pgdb.connect(host=options.host,
89 database=options.database,
90 user=options.username)
91
92
93 # We'll use this cursor for all of our queries.
94 cursor = conn.cursor()
95
96
97 # We use one query that basically just imports the WKT string and
98 # immediately exports it as KML. The geometry must have an SRID when
99 # ST_AsKml is called, so we provide one to ST_GeomFromText.
100 kml_query = "SELECT ST_AsKml(ST_GeomFromText('%s', %s))" % (death_tube.wkt(), options.srid)
101
102 cursor.execute(kml_query)
103 rows = cursor.fetchall()
104 kml_representation = rows[0][0]
105 conn.close()
106
107
108 doc = KML.Document()
109
110 # Create a semi-transparent blue polygon style, and add it to the
111 # document.
112 hex_value = "b0ff0000"
113 s = KML.Style(initial_id=('default'))
114 poly_style = KML.PolyStyle()
115 color = KML.Color(hex_value)
116 poly_style.children.append(color)
117 s.children.append(poly_style)
118 doc.styles.append(s)
119
120 # We're only going to have one placemark -- the object defined by our
121 # input WKT.
122 placemark = KML.Placemark()
123 name = KML.Name(options.name)
124 placemark.children.append(name)
125
126 # This applies the red polygon style defined earlier to our placemark.
127 styleurl = KML.StyleUrl('default')
128 placemark.children.append(styleurl)
129
130 # The database query is going to give us raw KML. For example, if our
131 # input WKT represents a polygon, the output of ST_AsKml will contain
132 # <Polygon>...</Polygon> and everything therein.
133 rawkml = KML.RawText(kml_representation)
134 placemark.children.append(rawkml)
135 doc.children.append(placemark)
136
137 # Default the output file to sys.stdout. If we were passed an outfile
138 # as an argument, use that instead.
139 output_file = sys.stdout
140 if (options.outfile != None):
141 output_file = open(options.outfile, 'w')
142
143 # Write the KML and get out of here.
144 output_file.write(doc.to_kml())
145 output_file.close()