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