5

I am looking for an public Rest API which I can consume and get random city name at every time.

No inputs (like country). City can be any size, it can be a village, town, city..

5

I've developed and host an online city database called GeoDB Cities which should fit the bill. Here's how I would implement a Random-City-Name feature:

1) Do an initial query to get the total count of all available cities. The results are chunked by pages, but each result also contains metadata about the total count of cities. You need to extract metadata.totalCount from the JSON. (You can safely cache this value.)

GET http://geodb-free-service.wirefreethought.com/v1/geo/cities?hateoasMode=off

2) Get a random number from 0 to (totalCount - 1) in the previous step (results are zero-based). Go here for an excellent example of how to do so in Java. The code in other languages should look similar. This will represent your offset result into the data.

3) Do another GET query to get a single offset result, where OFFSET is zero-based. Extract data.name from the JSON.

GET http://geodb-free-service.wirefreethought.com/v1/geo/cities?limit=1&offset=OFFSET&hateoasMode=off

The free instance is limited to cities with populations of at least 20000, but that might be fine for your purposes.

  • I will definately try this one and if it works then I will accept your answer – Prasad Telkikar Nov 22 '18 at 5:04
  • @PrasadTelkikar Did it work for you? If so, please accept the answer. – Michael Mogley Dec 17 '18 at 23:52
  • I used different approach to resolve my issue. I am accepting your answer as it received highest votes. – Prasad Telkikar Dec 19 '18 at 5:05
2

You can use Wikidata with a SPARQL query, which may be useful if you also want some facts about the city

SELECT DISTINCT ?city ?label WHERE {
  ?city rdfs:label ?label.
  ?city wdt:P31 wd:Q515.
  FILTER((LANG(?label)) = "en")
}
ORDER BY UUID()
LIMIT 10

Link to Query

  • Note1 : UUID() is to give random results. RAND() doesn't work with Wikidata (source).

  • Note2: I put in LIMIT 10 to show more results, but in your case set it to 1

  • Note3: Be careful of browser caching

You can access the SPARQL endpoint with your code (documentation) with this URL (currently XML output)

https://query.wikidata.org/sparql?query=SELECT%20DISTINCT%20%3Fcity%20%3Fcountry%20%3Flabel%20WHERE%20%7B%0A%20%20%3Fcity%20rdfs%3Alabel%20%3Flabel.%0A%20%20%3Fcity%20wdt%3AP31%20wd%3AQ515.%0A%20%20FILTER((LANG(%3Flabel))%20%3D%20%22en%22)%0A%7D%0AORDER%20BY%20UUID()%0ALIMIT%2010
  • @stanislav-kralin is a sparql expert and maybe he can clean up this answer :) – philshem Nov 22 '18 at 10:29
  • 1
    :). Something like SELECT ?cityLabel { { SELECT * { ?city wdt:P31 wd:Q515 } ORDER BY uuid() LIMIT 1 } SERVICE wikibase:label { bd:serviceParam wikibase:language "en" } } should by slightly faster here, but there is a chance to get something like Q21095147 as a result. – Stanislav Kralin Nov 22 '18 at 18:09

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.