开发者

Best API to retrieve zip code by user input city name (US only)? [closed]

Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines guidelines. It is not currently accepting answers. 开发者_如何学运维

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed 4 years ago.

Improve this question

I have a city name field I am getting value from (i.e. randomly formatted), such as "NEW YORK", "new york" or "new-york" or "ny".

Having that field's value, I need to present user with a list of cities that have that value in their name in this format:

NY – New York City – 10001

MN – New York Mills – 56567

Efficiency and performance is important. I can use JavaScript or PHP in order to retrieve this data.

So far, I've tried to use Freebase API. Here's an example query I've used: http://tinyurl.com/3ogpf7k

And here's JavaScript code I am using:

// App.q contains city name field's value

var query = {
    extended : 1,
    query : [{
        search : App.q,
        type : '/location/citytown',
        id : null,
        name : null,
        postal_codes : [],
        "/location/location/containedby" : [{
            "type" : "/location/us_state",
            "name": null,
            // two letters abbreviation of state
            "/common/topic/alias" : []
        }]
    }]
},
url = 'http://www.freebase.com/api/service/mqlread?callback=?&query=' + 
      encodeURIComponent(JSON.stringify(query));

$.getJSON(url, function( data ) {
    var cities, i, len, name, aliases, j, abbr, postal_code, HTML = [];

    for ( i = 0, len = data.result.length; i < len; i += 1 ) {
        // cities with names matching user's input
        if ( data.result[ i ].name.toLowerCase().indexOf( App.q ) === -1 ) continue;
        // cities that have postal_codes data available
        if ( data.result[ i ].postal_codes.length === 0 ) continue;

        name = data.result[ i ].name;
        aliases = data.result[ i ]["/location/location/containedby"][0]["/common/topic/alias"];
        postal_code = data.result[ i ].postal_codes[0];

        // find two-letters alias
        for ( j = aliases.length - 1; j >= 0; j -= 1 ) {
            if ( aliases[j].length === 2 && aliases[j] === aliases[j].toUpperCase() ) {
                 abbr = aliases[j];
            }
        }

        HTML.push( D.renderHTML( liTemplate, {
            name : name,
            abbr : abbr,
            postal_code : postal_code
        }) );

    }

    console.log( HTML.join('') );
});

However, querying "New York" doesn't seem to return even "New York City".

Is there a better API that satisfies my need? Am I doing something wrong with Freebase API?

UPD. Another helpful API that allows to do kind of the same (it still doesn't cut my needs though – too many results and no way of paging through them):

Docs: http://www.geonames.org/export/web-services.html

Example: http://api.geonames.org/postalCodeSearch?placename=los%20angeles&username=demo&maxRows=500

Thanks!


Sorry about the previous misleading answer. I didn't notice that you were using the MQL extension "search" rather than the "name" property.

The main problem is that the default ordering is not by search score (not sure why, but that's the way it is). Modifying your query like this should fix things:

"search":       {"query":"New York","score":null,"type_strict":"all"},
"sort":"-search.score",
"type":"/location/citytown",

The sort parameter is sorting in descending order by the "score" value returned from the "search" subquery. You could also use the mql_filter parameter for search to have it not even consider things which fail to meet your constraint (slightly more efficient).

The search extension is documented here and the document for the underlying search service that is uses are here

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜