Google geocoding service returns response for fake address - google-maps

I'm using the google geocoding service to validate that a city name (plus region and country) that has been entered in our system exists, and to get the lat/long.
However, I'm finding that it seems to 'guess' if you make a typo, and returns an response even if you made an error.
For instance, a request for "Beverton, Ontario, Canada" returns the lat/long for Beaverton, with no indication that you provided the wrong city name.
I'm using the CSV response type, and am getting the 200 response code.
Can I either prevent the service from doing this, or, better yet, find out if it has?
Edit: to clarify ... Google is correcting the input (when I would expect it to just fail) and I need to know if it has done this.

There isn't any way for the geocoder to let you know if it thinks you had a typo. I agree with Saul's answer, that your best bet is to check your query against the response.
I just wanted to point out that you'll have to check several elements of your input against several of the response values, in order to find the elements that should match up. In this case, "Beaverton" was found inside of "DependentLocalityName".
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
<name>Beverton, Ontario, Canada</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status>
<Placemark id="p1">
<address>Beaverton, Brock, ON, Canada</address>
<AddressDetails Accuracy="4" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Durham Regional Municipality</SubAdministrativeAreaName><Locality><LocalityName>Brock</LocalityName><DependentLocality><DependentLocalityName>Beaverton</DependentLocalityName></DependentLocality></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails>
<ExtendedData>
<LatLonBox north="44.4502166" south="44.4183470" east="-79.1199562" west="-79.1839858" />
</ExtendedData>
<Point><coordinates>-79.1519710,44.4342840,0</coordinates></Point>
</Placemark>
</Response></kml>
Update:
This may be impossible to actually implement. If your input is "Beverton, Ontario, Canada", how do you know which of those three words to check for? Two of them will match up just fine. What if they're entered in a different order?

Is it responding with a "200 Success Code"? There's a chance that it might be giving you a different status code.
Here are the different status codes google returns: http://code.google.com/apis/maps/documentation/reference.html#GGeoStatusCode

NOTE: See the answer by #Chris B above. As Chris points out, this may be impossible to implement.
Do you have to use the CSV response type? If not, the other response types such as KML provide enough details to determine the location that the coordinates refer to. You could verify your input against the response's LocalityName element.
<kml xmlns="http://earth.google.com/kml/2.0">
<Response>
<name>1600 amphitheatre mountain view ca</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status>
<Placemark>
<address>
1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
</address>
<AddressDetails Accuracy="8">
<Country>
<CountryNameCode>US</CountryNameCode>
<AdministrativeArea>
<AdministrativeAreaName>CA</AdministrativeAreaName>
<SubAdministrativeArea>
<SubAdministrativeAreaName>Santa Clara</SubAdministrativeAreaName>
<Locality>
<LocalityName>Mountain View</LocalityName>
<Thoroughfare>
<ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName>
</Thoroughfare>
<PostalCode>
<PostalCodeNumber>94043</PostalCodeNumber>
</PostalCode>
</Locality>
</SubAdministrativeArea>
</AdministrativeArea>
</Country>
</AddressDetails>
<Point>
<coordinates>-122.083739,37.423021,0</coordinates>
</Point>
</Placemark>
</Response>
</kml>

Related

Fetching select attributes from Google Contact API

While working with https://developers.google.com/google-apps/contacts/v3/reference, I haven't figured out a way yet to ONLY have Google return gd$email & gd$name instead of the following it returns by default.
["id", "gd$etag", "updated", "app$edited", "category", "title", "link", "gd$email", "gd$name"]
For our business use case, we only need these two attributes, having all the above in the response increases the response Pay Load and thus response time.
Any leads ?
You can change the response you get with contacts API. I tried for retrieving all the contacts, but to include only email and phone number in the response.
Here is the request https://www.google.com/m8/feeds/contacts/guntupalliswathi#gmail.com/full ?fields=entry/gd:email,entry/gd:phoneNumber(I tried in oauth playground)
Response:
<entry>
<gd:email rel="http://schemas.google.com/g/2005#other" address="xxxx#domain.com" primary="true"/>
</entry>
<entry>
<gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile" uri="tel:+91-0000-000-000"> </gd:phoneNumber>
</entry>
<entry>
<gd:email rel="http://schemas.google.com/g/2005#other" address="yyyy#domain.com" primary="true"/>
</entry>
<entry>
<gd:phoneNumber rel="http://schemas.google.com/g/2005#mobile">(000) 000-0001</gd:phoneNumber>
</entry>
Let me know if your issue is not resolved.
For JSON response, you can supply field list as follows:
https://www.google.com/m8/feeds/contacts/default/full/?alt=json&fields=feed(entry(gd$name(gd$fullName))),feed(entry(gd$email(address)))
This will give you just full name and email per contact. Hope this works.

How to properly use geocoder from Google Maps API

I'm developing a little web application with PHP, I have some address in my database (state, town, city) - "the state is always the same". But town and city vary.
Is there any way to force a preference search by location? For example, preference is always looking in the state of Delaware in USA.
So I can pass parameter something like this:
var address="{$city}, {$town}, Delaware";
The problem is that by doing this, I sometimes get results from other countries, is there any rule or algorithm to do what I want?
Thanks for reading :-)
You could try appending " Delaware state" or " Delaware, USA". There isn't any documented rule I know of, except that it attempts to match "postal addresses".
Per the documentation you can bias the search:
by viewport
by region code

Open Street Map Address Decode

I am using Nominatim reverse geocoding service to get address from latitude and longitude. Then, store the result in Mysql Database.
The coding is as fiddle below:
http://jsfiddle.net/GWL7A/171/
The address returned is in the local language such as in the example is in Chinese.
And the data stored is not readable as:
"麒麟山新æ‘, 惠æ¥åŽ¿, 广东, 中åŽäººæ°‘共和国/China"
Is that possible to make the address returned in English.
If that's not possible, how to store the data into database so that when retrieve it and show in web UI, it returned to Chinese words? It must not be limited to only Chinese word since it might be Afghanistan, Thailand, Vietnam or some other country's addresses.
Thank you.
The object in question is not yet internationalized in OSM, so nominatim can only give you its original name (which is in Chinese).
If you really need the name “in English”/in latin script, you probably have to do the transcription by yourself. I guess one can find some han-pinyin transcription library out there…
btw: make sure to use the correct charset when adding the strings to your database. OSM is using utf-8.
You can use &accept-language=es;q=0.8,de;q=0.4,en;q=0.2 at the end of the API:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=33.6321882&lon=72.8587481&accept-language=es;q=0.8,de;q=0.4,en;q=0.2
Which give you the result address returned in English.
The Above URL giving the results:
{"place_id":138192283,"licence":"Data © OpenStreetMap contributors,
ODbL 1.0.
https://osm.org/copyright","osm_type":"way","osm_id":263218431,"lat":"33.6328352161182","lon":"72.8584455708076","place_rank":26,"category":"highway","type":"residential","importance":0.1,"addresstype":"road","name":null,"display_name":"E
18, F-17, Dhok Minda, Islamabad,
Pakistán","address":{"neighbourhood":"E
18","suburb":"F-17","village":"Dhok
Minda","state":"Islamabad","country":"Pakistán","country_code":"pk"},"boundingbox":["33.6324874","33.6342918","72.8577017","72.8614997"]}
Without using &accept-language=es;q=0.8,de;q=0.4,en;q=0.2:
The JSON response is coming in URDU:
{"place_id":138192283,"licence":"Data © OpenStreetMap contributors,
ODbL 1.0.
https://osm.org/copyright","osm_type":"way","osm_id":263218431,"lat":"33.6328352161182","lon":"72.8584455708076","place_rank":26,"category":"highway","type":"residential","importance":0.1,"addresstype":"road","name":null,"display_name":"E
18, F-17, Dhok Minda, وفاقی دارالحکومت اسلام آباد,
Pakistan","address":{"neighbourhood":"E
18","suburb":"F-17","village":"Dhok Minda","state":"وفاقی دارالحکومت
اسلام
آباد","country":"Pakistan","country_code":"pk"},"boundingbox":["33.6324874","33.6342918","72.8577017","72.8614997"]}
for the URL:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=33.6321882&lon=72.8587481

Amazon Product API: "Your request is missing a required parameter combination" on Blended ItemSearch

I'm having some problems trying to do an ItemSearch on the Blended index using the Amazon Product API.
According to the documentation, Blended requests cannot specify the MerchantId parameter - and indeed, if I try to include it I get an error telling me so. However, when I don't include it, I get an error telling me that my request is missing a required parameter combination and that a valid combination includes MerchantId... what the hell?
The failing requests are being sent as part of batches with other requests that are succeeding. I'm using REST to send my requests, so here's an example:
http://ecs.amazonaws.com/onca/xml?AWSAccessKeyId=-------------&
ItemSearch.1.Keywords=Mates%20of%20State&
ItemSearch.1.MerchantId=Amazon&
ItemSearch.1.SearchIndex=DVD&
ItemSearch.2.Keywords=teaching%20Lily%20various%20computer%20related%20skills&
ItemSearch.2.SearchIndex=Blended&
ItemSearch.Shared.Availability=Available&
ItemSearch.Shared.Condition=All&
ItemSearch.Shared.ResponseGroup=Small%2CSalesRank%2CImages%2COfferSummary%2CSimilarities&
Operation=ItemSearch%2CSimilarityLookup&
Service=AWSECommerceService&
SimilarityLookup.1.ItemId=B000FNNHZ2&
SimilarityLookup.2.ItemId=B000EQ5UPU&
SimilarityLookup.Shared.Availability=Available&
SimilarityLookup.Shared.Condition=All&
SimilarityLookup.Shared.MerchantId=Amazon&
SimilarityLookup.Shared.ResponseGroup=Small%2CSalesRank%2CImages%2COfferSummary&
Timestamp=2010-04-02T17%3A18%3A05Z&
Signature=----------------
Here's the XML response:
<Items xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05">
<Request>
<IsValid>False</IsValid>
<ItemSearchRequest>
<Availability>Available</Availability>
<Condition>All</Condition>
<Keywords>teaching Lily various computer related skills</Keywords>
<ResponseGroup>Similarities</ResponseGroup>
<ResponseGroup>SalesRank</ResponseGroup>
<ResponseGroup>OfferSummary</ResponseGroup>
<ResponseGroup>Small</ResponseGroup>
<ResponseGroup>Images</ResponseGroup>
<SearchIndex>Blended</SearchIndex>
</ItemSearchRequest>
<Errors>
<Error>
<Code>AWS.MissingParameterCombination</Code>
<Message>Your request is missing a required parameter combination. Required parameter combinations include MerchantId, Availability.</Message>
</Error>
</Errors>
</Request>
</Items>
Any ideas as to what I'm doing wrong?
I seem to have solved this by removing both the Availability and Condition parameters. I'd ideally prefer to be able to filter by availability, but at least it's working.

How should I populate city/state fields based on the zip?

I'm aware there are databases for zip codes, but how would I grab the city/state fields based on that? Do these databases contain the city/states or do I have to do some sort of lookup to a webservice?
\begin{been-there-done-that}
Important realization: There is not a one-to-one mapping between cities/counties and ZIP codes. A ZIP code is not based on a political area but instead a distribution area as defined for the USPS's internal use. It doesn't make sense to look up a city based on a ZIP code unless you have the +4 or the entire street address to match a record in the USPS address database; otherwise, you won't know if it's RICHMOND or HENRICO, DALLAS or FORT WORTH, there's just not enough information to tell.
This is why, for example, many e-commerce vendors find dealing with New York state sales tax frustrating, since that tax scheme is based on county, e-commerce systems typically don't ask for the county, and ZIP codes (the only information they provide instead) in New York can span county lines.
The USPS updates its address database every month and costs real money, so pretty much any list that you find freely available on the Internet is going to be out of date, especially with the USPS closing post offices to save money.
One ZIP code may span multiple place names, and one city often uses several (but not necessarily whole) ZIP codes. Finally, the city name listed in the ZIP code file may not actually be representative of the place in which the addressee actually lives; instead, it represents the location of their post office. Our office mail is addressed to ASHLAND, but we work about 7 miles from the town's actual political limits. ASHLAND just happens to be where our carrier's route originates from.
For guesstimating someone's location, such as for a search of nearby points of interest, these sources and City/State/ZIP sets are probably fine, they don't need to be exact. But for address validation in a data entry scenario? Absolutely not--validate the whole address or don't bother at all.
Just a friendly reminder to take a step back and remember the data source's intended use!
\end{been-there-done-that}
Modern zip code databases contain columns for City, State fields.
http://sourceforge.net/projects/zips/
http://www.populardata.com/
Using the Ziptastic HTTP/JSON API
This is a pretty new service, but according to their documentation, it looks like all you need to do is send a GET request to http://ziptasticapi.com, like so:
GET http://ziptasticapi.com/48867
And they will return a JSON object along the lines of:
{"country": "US", "state": "MI", "city": "OWOSSO"}
Indeed, it works. You can test this from a command line by doing something like:
curl http://ziptasticapi.com/48867
Using the US Postal Service HTTP/XML API
According to this page on the US Postal Service website which documents their XML based web API, specifically Section 4.0 (page 22) of this PDF document, they have a URL where you can send an XML request containing a 5 digit Zip Code and they will respond with an XML document containing the corresponding City and State.
According to their documentation, here's what you would send:
http://SERVERNAME/ShippingAPITest.dll?API=CityStateLookup&XML=<CityStateLookupRequest%20USERID="xxxxxxx"><ZipCode ID= "0"><Zip5>90210</Zip5></ZipCode></CityStateLookupRequest>
And here's what you would receive back:
<?xml version="1.0"?>
<CityStateLookupResponse>
<ZipCode ID="0">
<Zip5>90210</Zip5>
<City>BEVERLY HILLS</City>
<State>CA</State>
</ZipCode>
</CityStateLookupResponse>
USPS does require that you register with them before you can use the API, but, as far as I could tell, there is no charge for access. By the way, their API has some other features: you can do Address Standardization and Zip Code Lookup, as well as the whole suite of tracking, shipping, labels, etc.
I'll try to answer the question "HOW should I populate...", and not "SHOULD I populate..."
Assuming you are going to do this more than once, you would want to build your own database. This could be nothing more than a text file you downloaded from any of the many sources (see Pentium10 reply here). When you need a city name, you search for the ZIP, and extract the city/state text. To speed things up, you would sort the table in numeric order by ZIP, build an index of lines, and use a binary search.
If you ZIP database looked like (from sourceforge):
"zip code", "state abbreviation", "latitude", "longitude", "city", "state"
"35004", "AL", " 33.606379", " -86.50249", "Moody", "Alabama"
"35005", "AL", " 33.592585", " -86.95969", "Adamsville", "Alabama"
"35006", "AL", " 33.451714", " -87.23957", "Adger", "Alabama"
The most simple-minded extraction from the text would go something like
$zipLine = lookup($ZIP);
if($zipLine) {
$fields = explode(", ", $zipLine);
$city = $fields[4];
$state = $fields[5];
} else {
die "$ZIP not found";
}
If you are just playing with text in PHP, that's all you need. But if you have a database application, you would do everything in SQL. Further details on your application may elicit more detailed responses.