Skip to content

Commit

Permalink
Merge pull request #4925 from mind84/raster_opacity
Browse files Browse the repository at this point in the history
[Bug]: Add layer opacity information to rasters
  • Loading branch information
Gustry authored Nov 6, 2024
2 parents c36a78b + ac32277 commit 9c5c1ad
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 13 deletions.
9 changes: 7 additions & 2 deletions lizmap/modules/lizmap/lib/Project/QgisProject.php
Original file line number Diff line number Diff line change
Expand Up @@ -377,13 +377,18 @@ protected function setShortNames(ProjectConfig $cfg)
*/
protected function setLayerOpacity(ProjectConfig $cfg)
{
$layerWithOpacities = $this->xpathQuery('//maplayer/layerOpacity[.!=1]/parent::*');
$layerWithOpacities = $this->xpathQuery('//maplayer/layerOpacity[.!=1]/parent::* | //maplayer/pipe/rasterrenderer/@opacity[.!=1]/ancestor::maplayer');
if ($layerWithOpacities) {
foreach ($layerWithOpacities as $layerWithOpacity) {
$name = (string) $layerWithOpacity->layername;
$layerCfg = $cfg->getLayer($name);
$opacity = 1;
if ($layerCfg) {
$opacity = (float) $layerWithOpacity->layerOpacity;
if (isset($layerWithOpacity->layerOpacity)) {
$opacity = (float) $layerWithOpacity->layerOpacity;
} elseif (isset($layerWithOpacity->pipe->rasterrenderer['opacity'])) {
$opacity = (float) $layerWithOpacity->pipe->rasterrenderer['opacity'];
}
$layerCfg->opacity = $opacity;
}
}
Expand Down
18 changes: 9 additions & 9 deletions tests/end2end/playwright/print.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ test.describe('Print', () => {
expect(postData).toContain('map0%3ASCALE=100000')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255&simple_label=simple%20label');
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255&simple_label=simple%20label');
// Disabled because of the migration when project is saved with QGIS >= 3.32
// expect(postData).toContain('multiline_label=Multiline%20label');
});
Expand All @@ -84,7 +84,7 @@ test.describe('Print', () => {
expect(postData).toContain('map0%3ASCALE=100000')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255');
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255');
});

await page.locator('#print-launch').click();
Expand All @@ -109,7 +109,7 @@ test.describe('Print', () => {
expect(postData).toContain('map1%3ASCALE=100000')
expect(postData).toContain('map1%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map1%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map1%3AOPACITIES=255%2C255%2C255')
expect(postData).toContain('map1%3AOPACITIES=204%2C255%2C255')
expect(postData).toMatch(/map0%3AEXTENT=761864.\d+%2C6274266.\d+%2C779334.\d+%2C6284518.\d+/);
});
await page.locator('#print-launch').click();
Expand All @@ -132,7 +132,7 @@ test.describe('Print', () => {
expect(postData).toContain('map0%3ASCALE=100000')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255')
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255')
expect(postData).toMatch(/map0%3AHIGHLIGHT_GEOM=CURVEPOLYGON\(CIRCULARSTRING\(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20772265.\d+%206279008.\d+%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20775229.\d+%206281972.\d+%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20778193.\d+%206279008.\d+%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20775229.\d+%206276044.\d+%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20772265.\d+%206279008.\d+\)\)/)
expect(postData).toContain('map0%3AHIGHLIGHT_SYMBOL=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%20%20%20%20%3CStyledLayerDescriptor%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20version%3D%221.1.0%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20http%3A%2F%2Fschemas.opengis.net%2Fsld%2F1.1.0%2FStyledLayerDescriptor.xsd%22%20xmlns%3Ase%3D%22http%3A%2F%2Fwww.opengis.net%2Fse%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CUserStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CFeatureTypeStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CRule%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CPolygonSymbolizer%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CStroke%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke%22%3E%23ff0000%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke-opacity%22%3E1%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke-width%22%3E2%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%3C%2FStroke%3E%0A%20%20%20%20%20%20%20%20%3CFill%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22fill%22%3E%23ff0000%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22fill-opacity%22%3E0.2%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%3C%2FFill%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FPolygonSymbolizer%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FRule%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FFeatureTypeStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FUserStyle%3E%0A%20%20%20%20%20%20%20%20%3C%2FStyledLayerDescriptor%3E')
expect(postData).toContain('simple_label=simple%20label');
Expand Down Expand Up @@ -183,7 +183,7 @@ test.describe('Print', () => {
expect(postData).toContain('map0%3ASCALE=100000')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255');
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255');
expect(postData).toContain('simple_label=simple%20label');
expect(postData).toContain('SELECTIONTOKEN=');
}
Expand Down Expand Up @@ -224,7 +224,7 @@ test.describe('Print', () => {
expect(postData).toContain('map0%3ASCALE=100000')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255');
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255');
expect(postData).toContain('simple_label=simple%20label');
expect(postData).toContain('FILTERTOKEN=');
}
Expand Down Expand Up @@ -451,7 +451,7 @@ test.describe('Print 3857', () => {
expect(postData).toContain('map0%3ASCALE=72224')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255')
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255')
expect(postData).toContain('simple_label=simple%20label');
// Disabled because of the migration when project is saved with QGIS >= 3.32
// expect(postData).toContain('multiline_label=Multiline%20label');
Expand All @@ -478,7 +478,7 @@ test.describe('Print 3857', () => {
expect(postData).toContain('map0%3ASCALE=72224')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255');
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255');
});

await page.locator('#print-launch').click();
Expand All @@ -501,7 +501,7 @@ test.describe('Print 3857', () => {
expect(postData).toContain('map0%3ASCALE=72224')
expect(postData).toContain('map0%3ALAYERS=OpenStreetMap%2Cquartiers%2Csousquartiers')
expect(postData).toContain('map0%3ASTYLES=default%2Cd%C3%A9faut%2Cd%C3%A9faut')
expect(postData).toContain('map0%3AOPACITIES=255%2C255%2C255')
expect(postData).toContain('map0%3AOPACITIES=204%2C255%2C255')
expect(postData).toContain('map0%3AHIGHLIGHT_GEOM=CURVEPOLYGON(CIRCULARSTRING(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20433697.51452157885%205404736.19944501%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20437978.67052402196%205409017.355447453%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20442259.82652646507%205404736.19944501%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20437978.67052402196%205400455.043442567%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20433697.51452157885%205404736.19944501))')
expect(postData).toContain('map0%3AHIGHLIGHT_SYMBOL=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0A%20%20%20%20%3CStyledLayerDescriptor%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20version%3D%221.1.0%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20http%3A%2F%2Fschemas.opengis.net%2Fsld%2F1.1.0%2FStyledLayerDescriptor.xsd%22%20xmlns%3Ase%3D%22http%3A%2F%2Fwww.opengis.net%2Fse%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CUserStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CFeatureTypeStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CRule%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CPolygonSymbolizer%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CStroke%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke%22%3E%23ff0000%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke-opacity%22%3E1%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22stroke-width%22%3E2%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%3C%2FStroke%3E%0A%20%20%20%20%20%20%20%20%3CFill%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22fill%22%3E%23ff0000%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CSvgParameter%20name%3D%22fill-opacity%22%3E0.2%3C%2FSvgParameter%3E%0A%20%20%20%20%20%20%20%20%3C%2FFill%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FPolygonSymbolizer%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FRule%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FFeatureTypeStyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FUserStyle%3E%0A%20%20%20%20%20%20%20%20%3C%2FStyledLayerDescriptor%3E')
expect(postData).toContain('simple_label=simple%20label');
Expand Down
3 changes: 2 additions & 1 deletion tests/units/classes/Project/QgisProjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,9 @@ public function testSetLayerOpacity()
{
$file = __DIR__.'/Ressources/simpleLayer.qgs.cfg';
$json = json_decode(file_get_contents($file));
$expectedLayer = clone $json->layers;
$expectedLayer = unserialize(serialize($json->layers));
$expectedLayer->montpellier_events->opacity = (float) 0.85;
$expectedLayer->local_raster_layer->opacity = (float) 0.6835;
$cfg = new Project\ProjectConfig((object) array('layers' => $json->layers));
$testProj = new qgisProjectForTests();
$testProj->setXmlForTest(simplexml_load_file(__DIR__.'/Ressources/opacity.qgs'));
Expand Down
61 changes: 61 additions & 0 deletions tests/units/classes/Project/Ressources/opacity.qgs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,65 @@
<checkConfiguration/>
</geometryOptions>
</maplayer>
<maplayer hasScaleBasedVisibilityFlag="0" refreshOnNotifyEnabled="0" autoRefreshMode="Disabled" minScale="1e+08" refreshOnNotifyMessage="" legendPlaceholderImage="" maxScale="0" styleCategories="AllStyleCategories" autoRefreshTime="0" type="raster">
<id>raster_78572dfa_41b3_42da_a9c6_933ead8bad8f</id>
<datasource>./media/raster.asc</datasource>
<shortname>local_raster</shortname>
<keywordList>
<value></value>
</keywordList>
<layername>local_raster_layer</layername>
<map-layer-style-manager current="default">
<map-layer-style name="default"/>
</map-layer-style-manager>
<metadataUrls/>
<customproperties/>
<mapTip enabled="1"></mapTip>
<pipe-data-defined-properties>
<Option type="Map">
<Option name="name" value="" type="QString"/>
<Option name="properties"/>
<Option name="type" value="collection" type="QString"/>
</Option>
</pipe-data-defined-properties>
<pipe>
<provider>
<resampling zoomedInResamplingMethod="nearestNeighbour" zoomedOutResamplingMethod="nearestNeighbour" enabled="false" maxOversampling="2"/>
</provider>
<rasterrenderer opacity="0.6835" alphaBand="-1" nodataColor="" grayBand="1" gradient="BlackToWhite" type="singlebandgray">
<rasterTransparency/>
<minMaxOrigin>
<limits>MinMax</limits>
<extent>WholeRaster</extent>
<statAccuracy>Estimated</statAccuracy>
<cumulativeCutLower>0.02</cumulativeCutLower>
<cumulativeCutUpper>0.98</cumulativeCutUpper>
<stdDevFactor>2</stdDevFactor>
</minMaxOrigin>
<contrastEnhancement>
<minValue>50</minValue>
<maxValue>125</maxValue>
<algorithm>StretchToMinimumMaximum</algorithm>
</contrastEnhancement>
<rampLegendSettings useContinuousLegend="1" maximumLabel="" prefix="" direction="0" minimumLabel="" suffix="" orientation="2">
<numericFormat id="basic">
<Option type="Map">
<Option name="decimal_separator" type="invalid"/>
<Option name="decimals" value="6" type="int"/>
<Option name="rounding_type" value="0" type="int"/>
<Option name="show_plus" value="false" type="bool"/>
<Option name="show_thousand_separator" value="true" type="bool"/>
<Option name="show_trailing_zeros" value="false" type="bool"/>
<Option name="thousand_separator" type="invalid"/>
</Option>
</numericFormat>
</rampLegendSettings>
</rasterrenderer>
<brightnesscontrast gamma="1" brightness="0" contrast="0"/>
<huesaturation colorizeBlue="128" invertColors="0" colorizeRed="255" saturation="0" colorizeGreen="128" colorizeStrength="100" grayscaleMode="0" colorizeOn="0"/>
<rasterresampler maxOversampling="2"/>
<resamplingStage>resamplingFilter</resamplingStage>
</pipe>
<blendMode>0</blendMode>
</maplayer>
</qgis>
35 changes: 34 additions & 1 deletion tests/units/classes/Project/Ressources/simpleLayer.qgs.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,39 @@
"imageFormat": "image/png",
"cached": "False",
"clientCacheExpiration": 300
}
},
"local_raster_layer": {
"id": "raster_78572dfa_41b3_42da_a9c6_933ead8bad8f",
"name": "local_raster_layer",
"type": "layer",
"extent": [
3.8485,
43.573100000000004,
4.0245,
43.6281
],
"crs": "OGC:CRS84",
"title": "local raster layer",
"abstract": "",
"link": "",
"minScale": 1,
"maxScale": 1000000000000,
"toggled": "False",
"popup": "False",
"popupSource": "auto",
"popupTemplate": "",
"popupMaxFeatures": 10,
"popupDisplayChildren": "False",
"popup_allow_download": true,
"legend_image_option": "hide_at_startup",
"groupAsLayer": "False",
"baseLayer": "False",
"displayInLegend": "True",
"group_visibility": [],
"singleTile": "True",
"imageFormat": "image/png",
"cached": "False",
"clientCacheExpiration": 300
}
}
}

0 comments on commit 9c5c1ad

Please sign in to comment.