stable: finalized GIS aesthetics and Syria/Jordan routing synchronization

This commit is contained in:
Hamza-Ayed
2026-03-28 04:12:01 +03:00
parent d6f3b41b53
commit 592af8ce5c
203 changed files with 9711 additions and 119 deletions
@@ -0,0 +1,56 @@
import { Injectable, OnModuleInit, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PlaceSyria } from './entities/place-syria.entity';
@Injectable()
export class GeocodingInitService implements OnModuleInit {
private readonly logger = new Logger(GeocodingInitService.name);
constructor(
@InjectRepository(PlaceSyria)
private readonly repo: Repository<PlaceSyria>,
) {}
async onModuleInit() {
this.logger.log('Checking for PostGIS extensions and triggers...');
try {
// Ensure PostGIS and Trigram extensions are enabled
await this.repo.query('CREATE EXTENSION IF NOT EXISTS postgis;');
await this.repo.query('CREATE EXTENSION IF NOT EXISTS pg_trgm;');
// Cleanup: Create a trigger to automatically update 'location' when lat/lng changes
await this.repo.query(`
CREATE OR REPLACE FUNCTION sync_place_location() RETURNS trigger AS $$
BEGIN
IF NEW.latitude IS NOT NULL AND NEW.longitude IS NOT NULL THEN
NEW.location := ST_SetSRID(ST_MakePoint(CAST(NEW.longitude AS FLOAT), CAST(NEW.latitude AS FLOAT)), 4326);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`);
await this.repo.query(`
DROP TRIGGER IF EXISTS trg_sync_place_location ON places_syria;
CREATE TRIGGER trg_sync_place_location
BEFORE INSERT OR UPDATE ON places_syria
FOR EACH ROW EXECUTE FUNCTION sync_place_location();
`);
// 1. GIST Geometry Indexes (for fast proximity search)
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_places_syria_location ON places_syria USING gist (location);');
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_osm_areas_geom ON osm_areas USING gist (geom);');
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_osm_points_geom ON osm_points_with_area USING gist (geom);');
// 2. GIST Trigram Indexes (for fast fuzzy name search and low server load)
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_places_syria_names_trgm ON places_syria USING gist (name_ar gist_trgm_ops, name_en gist_trgm_ops);');
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_osm_areas_names_trgm ON osm_areas USING gist (name_ar gist_trgm_ops);');
await this.repo.query('CREATE INDEX IF NOT EXISTS idx_osm_points_names_trgm ON osm_points_with_area USING gist (name_ar gist_trgm_ops, name_en gist_trgm_ops);');
this.logger.log('Geocoding database triggers and optimized indexes initialized.');
} catch (err) {
this.logger.error('Failed to initialize database geocoding triggers:', err);
}
}
}