Offline sleep location

28 views
Skip to first unread message

GOOD

unread,
Aug 12, 2026, 3:51:04 AM (7 days ago) Aug 12
to DroidScript
Hello, help me write a simple script that allows you to use sensors or location and the “start” button to count and draw the path you are walking along, but there is a nuance - all this is offline and without overlaying maps. that's the point. for example, got lost somewhere and to return along the drawn path by turning back or somewhere else. when turning back, it is necessary to take into account that the path that has been taken and when turning back it is drawn in gray, and the path along which I am walking is drawn in green and there should also be an icon where I am

GOOD

unread,
Aug 12, 2026, 6:08:48 AM (7 days ago) Aug 12
to DroidScript
Not work:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Путь без карты</title>
<style>
  canvas {
    border: 1px solid black;
  }
  #startBtn {
    margin-top: 10px;
  }
</style>
</head>
<body>
<canvas id="mapCanvas" width="800" height="600"></canvas><br/>
<button id="startBtn">Старт</button>
<script>
const canvas = document.getElementById('mapCanvas');
const ctx = canvas.getContext('2d');

let watchId = null;
let isTracking = false;
let path = []; // Все точки пути
let backPath = []; // Обратный маршрут
let currentPosition = null;

// Иконка для текущего положения
const iconSize = 10;

// Обработчик кнопки
document.getElementById('startBtn').addEventListener('click', () => {
  if (!isTracking) {
    startTracking();
  } else {
    stopTracking();
  }
});

function startTracking() {
  if (navigator.geolocation) {
    watchId = navigator.geolocation.watchPosition(
      (pos) => {
        const { latitude, longitude } = pos.coords;
        // Для простоты — используем координаты как есть
        // Можно добавить преобразование к экранным координатам
        const point = { lat: latitude, lon: longitude };
        updatePath(point);
        draw();
      },
      (err) => {
        alert('Ошибка получения геолокации: ' + err.message);
      },
      {
        enableHighAccuracy: true,
        maximumAge: 0,
        timeout: 5000,
      }
    );
    isTracking = true;
    document.getElementById('startBtn').textContent = 'Стоп';
  } else {
    alert('Геолокация не поддерживается браузером');
  }
}

function stopTracking() {
  if (watchId !== null) {
    navigator.geolocation.clearWatch(watchId);
    watchId = null;
  }
  isTracking = false;
  document.getElementById('startBtn').textContent = 'Старт';
}

// Обновляем путь
function updatePath(point) {
  if (path.length > 0) {
    // Если возвращаемся назад, переносим точку в серый путь
    const lastPoint = path[path.length - 1];
    if (distance(lastPoint, point) > 10) { // порог для определения движения
      // Простая проверка - если новая точка значительно отличается, считаем, что возвращаемся
      // В реальности можно сделать более сложную логику
      // Для примера просто добавляем новую точку
      path.push(point);
    }
  } else {
    path.push(point);
  }
  // Можно добавить логику для определения возврата и окраски пути
  // Но для простоты — все новые точки добавляются в зеленый путь
}

// Расстояние между точками
function distance(p1, p2) {
  const R = 6371e3; // радиус Земли в метрах
  const φ1 = p1.lat * Math.PI/180;
  const φ2 = p2.lat * Math.PI/180;
  const Δφ = (p2.lat - p1.lat) * Math.PI/180;
  const Δλ = (p2.lon - p1.lon) * Math.PI/180;

  const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
            Math.cos(φ1) * Math.cos(φ2) *
            Math.sin(Δλ/2) * Math.sin(Δλ/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  const d = R * c;
  return d;
}

// Отрисовка
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  if (path.length === 0) return;

  // Определим масштаб и смещение для отображения
  // Для простоты — используем диапазон координат и масштабируем под канвас
  const xs = path.map(p => p.lon);
  const ys = path.map(p => p.lat);
  const minX = Math.min(...xs);
  const maxX = Math.max(...xs);
  const minY = Math.min(...ys);
  const maxY = Math.max(...ys);
  const padding = 20;

  const scaleX = (canvas.width - 2*padding) / (maxX - minX || 1);
  const scaleY = (canvas.height - 2*padding) / (maxY - minY || 1);
  const scale = Math.min(scaleX, scaleY);

  // Функция для преобразования координат
  function toCanvas(p) {
    return {
      x: padding + (p.lon - minX) * scale,
      y: canvas.height - padding - (p.lat - minY) * scale // вверх - север
    };
  }

  // Рисуем пройденный путь
  ctx.lineWidth = 3;

  // Зеленый путь — текущий
  ctx.strokeStyle = 'green';
  ctx.beginPath();
  const start = toCanvas(path[0]);
  ctx.moveTo(start.x, start.y);
  for (let i = 1; i < path.length; i++) {
    const p = toCanvas(path[i]);
    ctx.lineTo(p.x, p.y);
  }
  ctx.stroke();

  // Обновляем текущую позицию
  currentPosition = toCanvas(path[path.length - 1]);

  // Рисуем иконку текущего положения
  ctx.fillStyle = 'blue';
  ctx.beginPath();
  ctx.arc(currentPosition.x, currentPosition.y, iconSize, 0, Math.PI*2);
  ctx.fill();
}
</script>
</body>
</html>

среда, 12 августа 2026 г. в 10:51:04 UTC+3, GOOD:
Reply all
Reply to author
Forward
0 new messages