-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add possibility do data define label position by point instead of X/Y #45007
Conversation
Please don't merge before I've had a chance to review |
src/core/labeling/qgslabeling.h
Outdated
@@ -30,6 +31,8 @@ | |||
*/ | |||
class CORE_EXPORT QgsLabeling | |||
{ | |||
Q_GADGET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the Q_GADGET for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be able to use the Q_ENUM macro
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better approach is to move the new enum to the Qgis class -- that's the general direction we're heading now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok i can move it there
@@ -66,3 +68,32 @@ QgsReferencedGeometry QgsReferencedGeometry::fromReferencedRect( const QgsRefere | |||
return QgsReferencedGeometry( QgsGeometry::fromRect( rectangle ), rectangle.crs() ); | |||
} | |||
|
|||
QgsReferencedGeometry QgsReferencedGeometry::fromEwkt( const QString &ewkt ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nyalldawson FYI, I think that's the thing that's interesting in here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah my comment was a mistake -- I didn't realise some of the changes were collapsed.
One question I do have with ewkt is if the crs number is a postgres srs id or is always an epsg code. The postgis docs suggest it's a postgis srid, which means the actual crs is server dependent and will vary server by server .. which means that interpretation has to reside in the data provider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is doing this in the provider not an incompatible change? We suddenly have different data types for columns (geometry or referenced geometry instead of string) and will break project configurations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I guess you'd need to ask the layer's data provider to convert the ewkt to a referenced geometry for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would that be requested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to forget, we also need a toEwkt method. Or support storing attributes with referenced geometry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually on second thoughts I'd avoid specifically referencing "ewkt" in the name, and go with "stringToReferencedGeometry" instead. Ewkt is postgis specific, but other providers may have an alternative format for string representation of geom + crs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like
virtual QgsReferencedGeometry QgsVectorDataProvider::fromEWkt( const QString& ewkt )
? Returns null geometry by default, postgres provider can implement with correct crs retrieval.
These seems a cleaner solution to me, I'll go for that. Thank you both for your comments!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to move the functions to the data provider but I can't find a way to access the provider in QgsPalLabeling. Is it not available on purpose? How could i get it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, you're right. The PAL label registration methods can't have any access to the layer, as they'll be used in a background thread.
It's going to get super complex to handle this. I think the only way would be some small abstract "text to geometry" converter object which can be set in the render context, where you retrieve an instance of that from the layer's data provider and set it in the render context during the map render job preparation stages. (With care taken to make sure it's safe to do the conversion in a different thread from what this object was created in).
@domi4484 I'd suggest in the interest of moving this forward that you split the work into two parts -- get the (basically unrelated) labelling part merged first, and then tackle the tricky ewkt handling in a follow up work. On the ewkt note -- my impression is that ewkt has seen no adoption outside of postgis. I'm wondering if it wouldn't be simpler to ask the postgis team for a new "as ewkt2" method which uses the full wkt2 definition of the crs instead. That'd completely side step all the complexity then (and also be of more use as a quasi standard for use outside of postgis). |
|
||
// Look if crs already cached | ||
QMutexLocker locker( mCrsCacheMutex ); | ||
if ( mCrsCache->contains( srid ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nyalldawson I passed the crs cache to the converter object. In most cases the right crs will already be in the cache at the time of rendering labels.
Do you think this could be a good enough solution? Otherwise i will embrace your suggestion about splitting the pr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that doesn't help -- it uses a different definition of IDs. (And there's a chance a user will have two postgis connections with different crs definitions for the same id number)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok i understand, but in this case the current implementation is also wrong. The crs cache is static and not per provider
Here's my two cents: instead of spending lots of energy on this ewkt thing, why don't we send it on fixing what's really broken here: the absence of geometry field support. If the postgis layer column that holds that EWKT-stored geometry would be exposed in QGIS as a (referenced) geometry field, we wouldn't need EWKT acrobatics. The EWKT to geometry would happen within the provider's feature iterator. |
As for EWKT handling on the short term: users can come up with an expression which assumes the SRID ID == EPSG ID:
Obviously, the users would replace the arbitrary string I used above (i.e. |
If someone wants to do a rock solid expression-based EWKT to geometry: he/she can actually add the postigs' spatial_ref_sys table in his/her project and query the SRID info by using |
1c504b7
to
00f3b97
Compare
Thank you @nirvn for taking us back to the root of the problem. At this state the limitation is that the label position read from an additional geometry field from postgis can't be parsed correctly (and this was the main objective of my work here). Now I see three possible solution/workaround for this:
My favorite at the moment is 1 but I don't know if it is acceptable :) |
-1 for the ugly workaround, +1 for the clean solution but I can see why it's not a welcoming option especially during feature freeze, -1 to introducing new flag. Here's an alternative proposition: transform the EWKT string into a WKT string when fetching the column value in the provider (in QgsPostgresProvider::convertValue()). You can detect whether the field type name is "geometry", and if so transform EWKTs into WKT (re-projecting to the layer's CRS if needed). That'd feel slightly less duck taped. |
If conversion of the attribute directly in the provider to a ReferencedGeometry is acceptable, this is certainly the cleanest option long term. I don't think inside qgis code it will require much changes. I think we either need to go for in-provider conversion, accepting the effects. |
@m-kuhn , ah right regarding the flag, makes sense. |
I'm +1 for changing to always returning referenced geometries, and making users deal with the fallout. In fact, I started work on this yeeeeeears ago: https://github.com/nyalldawson/QGIS/commits/multi_geom2 😆 (Still a non trivial amount of work to do -- specifically handling the geometry values cleanly for updates/add features, and I lost interest as the project I was wanting this for wrapped up.) |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
While we hate to see this happen, this PR has been automatically closed because it has not had any activity in the last 21 days. If this pull request should be reconsidered, please follow the guidelines in the previous comment and reopen this pull request. Or, if you have any further questions, just ask! We love to help, and if there's anything the QGIS project can do to help push this PR forward please let us know how we can assist. |
The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check
|
This one is still blocked by me |
@domi4484 thanks for picking this up again! Coming back to the core topic of this change, I propose a slightly different UI for exposing this functionality. Instead of the drop down to switch between "X/Y" and "Point" modes, I'd instead suggest JUST having a new property override button sitting next to the existing X / Y ones which is "[.] Point". This can get automatically disabled if x or y is set (and vice versa -- the x/y buttons get disabled if point property is set). It's a simpler UI, and would also substantially simplify the code (e.g. no need for the placementCoordinateType/setPlacementCoordinateType methods, since everything will be done via the property instead). @nirvn would be keen for your thoughts regarding this proposal |
@nyalldawson , @domi4484 , sounds like a good solution to me, certainly better than the combobox and its addition getter/setter. |
@nyalldawson good idea i will change it that way! |
@domi4484 are you happy for me to close this PR in the meantime? There's a lot of discussion here which is no longer relevant... |
@nyalldawson yes no problem |
Add possibility do data define label position by point instead of X/Y
This will allow to use the move label tool to change the position of a label coming from a point geometry column.
In the attached screencast a postgis table has a line geometry column and an additional point geometry column for the label position.