I have a small testing tool in Node.js with which I get nearby towns and cities in the radius of 100 miles (160934 meters => 100 miles):
// Overpass API endpoint
const overpassUrl = 'https://overpass-api.de/api/interpreter';
// Query to retrieve both cities and towns within a radius
const overpassQuery = `
[out:json];
(
node["place"="town"](around:160934,${userLat},${userLon});
node["place"="city"](around:160934,${userLat},${userLon});
);
out body;
>;
out skel qt;
`;
Then, when I fetch the result, I restructure it to fit my needs:
// Make the HTTP request to the Overpass API using fetch
fetch(overpassUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ data: overpassQuery })
})
.then(response => {
// Error handling here and...
return response.json();
})
.then(data => {
data.elements.forEach(node => {
node.distance = calculateDistance(userLat, userLon, node.lat, node.lon);
});
// Process the JSON data
// Sort the results by distance
const sortedResults = data.elements.sort((a, b) => a.distance - b.distance);
console.log(data);
})
.catch(error => console.error('Error:', error));
The function calculateDistance
is a standard Haversine formula distance calculation function between two LAT/LNG points, and it does not produce and problems.
The problem is in the response I'm getting, i.e. data.elements[0]
looks like this:
{
type: 'node',
id: 151537134,
lat: 41.0341224,
lon: -93.7665629,
tags: {
ele: '348',
'gnis:feature_id': '459906',
name: 'Osceola',
place: 'town',
population: '5415',
'population:date': '2020',
'source:population': 'US Census',
wikidata: 'Q1913383',
wikipedia: 'en:Osceola, Iowa'
},
distance: 8.726664284057101
}
I'm getting a full name of the state in the wikipedia
key, but the problem occurs when wikipedia
key does not exist for certain places, which are probably not documented by Nominatim/OpenStreetMap.
Is there any way to force my OverPass Query to return "state" or "province name" every time I send a request to the OverPass API interpreter?
I have tried adding admin_level
to the node segment, with various levels (from 1 to 8), but neither helped.
Overpass API is not a geocoder.
Overpass API is designed to query OSM elements by tag. OSM elements don't necessarily have a full address given. Often, some parts of the address (country, postcode, city) are represented by administrative boundaries and similar structures instead in order not to have the same redundant information on each element.
If you want to convert an address to a geographic location, use a geocoder instead. Popular OSM-based geocoders are Nominatim and Photon.
For your specific case, you probably have to perform a geocoding query for each of your city/town.