Note

This bug is fixed as of 14 April 2005, and will be in the 0.7 release of Qgis. Thanks to Brendan for working out the problem and suggesting the solution (as detailed below).

Introduction

Since this bug is a showstopper for QGIS 0.7, I thought I would write up about it, in the hope that someone with more time than me can sit down and fix it (or edit this page if they think I'm wrong about something).

Description

In qgsvectorlayer.cpp there is the drawfeature function.

In there it makes several calls of the qpainter moveto and lineto functions.

According to the Qt documentation, "Warning: On X11, coordinates that do not fit into 16-bit signed values are truncated. This limitation is expected to go away in Qt 4."

This +/- 32767 limitation could easily be reached when zooming in enough on a complicated geometry object, and perhaps this is the source of the bug.

Suggested Remedy

There needs to be a viewport intersection test. For this to happen, qgsvectorlayer::drawfeature must treat coordinates line-by-line instead of the current point by point.

Therefore for each line, drawfeature will have to clip each line component to the viewport plus a margin just wider than the width of the line. (The margin helps avoid any arbitrary line caps from leaking onto the viewport itself.) By clipping, there is no danger of overflowing the X11 16 bit restriction.

Practically speaking, qgsrect could be extended to provide a testing / clipping function against lines.

As part of fixing this bug, I've noticed we've had other issues with penjoinstyle and pencapstyle - in that every line segment of a linestring geometry is rendered as a standalone line in QGIS, which invokes the pencapstyle but not the penjoinstyle.

This could be rectified by using qpainter::drawpolyline, but this takes a qpointarray not a WKB.

Therefore it would be prudent to add a new parser class for WKB which could have a function to output the WKB as a qpointarray, directly for feeding into qpainter::drawployline.

Another reason for separating the WKB parsing code into its own class is so that the coding can be cleaned up. For example, the multilinestring should by its nature call the same part of code that renders a single linestring, but in the current QGIS code, the code is duplicated. There's also a prevalence of magic numbers that can be cleaned up.

Assumptions / Caveats

  1. I haven't considered the effect on polygon fills. Hopefully it will be an evolution of the above design.
  2. The above assumes cartesian (i.e. screen) coordinates - I'm not sure if or how projected maps will affect this design.

That's it. Good luck, coders!