Example #1
0
def app(environ, start_response):
	stderr = environ['wsgi.errors']

	cursor, response_headers = dbopen(environ, "openaddresses.sqlite")
	if cursor is None:
		start_response("304 Not Modified", response_headers)
		return []

	query_string = unquote_plus(environ['QUERY_STRING'])
	house_number, apartment_number, street, city, state, postal_code = json.loads(query_string)

	# Build the query template
	query_template = "SELECT longitude, latitude FROM addresses where {house} and street=? and city=? and region=?"
	address_base = [
		street,
		city,
		state
		]
	if postal_code is not None and postal_code != "":
		query_template += " and (postal_code=? or postal_code is null)"
		address_base.append(postal_code)

	# Result of SQL queries go here.
	row = None

	# If the apartment number is specified in the address, try a search with the exact house number and apartment number.
	if apartment_number:
		cursor.execute(query_template.replace("{house}", "apartment_number=? and house_number=?"), [apartment_number, house_number] + address_base)
		row = cursor.fetchone()

	# If the previous search was not performed or did not produce anything, try without the apartment number.
	if row is None:
		# Try for an exact match 
		#start_time = time.time()
		cursor.execute(query_template.replace("{house}", "house_number=?"), [house_number] + address_base)
		#stderr.write("elapsed: %f\n" % (time.time() - start_time))
		row = cursor.fetchone()

	# If nothing found, look for an entry which gives a range of house numbers which includes this one.
	if row is None and re.match(r'^\d+$', house_number):
		house_number = int(house_number)
		cursor.execute(query_template.replace("{house}", "house_number_start <= ? and house_number_end >= ?"), [house_number, house_number] + address_base)
		row = cursor.fetchone()

	# If we got a match, insert the latitude and longitude into a GeoJSON point object.
	if row:
		feature = {
			'type':'Feature',
			'geometry':{'type':'Point', 'coordinates':[row[0], row[1]]},
			'properties':{'precision':'ROOF'}
			}	
	else:
		feature = None

	start_response("200 OK", response_headers + [
		('Content-Type', 'application/json')
		])
	#stderr.write("Result: %s\n" % str(feature))
	return [json.dumps(feature).encode("utf-8")]
def application(environ, start_response):
	stderr = environ['wsgi.errors']

	cursor, response_headers = dbopen(environ, "openaddresses.sqlite")
	if cursor is None:
		start_response("304 Not Modified", response_headers)
		return []

	query_string = unquote_plus(environ['QUERY_STRING'])
	house_number, apartment_number, street, city, state, postal_code = json.loads(query_string)

	# Build the query template
	query_template = "SELECT longitude, latitude FROM addresses where {house} and street=? and city=? and region=?"
	address_base = [
		street,
		city,
		state
		]
	if postal_code is not None and postal_code != "":
		query_template += " and (postal_code=? or postal_code is null)"
		address_base.append(postal_code)

	# Result of SQL queries go here.
	row = None

	# If the apartment number is specified in the address, try a search with the exact house number and apartment number.
	if apartment_number:
		cursor.execute(query_template.replace("{house}", "apartment_number=? and house_number=?"), [apartment_number, house_number] + address_base)
		row = cursor.fetchone()

	# If the previous search was not performed or did not produce anything, try without the apartment number.
	if row is None:
		# Try for an exact match 
		#start_time = time.time()
		cursor.execute(query_template.replace("{house}", "house_number=?"), [house_number] + address_base)
		#stderr.write("elapsed: %f\n" % (time.time() - start_time))
		row = cursor.fetchone()

	# If nothing found, look for an entry which gives a range of house numbers which includes this one.
	if row is None and re.match(r'^\d+$', house_number):
		house_number = int(house_number)
		cursor.execute(query_template.replace("{house}", "house_number_start <= ? and house_number_end >= ?"), [house_number, house_number] + address_base)
		row = cursor.fetchone()

	# If we got a match, insert the latitude and longitude into a GeoJSON point object.
	if row:
		feature = {
			'type':'Feature',
			'geometry':{'type':'Point', 'coordinates':[row[0], row[1]]},
			'properties':{'precision':'ROOF'}
			}	
	else:
		feature = None

	start_response("200 OK", response_headers + [
		('Content-Type', 'application/json')
		])
	#stderr.write("Result: %s\n" % str(feature))
	return [json.dumps(feature).encode("utf-8")]
def application(environ, start_response):
	stderr = environ['wsgi.errors']

	cursor, response_headers = dbopen(environ, "parcels.sqlite")
	if cursor is None:
		start_response("304 Not Modified", response_headers)
		return []

	query_string = urllib.unquote_plus(environ['QUERY_STRING'])
	#stderr.write("QUERY_STRING: %s\n" % query_string)
	house_number, apartment_number, street, town, state, postal_code = json.loads(query_string)

	# Build the query and the list of address elements to be inserted into it
	query = "SELECT centroid FROM parcel_addresses where house_number=? and street=? and city=? and state=?"
	address = [
		house_number,
		street,
		town,
		state
		]
	if postal_code != "":
		query += " and (zip=? OR zip='' OR zip IS NULL)"
		address.append(postal_code)

	# Try for an exact match
	start_time = time.time()
	cursor.execute(query, address)
	#stderr.write("elapsed: %f\n" % (time.time() - start_time))
	row = cursor.fetchone()

	# If nothing found, try a house number two lower on the chance that
	# this is the second apartment in a duplex. The assessor's map
	# supposedly lists only the lowest number in such cases.
	if row is None:
		try:
			address[0] = str(int(address[0]) - 2)
			cursor.execute(query, address)
			row = cursor.fetchone()
		except ValueError:
			pass

	# If one or the other matched,
	if row:
		geometry = json.loads(row[0])
		feature = {
			'type':'Feature',
			'geometry':geometry,
			'properties':{'precision':'LOT'}
			}	
	else:
		feature = None

	start_response("200 OK", response_headers + [
		('Content-Type', 'application/json')
		])
	#stderr.write("Result: %s\n" % str(feature))
	return [json.dumps(feature).encode("utf-8")]
Example #4
0
def app(environ, start_response):
    stderr = environ['wsgi.errors']

    cursor, response_headers = dbopen(environ, "parcels.sqlite")
    if cursor is None:
        start_response("304 Not Modified", response_headers)
        return []

    query_string = unquote_plus(environ['QUERY_STRING'])
    #stderr.write("QUERY_STRING: %s\n" % query_string)
    house_number, apartment_number, street, town, state, postal_code = json.loads(
        query_string)

    # Build the query and the list of address elements to be inserted into it
    query = "SELECT centroid FROM parcel_addresses where house_number=? and street=? and city=? and state=?"
    address = [house_number, street, town, state]
    if postal_code != "":
        query += " and (zip=? OR zip='' OR zip IS NULL)"
        address.append(postal_code)

    # Try for an exact match
    start_time = time.time()
    cursor.execute(query, address)
    #stderr.write("elapsed: %f\n" % (time.time() - start_time))
    row = cursor.fetchone()

    # If nothing found, try a house number two lower on the chance that
    # this is the second apartment in a duplex. The assessor's map
    # supposedly lists only the lowest number in such cases.
    if row is None:
        try:
            address[0] = str(int(address[0]) - 2)
            cursor.execute(query, address)
            row = cursor.fetchone()
        except ValueError:
            pass

    # If one or the other matched,
    if row:
        geometry = json.loads(row[0])
        feature = {
            'type': 'Feature',
            'geometry': geometry,
            'properties': {
                'precision': 'LOT'
            }
        }
    else:
        feature = None

    start_response("200 OK",
                   response_headers + [('Content-Type', 'application/json')])
    #stderr.write("Result: %s\n" % str(feature))
    return [json.dumps(feature).encode("utf-8")]
Example #5
0
def application(environ, start_response):
	stderr = environ['wsgi.errors']

	m = re.match(r'^/([^/]+)/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO'])
	assert m, environ['PATH_INFO']
	layer_name = m.group(1)
	zoom = int(m.group(2))
	x = int(m.group(3))
	y = int(m.group(4))
	stderr.write("%s tile (%d, %d) at zoom %d...\n" % (layer_name, x, y, zoom))
	assert zoom <= 16

	cursor, response_headers = dbopen(environ, "osm_map.sqlite")
	if cursor is None:
		start_response("304 Not Modified", response_headers)
		return []

	p1 = unproject_from_tilespace(x, y, zoom)
	p2 = unproject_from_tilespace(x + 1.0, y + 1.0, zoom)
	small_bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0])

	p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom)
	p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom)
	large_bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0])

	if layer_name in map_layer_sets:
		layer_names = map_layer_sets[layer_name]
		geojson = {}
		for layer_name in layer_names:
			tile_geojson = get_tile(stderr, cursor, layer_name, small_bbox, large_bbox, zoom)
			if tile_geojson is not None:
				geojson[layer_name.replace("osm-vector-","")] = tile_geojson
	else:
		geojson = get_tile(stderr, cursor, layer_name, small_bbox, large_bbox, zoom)

	# Convert Python objects to JSON and compress
	out = io.BytesIO()
	with gzip.GzipFile(fileobj=out, mode='w') as fo:
		json.dump(geojson, fo)
	geojson = out.getvalue()

	start_response("200 OK", response_headers + [
		('Content-Type', 'application/json'),
		('Content-Encoding', 'gzip'),
		])
	return [geojson]
Example #6
0
def application(environ, start_response):
	stderr = environ['wsgi.errors']

	m = re.match(r'^/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO'])
	assert m, environ['PATH_INFO']
	zoom = int(m.group(1))
	x = int(m.group(2))
	y = int(m.group(3))
	stderr.write("Parcel tile (%d, %d) at zoom %d...\n" % (x, y, zoom))
	assert zoom <= 16

	cursor, response_headers = dbopen(environ, "parcels.sqlite")
	if cursor is None:
		start_response("304 Not Modified", response_headers)
		return []

	p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom)
	p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom)
	bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0])

	geometry = "Intersection(Geometry,{bbox})".format(bbox=bbox)
	if zoom < 16:
		geometry = "SimplifyPreserveTopology({geometry},{simplification})".format(
			geometry=geometry,
			simplification = 360.0 / (2.0 ** zoom) / 256.0		# one pixel
			)
	else:
		stderr.write("Not simplified\n")

	query = """SELECT rowid as __id__, AsGeoJSON({geometry}) as __geometry__, house_number, street, centroid
		FROM parcels
		WHERE MBRIntersects({bbox}, Geometry)
		AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'parcels' AND search_frame = {bbox} )
		""".format(geometry=geometry, bbox=bbox)

	cursor.execute(query)

	features = []
	for row in cursor:
		if row['__geometry__'] is None:
			continue
		row = dict(row)
		feature = {
			'type': 'Feature',
			'id': row.pop("__id__"),
			'geometry': json.loads(row.pop("__geometry__")),
			'properties': row,
			}
		features.append(feature)
	stderr.write("Found %d feature(s)\n" % len(features))

	geojson = {
		'type': 'FeatureCollection',
		'features': features,
		}

	# Convert to JSON and compress
	out = io.BytesIO()
	with gzip.GzipFile(fileobj=out, mode='w') as fo:
		json.dump(geojson, fo)
	geojson = out.getvalue()

	start_response("200 OK", response_headers + [
		('Content-Type', 'application/json'),
		('Content-Encoding', 'gzip'),
		])
	return [geojson]
Example #7
0
def application(environ, start_response):
    stderr = environ['wsgi.errors']

    m = re.match(r'^/(\d+)/(\d+)/(\d+)\.geojson$', environ['PATH_INFO'])
    assert m, environ['PATH_INFO']
    zoom = int(m.group(1))
    x = int(m.group(2))
    y = int(m.group(3))
    stderr.write("Parcel tile (%d, %d) at zoom %d...\n" % (x, y, zoom))
    assert zoom <= 16

    cursor, response_headers = dbopen(environ, "parcels.sqlite")
    if cursor is None:
        start_response("304 Not Modified", response_headers)
        return []

    p1 = unproject_from_tilespace(x - 0.05, y - 0.05, zoom)
    p2 = unproject_from_tilespace(x + 1.05, y + 1.05, zoom)
    bbox = 'BuildMBR(%f,%f,%f,%f,4326)' % (p1[1], p1[0], p2[1], p2[0])

    geometry = "Intersection(Geometry,{bbox})".format(bbox=bbox)
    if zoom < 16:
        geometry = "SimplifyPreserveTopology({geometry},{simplification})".format(
            geometry=geometry,
            simplification=360.0 / (2.0**zoom) / 256.0  # one pixel
        )
    else:
        stderr.write("Not simplified\n")

    query = """SELECT rowid as __id__, AsGeoJSON({geometry}) as __geometry__, house_number, street, centroid
		FROM parcels
		WHERE MBRIntersects({bbox}, Geometry)
		AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'parcels' AND search_frame = {bbox} )
		""".format(geometry=geometry, bbox=bbox)

    cursor.execute(query)

    features = []
    for row in cursor:
        if row['__geometry__'] is None:
            continue
        row = dict(row)
        feature = {
            'type': 'Feature',
            'id': row.pop("__id__"),
            'geometry': json.loads(row.pop("__geometry__")),
            'properties': row,
        }
        features.append(feature)
    stderr.write("Found %d feature(s)\n" % len(features))

    geojson = {
        'type': 'FeatureCollection',
        'features': features,
    }

    # Convert to JSON and compress
    out = io.BytesIO()
    with gzip.GzipFile(fileobj=out, mode='w') as fo:
        json.dump(geojson, fo)
    geojson = out.getvalue()

    start_response(
        "200 OK", response_headers + [
            ('Content-Type', 'application/json'),
            ('Content-Encoding', 'gzip'),
        ])
    return [geojson]