Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ A big thanks to all the people that help contribute:
- esy_ - Submitted Github Issues
- Sergei Grabalin (Сергей Грабалин) - Fixed Python2 Unicode Issues
- `Matthieu Rigal`_ - Added session support
- `Nick Masi`_ - Added New York State provider.

.. _`Virus Warnning`: https://github.com/virus-warnning
.. _`Kevin Brolly`: https://twitter.com/KevinBrolly
Expand All @@ -53,3 +54,4 @@ A big thanks to all the people that help contribute:
.. _patrickyan: https://github.com/patrickyan
.. _esy: https://github.com/lambda-conspiracy
.. _Matthieu Rigal: https://github.com/MRigal
.. _Nick Masi: https://github.com/N-Masi
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ $ geocode "Ottawa, ON" \
| [MapQuest][MapQuest] | World | API key | yes | yes | | yes |
| [~~Mapzen~~][Mapzen] | Shutdown | API key | yes | yes | | |
| [MaxMind][MaxMind] | World | | | | | |
| [NewYorkState][NewYorkState] | NYS | | yes | | | |
| [OpenCage][OpenCage] | World | API key | yes | yes | | |
| [OpenStreetMap][OpenStreetMap] | World | [Policy][OpenStreetMap-Policy] | yes | yes | | |
| [Tamu][Tamu] | US | API key | | | | |
Expand Down Expand Up @@ -342,3 +343,4 @@ See [CHANGELOG.md](./CHANGELOG.md)
[Komoot]: http://photon.komoot.de
[USCensus]: https://geocoding.geo.census.gov/geocoder/Geocoding_Services_API.html
[Gisgraphy]: https://premium.gisgraphy.com/
[NewYorkState]: https://gis.ny.gov/system/files/documents/2022/07/geocoding-help-101.pdf
2 changes: 1 addition & 1 deletion geocoder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from geocoder.api import nokia, osm, tomtom, geolytica, arcgis, opencage, locationiq # noqa
from geocoder.api import maxmind, ipinfo, freegeoip, ottawa, here, baidu, gaode, w3w # noqa
from geocoder.api import yandex, mapzen, komoot, tamu, geocodefarm, tgos, uscensus # noqa
from geocoder.api import gisgraphy # noqa
from geocoder.api import gisgraphy, newyorkstate # noqa

# EXTRAS
from geocoder.api import timezone, elevation, places, ip, canadapost, reverse, distance, location # noqa
Expand Down
11 changes: 11 additions & 0 deletions geocoder/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from geocoder.mapquest import MapquestQuery
from geocoder.mapzen import MapzenQuery
from geocoder.maxmind import MaxmindQuery
from geocoder.newyorkstate import NewYorkStateQuery
from geocoder.opencage import OpenCageQuery
from geocoder.osm import OsmQuery, OsmQueryDetail
from geocoder.ottawa import OttawaQuery
Expand Down Expand Up @@ -103,6 +104,7 @@
'reverse': MapboxReverse,
},
'maxmind': {'geocode': MaxmindQuery},
'newyorkstate': {'geocode': NewYorkStateQuery},
'ipinfo': {'geocode': IpinfoQuery},
'geonames': {
'geocode': GeonamesQuery,
Expand Down Expand Up @@ -659,3 +661,12 @@ def gisgraphy(location, **kwargs):
:param ``location``: Your search location you want geocoded.
"""
return get(location, provider='gisgraphy', **kwargs)


def newyorkstate(location, **kwargs):
"""New York State Office of Information Technology Services Provider

:param ``location``: Your search location you want geocoded.
:param ``maxRows``: (default=1) Max number of results to fetch
"""
return get(location, provider='newyorkstate', **kwargs)
102 changes: 102 additions & 0 deletions geocoder/newyorkstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/python
# coding: utf8

from __future__ import absolute_import

import logging
import re

from geocoder.base import OneResult, MultipleResultsQuery

class NewYorkStateResult(OneResult):

@property
def lat(self):
return self.raw.get('location', {}).get('y')

@property
def lng(self):
return self.raw.get('location', {}).get('x')

@property
def address(self):
return self.raw.get('address')

@property
def housenumber(self):
expression = r'\d+'
matches = re.findall(expression, self.address)
if matches:
return matches[0]

@property
def street(self):
expression = r'^\d*\s*([A-Za-z ]+)(?=,)'
matches = re.findall(expression, self.address)
if matches:
return matches[0]

@property
def city(self):
expression = r',\s*([^,]+)\s*,'
matches = re.findall(expression, self.address)
if matches:
return matches[0]

@property
def state(self):
return 'NY'

@property
def postal(self):
expression = r'\d{5}'
matches = re.findall(expression, self.address)
if matches:
return matches[-1]

@property
def country(self):
return 'USA'

@property
def address(self):
return self.raw.get('address')

@property
def accuracy(self):
return self.raw.get('score')

class NewYorkStateQuery(MultipleResultsQuery):
"""
NYS ITS Geocoder REST Services
=======================
Geocoding is the use of technology and reference data to return a geographic coordinate when a street address is entered. Geocoding is used when lists of addresses need to be placed on a map, when an address is entered in an application to center a map or return information for that location, or any other time you have an address, and a geographic coordinate is needed. An address is entered either manually or by bulk input from a database or other source. The geocoder then compares the entered address to a set of reference data. The geocoder returns a coordinate pair and standardized address for each input address it can match. The NYS ITS Geospatial Services geocoder uses a series of combinations of reference data and configuration parameters to optimize both the likelihood of a match and the quality of the results. The reference data supporting the geocoder is stored in NENA GIS Data Model standard.

API Reference
-------------
https://gisservices.its.ny.gov/arcgis/rest/services/Locators/Street_and_Address_Composite/GeocodeServer
https://gis.ny.gov/system/files/documents/2022/07/geocoding-help-101.pdf
https://gis.ny.gov/address-geocoder
"""
provider = 'newyorkstate'
method = 'geocode'

_URL = 'https://gisservices.its.ny.gov/arcgis/rest/services/Locators/Street_and_Address_Composite/GeocodeServer/findAddressCandidates'
_RESULT_CLASS = NewYorkStateResult
_KEY_MANDATORY = False

def _build_params(self, location, provider_key, **kwargs):
return {
'SingleLine': location,
'f': 'json',
'outSR': 4326,
'maxLocations': kwargs.get('maxRows', 1)
}

def _adapt_results(self, json_response):
return json_response.get('candidates', [])

if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
g = NewYorkStateQuery('65 Niagara Square, Buffalo, NY 14202')
g.debug()
14 changes: 14 additions & 0 deletions tests/test_newyorkstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# coding: utf8

import geocoder

location = '65 Niagara Square, Buffalo, NY 14202'


def test_newyorkstate():
g = geocoder.newyorkstate(location)
assert g.ok
osm_count, fields_count = g.debug()[0]
assert osm_count >= 6
assert fields_count >= 13