moving features: write to sqlite modified features
This commit is contained in:
BIN
server/ems.db
BIN
server/ems.db
Binary file not shown.
8
server/src/gis/dto/update-features-batch.ts
Normal file
8
server/src/gis/dto/update-features-batch.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsArray } from "class-validator";
|
||||
|
||||
export class UpdateFeaturesBatchDto {
|
||||
@ApiProperty()
|
||||
@IsArray()
|
||||
features: any[]
|
||||
}
|
||||
@ -2,6 +2,7 @@ import { Body, Controller, Get, Param, ParseIntPipe, Post, Query } from '@nestjs
|
||||
import { GisService } from './gis.service';
|
||||
import { ApiBody } from '@nestjs/swagger';
|
||||
import { BoundsRequestDto } from './dto/bound';
|
||||
import { UpdateFeaturesBatchDto } from './dto/update-features-batch';
|
||||
|
||||
@Controller('gis')
|
||||
export class GisController {
|
||||
@ -22,6 +23,11 @@ export class GisController {
|
||||
return await this.gisService.getBoundsByEntityTypeAndId(entity_type, entity_id)
|
||||
}
|
||||
|
||||
@Post('/features/update')
|
||||
async updateFeaturesBatch(@Body() updateFeaturesBatch: UpdateFeaturesBatchDto) {
|
||||
return await this.gisService.updateFeaturesBatch(updateFeaturesBatch.features)
|
||||
}
|
||||
|
||||
@Post('/bounds/:entity_type')
|
||||
@ApiBody({ type: BoundsRequestDto })
|
||||
async getBoundsByEntityTypeAndList(
|
||||
|
||||
@ -119,26 +119,108 @@ export class GisService {
|
||||
return result
|
||||
}
|
||||
|
||||
// async getFigures(offset: number, limit: number, year: number, city_id: number): Promise<any[]> {
|
||||
// const result = await this.emsDataSource.query(`
|
||||
// SELECT o.*, f.[figure_type_id], f.[left], f.[top], f.[width], f.[height], f.[angle], f.[points], f.[label_left], f.[label_top], f.[label_angle], f.[label_size] FROM New_Gis..figures f
|
||||
// JOIN nGeneral..vObjects o ON o.object_id = f.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<any[]> {
|
||||
// const result = await this.emsDataSource.query(
|
||||
// `
|
||||
// SELECT o.[object_id], o.[id_city], o.[id_parent], o.[type], o.[planning], o.[activity], o.[kvr], o.[jur], o.[fuel], o.[boiler_id],
|
||||
// l.[x1], l.[y1], l.[x2], l.[y2], l.[points], l.[label_offset], l.[group_id], l.[show_label], l.[forced_lengths], l.[label_sizes], l.[label_angles], l.[label_positions], l.[year]
|
||||
// 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 getFigures(offset: number, limit: number, year: number, city_id: number): Promise<any[]> {
|
||||
const result = await this.emsDataSource.query(`
|
||||
SELECT o.*, f.[figure_type_id], f.[left], f.[top], f.[width], f.[height], f.[angle], f.[points], f.[label_left], f.[label_top], f.[label_angle], f.[label_size] FROM New_Gis..figures f
|
||||
JOIN nGeneral..vObjects o ON o.object_id = f.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
|
||||
// Get original figures from EMS
|
||||
const originalFigures = await this.emsDataSource.query(`
|
||||
SELECT o.[object_id], o.[id_city], o.[id_parent], o.[type], o.[planning], o.[activity], o.[kvr], o.[jur], o.[fuel], o.[boiler_id], f.[figure_type_id], f.[left], f.[top], f.[width], f.[height], f.[angle], f.[points], f.[label_left], f.[label_top], f.[label_angle], f.[label_size], f.[year] FROM New_Gis..figures f
|
||||
JOIN nGeneral..vObjects o ON o.object_id = f.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;
|
||||
`)
|
||||
|
||||
// Get modified figures from SQLite for the same year
|
||||
const modifiedFigures = await this.dataSource.query(
|
||||
`SELECT * FROM figures WHERE year = ?`,
|
||||
[year]
|
||||
)
|
||||
|
||||
// Create a lookup map using object_id + year as key
|
||||
const modifiedMap = new Map()
|
||||
modifiedFigures.forEach(fig => {
|
||||
const key = `${fig.object_id}_${fig.year}`
|
||||
modifiedMap.set(key, fig)
|
||||
})
|
||||
|
||||
// Replace original values with modified ones
|
||||
const mergedResult = originalFigures.map(original => {
|
||||
const key = `${original.object_id}_${year}`
|
||||
const modified = modifiedMap.get(key)
|
||||
|
||||
if (modified) {
|
||||
return {
|
||||
...original,
|
||||
modified: modified.feature
|
||||
}
|
||||
}
|
||||
|
||||
return original
|
||||
})
|
||||
|
||||
return mergedResult
|
||||
}
|
||||
|
||||
async getLines(year: number, city_id: number): Promise<any[]> {
|
||||
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};
|
||||
`
|
||||
// Get original lines from EMS
|
||||
const originalLines = await this.emsDataSource.query(`
|
||||
SELECT o.[object_id], o.[id_city], o.[id_parent], o.[type], o.[planning], o.[activity], o.[kvr], o.[jur], o.[fuel], o.[boiler_id],
|
||||
l.[x1], l.[y1], l.[x2], l.[y2], l.[points], l.[label_offset], l.[group_id], l.[show_label], l.[forced_lengths], l.[label_sizes], l.[label_angles], l.[label_positions], l.[year]
|
||||
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};
|
||||
`)
|
||||
|
||||
// Get modified lines from SQLite for the same year
|
||||
const modifiedLines = await this.dataSource.query(
|
||||
`SELECT * FROM lines WHERE year = ?`,
|
||||
[year]
|
||||
)
|
||||
|
||||
return result
|
||||
// Create lookup map with object_id + year
|
||||
const modifiedMap = new Map()
|
||||
modifiedLines.forEach(line => {
|
||||
const key = `${line.object_id}_${line.year}`
|
||||
modifiedMap.set(key, line)
|
||||
})
|
||||
|
||||
// Replace original with modified
|
||||
const mergedResult = originalLines.map(original => {
|
||||
const key = `${original.object_id}_${year}`
|
||||
const modified = modifiedMap.get(key)
|
||||
|
||||
if (modified) {
|
||||
return {
|
||||
...original,
|
||||
modified: modified.feature
|
||||
}
|
||||
}
|
||||
|
||||
return original
|
||||
})
|
||||
|
||||
return mergedResult
|
||||
}
|
||||
|
||||
async getRegionBorders(): Promise<any[]> {
|
||||
@ -150,4 +232,63 @@ export class GisService {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async updateFeaturesBatch(features: any[]) {
|
||||
let figures: any[] = []
|
||||
let lines: any[] = []
|
||||
|
||||
features.map(feature => {
|
||||
if (feature.type === 'figure') {
|
||||
figures.push(feature)
|
||||
} else if (feature.type === 'line') {
|
||||
lines.push(feature)
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Figures to update:', figures.length)
|
||||
console.log('Lines to update:', lines.length)
|
||||
|
||||
// Update figures
|
||||
if (figures.length > 0) {
|
||||
const figurePlaceholders = figures.map(() =>
|
||||
`(?, ?, ?)`
|
||||
).join(', ')
|
||||
|
||||
const figureParams = figures.flatMap(fig => [
|
||||
fig.object_id,
|
||||
fig.year, // Default year if not provided
|
||||
JSON.stringify(fig.feature)
|
||||
])
|
||||
|
||||
await this.dataSource.query(`
|
||||
INSERT OR REPLACE INTO figures
|
||||
(object_id, year, feature)
|
||||
VALUES ${figurePlaceholders}
|
||||
`, figureParams)
|
||||
}
|
||||
|
||||
// Update lines
|
||||
if (lines.length > 0) {
|
||||
const linePlaceholders = lines.map(() =>
|
||||
`(?, ?, ?)`
|
||||
).join(', ')
|
||||
|
||||
const lineParams = lines.flatMap(line => [
|
||||
line.object_id,
|
||||
line.year,
|
||||
JSON.stringify(line.feature)
|
||||
])
|
||||
|
||||
await this.dataSource.query(`
|
||||
INSERT OR REPLACE INTO lines
|
||||
(object_id, year, feature)
|
||||
VALUES ${linePlaceholders}
|
||||
`, lineParams)
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Updated ${figures.length} figures and ${lines.length} lines`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,12 +2,14 @@ import { NestFactory } from '@nestjs/core';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
import { AppModule } from './app.module';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { json } from 'express';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
cors: true
|
||||
});
|
||||
app.enableCors()
|
||||
app.use(json({ limit: '50mb' }))
|
||||
app.useGlobalPipes(new ValidationPipe({ transform: true }))
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('Fuel API')
|
||||
|
||||
Reference in New Issue
Block a user