Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI:[feat] naming revise #144

Merged
merged 3 commits into from
Dec 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 77 additions & 25 deletions src/ai/path_naming.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
import pandas as pd
import numpy as np
from geopy.distance import geodesic
from sklearn.neighbors import KDTree

class GPXProcessor:
def __init__(self, toilet_data_path, conv_data_path):
def __init__(self, toilet_data_path, conv_data_path, trafficlight_data_path):
# 데이터 로드
self.toilet_data = pd.read_csv(toilet_data_path)
self.conv_data = pd.read_csv(conv_data_path)
self.trafficlight_data = pd.read_csv(trafficlight_data_path)

# K-D 트리 생성 (시설 위치 기준으로)
self.toilet_tree = KDTree(self.toilet_data[['latitude', 'longitude']].values)
self.conv_tree = KDTree(self.conv_data[['latitude', 'longitude']].values)
self.trafficlight_tree = KDTree(self.trafficlight_data[['latitude', 'longitude']].values)

def extract_gpx_points(self, file_path):
points = []
Expand All @@ -16,9 +24,7 @@ def extract_gpx_points(self, file_path):
for track in gpx.tracks:
for segment in track.segments:
for point in segment.points:
# 고도 값이 None이면 0으로 대체
elevation = point.elevation if point.elevation is not None else 0
points.append((point.latitude, point.longitude, elevation))
points.append((point.latitude, point.longitude, point.elevation if point.elevation else 0))
return np.array(points)

def calculate_distances(self, points):
Expand All @@ -40,13 +46,12 @@ def count_nearby_facilities(self, sampled_points, facility_data, radius=500):
sampled_coords = sampled_points[:, :2]
facility_coords = facility_data[['latitude', 'longitude']].to_numpy()

# 전체 샘플 포인트와 시설 사이의 거리를 한 번에 계산하여 효율성 향상
distances_to_facilities = np.array([
[geodesic(sample, facility).meters for sample in sampled_coords] for facility in facility_coords
])

# 각 시설에 대해 반경 내에 있는 샘플 포인트가 있는지 확인
count = np.sum(np.any(distances_to_facilities <= radius, axis=1))
count = sum(
np.any(
np.array([geodesic(sample, facility).meters for sample in sampled_coords]) <= radius
)
for facility in facility_coords
)
return count

def classify_facilities(self, toilets, conv_stores):
Expand Down Expand Up @@ -91,41 +96,88 @@ def classify_difficulty(self, avg_elevation_change):
else:
return "Expert"

def count_facilities_for_gpx(self, sampled_points, radius=500):
def count_and_collect_nearby(facility_data, tree):
total_count = 0
locations = []
for _, facility in facility_data.iterrows():
for point in sampled_points:
if geodesic(point[:2], (facility['latitude'], facility['longitude'])).meters <= radius:
total_count += 1
locations.append((facility['latitude'], facility['longitude']))
break
return total_count, locations

toilet_count, toilet_locations = count_and_collect_nearby(self.toilet_data, self.toilet_tree)
conv_count, conv_locations = count_and_collect_nearby(self.conv_data, self.conv_tree)
trafficlight_count = self.count_unique_trafficlights(sampled_points, self.trafficlight_data, radius=0.001)

return toilet_count, toilet_locations, conv_count, conv_locations, trafficlight_count

def count_unique_trafficlights(self, points, trafficlight_data, radius=0.001):
tree = KDTree(points[:, :2])
trafficlight_coords = trafficlight_data[['latitude', 'longitude']].values

nearby_indices = tree.query_radius(trafficlight_coords, r=radius)
unique_trafficlights = set()

for i, indices in enumerate(nearby_indices):
if indices.size > 0:
unique_trafficlights.add(tuple(trafficlight_coords[i]))

return len(unique_trafficlights)

def process_gpx_file(self, file_path):
points = self.extract_gpx_points(file_path)
distances = self.calculate_distances(points)

total_length_km = distances.sum() / 1000
sampled_points = self.sample_points_by_distance(points, distances)

toilets = self.count_nearby_facilities(sampled_points, self.toilet_data)
conv_stores = self.count_nearby_facilities(sampled_points, self.conv_data)
toilet_count, toilet_locations, conv_count, conv_locations, trafficlight_count = self.count_facilities_for_gpx(sampled_points)

# 고도 변화 계산 (None 처리 포함)
elevation_differences = np.diff(points[:, 2])
facility_label = self.classify_facilities(toilet_count, conv_count, trafficlight_count)
track_label = self.classify_track(points, distances)

elevation_differences = np.diff(points[:, 2]) if points.shape[1] > 2 else np.array([0])
valid_distances = distances[distances > 0]
elevation_ratios = elevation_differences[:len(valid_distances)] / valid_distances
avg_elevation_change = np.mean(np.abs(elevation_ratios[np.isfinite(elevation_ratios)]))

facility_label = self.classify_facilities(toilets, conv_stores)
track_label = self.classify_track(points, distances)
difficulty_label = self.classify_difficulty(avg_elevation_change)

track_value = "TRUE" if track_label == "Track" else "FALSE"
elevation_value = (
"LOW" if difficulty_label == "Beginner" else
"MEDIUM" if difficulty_label == "Advanced" else
"HIGH"
)
convenience_value = (
"LOW" if facility_label == "No_Facilities" else
"MEDIUM" if facility_label == "Essential_Facilities" else
"HIGH"
)

return {
"file_name": os.path.basename(file_path),
"difficulty": difficulty_label,
"facilities": facility_label,
"track_type": track_label,
"distance_km": round(total_length_km, 1)
"name": f"{int(total_length_km)}_{difficulty_label}_{facility_label}_{track_label}_{round(total_length_km, 1)}Km.gpx",
"toilet_counts": toilet_count,
"toilet_location": toilet_locations,
"store_counts": conv_count,
"store_location": conv_locations,
"distance_km": round(total_length_km, 1),
"Track": track_value,
"Elevation": elevation_value,
"Convenience": convenience_value,
"trafficlight_counts": trafficlight_count,
}

if __name__ == "__main__":
toilet_data_path = "C:/Users/정호원/OneDrive/바탕 화면/gpx 수집/test/final_toilet.csv"
conv_data_path = "C:/Users/정호원/OneDrive/바탕 화면/gpx 수집/test/final_conv.csv"
sample_file = "C:/Users/정호원/OneDrive/바탕 화면/gpx 수집/test_clustering/test_off_c2.gpx"
sample_file = "C:/Users/정호원/OneDrive/바탕 화면/gpx 수집/test/서울_서대문구_대현동_45-51.gpx"

gpx_processor = GPXProcessor(toilet_data_path, conv_data_path)
gpx_processor = GPXProcessor(toilet_data_path, conv_data_path, trafficlight_data_path)
result = gpx_processor.process_gpx_file(sample_file)

new_file_name = f"{result['difficulty']}_{result['facilities']}_{result['track_type']}_{result['distance_km']}Km.gpx"
print(f"새로운 파일명: {new_file_name}")
###