]> gitweb.michael.orlitzky.com - dead/census-tools.git/blob - bin/wkt2kml
Added a "Related Projects" heading containing a description of TRAGIS.
[dead/census-tools.git] / bin / wkt2kml
1 #!/usr/bin/env python
2
3 """
4 Convert an OGC Well-Known Text string to a Keyhole Markup Language
5 (KML) file.
6 """
7
8 """
9 We take a Well-Known Text[1] string as input, and optionally a
10 filename to which to write the output. While we shouldn't technically
11 *need* access to a PostGIS database to perform this conversion, it
12 makes everything a lot easier, so we require it.
13
14 There is prior art[2] (written in Perl) should we ever desire to do the
15 conversions correctly, sans-database.
16
17 [1] http://en.wikipedia.org/wiki/Well-known_text
18 [2] http://search.cpan.org/dist/Geo-Converter-WKT2KML/
19 """
20
21 from optparse import OptionParser
22 import os
23 import pgdb
24 import site
25 import sys
26
27 # Basically, add '../src' to our path.
28 # Needed for the imports that follow.
29 site.addsitedir(os.path.dirname(os.path.abspath(sys.argv[0])) + '/../src')
30
31 import Configuration.Defaults
32 import ExitCodes
33 import GPS
34 import SummaryFile1
35 import KML
36
37
38 """
39 Parse the command line options. All of these are optional; defaults
40 are provided for the database information and the output is written to
41 stdout unless otherwise specified via '-o'.
42
43 We take an SRID too, in case there's ever a reason to override the
44 default. The name option is available in case the user would like to
45 e.g. see the object name in Google Earth.
46 """
47
48 # -h (help) Conflicts with -h HOSTNAME
49 parser = OptionParser(add_help_option = False)
50
51 # Use this module's docstring as the description.
52 parser.description = __doc__.strip()
53
54 parser.add_option('-h',
55 '--host',
56 help='The hostname/address where the database is located.',
57 default=Configuration.Defaults.DATABASE_HOST)
58
59 parser.add_option('-d',
60 '--database',
61 help='The database in which the population data are stored.',
62 default=Configuration.Defaults.DATABASE_NAME)
63
64 parser.add_option('-U',
65 '--username',
66 help='The username who has access to the database.',
67 default=Configuration.Defaults.DATABASE_USERNAME)
68
69 parser.add_option('-o',
70 '--outfile',
71 help='Optional output file path. Defaults to stdout.')
72
73 parser.add_option('-s',
74 '--srid',
75 help="SRID of the input geometry. Defaults to %s." % Configuration.Defaults.SRID,
76 default=Configuration.Defaults.SRID)
77
78 parser.add_option('-n',
79 '--name',
80 help='Name to give the geometry object in the KML document.',
81 default='WKT Object')
82
83 (options, args) = parser.parse_args()
84
85
86 if len(args) < 1:
87 print 'ERROR: You must provide a geometry object in Well-Known Text (WKT) format.'
88 parser.print_help()
89 print '' # Print a newline. Durrrr.
90 raise SystemExit(ExitCodes.NOT_ENOUGH_ARGS)
91
92
93 conn = pgdb.connect(host=options.host,
94 database=options.database,
95 user=options.username)
96
97 # We'll use this cursor for all of our queries.
98 cursor = conn.cursor()
99
100
101 # We use one query that basically just imports the WKT string and
102 # immediately exports it as KML. The geometry must have an SRID when
103 # ST_AsKml is called, so we provide one to ST_GeomFromText.
104 kml_query = "SELECT ST_AsKml(ST_GeomFromText('%s', %s))" % (args[0], options.srid)
105
106 cursor.execute(kml_query)
107 rows = cursor.fetchall()
108 kml_representation = rows[0][0]
109 conn.close()
110
111
112 doc = KML.Document()
113
114 # Create a semi-transparent red polygon style, and add it to the
115 # document.
116 hex_value = "900000ff"
117 s = KML.Style(initial_id=('default'))
118 poly_style = KML.PolyStyle()
119 color = KML.Color(hex_value)
120 poly_style.children.append(color)
121 s.children.append(poly_style)
122 doc.styles.append(s)
123
124 # We're only going to have one placemark -- the object defined by our
125 # input WKT.
126
127 placemark = KML.Placemark()
128 name = KML.Name(options.name)
129 placemark.children.append(name)
130
131 # This applies the red polygon style defined earlier to our placemark.
132 styleurl = KML.StyleUrl('default')
133 placemark.children.append(styleurl)
134
135 # The database query is going to give us raw KML. For example, if our
136 # input WKT represents a polygon, the output of ST_AsKml will contain
137 # <Polygon>...</Polygon> and everything therein.
138 rawkml = KML.RawText(kml_representation)
139 placemark.children.append(rawkml)
140 doc.children.append(placemark)
141
142 # Default the output file to sys.stdout. If we were passed an outfile
143 # as an argument, use that instead.
144 output_file = sys.stdout
145 if (options.outfile != None):
146 output_file = open(options.outfile, 'w')
147
148 # Write the KML and get out of here.
149 output_file.write(doc.to_kml())
150 output_file.close()