diff --git a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/MapLayer.php b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/MapLayer.php index 3ec4f78cf5..aeb0b6b0fc 100644 --- a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/MapLayer.php +++ b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/MapLayer.php @@ -133,7 +133,7 @@ protected static function getAttributes($oXmlReader) * * @param array $data the instance data * - * @return EmbeddedLayer|MapLayer|VectorLayer the instance + * @return EmbeddedLayer|MapLayer|RasterLayer|VectorLayer the instance */ protected static function buildInstance($data) { @@ -156,6 +156,10 @@ protected static function buildInstance($data) && $data['type'] === 'vector') { return new VectorLayer($data); } + if (array_key_exists('type', $data) + && $data['type'] === 'raster') { + return new RasterLayer($data); + } return new MapLayer($data); } @@ -406,3 +410,6 @@ protected static function buildInstance($data) MapLayer::registerChildParser('renderer-v2', function ($oXmlReader) { return RendererV2::fromXmlReader($oXmlReader); }); +MapLayer::registerChildParser('pipe', function ($oXmlReader) { + return RasterLayerPipe::fromXmlReader($oXmlReader); +}); diff --git a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayer.php b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayer.php new file mode 100644 index 0000000000..892ed8a77a --- /dev/null +++ b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayer.php @@ -0,0 +1,89 @@ + $keywordList + * @property RasterLayerPipe $pipe + * @property MapLayerStyleManager $styleManager + */ +class RasterLayer extends Qgis\BaseQgisObject +{ + /** @var array The instance properties */ + protected $properties = array( + 'id', + 'embedded', + 'type', + 'layername', + 'srs', + 'datasource', + 'provider', + 'styleManager', + 'shortname', + 'title', + 'abstract', + 'keywordList', + 'pipe', + ); + + /** @var array The not null properties */ + protected $mandatoryProperties = array( + 'id', + 'embedded', + 'type', + 'layername', + 'srs', + 'datasource', + 'provider', + 'styleManager', + 'pipe', + ); + + /** + * Get map layer as key array. + * + * @return array + */ + public function toKeyArray() + { + return array( + 'type' => $this->type, + 'id' => $this->id, + 'name' => $this->layername, + 'shortname' => $this->shortname !== null ? $this->shortname : '', + 'title' => $this->title !== null ? $this->title : $this->layername, + 'abstract' => $this->abstract !== null ? $this->abstract : '', + 'proj4' => $this->srs->proj4, + 'srid' => $this->srs->srid, + 'authid' => $this->srs->authid, + 'datasource' => $this->datasource, + 'provider' => $this->provider, + 'keywords' => $this->keywordList !== null ? $this->keywordList : array(), + ); + } +} diff --git a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerHueSaturation.php b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerHueSaturation.php new file mode 100644 index 0000000000..c7878f524e --- /dev/null +++ b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerHueSaturation.php @@ -0,0 +1,71 @@ + The instance properties */ + protected $properties = array( + 'saturation', + 'grayscaleMode', + 'invertColors', + 'colorizeOn', + 'colorizeRed', + 'colorizeGreen', + 'colorizeBlue', + 'colorizeStrength', + ); + + /** @var array The not null properties */ + protected $mandatoryProperties = array( + 'saturation', + 'grayscaleMode', + 'invertColors', + 'colorizeOn', + 'colorizeRed', + 'colorizeGreen', + 'colorizeBlue', + 'colorizeStrength', + ); + + /** @var string The XML element local name */ + protected static $qgisLocalName = 'huesaturation'; + + protected static function getAttributes($oXmlReader) + { + return array( + 'saturation' => (int) $oXmlReader->getAttribute('saturation'), + 'grayscaleMode' => (int) $oXmlReader->getAttribute('grayscaleMode'), + 'invertColors' => filter_var($oXmlReader->getAttribute('invertColors'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), + 'colorizeOn' => filter_var($oXmlReader->getAttribute('colorizeOn'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), + 'colorizeRed' => (int) $oXmlReader->getAttribute('colorizeRed'), + 'colorizeGreen' => (int) $oXmlReader->getAttribute('colorizeGreen'), + 'colorizeBlue' => (int) $oXmlReader->getAttribute('colorizeBlue'), + 'colorizeStrength' => (int) $oXmlReader->getAttribute('colorizeStrength'), + ); + } +} diff --git a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerPipe.php b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerPipe.php new file mode 100644 index 0000000000..3418e6559b --- /dev/null +++ b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerPipe.php @@ -0,0 +1,68 @@ + The instance properties */ + protected $properties = array( + 'renderer', + 'hueSaturation', + ); + + /** @var array The not null properties */ + protected $mandatoryProperties = array( + 'renderer', + 'hueSaturation', + ); + + /** @var string The XML element local name */ + protected static $qgisLocalName = 'pipe'; + + /** @var array The XML element parsed children */ + protected static $children = array( + 'rasterrenderer', + 'huesaturation', + ); + + protected static $childParsers = array(); + + protected static function buildInstance($data) + { + if (array_key_exists('rasterrenderer', $data)) { + $data['renderer'] = $data['rasterrenderer']; + unset($data['rasterrenderer']); + } + + if (array_key_exists('huesaturation', $data)) { + $data['hueSaturation'] = $data['huesaturation']; + unset($data['huesaturation']); + } + + return new RasterLayerPipe($data); + } +} +RasterLayerPipe::registerChildParser('rasterrenderer', function ($oXmlReader) { + return RasterLayerRasterRenderer::fromXmlReader($oXmlReader); +}); +RasterLayerPipe::registerChildParser('huesaturation', function ($oXmlReader) { + return RasterLayerHueSaturation::fromXmlReader($oXmlReader); +}); diff --git a/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerRasterRenderer.php b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerRasterRenderer.php new file mode 100644 index 0000000000..c8a99f419b --- /dev/null +++ b/lizmap/modules/lizmap/lib/Project/Qgis/Layer/RasterLayerRasterRenderer.php @@ -0,0 +1,47 @@ + The instance properties */ + protected $properties = array( + 'type', + 'opacity', + ); + + /** @var array The not null properties */ + protected $mandatoryProperties = array( + 'type', + 'opacity', + ); + + /** @var string The XML element local name */ + protected static $qgisLocalName = 'rasterrenderer'; + + protected static function getAttributes($oXmlReader) + { + return array( + 'type' => $oXmlReader->getAttribute('type'), + 'opacity' => (float) $oXmlReader->getAttribute('opacity'), + ); + } +} diff --git a/lizmap/modules/lizmap/lib/Project/QgisProject.php b/lizmap/modules/lizmap/lib/Project/QgisProject.php index 8a6e56f2bd..fcd9af2d1d 100644 --- a/lizmap/modules/lizmap/lib/Project/QgisProject.php +++ b/lizmap/modules/lizmap/lib/Project/QgisProject.php @@ -408,12 +408,21 @@ protected function setLayerOpacity(ProjectConfig $cfg) $project = Qgis\ProjectInfo::fromQgisPath($this->path); foreach ($project->projectlayers as $layer) { - if (!isset($layer->layerOpacity) || $layer->layerOpacity == 1) { + /** @var Qgis\Layer\MapLayer $layer */ + if ($layer->embedded) { continue; } + + $opacity = 1; + if ($layer->type == 'raster') { + /** @var Qgis\Layer\RasterLayer $layer */ + $opacity = $layer->pipe->renderer->opacity; + } elseif (isset($layer->layerOpacity) && $layer->layerOpacity != 1) { + $opacity = $layer->layerOpacity; + } $layerCfg = $cfg->getLayer($layer->layername); if ($layerCfg) { - $layerCfg->opacity = $layer->layerOpacity; + $layerCfg->opacity = $opacity; } } } diff --git a/tests/units/classes/Project/Qgis/MapLayerTest.php b/tests/units/classes/Project/Qgis/MapLayerTest.php index e79aac84d7..6d12f5371c 100644 --- a/tests/units/classes/Project/Qgis/MapLayerTest.php +++ b/tests/units/classes/Project/Qgis/MapLayerTest.php @@ -127,7 +127,7 @@ public function testFromXmlReader() $oXml = App\XmlTools::xmlReaderFromString($xmlStr); $layer = Qgis\Layer\MapLayer::fromXmlReader($oXml); $this->assertFalse($layer->embedded); - $this->assertInstanceOf(Qgis\Layer\MapLayer::class, $layer); + $this->assertInstanceOf(Qgis\Layer\RasterLayer::class, $layer); $data = array( 'id' => 'osm_mapnik20180315181738526', diff --git a/tests/units/classes/Project/Qgis/RasterLayerPipeTest.php b/tests/units/classes/Project/Qgis/RasterLayerPipeTest.php new file mode 100644 index 0000000000..c0472449d6 --- /dev/null +++ b/tests/units/classes/Project/Qgis/RasterLayerPipeTest.php @@ -0,0 +1,115 @@ + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + '; + $oXml = App\XmlTools::xmlReaderFromString($xmlStr); + $pipe = Qgis\Layer\RasterLayerPipe::fromXmlReader($oXml); + + $this->assertInstanceOf(Qgis\Layer\RasterLayerPipe::class, $pipe); + + $this->assertNotNull($pipe->renderer); + $this->assertEquals('singlebandcolordata', $pipe->renderer->type); + $this->assertEquals(1, $pipe->renderer->opacity); + + $this->assertNotNull($pipe->hueSaturation); + $this->assertEquals(0, $pipe->hueSaturation->saturation); + $this->assertEquals(0, $pipe->hueSaturation->grayscaleMode); + $this->assertFalse($pipe->hueSaturation->invertColors); + $this->assertFalse($pipe->hueSaturation->colorizeOn); + $this->assertEquals(255, $pipe->hueSaturation->colorizeRed); + $this->assertEquals(128, $pipe->hueSaturation->colorizeGreen); + $this->assertEquals(128, $pipe->hueSaturation->colorizeBlue); + $this->assertEquals(100, $pipe->hueSaturation->colorizeStrength); + + $xmlStr = ' + + + + + + + + MinMax + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + 50 + 125 + StretchToMinimumMaximum + + + + + + + + + + + + + + + + + + resamplingFilter + + '; + $oXml = App\XmlTools::xmlReaderFromString($xmlStr); + $pipe = Qgis\Layer\RasterLayerPipe::fromXmlReader($oXml); + + $this->assertInstanceOf(Qgis\Layer\RasterLayerPipe::class, $pipe); + + $this->assertNotNull($pipe->renderer); + $this->assertEquals('singlebandgray', $pipe->renderer->type); + $this->assertEquals(0.6835, $pipe->renderer->opacity); + + $this->assertNotNull($pipe->hueSaturation); + $this->assertEquals(0, $pipe->hueSaturation->saturation); + $this->assertEquals(0, $pipe->hueSaturation->grayscaleMode); + $this->assertFalse($pipe->hueSaturation->invertColors); + $this->assertFalse($pipe->hueSaturation->colorizeOn); + $this->assertEquals(255, $pipe->hueSaturation->colorizeRed); + $this->assertEquals(128, $pipe->hueSaturation->colorizeGreen); + $this->assertEquals(128, $pipe->hueSaturation->colorizeBlue); + $this->assertEquals(100, $pipe->hueSaturation->colorizeStrength); + } +} diff --git a/tests/units/classes/Project/Qgis/RasterLayerTest.php b/tests/units/classes/Project/Qgis/RasterLayerTest.php new file mode 100644 index 0000000000..07ac5ffdce --- /dev/null +++ b/tests/units/classes/Project/Qgis/RasterLayerTest.php @@ -0,0 +1,427 @@ + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + osm_mapnik20180315181738526 + crs=EPSG:3857&format=&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + osm-mapnik + + + PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3857"]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + '; + $oXml = App\XmlTools::xmlReaderFromString($xmlStr); + $layer = Qgis\Layer\MapLayer::fromXmlReader($oXml); + $this->assertFalse($layer->embedded); + $this->assertInstanceOf(Qgis\Layer\RasterLayer::class, $layer); + + $this->assertNotNull($layer->pipe); + $pipe = $layer->pipe; + $this->assertInstanceOf(Qgis\Layer\RasterLayerPipe::class, $pipe); + + $this->assertNotNull($pipe->renderer); + $this->assertEquals('singlebandcolordata', $pipe->renderer->type); + $this->assertEquals(1, $pipe->renderer->opacity); + + $this->assertNotNull($pipe->hueSaturation); + $this->assertEquals(0, $pipe->hueSaturation->saturation); + $this->assertEquals(0, $pipe->hueSaturation->grayscaleMode); + $this->assertFalse($pipe->hueSaturation->invertColors); + $this->assertFalse($pipe->hueSaturation->colorizeOn); + $this->assertEquals(255, $pipe->hueSaturation->colorizeRed); + $this->assertEquals(128, $pipe->hueSaturation->colorizeGreen); + $this->assertEquals(128, $pipe->hueSaturation->colorizeBlue); + $this->assertEquals(100, $pipe->hueSaturation->colorizeStrength); + + $xmlStr = ' + + + 3.84850000000000003 + 43.57310000000000372 + 4.02449999999999974 + 43.62810000000000343 + + + 3.84850000000000003 + 43.57310000000000372 + 4.02450000000000152 + 43.62809999999999633 + + raster_78572dfa_41b3_42da_a9c6_933ead8bad8f + ./media/raster.asc + local_raster + + + + local_raster_layer + + + GEOGCRS["WGS 84 (CRS84)",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic longitude (Lon)",east,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic latitude (Lat)",north,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Not known."],AREA["World."],BBOX[-90,-180,90,180]],ID["OGC","CRS84"]] + +proj=longlat +datum=WGS84 +no_defs + 63159 + 520003159 + OGC:CRS84 + WGS 84 (CRS84) + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + gdal + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinMax + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + 50 + 125 + StretchToMinimumMaximum + + + + + + + + + + + + + + + + + + resamplingFilter + + 0 + + '; + $oXml = App\XmlTools::xmlReaderFromString($xmlStr); + $layer = Qgis\Layer\MapLayer::fromXmlReader($oXml); + $this->assertFalse($layer->embedded); + $this->assertInstanceOf(Qgis\Layer\RasterLayer::class, $layer); + + $data = array( + 'id' => 'raster_78572dfa_41b3_42da_a9c6_933ead8bad8f', + 'embedded' => false, + 'type' => 'raster', + 'layername' => 'local_raster_layer', + //'srs', + 'datasource' => './media/raster.asc', + 'provider' => 'gdal', + 'shortname' => 'local_raster', + 'title' => null, + 'abstract' => null, + 'keywordList' => array(''), + ); + foreach($data as $prop => $value) { + $this->assertEquals($value, $layer->$prop, $prop); + } + + $this->assertNotNull($layer->srs); + $data = array( + 'proj4' => '+proj=longlat +datum=WGS84 +no_defs', + 'srid' => 520003159, + 'authid' => 'OGC:CRS84', + 'description' => 'WGS 84 (CRS84)', + ); + foreach($data as $prop => $value) { + $this->assertEquals($value, $layer->srs->$prop, $prop); + } + + $this->assertNotNull($layer->styleManager); + $data = array( + 'current' => 'default', + 'styles' => array('default'), + ); + foreach($data as $prop => $value) { + $this->assertEquals($value, $layer->styleManager->$prop, $prop); + } + + $keyData = $layer->toKeyArray(); + $this->assertTrue(is_array($keyData)); + $data = array( + 'type' => 'raster', + 'id' => 'raster_78572dfa_41b3_42da_a9c6_933ead8bad8f', + 'name' => 'local_raster_layer', + 'shortname' => 'local_raster', + 'title' => 'local_raster_layer', + 'abstract' => '', + 'proj4' => '+proj=longlat +datum=WGS84 +no_defs', + 'srid' => 520003159, + 'authid' => 'OGC:CRS84', + 'datasource' => './media/raster.asc', + 'provider' => 'gdal', + 'keywords' => array(''), + ); + foreach($data as $prop => $value) { + $this->assertEquals($value, $keyData[$prop], $prop); + } + + $this->assertNotNull($layer->pipe); + $pipe = $layer->pipe; + $this->assertInstanceOf(Qgis\Layer\RasterLayerPipe::class, $pipe); + + $this->assertNotNull($pipe->renderer); + $this->assertEquals('singlebandgray', $pipe->renderer->type); + $this->assertEquals(0.6835, $pipe->renderer->opacity); + + $this->assertNotNull($pipe->hueSaturation); + $this->assertEquals(0, $pipe->hueSaturation->saturation); + $this->assertEquals(0, $pipe->hueSaturation->grayscaleMode); + $this->assertFalse($pipe->hueSaturation->invertColors); + $this->assertFalse($pipe->hueSaturation->colorizeOn); + $this->assertEquals(255, $pipe->hueSaturation->colorizeRed); + $this->assertEquals(128, $pipe->hueSaturation->colorizeGreen); + $this->assertEquals(128, $pipe->hueSaturation->colorizeBlue); + $this->assertEquals(100, $pipe->hueSaturation->colorizeStrength); + } +} diff --git a/tests/units/classes/Project/Ressources/opacity.qgs b/tests/units/classes/Project/Ressources/opacity.qgs index 452d69b440..37c265d4e0 100644 --- a/tests/units/classes/Project/Ressources/opacity.qgs +++ b/tests/units/classes/Project/Ressources/opacity.qgs @@ -791,7 +791,19 @@ def my_form_open(dialog, layer, feature): 0 - + + + 3.84850000000000003 + 43.57310000000000372 + 4.02449999999999974 + 43.62810000000000343 + + + 3.84850000000000003 + 43.57310000000000372 + 4.02450000000000152 + 43.62809999999999633 + raster_78572dfa_41b3_42da_a9c6_933ead8bad8f ./media/raster.asc local_raster @@ -799,25 +811,173 @@ def my_form_open(dialog, layer, feature): local_raster_layer + + + GEOGCRS["WGS 84 (CRS84)",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic longitude (Lon)",east,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic latitude (Lat)",north,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Not known."],AREA["World."],BBOX[-90,-180,90,180]],ID["OGC","CRS84"]] + +proj=longlat +datum=WGS84 +no_defs + 63159 + 520003159 + OGC:CRS84 + WGS 84 (CRS84) + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + gdal + + + - + - - - + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + MinMax WholeRaster @@ -831,23 +991,23 @@ def my_form_open(dialog, layer, feature): 125 StretchToMinimumMaximum - + + + + + + + - - - + + + resamplingFilter 0