Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Melissa Data to API Options #1521

Merged
merged 4 commits into from
Sep 1, 2021
Merged
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
11 changes: 11 additions & 0 deletions README_API_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@ The [Google Places Search API](https://developers.google.com/maps/documentation/
* **Limitations**: ?
* **Notes**: You can use the open (non-licensed) API by setting: `Geocoder.configure(mapquest: {open: true})` (defaults to licensed version)

### Melissa Data (`:melissa_street`)

* **API key**: required
* **Key signup**: https://www.melissa.com/developer/
* **Quota**: ?
* **Region**: world
* **Languages**: English
* **Documentation**: https://www.melissa.com/developer/
* **Terms of Service**: https://www.melissa.com/terms
* **Limitations**: ?

### Nominatim (`:nominatim`)

* **API key**: none
Expand Down
1 change: 1 addition & 0 deletions lib/geocoder/lookup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def street_services
:latlon,
:amap,
:osmnames,
:melissa_street,
:amazon_location_service,
:geoapify
]
Expand Down
41 changes: 41 additions & 0 deletions lib/geocoder/lookups/melissa_street.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'geocoder/lookups/base'
require "geocoder/results/melissa_street"

module Geocoder::Lookup
class MelissaStreet < Base

def name
"MelissaStreet"
end

def results(query)
return [] unless doc = fetch_data(query)

if doc["TransmissionResults"] == "GE05"
raise_error(Geocoder::InvalidApiKey) ||
Geocoder.log(:warn, "Melissa service error: invalid API key.")
end

return doc["Records"]
end

private # ---------------------------------------------------------------

def base_query_url(query)
"#{protocol}://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress?"
end

def query_url_params(query)
params = {
id: configuration.api_key,
format: "JSON",
a1: query.sanitized_text,
loc: query.options[:city],
admarea: query.options[:state],
postal: query.options[:postal],
ctry: query.options[:country]
}
params.merge(super)
end
end
end
46 changes: 46 additions & 0 deletions lib/geocoder/results/melissa_street.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'geocoder/results/base'

module Geocoder::Result
class MelissaStreet < Base
def address(format = :full)
@data['FormattedAddress']
end

def street_address
@data['AddressLine1']
end

def suffix
@data['ThoroughfareTrailingType']
end

def number
@data['PremisesNumber']
end

def city
@data['Locality']
end

def state_code
@data['AdministrativeArea']
end
alias_method :state, :state_code

def country
@data['CountryName']
end

def country_code
@data['CountryISO3166_1_Alpha2']
end

def postal_code
@data['PostalCode']
end

def coordinates
[@data['Latitude'].to_f, @data['Longitude'].to_f]
end
end
end
6 changes: 6 additions & 0 deletions test/fixtures/melissa_street_invalid_key
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"Version": "3.0.1.167",
"TransmissionReference": "",
"TransmissionResults": "GE05",
"TotalRecords": "0"
}
73 changes: 73 additions & 0 deletions test/fixtures/melissa_street_low_accuracy
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"Version": "3.0.1.167",
"TransmissionReference": "",
"TransmissionResults": "",
"TotalRecords": "1",
"Records": [
{
"RecordID": "1",
"Results": "AC16,AE11,AV13,GS03",
"FormattedAddress": "Frank H Ogawa Plaza;Oakland, CA 94612",
"Organization": "",
"AddressLine1": "Frank H Ogawa Plaza",
"AddressLine2": "Oakland, CA 94612",
"AddressLine3": "",
"AddressLine4": "",
"AddressLine5": "",
"AddressLine6": "",
"AddressLine7": "",
"AddressLine8": "",
"SubPremises": "",
"DoubleDependentLocality": "",
"DependentLocality": "",
"Locality": "Oakland",
"SubAdministrativeArea": "Alameda",
"AdministrativeArea": "CA",
"PostalCode": "94612",
"PostalCodeType": " ",
"AddressType": " ",
"AddressKey": "94612000000",
"SubNationalArea": "",
"CountryName": "United States of America",
"CountryISO3166_1_Alpha2": "US",
"CountryISO3166_1_Alpha3": "USA",
"CountryISO3166_1_Numeric": "840",
"CountrySubdivisionCode": "US-CA",
"Thoroughfare": "Frank H Ogawa Plz",
"ThoroughfarePreDirection": "",
"ThoroughfareLeadingType": "",
"ThoroughfareName": "Frank H Ogawa",
"ThoroughfareTrailingType": "Plz",
"ThoroughfarePostDirection": "",
"DependentThoroughfare": "",
"DependentThoroughfarePreDirection": "",
"DependentThoroughfareLeadingType": "",
"DependentThoroughfareName": "",
"DependentThoroughfareTrailingType": "",
"DependentThoroughfarePostDirection": "",
"Building": "",
"PremisesType": "",
"PremisesNumber": "",
"SubPremisesType": "",
"SubPremisesNumber": "",
"PostBox": "",
"Latitude": "37.806200",
"Longitude": "-122.268900",
"DeliveryIndicator": "U",
"MelissaAddressKey": "",
"MelissaAddressKeyBase": "",
"PostOfficeLocation": "",
"SubPremiseLevel": "",
"SubPremiseLevelType": "",
"SubPremiseLevelNumber": "",
"SubBuilding": "",
"SubBuildingType": "",
"SubBuildingNumber": "",
"UTC": "UTC-08:00",
"DST": "Y",
"DeliveryPointSuffix": "",
"CensusKey": "060014029001027",
"Extras": {}
}
]
}
73 changes: 73 additions & 0 deletions test/fixtures/melissa_street_oakland_city_hall
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"Version": "3.0.1.167",
"TransmissionReference": "",
"TransmissionResults": "",
"TotalRecords": "1",
"Records": [
{
"RecordID": "1",
"Results": "AC10,AC14,AC16,AV14,GS05",
"FormattedAddress": "1 Frank H Ogawa Plz Fl 3;Oakland, CA 94612-1932",
"Organization": "",
"AddressLine1": "1 Frank H Ogawa Plz Fl 3",
"AddressLine2": "Oakland, CA 94612-1932",
"AddressLine3": "",
"AddressLine4": "",
"AddressLine5": "",
"AddressLine6": "",
"AddressLine7": "",
"AddressLine8": "",
"SubPremises": "Fl 3",
"DoubleDependentLocality": "",
"DependentLocality": "",
"Locality": "Oakland",
"SubAdministrativeArea": "Alameda",
"AdministrativeArea": "CA",
"PostalCode": "94612-1932",
"PostalCodeType": " ",
"AddressType": "H",
"AddressKey": "94612193299",
"SubNationalArea": "",
"CountryName": "United States of America",
"CountryISO3166_1_Alpha2": "US",
"CountryISO3166_1_Alpha3": "USA",
"CountryISO3166_1_Numeric": "840",
"CountrySubdivisionCode": "US-CA",
"Thoroughfare": "Frank H Ogawa Plz",
"ThoroughfarePreDirection": "",
"ThoroughfareLeadingType": "",
"ThoroughfareName": "Frank H Ogawa",
"ThoroughfareTrailingType": "Plz",
"ThoroughfarePostDirection": "",
"DependentThoroughfare": "",
"DependentThoroughfarePreDirection": "",
"DependentThoroughfareLeadingType": "",
"DependentThoroughfareName": "",
"DependentThoroughfareTrailingType": "",
"DependentThoroughfarePostDirection": "",
"Building": "",
"PremisesType": "",
"PremisesNumber": "1",
"SubPremisesType": "Fl",
"SubPremisesNumber": "3",
"PostBox": "",
"Latitude": "37.805402",
"Longitude": "-122.272797",
"DeliveryIndicator": "B",
"MelissaAddressKey": "9772863955",
"MelissaAddressKeyBase": "",
"PostOfficeLocation": "",
"SubPremiseLevel": "",
"SubPremiseLevelType": "",
"SubPremiseLevelNumber": "",
"SubBuilding": "",
"SubBuildingType": "",
"SubBuildingNumber": "",
"UTC": "UTC-08:00",
"DST": "Y",
"DeliveryPointSuffix": "",
"CensusKey": "060014028002040",
"Extras": {}
}
]
}
8 changes: 8 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,14 @@ def default_fixture_filename
end
end

require 'geocoder/lookups/melissa_street'
class MelissaStreet
private
def default_fixture_filename
"melissa_street_oakland_city_hall"
end
end

require 'geocoder/lookups/postcode_anywhere_uk'
class PostcodeAnywhereUk
private
Expand Down
9 changes: 8 additions & 1 deletion test/unit/lookup_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ def test_responds_to_name_method

def test_search_returns_empty_array_when_no_results
Geocoder::Lookup.all_services_except_test.each do |l|
next if [:abstract_api, :ipgeolocation, :ipqualityscore, :nationaal_georegister_nl].include?(l) # lookups that always return a result
next if [
:abstract_api,
:ipgeolocation,
:ipqualityscore,
:melissa_street,
:nationaal_georegister_nl
].include?(l) # lookups that always return a result

lookup = Geocoder::Lookup.get(l)
set_api_key!(l)
silence_warnings do
Expand Down
35 changes: 35 additions & 0 deletions test/unit/lookups/melissa_street_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# encoding: utf-8
require 'test_helper'

class MelissaStreetTest < GeocoderTestCase

def setup
Geocoder.configure(lookup: :melissa_street)
set_api_key!(:melissa_street)
end

def test_result_components
result = Geocoder.search("1 Frank H Ogawa Plz Fl 3").first
assert_equal "1", result.number
assert_equal "1 Frank H Ogawa Plz Fl 3", result.street_address
assert_equal "Plz", result.suffix
assert_equal "CA", result.state
assert_equal "94612-1932", result.postal_code
assert_equal "Oakland", result.city
assert_equal "US", result.country_code
assert_equal "United States of America", result.country
assert_equal([37.805402, -122.272797], result.coordinates)
end

def test_low_accuracy
result = Geocoder.search("low accuracy").first
assert_equal "United States of America", result.country
end

def test_raises_api_key_exception
Geocoder.configure(:always_raise => [Geocoder::InvalidApiKey])
assert_raises Geocoder::InvalidApiKey do
Geocoder.search("invalid key")
end
end
end
8 changes: 6 additions & 2 deletions test/unit/result_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ def test_forward_geocoding_result_has_required_attributes

def test_reverse_geocoding_result_has_required_attributes
Geocoder::Lookup.all_services_except_test.each do |l|
next if l == :ip2location # has pay-per-attribute pricing model
next if l == :nationaal_georegister_nl # no reverse geocoding
next if [
:ip2location, # has pay-per-attribute pricing model
:nationaal_georegister_nl, # no reverse geocoding
:melissa_street, # reverse geocoding not implemented
].include?(l)

Geocoder.configure(:lookup => l)
set_api_key!(l)
result = Geocoder.search([45.423733, -75.676333]).first
Expand Down