source: osm/applications/editors/josm/haiti_earthquake/hospitals/HospitalChunkCheck.groovy@ 22545

Last change on this file since 22545 was 19880, checked in by guggis, 15 years ago

compiled xpaths, more efficient processing

File size: 4.6 KB
Line 
1package ch.guggis.haiti.hospital;
2import java.io.BufferedReader;
3import javax.xml.xpath.*
4import groovy.util.XmlParser
5import groovy.xml.DOMBuilder
6
7/**
8 * Takes one of the chunks of health facilities posted here
9 * http://github.com/wonderchook/PAHO_to_OSM/ and checks for each
10 * entry
11 * <ol>
12 * <li>whether there are other already mapped hospitals in the neighborhood</li>
13 * <li>whether there are other already mapped health facilities in the neighborhood</li>
14 * <li>whether an OSM object with the given PAHO id already exists</li>
15 * </ol>
16 *
17 * <strong>Usage</strong>
18 * <pre>
19 * groovy ch.guggis.haiti.hospital.HospitalChunkCheck [options] file
20 *
21 * Options:
22 * -h, --help show help information
23 * </pre>
24 */
25class HospitalChunkCheck {
26
27 def File inputFile
28 def xpath = XPathFactory.newInstance().newXPath()
29
30 public HospitalChunkCheck(File inputFile) {
31 this.inputFile = inputFile
32 }
33
34 def String buildQueryBbox( node) {
35 def minLat = xpath.evaluate("./@lat", node, XPathConstants.NUMBER) - 0.003
36 def minLon = xpath.evaluate("./@lon", node, XPathConstants.NUMBER) - 0.003
37 def maxLat = xpath.evaluate("./@lat", node, XPathConstants.NUMBER) + 0.003
38 def maxLon = xpath.evaluate("./@lon", node, XPathConstants.NUMBER) + 0.003
39 return "bbox=${minLon},${minLat},${maxLon},${maxLat}"
40 }
41
42 def exprHospitalsInProximity = xpath.compile("count(//tag[@k = 'amenity'][@v = 'hospital']/..)")
43 def int countHospitalsInProximity(node) {
44 def bbox = buildQueryBbox(node)
45 def queryUrl = "http://xapi.openstreetmap.org/api/0.6/*[amenity=hospital][${bbox}]"
46 def xapiResponse = DOMBuilder.parse(new InputStreamReader(new URL(queryUrl).openStream(), "UTF-8"))
47 def int count = exprHospitalsInProximity.evaluate(xapiResponse, XPathConstants.NUMBER)
48 return count
49 }
50
51 def exprHealthFacilitiesInProximity = xpath.compile("count(//tag[@k = 'health_facility:paho_id']/..)")
52 def int countHealthFacilitiesInProximity(node) {
53 def bbox = buildQueryBbox(node)
54 def queryUrl = "http://xapi.openstreetmap.org/api/0.6/*[health_facility:paho_id=*][${bbox}]"
55 def xapiResponse = DOMBuilder.parse(new InputStreamReader(new URL(queryUrl).openStream(), "UTF-8"))
56 def int count = exprHealthFacilitiesInProximity.evaluate(xapiResponse, XPathConstants.NUMBER)
57 return count
58 }
59
60 def healthFacilityAlreadyMapped(node) {
61 def id = getHealthFacilityId(node)
62 def queryUrl = "http://xapi.openstreetmap.org/api/0.6/*[health_facility:paho_id=${id}]"
63 //def queryUrl = "http://osmxapi.hypercube.telascience.org/api/0.6/*[health_facility:paho_id=${id}]"
64 def xapiResponse = DOMBuilder.parse(new InputStreamReader(new URL(queryUrl).openStream(), "UTF-8"))
65 def int count = xpath.evaluate("count(//tag[@k = 'health_facility:paho_id'][@v =${id}])", xapiResponse, XPathConstants.NUMBER)
66 return count > 0
67 }
68
69 def exprHealthFacilityId = xpath.compile("./tag[@k = 'health_facility:paho_id']/@v")
70 def getHealthFacilityId(node) {
71 return exprHealthFacilityId.evaluate(node)
72 }
73
74 def exprName = xpath.compile("./tag[@k = 'name']/@v")
75 def getName(node) {
76 return exprName.evaluate(node)
77 }
78
79 def exprId = xpath.compile("./@id")
80 def getNodeId(node) {
81 return exprId.evaluate(node)
82 }
83
84 def process() {
85 inputFile.withReader("UTF-8") {
86 reader ->
87 def doc = DOMBuilder.parse(reader)
88 def nodes = xpath.evaluate("//node", doc, XPathConstants.NODESET)
89 nodes.each {
90 def int numHospitals = countHospitalsInProximity(it)
91 def int numHealthFacilities = countHealthFacilitiesInProximity(it)
92 def name = getName(it)
93 def id = getNodeId(it)
94 def alreadyMapped = healthFacilityAlreadyMapped(it)
95 def action = "AUTOMATIC"
96 if (alreadyMapped || numHospitals > 0 || numHealthFacilities >0) {
97 action = "MANUAL MERGE"
98 }
99 println "${action}: id:${id},name: ${name}, num hospitals: ${numHospitals}, num health facilities: ${numHealthFacilities}, already mapped: ${alreadyMapped}"
100 }
101 }
102 }
103
104 static def usage() {
105 println """
106groovy ch.guggis.haiti.hospital.HospitalChunkCheck [options] file
107
108Options:
109 -h, --help show help information
110"""
111 }
112
113
114
115 static public void main(args) {
116 def files = []
117 args.each {
118 arg ->
119 switch(arg) {
120 case "-h":
121 case "--help":
122 usage();
123 System.exit(0)
124 default:
125 files << arg
126 }
127 }
128 if (files.size() != 1) {
129 System.err.println("Error: Exactly one input file required")
130 usage()
131 System.exit(1)
132 }
133 def checker = new HospitalChunkCheck(new File(files[0]))
134 checker.process()
135 }
136}
Note: See TracBrowser for help on using the repository browser.