Comments (27)
I have made a simple but dramatic improvement as you can see in the attached screendumps. All I did was shifting each individual character with it's own angle instead of shifting the whole label with the average angle. I think it is worth to implement this pending your improvement.
I am looking for someone with write access to implement this for me. Contact me if you are interested.
from qgis-enhancement-proposals.
I'm +1 on this QEP. @NathanW2 do we need more +1s to accept this?
from qgis-enhancement-proposals.
@haubourg
Currently the characters are effectively rotated at the baseline. This results in overlapping characters if the angle is upwards and too much space if the angle is downwards. My improvement effectively rotates characters at the mean line, which looks much nicer. It is really a very small change in code.
This is my code in FeaturePart::curvedPlacementAtOffset
:
if (li->max_char_angle_inside == 41) // for testing only , should be true
{
double dist = 0.9 * li->label_height / 2; // 0.9 looks nicer
if (orientation < 0)
dist = -dist;
start_x += dist * cos(angle + M_PI_2);
start_y -= dist * sin(angle + M_PI_2);
}
// existing code follows
double render_angle = angle;
and in FeaturePart::createCurvedCandidatesAlongLine
:
positions.append( _createCurvedCandidate( slp, angle_avg, li->max_char_angle_inside == 41 ? 0 : -li->label_height / 2 ) );
BTW I'm using the magic number 41 as a way to compare old and new.
from qgis-enhancement-proposals.
Hi, if I understand well, that QEP is only for line layers. I must point that currently curved label fails when curvature is too high at a given zoom level.
Improving current curved labeling to have it work fast and readable dynamically would not only require a simplify function, but also a smoothing one. Suppressing node could generate high angles. preserving smooth angles and long enough paths to allow labeling engine to compute a label needs a fairly advanced (and maybe iterative) smooth-simplify algorithm.
from qgis-enhancement-proposals.
Hi. Actually we could easily extend this to any kind of layers, not only line layers.
About this and the simplification / smoothing function, here are two comments from @nyalldawson on the PR part:
A core change which would be required to accompany this would be to allow access to other geometry columns defined within a layer. Eg for many data formats (Postgis, spatialite) it's possible to have more than one geometry column. These additional geometries are currently just converted to wkb representations and displayed as text fields by QGIS (consequently bogging down use of the attribute table for layers with complex secondary geometries). Support should be added so that additional geometry columns are stored as QgsGeometry objects, and then the label path could be directly bound to the secondary geometry column without the expense of going through the expression engine. This would also allow for the following use case:
- Polygon layer with a secondary line geometry attribute
- Data defined label path is bound to line geometry
- User can add the layer a second time to QGIS, using the line geometry as the main geometry column
- User can then edit the line geometries using the existing digitizing tools, and the labels for the polygon layer will instantly update to reflect any changes to paths.
I've played with this a bit in the past and found that the default Douglas–Peucker simplification method doesn't help at all for curved labeling, as the sharp corners in the linear geometry are preserved. From my tests a better approach is:
- Use Visvalingam’s algorithm to simplify, as that removes sharp corners whilst preserving the overall shape of a line
- Combine smoothing with simplification (see http://qgis.org/api/classQgsGeometry.html#ab2f6d720b51f96686f3152a6dabfe201 ). Note that smoothing increases the number of vertices in a geometry, so it needs to be done after simplifying the geometry.
- Even better would be a "bend simplify" based on the algorithm described in http://web.cs.sunyit.edu/~poissad/projects/Curve/pdf/1998.pdf . It's a more effective method of maintaining the general shape of lines will removing small fluctuations.
from qgis-enhancement-proposals.
@nyalldawson I paste here your original comment about the obstacle geometry:
Note that it's not sufficient to just use the alternative geometry when registering a label. Instead, labels needs to be able to register an optional "obstacle geometry" which can differ from the feature geometry. Otherwise the simplified/smoothed line feature would be used for the obstacle detection too, and could result on labels being placed over the rendered symbol for a line.
Without this obstacle geometry, it could give something like that: (dotted line is the simplified version)
So ok to add an option to consider the original geometry as an obstacle. So that the placement algorithm will do its best to move the label out of the "spike" here.
But it should not avoid the label to overlap the original lines, in case no room is available. Is this how the obstacle works in the label engine ?
Then you were talking (on gitter) about a way to use visvalingram (or something else) only on one "side" of the label. I am not sure to follow. Could you develop ?
from qgis-enhancement-proposals.
Not sure if this is the right place to post this, but maybe it could be though in this QEP as well.
Currently, when a user uses the label move tool (with data defined properties set), curved labels are transformed in horizontal ones. It would be nice, if the user could instead move the label along the path. For that, the Label's starting position would need to be saved relative to the path itself, maybe using a distance to the start point in layer's units, or, even better, a relative position in the line (from 0.0 to 1.0). This would be possible to do with the original path or user simplified one.
My appologies if this is not the right place to discuss this feature. If so, I will simply create a feature request.
from qgis-enhancement-proposals.
@SrNetoChan Seems and interesting feature. It is somehow related to the label path feature, so I'll try to add it here. Thanks!
from qgis-enhancement-proposals.
@mhugo Note that QGIS master now supports registering a different geometry to act as an obstacle from the geometry used for generating candidates. See:
qgis/QGIS@9cc10e2
qgis/QGIS@55ead85
and qgis/QGIS@6b0e7de
This should make it possible to use the original line geometry as an obstacle for other labels, while using a simplified/smoothed/... geometry for label candidate generation.
from qgis-enhancement-proposals.
@nyalldawson Great, thanks !
from qgis-enhancement-proposals.
Small updates of the text:
- point to qgis/qgis4.0_api#21
- notice that simplification / smoothing functions could be optimized based on the current visible extent
from qgis-enhancement-proposals.
@SrNetoChan Hi. After thinking about it, I think your request is not related. You would need a way to manually fix the position of the label relative to the start of the line and have it as a data-defined property with corresponding tools.
from qgis-enhancement-proposals.
Ok. Thanks for considering it.
from qgis-enhancement-proposals.
Apart from the simplification / smoothing function details which may be determined afterwards, I think the description is enough. If no other objection, @NathanW2 could you tag as final draft ?
from qgis-enhancement-proposals.
👍 from me too!
from qgis-enhancement-proposals.
@NathanW2 could it be tagged as accepted ?
from qgis-enhancement-proposals.
Just a slight update to mention the Chaikin algorithm as a smoothing algorithm.
I think we have two +1 here ... @NathanW2 could it be tagged as accepted ?
from qgis-enhancement-proposals.
Sure thing.
On Thu, Jun 2, 2016 at 2:07 AM, Hugo Mercier [email protected]
wrote:
Just a slight update to mention the Chaikin algorithm as a smoothing
algorithm.
I think we have two +1 here ... @NathanW2 https://github.com/NathanW2
could it be tagged as accepted ?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#46 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAXS3P1dVc3oOjBlekTVNNBWe7vTGZGAks5qHa4kgaJpZM4GYG2P
.
from qgis-enhancement-proposals.
Thanks!
from qgis-enhancement-proposals.
Quite nice, +1!
from qgis-enhancement-proposals.
@fritsvanveen Hi, Just to be sure to understand, what is the difference between curved labels and your actual proposal. In curved labels, each letter is rotated too. What we miss is 👍
- having curved label being drawn even if lines have too high curve frequency at a given scale (too much letter overlapping)
- being able to choose where on a line a label should be drawn (think of cartographers needing a label on a watercourse to be at a specific place, but still curved).
- have curved labels even for polygons (think of the name of a big moutain chain, we like sometimes to have the label follow a curve on the map)..
from qgis-enhancement-proposals.
As a cartographic user of QGIS, this seems like a simple but very effective improvement for curved line labels. I warmly support the implementation of this "very small change".
from qgis-enhancement-proposals.
@fritsvanveen Thanks for the explanation, it is much more clear now. @mhugo any opinion?
from qgis-enhancement-proposals.
@fritsvanveen I've just given your changes a test drive. They certainly look much better for labeling over the line, but it breaks the placement if the curved labels are set to draw on top or below the line. Is this correct or did I apply your changes incorrectly?
from qgis-enhancement-proposals.
@nyalldawson
I had already extended my code to work with all placements.
if (( !reversed && ( flags & FLAG_ABOVE_LINE ) ) || ( reversed && ( flags & FLAG_BELOW_LINE ) ) )
positions.append( _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 ) );
if ( flags & FLAG_ON_LINE )
positions.append( _createCurvedCandidate( slp, angle_avg, 0 ) );
if (( !reversed && ( flags & FLAG_BELOW_LINE ) ) || ( reversed && ( flags & FLAG_ABOVE_LINE ) ) )
positions.append( _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() ) );
Probably the middle _createCurvedCandidate( slp, angle_avg, 0 ) can be replaced by slp
.
No, slp is deleted afterwards.
The other code fragment now reads;
// Shift the character downwards since the draw position is specified at the baseline
// and we're calculating the mean line here
double dist = 0.9 * li->label_height / 2;
if (orientation < 0)
dist = -dist;
start_x += dist * cos(angle + M_PI_2);
start_y -= dist * sin(angle + M_PI_2);`
from qgis-enhancement-proposals.
@fritsvanveen any chance you could open a pull request with your changes? That'd make it easier to test and we could move the discussion over there.
from qgis-enhancement-proposals.
@nyalldawson Made a pull request.
from qgis-enhancement-proposals.
Related Issues (20)
- Build snapping index at render time HOT 10
- GSSAPI authentication not supported HOT 1
- Support for Complex Features in WFS provider HOT 9
- Authentication system updates HOT 21
- License requirements for plugins on plugins.qgis.org HOT 8
- Indicator on volatile default values
- R QGIS_process integration into JASP HOT 4
- QGIS Enhancement: Allow a simple way to refresh external datasets manually HOT 1
- CMYK Support HOT 22
- A better experience for first time plugin manager users HOT 7
- PyQGIS linter warnings HOT 1
- Move more data providers to core library HOT 15
- QGIS Enhancement: Authentication system revision (v1.1) HOT 3
- Clean up point cloud index and improve its thread safety HOT 2
- QGIS Enhancement Proposal: Mitigate Abusive Tile Fetching on OpenStreetMap (OSM) Servers HOT 11
- QGIS Enhancement Proposal: Implementing CI Qt6 Windows Builds through vcpkg HOT 4
- QGIS Enhancement Proposal: Paged Fetching of Features and Browser Attribute Table Improvements HOT 2
- Fix access to remote data sources in WebAssembly builds HOT 14
- Embedded end-user feedback HOT 6
- Trusted Projects and Folders HOT 12
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qgis-enhancement-proposals.