1

I have three polygon features of the same category in a larger vector layer from which I would like to create a center point (mean coordinate) that holds the same attributes as the three polygons. I would then like to delete the original polygon features and replace them with the new point in the larger vector layer.

Running the below commands finds me the center point, which, following the answer by Micha, can be connected to the attribute table of the polygons to hold the same data. However, during these steps the character columns are redefined as text columns, making it so that it can't be patched with the original vector layer as 'Length of string columns differ'. I thus need a way to avoid this transformation, or a way to transform the column-types back again. I will look into this last point, which I assume can be done by defining a new table and copying over the data - although that sounds like it should have a better solution.

# First extract the three polygons that have cat 1
v.extract input=vector_layer cats=1 output=polygons

# Content of the attribute table
v.db.select polygons
cat|precision|method_con|measure_me|survey_yea|event|elev_minimum
1|3|tpDmg|gnss|2017||101.230186462402

# With corresponding column names and types
v.info -c polygons
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|precision
CHARACTER|method_con
CHARACTER|measure_me
INTEGER|survey_yea
CHARACTER|event
DOUBLE PRECISION|elev_minimum

# Then find the center points of the individual polygons 
v.centerpoint input=polygons output=poly_center

# These automatically hold an identical attribute table as the polygons
v.info -c poly_center
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|precision
CHARACTER|method_con
CHARACTER|measure_me
INTEGER|survey_yea
CHARACTER|event
DOUBLE PRECISION|elev_minimum

v.db.select poly_center
cat|precision|method_con|measure_me|survey_yea|event|elev_minimum
1|3|tpDmg|gnss|2017||101.230186462402

# Then find the center point of the three polygon center points 
v.centerpoint input=poly_center output=centerpoint

# This point does not have an attribute table.
# Add attribute table and join with that of the poly_center points
v.db.addtable centerpoint
v.db.join centerpoint column=cat other_column=cat other_table=poly_center

# The data itself is the same
v.db.select centerpoint
cat|precision|method_con|measure_me|survey_yea|event|elev_minimum
1|3|tpDmg|gnss|2017||101.230186462402

# However, the 'character' columns (all of length 254)
# have been redefined as 'text' columns of length 1000.
v.info -c centerpoint
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|precision
TEXT|method_con
TEXT|measure_me
INTEGER|survey_yea
TEXT|event
DOUBLE PRECISION|elev_minimum

# Delete the three polygons from the larger vector layer
db.execute sql="DELETE FROM vector_layer WHERE cat = 1"

# Attempt to patch the centerpoint to the larger vector layer
v.patch -e input=vector_layer,centerpoint output=new_vect
ERROR:Length of string columns differ 

enter image description here

I am using GRASS GIS 7.6.1 on Windows 10. I am also open to a complete reworking of the steps taken, as they certainly might not be the best.

  • 1
    What is in the attribute table of centerpoint before the v.db.connect step? i.e. v.db.select centerpoint. Since the polygons have only 1 cat, the centerpoint should have a duplicate attrib table. – Micha Jul 27 at 17:04
  • Running v.db.select centerpoint before v.db.connect returns ERROR: Database connection not defined for layer <1> – humperderp Jul 28 at 8:55
1

After your comment, I double checked, and this is what I worked out. I start with a multipolygon multi with three areas and two attrib columns cat (value 1) and label (value "one").

# The initial multi_polygon    
GRASS 7.6.0 (WGS84):/tmp > v.info -t multi
nodes=3
points=0
lines=0
boundaries=3
centroids=3
areas=3
islands=3
primitives=6
map3d=0
GRASS 7.6.0 (WGS84):/tmp > v.info -c multi
Displaying column types/names for database connection of layer <1>:
INTEGER|cat
INTEGER|cat_
TEXT|label
# The attribute table has only one row
GRASS 7.6.0 (WGS84):/tmp > v.db.select multi
cat|cat_|label
1|1|One

# First extract centroids, and convert to points:
GRASS 7.6.0 (WGS8):/tmp > v.extract input=multi type=centroid out=multi_centroids
GRASS 7.6.0 (WGS84):/tmp > v.type input=multi_centroids from=centroid to=point out=multi_pts
# Three points but still only one attribute row:
GRASS 7.6.0 (WGS84):/tmp > v.db.select multi_pts
cat|cat_|label
1|1|One

# Now get the centerpoint from the centroid points of each area
GRASS 7.6.0 (WGS84):/tmp > v.centerpoint multi_pts output=center_point
Calculating center of gravity...
 100%
WARNING: No areas in input vector <multi_pts>
Building topology for vector map <center_point@tmp>...
Registering primitives...
# As you noted, there is no table attached, so create it:
GRASS 7.6.0 (WGS84):tmp > v.db.addtable center_point
WARNING: Values in column <cat> will be overwritten
Reading features...
 100%
Updating database...
 100%
1 categories read from vector map (layer 1)
1 categories read from vector map don't exist in selection from table
1 records updated/inserted (layer 1)

# And now join the multi_pts table to the center_point
GRASS 7.6.0 (WGS84):/tmp > v.db.join center_point column=cat other_column=cat other_table=multi_pts

# Check result:
GRASS 7.6.0 (WGS84):/media/sf_D_DRIVE/Deliverable/tmp > v.db.select center_point
cat|cat_|label
1|1|One

HTH

  • Thank you. This certainly brings me closer. However, I seem to have an issue with columns of type 'character' in the original attribute table being transformed to 'text' in the attribute table of the final center point. This makes the final patching of the two fail. I'll update my question with more details. – humperderp Jul 29 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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