{"id":1130,"date":"2016-02-16T11:34:51","date_gmt":"2016-02-16T10:34:51","guid":{"rendered":"http:\/\/www.3dgis.it\/it\/?p=1130"},"modified":"2016-02-16T11:35:14","modified_gmt":"2016-02-16T10:35:14","slug":"garantire-lordine-rendering-la-vestizione-sld","status":"publish","type":"post","link":"https:\/\/www.3dgis.it\/it\/garantire-lordine-rendering-la-vestizione-sld\/","title":{"rendered":"Garantire l&#8217;ordine di rendering con la vestizione SLD"},"content":{"rendered":"<p>Garantire la consistenza del rendering del server geospaziale, indipendentemente da quale scegliate, \u00e8 di fondamentale importanza per ottenere risultati di qualit\u00e0.\u00a0Nel caso dobbiate disegnare un layer con feature sovrapposte, vi dovreste preoccupare dell&#8217;<strong>ordine con cui sono\u00a0disegnate le feature<\/strong>.<\/p>\n<p>Un classico esempio di questo problema \u00e8 dato dal layer delle strade, in presenza di cavalcavia o sottopassi. Vorrete, infatti, che queste feature siano disegnate dopo le altre al piano stradale e che magari abbiano uno stile particolare, che ne evidenzi le peculiarit\u00e0.<\/p>\n<p>Fortunatamente lo standard <strong>OGC SLD<\/strong>, e anche la sua recente evoluzione OGC SE, ci viene in aiuto con le <strong>Rule<\/strong>.<\/p>\n<p>&#8220;Baster\u00e0 definire due regole per ottenere quanto voluto&#8221;, direte voi.<\/p>\n<p>Verissimo, ma potreste incappare in spiacevoli conseguenze.<\/p>\n<p>Considerate questo caso molto semplice: <em>uno strato informativo poligonale delle aree verdi, che contiene sia le geometrie dei parchi che geometrie sovrapposte degli specchi d&#8217;acqua<\/em>.<\/p>\n<h2>Due regole per lo stesso stile<\/h2>\n<p>La logica vuole far disegnare gli specchi d&#8217;acqua sopra le aree verdi e quindi potreste pensare ad un SLD cos\u00ec fatto:<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\"?&gt;\r\n&lt;StyledLayerDescriptor version=\"1.0.0\" xmlns=\"http:\/\/www.opengis.net\/sld\" xmlns:ogc=\"http:\/\/www.opengis.net\/ogc\"\r\n xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n xsi:schemaLocation=\"http:\/\/www.opengis.net\/sld http:\/\/schemas.opengis.net\/sld\/1.0.0\/StyledLayerDescriptor.xsd\"&gt;\r\n &lt;NamedLayer&gt;\r\n &lt;Name&gt;Multirule&lt;\/Name&gt;\r\n &lt;UserStyle&gt;\r\n\r\n &lt;FeatureTypeStyle&gt;\r\n\r\n &lt;Rule&gt;\r\n &lt;ogc:Filter&gt;\r\n &lt;ogc:PropertyIsEqualTo&gt;\r\n &lt;ogc:PropertyName&gt;CFCC&lt;\/ogc:PropertyName&gt;\r\n &lt;ogc:Literal&gt;H41&lt;\/ogc:Literal&gt;\r\n &lt;\/ogc:PropertyIsEqualTo&gt;\r\n &lt;\/ogc:Filter&gt;\r\n &lt;PolygonSymbolizer&gt;\r\n &lt;Fill&gt;\r\n &lt;CssParameter name=\"fill\"&gt;#3366ff&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"fill-opacity\"&gt;0.5&lt;\/CssParameter&gt;\r\n &lt;\/Fill&gt;\r\n &lt;Stroke&gt;\r\n &lt;CssParameter name=\"stroke\"&gt;#3366ff&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"stroke-width\"&gt;1&lt;\/CssParameter&gt;\r\n &lt;\/Stroke&gt;\r\n &lt;\/PolygonSymbolizer&gt;\r\n &lt;\/Rule&gt;\r\n\r\n &lt;Rule&gt;\r\n &lt;PolygonSymbolizer&gt;\r\n &lt;Fill&gt;\r\n &lt;CssParameter name=\"fill\"&gt;#339933&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"fill-opacity\"&gt;0.5&lt;\/CssParameter&gt;\r\n &lt;\/Fill&gt;\r\n &lt;Stroke&gt;\r\n &lt;CssParameter name=\"stroke\"&gt;#339933&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"stroke-width\"&gt;1&lt;\/CssParameter&gt;\r\n &lt;\/Stroke&gt;\r\n &lt;\/PolygonSymbolizer&gt;\r\n &lt;\/Rule&gt;\r\n\r\n &lt;\/FeatureTypeStyle&gt;\r\n\r\n &lt;\/UserStyle&gt;\r\n &lt;\/NamedLayer&gt;\r\n&lt;\/StyledLayerDescriptor&gt;<\/pre>\n<p>La prima regola filtra gli specchi d&#8217;acqua mentre tutto il resto viene disegnato dalla seconda. Dal punto di vista umano, la regola in alto\u00a0dovrebbe consentire agli specchi d&#8217;acqua di apparire sopra ai parchi.<\/p>\n<p>Usando Geoserver come server geospaziale otterrete tuttavia la sequenza opposta\u00a0dato che il rendering \u00e8 incrementale, quindi le regole sono applicate in sequenza, e funziona\u00a0secondo una logica\u00a0basata sull&#8217;arrivo dei dati cos\u00ec come sono inviati dalla sorgente dati:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1147\" src=\"\/wp-content\/uploads\/2016\/02\/geoserver-sld-wrong.png\" alt=\"geoserver-sld-wrong\" width=\"978\" height=\"436\" srcset=\"https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-wrong.png 978w, https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-wrong-300x134.png 300w, https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-wrong-768x342.png 768w\" sizes=\"auto, (max-width: 978px) 100vw, 978px\" \/><\/p>\n<p>Il primo approccio potrebbe essere quello di dire &#8220;Baster\u00e0 quindi girare le regole per sistemare il problema.&#8221; ma non avrete risolto il problema alla radice. Funziona con il caso in questione (e infatti lo faremo) ma non potrete mai sapere con certezza come vengano forniti i dati dalla sorgente, soprattutto se non avete il completo controllo dei file o del database, e anche in questo caso sar\u00e0 sufficiente modificare il tipo di un record esistente per vanificare le nostre speranze.<\/p>\n<p>Inoltre basterebbe cambiare server geospaziale (ad esempio usando QGIS) per ottenere risultati diversi dato che non esiste una regola generale ma il rendering dipende dall&#8217;implementazione fatta dai programmatori.<\/p>\n<h2>Utilizzare\u00a0FeatureTypeStyle per garantire l&#8217;ordine di rendering<\/h2>\n<p>L&#8217;unico modo efficace di risolvere quindi il problema \u00e8 modificare concettualmente l&#8217;applicazione dell&#8217;SLD. Invece di aggiungere due o pi\u00f9 regole allo stesso <strong>FeatureTypeStyle<\/strong>, aggiungeremo pi\u00f9 FeatureTypeStyle ognuno contenente una Rule.<\/p>\n<p>Qual \u00e8 la differenza principale? I FeatureTypeStyle sono definiti dallo standard come un foglio di acetato sovrapponibile, ovvero un raggruppamento logico delle feature del layer ed \u00e8 garantita la consistenza e l&#8217;applicazione di un ordine deterministico. Le Rule\u00a0invece sono considerate dallo standard come un symbolizer e quindi privo di ogni raggruppamento logico.<\/p>\n<p>Cambiamo quindi l&#8217;SLD come segue:<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\"?&gt;\r\n&lt;StyledLayerDescriptor version=\"1.0.0\" xmlns=\"http:\/\/www.opengis.net\/sld\" xmlns:ogc=\"http:\/\/www.opengis.net\/ogc\"\r\n xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n xsi:schemaLocation=\"http:\/\/www.opengis.net\/sld http:\/\/schemas.opengis.net\/sld\/1.0.0\/StyledLayerDescriptor.xsd\"&gt;\r\n &lt;NamedLayer&gt;\r\n &lt;Name&gt;Multirule&lt;\/Name&gt;\r\n\r\n &lt;FeatureTypeStyle&gt;\r\n &lt;Rule&gt;\r\n &lt;PolygonSymbolizer&gt;\r\n &lt;Fill&gt;\r\n &lt;CssParameter name=\"fill\"&gt;#339933&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"fill-opacity\"&gt;0.5&lt;\/CssParameter&gt;\r\n &lt;\/Fill&gt;\r\n &lt;Stroke&gt;\r\n &lt;CssParameter name=\"stroke\"&gt;#339933&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"stroke-width\"&gt;1&lt;\/CssParameter&gt;\r\n &lt;\/Stroke&gt;\r\n &lt;\/PolygonSymbolizer&gt;\r\n &lt;\/Rule&gt;\r\n &lt;\/FeatureTypeStyle&gt;\r\n\r\n &lt;FeatureTypeStyle&gt;\r\n &lt;Rule&gt;\r\n &lt;ogc:Filter&gt;\r\n &lt;ogc:PropertyIsEqualTo&gt;\r\n &lt;ogc:PropertyName&gt;CFCC&lt;\/ogc:PropertyName&gt;\r\n &lt;ogc:Literal&gt;H41&lt;\/ogc:Literal&gt;\r\n &lt;\/ogc:PropertyIsEqualTo&gt;\r\n &lt;\/ogc:Filter&gt;\r\n &lt;PolygonSymbolizer&gt;\r\n &lt;Fill&gt;\r\n &lt;CssParameter name=\"fill\"&gt;#3366ff&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"fill-opacity\"&gt;0.5&lt;\/CssParameter&gt;\r\n &lt;\/Fill&gt;\r\n &lt;Stroke&gt;\r\n &lt;CssParameter name=\"stroke\"&gt;#3366ff&lt;\/CssParameter&gt;\r\n &lt;CssParameter name=\"stroke-width\"&gt;1&lt;\/CssParameter&gt;\r\n &lt;\/Stroke&gt;\r\n &lt;\/PolygonSymbolizer&gt;\r\n &lt;\/Rule&gt;\r\n &lt;\/FeatureTypeStyle&gt;\r\n\r\n &lt;\/UserStyle&gt;\r\n &lt;\/NamedLayer&gt;\r\n&lt;\/StyledLayerDescriptor&gt;<\/pre>\n<p>Ecco il risultato corretto:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1150\" src=\"\/wp-content\/uploads\/2016\/02\/geoserver-sld-right.png\" alt=\"geoserver-sld-right\" width=\"926\" height=\"468\" srcset=\"https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-right.png 926w, https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-right-300x152.png 300w, https:\/\/www.3dgis.it\/wp-content\/uploads\/2016\/02\/geoserver-sld-right-768x388.png 768w\" sizes=\"auto, (max-width: 926px) 100vw, 926px\" \/><\/p>","protected":false},"excerpt":{"rendered":"<p>State preparando una mappa del centro urbano: strade, aree verdi, edifici, zone industriali e con tutte le specificit\u00e0 di un piano di assetto del territorio.<br \/>\nPer ogni layer avete preparato la sua vestizione secondo lo standard SLD: siete sicuri di ottenere sempre quanto voluto?<\/p>\n","protected":false},"author":3,"featured_media":1139,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[10],"tags":[284,285,286],"class_list":["post-1130","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sviluppatori-gis","tag-geoserver","tag-sld","tag-standard"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/posts\/1130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/comments?post=1130"}],"version-history":[{"count":18,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/posts\/1130\/revisions"}],"predecessor-version":[{"id":1152,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/posts\/1130\/revisions\/1152"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/media\/1139"}],"wp:attachment":[{"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/media?parent=1130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/categories?post=1130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.3dgis.it\/it\/wp-json\/wp\/v2\/tags?post=1130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}