stable: mapping v1.0 restored and verified
This commit is contained in:
@@ -11,10 +11,10 @@ export class PlaceSyria {
|
|||||||
@Column({ type: 'decimal', precision: 11, scale: 8, nullable: true })
|
@Column({ type: 'decimal', precision: 11, scale: 8, nullable: true })
|
||||||
longitude: number;
|
longitude: number;
|
||||||
|
|
||||||
@Column({ nullable: true, unique: true })
|
@Column({ nullable: true })
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@Column({ nullable: true, unique: true })
|
@Column({ nullable: true })
|
||||||
name_ar: string;
|
name_ar: string;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ export class GeocodingController {
|
|||||||
return this.geocodingService.addPlace(placeData);
|
return this.geocodingService.addPlace(placeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('upsert-place')
|
||||||
|
@ApiOperation({ summary: 'Add or Update a location (Automated Scraper)' })
|
||||||
|
async upsertPlace(@Body() placeData: any) {
|
||||||
|
return this.geocodingService.upsertPlace(placeData);
|
||||||
|
}
|
||||||
|
|
||||||
@Get('places')
|
@Get('places')
|
||||||
@ApiOperation({ summary: 'Get recent user submitted places' })
|
@ApiOperation({ summary: 'Get recent user submitted places' })
|
||||||
async getPlaces(@Query('limit') limit?: number) {
|
async getPlaces(@Query('limit') limit?: number) {
|
||||||
|
|||||||
@@ -191,6 +191,49 @@ export class GeocodingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async upsertPlace(data: Partial<PlaceSyria>) {
|
||||||
|
try {
|
||||||
|
if (!data.latitude || !data.longitude || (!data.name && !data.name_ar)) {
|
||||||
|
throw new HttpException('Missing required fields for upsert', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lng = Number(data.longitude);
|
||||||
|
const lat = Number(data.latitude);
|
||||||
|
|
||||||
|
// 1. Check for spatial match (within 10 meters)
|
||||||
|
const existingQuery = `
|
||||||
|
SELECT id FROM places_syria
|
||||||
|
WHERE ST_DistanceSphere(location, ST_SetSRID(ST_MakePoint($1, $2), 4326)) < 10
|
||||||
|
LIMIT 1
|
||||||
|
`;
|
||||||
|
const existing = await this.placesRepository.query(existingQuery, [lng, lat]);
|
||||||
|
|
||||||
|
if (existing && existing.length > 0) {
|
||||||
|
const id = existing[0].id;
|
||||||
|
this.logger.log(`Spatial match found for ${data.name || data.name_ar} (ID: ${id}). Updating...`);
|
||||||
|
|
||||||
|
await this.placesRepository.update(id, {
|
||||||
|
name: data.name || undefined,
|
||||||
|
name_ar: data.name_ar || undefined,
|
||||||
|
address: data.address || undefined,
|
||||||
|
category: data.category || undefined,
|
||||||
|
description: data.description || undefined,
|
||||||
|
city: data.city || undefined,
|
||||||
|
neighbourhood: data.neighbourhood || undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
return { id, action: 'updated' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. No matching place found, create new one
|
||||||
|
const result = await this.addPlace(data);
|
||||||
|
return { id: result.id, action: 'created' };
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error('Upsert failed:', error.message);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getRecentPlaces(limit: number = 50) {
|
async getRecentPlaces(limit: number = 50) {
|
||||||
try {
|
try {
|
||||||
return this.placesRepository.find({
|
return this.placesRepository.find({
|
||||||
|
|||||||
Reference in New Issue
Block a user