2

Let's say I have a Spatialite database filled with polygons. I've learned on this question that I can have as many geometry columns as I want in my database. So, I'd like to find a way of getting a result where I get the first pair of lat and long from the polygon in the line to generate a new geometry column of points... I'd need something like the following:

select (unknown query) as newgeometry,* from mydatabase

In this sample, (unknown query) would be a way of creating a geometry value of points from the first values of my geometry column of polygons. Is it possible to do on SpatiLite without an overcomplicated solution?

1 Answer 1

4

It can be done in two steps.

First, add a new geometry column to you table:

SELECT AddGeometryColumn('my_table', 'my_new_geom_column', 4326,  'POINT');

Remember to change in the previous query my dummy values with the those that fit for database schema. The 4326 value is the SRID of the new geometry column, and if you don't make reprojection it must match the value of your existing geometry column.

In the second step, populate the new column with the desired values:

UPDATE 'my_table' SET
    my_new_geom_column = ST_StartPoint(ST_ExteriorRing(ST_GeometryN(geom, 1)))
;

AFAIK Spatialite does not have a function to extract an specific vertex from a Polygon, but have it to extract vertex from LineString.

I'm using ST_ExteriorRing to get the "boundary" of the Polygon, a LineString and then ST_StartPoint to get the first point of the exterior ring. But you can use also ST_PointN(geom, vertex_number) (as @user30184 explains in the comments)

But as @raylight points in the comments if the geometry is a MultiPolygon with more than one geometry ST_ExteriorRing will return NULL. It seams that ST_ExteriorRing in Spatialite only works for simple geometries:

-- With the example data provided by the OP
SELECT
    ogc_fid
    , ST_GeometryType(geometry)
    , ST_NumGeometries(geometry)
    , ST_AsText(
        ST_StartPoint(ST_ExteriorRing(geometry))
    )
FROM sample
ORDER BY 3;

4529|MULTIPOLYGON|1|POINT(-46.739131 -23.578109)
981|MULTIPOLYGON|2|

One way to avoid this is always get the "first geometry" of the collection/MultiPolygon

SELECT
    ogc_fid
    , ST_GeometryType(geometry)
    , ST_NumGeometries(geometry)
    , ST_AsText(
        ST_StartPoint(ST_ExteriorRing(ST_GeometryN(geometry, 1)))
    )
FROM sample 
ORDER BY 3;

4529|MULTIPOLYGON|1|POINT(-46.739131 -23.578109)
981|MULTIPOLYGON|2|POINT(-46.638364 -23.555674)

I'm not sure if there are more corner cases, where this approach does not really extract the first vertex of the Polygon.

5
  • 1
    I think that you are doing the right thing by considering that a polygons starts from its exterior ring. Same result than with ST_Start_Point could be achieved also with PointN(ExteriorRing(geom),1).
    – user30184
    Commented Jun 29, 2021 at 7:44
  • @FranciscoPuga After working with it for a while I've realized some edge cases in this SpatiaLite dataset, sometimes it doesn't identify the first value of a polygon and it returns NULL. In this dataset it happens on different lines like the 95, 615, 981, 1135 lines. I'm not sure what's happening wrong in it. I've tested with the alternative PointN(ExteriorRing(geom),1) and it generates most of the values as well but the NULL values remain in the same lines. Do you have any idea of what could be causing it?
    – raylight
    Commented Jun 30, 2021 at 4:16
  • Just found out that some of the polygons on my dataset are actually multipolygons... The NULL values happen on the lines where I have multiple polygons in a single geometry line.
    – raylight
    Commented Jun 30, 2021 at 4:31
  • 1
    @raylight check my update. If you want to get the first vertex for each geometry in a multipolygon ST_Dump should be used instead of ST_GeometryN Commented Jun 30, 2021 at 6:55
  • Thanks, it's working perfectly now.
    – raylight
    Commented Jun 30, 2021 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.