import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; @Injectable() export class GisService { constructor( @InjectDataSource('sqliteConnection') private dataSource: DataSource, @InjectDataSource('emsConnection') private emsDataSource: DataSource ) { } async getTypeRoles(): Promise { const result = await this.emsDataSource.query(` SELECT * FROM New_Gis..TypeRoles; `) return result } async getBoundsByEntityType(entity_type: 'region' | 'district' | 'city'): Promise { const result = await this.dataSource.query(` SELECT entity_id, entity_type, geometry FROM bounds WHERE entity_type = $1 `, [entity_type]) if (Array.isArray(result)) { if (result.length > 0) { const geometries = result.map((bound: { id: string, entity_id: number, entity_type: string, geometry: string, published_at: string, deleted_at: string | null }) => { return { ...(JSON.parse(bound.geometry)), properties: { id: bound.id, entity_id: bound.entity_id, entity_type: bound.entity_type } } }) return geometries } else { throw new NotFoundException('not found') } } else { throw new NotFoundException('not found') } } async getBoundsByEntityTypeAndId(entity_type: 'region' | 'district' | 'city', entity_id: number): Promise { const result = await this.dataSource.query(` SELECT entity_id, entity_type, geometry FROM bounds WHERE entity_type = $1 AND entity_id = $2 `, [entity_type, entity_id]) if (Array.isArray(result)) { if (result.length > 0) { return JSON.parse(result[0].geometry) } else { throw new NotFoundException('not found') } } else { throw new NotFoundException('not found') } } async getBoundsByEntityTypeAndList( entity_type: 'region' | 'district' | 'city', list: number[], ): Promise { if (!list || list.length === 0) { throw new NotFoundException('No entity IDs provided'); } // Build placeholders (?, ?, ?) for SQLite IN clause const placeholders = list.map(() => '?').join(', '); const result = await this.dataSource.query( ` SELECT entity_id, entity_type, geometry FROM bounds WHERE entity_type = ? AND entity_id IN (${placeholders}) `, [entity_type, ...list], ); if (!Array.isArray(result) || result.length === 0) { throw new NotFoundException('Not found'); } return result.map( (bound: { id: string; entity_id: number; entity_type: string; geometry: string; published_at: string; deleted_at: string | null; }) => ({ ...(JSON.parse(bound.geometry)), properties: { id: bound.id, entity_id: bound.entity_id, entity_type: bound.entity_type, }, }), ); } async getImages(offset: number, limit: number, city_id: number): Promise { const result = await this.emsDataSource.query(` SELECT * FROM images ${city_id ? `WHERE city_id = ${city_id}` : ''} ORDER BY city_id OFFSET ${Number(offset) || 0} ROWS FETCH NEXT ${Number(limit) || 10} ROWS ONLY; `) return result } async getFigures(offset: number, limit: number, year: number, city_id: number): Promise { const result = await this.emsDataSource.query(` SELECT * FROM figures f JOIN nGeneral..vObjects o ON f.object_id = o.object_id WHERE o.id_city = ${city_id} AND f.year = ${year} ORDER BY f.year OFFSET ${Number(offset) || 0} ROWS FETCH NEXT ${Number(limit) || 10} ROWS ONLY; `) return result } async getLines(year: number, city_id: number): Promise { const result = await this.emsDataSource.query( ` SELECT * FROM New_Gis..lines l JOIN nGeneral..vObjects o ON l.object_id = o.object_id WHERE o.id_city = ${city_id} AND l.year = ${year}; ` ) return result } async getRegionBorders(): Promise { const result = await this.emsDataSource.query( ` SELECT * FROM New_Gis..visual_regions ` ) return result } }