Skip to content

Commit

Permalink
Add BaiduV3 geocoder
Browse files Browse the repository at this point in the history
  • Loading branch information
KostyaEsmukov committed May 11, 2020
1 parent f5af3d4 commit f612130
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/changelog_1xx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Changelog
* ADDED: `AlgoliaPlaces` geocoder.
Contributed by Álvaro Mondéjar. (#405)

* ADDED: `BaiduV3` geocoder. (#394)

* ADDED: `MapQuest` geocoder.
Contributed by Pratheek Rebala. (#399)

Expand Down
10 changes: 10 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ Baidu

.. automethod:: __init__

BaiduV3
-------

.. autoclass:: geopy.geocoders.BaiduV3
:members:
:inherited-members:
:show-inheritance:

.. automethod:: __init__

BANFrance
---------

Expand Down
4 changes: 3 additions & 1 deletion geopy/geocoders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"ArcGIS",
"AzureMaps",
"Baidu",
"BaiduV3",
"BANFrance",
"Bing",
"DataBC",
Expand Down Expand Up @@ -155,7 +156,7 @@
from geopy.geocoders.algolia import AlgoliaPlaces
from geopy.geocoders.arcgis import ArcGIS
from geopy.geocoders.azure import AzureMaps
from geopy.geocoders.baidu import Baidu
from geopy.geocoders.baidu import Baidu, BaiduV3
from geopy.geocoders.banfrance import BANFrance
from geopy.geocoders.base import options
from geopy.geocoders.bing import Bing
Expand Down Expand Up @@ -186,6 +187,7 @@
"arcgis": ArcGIS,
"azure": AzureMaps,
"baidu": Baidu,
"baiduv3": BaiduV3,
"banfrance": BANFrance,
"bing": Bing,
"databc": DataBC,
Expand Down
31 changes: 25 additions & 6 deletions geopy/geocoders/baidu.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ class Baidu(Geocoder):
Documentation at:
http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
.. attention::
Newly registered API keys will not work with v2 API,
use :class:`.BaiduV3` instead.
.. versionadded:: 1.0.0
"""

api_path = '/geocoder/v2/'
reverse_path = '/geocoder/v2/'

def __init__(
self,
Expand Down Expand Up @@ -86,6 +91,7 @@ def __init__(
)
self.api_key = api_key
self.api = '%s://api.map.baidu.com%s' % (self.scheme, self.api_path)
self.reverse_api = '%s://api.map.baidu.com%s' % (self.scheme, self.reverse_path)
self.security_key = security_key

@staticmethod
Expand Down Expand Up @@ -126,7 +132,7 @@ def geocode(
'address': self.format_string % query,
}

url = self._construct_url(params)
url = self._construct_url(self.api, self.api_path, params)

logger.debug("%s.geocode: %s", self.__class__.__name__, url)
return self._parse_json(
Expand Down Expand Up @@ -162,7 +168,7 @@ def reverse(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL):
'location': self._coerce_point_to_string(query),
}

url = self._construct_url(params)
url = self._construct_url(self.reverse_api, self.reverse_path, params)

logger.debug("%s.reverse: %s", self.__class__.__name__, url)
return self._parse_reverse_json(
Expand Down Expand Up @@ -269,12 +275,25 @@ def _check_status(status):
else:
raise GeocoderQueryError('Unknown error. Status: %r' % status)

def _construct_url(self, params):
def _construct_url(self, url, path, params):
query_string = urlencode(params)
if self.security_key is None:
return "%s?%s" % (self.api, query_string)
return "%s?%s" % (url, query_string)
else:
# http://lbsyun.baidu.com/index.php?title=lbscloud/api/appendix
raw = "%s?%s%s" % (self.api_path, query_string, self.security_key)
raw = "%s?%s%s" % (path, query_string, self.security_key)
sn = hashlib.md5(quote_plus(raw).encode('utf-8')).hexdigest()
return "%s?%s&sn=%s" % (self.api, query_string, sn)
return "%s?%s&sn=%s" % (url, query_string, sn)


class BaiduV3(Baidu):
"""Geocoder using the Baidu Maps v3 API.
Documentation at:
http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
.. versionadded:: 1.22.0
"""

api_path = '/geocoding/v3/'
reverse_path = '/reverse_geocoding/v3/'
31 changes: 30 additions & 1 deletion test/geocoders/baidu.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from geopy.compat import u
from geopy.exc import GeocoderAuthenticationFailure
from geopy.geocoders import Baidu
from geopy.geocoders import Baidu, BaiduV3
from geopy.point import Point
from test.geocoders.util import GeocoderTestBase, env

Expand Down Expand Up @@ -92,3 +92,32 @@ def test_sn_with_peculiar_chars(self):
)},
{"latitude": 39.983615544507, "longitude": 116.32295155093},
)


@unittest.skipUnless(
bool(env.get('BAIDU_V3_KEY')),
"No BAIDU_V3_KEY env variable set"
)
class BaiduV3TestCase(BaiduTestCase):

@classmethod
def setUpClass(cls):
cls.geocoder = BaiduV3(
api_key=env['BAIDU_V3_KEY'],
timeout=3,
)


@unittest.skipUnless(
bool(env.get('BAIDU_V3_KEY_REQUIRES_SK')) and bool(env.get('BAIDU_V3_SEC_KEY')),
"BAIDU_V3_KEY_REQUIRES_SK and BAIDU_V3_SEC_KEY env variables not set"
)
class BaiduV3SKTestCase(BaiduSKTestCase):

@classmethod
def setUpClass(cls):
cls.geocoder = BaiduV3(
api_key=env['BAIDU_V3_KEY_REQUIRES_SK'],
security_key=env['BAIDU_V3_SEC_KEY'],
timeout=3,
)

0 comments on commit f612130

Please sign in to comment.