Geographic Information Systems Asked by she_weeds on January 18, 2021
I’ve been using QGIS’ wonderful geometry generator to dynamically generate root protection zones and crown areas for some tree inventories I’ve been working on. It’s been a massive time saver.
Unfortunately our clients usually insist on CAD drawings for tree plans, and the robust DXF export in QGIS does not support this level of symbology. Neither does OGR2OGR from what I can gather?
I’m still new to GIS, and our workflow is such that I’m not yet confident migrating our data to PostGIS and using ST_MakeLine etc. to dynamically generate geometries.
Are there any other quick alternatives to dynamically generating geometry, which can be successfully exported to DXF?
(or is there a way to export this sort of styling to DXF?)
Just as a reference, here’s what I’ve been using to generate the geometries from the tree points. RPZ and N/E/S/W are fields in the data, in meters.
RPZ (Red):
Radius line:
make_line(
$geometry,
make_point($x + "RPZ"*cos(radians(45)), $y - ("RPZ"*sin(radians(45))))
)
(2019 update: The above doesn’t work for multipoint geometries; you need to convert them to single parts by getting a centroid of the buffer like so:)
make_line(
centroid(buffer($geometry,0.1)),
make_point($x + "rpz"*cos(radians(45)), $y - ("rpz"*sin(radians(45)))))
Circle:
buffer($geometry,"RPZ")
Crown area (blue):
make_polygon(make_line(
translate($geometry,0,max("N",0.2)),
translate($geometry,0.6*max("E",0.2),0.6*max("N",0.2)),
translate($geometry,max("E",0.2),0),
translate($geometry,0.6*max("E",0.2),-0.6*max("S",0.2)),
translate($geometry,0,-max("S",0.2)),
translate($geometry,-0.6*max("W",0.2),-0.6*max("S",0.2)),
translate($geometry,-max("W",0.2),0),
translate($geometry,-0.6*max("W",0.2),0.6*max("N",0.2)),
translate($geometry,0,max("N",0.2))))
And the current output looks like this (pretty fugly crown area, I know 🙂 – are splines even an option?)
I'm not sure which update of QGIS 2.x and 3.x changed it, but as of 2018 November and probably earlier, geometry generator symbology styling does get exported with the native QGIS dxf exporter. Generated polygon geometries styled with outline only will be exported as polylines; albeit with many vertices still.
So all of the below is no longer necessary.
Answering my own question: I found a way to generate the above-mentioned layers dynamically using Virtual Layers, which don't even require your source data to be in a database. Essentially I translated the above into Spatialite syntax the best I could.
I have tested this with spatialite, shapefiles, even xlsx source data. I believe this solution also gets around the apparent limitation that Spatialite itself does not allow views of a different geometry type from the original table?
Go to Layer > Add Layer > Add/Edit Virtual Layer, the above dialog box should appear. Give your layer an appropriate name.
Import the tree data layer
Use one of the following queries, adapted to your field names, with whatever other fields you want to SELECT (e.g. treeid, rpz_m in this case), and any filters (WHERE ...) These are what I've used:
RPZ (circle polygon)
SELECT treeid, rpz_m,
st_buffer(geometry,rpz_m) AS geometry
FROM table_name;
RPZ (line) - note I've put the line as a separate layer as it makes labeling much easier, also so you can optionally export just the circle as a polygon
SELECT treeid, rpz_m,
Make_Line(geometry,translate(geometry,
rpz_m*cos(radians(45)), rpz_m*-1*sin(radians(45)))) AS geometry
FROM layer_name;
RPZ (circle outline + line)
SELECT treeid, rpz_m,
ST_Union(makeline(geometry,translate(geometry,
rpz_m*cos(radians(45)), rpz_m*-1*sin(radians(45)))),
ST_ExteriorRing(ST_Buffer(geometry,rpz_m))) AS geometry
FROM layer_name;
Crown Area (polygon) - exports even crown spread as a circle (CASE WHEN...), otherwise (ELSE) as a polygon
SELECT treeid, n, e, s, w,
CASE WHEN n = s AND n = e AND n = w THEN ST_Buffer(geometry,n)
ELSE Make_Polygon(Make_Line(
translate(geometry,0,n),translate(geometry,0.6*e,0.6*n),
translate(geometry,e,0),translate(geometry,0.6*e,-0.6*s),
translate(geometry,0,-s),translate(geometry,-0.6*w,-0.6*s),
translate(geometry,-w,0),translate(geometry,-0.6*w,0.6*n),
translate(geometry,0,n))) END
AS geometry
FROM layer_name WHERE n != 0;
Crown Area (convex hull polygon - not in original post but expanded on here, refer to link for accuracy limitations) (as above, exports even crown spread as a circle)
SELECT n, e, s, w,
CASE WHEN n = s AND n = e AND n = w THEN st_buffer(geometry,n)
ELSE st_convexhull(
st_union(st_buffer(translate(geometry, -(case when w=0 then 0.1 else w/2.0 end),0),case when w=0 then 0.1 else w/2.0 end),
st_union(st_buffer(translate(geometry,case when e=0 then 0.1 else e/2.0
end,0),case when e=0 then 0.1 else e/2.0 end),
st_union(st_buffer(translate(geometry,0,case when n=0 then 0.1 else n/2.0
end),case when n=0 then 0.1 else n/2.0 end),
st_buffer(translate(geometry,0,-(case when s=0 then 0.1 else s/2.0 end)),case
when s=0 then 0.1 else s/2.0 end))))) END
AS geometry
FROM layer_name WHERE n is not null;
Edit (30 Dec 2017): Modified original code to include case function to convert any 0s to 0.1 (or whatever minimum number). Otherwise if you have a 0 value in any of the crown spread fields it will not work. At any rate, if you have a 0 in just one field the resultant polygon will not be accurate. (see link above). Note also division by 2.0, not 2, to avoid result being cast as an integer.
Of course, if you have trees with no crown spread data, make sure that the values are NULL instead of 0.
(Optional) You may wish to force the appropriate geometry just to be sure - especially if you do not include "AS geometry" in the above code, otherwise it might come out as a geometry collection that QGIS cannot style.
Test the code works, if it says No errors then load
Style the layers appropriately, add a label to the line.
Results (in AutoCAD): Purple = DXF export as polylines - note number of vertices on circles!
DXF export with rough polygons as hatch (see export limitations below)
SQL code notes:
DXF export limitations:
Correct answer by she_weeds on January 18, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP