#!/usr/bin/env python2.3 import urllib, urllib2 import cgi, re from xml.dom.minidom import parseString url = "http://gsp.maps.nsw.gov.au/servlet/com.esri.esrimap.Esrimap?ServiceName=cad_portlet&CustomService=Query&ClientVersion=4.0&Form=True&Encode=False" class Location: def __init__(self, minx, maxx, miny, maxy, housenumberfirst, roadname, roadtype, suburb, postcode): self.minx = minx self.maxx = maxx self.miny = miny self.maxy = maxy self.x = (minx + maxx) / 2 self.y = (miny + maxy) / 2 self.housenumber = housenumberfirst self.roadname = roadname self.roadtype = roadtype self.suburb = suburb self.postcode = postcode def __str__(self): ret = "%s %s %s %s %s (%f, %f)" % (self.housenumber, self.roadname, self.roadtype, self.suburb, self.postcode, self.x, self.y) return ret def nsw_geocode(number, street, suburb = None, max=25, start=1): """Takes a number, street and suburb and returns a list of matching results. Each result in the list of a tuple of lat,lng tuples. E.g: [ ((lat, lng), (lat, lng)), ((lat, lng), (lat, lng))]. Each results is the boundary of the property searched for.""" subfields = "delivsdm:geodb.addressstring.housenumberfirst delivsdm:geodb.addressstring.roadname delivsdm:geodb.addressstring.roadtype delivsdm:geodb.addressstring.suburbname delivsdm:geodb.addressstring.postcode #SHAPE#" q = [] if number: q.append("housenumberfirst = %s" % number) if street: street = street.replace("'", "''") q.append("roadname = '%s'" % street.upper()) if suburb: suburb = suburb.replace("'", "''") q.append("suburbname = '%s'" % suburb.upper()) qs = " AND ".join(q) xml = """ """ % (max, start, subfields, qs) post_data = urllib.urlencode([("ArcXMLRequest", xml), ("FormCharset", "ISO-8859-1")]) req = urllib2.Request(url= url, data = post_data) f = urllib2.urlopen(req) data = f.read() match = re.search(r"XMLResponse='(.*)';", data) xml = match.group(1) xml = xml.replace(':', "_") xml = xml.replace('#', "_") #print xml dom = parseString(xml) error = dom.getElementsByTagName("ERROR") if len(error): raise "Error" features = dom.getElementsByTagName("FEATURE") feature_count = dom.getElementsByTagName("FEATURECOUNT")[0] count = int(feature_count.getAttribute("count")) hasmore = feature_count.getAttribute("hasmore") #print count, hasmore results = [] for feature in features: env = feature.getElementsByTagName("ENVELOPE")[0] fields = feature.getElementsByTagName("FIELDS")[0] suburb = fields.getAttribute("delivsdm_geodb.addressstring.suburbname") roadname = fields.getAttribute("delivsdm_geodb.addressstring.roadname") roadtype = fields.getAttribute("delivsdm_geodb.addressstring.roadtype") postcode = fields.getAttribute("delivsdm_geodb.addressstring.postcode") housenumberfirst = fields.getAttribute("delivsdm_geodb.addressstring.housenumberfirst") minx = float(env.getAttribute("minx")) maxx = float(env.getAttribute("maxx")) miny = float(env.getAttribute("miny")) maxy = float(env.getAttribute("maxy")) loc = Location(minx, maxx, miny, maxy, housenumberfirst, roadname, roadtype, suburb, postcode) results.append(loc) return results for each in nsw_geocode("40000", "O'Brien", "Yass"): print each