Skip to content

Commit

Permalink
#117 Added Yandex as Provider
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisCarriere committed Mar 1, 2015
1 parent a413b68 commit 82e6076
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 18 deletions.
55 changes: 55 additions & 0 deletions docs/providers/Yandex.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Yandex

Yandex (Russian: Яндекс) is a Russian Internet company
which operates the largest search engine in Russia with
about 60% market share in that country.

The Yandex home page has been rated as the most popular website in Russia.

## Examples

**Standard Geocoding**

```python
>>> import geocoder
>>> g = geocoder.yandex('Moscow Russia')
>>> g.json
...
```

**Reverse Geocoding**

```python
>>> import geocoder
>>> g = geocoder.yandex([45.15, -75.14], method='reverse')
>>> g.json
...
```

**Command Line Interface**

```bash
$ geocode 'embedded.fizzled.trial' --provider w3w
$ geocode '45.15, -75.14' --provider w3w --method reverse
```

## Parameters

- `location`: Your search location you want geocoded.
- `lang`: Chose the following language:
* `ru-RU` — Russian (by default)
* `uk-UA` — Ukrainian
* `be-BY` — Belarusian
* `en-US` — American English
* `en-BR` — British English
* `tr-TR` — Turkish (only for maps of Turkey)
- `kind`: Type of toponym (only for reverse geocoding):
* `house` - house or building
* `street` - street
* `metro` - subway station
* `district` - city district
* `locality` - locality (city, town, village, etc.)

## References

- [API Reference](http://api.yandex.com/maps/doc/geocoder/desc/concepts/input_params.xml)
2 changes: 1 addition & 1 deletion geocoder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# CORE
from .api import get, yahoo, bing, geonames, google, mapquest
from .api import nokia, osm, tomtom, geolytica, arcgis, opencage
from .api import maxmind, freegeoip, ottawa, here, baidu, w3w
from .api import maxmind, freegeoip, ottawa, here, baidu, w3w, yandex

# EXTRAS
from .api import timezone, elevation, ip, canadapost, reverse
Expand Down
27 changes: 27 additions & 0 deletions geocoder/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .google import Google
from .arcgis import Arcgis
from .ottawa import Ottawa
from .yandex import Yandex
from .maxmind import Maxmind
from .opencage import OpenCage
from .geonames import Geonames
Expand All @@ -25,6 +26,7 @@
from .here_reverse import HereReverse
from .bing_reverse import BingReverse
from .google_reverse import GoogleReverse
from .yandex_reverse import YandexReverse
from .mapquest_reverse import MapquestReverse
from .opencage_reverse import OpenCageReverse

Expand Down Expand Up @@ -57,6 +59,10 @@ def get(location, **kwargs):
'geocode': W3W,
'reverse': W3WReverse,
},
'yandex': {
'geocode': Yandex,
'reverse': YandexReverse,
},
'mapquest': {
'geocode': Mapquest,
'reverse': MapquestReverse,
Expand Down Expand Up @@ -108,6 +114,27 @@ def google(location, **kwargs):
return get(location, provider='google', **kwargs)


def yandex(location, **kwargs):
"""Yandex Provider
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
"""
return get(location, provider='yandex', **kwargs)


def w3w(location, **kwargs):
"""what3words Provider
Expand Down
29 changes: 16 additions & 13 deletions geocoder/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,25 +187,28 @@ def status(self):

def _get_bbox(self, south, west, north, east):
# South Latitude, West Longitude, North Latitude, East Longitude
self.south = south
self.west = west
self.north = north
self.east = east
try:
self.south = float(south)
self.west = float(west)
self.north = float(north)
self.east = float(east)
except:
pass

# Bounding Box Corners
self.northeast = [north, east]
self.northwest = [north, west]
self.southwest = [south, west]
self.southeast = [south, east]
self.northeast = [self.north, self.east]
self.northwest = [self.north, self.west]
self.southwest = [self.south, self.west]
self.southeast = [self.south, self.east]

# GeoJSON bbox
self.westsouth = [west, south]
self.eastnorth = [east, north]
self.westsouth = [self.west, self.south]
self.eastnorth = [self.east, self.north]

if bool(south and east and north and west):
if bool(self.south and self.east and self.north and self.west):
bbox = {
'northeast': [north, east],
'southwest': [south, west],
'northeast': [self.north, self.east],
'southwest': [self.south, self.west],
}
return bbox
return {}
Expand Down
1 change: 0 additions & 1 deletion geocoder/bing.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,5 @@ def bbox(self):
return self._get_bbox(south, west, north, east)

if __name__ == '__main__':
#g = Bing('1552 Payette dr, Ottawa ON')
g = Bing('Ottawa ON')
g.debug()
13 changes: 10 additions & 3 deletions geocoder/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ def _check_for_list(self, location):
condition_3 = lat <= 90 and lat >= -90
condition_4 = lng <= 180 and lng >= -180

# Check if inputs are within the World Geographical boundary (90,180,-90,-180)
# Check if inputs are within the World Geographical
# boundary (90,180,-90,-180)
if bool(condition_3 and condition_4):
self.lat = lat
self.lng = lng
return self.lat, self.lng
else:
self.error = 'ERROR - Lat & Lng are not within the world\'s geographical boundary.'
self.error = 'ERROR - Lat & Lng are not '\
'within the world\'s geographical boundary.'
else:
self.error = 'ERROR - Lat & Lng are not floats.'

Expand All @@ -96,7 +98,12 @@ def latlng(self):
if bool(condition1 and condition2):
return '{0}, {1}'.format(self.lat, self.lng)

@property
def xy(self):
condition1 = isinstance(self.lat, float)
condition2 = isinstance(self.lng, float)
if bool(condition1 and condition2):
return '{0}, {1}'.format(self.lng, self.lat)

if __name__ == '__main__':
l = Location('45.123, 0.0')
print(l.latlng)
124 changes: 124 additions & 0 deletions geocoder/yandex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#!/usr/bin/python
# coding: utf8

from .base import Base


class Yandex(Base):
"""
Yandex
======
Yandex (Russian: Яндекс) is a Russian Internet company
which operates the largest search engine in Russia with
about 60% market share in that country.
The Yandex home page has been rated as the most popular website in Russia.
Params
------
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
References
----------
API Reference: http://api.yandex.com/maps/doc/geocoder/
desc/concepts/input_params.xml
"""
provider = 'yandex'
method = 'geocode'

def __init__(self, location, **kwargs):
self.url = 'http://geocode-maps.yandex.ru/1.x/'
self.location = location
self.params = {
'geocode': location,
'lang': kwargs.get('lang', 'en-US'),
'kind': kwargs.get('kind', ''),
'format': 'json',
'results': 1,
}
self._initialize(**kwargs)

def _exceptions(self):
# Build intial Tree with results
feature = self.parse['GeoObjectCollection']['featureMember']
for item in feature:
self._build_tree(item['GeoObject'])

@property
def address(self):
return self.parse['GeocoderMetaData'].get('text')

@property
def lat(self):
pos = self.parse['Point'].get('pos')
if pos:
return pos.split(' ')[1]

@property
def lng(self):
pos = self.parse['Point'].get('pos')
if pos:
return pos.split(' ')[0]

@property
def bbox(self):
if self.parse['Envelope']:
east, north = self.parse['Envelope'].get('upperCorner').split(' ')
west, south = self.parse['Envelope'].get('lowerCorner').split(' ')
return self._get_bbox(south, west, north, east)

@property
def quality(self):
return self.parse['GeocoderMetaData'].get('kind')

@property
def accuracy(self):
return self.parse['GeocoderMetaData'].get('precision')

@property
def housenumber(self):
return self.parse['Premise'].get('PremiseNumber')

@property
def street(self):
return self.parse['Thoroughfare'].get('ThoroughfareName')

@property
def city(self):
return self.parse['Locality'].get('LocalityName')

@property
def county(self):
return self.parse['SubAdministrativeArea'].get('SubAdministrative'
'AreaName')

@property
def state(self):
return self.parse['AdministrativeArea'].get('AdministrativeAreaName')

@property
def country(self):
return self.parse['Country'].get('CountryName')

@property
def country_code(self):
return self.parse['Country'].get('CountryNameCode')


if __name__ == '__main__':
g = Yandex('-75.501846, 45.481158')
import json
print(json.dumps(g.json, indent=2))
65 changes: 65 additions & 0 deletions geocoder/yandex_reverse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/python
# coding: utf8

from .base import Base
from .yandex import Yandex
from .location import Location


class YandexReverse(Yandex, Base):
"""
Yandex
======
Yandex (Russian: Яндекс) is a Russian Internet company
which operates the largest search engine in Russia with
about 60% market share in that country.
The Yandex home page has been rated as the most popular website in Russia.
Params
------
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
References
----------
API Reference: http://api.yandex.com/maps/doc/geocoder/
desc/concepts/input_params.xml
"""
provider = 'yandex'
method = 'reverse'

def __init__(self, location, **kwargs):
self.url = 'http://geocode-maps.yandex.ru/1.x/'
location = Location(location)
self.location = location.xy
self.params = {
'geocode': self.location,
'lang': kwargs.get('lang', 'en-US'),
'kind': kwargs.get('kind', ''),
'format': 'json',
'results': 1,
}
self._initialize(**kwargs)

@property
def ok(self):
return bool(self.address)


if __name__ == '__main__':
g = Yandex('-75.501846, 45.481158')
import json
print(json.dumps(g.json, indent=2))

0 comments on commit 82e6076

Please sign in to comment.