diff --git a/README.md b/README.md index 4a67749..9e4dcbb 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,9 @@ Home Assistant에 기록된 Galaxy Z Fold7의 위치, 배터리, 활동 상태, ## 히스토리와 지도 -실시간 화면은 현재 위치와 상태만 조회하고, 이동 기록은 기간 입력을 변경했을 때만 `history=1` 옵션으로 요청합니다. 서버는 Home Assistant 위치 기록을 15m 미만 미세 이동 기준으로 정리한 뒤 최대 300개 지점으로 샘플링합니다. +실시간 화면은 현재 위치와 상태를 조회하고, 기본 기간 입력값에 해당하는 최근 하루 이동 기록도 지도에 함께 표시합니다. 기간 입력을 변경하면 해당 범위의 이동 기록을 `history=1` 옵션으로 다시 요청합니다. 서버는 Home Assistant 위치 기록을 5m 미만 미세 이동 기준으로 정리한 뒤 최대 800개 지점으로 샘플링합니다. -Naver Map에는 전체 경로선을 먼저 그리고 시작/종료 마커와 최대 60개의 중간 포인트만 표시합니다. 기록 조회 시 지도는 경로 전체가 보이도록 자동으로 범위를 맞추며, 종료 지점 정보창을 먼저 열어 최근 위치를 바로 확인할 수 있게 합니다. +Naver Map에는 전체 경로선을 먼저 그리고 시작/종료 마커와 최대 180개의 중간 포인트를 표시합니다. 기록 조회 시 지도는 경로 전체가 보이도록 자동으로 범위를 맞추며, 종료 지점 정보창을 먼저 열어 최근 위치를 바로 확인할 수 있게 합니다. 지도 기능은 NAVER 지도 API v3의 기본 컨트롤, 지도 유형, `TrafficLayer`, `StreetLayer`, `Polyline`, `PointingIcon`, `fitBounds`를 활용합니다. 화면 상단 지도 도구에서 일반/위성 지도 전환, 교통 레이어, 거리뷰 가능 구역 레이어, 경로 전체 보기, 경로 재생을 제어합니다. diff --git a/js/main.js b/js/main.js index 49dd31a..f94c85a 100644 --- a/js/main.js +++ b/js/main.js @@ -666,8 +666,8 @@ document.addEventListener('DOMContentLoaded', () => { endTime: toServerTime(endEl.value) }; - // ✅ 사용자가 변경했거나 URL에 기간이 있으면 히스토리 모드 const shouldUseHistory = userTriggered || hasQS; + const shouldRequestHistory = shouldUseHistory || !userTriggered; if (shouldUseHistory) { _overrideRange = range; resetHistoryLayer(); @@ -676,13 +676,16 @@ document.addEventListener('DOMContentLoaded', () => { } try { - const data = await fetchDeviceData(true, shouldUseHistory ? range : null); + const data = await fetchDeviceData(true, shouldRequestHistory ? range : null); updateDOMWithData(data); - - const last = data.history && data.history[data.history.length - 1]; - if (last && mapState.map) { - mapState.map.panTo(new naver.maps.LatLng(last.lat, last.lng)); - } + if (!shouldUseHistory && data.history?.length > 0) { + updateHistoryMarkers(data.history); + } + + const last = data.history && data.history[data.history.length - 1]; + if (shouldUseHistory && last && mapState.map) { + mapState.map.panTo(new naver.maps.LatLng(last.lat, last.lng)); + } } catch (err) { alert(langCode === 'ko' ? '기록을 불러오지 못했습니다.' : 'Failed to load history.'); } @@ -1528,7 +1531,7 @@ function updateHistoryMarkers(history) { mapState.historyStartMarker = makeMarker(first, 'start'); mapState.historyEndMarker = makeMarker(last, 'end'); - const maxDots = 60; + const maxDots = 180; const step = Math.max(1, Math.ceil(points.length / maxDots)); points.forEach((pos, idx) => { if (idx === 0 || idx === points.length - 1 || idx % step !== 0) return; @@ -1693,7 +1696,7 @@ function fetchDeviceData(includeLang = true, range = null) { if (e) params.set('endTime', e); if (hasHistoryRange) { params.set('history', '1'); - params.set('maxPoints', '300'); + params.set('maxPoints', '800'); } const url = `https://chaegeon.com/custom/findmydevice/php/api.php?${params.toString()}`; diff --git a/php/api.php b/php/api.php index 810d95c..b99ad9c 100644 --- a/php/api.php +++ b/php/api.php @@ -77,7 +77,7 @@ if ($startParam && $endParam) { // API URL 생성 $historyEndpoint = "/history/period/{$startTime}?filter_entity_id=" . rawurlencode($entities['device']) . "&end_time={$endTime}"; $includeHistory = isset($_GET['history']) && $_GET['history'] === '1' && !isset($_GET['hashonly']); -$historyMaxPoints = max(20, min(1000, (int)($_GET['maxPoints'] ?? 300))); +$historyMaxPoints = max(20, min(1200, (int)($_GET['maxPoints'] ?? 800))); // 공통 요청 함수 function getData($entityId) { @@ -239,7 +239,7 @@ function simplify_path(array $path, int $maxPoints): array $filtered = []; $last = null; foreach ($path as $point) { - if ($last === null || path_distance_m($last, $point) >= 15) { + if ($last === null || path_distance_m($last, $point) >= 5) { $filtered[] = $point; $last = $point; }