Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spatial support for PostgreSQL using PostGIS #2423

Merged
merged 18 commits into from Jul 3, 2018
Merged

Conversation

mojodna
Copy link
Contributor

@mojodna mojodna commented Jun 28, 2018

This includes support for both geometry and geography columns as well as GiST indices (used when passing the spatial: true option). Client representations use GeoJSON (existing MySQL and MS SQL drivers use WKT (well-known text)) for compatibility with geospatial libraries such as Turf, JSTS, etc.

Fixes #370

This includes support for both geometry and geography columns as well as
GiST indices (used when passing the `spatial: true`). Client
representations use GeoJSON (existing MySQL and MS SQL drivers use WKT
(well-known text)) for compatibility with geospatial libraries such as
Turf, JSTS, etc.
@mojodna
Copy link
Contributor Author

mojodna commented Jun 28, 2018

@AlexMesser

@OKNoah
Copy link
Contributor

OKNoah commented Jun 29, 2018

@mojodna Thanks, I was just about to do this! I'm going to try add a test or function for orderBy based on distance from a certain input.

Specifying a feature type will pass it as a parameter to the underlying
spatial type, allowing PostGIS to validate that stored geometries match
expectations.

Specifying an SRID will do similarly, with the additional benefit of
allowing the coordinate system used for a geometry to be stored in order
to transform it into other coordinate systems.
This way, if transforms are applied to parameters, they only need to be
implemented in 1 place.
@mojodna
Copy link
Contributor Author

mojodna commented Jun 29, 2018

See mojodna#1 for more discussion on this.

@Column({ type: "geometry" })
@Index({ spatial: true })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it broke the build; some of the before/after hooks are now hanging. Is there a good way to diagnose this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it looks like introducing support for spatial indexes in Postgres is conflicts with tests that also execute in MySQL. I think I've just pushed a fix for this.

Since the order-by tests run for multiple database engines, including
Postgres-targeted spatial types will break other engines (or cause them
to hang on startup).
@@ -370,7 +384,7 @@ export class PostgresDriver implements Driver {
|| columnMetadata.type === "timestamp without time zone") {
return DateUtils.mixedDateToDate(value);

} else if (columnMetadata.type === "json" || columnMetadata.type === "jsonb") {
} else if (this.spatialTypes.concat(["json", "jsonb"]).indexOf(columnMetadata.type) >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previous one was better =)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

waits for Array.includes in TS...

Local style should be:

} else if (columnMetadata.type === "json" ||
           columnMetadata.type === "jsonb" ||
           this.spatialTypes.indexOf(columnMetadata.type) >= 0) {

Copy link
Member

@pleerock pleerock Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, thats fine as well, you can keep it. I simply don't like concat, I would either go with "local style" you wrote or ["json", "jsob", ... this.spatialTypes].indexOf() which looks much better than concat

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right, I always forget about spreads in this context.

@@ -39,7 +39,7 @@ services:

# postgres
postgres:
image: "postgres:9.6.1"
image: "mdillon/postgis:9.6"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess somebody else can easily create a PR for the feature with specific extension and put another docker image with that extension, but without gis let's say. So better solution would be to have a base postgres image with all modifications applied

Copy link
Contributor Author

@mojodna mojodna Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. mdillon/postgis is just postgres + PostGIS (pretty sure it doesn't include any other additional extensions). Is this worth punting on until someone else needs to add another extension? (We can add a note/apology here ;-)

Copy link
Member

@pleerock pleerock Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha yeah... I hope it won't be me 😆

@pleerock
Copy link
Member

pleerock commented Jul 2, 2018

wow, this is huge. This wasn't an easy thing to implement, how much time it took you to bring all this into TypeORM?)

Lets ask @AlexMesser if he can review it.

@mojodna
Copy link
Contributor Author

mojodna commented Jul 2, 2018

Thanks! I'm guessing ~8 hours (including getting familiar with TypeORM generally while on a plane) over the span of a week and a half..

@pleerock
Copy link
Member

pleerock commented Jul 2, 2018

You are the beast!

@AlexMesser
Copy link
Collaborator

Great work!
Also, please create documentation for SpatialColumnOptions and its usage.

@mojodna
Copy link
Contributor Author

mojodna commented Jul 3, 2018

@AlexMesser docs pushed.

@pleerock pleerock merged commit eece0c3 into typeorm:master Jul 3, 2018
@pleerock
Copy link
Member

pleerock commented Jul 3, 2018

Thank you very much! This will be published in 0.2.8 soon!

@RDeluxe
Copy link

RDeluxe commented Jul 3, 2018

Awesome work @mojodna , thanks again !

@htonkovac
Copy link

When can we expect 0.2.8 to be released?

@sublimator
Copy link

Yes please to 0.2.8!

@pleerock
Copy link
Member

pleerock commented Aug 4, 2018

we have a blocking issue with nativescript that is merged and prevent block releasing 0.2.8

@lorenzopicoli
Copy link

Any update on the 0.2.8 release @pleerock?

@lucashsilva
Copy link
Contributor

Looking forward for this

@Vincz
Copy link

Vincz commented Oct 5, 2018

Hi @pleerock , Any update about the next release ?

@hussainwali74
Copy link

I just want a simple example please:
how to insert lat-long point dataa into postgres, find distance between 2 points??

I have this column:

@Index({ spatial: true })
 @Column({
   type: 'geometry',
   srid: 4326,
   nullable: true,
   spatialFeatureType: 'Point',
   transformer: {
     to: (v: Point) => {
       console.log(v);
       console.log(JSON.stringify(v));
       return eval(
         `ST_GeomFromGeoJSON('{"type":"Point","coordinates":[39.807222,-76.984722]}')`,
       );
     },
     from: (v: any) => {
       return v;
     },
   },
 })
 current_location: string;


when I try to insert data:
"current_location": "{"type":"Point","coordinates":[39.807222,-76.984722]}",

it says ST_GeomFromGeoJSON is not defined. Please help

@mojodna
Copy link
Contributor Author

mojodna commented May 10, 2021

It looks like you don’t have the PostGIS extension installed. To enable it in a specific database, run create extension postgis directly from psql.

@hussainwali74
Copy link

hussainwali74 commented May 10, 2021

It looks like you don’t have the PostGIS extension installed. To enable it in a specific database, run create extension postgis directly from psql.

@mojodna sir,
I already have postgis installed, ST_GeomFromGeoJSON works in the psql cli
also here is the screenshot of SELECT postgis_full_version();
image

I am also able to run all these from within my nodejs code. (all the commented queries also work fine)

  async test() {
    // const query = `SELECT * FROM v`
    const query = `select St_AsGeoJson(current_location) from vehicle where vehicle_id=4;    `;
    // works => select ST_Distance(ST_GeometryFromText('POINT(0 0)',4326),current_location) from vehicle where vehicle_id=4;
    // SELECT ST_GeomFromGeoJSON('{"type":"Point","coordinates":[39.807222,-76.984722]}');
    // select ST_Distance(ST_GeometryFromText('POINT(32.333 1.233)',0), current_location::geometry) from vehicle;
    // select ST_Distance(ST_GeometryFromText('POINT(32.333 1.233)',4326),ST_GeometryFromtext('POINT(42.322 1.234)',4326));
    // const query = `SELECT ST_Distance (ST_GeomFromText('POINT(0 0'), ST_X(current_location))
    // FROM vehicle
    // GROUP BY type`;

    // INSERT INTO vehicle(base_location,current_location) VALUES
    // ( 'Islamabad',ST_GeomFromGeoJSON('{"type":"Point","coordinates":[28.612849, 77.229883]}'));
    try {
      return await this.vehicleRepository.query(query);
    } catch (error) {
      throw new HttpException(error, HttpStatus.NOT_IMPLEMENTED);
    }
  }

Only issue is when I try to insert data using typeorm, it gives me the error ST_GeoomFromText() is not a function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for PostGIS data types