2

I'm looking for the best way to plot ship outlines to the correct size in QGIS.

I have a series of GPS positions inserted as points and I know the dimensions of the ship relative to the location of the antenna on the ship (i.e. 100 metres to the bow, 20 metres to stern, 5 metres to port and 5 metres to starboard).

The problem I'm having is that even if I use a simple square box as a marker when I measure the dimensions of the box using the measure tool the box is not the correct size, and as such I cant say that the position of the vessel outline relative to a feature (a dock wall or shallow) is correct.

I understand that this is most likely due to the map projections but is there a way of drawing a marker of the correct size to represent a ship?

Duncan
  • 21
  • 1

1 Answers1

1
  1. You should select a CRS that is apt for measurements and reproject your points to this CRS. I don't know what your area of interest is, so as a general rule, use the local UTM zone. For this exercise, let's say our ship is near the eastern coast of Sicily, thus we use UTM zone 33N, EPSG:6708. See here which UTM zone to use.

    If you have points distributed over the whole world, you need different CRS. See below how to deal with this.

  2. You need some value of the orientation of the ship, so in which direction it is going. Let's say each point contains an attribute azimuth: the angle from north of the line from the antenna to the bow. If you set this value to 0, the ship is heading towards north, 180 towards south etc.

  3. Use Geoemtry Generator (for visualization only) or Geometry by expression (for actual geometries; see here for differences between both options) with this expression:

     make_polygon( make_line (
         project ($geometry, 100, radians(azimuth)),
         project ($geometry, 5, radians(azimuth-90)),
         project ($geometry, 20, radians(azimuth-180)),
         project ($geometry, 5, radians(azimuth+90))
     ))
    

The expression in use with Geometry Generator; the labels indicate the azimuth value for each point: enter image description here


Using different local CRS

If you have points in different areas of the world, you need different CRS. In this case, leave your layer in (or reproject it to) EPSG:4326. We'll make the reprojection to local CRS inside the expresssion, using the function transform().

In this case, each point should have an attribute with the EPSG code for the CRS to be used - depending where on earth the point is located. I use an attribute called utm_zone with value 6708 (for areas east of Sicily) and 32755 (for areas east of Tasmania). Then use this expression which will automatically create correct dimensions for any place on earth (if you set the correct value for the local UTM zone of the point):

with_variable(
    'epsg',
    'EPSG:' || utm_zone,
transform (
    with_variable (
        'geom',
        transform ($geometry, 'EPSG:4326',@epsg),
    make_polygon( make_line (
        project (@geom, 100, radians(azimuth)),
        project (@geom, 5, radians(azimuth-90)),
        project (@geom, 20, radians(azimuth-180)),
        project (@geom, 5, radians(azimuth+90))
    ))),
    @epsg,'EPSG:4326'
))
Babel
  • 71,072
  • 14
  • 78
  • 208