fix: Fix edit
entities on the map
This commit is contained in:
@ -22,6 +22,28 @@ interface ApiSight {
|
|||||||
longitude: number;
|
longitude: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Допуск для сравнения координат, чтобы избежать ошибок с точностью чисел.
|
||||||
|
const COORDINATE_PRECISION_TOLERANCE = 1e-9;
|
||||||
|
|
||||||
|
// Вспомогательная функция, обновленная для сравнения с допуском.
|
||||||
|
const arePathsEqual = (
|
||||||
|
path1: [number, number][],
|
||||||
|
path2: [number, number][]
|
||||||
|
): boolean => {
|
||||||
|
if (path1.length !== path2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < path1.length; i++) {
|
||||||
|
if (
|
||||||
|
Math.abs(path1[i][0] - path2[i][0]) > COORDINATE_PRECISION_TOLERANCE ||
|
||||||
|
Math.abs(path1[i][1] - path2[i][1]) > COORDINATE_PRECISION_TOLERANCE
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
class MapStore {
|
class MapStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
makeAutoObservable(this);
|
makeAutoObservable(this);
|
||||||
@ -33,25 +55,19 @@ class MapStore {
|
|||||||
|
|
||||||
getRoutes = async () => {
|
getRoutes = async () => {
|
||||||
const routes = await languageInstance("ru").get("/route");
|
const routes = await languageInstance("ru").get("/route");
|
||||||
|
|
||||||
const routedIds = routes.data.map((route: any) => route.id);
|
const routedIds = routes.data.map((route: any) => route.id);
|
||||||
|
|
||||||
const mappedRoutes: ApiRoute[] = [];
|
const mappedRoutes: ApiRoute[] = [];
|
||||||
for (const routeId of routedIds) {
|
for (const routeId of routedIds) {
|
||||||
const responseSoloRoute = await languageInstance("ru").get(
|
const responseSoloRoute = await languageInstance("ru").get(
|
||||||
`/route/${routeId}`
|
`/route/${routeId}`
|
||||||
);
|
);
|
||||||
const route = responseSoloRoute.data;
|
const route = responseSoloRoute.data;
|
||||||
|
mappedRoutes.push({
|
||||||
const mappedRoute = {
|
|
||||||
id: route.id,
|
id: route.id,
|
||||||
route_number: route.route_number,
|
route_number: route.route_number,
|
||||||
path: route.path,
|
path: route.path,
|
||||||
};
|
});
|
||||||
|
|
||||||
mappedRoutes.push(mappedRoute);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.routes = mappedRoutes.sort((a, b) =>
|
this.routes = mappedRoutes.sort((a, b) =>
|
||||||
a.route_number.localeCompare(b.route_number)
|
a.route_number.localeCompare(b.route_number)
|
||||||
);
|
);
|
||||||
@ -59,27 +75,23 @@ class MapStore {
|
|||||||
|
|
||||||
getStations = async () => {
|
getStations = async () => {
|
||||||
const stations = await languageInstance("ru").get("/station");
|
const stations = await languageInstance("ru").get("/station");
|
||||||
const mappedStations = stations.data.map((station: any) => ({
|
this.stations = stations.data.map((station: any) => ({
|
||||||
id: station.id,
|
id: station.id,
|
||||||
name: station.name,
|
name: station.name,
|
||||||
latitude: station.latitude,
|
latitude: station.latitude,
|
||||||
longitude: station.longitude,
|
longitude: station.longitude,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.stations = mappedStations;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getSights = async () => {
|
getSights = async () => {
|
||||||
const sights = await languageInstance("ru").get("/sight");
|
const sights = await languageInstance("ru").get("/sight");
|
||||||
const mappedSights = sights.data.map((sight: any) => ({
|
this.sights = sights.data.map((sight: any) => ({
|
||||||
id: sight.id,
|
id: sight.id,
|
||||||
name: sight.name,
|
name: sight.name,
|
||||||
description: sight.description,
|
description: sight.description,
|
||||||
latitude: sight.latitude,
|
latitude: sight.latitude,
|
||||||
longitude: sight.longitude,
|
longitude: sight.longitude,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.sights = mappedSights;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteRecourse = async (recourse: string, id: number) => {
|
deleteRecourse = async (recourse: string, id: number) => {
|
||||||
@ -94,31 +106,98 @@ class MapStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleSave = async (json: string) => {
|
handleSave = async (json: string) => {
|
||||||
const sights: any[] = [];
|
const newSights: any[] = [];
|
||||||
const routes: any[] = [];
|
const newRoutes: any[] = [];
|
||||||
const stations: any[] = [];
|
const newStations: any[] = [];
|
||||||
|
const updatedSights: any[] = [];
|
||||||
|
const updatedRoutes: any[] = [];
|
||||||
|
const updatedStations: any[] = [];
|
||||||
|
|
||||||
const parsedJSON = JSON.parse(json);
|
const parsedJSON = JSON.parse(json);
|
||||||
|
console.log("Данные для сохранения (GeoJSON):", parsedJSON);
|
||||||
|
|
||||||
console.log(parsedJSON);
|
for (const feature of parsedJSON.features) {
|
||||||
parsedJSON.features.forEach((feature: any) => {
|
|
||||||
const { geometry, properties, id } = feature;
|
const { geometry, properties, id } = feature;
|
||||||
const idCanBeSplited = id.split("-");
|
const idParts = String(id).split("-");
|
||||||
|
|
||||||
if (!(idCanBeSplited.length > 1)) {
|
if (idParts.length > 1) {
|
||||||
|
const featureType = idParts[0];
|
||||||
|
const numericId = parseInt(idParts[1], 10);
|
||||||
|
if (isNaN(numericId)) continue;
|
||||||
|
|
||||||
|
if (featureType === "station") {
|
||||||
|
const originalStation = this.stations.find((s) => s.id === numericId);
|
||||||
|
if (!originalStation) continue;
|
||||||
|
|
||||||
|
const currentStation = {
|
||||||
|
name: properties.name || "",
|
||||||
|
latitude: geometry.coordinates[1],
|
||||||
|
longitude: geometry.coordinates[0],
|
||||||
|
};
|
||||||
|
|
||||||
|
// ИЗМЕНЕНИЕ: Сравнение координат с допуском
|
||||||
|
if (
|
||||||
|
originalStation.name !== currentStation.name ||
|
||||||
|
Math.abs(originalStation.latitude - currentStation.latitude) >
|
||||||
|
COORDINATE_PRECISION_TOLERANCE ||
|
||||||
|
Math.abs(originalStation.longitude - currentStation.longitude) >
|
||||||
|
COORDINATE_PRECISION_TOLERANCE
|
||||||
|
) {
|
||||||
|
updatedStations.push({ id: numericId, ...currentStation });
|
||||||
|
}
|
||||||
|
} else if (featureType === "route") {
|
||||||
|
const originalRoute = this.routes.find((r) => r.id === numericId);
|
||||||
|
if (!originalRoute) continue;
|
||||||
|
|
||||||
|
const currentRoute = {
|
||||||
|
route_number: properties.name || "",
|
||||||
|
path: geometry.coordinates,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ИЗМЕНЕНИЕ: Используется новая функция arePathsEqual с допуском
|
||||||
|
if (
|
||||||
|
originalRoute.route_number !== currentRoute.route_number ||
|
||||||
|
!arePathsEqual(originalRoute.path, currentRoute.path)
|
||||||
|
) {
|
||||||
|
updatedRoutes.push({ id: numericId, ...currentRoute });
|
||||||
|
}
|
||||||
|
} else if (featureType === "sight") {
|
||||||
|
const originalSight = this.sights.find((s) => s.id === numericId);
|
||||||
|
if (!originalSight) continue;
|
||||||
|
|
||||||
|
const currentSight = {
|
||||||
|
name: properties.name || "",
|
||||||
|
description: properties.description || "",
|
||||||
|
latitude: geometry.coordinates[1],
|
||||||
|
longitude: geometry.coordinates[0],
|
||||||
|
};
|
||||||
|
|
||||||
|
// ИЗМЕНЕНИЕ: Сравнение координат с допуском
|
||||||
|
if (
|
||||||
|
originalSight.name !== currentSight.name ||
|
||||||
|
originalSight.description !== currentSight.description ||
|
||||||
|
Math.abs(originalSight.latitude - currentSight.latitude) >
|
||||||
|
COORDINATE_PRECISION_TOLERANCE ||
|
||||||
|
Math.abs(originalSight.longitude - currentSight.longitude) >
|
||||||
|
COORDINATE_PRECISION_TOLERANCE
|
||||||
|
) {
|
||||||
|
updatedSights.push({ id: numericId, ...currentSight });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (properties.featureType === "station") {
|
if (properties.featureType === "station") {
|
||||||
stations.push({
|
newStations.push({
|
||||||
name: properties.name || "",
|
name: properties.name || "",
|
||||||
latitude: geometry.coordinates[1],
|
latitude: geometry.coordinates[1],
|
||||||
longitude: geometry.coordinates[0],
|
longitude: geometry.coordinates[0],
|
||||||
});
|
});
|
||||||
} else if (properties.featureType === "route") {
|
} else if (properties.featureType === "route") {
|
||||||
routes.push({
|
newRoutes.push({
|
||||||
route_number: properties.name || "",
|
route_number: properties.name || "",
|
||||||
path: geometry.coordinates,
|
path: geometry.coordinates,
|
||||||
});
|
});
|
||||||
} else if (properties.featureType === "sight") {
|
} else if (properties.featureType === "sight") {
|
||||||
sights.push({
|
newSights.push({
|
||||||
name: properties.name || "",
|
name: properties.name || "",
|
||||||
description: properties.description || "",
|
description: properties.description || "",
|
||||||
latitude: geometry.coordinates[1],
|
latitude: geometry.coordinates[1],
|
||||||
@ -126,16 +205,54 @@ class MapStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
for (const station of stations) {
|
const requests: Promise<any>[] = [];
|
||||||
await languageInstance("ru").post("/station", station);
|
|
||||||
|
console.log(
|
||||||
|
`К созданию: ${newStations.length} станций, ${newRoutes.length} маршрутов, ${newSights.length} достопримечательностей.`
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`К обновлению: ${updatedStations.length} станций, ${updatedRoutes.length} маршрутов, ${updatedSights.length} достопримечательностей.`
|
||||||
|
);
|
||||||
|
|
||||||
|
newStations.forEach((data) =>
|
||||||
|
requests.push(languageInstance("ru").post("/station", data))
|
||||||
|
);
|
||||||
|
newRoutes.forEach((data) =>
|
||||||
|
requests.push(languageInstance("ru").post("/route", data))
|
||||||
|
);
|
||||||
|
newSights.forEach((data) =>
|
||||||
|
requests.push(languageInstance("ru").post("/sight", data))
|
||||||
|
);
|
||||||
|
|
||||||
|
updatedStations.forEach(({ id, ...data }) =>
|
||||||
|
requests.push(languageInstance("ru").patch(`/station/${id}`, data))
|
||||||
|
);
|
||||||
|
updatedRoutes.forEach(({ id, ...data }) =>
|
||||||
|
requests.push(languageInstance("ru").patch(`/route/${id}`, data))
|
||||||
|
);
|
||||||
|
updatedSights.forEach(({ id, ...data }) =>
|
||||||
|
requests.push(languageInstance("ru").patch(`/sight/${id}`, data))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (requests.length === 0) {
|
||||||
|
console.log("Нет изменений для сохранения.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for (const route of routes) {
|
|
||||||
await languageInstance("ru").post("/route", route);
|
try {
|
||||||
}
|
await Promise.all(requests);
|
||||||
for (const sight of sights) {
|
console.log("Все изменения успешно сохранены!");
|
||||||
await languageInstance("ru").post("/sight", sight);
|
|
||||||
|
await Promise.all([
|
||||||
|
this.getRoutes(),
|
||||||
|
this.getStations(),
|
||||||
|
this.getSights(),
|
||||||
|
]);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Ошибка при сохранении данных:", error);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user