Реалізація 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 дні.