Example #1
0
    def get_local_lat_lng(self, request):
        ip = request.META.get("REMOTE_ADDR", None)

        gi = pygeoip.GeoIP(settings.GEOIP_DATABASE, pygeoip.STANDARD)
        record = gi.record_by_addr(ip)

        if record:
            lat = record["latitude"]
            lng = record["longitude"]
            city = "%s, %s" % (record["city"], record["country_name"])
        else:
            lat = -4.521666
            lng = -58.318725
            city = "Amazonas, Brasil"

        if not lat or not lng:
            geocoder = Geocoder()
            results, status_code = geocoder.geocode({"address": city})
            if results:
                for r in results:
                    lat, lng = r["geometry"]["location"]["arg"]

        return maps.LatLng(lat, lng)
Example #2
0
def generate_longlat(sender, **kwargs):
    geocoder = Geocoder()
    loc = kwargs["instance"]

    region_bias = getattr(settings, "MAPS_REGION_BIAS", None)
    region_bounds = getattr(settings, "MAPS_REGION_BOUNDS", None)

    if False:
        # check if the instance is being created
        if loc.pk and loc.lat and loc.lon:
            # It created previously and is now
            # just being updated

            # Check if the address has changed
            try:
                old_loc = sender.objects.get(pk=loc.pk)
                if str(old_loc) == str(loc):
                    # the addresses havnt changed so there's
                    # no need to update the latlong
                    return
                if old_loc.lat != loc.lat or old_loc.lon != loc.lon:
                    # the latlong has been manually updated
                    # so we shouldn't change it
                    return
            except Location.DoesNotExist:
                # this doesnt make a lot of sense but...
                pass
    if loc.pk:
        # The location has already previously
        # been saved to the db and doesnt
        # need to have fields auto filled
        return

    if not loc.street_address and not loc.suburb:
        # no suburb or address so we're not going to
        # get meaningful results
        return

    addr = str(loc)

    # See of google can find the address

    query_dict = {"address": addr}
    if region_bias:
        # Limit to a certain country using a cctl (e.g. 'au' for Australia)
        query_dict["region"] = region_bias

    if region_bounds:
        # limit to a certain viewport (e.g. Melbourne)
        l, t, r, b = region_bounds
        query_dict["bounds"] = "%d,%d|%d,%d" % (l, t, r, b)

    result, code = geocoder.geocode(query_dict)

    if code != "OK":
        # something went wrong...
        return

    # 'result' looks like:
    #
    #   [{
    #       'geometry': {
    #           'location': {
    #               'arg': [-37.81928, 145.004793],
    #               'cls': 'LatLng'
    #               },
    #           'viewport': {
    #               'arg': [
    #                   {
    #                       'arg': [-37.820629, 145.003444],
    #                       'cls': 'LatLng'
    #                   },
    #                   {
    #                       'arg': [-37.817931, 145.006142],
    #                       'cls': 'LatLng'
    #                   }
    #                   ],
    #               'cls': 'LatLngBounds'
    #               },
    #           'location_type': 'ROOFTOP'
    #           },
    #       'address_components': [
    #           {
    #               'long_name': '400',
    #               'types': ['street_number'],
    #               'short_name': '400'
    #           },
    #           {'
    #               long_name': 'Bridge Rd',
    #               'types': ['route'],
    #               'short_name': 'Bridge Rd'
    #           },
    #           {
    #               'long_name': 'Richmond',
    #               'types': ['locality', 'political'],
    #               'short_name': 'Richmond'
    #           },
    #           {
    #               'long_name': 'Victoria',
    #               'types': ['administrative_area_level_1', 'political'],
    #               'short_name': 'VIC'
    #           },
    #           {
    #               'long_name': 'Australia',
    #               'types': ['country', 'political'],
    #               'short_name': 'AU'
    #           },
    #           {
    #               'long_name': '3121',
    #               'types': ['postal_code'],
    #               'short_name': '3121'
    #           }
    #           ],
    #       'formatted_address': '400 Bridge Rd, Richmond VIC 3121, Australia',
    #       'types': ['street_address']
    #       }]
    #
    # So like...just parse it?
    #

    entry = result[0]
    latitude, longitude = entry["geometry"]["location"]["arg"]
    loc.lat = latitude
    loc.lon = longitude

    addr_components = entry["address_components"]

    # match values returned from google to
    # fields in our model
    for component in addr_components:
        for t in component["types"]:
            [field_name, fmt] = addr_mappings.get(t, (None, None))
            if field_name and not loc.__getattribute__(field_name):
                # TODO make content safe
                loc.__setattr__(field_name, component[fmt])