Feature request: save composer image as SVG

Hi Rich

A long time ago now, probably around 2 years, we were corresponding about your Biological Records Tools plugin as I was creating a load of dot maps for my Dad’s flora which he is writing for VCs 79 & 80. The gestation period is finally nearly over and we’re about to send the proofs to the publisher in the next few weeks. And that means I have to generate 900+ dotmaps. Your plugin is still doing sterling service, and I’ve no issues with creating the dot maps themselves, but the publisher would prefer the maps to be in a vector format, so while it’s very easy to create PNGs from the plugin I can’t find a way to configure the plugin to output SVG images from the composer. So I was hoping I had missed this feature, or maybe you were thinking of adding it?

Cheers

Bill

Hello Bill,

I’ve looked at including this before but haven’t due to issues that QGIS has with SVG (because of an underlying problem that QT - the technology QGIS uses to build it’s GUI - has with SVG). If you click the button to generate SVG from the map layout, you see this message:

image

When I have produced SVG I do indeed get the problem that layers are not clipped to the map extent. However, you may find that for your atlas maps you don’t have any layers going beyond the map extent (it depends on your background layers I guess).

So if you produce an SVG from one of your layouts and view it (I drag the SVG file into Chrome to do this) and it actually looks to be what you want then we might get away with it. If so, I will look at adding into a beta version for you to test. I may be able to do that this weekend if it proves to be simple (which I think it will).

Rich

Hi Rich

Thanks for the prompt reply.

I saw the SVG warning in QGIS when I was experimenting with exporting to SVG and went ahead ahead anyway. At least for my dot maps the SVG output looks ok. Here’s a screenshot of one of the SVG dot maps in chrome:

I’ve got a mask which hides everything outside the boundary which may be preventing the clipping issue.

I have noticed that you need select the SVG options carefully on save:

I’ve left the export as SCG groups unchecked as I don’t have any labels, and am not bothered about grouping layers.

I’ve checked Always export as vectors, otherwise QGIS just seems to create an SVG file with an image of the map embedded in it, which kind of defeats the purpose of exporting to a vector format.

And I’ve unchecked the RDF metadata as Chrome chokes on it, but from further investigation as to what RDF actually is (Resource Description Framework) I think that’s Chrome’s problem and shouldn’t make a difference if it’s in or out.

I would send you the svg files themselves, but I can’t upload .svgs (or zips) so the screenshot will have to suffice.

If you can hack together a SVG output into the plugin I’d be very grateful. Though your acknowledgement in Dad’s flora as the facilitator to help create the dot maps is assured regardless! :slight_smile:

Cheers

-Bill-

Hello Bill,

I’ve prepared a version - not properly released yet - that can perform batch output to SVG through a composer as requested. Have a go with it and let me know if it does the trick.

  • Goto https://github.com/FieldStudiesCouncil/QGIS-Biological-Recording-Tools/tree/svg-plus.
  • From the green Clone or download button, select Download zip.
  • Unzip the download which will give you a folder called ‘QGIS-Biological-Recording-Tools-svg-plus’.
  • Change directory into that folder and you will see another folder with exactly the same name - ‘QGIS-Biological-Recording-Tools-svg-plus’.
  • Move this deeper folder into you plugins folder (see steps below to locate that).

To locate you plugins folder:

  • Start QGIS.
  • From Settings > User profiles menu, choose ‘Open active profile folder’.
  • Change directory into the ‘python/plugis’ subfolder.
  • This is where you need to copy the folder to.

To start the plugin:

  • Restart QGIS if already running.
  • Got plugins manager.
  • You should see two versions of the TomBio plugin - the one you have installed from the repository and the one you have just copied in.
  • Uncheck the official one and check the new test version - you can identify it by the version in the right-had pane when you click on each tool. The latest proper release is 3.2.2. This test version is marked 3.2.x.

Now you should be able to use the plugin with the new feature.

Hi Rich

Yes, it works perfectly thanks.

QGIS appears to be outputting the gird as an image instead of vectors which is odd, but that’s an issue with the QGIS SVG export, not your plugin, so I’ll have to try and see what’s going on there.

Thanks for spending the time upgrading the plugin to output the SVG. Much appreciated.

Cheers

-Bill-

You’re welcome Bill. I will probably make a proper release of this within the next couple of weeks. If you make any progress on the grid problem, let me know in case it’s something that can be dealt with within the plugin.

Rich

Hi Rich

I did some playing around with the map layers to try and stop QGIS from embedding pngs into the SVG and I finally managed it. It’s definitely a QGIS issue and not your plugin. Here’s what I discovered:

  1. By converting the 10km and tetrad grid layers from polys to polylines the grids were outputted as vectors in the SVG. Previously they were being outputted as single png image per grid layer containing the grid squares
  2. By dissolving the gird polylines in QGIS to create a single grid object the resulting SVG file was much smaller as it didn’t have to plot many identical gridlines over each other as all the individual line segments of the each grid poly were merged into a single line
  3. Depending on what QGIS feels like, some poly layers were still outputted as pngs. This was true of the VC boundaries. I couldn’t turn them into polylines as I wanted two of the VC polys to have a fill to distinguish them from the VCs not in the flora. It seems the larger the areal extent the poly coverage is, the more likely QGIS is to output the polys as vectors instead of pngs. But it’s an inexact science and I couldn’t really find a reason for it. Just had to experiment until I got the result I wanted.
  4. After opening my early SVG maps in Inkscape, the ones where I used a inverted mask to hide anything I wasn’t interested, I realised the clipping issue that QGIS/you warn against might become an issue if the SVG files are edited, as the inverted mask is just replicated in the SVG file and editing the mask in the SVG file can reveal the previously hidden parts of the map. So I created a new layer clipped to the required map extent in QGIS for each of the output layers, and used these layers in composer as the output for SVG. The resulting SVG was the much cleaner, and smaller.

So as long as you’re prepared to put some effort in to create layers tailored specifically for the SVG output it seems it’s reasonably easy to overcome the limitations in SVG output in QGIS.

Cheers

-Bill-

Many thanks Bill. It’s great to have this here on the forum because it may help people who come after with the same, or similar, issue.

One thing occurs to me - the VC boundary files are very detailed with many vertices in the boundaries. They would inflate the size of the SVG if encoded as vectors, so I wonder if QGIS is using the number of vertices as some sort of trigger to decide between vector and png. If that is the case, you may find that you can create a new VC layer for your purposes by using QGIS vector ‘simplify’ feature to reduce the number of vertices below the point that triggers png creation. At the scale required for your plots, you could probably afford to simplify the VC vector file quite dramatically without affecting its visual appearance.

Yup, simplifying the VC boundaries for SVG will definitely help to decrease the size of the SVG file. I’ll have a play to see if it affects the generation of embedded pngs.

I ought to have thought of this myself, but I was just being lazy. When I was outputting to png images it didn’t matter that the boundaries were ungeneralised so I didn’t bother :slight_smile: