Geolocation API и работа с GPS

Hyperapp — это легковесный JavaScript-фреймворк, ориентированный на управление состоянием и виртуальный DOM. Несмотря на минимализм, он позволяет интегрировать внешние браузерные API, включая Geolocation API для работы с GPS.

Подключение и инициализация Hyperapp

Для начала создаётся минимальная структура приложения:

import { h, app } from "https://unpkg.com/hyperapp@2.0.15?module";

const state = {
  coords: null,
  error: null
};

const actions = {
  setCoords: (coords) => ({ coords }),
  setError: (error) => ({ error }),
};

const view = (state, actions) => h("div", {}, [
  state.coords
    ? h("p", {}, `Широта: ${state.coords.latitude}, Долгота: ${state.coords.longitude}`)
    : h("p", {}, "Координаты не определены"),
  state.error && h("p", { style: { color: "red" } }, `Ошибка: ${state.error}`),
  h("button", { onclick: () => actions.getLocation() }, "Определить местоположение")
]);

Получение координат через Geolocation API

Geolocation API встроен в большинство современных браузеров. Для запроса текущей позиции используется метод navigator.geolocation.getCurrentPosition. В Hyperapp этот процесс удобно оборачивать в action:

actions.getLocation = () => (state, actions) => {
  if (!navigator.geolocation) {
    actions.setError("Geolocation API не поддерживается этим браузером");
    return;
  }

  navigator.geolocation.getCurrentPosition(
    (position) => {
      actions.setCoords(position.coords);
    },
    (error) => {
      switch(error.code) {
        case error.PERMISSION_DENIED:
          actions.setError("Доступ к местоположению запрещен пользователем");
          break;
        case error.POSITION_UNAVAILABLE:
          actions.setError("Информация о местоположении недоступна");
          break;
        case error.TIMEOUT:
          actions.setError("Время запроса местоположения истекло");
          break;
        default:
          actions.setError("Неизвестная ошибка при определении местоположения");
      }
    },
    { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }
  );
};

Ключевые моменты:

  • enableHighAccuracy: true — повышает точность GPS, но увеличивает потребление энергии.
  • timeout — максимальное время ожидания ответа.
  • maximumAge — максимальный возраст кэшированных координат.

Наблюдение за изменением местоположения

Для постоянного отслеживания позиции используется navigator.geolocation.watchPosition, который возвращает идентификатор наблюдателя:

let watchId = null;

actions.startTracking = () => (state, actions) => {
  if (!navigator.geolocation) {
    actions.setError("Geolocation API не поддерживается");
    return;
  }

  watchId = navigator.geolocation.watchPosition(
    (position) => actions.setCoords(position.coords),
    (error) => actions.setError(error.message),
    { enableHighAccuracy: true }
  );
};

actions.stopTracking = () => () => {
  if (watchId !== null) {
    navigator.geolocation.clearWatch(watchId);
    watchId = null;
  }
};

Использование этих методов позволяет реализовать динамическое отображение местоположения на карте или создание приложений для навигации.

Интеграция с картографическими сервисами

Полученные координаты можно передавать в сторонние сервисы, например, Google Maps или OpenStreetMap. Для Hyperapp создаются отдельные компоненты или view-фрагменты, которые обновляются при изменении состояния coords:

const mapView = (coords) =>
  coords
    ? h("iframe", {
        src: `https://www.openstreetmap.org/export/embed.html?bbox=${coords.longitude-0.01}%2C${coords.latitude-0.01}%2C${coords.longitude+0.01}%2C${coords.latitude+0.01}&layer=mapnik`,
        width: "100%",
        height: "400"
      })
    : h("p", {}, "Карта недоступна");

Обработка ошибок и UX

При работе с GPS необходимо учитывать:

  • Пользователь может отклонить запрос доступа к геолокации.
  • Устройство может быть вне зоны покрытия GPS.
  • Запросы с высокой точностью увеличивают нагрузку на батарею.
  • Нужно предоставлять пользователю информативные сообщения об ошибках.

Оптимизация и производительность

  • Кэширование координат: хранение последних известных координат для мгновенного отображения.
  • Контроль частоты обновлений: использование watchPosition с разумными интервалами.
  • Lazy-загрузка карт: подключение картографических сервисов только при наличии координат.

Hyperapp позволяет эффективно управлять состоянием, и сочетание его реактивной модели с Geolocation API делает возможным создание легких, динамичных и отзывчивых приложений с GPS-навигацией.