let cache_key = format!(
    "route:list:{:.4}:{:.4}:{:.4}:{:.4}",
    query.sx, query.sy, query.ex, query.ey
);

So what: 좌표를 소수점 4자리로 고정해서 캐싱 키를 만든다.

So why: Flutter에서 GPS 좌표를 보낼 때 소주점 더 아래의 숫자들 처럼 미세한 값들이 올 수 있다. 그럴 경우 사실상 같은 경로인데 캐시 키가 달라져서 매번 ODSay를 호출하게된다. 4자리로 자르면 약 11m 오차 이내는 같은 키로 처리해서 히트율을 높였다

 

let mut path_congestion: Vec<(usize, f64, usize)> = result.paths.iter()
    .enumerate()
    .map(|(i, _)| (i, 0.0_f64, 0_usize))
    .collect();

for (pred, (path_idx, _)) in predictions.iter().zip(path_segment_map.iter()) {
    path_congestion[*path_idx].1 += pred.congestion;
    path_congestion[*path_idx].2 += 1;
}

let mut scored: Vec<(usize, f64)> = path_congestion.iter()
    .map(|(idx, total, count)| {
        let avg = if *count > 0 { total / *count as f64 } else { 50.0 };
        (*idx, avg)
    })
    .collect();

So what: 경로별로 지하철 구간 혼잡도 평균을 계산하고 낮은 순으로 정렬한다

So why:  경로 하나에 지하철 구간이 여러 개 일수도 있다. 구간별 혼잡도를 합산하고 구간 수로 나눠서 경로 전체의 평균 혼잡도를 구한다. count == 0일 경우 지하철 구간이 없는 버스/도보 경로라는 뜻이라 중간값 50.0을 부여해 정렬 기준에 포함시켰다. 완전히 제외하면 버스 경로가 목록에서 제외 되어버리기 때문이다.

pub async fn search_walking(
    state: web::Data<AppState>,
    query: web::Query<RouteQuery>,
) -> HttpResponse {
    match state.routes.search_walking_route(query.sy, query.sx, query.ey, query.ex).await {
        Ok(result) => HttpResponse::Ok().json(result),
        Err(e)     => HttpResponse::InternalServerError().body(format!("에러: {}", e)),
    }
}

So what: TMap 도보 경로는 캐시 없이 매번 직접 호출한다.

So why: 도보 경로는 사용자의 실시간 위치 기반으로 호출되는 경우가 많아서 출발지 좌표가 매번 조금씩 다르다. 캐시를 걸어도 히트율이 낮고 도보 경로 자체가 AR 진입 직접에만 한 번 호출되는 구조라 ODSay처럼 반복 호출 부담이 없다. 또한 TMap 파라미터 순서가 lat, lng 순인데 RouteQuery는 경도 위도 순으로 받아서 호출시 query.sy, query.sx로 순서를 바꿔서 넘긴다.

'Project > SSAFY2학기 특화 PJT' 카테고리의 다른 글

팀 프로젝트 정리 사이  (0) 2026.04.28
AR 내부 회고  (0) 2026.03.31
[BE] main.rs ( 메인 실행 코드 )  (0) 2026.03.16
[BE] realtime.rs ( 실시간 데이터 )  (0) 2026.03.13
[BE] fare.rs ( 요금 정보 )  (0) 2026.03.13

+ Recent posts