Skip to content

Commit

Permalink
Merge pull request #144 from CSID-DGU/ai/feature/naming
Browse files Browse the repository at this point in the history
AI:[feat] naming revise
  • Loading branch information
DONGSANSUNJAE authored Dec 2, 2024
2 parents 52cb3f1 + 0dec3e0 commit c0f5ef9
Showing 1 changed file with 77 additions and 25 deletions.
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}")
###

0 comments on commit c0f5ef9

Please sign in to comment.