I want to send GeoJSON polygon data into PostgresSQL by POST request.
Therefore, I have tried to receive Position[][] type and convert it into a Polygon type then send a POST request by Postman for API test but I got an error: "QueryFailedError: Unable to find 'coordinates' in GeoJSON string".
There are my codes:
Entity
import { Column, Entity, Index, PrimaryGeneratedColumn } from "typeorm";
import { Polygon } from "geojson";
@Entity({ name: 'parcels' })
export class Parcel {
@PrimaryGeneratedColumn('uuid')
id: string
@Index({ spatial: true })
@Column({
type: 'geography',
spatialFeatureType: 'Polygon',
srid:4326,
nullable: true
})
polygon: Polygon
}
Dto
import { IsOptional } from "class-validator";
import { Position } from "geojson";
export class CreateParcelPointDto {
@IsOptional()
position?: Position[][]
}
Controller
import { Body, Controller, Post } from '@nestjs/common';
import { CreateParcelPointDto } from './dto/create-parcel-point.dto';
import { Parcel } from './parcel.entity';
import { ParcelService } from './parcel.service';
@Controller('parcels')
export class ParcelController {
constructor(private parcelService: ParcelService) {}
@Post()
async createParcelPoint(
@Body()
createParcelPointDto: CreateParcelPointDto
): Promise<Parcel> {
return this.parcelService.createParcelPoint(createParcelPointDto)
}
}
Service
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Polygon } from 'geojson';
import { CreateParcelPointDto } from './dto/create-parcel-point.dto';
import { ParcelRepository } from './parcel.repository';
import { Parcel } from './parcel.entity';
@Injectable()
export class ParcelService {
constructor(
@InjectRepository(ParcelRepository)
private parcelRepository: ParcelRepository
) {}
async createParcelPoint(createParcelPointDto: CreateParcelPointDto): Promise<Parcel> {
const { position } = createParcelPointDto
const polygon: Polygon = {
type: 'Polygon',
coordinates: position
}
const parcel = this.parcelRepository.create({
polygon,
})
await this.parcelRepository.save(parcel)
return parcel
}
}
POST request JSON
{
"polygon" : [
[ 102.016680916961207, 14.876721809875564 ],
[ 102.016926580451127, 14.876676829236565 ],
[ 102.016936960598585, 14.876688939408604 ],
[ 102.017125533277465, 14.876656068941644 ],
[ 102.017130723351187, 14.876638768695875 ],
[ 102.017360816619913, 14.876598978130607 ],
[ 102.017243174948689, 14.87595713901259 ],
[ 102.017000971507926, 14.876002119651588 ],
[ 102.016994051409625, 14.875983089381243 ],
[ 102.016789908509551, 14.876022879946511 ],
[ 102.016786448460394, 14.876047100290586 ],
[ 102.016559815240825, 14.876090350905008 ],
[ 102.016680916961207, 14.876721809875564 ]
],
}
I don't know how to handle GeoJSON type into typeorm by POST request. If anyone has some solution please help me.
I had solved the problem. In this case, you need to define the type in Dto as the number. The dimension must be the same as the Position type and increase one more dimension in coordinates while you create a Polygon object.
For example, a Polygon type is needed to receive coordinate in Position[][]. Therefore, You need to define polygon as type number[][] in Dto and define coordinates as [polygon] while you create Polygon objects.
Code example :
Dto
import { IsOptional } from "class-validator";
export class CreateParcelPointDto {
@IsOptional()
polygon?: number[][]
}
Service
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Polygon } from 'geojson';
import { CreateParcelPointDto } from './dto/create-parcel-point.dto';
import { ParcelRepository } from './parcel.repository';
import { Parcel } from './parcel.entity';
@Injectable()
export class ParcelService {
constructor(
@InjectRepository(ParcelRepository)
private parcelRepository: ParcelRepository
) {}
async createParcelPoint(createParcelPointDto: CreateParcelPointDto): Promise<Parcel> {
const {
polygon,
} = createParcelPointDto
const polygonCreated: Polygon = {
type: 'Polygon',
coordinates: [polygon] //Need one more dimension here.
}
const parcel = this.parcelRepository.create({
polygon: polygonCreated,
})
await this.parcelRepository.save(parcel)
return parcel
}
}