def save(self, commit=True): obj = super(LocationAnswer, self).save(commit=False) if obj.value: obj.latitude, obj.longitude = get_latitude_and_longitude(obj.value) if commit: obj.save() return obj return None
def _extra_from_distance(filter, submission_id_column): """ This uses the Spherical Law of Cosines for a close enough approximation of distances. distance = acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lng2 - lng1)) * 3959 The "radius" of the earth varies between 3,950 and 3,963 miles. """ spaces = re.compile(r'\s') key = spaces.sub("+", "lat_lng_of_" + str(filter.location_value.lower())) lat_lng = cache.get(key, None) if lat_lng is None: lat_lng = get_latitude_and_longitude(filter.location_value) cache.set(key, lat_lng) (lat, lng) = lat_lng if lat is None or lng is None: return acos_of_args = ( sin(_radians(lat)), _D_TO_R, cos(_radians(lat)), _D_TO_R, lng, _D_TO_R) acos_of = ( "%f * sin(latitude / %f) + " "%f * cos(latitude / %f) * " "cos((longitude - %f) / %f)") % acos_of_args # if acos_of >= 1 then the address in the database is practically the # same address we're searching for and acos(acos_of) is mathematically # impossible so just always include it. If acos_of < 1 then we need to # check the distance. where = "".join(( submission_id_column, " IN (SELECT ca.submission_id FROM ", "survey_answer AS ca JOIN survey_submission AS cs ", "ON ca.submission_id = cs.id ", "WHERE cs.survey_id = %s AND latitude IS NOT NULL ", "AND longitude IS NOT NULL AND ", acos_of, " >= 1 OR (", acos_of, " < 1 AND 3959.0 * acos(", acos_of, ") <= %s))")) params = [int(filter.field.survey_id), int(filter.within_value)] return where, params