Реализация Geolocation API на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Geolocation API на сайте
Простая
~1 рабочий день
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Geolocation API на сайте

Geolocation API даёт координаты устройства — через GPS, WiFi триангуляцию или IP-геолокацию. Браузер всегда запрашивает разрешение пользователя. Точность варьируется от метров (GPS на улице) до километров (IP).

Получение текущей позиции

interface GeoPosition {
  lat: number
  lng: number
  accuracy: number      // метры
  altitude?: number
  speed?: number        // м/с
  heading?: number      // градусы от севера
  timestamp: number
}

async function getCurrentPosition(
  options: PositionOptions = {}
): Promise<GeoPosition> {
  if (!navigator.geolocation) {
    throw new Error('Geolocation API не поддерживается')
  }

  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        resolve({
          lat: position.coords.latitude,
          lng: position.coords.longitude,
          accuracy: position.coords.accuracy,
          altitude: position.coords.altitude ?? undefined,
          speed: position.coords.speed ?? undefined,
          heading: position.coords.heading ?? undefined,
          timestamp: position.timestamp,
        })
      },
      (error) => reject(mapGeolocationError(error)),
      {
        enableHighAccuracy: options.enableHighAccuracy ?? false,
        timeout: options.timeout ?? 10000,
        maximumAge: options.maximumAge ?? 0,
      }
    )
  })
}

function mapGeolocationError(error: GeolocationPositionError): Error {
  const messages: Record<number, string> = {
    1: 'Пользователь запретил доступ к геолокации',
    2: 'Позиция недоступна (нет сигнала)',
    3: 'Превышен таймаут получения позиции',
  }
  return new Error(messages[error.code] ?? 'Неизвестная ошибка геолокации')
}

Слежение за позицией

Для трекинга маршрута, навигации или живого обновления карты:

class GeolocationWatcher {
  private watchId: number | null = null
  private onPosition: (pos: GeoPosition) => void
  private onError: (err: Error) => void

  constructor(
    onPosition: (pos: GeoPosition) => void,
    onError: (err: Error) => void
  ) {
    this.onPosition = onPosition
    this.onError = onError
  }

  start(highAccuracy = true): void {
    if (this.watchId !== null) return

    this.watchId = navigator.geolocation.watchPosition(
      (position) => {
        this.onPosition({
          lat: position.coords.latitude,
          lng: position.coords.longitude,
          accuracy: position.coords.accuracy,
          speed: position.coords.speed ?? undefined,
          heading: position.coords.heading ?? undefined,
          timestamp: position.timestamp,
        })
      },
      (error) => this.onError(mapGeolocationError(error)),
      { enableHighAccuracy: highAccuracy, timeout: 5000, maximumAge: 1000 }
    )
  }

  stop(): void {
    if (this.watchId !== null) {
      navigator.geolocation.clearWatch(this.watchId)
      this.watchId = null
    }
  }
}

React-хук

interface UseGeolocationReturn {
  position: GeoPosition | null
  error: string | null
  loading: boolean
  get: () => Promise<void>
  watch: () => void
  stopWatch: () => void
}

function useGeolocation(): UseGeolocationReturn {
  const [position, setPosition] = useState<GeoPosition | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)
  const watcherRef = useRef<GeolocationWatcher>()

  useEffect(() => {
    watcherRef.current = new GeolocationWatcher(
      (pos) => setPosition(pos),
      (err) => setError(err.message)
    )
    return () => watcherRef.current?.stop()
  }, [])

  const get = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const pos = await getCurrentPosition({ enableHighAccuracy: true })
      setPosition(pos)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Ошибка геолокации')
    } finally {
      setLoading(false)
    }
  }, [])

  const watch = useCallback(() => watcherRef.current?.start(), [])
  const stopWatch = useCallback(() => watcherRef.current?.stop(), [])

  return { position, error, loading, get, watch, stopWatch }
}

Вычисление расстояния (формула Хаверсина)

Часто нужно рядом с геолокацией — найти ближайшие объекты, показать дистанцию:

function haversineDistance(
  a: { lat: number; lng: number },
  b: { lat: number; lng: number }
): number {
  const R = 6371000 // радиус Земли в метрах
  const toRad = (deg: number) => (deg * Math.PI) / 180

  const dLat = toRad(b.lat - a.lat)
  const dLng = toRad(b.lng - a.lng)

  const ha =
    Math.sin(dLat / 2) ** 2 +
    Math.cos(toRad(a.lat)) * Math.cos(toRad(b.lat)) * Math.sin(dLng / 2) ** 2

  return R * 2 * Math.atan2(Math.sqrt(ha), Math.sqrt(1 - ha))
}

// Найти ближайший объект
function findNearest<T extends { lat: number; lng: number }>(
  current: { lat: number; lng: number },
  points: T[]
): T | null {
  if (!points.length) return null
  return points.reduce((nearest, point) =>
    haversineDistance(current, point) < haversineDistance(current, nearest)
      ? point
      : nearest
  )
}

Что входит в работу

Утилиты получения и слежения за позицией, корректная обработка ошибок (отказ в разрешении, таймаут, недоступность), React-хук, вычисление расстояний, интеграция с картой (Leaflet, Google Maps, Mapbox) по необходимости.

Срок: 0.5–1 день. С картой — 1–2 дня.