2026-04-14-2 full

This commit is contained in:
Hamza-Ayed
2026-04-14 13:28:19 +03:00
parent 581eda1ea8
commit 830b498485
8 changed files with 138 additions and 83 deletions
+38 -14
View File
@@ -81,11 +81,9 @@ export class GeocodingService {
LEFT JOIN neighborhood_polygons n ON p.neighborhood_id = n.id
LEFT JOIN admin_boundaries d ON p.sub_district_id = d.id
LEFT JOIN admin_boundaries g ON p.governorate_id = g.id
WHERE (p.name_ar % $1 OR p.name % $1 OR p.neighbourhood % $1 OR p.name_ar ILIKE $4 OR p.name ILIKE $4 OR p.neighbourhood ILIKE $4)
${hasLocation ? `AND (p.location && ST_Expand(ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326), $5::float) OR ST_DistanceSphere(p.location, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) <= $6::float)` : ''}
ORDER BY relevance DESC, distance ASC LIMIT 15
ORDER BY relevance DESC, distance ASC LIMIT 25
`;
const results = await repo.query(userQuery, [cleanQuery, lat || null, lon || null, ILikeQuery, radiusInDegrees, radius]);
const results = await repo.query(userQuery, [cleanQuery, lat || null, lon || null]);
allResults.push(...results);
}
@@ -95,17 +93,33 @@ export class GeocodingService {
else if (targetRegion === 'egypt') osmBoundFilter = 'AND ST_Contains(ST_MakeEnvelope(24.5, 22.0, 37.0, 31.8, 4326), geom)';
const osmQuery = `
SELECT osm_id as id, name, name_ar, name_en, COALESCE(amenity, shop, 'place') as category,
latitude, longitude, addr_street as address, 'osm_global' as source,
CASE WHEN $2::float IS NOT NULL THEN ST_DistanceSphere(geom, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) ELSE 0 END as distance,
similarity(COALESCE(name_ar, ''), $1) + similarity(COALESCE(name_en, ''), $1) as relevance
FROM osm_points_with_area
WHERE (name_ar % $1 OR name_en % $1 OR name % $1 OR name_ar ILIKE $4 OR name_en ILIKE $4)
${osmBoundFilter}
${hasLocation ? `AND (geom && ST_Expand(ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326), $5::float) OR ST_DistanceSphere(geom, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) <= $6::float)` : ''}
ORDER BY relevance DESC, distance ASC LIMIT 20
SELECT
o.osm_id as id, o.name, o.name_ar, o.name_en, COALESCE(o.amenity, o.shop, 'place') as category,
o.latitude, o.longitude, o.addr_street as address, 'osm_global' as source,
n.name_ar as neighbourhood,
d.name_ar as district,
g.name_ar as governorate,
CASE WHEN $2::float IS NOT NULL THEN ST_DistanceSphere(o.geom, ST_SetSRID(ST_MakePoint($3::float, $2::float), 4326)) ELSE 0 END as distance,
similarity(COALESCE(o.name_ar, ''), $1) + similarity(COALESCE(o.name_en, ''), $1) as relevance
FROM osm_points_with_area o
LEFT JOIN LATERAL (
SELECT name_ar FROM neighborhood_polygons np
ORDER BY o.geom <-> np.geometry
LIMIT 1
) n ON true
LEFT JOIN LATERAL (
SELECT name_ar FROM admin_boundaries ab
WHERE ab.admin_level = 8 AND ST_Contains(ab.geom, o.geom)
LIMIT 1
) d ON true
LEFT JOIN LATERAL (
SELECT name_ar FROM admin_boundaries ab
WHERE ab.admin_level = 4 AND ST_Contains(ab.geom, o.geom)
LIMIT 1
) g ON true
ORDER BY relevance DESC, distance ASC LIMIT 30
`;
const osmResults = await this.osmPointsRepository.query(osmQuery, [cleanQuery, lat || null, lon || null, ILikeQuery, radiusInDegrees, radius]);
const osmResults = await this.osmPointsRepository.query(osmQuery, [cleanQuery, lat || null, lon || null]);
allResults.push(...osmResults);
// Note: We removed the raw query to 'overture_building' because raw overture tables
@@ -113,8 +127,18 @@ export class GeocodingService {
// scanning them with ILIKE without trigram indices causes a 2-second latency spike.
// Overture data is already properly ingested via the Scraper into places_jordan.
const seenStreets = new Set<string>();
const sortedResults = allResults
.sort((a, b) => hasLocation ? ((a.distance - b.distance) || (b.relevance - a.relevance)) : ((b.relevance - a.relevance) || (a.distance - b.distance)))
.filter(r => {
if (r.category === 'street') {
const key = `${r.name_ar || r.name}_${r.district}_${r.governorate}`;
if (seenStreets.has(key)) return false;
seenStreets.add(key);
}
return true;
})
.slice(0, 25)
.map(r => {
// Build full administrative address from admin_boundaries