source: osm/applications/editors/josm/haiti_earthquake/radiotv/Kml2OsmConverter.groovy@ 20007

Last change on this file since 20007 was 19939, checked in by guggis, 15 years ago

Scripts for importing radio/tv studios in Haiti

File size: 8.8 KB
Line 
1package ch.guggis.haiti.radiotv;
2
3import java.io.OutputStreamWriter;
4import java.io.StringReader;
5import java.io.BufferedReader;
6import javax.xml.xpath.*
7import groovy.util.IndentPrinter;
8import groovy.util.XmlParser
9import groovy.xml.MarkupBuilder;
10import groovy.xml.DOMBuilder;
11import javax.xml.parsers.DocumentBuilderFactory
12import org.xml.sax.InputSource
13import groovy.xml.StreamingMarkupBuilder
14import org.w3c.dom.Node
15import java.text.SimpleDateFormat
16import groovy.util.CliBuilder
17
18
19/**
20 * A radio or tv studio in the IMS list
21 */
22class Studio {
23 private static def xpath = XPathFactory.newInstance().newXPath()
24
25 def id
26 def lat
27 def lon
28 def String name = null
29 def String type = null
30 def String address = null
31 def String contact = null
32 def String email = null
33 def String phone = null
34 def String frequency = null
35 def String notes = null
36
37 /**
38 * Create a studio from a Placemark in the KML file
39 */
40 public Studio(Node placemark) {
41 initId(placemark)
42 initName(placemark)
43 initType(placemark)
44 initAddress(placemark)
45 initContact(placemark)
46 initPhone(placemark)
47 initFrequency(placemark)
48 initNotes(placemark)
49 initEmail(placemark)
50 initLatLon(placemark)
51 }
52
53 private def normalize(String s) {
54 if (s == null) return s
55 s = s.trim()
56 s = s.replaceAll("\n", " ")
57 s = s.substring(0,Math.min(s.length(), 255))
58 return s
59 }
60
61 /**
62 * init the the from the Placemark node
63 */
64 static private def exprId = xpath.compile("./@id")
65 private def initId(placemark) {
66 id = exprId.evaluate(placemark, XPathConstants.STRING)
67 }
68
69 /**
70 * init the lat/lon-coordinates from the Placemark node
71 */
72 static private def exprLatLon = xpath.compile("./Point/coordinates/text()")
73 private def initLatLon(placemark) {
74 def latlon = exprLatLon.evaluate(placemark, XPathConstants.STRING)
75 lat = null
76 lon = null
77 if (latlon == null) {
78 return
79 }
80 def latlonarr = latlon.split(",")
81 if (latlonarr == null || latlonarr.length != 2) {
82 println "Error: illegal format of latlon '${latlon}' for studio '${id}'"
83 return
84 }
85 lat = latlonarr[1].trim()
86 lon = latlonarr[0].trim()
87 }
88
89 /**
90 * init the name from the Placemark
91 */
92 static private def exprName = xpath.compile("./name/text()")
93 def initName(placemark) {
94 name = exprName.evaluate(placemark, XPathConstants.STRING)
95 if (name != null) name = name.trim()
96 }
97
98 /**
99 * init the media type from the Placemark
100 */
101 static private def exprType = xpath.compile("./ExtendedData/Data[@name = 'Type']/value/text()")
102 def initType(placemark) {
103 type = exprType.evaluate(placemark, XPathConstants.STRING)
104 if (type != null) type = type.trim()
105 }
106
107 /**
108 * init the address from the Placemark
109 */
110 static private def exprAddress = xpath.compile("./ExtendedData/Data[@name = 'Address']/value/text()")
111 def initAddress(placemark) {
112 address = normalize(exprAddress.evaluate(placemark, XPathConstants.STRING))
113 }
114
115 /**
116 * init the contact information from the Placemark
117 */
118 static private def exprContact = xpath.compile("./ExtendedData/Data[@name = 'Contact']/value/text()")
119 def initContact(placemark) {
120 contact = normalize(exprContact.evaluate(placemark, XPathConstants.STRING))
121 }
122
123 /**
124 * init the email address from the Placemark
125 */
126 static private def exprEmail = xpath.compile("./ExtendedData/Data[@name = 'Email']/value/text()")
127 def initEmail(placemark) {
128 email = normalize(exprEmail.evaluate(placemark, XPathConstants.STRING))
129 }
130
131 /**
132 * init the frequency from the Placemark
133 */
134 static private def exprFrequency = xpath.compile("./ExtendedData/Data[@name = 'Frequency']/value/text()")
135 def initFrequency(placemark) {
136 frequency = normalize(exprFrequency.evaluate(placemark, XPathConstants.STRING))
137 }
138
139 /**
140 * init the notes from the Placemark
141 */
142 static private def exprNotes = xpath.compile("./ExtendedData/Data[@name = 'Notes']/value/text()")
143 def initNotes(placemark) {
144 notes = normalize(exprNotes.evaluate(placemark, XPathConstants.STRING))
145 }
146
147 /**
148 * init the phone from the Placemark
149 */
150 static private def exprPhone = xpath.compile("./ExtendedData/Data[@name = 'Subtitle']/value/text()")
151 def initPhone(placemark) {
152 phone = normalize(exprPhone.evaluate(placemark, XPathConstants.STRING))
153 if (phone != null) {
154 def matcher = phone =~ /^\s*Tel\s*:\s*(.*)/
155 if (matcher.matches()) {
156 phone = matcher[0][1]
157 }
158 }
159 }
160
161 /**
162 * Replies true if this studio has a valid position
163 */
164 def boolean isValidPosition() {
165 return lat != null && lon != null
166 }
167
168 def boolean isTower() {
169 return notes != null && notes.startsWith("This location was found using GPS at the site")
170 }
171
172 def boolean isTvStation() {
173 return type == "TV Stations"
174 }
175}
176
177
178/**
179 * The converter
180 */
181class Kml2OsmConverter {
182 static final public String RADIO_TV_FILE = "C:/data/projekte/haiti/radiotv/RadioStationsHaitiJan2010.xml"
183 private def xpath = XPathFactory.newInstance().newXPath()
184
185 def reader
186 def writer
187
188 def process() {
189 def builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
190 def doc = builder.parse(new InputSource(reader)).documentElement
191 def markup = new MarkupBuilder(writer)
192 def nodeId = 0
193 markup.getMkp().pi(xml: [version: "1.0", encoding:"UTF-8"])
194 markup.getMkp().comment("""
195Automatically generated from this list of radio and tv studios in haiti:
196http://spreadsheets.google.com/pub?key=tZP0wXS4HMLAWEhDlzdW36w&output=txt&output=txt&gid=0&range=kml_output
197
198Generated on: ${new SimpleDateFormat().format(new Date())}
199""")
200 markup.osm(version: "0.6", generator: "Ism2Osm") {
201 xpath.evaluate("//Placemark", doc, XPathConstants.NODESET).each {
202 Node placemark ->
203 def studio = new Studio(placemark)
204 println "Processing studio '${studio.id}' with name '${studio.name}'"
205 if (!studio.isValidPosition()) {
206 println "Error: studio '${studio.id}' doesn't have a valid position. Skipping."
207 return
208 }
209 if (!studio.id) {
210 println "Error: studio '${studio.id}' doesn't have a valid IMS id. Skipping."
211 return
212 }
213 nodeId--
214 node(id:nodeId, version:1, lat: studio.lat, lon: studio.lon) {
215 if (studio.isTower()) {
216 tag(k:"man_made", v:"tower");
217 tag(k:"tower:type", v:"communication")
218 } else {
219 tag(k:"amenity", v:"studio")
220 if (studio.isTvStation()) {
221 tag(k:"type", v:"video")
222 }
223 }
224 if (studio.name) {
225 tag(k:"name", v:studio.name)
226 }
227 if (studio.type) {
228 tag(k:"ims:media_type", v:studio.type)
229 }
230 tag(k:"ims:id", v:studio.id)
231 if (studio.address) {
232 tag(k:"addr", v:studio.address)
233 }
234 if (studio.contact) {
235 tag(k:"contact", v:studio.contact)
236 }
237 if (studio.email) {
238 tag(k: "contact:email", v:studio.email)
239 }
240 if (studio.phone) {
241 tag(k: "phone", v:studio.phone)
242 }
243 if (studio.frequency) {
244 tag(k: "ims:frequency", v:studio.frequency)
245 }
246 if (studio.notes) {
247 tag(k: "note", v:studio.notes)
248 }
249 tag(k:"source_ref", v: "http://spreadsheets.google.com/pub?key=tZP0wXS4HMLAWEhDlzdW36w&output=txt&output=txt&gid=0&range=kml_output")
250 tag(k:"source", "CartONG - http://www.cartong.org")
251 }
252 }
253 }
254
255 }
256
257 def usage() {
258 println """
259groovy ch.guggis.haiti.radiotv.Kml2OsmConverter [options]
260Options:
261 -h, --help show help information
262 -i, --input-file the input file. Reads from stdin if missing
263 -o, --output-file the output file. Writes to stdout if missing.
264"""
265 }
266
267 def fail(msg) {
268 println msg
269 usage()
270 System.exit(1)
271 }
272
273 def processCommandLineOptions(argArray) {
274 def inputFile
275 def outputFile
276 def args = Arrays.asList(argArray)
277 args = args.reverse()
278 def arg = args.pop()
279 while(arg != null) {
280 switch(arg) {
281 case "-i":
282 case "--input-file":
283 inputFile = args.pop()
284 if (inputFile == null) {
285 fail "Error: missing input file"
286 }
287 break
288 case "-o":
289 case "--output-file":
290 outputFile = args.pop()
291 if (outputFile == null) {
292 fail "Error: missing output file"
293 }
294 break
295
296 case "-h":
297 case "--help":
298 usage()
299 System.exit(0)
300 break
301
302 default:
303 fail "Illegal argument ${arg}"
304 }
305 arg = args.empty ? null : args.pop()
306 }
307
308 if (inputFile) {
309 reader = new File(inputFile).newReader("UTF-8")
310 } else {
311 reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8"))
312 }
313 if (outputFile) {
314 writer = new File(outputFile).newWriter("UTF-8")
315 } else {
316 writer = new PrintWriter(new OutputStreamWriter(System.out, "UTF-8"))
317 }
318 }
319
320 static public void main(args) {
321 def task = new Kml2OsmConverter()
322 task.processCommandLineOptions(args)
323 task.process()
324 }
325}
Note: See TracBrowser for help on using the repository browser.