How to create an outline of a ship given the geom of the GPS aerial, ship dimensions, true heading

I have a table of AIS positions for a vessel and its true heading. I also know the distance of the GPS aerial to the bow, and the starboard side, and the overall length and width of the ship.

I want to know how to take the known point and create a second point 200m in the direction of the true heading, create a third point at +90 degrees to the true heading at the length of the distance from the aerial to the starboard side, create 4th point at 180 degrees to the true heading at the distance of total length of the vessel, etc until I have the points for each corner of the vessel and then create a line string to join the points and create an outline of the vessel pointing in the direction of its true heading.

I want to use QGIS / PostGIS to solve this.

• – Ian Turton Jan 7 at 8:57
• You can use functions like sin, cos, ST_Rotate, ST_Azimuth and ST_Translate to do this. It is just basic trigonometry, after all. – John Powell Jan 7 at 11:59
• Have a go using these functions. Hint: it is easiest if you start from the point (0,0), create your various points at 90,180, etc degress, which will simply be offsets along the x and y axis, create a polygon from those, then use ST_Rotate and finally ST_Translate, if you actually want it in some location, rather than just the outline. – John Powell Jan 7 at 12:28

B Barton, take me a pilot to your ship, and I will properly carry out my duties and we will go on a harsh and long-distance march together and do not disturb the course of our ship. Then go ahead to the winds, waves and geographic adventures :-). Remember that there are many ways to solve your problem, and this is one of them in Postgres / PostGIS.

1) Run the script

```create table navy_pt1_2 as select ST_Translate (st_setsrid('Point(0.0 0.0)'::geometry, 4326) ,0.001275, 0.001275) as end_pt ,st_setsrid('Point(0.0 0.0)'::geometry, 4326) as start_pt```

the result is shown in Figure 1

I got the distance from the GPS antenna from the conditional Point (0.0 0.0) to a point at a distance of about 200 meters and about 45 degrees, through the legs of an equilateral right triangle, and in order to check this statement, run the scripts:

```select st_distance(geography(navy_pt1_2.start_pt),geography(navy_pt1_2.end_pt)) as dist from navy_pt1_2; select DEGREES(st_azimuth(geography(navy_pt1_2.start_pt),geography(navy_pt1_2.end_pt))) as azimut from navy_pt1_2; ```

2) Now, in order to get the contour points of the ship, run the following script:

```create table navy_pt1_0 as select (ST_Rotate ( ST_Translate ( st_setsrid((start_pt)::geometry, 4326) , 0.0002, 0.0002) , (0.0) * pi() / 180.0 ) ) as geom from navy_pt1_2;```

```create table navy_pt1_90 as select (ST_Rotate ( ST_Translate ( st_setsrid((start_pt)::geometry, 4326) , 0.0001, 0.0001) , (90.0) * pi() / 180.0 ) ) as geom from navy_pt1_2;```

```create table navy_pt1_180 as select (ST_Rotate ( ST_Translate ( st_setsrid((start_pt)::geometry, 4326) , 0.0002, 0.0002) , (180.0) * pi() / 180.0 ) ) as geom from navy_pt1_2;```

```create table navy_pt1_270 as select (ST_Rotate ( ST_Translate ( st_setsrid((start_pt)::geometry, 4326) , 0.0001, 0.0001) , (270.0) * pi() / 180.0 ) ) as geom from navy_pt1_2;```

Note that points will be created in a counterclockwise direction. The joint result is shown in Figure 2.

So now we have the initial data for creating map objects.

3) To create the outline of the ship, run the script:

```create table navy_all_pt as (select * from navy_pt1_0 union all select * from navy_pt1_90 union all select * from navy_pt1_180 union all select * from navy_pt1_270 union all select * from navy_pt1_0);```

(do not forget about strict order on our ship!, create points in strict sequence either clockwise or counterclockwise ...) and

```create table navy_reg as select st_makeline (geom) as geom from navy_all_pt; create table navy_dir as select st_makeline ((navy_pt1_2.start_pt),(navy_pt1_2.end_pt)) as geom from navy_pt1_2;```

The result, see figure 3.

From this point on, you can mark 1 lines and points at your own discretion and rotate and move the ship in any direction and direction, now sail the ship, sail ...

4) Now I have changed the ship's course.

```update navy_dir set geom= ST_Rotate ( st_setsrid((geom)::geometry, 4326) , (90.0) * pi() / 180.0 );```

see figure 4

and now the ship itself

```update navy_reg set geom= ST_Rotate ( st_setsrid((geom)::geometry, 4326) , (90.0) * pi() / 180.0 );```

see figure 5

Good swimming to you, and from you a bottle of Roma,: -) ...