134 lines
5.9 KiB
JavaScript
134 lines
5.9 KiB
JavaScript
"use strict";
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
};
|
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
};
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.MapsService = void 0;
|
|
const common_1 = require("@nestjs/common");
|
|
const config_1 = require("@nestjs/config");
|
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
const typeorm_2 = require("typeorm");
|
|
const road_stat_entity_1 = require("./road-stat.entity");
|
|
const redis_service_1 = require("../common/redis.service");
|
|
const axios_1 = __importDefault(require("axios"));
|
|
let MapsService = class MapsService {
|
|
configService;
|
|
roadStatRepo;
|
|
dataSource;
|
|
redisService;
|
|
graphHopperUrl;
|
|
TRAFFIC_CACHE_KEY = 'traffic_snapshot';
|
|
constructor(configService, roadStatRepo, dataSource, redisService) {
|
|
this.configService = configService;
|
|
this.roadStatRepo = roadStatRepo;
|
|
this.dataSource = dataSource;
|
|
this.redisService = redisService;
|
|
this.graphHopperUrl = this.configService.get('GRAPH_HOPPER_URL', 'http://map-routing:8080');
|
|
}
|
|
async getRoute(from, to) {
|
|
const congestedSegments = await this.redisService.get(this.TRAFFIC_CACHE_KEY) || [];
|
|
const buffer = 0.05;
|
|
const minLat = Math.min(from[0], to[0]) - buffer;
|
|
const maxLat = Math.max(from[0], to[0]) + buffer;
|
|
const minLng = Math.min(from[1], to[1]) - buffer;
|
|
const maxLng = Math.max(from[1], to[1]) + buffer;
|
|
const nearbyCongestion = congestedSegments.filter(seg => {
|
|
const geom = JSON.parse(typeof seg.geojson === 'string' ? seg.geojson : JSON.stringify(seg.geojson));
|
|
return geom.coordinates.some(([lng, lat]) => lat >= minLat && lat <= maxLat && lng >= minLng && lng <= maxLng);
|
|
}).slice(0, 50);
|
|
const customModel = {
|
|
speed: [],
|
|
areas: {},
|
|
};
|
|
nearbyCongestion.forEach((seg, index) => {
|
|
const areaId = `cong_${index}`;
|
|
const geojson = typeof seg.geojson === 'string' ? JSON.parse(seg.geojson) : seg.geojson;
|
|
customModel.areas[areaId] = {
|
|
type: 'Feature',
|
|
geometry: geojson,
|
|
properties: {}
|
|
};
|
|
customModel.speed.push({
|
|
if: `in_${areaId}`,
|
|
multiply_by: Math.max(0.1, 1 / seg.congestionFactor)
|
|
});
|
|
});
|
|
try {
|
|
const params = {
|
|
point: [`${from[0]},${from[1]}`, `${to[0]},${to[1]}`],
|
|
profile: 'car',
|
|
locale: 'en',
|
|
calc_points: true,
|
|
points_encoded: true,
|
|
elevation: false,
|
|
type: 'json',
|
|
};
|
|
if (customModel.speed.length > 0) {
|
|
params.custom_model = JSON.stringify(customModel);
|
|
}
|
|
const response = await axios_1.default.get(`${this.graphHopperUrl}/route`, {
|
|
params,
|
|
paramsSerializer: (params) => {
|
|
const searchParams = new URLSearchParams();
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
if (Array.isArray(value)) {
|
|
value.forEach(v => searchParams.append(key, v));
|
|
}
|
|
else {
|
|
searchParams.append(key, value);
|
|
}
|
|
});
|
|
return searchParams.toString();
|
|
},
|
|
});
|
|
console.log('Routing Successful with congestion:', customModel.speed.length, 'segments');
|
|
const route = response.data.paths[0];
|
|
if (!route) {
|
|
throw new common_1.HttpException('No route found', common_1.HttpStatus.NOT_FOUND);
|
|
}
|
|
return {
|
|
distance: route.distance,
|
|
duration: route.time / 1000,
|
|
points: route.points,
|
|
bbox: route.bbox,
|
|
congestionAware: customModel.speed.length > 0,
|
|
};
|
|
}
|
|
catch (error) {
|
|
console.error('Routing Error:', error.message);
|
|
if (error.response) {
|
|
console.error('GraphHopper Response:', error.response.data);
|
|
}
|
|
throw new common_1.HttpException('Error calculating route', common_1.HttpStatus.BAD_GATEWAY);
|
|
}
|
|
}
|
|
async getMapConfig() {
|
|
return {
|
|
center: [31.95, 35.91],
|
|
zoom: 12,
|
|
tileServerUrl: this.configService.get('TILE_SERVER_URL', 'http://localhost:3001'),
|
|
};
|
|
}
|
|
};
|
|
exports.MapsService = MapsService;
|
|
exports.MapsService = MapsService = __decorate([
|
|
(0, common_1.Injectable)(),
|
|
__param(1, (0, typeorm_1.InjectRepository)(road_stat_entity_1.RoadSegmentStat)),
|
|
__metadata("design:paramtypes", [config_1.ConfigService,
|
|
typeorm_2.Repository,
|
|
typeorm_2.DataSource,
|
|
redis_service_1.RedisService])
|
|
], MapsService);
|
|
//# sourceMappingURL=maps.service.js.map
|