Skip to content
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 highlight features when "follow map theme" is selected in map layout #36007

Closed

Conversation

jgrocha
Copy link
Member

@jgrocha jgrocha commented Apr 26, 2020

Description

This is exactly the same as #34271. I closed the previous one, because I pushed my local repo with a rebase (instead of merge).

All the previous discussion is there.

Fix #34178

@jgrocha jgrocha added Bug Either a bug report, or a bug fix. Let's hope for the latter! Server Related to QGIS server labels Apr 26, 2020
@github-actions github-actions bot added this to the 3.14.0 milestone Apr 26, 2020
@pblottiere
Copy link
Member

Hello @jgrocha,

Just to be sure I cloned your branch and added these outputs in configurePrintLayout:

// Add the theme and set it
newPresetName = presetName + QStringLiteral( "__highlight" );
std::cout << "newPresetName: " << newPresetName.toStdString() << std::endl;
for ( const QString &theme : c->project()->mapThemeCollection()->mapThemes() )
    std::cout << "Existing map theme: " << theme.toStdString() << std::endl;

Then I manually throw an exception just before calling the unConfigurePrintLayout method in getPrint:

throw QgsException( QStringLiteral( "Fake exception." ) );
unConfigurePrintLayout( layout.get() );

After the first WMS GetPrint request I have:

newPresetName: World__highlight
Existing map theme: World
15:13:33 CRITICAL Server[416879]: Fake exception.

After the second request:

newPresetName: World__highlight
Existing map theme: World
Existing map theme: World__highlight
15:13:33 CRITICAL Server[416879]: Fake exception.

In this case we see that the map theme collection is not correctly cleaned if the unConfigurePrintLayout method is not called. Moreover, in the same way, it means that if we have an exception during the GetPrint rendering, the unConfigurePrintLayout is still not called which mean that the project is left in an uncleaned state.

What do you think @jgrocha? So if I'm not wrong, we should think about using something like the QgsLayerRestorer mechanism.

@jgrocha
Copy link
Member Author

jgrocha commented Apr 28, 2020

Hi @pblottiere I've tested the code again. I've comment out unConfigurePrintLayout() and issued three consecutive GetPrint requests using the same layout (with a theme set). The first call has highlight, no highlight on the second and a different highlight on the third call. All three requests returned the expected result. There is no highlight left from the first request on the second request. I'm missing something for sure, but I don't think that unConfigurePrintLayout() is really important. I can't see a way to write a unit test to get this PR failing.

QgsLayerRestorer is already used in all requests. I thought it was there to ensure that we don't mess the layer configuration, but I really didn't dig into it. Do we have to call something else to recover the previous layer configuration? I have to see how to use it and test it, but as I said, without a test that makes the code fail, it is more difficult.

@jgrocha jgrocha force-pushed the highlight-geom-on-top-of-locked-layers-mc branch from ebb6427 to c77bfd1 Compare April 28, 2020 20:59
@pblottiere
Copy link
Member

I've tested the code again. I've comment out unConfigurePrintLayout() and issued three consecutive GetPrint requests using the same layout (with a theme set). The first call has highlight, no highlight on the second and a different highlight on the third call. All three requests returned the expected result. There is no highlight left from the first request on the second request. I'm missing something for sure, but I don't think that unConfigurePrintLayout() is really important. I can't see a way to write a unit test to get this PR failing.

Indeed, results of the requests will be the same with or without the unConfigurePrintLayout because the QgsMapThemeCollection::insert() method replaces a previous record with the same name (for now). However, the underlying QgsProject instance is cached meaning that the same instance is used for each request. So leaving this instance in a different state after a request is potentially risky and can lead to undefined behaviors in the future.

So, in order to be perfectly robust and avoid strange side effects, I think we have to keep the shared QgsProject instance exactly in the same state before and after request. And yes, you can't write Python unit test, but you can totally write a c++ unit test for that (you can take a look to the test_qgsserver_wms_dxf.cpp test for example). In this case, it would mean to:

  1. create a WMS renderer with a specific project
  2. call the GetPrint method with a highlight parameter
  3. check that the map theme collection is identical before and after the GetPrint method

QgsLayerRestorer is already used in all requests. I thought it was there to ensure that we don't mess the layer configuration, but I really didn't dig into it. Do we have to call something else to recover the previous layer configuration? I have to see how to use it and test it, but as I said, without a test that makes the code fail, it is more difficult.

The QgsLayerRestorer instance is stored in a unique_ptr. It means that whatever is happening (exception, ...), the destructor is always called. And it's precisely in the destructor that we post-process the layer configuration to ensure that the state is the same before and after each request.

So I think that we're in the same situation here.

@jgrocha let me know if I'm missing something.

@jgrocha
Copy link
Member Author

jgrocha commented Apr 28, 2020

Hi @pblottiere I'm learning slow, but you are being very helpful in your comments.

As far as I understand, my challenge is to improve QgsLayerRestorer()/~QgsLayerRestorer() to handle this, write? I have to iterate over all project()->mapThemeCollection() and make sure that they are the same before and after each request. Something like that? Is this the way?

@pblottiere
Copy link
Member

Hi @jgrocha,

but you are being very helpful in your comments.

Good, I'm not totally useless then :).

As far as I understand, my challenge is to improve QgsLayerRestorer()/~QgsLayerRestorer() to handle this, write? I have to iterate over all project()->mapThemeCollection() and make sure that they are the same before and after each request. Something like that? Is this the way?

Yes. However, even if the mechanism would be the same as the QgsLayerRestorer, I'm not sure it's the right place to do it. As stated in the name of the class, it's about layers, not about project.

And considering that the QgsLayerRestorer is part of the public API, we cannot rename it... So I'd probably go for:

  • adding a new QgsProjectRestorer which take a QgsProject instance and reset modifications on map theme collection (and maybe more in the future)
  • adding a new QgsContextRestorer which take a QgsWmsRenderContext instance in parameter
    and encapsulate the whole restoration process (layers, project and maybe more in the future)

This way we'd replace the usual:

std::unique_ptr<QgsLayerRestorer> restorer;
restorer.reset( new QgsLayerRestorer( mContext.layers() ) );

by:

std::unique_ptr<QgsContextRestorer> restorer;
restorer.reset( new QgsContextRestorer( mContext ) );

(the context has access to layers, project, ...). I think it's robust and the mechanism can easily evolve in time to support more restoration actions.

@jgrocha what do you think? If you're not comfortable enough, I can work on that part by modifying your branch. Let me know what you prefer. And do not hesitate to share if you think I'm missing something.

@jgrocha
Copy link
Member Author

jgrocha commented Apr 29, 2020

Fully agree with your comments. We need something with a boarder scope than the current QgsLayerRestorer(), that only includes the layers. As you have pointed out, a more robust mechanism should be put in place to support future run time modifications. It has to guarantee a proper isolation between each request.

If you don't mind - if you can afford the time and dedication - I would prefer that you introduce such important design decision into the code. If you think my branch is good enough to start, please use it.

I can handle this (maybe!) if necessary, but it would be awesome if your can take this into your own hands @pblottiere.

Please feel free to close this PR as soon as you submit yours.

@pblottiere
Copy link
Member

Hello @jgrocha,

I upgraded the restorer mechanism in this PR: #36141.

Once merged, I think you'll be able to update this one. Do you agree?

@pblottiere
Copy link
Member

@jgrocha The new restorer mechanism has been merged so I think you can smoothly add a project restorer now.

@jgrocha jgrocha force-pushed the highlight-geom-on-top-of-locked-layers-mc branch from c77bfd1 to b3f2881 Compare May 8, 2020 08:07
@stale
Copy link

stale bot commented May 22, 2020

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

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@stale stale bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label May 22, 2020
…-top-of-locked-layers-mc

merge updated upstream qgis repo into my dev branch
@stale stale bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label May 23, 2020
@pblottiere
Copy link
Member

Hi @jgrocha,

Do you plan to take a look to this PR for the 3.14 release? If not, I think I can dedicate some time to work on it.

@jgrocha
Copy link
Member Author

jgrocha commented Jun 3, 2020

Hi @jgrocha,

Do you plan to take a look to this PR for the 3.14 release? If not, I think I can dedicate some time to work on it.

I would love to, but right now I'm quite limited on time. If you can work on this, it would be great. Thank you!
(Please close this PR, soon as you submit yours or let me know and I'll close it).

@stale
Copy link

stale bot commented Jun 17, 2020

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

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@stale stale bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Jun 17, 2020
@stale
Copy link

stale bot commented Jun 26, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Server Related to QGIS server stale Uh oh! Seems this work is abandoned, and the PR is about to close.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

QGIS Server GetPrint: HIGHLIGHT_GEOM is not printed if map layers are configured to follow a map theme
2 participants