Simplify findmydevice map controls

This commit is contained in:
seo
2026-06-18 03:55:44 +09:00
parent 3dfb506474
commit 08bd2ab4a4
2 changed files with 3 additions and 55 deletions
+2 -3
View File
@@ -13,7 +13,6 @@ Home Assistant에 기록된 Galaxy Z Fold7의 위치, 배터리, 활동 상태,
- 현재 위치 지도 표시 - 현재 위치 지도 표시
- GPS 정확도 원 표시 - GPS 정확도 원 표시
- 사용자 지정 기간 이동 경로 표시 - 사용자 지정 기간 이동 경로 표시
- 지도 타입 전환, 교통/거리뷰 레이어 토글
- 이동 기록 요약, 경로 전체 보기, 경로 재생, 시간 슬라이더 - 이동 기록 요약, 경로 전체 보기, 경로 재생, 시간 슬라이더
- 부드러운 렌더링용 경로선, GPS 튐 보정 토글, 체류 지점 자동 표시 - 부드러운 렌더링용 경로선, GPS 튐 보정 토글, 체류 지점 자동 표시
- 현재 위치 기준 집 50m, 500m/1km 반경 표시와 선택 지점 Naver 지도 열기 - 현재 위치 기준 집 50m, 500m/1km 반경 표시와 선택 지점 Naver 지도 열기
@@ -52,9 +51,9 @@ Home Assistant에 기록된 Galaxy Z Fold7의 위치, 배터리, 활동 상태,
Naver Map에는 단일 Polyline 중심의 부드러운 경로선을 먼저 그리고 시작/종료 마커와 체류 지점 마커를 표시합니다. 중간 점 마커는 긴 기간 조회에서 브라우저 부하가 커지므로 표시하지 않습니다. 기록 조회 시 지도는 경로 전체가 보이도록 자동으로 범위를 맞추며, 종료 지점 정보창을 먼저 열어 최근 위치를 바로 확인할 수 있게 합니다. Naver Map에는 단일 Polyline 중심의 부드러운 경로선을 먼저 그리고 시작/종료 마커와 체류 지점 마커를 표시합니다. 중간 점 마커는 긴 기간 조회에서 브라우저 부하가 커지므로 표시하지 않습니다. 기록 조회 시 지도는 경로 전체가 보이도록 자동으로 범위를 맞추며, 종료 지점 정보창을 먼저 열어 최근 위치를 바로 확인할 수 있게 합니다.
지도 기능은 NAVER 지도 API v3의 기본 컨트롤, 지도 유형, `TrafficLayer`, `StreetLayer`, `Polyline`, `PointingIcon`, `Circle`, `fitBounds`를 활용합니다. 지도 아래 도구 패널에서 일반/위성 지도 전환, 교통 레이어, 거리뷰 가능 구역 레이어, 경로 전체 보기, 경로 재생, GPS 튐 보정, Naver 지도 열기를 제어합니다. 지도 기능은 NAVER 지도 API v3의 기본 컨트롤, `Polyline`, `PointingIcon`, `Circle`, `fitBounds`를 활용합니다. 지도 아래 도구 패널에서 경로 전체 보기, 경로 재생, GPS 튐 보정, Naver 지도 열기를 제어합니다.
히스토리 요약 패널은 이동 거리, 기록 시간, 평균 속도, 최대 기록 공백, 지점 수, 체류 지점 수, 집 반경, 집 체류 시간, 외출 시간, 외출 횟수, 마지막 복귀 시각과 현재 상태를 표시합니다. 경로선 클릭으로 요약 패널을 숨기거나 다시 볼 수 있고, 각 히스토리 마커 정보창에는 기록 시각, 시작점 기준 누적 거리, 좌표를 함께 표시합니다. 히스토리 요약 패널은 이동 거리, 기록 시간, 평균 속도, 최대 기록 공백, 지점 수, 체류 지점 수, 집 반경, 집 체류 시간, 외출 시간, 외출 횟수, 마지막 복귀 시각과 현재 상태를 표시합니다. 각 히스토리 마커 정보창에는 기록 시각, 시작점 기준 누적 거리, 좌표를 함께 표시합니다.
경로선은 Douglas-Peucker 단순화와 가벼운 좌표 smoothing을 거쳐 긴 기간에서도 완만한 단일 선으로 표시합니다. 2km 이상 순간 이동하면서 180km/h를 넘는 GPS 튐은 기본적으로 제외하며, 지도 아래 `GPS 튐 보정` 버튼으로 원본 렌더링 경로와 보정 경로를 전환할 수 있습니다. 경로선은 Douglas-Peucker 단순화와 가벼운 좌표 smoothing을 거쳐 긴 기간에서도 완만한 단일 선으로 표시합니다. 2km 이상 순간 이동하면서 180km/h를 넘는 GPS 튐은 기본적으로 제외하며, 지도 아래 `GPS 튐 보정` 버튼으로 원본 렌더링 경로와 보정 경로를 전환할 수 있습니다.
+1 -52
View File
@@ -165,10 +165,6 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
history: "기록", history: "기록",
startTime: "시작", startTime: "시작",
endTime: "종료", endTime: "종료",
mapNormal: "일반",
mapSatellite: "위성",
mapTraffic: "교통",
mapStreet: "거리뷰",
mapFit: "전체", mapFit: "전체",
mapPlay: "재생", mapPlay: "재생",
mapPause: "정지", mapPause: "정지",
@@ -376,10 +372,6 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
history: "History", history: "History",
startTime: "Start", startTime: "Start",
endTime: "End", endTime: "End",
mapNormal: "Normal",
mapSatellite: "Satellite",
mapTraffic: "Traffic",
mapStreet: "Street",
mapFit: "Fit", mapFit: "Fit",
mapPlay: "Play", mapPlay: "Play",
mapPause: "Pause", mapPause: "Pause",
@@ -448,9 +440,6 @@ const deviceLang = (navigator.language || navigator.userLanguage || "en").starts
stayPoints: [], stayPoints: [],
homeStats: null, homeStats: null,
filterOutliers: true, filterOutliers: true,
layers: {},
layerActive: {},
activeMapType: 'normal',
openInfoWindow: null, openInfoWindow: null,
mapClickHandlerAdded: false, mapClickHandlerAdded: false,
initialInfoOpened: false, initialInfoOpened: false,
@@ -1137,16 +1126,9 @@ function initMap(latlng, accuracy = 50) {
createMainMarker(latlng); createMainMarker(latlng);
createAccuracyCircle(latlng, accuracy); createAccuracyCircle(latlng, accuracy);
updateHomeCircle(); updateHomeCircle();
initMapLayers();
ensureMapTools(); ensureMapTools();
} }
function initMapLayers() {
if (!mapState.map || mapState.layers.traffic) return;
mapState.layers.traffic = new naver.maps.TrafficLayer();
mapState.layers.street = new naver.maps.StreetLayer();
}
function ensureMapTools() { function ensureMapTools() {
const container = document.getElementById('mapContainer') || document.getElementById('map')?.parentElement; const container = document.getElementById('mapContainer') || document.getElementById('map')?.parentElement;
if (!container || document.getElementById('mapTools')) return; if (!container || document.getElementById('mapTools')) return;
@@ -1161,10 +1143,6 @@ function ensureMapTools() {
tools.id = 'mapTools'; tools.id = 'mapTools';
tools.className = 'map-tools'; tools.className = 'map-tools';
tools.innerHTML = ` tools.innerHTML = `
<button type="button" class="map-tool active" data-map-action="normal"></button>
<button type="button" class="map-tool" data-map-action="satellite"></button>
<button type="button" class="map-tool" data-map-action="traffic"></button>
<button type="button" class="map-tool" data-map-action="street"></button>
<button type="button" class="map-tool" data-map-action="fit"></button> <button type="button" class="map-tool" data-map-action="fit"></button>
<button type="button" class="map-tool" data-map-action="play"></button> <button type="button" class="map-tool" data-map-action="play"></button>
<button type="button" class="map-tool active" data-map-action="filter"></button> <button type="button" class="map-tool active" data-map-action="filter"></button>
@@ -1206,10 +1184,6 @@ function ensureMapTools() {
function updateMapToolLabels() { function updateMapToolLabels() {
const t = translations[langCode] || translations.ko; const t = translations[langCode] || translations.ko;
const labelMap = { const labelMap = {
normal: t.mapNormal,
satellite: t.mapSatellite,
traffic: t.mapTraffic,
street: t.mapStreet,
fit: t.mapFit, fit: t.mapFit,
play: mapState.playbackTimer ? t.mapPause : t.mapPlay, play: mapState.playbackTimer ? t.mapPause : t.mapPlay,
filter: t.historyFiltered, filter: t.historyFiltered,
@@ -1227,27 +1201,6 @@ function updateMapToolLabels() {
function handleMapTool(action) { function handleMapTool(action) {
if (!mapState.map) return; if (!mapState.map) return;
if (action === 'normal' || action === 'satellite') {
mapState.activeMapType = action;
const mapTypes = naver.maps.MapTypeId || {};
const typeId = action === 'satellite'
? (mapTypes.HYBRID || mapTypes.SATELLITE || 'satellite')
: (mapTypes.NORMAL || 'normal');
mapState.map.setMapTypeId(typeId);
document.querySelectorAll('[data-map-action="normal"], [data-map-action="satellite"]').forEach(button => {
button.classList.toggle('active', button.dataset.mapAction === action);
});
return;
}
if (action === 'traffic' || action === 'street') {
const layer = mapState.layers[action];
if (!layer) return;
const nextActive = !mapState.layerActive[action];
layer.setMap(nextActive ? mapState.map : null);
mapState.layerActive[action] = nextActive;
document.querySelector(`[data-map-action="${action}"]`)?.classList.toggle('active', nextActive);
return;
}
if (action === 'fit') { if (action === 'fit') {
fitHistoryOrCurrentBounds(); fitHistoryOrCurrentBounds();
return; return;
@@ -1698,11 +1651,7 @@ function drawSpeedTrack(points) {
strokeLineJoin: 'round', strokeLineJoin: 'round',
endIcon: naver.maps.PointingIcon?.BLOCK_ARROW, endIcon: naver.maps.PointingIcon?.BLOCK_ARROW,
endIconSize: 16, endIconSize: 16,
clickable: true clickable: false
});
naver.maps.Event.addListener(line, 'click', () => {
const panel = document.getElementById('historySummaryPanel');
if (panel) panel.hidden = !panel.hidden;
}); });
mapState.trackLines.push(line); mapState.trackLines.push(line);
mapState.trackLine = line; mapState.trackLine = line;