我如何在typeorm和postgres中使用经度和纬度
我当前的实体如下所示:
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Landmark extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
longitude: number
@Column()
latitude: number
}
但我想知道是否有更好的方法来做到这一点,使用一种特殊的 postgres 类型,它适用于 typeorm。
回答
您将要查看 Typeorm 中的 PostGIS 和空间列支持:
https://github.com/typeorm/typeorm/blob/master/docs/entities.md#spatial-columns
PostGIS 是一个扩展,您可以在 postgres 数据库中启用它来处理空间数据类型。安装 PostGIS 后,您可以在 Typeorm 查询构建器中使用其特殊的空间数据函数,就像使用由 GeoJSON 支持的任何其他 PG 函数一样。
Typeorm 的 postgres 驱动程序在内部使用 GeoJSON 与 PostGIS 一起使用,因此当您定义 Typeorm 模型时,您需要添加@types/geojson,这将使您能够按照要求正确键入 Typeorm 列。
例如,您可以导入Geometry类型定义并输入您的列,如下所示:
import { Geometry } from 'geojson';
...
@Column
location: Geometry
在您的情况下,您可能希望将列latitude和longitude列合并为一列 -- location-- 可以使用该point()函数将纬度和经度合并为一个Geometry类型。
作为人为的示例,您可以执行以下操作:
UPDATE customers SET location = 'point(37.7, 122.4)' where id = 123;
这会将location您customers表上的列(作为示例)geometry(point)设置为与旧金山的纬度/经度位置相对应的列类型。
如果您想将 lat/lon 的现有双精度列值(这是您自己存储 lat/lon 的方式)迁移到locationtype的单个列geometry(point),您可以使用ST_MakePointPostGIS 自带的函数。
IE
-- Assuming you have a lat and lon columns on the `customers` table that you are migrating to the PostGIS geometry(point) type
UPDATE customers SET location = ST_MakePoint(lat, lon) where id = 123;
回答
扩展 JosephHall 答案
使用过 postgres、postgis、typeORM、@types/geojson、Nest JS
import { Column, Entity, Index, PrimaryGeneratedColumn} from 'typeorm';
import { Point } from 'geojson';
@Entity({ name: 't_test_location' })
export class TestLocation {
@PrimaryGeneratedColumn('increment')
pk_id: number;
@Column({ type: 'varchar', name: 's_city' })
city: string;
@Index({ spatial: true })
@Column({
type: 'geography',
spatialFeatureType: 'Point',
srid: 4326,
nullable: true,
})
location:Point
}
服务类
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { TestLocation } from 'src/model/testlocation.entity';
import { getManager, QueryBuilder, Repository } from 'typeorm';
import { Geometry, Point } from 'geojson';
@Injectable()
export class LocationService {
constructor(
@InjectRepository(TestLocation) private readonly repo: Repository<TestLocation>,
) {}
public async getAll() {
return await this.repo.find();
}
public async create(location:TestLocation){
const pointObject :Point= {
type: "Point",
coordinates: [location.long,location.lat]
};
location.location = pointObject;
return await this.repo.save(location)
}
控制器
import { Body, Controller, Get, Post } from '@nestjs/common';
import { TestLocation } from 'src/model/testlocation.entity';
import { LocationService } from './location.service';
@Controller('location')
export class LocationController {
constructor(private serv: LocationService) {}
@Get()
public async getAll() {
return await this.serv.getAll();
}
@Post()
createLocation(@Body() location : TestLocation): void{
this.serv.create(location);
}
}
- Why do you import `Geometry`? I don't see it used anywhere.