Example #1
0
 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
Example #2
0
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