示例#1
0
def query_address_api(df, address_api='openmapquest', address_api_key=None):

    logger.info("Querying address API")

    # Create the address data frame and cache file if it doesn't exist already
    if not os.path.exists(ADDRESS_CACHE):
        logger.info(
            "Converting {} geometries to EPSG 4326, this may take awhile ".
            format(len(df)))
        df_address = geopandas.GeoDataFrame(df.to_crs(epsg='4326').geometry,
                                            crs='epsg:4326')
        df_address['address'] = None
        logger.info("Creating new address cache file {}".format(ADDRESS_CACHE))
        df_address.to_file(ADDRESS_CACHE, driver='ESRI Shapefile')
    else:
        logger.info(
            "Reading in previous address cache file {}".format(ADDRESS_CACHE))
        df_address = geopandas.read_file(ADDRESS_CACHE)

    empty_address = df_address.loc[pd.isna(df_address['address'])]
    logger.info("Querying for {} addresses".format(len(empty_address)))
    for row in tqdm(empty_address.itertuples(), total=empty_address.shape[0]):
        try:
            address = reverse_geocode(row.geometry.centroid,
                                      user_agent='caladrius',
                                      provider=address_api,
                                      api_key=address_api_key)
            df_address.loc[row.Index, 'address'] = address['address'][0]
            df_address.to_file(ADDRESS_CACHE, driver='ESRI Shapefile')
        except Exception as e:
            logger.exception('Geocoding failed for {latlon}'.format(
                latlon=row.geometry.centroid))
            continue
示例#2
0
def get_point_location(points, provider='nominatim', user_agent='petk'):
    centroid = MultiPoint(points).centroid

    if importlib.util.find_spec('geopy') is not None:
        from geopandas.tools import reverse_geocode

        return reverse_geocode(centroid,
                               provider=provider,
                               user_agent=user_agent)['address'][0]
    else:
        return ', '.join([str(x) for x in mapping(centroid)['coordinates']])
示例#3
0
    def test_reverse(self):
        with mock.patch('geopy.geocoders.googlev3.GoogleV3.reverse',
                        ReverseMock()) as m:
            g = reverse_geocode(self.points, provider='googlev3', timeout=2)
            self.assertEqual(len(self.points), m.call_count)

        self.assertIsInstance(g, gpd.GeoDataFrame)

        expected = GeoSeries(self.points, crs=from_epsg(4326))
        assert_geoseries_equal(expected, g['geometry'])
        tm.assert_series_equal(
            g['address'],
            pd.Series('address' + str(x) for x in range(len(self.points))))
示例#4
0
    def test_reverse(self):
        with mock.patch('geopy.geocoders.googlev3.GoogleV3.reverse',
                        ReverseMock()) as m:
            g = reverse_geocode(self.points, provider='googlev3', timeout=2)
            self.assertEqual(len(self.points), m.call_count)

        self.assertIsInstance(g, gpd.GeoDataFrame)

        expected = GeoSeries(self.points, crs=from_epsg(4326))
        assert_geoseries_equal(expected, g['geometry'])
        address = pd.Series(['address' + str(x) for x in range(len(self.points))],
                            name='address')
        tm.assert_series_equal(g['address'], address)
示例#5
0
    def test_reverse(self):
        with mock.patch('geopy.geocoders.googlev3.GoogleV3.reverse',
                        ReverseMock()) as m:
            g = reverse_geocode(self.points, provider='googlev3', timeout=2)
            assert len(self.points) == m.call_count

        assert isinstance(g, GeoDataFrame)

        expected = GeoSeries(self.points, crs=from_epsg(4326))
        assert_geoseries_equal(expected, g['geometry'])
        address = pd.Series(
            ['address' + str(x) for x in range(len(self.points))],
            name='address')
        assert_series_equal(g['address'], address)
示例#6
0
def test_reverse(locations, points):
    from geopy.geocoders import GeocodeFarm
    for provider in ['geocodefarm', GeocodeFarm]:
        with mock.patch('geopy.geocoders.GeocodeFarm.reverse',
                        ReverseMock()) as m:
            g = reverse_geocode(points, provider=provider, timeout=2)
            assert len(points) == m.call_count

        assert isinstance(g, GeoDataFrame)

        expected = GeoSeries(points, crs=from_epsg(4326))
        assert_geoseries_equal(expected, g['geometry'])
        address = pd.Series(['address' + str(x) for x in range(len(points))],
                            name='address')
        assert_series_equal(g['address'], address)
示例#7
0
def test_reverse(locations, points):
    from geopy.geocoders import Photon

    for provider in ["photon", Photon]:
        with mock.patch("geopy.geocoders.Photon.reverse", ReverseMock()) as m:
            g = reverse_geocode(points, provider=provider, timeout=2)
            assert len(points) == m.call_count

        assert isinstance(g, GeoDataFrame)

        expected = GeoSeries(points, crs="EPSG:4326")
        assert_geoseries_equal(expected, g["geometry"])
        address = pd.Series(["address" + str(x) for x in range(len(points))],
                            name="address")
        assert_series_equal(g["address"], address)
示例#8
0
def test_reverse(locations, points):
    from geopy.geocoders import GoogleV3
    for provider in ['googlev3', GoogleV3]:
        with mock.patch('geopy.geocoders.googlev3.GoogleV3.reverse',
                        ReverseMock()) as m:
            g = reverse_geocode(points, provider=provider, timeout=2)
            assert len(points) == m.call_count

        assert isinstance(g, GeoDataFrame)

        expected = GeoSeries(points, crs=from_epsg(4326))
        assert_geoseries_equal(expected, g['geometry'])
        address = pd.Series(
            ['address' + str(x) for x in range(len(points))],
            name='address')
        assert_series_equal(g['address'], address)
def test_bad_provider_reverse():
    from geopy.exc import GeocoderNotFound

    with pytest.raises(GeocoderNotFound):
        reverse_geocode(["cambridge, ma"], "badprovider")
示例#10
0
def test_bad_provider_reverse():
    from geopy.exc import GeocoderNotFound
    with pytest.raises(GeocoderNotFound):
        reverse_geocode(['cambridge, ma'], 'badprovider')
示例#11
0
 def test_bad_provider_reverse(self):
     with self.assertRaises(ValueError):
         reverse_geocode(['cambridge, ma'], 'badprovider')
示例#12
0
 def test_bad_provider_reverse(self):
     from geopy.exc import GeocoderNotFound
     with pytest.raises(GeocoderNotFound):
         reverse_geocode(['cambridge, ma'], 'badprovider')
示例#13
0
 def test_bad_provider_reverse(self):
     with self.assertRaises(ValueError):
         reverse_geocode(['cambridge, ma'], 'badprovider')
示例#14
0
 def test_googlev3_reverse(self):
     g = reverse_geocode(self.points, provider='googlev3', timeout=2)
     self.assertIsInstance(g, gpd.GeoDataFrame)
示例#15
0
def test_bad_provider_reverse():
    from geopy.exc import GeocoderNotFound

    with pytest.raises(GeocoderNotFound):
        reverse_geocode([Point(0, 0)], "badprovider")
示例#16
0
def apply(data, options=default_options, config=default_config, warning=print):
    """Perform conversion between latitude,longitude and address

    ARGUMENTS:

        data (pandas.DataFrame)

            The data frame must contain either an `address` field or `latitude` and `longitude`
            fields, according to whether `options["reverse"]` is `True` or `False`.

        options (dict)

            "reverse" (bool) specifies the direction of resolution. Forward resolves `address`
            from `latitude,longitude` from . Reverse resolves `latitude,longitude`
            `address` from. The default is `options["reverse"] = False`, which provides
            forward resolution.

        config (dict)

            "provider" (str) specifies the providers of the address resolution algorithm.
            The default is "nominatim".

            "user_agent" (str) specifies the user agent for the address resolution algorithm.
            The default is "csv_user_ht".

    RETURNS:

        pandas.DataFrame

            The first (and only) return value is the `data` data frame with either the
            `address` or `latitude,longitude` fields updated/added.

    """

    if options["reverse"]:

        # convert address to lat,lon
        if not "address" in list(data.columns):
            raise Exception(
                "reserve address resolution requires 'address' field")
        data.reset_index(inplace=True)  # index is not meaningful
        for retries in range(config["retries"]):
            try:
                pos = geocode(
                    data["address"],
                    provider=config["provider"],
                    user_agent=config["user_agent"],
                    timeout=config["timeout"],
                )
                break
            except Exception as err:
                pos = err
            import time
            time.sleep(config["sleep"])
        if type(pos) is Exception:
            raise pos
        data["longitude"] = list(map(lambda p: p.x, pos["geometry"]))
        data["latitude"] = list(map(lambda p: p.y, pos["geometry"]))
        return data

    else:

        # convert lat,lon to address
        try:
            lats = list(map(lambda x: float(x), data["latitude"]))
            lons = list(map(lambda x: float(x), data["longitude"]))
            pos = list(map(lambda xy: Point(xy), list(zip(lons, lats))))
        except:
            pos = None
        if type(pos) == type(None):
            raise Exception(
                "address resolution requires 'latitude' and 'longitude' fields"
            )
        for retries in range(config["retries"]):
            try:
                addr = reverse_geocode(
                    pos,
                    provider=config["provider"],
                    user_agent=config["user_agent"],
                    timeout=config["timeout"],
                )
                break
            except Exception as err:
                addr = err
            import time
            time.sleep(config["sleep"])
        if type(addr) is Exception:
            raise addr
        data["address"] = Series(addr["address"], dtype="string").tolist()
        return data