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..

0

2 Answers 2

4

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 40000, but that might be fine for your purposes.

0
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
2
  • @stanislav-kralin is a sparql expert and maybe he can clean up this answer :)
    – philshem
    Commented Nov 22, 2018 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. Commented Nov 22, 2018 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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