How to check efficiently if thousands of points are located inside a building polygon using overpass ?
Hi, I want to check for thousands of points (lat, lon), if they are located inside a building polygon using the overpass API.
I know how to do it for one point (eg: https://help.openstreetmap.org/questions/55529/how-to-detect-if-point-is-inside-a-building-polygon-with-overpass) but I don't know how to do it without sending requests during hours to the overpass API.
I'm currently using this request for one point:
> Blockquote
way(around:5, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:10, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:15, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:20, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:25, {lat}, {lon})[building];
}}}} }}}}
out geom;
where I check gradually up until 25 meters for close buildings. I don't think there is a tool in overpass for checking if the point at lat, lon is located inside any of the close buildings (except creating temporary areas and using is_in?). So, I use the shapely python library for that. The full process for the thousand points takes hours.
How could I do it **efficiently**?
I could query all the close buildings of all the points in one request but I don't know how to keep a reference to the node from which a building is close. Thus, I will be forced to check if a node is inside any buildings that I got, no matter from which node the building is close. In this case, it will also not be efficient.
Does anyone have an idea for the query to use? Or on how to keep the reference?
Thanks!
Vucod
----------
The full code:
> Blockquote
from OSMPythonTools.overpass import Overpass
import pandas as pd
from shapely.geometry import Point
from shapely.geometry.polygon import Polygon
def checkIfOnBuilding(lat, lon):
"""
Check for building in a 25 radius
lat, lon as string
"""
point = Point(lat, lon)
result = overpass.query(f"""
way(around:5, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:10, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:15, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:20, {lat}, {lon})[building];
if(count(ways) < 1) {{
way(around:25, {lat}, {lon})[building];
}}}} }}}}
out geom;
""", timeout=500)
dict_ = result.toJSON()['elements']
df = pd.DataFrame(dict_)
if len(df) > 0:
for i, row in df.iterrows():
nodes = [(node["lat"], node["lon"]) for node in row.geometry]
polygon = Polygon(nodes)
res = polygon.contains(point)
if res:
break
else:
res = False
return res