def chicken_finder(request): t1 = time.time() lat, long = request.args["gps"][0].split(",") geopoint = GeoPoint(lat=float(lat), long=float(long)) ghash = geohash.encode(geopoint.lat, geopoint.long, precision=10) postcode = yield geo.geopoint_to_postcode(geopoint, ghash) logging.info("Got postcode: %s" % postcode) location = Location(geopoint=geopoint, geohash=ghash, postcode=postcode) places = {} returner = [] futures = [] titles_cache = [] for name, instance in SOURCES.items(): if instance.NEEDS_POSTCODE and not location.postcode: continue futures.append(instance.GetAvailablePlaces(location)) results = yield defer.DeferredList(futures) for result in results: if result[0]: for id, p in result[1].items(): if p.Title not in titles_cache: titles_cache.append(p.Title) places[id] = p # Some sources may already have set the location. Filter those out and get the geopoints geopoints = yield geo.address_to_geopoint( {l.Id: l.Address for l in places.values() if l.Location is None}) for id, point in geopoints.items(): places[id] = places[id]._replace(Location=point) for id, place in places.items(): if not place.Distance and not place.Location: # We have a problem! For now exclude them from the results. # ToDo: Do something smart here. continue returner.append( place._replace( Distance=geo.distance(location.geopoint, place.Location))) # Now each location hopefully has a resolved GeoPoint we can sort the Locations by the distance from us returner = [ p._asdict() for p in sorted(returner, key=operator.attrgetter('Distance'))[:10] ] t2 = time.time() print "Request took %s" % (t2 - t1) request.setHeader("content-type", "application/json") defer.returnValue(json.dumps(returner))
def chicken_finder(request): t1 = time.time() lat, long = request.args["gps"][0].split(",") geopoint = GeoPoint(lat=float(lat), long=float(long)) ghash = geohash.encode(geopoint.lat, geopoint.long, precision=10) postcode = yield geo.geopoint_to_postcode(geopoint, ghash) logging.info("Got postcode: %s"%postcode) location = Location(geopoint=geopoint, geohash=ghash, postcode=postcode) places = {} returner = [] futures = [] titles_cache = [] for name,instance in SOURCES.items(): if instance.NEEDS_POSTCODE and not location.postcode: continue futures.append(instance.GetAvailablePlaces(location)) results = yield defer.DeferredList(futures) for result in results: if result[0]: for id,p in result[1].items(): if p.Title not in titles_cache: titles_cache.append(p.Title) places[id] = p # Some sources may already have set the location. Filter those out and get the geopoints geopoints = yield geo.address_to_geopoint({l.Id:l.Address for l in places.values() if l.Location is None}) for id,point in geopoints.items(): places[id] = places[id]._replace(Location=point) for id,place in places.items(): if not place.Distance and not place.Location: # We have a problem! For now exclude them from the results. # ToDo: Do something smart here. continue returner.append(place._replace(Distance=geo.distance(location.geopoint, place.Location))) # Now each location hopefully has a resolved GeoPoint we can sort the Locations by the distance from us returner = [p._asdict() for p in sorted(returner, key=operator.attrgetter('Distance'))[:10]] t2 = time.time() print "Request took %s"%(t2-t1) request.setHeader("content-type", "application/json") defer.returnValue(json.dumps(returner))
def save(self, location): lat = location['lat'] lng = location['lng'] loc = db.GeoPt(lat, lng) loc_hash = geohash.encode(lat, lng) bbox_hash = loc_hash[:6] bbox = Box.get_or_insert(bbox_hash) bbox.save() self.location = loc self.online = True self.box = bbox self.fb_uid = self.key().name() self.put()
def geopoint_to_address(geopoint, ghash=None): if ghash is None: ghash = geohash.encode(geopoint.lat, geopoint.long, precision=10) cache_result = postcode_cache.get(ghash) if cache_result is not None: defer.returnValue(cache_result) else: # Lookup the address page = yield getPage(get_reverse_uri(geopoint)) rset = json.loads(page)["ResultSet"] if "Result" in rset: address = rset["Result"] else: address = rset["Results"][0] postcode_cache.set(ghash, address) defer.returnValue(address)
def GetAvailablePlaces(self, postcode=None, location=None): encoded = geohash.encode(location.lat, location.lon, precision=10) result = memcache.get(encoded, namespace=self.NAME) if result is None: result = json.loads(urlfetch.fetch(BASE_URL.format(location.lat, location.lon)).content) memcache.set(encoded, result, namespace=self.NAME) places = [] for place in result: chicken_place = ChickenPlace() chicken_place.title = place["storeName"] chicken_place.address = "%s %s %s %s"%(place["address1"], place["address2"], place["address3"], place["postcode"]) chicken_place.location = ndb.GeoPt(place["latitude"], place["longitude"]) places.append(chicken_place) return places
def GetAvailablePlaces(self, postcode=None, location=None): encoded = geohash.encode(location.lat, location.lon, precision=10) result = memcache.get(encoded, namespace=self.NAME) if result is None: result = json.loads( urlfetch.fetch(BASE_URL.format(location.lat, location.lon)).content) memcache.set(encoded, result, namespace=self.NAME) places = [] for place in result: chicken_place = ChickenPlace() chicken_place.title = place["storeName"] chicken_place.address = "%s %s %s %s" % ( place["address1"], place["address2"], place["address3"], place["postcode"]) chicken_place.location = ndb.GeoPt(place["latitude"], place["longitude"]) places.append(chicken_place) return places
def geohash_encode(pt): """Geohash a point (lon, lat)""" from lib import geohash return geohash.encode(pt[1], pt[0])