From 343df69cc2765fe0adb51e4515a82d1cfac18d47 Mon Sep 17 00:00:00 2001 From: seo Date: Sun, 12 Jul 2026 16:38:17 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=AC=EC=83=9D=20=EB=B0=B0=EC=86=8D?= =?UTF-8?q?=EA=B3=BC=20=EA=B8=B0=EB=B3=B8=20=EC=A7=80=EB=8F=84=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EA=B0=92=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- js/main.js | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2e7422a..3330d82 100644 --- a/README.md +++ b/README.md @@ -64,19 +64,19 @@ PWA standalone으로 진입한 경우에는 설치형 앱 사용성을 우선해 Naver Map에는 단일 Polyline 중심의 부드러운 경로선을 먼저 그리고 체류 지점 마커를 표시합니다. 시작/종료 마커와 자동 정보창은 표시하지 않습니다. 중간 점 마커는 긴 기간 조회에서 브라우저 부하가 커지므로 표시하지 않습니다. 기록 조회 시 지도는 경로 전체가 보이도록 자동으로 범위를 맞춥니다. 지도 도구에서는 교통 상황, 지적편집도, 위성/일반 지도, 내 기록/체류 표시를 토글할 수 있습니다. -지도 기능은 NAVER 지도 API v3의 기본 컨트롤, `Polyline`, `Circle`, `fitBounds`를 활용합니다. 지도 아래 도구 패널에서 경로 전체 보기, 경로 재생, GPS 튐 보정, Naver 지도 열기를 제어합니다. +지도 기능은 NAVER 지도 API v3의 기본 컨트롤, `Polyline`, `Circle`, `fitBounds`를 활용합니다. 지도 아래 도구 패널에서 경로 전체 보기, 경로 재생, GPS 튐 보정, 지도 열기를 제어합니다. 히스토리 요약 패널은 이동 거리, 기록 시간, 지도에 실제로 그려진 지점 수를 기본으로 보여줍니다. 체류 지점, 현재 상태, 외출 시간, 외출 횟수, 마지막 복귀 시각은 값이 있을 때만 보여주므로 빈값이나 판단 가치가 낮은 항목은 화면에 남지 않습니다. 각 히스토리 마커 정보창에는 기록 시각, 시작점 기준 누적 거리, 좌표를 함께 표시합니다. Home Assistant 주소가 비어 있으면 브라우저에서 Naver reverse geocode를 시도하고, 실패하면 좌표를 현재 위치 값으로 표시합니다. -경로선은 기본값으로 서버가 내려준 병합 지점을 전부 사용해 표시합니다. `GPS 튐 보정`을 켜면 집 중심 1.2km 안의 장기 체류성 흔들림은 집 위치로 흡수하고, 집 주변 보정 지점은 30분 단위로 줄여 지도 낙서를 줄입니다. 이전/다음 지점이 가까운데 중간 지점만 250m 이상 튀고 왕복 속도가 80km/h를 넘는 단발 스파이크, 500m 이상 220km/h 초과 이동, 2km 이상 120km/h 초과 이동, 정확도 300m 초과 지점은 제외합니다. 30분 이상 기록 공백은 선을 끊고 이동 거리 합산에서도 제외합니다. 지도 아래 `GPS 튐 보정` 버튼으로 전체 지점 경로와 보정 경로를 전환할 수 있습니다. +경로선은 기본값으로 GPS 튐 보정을 켠 상태에서 표시합니다. `GPS 튐 보정`을 켜면 집 중심 1.2km 안의 장기 체류성 흔들림은 집 위치로 흡수하고, 집 주변 보정 지점은 30분 단위로 줄여 지도 낙서를 줄입니다. 이전/다음 지점이 가까운데 중간 지점만 250m 이상 튀고 왕복 속도가 80km/h를 넘는 단발 스파이크, 500m 이상 220km/h 초과 이동, 2km 이상 120km/h 초과 이동, 정확도 300m 초과 지점은 제외합니다. 30분 이상 기록 공백은 선을 끊고 이동 거리 합산에서도 제외합니다. 지도 아래 `GPS 튐 보정` 버튼으로 전체 지점 경로와 보정 경로를 전환할 수 있습니다. 집 판정은 설정된 서울 집과 목포 집 좌표를 중심점으로 한 150m 반경을 기준으로 합니다. GPS 튐 보정이 켜져 있으면 두 집 주변 1.2km 안의 지점은 가까운 집 위치로 흡수하고, 외출은 연속된 외부 지점이 5분 이상 지속될 때만 세션으로 확정합니다. 외부 지점 사이의 공백이 2시간을 넘으면 해당 구간은 알 수 없는 구간으로 보고 외출 지속시간에 합산하지 않습니다. 여러 번 나갔다 돌아온 경우 집 체류 시간은 합산하고, 외출은 출발/복귀 단위의 세션으로 따로 보여줍니다. -기록 시간 슬라이더를 움직이면 지도 아래에는 `월. 일. 시간` 형식의 선택 시각만 간결하게 표시합니다. 경로 재생은 얼굴 아이콘 마커만 사용하며, 재생 중에는 현재 위치 얼굴과 정확도 원을 숨깁니다. 재생 버튼은 지점 수에 따라 의미 있는 배속만 남겨 `2x`, `5x`, `10x`, `20x`, `50x`, `100x`, `500x` 순서로 돌고, 각 배속에서 최소 80단계 이상 보여줄 수 없으면 해당 배속은 건너뜁니다. 100m 반경 안에서 10분 이상 머문 구간은 체류 지점 마커로 묶어 표시하되, 서울 집과 목포 집 안의 체류는 계산하거나 표시하지 않습니다. 같은 위치의 체류는 하나의 마커로 합산하고, 클릭 시 총 체류 시간과 방문별 시작/종료/체류 시간을 확인할 수 있습니다. 지도를 축소하면 가까운 체류 지점을 `n개` 마커로 묶고, 확대하면 체류 장소와 시간이 다시 보입니다. 라이브 위치가 기존 체류 지점 100m 안에 다시 들어오면 초상화 위를 가리지 않는 커스텀 배지로 누적 체류중 시간을 표시하되, 지도를 크게 축소한 상태에서는 배지를 숨깁니다. +기록 시간 슬라이더를 움직이면 지도 아래에는 `월. 일. 시간` 형식의 선택 시각만 간결하게 표시합니다. 경로 재생은 얼굴 아이콘 마커만 사용하며, 재생 중에는 현재 위치 얼굴과 정확도 원을 숨깁니다. 재생 버튼은 지점 수에 따라 의미 있는 배속만 남겨 `2x`, `5x`, `10x` 순서로 돌고, 각 배속에서 최소 80단계 이상 보여줄 수 없으면 해당 배속은 건너뜁니다. 100m 반경 안에서 10분 이상 머문 구간은 체류 지점 마커로 묶어 표시하되, 서울 집과 목포 집 안의 체류는 계산하거나 표시하지 않습니다. 같은 위치의 체류는 하나의 마커로 합산하고, 클릭 시 총 체류 시간과 방문별 시작/종료/체류 시간을 확인할 수 있습니다. 지도를 축소하면 가까운 체류 지점을 `n개` 마커로 묶고, 확대하면 체류 장소와 시간이 다시 보입니다. 라이브 위치가 기존 체류 지점 100m 안에 다시 들어오면 초상화 위를 가리지 않는 커스텀 배지로 누적 체류중 시간을 표시하되, 지도를 크게 축소한 상태에서는 배지를 숨깁니다. 재생 중 주기적 위치 갱신으로 히스토리 경로가 다시 그려져도 현재 재생 위치를 유지합니다. 재생 타이머는 시작 당시 지점 목록에 고정하지 않고 최신 히스토리 지점 목록을 기준으로 계속 진행합니다. -라이브 위치에는 설정된 집 150m 원과 GPS 정확도 원만 표시합니다. 히스토리 범위 조회나 기록 재생 중에는 현재 위치 사진 마커와 정확도 원을 숨기고, 종료 지점 정보창을 자동으로 열지 않습니다. `Naver 지도` 버튼은 히스토리 선택 지점 또는 현재 위치를 Naver 지도에서 바로 엽니다. +라이브 위치에는 설정된 집 150m 원과 GPS 정확도 원만 표시합니다. 히스토리 범위 조회나 기록 재생 중에는 현재 위치 사진 마커와 정확도 원을 숨기고, 종료 지점 정보창을 자동으로 열지 않습니다. `지도` 버튼은 히스토리 선택 지점 또는 현재 위치를 Naver 지도에서 바로 엽니다. ## 센서 표시 정책 diff --git a/js/main.js b/js/main.js index b17d375..9c655f6 100644 --- a/js/main.js +++ b/js/main.js @@ -218,7 +218,7 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts departure: "출발", returnHome: "복귀", awaySessionTitle: "외출 기록", - openNaverMap: "Naver 지도", + openNaverMap: "지도", selectedPoint: "선택 지점", }, en: { @@ -471,7 +471,7 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts historyStats: null, stayPoints: [], homeStats: null, - filterOutliers: false, + filterOutliers: true, openInfoWindow: null, mapClickHandlerAdded: false, initialInfoOpened: false, @@ -494,7 +494,7 @@ let langCode = localStorage.getItem("currentLang") || deviceLang, wakeLock = null; const reverseGeocodeCache = new Map(); -const PLAYBACK_SPEEDS = [2, 5, 10, 20, 50, 100, 500]; +const PLAYBACK_SPEEDS = [2, 5, 10]; const PLAYBACK_MIN_VISIBLE_STEPS = 80; const PLAYBACK_TICK_MS = 160; const STAY_MIN_SECONDS = 10 * 60; @@ -1228,6 +1228,12 @@ function isUsefulAddress(value) { return !!text && text !== '-' && text.toLowerCase() !== 'not_home' && text.toUpperCase() !== 'N/A'; } +function displayAddress(value) { + const text = String(value || '').trim(); + if (text.toLowerCase() === 'home') return langCode === 'ko' ? '집' : 'Home'; + return text; +} + function formatLatLngAddress(lat, lng) { return `${Number(lat).toFixed(5)}, ${Number(lng).toFixed(5)}`; } @@ -1241,11 +1247,11 @@ function setCurrentPositionText(value) { function updateCurrentAddress(data) { if (!hasValidCoords(data.latitude, data.longitude)) { - setCurrentPositionText(isUsefulAddress(data.address) ? data.address : '-'); + setCurrentPositionText(isUsefulAddress(data.address) ? displayAddress(data.address) : '-'); return; } if (isUsefulAddress(data.address)) { - setCurrentPositionText(data.address); + setCurrentPositionText(displayAddress(data.address)); return; } @@ -1286,7 +1292,7 @@ function updateDOM(data) { const textMap = { currentPosition: isUsefulAddress(data.address) - ? data.address + ? displayAddress(data.address) : (hasValidCoords(data.latitude, data.longitude) ? formatLatLngAddress(data.latitude, data.longitude) : '-'), lastUpdateTime: data.updated ? getRelativeTime(data.updated) : "-", nowActivity: data.activity,