Для сохранения маршрута пользователя в базе данных, обычно используется набор координат, представляющих его перемещение во времени. Этот набор координат может быть представлен в виде линии или пути, где каждая точка содержит информацию о местоположении (широта и долгота), времени и, возможно, другие дополнительные данные, такие как высота или скорость.
Содержание
Сохранение в БД PostgreSQL с помощью PostGIS
Одним из распространенных способов хранения маршрутов в базе данных является использование географических типов данных, предоставляемых многими современными базами данных. Например, в PostgreSQL с расширением PostGIS можно использовать тип данных “geometry“ или “geography“ для хранения географических объектов, таких как линии.
Пример создания таблицы для хранения маршрутов в PostgreSQL с использованием PostGIS:
CREATE TABLE user_routes (
user_id INT,
route_id SERIAL PRIMARY KEY,
route_geometry GEOMETRY(LineString, 4326),
timestamp TIMESTAMP
);В этом примере:
user_id– идентификатор пользователя, чтобы можно было связать маршрут с конкретным пользователем.route_id– уникальный идентификатор маршрута.route_geometry– поле для хранения геометрии маршрута в виде линии (LineString) в системе координат EPSG 4326 (широта/долгота).timestamp– метка времени, указывающая, когда была записана каждая точка маршрута.
Примечание: мы скорее всего будем связывать маршрут с поездкой( trip_id ), а поездка уже с пользователем.(хотя можно привязать и к user тоже)
Когда пользователь записывает свой маршрут, каждая точка маршрута (координаты в определенный момент времени) добавляется в базу данных с указанием соответствующего user_id, создается уникальный route_id, и записывается временная метка.
Позже пользователь может запросить данные из базы данных для визуализации своего маршрута на карте или для анализа перемещения во времени.
Пример конкретной записи маршрута в ячейках этой таблицы
Запись маршрута в ячейках будет выглядеть следующим образом:
INSERT INTO user_routes (user_id, route_geometry, timestamp)
VALUES
(1, ST_GeomFromText('LINESTRING(30.1234 50.5678, 30.4567 50.9876, 30.7890 50.6543)'), '2022-01-01T12:00:00Z');
В этом примере:
user_id: Идентификатор пользователя.route_geometry: Геометрия маршрута, представленная в виде LineString.ST_GeomFromTextиспользуется для создания геометрии из текстового представления координат.timestamp: Временная метка, указывающая момент времени, когда была записана точка маршрута.
Таким образом, вы можете использовать функцию “ST_GeomFromText“, чтобы вставить геометрию маршрута в таблицу “user_routes". Помните, что это просто пример, и реальный формат данных будет зависеть от вашего кода вставки данных и формата представления геометрии.
С какой периодичностью(время) координаты записываются в БД
Частота передачи координат на сервер зависит от требований конкретного приложения, его целей и ограничений. В случае отслеживания перемещения пользователя, частота может варьироваться в зависимости от таких факторов, как:
- Точность маршрута: Если важна высокая точность отслеживания маршрута, то частота обновления может быть высокой, например, раз в несколько секунд.
- Энергопотребление устройства: Чем чаще передаются координаты, тем больше энергии требуется от устройства пользователя (например, смартфона). Поэтому, в контексте мобильных устройств, разработчики могут настраивать частоту обновления, чтобы балансировать точность и энергопотребление.
- Необходимость реального времени: Если требуется реальное времени (например, в приложениях для отслеживания передвижения транспорта), частота обновления может быть высокой, чтобы обеспечить актуальные данные.
- Требования к пропускной способности сети: Высокая частота обновления может привести к увеличению объема передаваемых данных, что может оказаться важным фактором в приложениях с ограниченной пропускной способностью сети.
Для отслеживания перемещения на транспортных средствах, как в вашем примере со скоростью 25 км/час, разумно выбирать частоту обновления, достаточную для точного представления маршрута без излишней нагрузки на сеть и устройство. Например, обновление каждые несколько секунд может быть достаточным для точного отслеживания местоположения при такой скорости.
На примере шеринга самокатов
Для проката шеринговых самокатов, где важна точность и актуальность данных о местоположении, частота обновления может быть настроена на уровне секунд. В большинстве случаев это будет в пределах 1-5 секунд.
Давайте рассмотрим пример:
Если пользователь двигается со скоростью 25 км/час, то за одну секунду он пройдет приблизительно 7 метров (25 км/ч / 3600 сек/ч). Следовательно, если обновлять местоположение каждую секунду, вы сможете получить довольно точное представление о его маршруте.
Однако важно также учесть, что частота обновления может влиять на энергопотребление мобильного устройства и объем передаваемых данных. Поэтому рекомендуется провести тестирование и настройку в зависимости от конкретных требований вашего приложения и оборудования.
Запись маршрута на стороне клиента. Браузер
Можно использовать локальное хранение данных на стороне клиента, чтобы записывать маршрут и отправлять его в базу данных позже, когда пользователь завершит маршрут. Одним из подходов к этой задаче может быть использование локального хранилища браузера, такого как “localStorage" или "IndexedDB“.
Пример использования “localStorage“:
// Начать запись маршрута
function startRecordingRoute() {
// Инициализировать массив для хранения координат маршрута
const routeCoordinates = [];
// Сохранить массив в локальное хранилище
localStorage.setItem('routeCoordinates', JSON.stringify(routeCoordinates));
}
// Добавить координаты в массив маршрута
function addCoordinateToRoute(latitude, longitude) {
// Получить текущий массив координат из локального хранилища
const routeCoordinates = JSON.parse(localStorage.getItem('routeCoordinates')) || [];
// Добавить новые координаты в массив
routeCoordinates.push({ latitude, longitude });
// Обновить массив в локальном хранилище
localStorage.setItem('routeCoordinates', JSON.stringify(routeCoordinates));
}
// Завершить запись маршрута и сохранить в БД
function finishRecordingAndSaveToDB() {
// Получить массив координат из локального хранилища
const routeCoordinates = JSON.parse(localStorage.getItem('routeCoordinates')) || [];
// Отправить массив координат в вашу базу данных
// (реализация этой части зависит от вашего стека технологий на сервере)
// Пример запроса на сервер с использованием fetch:
fetch('/api/saveRoute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ route: routeCoordinates }),
})
.then(response => response.json())
.then(data => {
// Обработать ответ от сервера (если необходимо)
console.log('Маршрут успешно сохранен в базе данных');
// Очистить локальное хранилище после сохранения в БД
localStorage.removeItem('routeCoordinates');
})
.catch(error => {
console.error('Произошла ошибка при сохранении маршрута:', error);
});
}
В этом примере startRecordingRoute и addCoordinateToRoute используются для записи координат в локальное хранилище на стороне клиента. finishRecordingAndSaveToDB отправляет сохраненные координаты на сервер для сохранения в базе данных. После успешного сохранения маршрута данные из локального хранилища удаляются.
Обратите внимание, что использование “localStorage“ имеет ограничения по объему данных, и для более крупных объемов данных может быть разумным использовать “IndexedDB“.
Запись маршрута на стороне клиента. Мобильное приложение. ReactNative
В мобильном приложении на React Native, вы можете использовать локальное хранение данных, также как и в веб-приложении, но с использованием инструментов, предоставляемых React Native. Вместо “localStorage“ вы можете использовать “AsyncStorage“ для асинхронного хранения данных.
Пример использования “AsyncStorage“ для записи и отправки маршрута:
import React, { useState } from 'react';
import { View, Button } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
const RouteRecorder = () => {
const [routeCoordinates, setRouteCoordinates] = useState([]);
const startRecordingRoute = async () => {
// Инициализировать массив для хранения координат маршрута
await AsyncStorage.setItem('routeCoordinates', JSON.stringify([]));
};
const addCoordinateToRoute = async (latitude, longitude) => {
// Получить текущий массив координат из AsyncStorage
const storedRoute = await AsyncStorage.getItem('routeCoordinates');
const routeCoordinates = storedRoute ? JSON.parse(storedRoute) : [];
// Добавить новые координаты в массив
routeCoordinates.push({ latitude, longitude });
// Обновить массив в AsyncStorage
await AsyncStorage.setItem('routeCoordinates', JSON.stringify(routeCoordinates));
// Обновить состояние компонента
setRouteCoordinates(routeCoordinates);
};
const finishRecordingAndSaveToDB = async () => {
// Получить массив координат из AsyncStorage
const storedRoute = await AsyncStorage.getItem('routeCoordinates');
const routeCoordinates = storedRoute ? JSON.parse(storedRoute) : [];
// Отправить массив координат в вашу базу данных
// (реализация этой части зависит от вашего стека технологий на сервере)
// Пример запроса на сервер с использованием fetch:
fetch('https://example.com/api/saveRoute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ route: routeCoordinates }),
})
.then(response => response.json())
.then(data => {
// Обработать ответ от сервера (если необходимо)
console.log('Маршрут успешно сохранен в базе данных');
// Очистить AsyncStorage после сохранения в БД
AsyncStorage.removeItem('routeCoordinates');
setRouteCoordinates([]);
})
.catch(error => {
console.error('Произошла ошибка при сохранении маршрута:', error);
});
};
return (
<View>
<Button title="Start Recording" onPress={startRecordingRoute} />
<Button title="Add Coordinate" onPress={() => addCoordinateToRoute(37.7749, -122.4194)} />
<Button title="Finish and Save to DB" onPress={finishRecordingAndSaveToDB} />
</View>
);
};
export default RouteRecorder;
Этот пример демонстрирует использование “AsyncStorage“ для сохранения и получения данных в React Native. Помните, что “AsyncStorage“ имеет свои ограничения, и его стоит использовать для относительно небольших объемов данных. Если маршруты становятся крупными, вы можете рассмотреть использование других библиотек для управления локальным хранением данных в React Native, таких как “react-native-sqlite-storage“ или “realm“.
