Adding features to find public toilets and shopping streets #41

Merged
kscheidecker merged 21 commits from feature/backend/toilets-and-shopping-streets into main 2024-12-14 15:57:09 +00:00
2 changed files with 42150 additions and 42 deletions
Showing only changes of commit 9ddfa0393f - Show all commits

View File

@ -7,6 +7,7 @@ from sklearn.decomposition import PCA
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from pydantic import BaseModel from pydantic import BaseModel
from OSMPythonTools.overpass import Overpass, overpassQueryBuilder from OSMPythonTools.overpass import Overpass, overpassQueryBuilder
from OSMPythonTools.cachingStrategy import CachingStrategy, JSON
from math import sin, cos, sqrt, atan2, radians from math import sin, cos, sqrt, atan2, radians
@ -177,7 +178,7 @@ def fit_lines(points, labels):
else : else :
loc = ShoppingLocation( loc = ShoppingLocation(
type='street', type='street',
centroid=tuple(centroid), centroid=tuple((centroid[1], centroid[0])),
importance = len(cluster_points), importance = len(cluster_points),
start=start_point, start=start_point,
end=end_point end=end_point
@ -199,24 +200,13 @@ def create_landmark(shopping_location: ShoppingLocation):
# Define the bounding box for a given radius around the coordinates # Define the bounding box for a given radius around the coordinates
lat, lon = shopping_location.centroid lat, lon = shopping_location.centroid
bbox = ("around:500", str(lat), str(lon)) bbox = ("around:1000", str(lat), str(lon))
overpass = Overpass() overpass = Overpass()
# CachingStrategy.use(JSON, cacheDir=OSM_CACHE_DIR)
# Query neighborhoods and shopping malls # Query neighborhoods and shopping malls
query = overpassQueryBuilder( selectors = ['"place"~"^(suburb|neighborhood|city_block)$"', '"shop"="mall"']
bbox = bbox,
elementType = ['node'],
selector = ['"place"="suburb"'],
includeCenter = True,
out = 'body'
)
try:
result = overpass.query(query)
print(f'query OK with {len(result.elements())} elements')
except Exception as e:
raise Exception("query unsuccessful")
min_dist = float('inf') min_dist = float('inf')
new_name = 'Shopping Area' new_name = 'Shopping Area'
@ -224,15 +214,39 @@ def create_landmark(shopping_location: ShoppingLocation):
osm_id = 0 osm_id = 0
osm_type = 'node' osm_type = 'node'
for sel in selectors :
query = overpassQueryBuilder(
bbox = bbox,
elementType = ['node', 'way', 'relation'],
selector = sel,
includeCenter = True,
out = 'body'
)
try:
result = overpass.query(query)
# print(f'query OK with {len(result.elements())} elements')
except Exception as e:
raise Exception("query unsuccessful")
for elem in result.elements(): for elem in result.elements():
location = (elem.lat(), elem.lon())
if location[0] is None :
location = (elem.centerLat(), elem.centerLon()) location = (elem.centerLat(), elem.centerLon())
print(f"Distance : {get_distance(shopping_location.centroid, location)}") if location[0] is None :
if get_distance(shopping_location.centroid, location) < min_dist : continue
# print(f"Distance : {get_distance(shopping_location.centroid, location)}")
d = get_distance(shopping_location.centroid, location)
if d < min_dist :
min_dist = d
new_name = elem.tag('name') new_name = elem.tag('name')
osm_type = elem.type() # Add type: 'way' or 'relation' osm_type = elem.type() # Add type: 'way' or 'relation'
osm_id = elem.id() # Add OSM id osm_id = elem.id() # Add OSM id
print("closer thing found") # print("closer thing found")
# add english name if it exists # add english name if it exists
try : try :
@ -253,7 +267,9 @@ def create_landmark(shopping_location: ShoppingLocation):
# Extract points # Extract points
points = extract_points('lyon_data.json') points = extract_points('newyork_data.json')
# print(len(points))
######## Create a figure with 1 row and 3 columns for side-by-side plots ######## Create a figure with 1 row and 3 columns for side-by-side plots
fig, axes = plt.subplots(1, 3, figsize=(15, 5)) fig, axes = plt.subplots(1, 3, figsize=(15, 5))
@ -280,6 +296,7 @@ axes[1].set_title('DBSCAN Clusters')
axes[1].scatter(clustered_points[:, 0], clustered_points[:, 1], c=clustered_labels, cmap='rainbow', s=20) axes[1].scatter(clustered_points[:, 0], clustered_points[:, 1], c=clustered_labels, cmap='rainbow', s=20)
axes[1].scatter(noise_points[:, 0], noise_points[:, 1], c='blue', s=7, label='Noise') axes[1].scatter(noise_points[:, 0], noise_points[:, 1], c='blue', s=7, label='Noise')
# Keep the 5 biggest clusters
clustered_points, clustered_labels = filter_clusters(clustered_points, clustered_labels) clustered_points, clustered_labels = filter_clusters(clustered_points, clustered_labels)
# Fit lines # Fit lines
@ -289,26 +306,26 @@ corners, locations = fit_lines(clustered_points, clustered_labels)
######## Plot clustered points in normal size and noise points separately ######## Plot clustered points in normal size and noise points separately
axes[2].scatter(clustered_points[:, 0], clustered_points[:, 1], c=clustered_labels, cmap='rainbow', s=30) axes[2].scatter(clustered_points[:, 0], clustered_points[:, 1], c=clustered_labels, cmap='rainbow', s=30)
axes[2].set_title('PCA Fitted Lines on Clusters')
# Create a list of Landmarks for the shopping things # Create a list of Landmarks for the shopping things
shopping_landmarks = [] shopping_landmarks = []
for loc in locations : for loc in locations :
axes[2].scatter(loc.centroid[0], loc.centroid[1], color='lime', marker='x', s=200, linewidth=3)
landmark = create_landmark(loc) landmark = create_landmark(loc)
shopping_landmarks.append(landmark) shopping_landmarks.append(landmark)
print(f"{landmark.name} is a shopping area with a score of {landmark.attractiveness}")
####### Plot the detected lines in the final plot ####### ####### Plot the detected lines in the final plot #######
for loc in locations: # for loc in locations:
if loc.type == 'street' : # if loc.type == 'street' :
line_x = loc.start # line_x = loc.start
line_y = loc.end # line_y = loc.end
axes[2].plot(line_x, line_y, color='lime', linewidth=3) # axes[2].plot(line_x, line_y, color='lime', linewidth=3)
else : # else :
axes[2].scatter(loc.centroid[0], loc.centroid[1], color='None', edgecolors='lime', s=200, linewidth=3)
axes[2].set_title('PCA Fitted Lines on Clusters')
axes[0].set_xlim(xmin-0.01, xmax+0.01) axes[0].set_xlim(xmin-0.01, xmax+0.01)
axes[0].set_ylim(ymin-0.01, ymax+0.01) axes[0].set_ylim(ymin-0.01, ymax+0.01)
@ -319,5 +336,11 @@ axes[1].set_ylim(ymin-0.01, ymax+0.01)
axes[2].set_xlim(xmin-0.01, xmax+0.01) axes[2].set_xlim(xmin-0.01, xmax+0.01)
axes[2].set_ylim(ymin-0.01, ymax+0.01) axes[2].set_ylim(ymin-0.01, ymax+0.01)
# plt.tight_layout()
# plt.show() print("\n\n\n")
for landmark in shopping_landmarks :
print(f"{landmark.name} is a shopping area with a score of {landmark.attractiveness}")
plt.tight_layout()
plt.show()

File diff suppressed because it is too large Load Diff