Geoserver raster with external SLD - geoserver

I want to use an external SLD (hosted in my server) for symbolizing a raster in Geoserver.
The SLD below works if used as default style in Geoserver. If I copy it (changing some colors) and put outside Geoserver, save as SLD (or XML), and call the GetMap with SLD=https://my_server/mySLD.sld the map I get is still with the 'default, Geoserver' style
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:se="http://www.opengis.net/se">
<NamedLayer>
<Name>my_schema:my_layer</Name>
<UserStyle>
<FeatureTypeStyle>
<Rule>
<RasterSymbolizer>
<Geometry>
<PropertyName>GRAY_INDEX</PropertyName>
</Geometry>
<Opacity>1</Opacity>
<ColorMap>
<ColorMapEntry color="#E69800" label="1" opacity="0.0" quantity="0.0"/>
<ColorMapEntry color="#1b4bde" label="Building" opacity="1.0" quantity="1.0"/>
<ColorMapEntry color="#bcbcbc" label="Ground cover" opacity="1.0" quantity="2.0"/>
</ColorMap>
</RasterSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
shortly, WMS call would be like this (also tried withou STYLES param)
https://my_geoserver_url/wms?service=WMS&version=1.1.0&request=GetMap&layers=my_schema:my_layer&STYLES=&SLD=https://my_server/my_sld.sld&transparent=true&bbox=...&format=image/png
I did this for dynamic filtering in vectorial data and all good (SLDs are created dynamically via PHP), so I am wondering if the problem is that with RASTER data is not possible

You are trying to operate in library mode:
Style lookup in library mode operates as follows:
For each layer in the layers list, the applied style is either a named style specified in the styles list (if present), or the layerdefault style
For a named style, if the external style document has a <NamedLayer>...<UserStyle> with matching layer name and style name, then it is used. Otherwise, the style name is searched for in the
catalog. If it is not found there, an error occurs.
For a default style, the external style document is searched to find a <NamedLayer> element with the layer name. If it contains a
<UserStyle> with the <IsDefault> element having the value 1 then that
style is used. Otherwise, the default server style for the layer
(which must exist) is used.
So you either need to provide a named style in the styles parameter or make your style a default style by adding <IsDefault>1</IsDefault> to it.

Related

How can I present a different next/Image based on the user's preferred color scheme?

I'm trying to use a next/image instead of a regular img tag in the code below. With the regular <img> tag, the following achieves exactly what I'm looking for:
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<img
src='https://via.placeholder.com/100/dddddd/000000.png'
width='100px'
height='100px'
alt='Placeholder image'
/>
</picture>
<p>Change your OS or browser's preferred color scheme to see a different image.</p>
</div>
Indeed, when I set my OS (or browser) to the dark theme, I get a dark image, and vice-versa for the light theme.
However, if I try the same thing with a next/image, I just get the light-themed image every time… I can't put this into a snippet because next/image requires a Next.js server, but here is the code that I'm using, which, in my tests, is backed by a Next.js development server with the appropriate image-related settings configured in next.config.js:
// pages/test.js
import Image from 'next/image'
export default function MyWebPage () {
return (
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<Image src='https://via.placeholder.com/100/dddddd/000000.png' width='100px' height='100px' alt='Placeholder image' />
</picture>
<p>You can change your OS or browser's preferred color scheme, but you'll always see the light-theme image.</p>
</div>
)
}
Here I never get the dark-themed image, unfortunately.
Theories:
Perhaps next/image doesn't interact with the <picture> tag exactly the same way as <img>? But I'm not finding anything online about using next/image with the <picture> tag…
Perhaps I should be providing this media-query-dependant source set in a different way when using next/image? But, I'm not finding any media attribute in the next/image docs…
Question:
How can I change the src of my next/image based on the user's preferred color scheme?
Non-solutions:
I could put 2 images on the page and use display: none on one of the two as a function of the user's preferred color scheme, but I'm hoping to find a solution that doesn't require so many duplicate images all over the place, which incurs a (small) performance penalty and makes the code that much harder to maintain, or that much more complex if a helper component is created.
I could change the src using Javascript when the page loads, but this would result in a flash of incorrectly styled content and generally does against my objective of having my page fully server-rendered and compatible with browsers where Javascript is turned off.
I could use cookies to let the server know about a user's color scheme preference and render the page consequently, but this would not work for the very first visit and comes with the requirement to include a cookie bar to inform the user of the reasons behind the use of cookies, as well as a way to opt-out.

Styling wms by request parameter

in general:
Is it possible to differently style some of the wms features from a single wms query based on the cql filter, or other parameter?
in particular:
on a wms query, returning the raster of a collection of features (i.e. points styled as red dots),
i wish geoserver to differrently style (blue dot) just one particular feature identified by a http-req-parameter sent with the wms request
keeping the others in the collection with default style
and avoiding an overlap of two wms:
A quicker (and probably easier) way than #Fmba's suggestion is to request the layer twice, once with the default color and a second time with a filter and a highlight style. You could either do this in one request or make two requests so that the browser can cache the default layer and only refetch the highlights.
For the first request it would look something like:
http://....../wms?service=wms&.....&layers=dots,dots&styles=,highlight&cql_filter=INCLUDE;INTERSECT(the_geom,%20POINT%20(-74.817265%2040.5296504))
This requests the layer (dots) twice, once with the default style (or you could use a named style here too) and then with the highlight style. Finally you must supply two filters (the first is just true to return everything).
while in the second you would just add another layer as usual.
You can use both filters and variable substitution for this.
Your SLD could be something like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- a Named Layer is the basic building block of an SLD document -->
<NamedLayer>
<Name>default_point</Name>
<UserStyle>
<!-- Styles can have names, titles and abstracts -->
<Title>Default Point</Title>
<Abstract>A sample style that draws a point</Abstract>
<FeatureTypeStyle>
<Rule>
<Name>rule1</Name>
<Title>Red Square</Title>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>square</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>
</Rule>
<Rule>
<Name>rule2</Name>
<Title>Blue Square</Title>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>name</ogc:PropertyName>
<ogc:Function name="env">
<ogc:Literal>element</ogc:Literal>
</ogc:Function>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>square</WellKnownName>
<Fill>
<CssParameter name="fill">#0000FF</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
See that we are using a parameter called 'element' (as we defined in the SLD) in the 'env' parameter (at the end of the request), wich you can assign a value in the wms request, so only the feature with a value of 'name_yo_want_to_filter' for the attribute 'name' would be rendered as blue, like this:
http://your_geoserver/wms?LAYERS=your_layer&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A25830&BBOX=177329.45520721,4198063.2254456,177681.24924735,4198495.164411&WIDTH=417&HEIGHT=512&env=element:name_yo_want_to_filter
Bear in mind that 'fid' would not be a valid parameter as it is usually hidden, so geoserver wont accept a 'PropertyIsEqualTo' filter of it.
Ref: http://docs.geoserver.org/latest/en/user/styling/sld-extensions/substitution.html
Ref: http://docs.geoserver.org/latest/en/user/styling/sld-reference/filters.html

How to extract image from IDML file using IDMLlib

I need to parse an IDML file and save the images separately from that file in formats for the Web. Can I do that IDMLlib? And if it's possible then can you show me some examples? P.S. The documentation of that library is awful, and the examples are horrible.
Yes, you can do it with IDMLlib, or by writing your own IDML parser (which is what I've done).
Images in IDML can be either embedded or linked. To extract an embedded image, you need to find the content node, as Jongware has described.
Here is an example of the IDML for an image that is not embedded:
<Image ItemTransform="1 0 0 1 -32.04 -35.04" Self="uf4" Name="$ID/" Visible="true" AppliedObjectStyle="ObjectStyle/$ID/[None]" GradientFillHiliteAngle="0" GradientFillHiliteLength="0" LocalDisplaySetting="Default" GradientFillAngle="0" GradientFillLength="0" GradientFillStart="0 0" VerticalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" HorizontalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" OverriddenPageItemProps="" LastUpdatedInterfaceChangeCount="" TargetInterfaceChangeCount="" ParentInterfaceChangeCount="" ImageTypeName="$ID/JPEG" ImageRenderingIntent="UseColorSettings" EffectivePpi="300 300" ActualPpi="300 300" Space="$ID/#Links_RGB">
<Properties>
<Profile type="string">$ID/None</Profile>
<GraphicBounds Right="64.08" Left="0" Bottom="70.08" Top="0"/>
</Properties>
<TextWrapPreference TextWrapMode="None" TextWrapSide="BothSides" ApplyToMasterPageOnly="false" Inverse="false">
<Properties>
<TextWrapOffset Right="0" Left="0" Bottom="0" Top="0"/>
</Properties>
<ContourOption ContourPathName="$ID/" IncludeInsideEdges="false" ContourType="SameAsClipping"/>
</TextWrapPreference>
<Link Self="uf7" LinkResourceSize="0~6561" LinkImportTime="2012-09-03T15:23:30" LinkImportModificationTime="2012-05-22T15:25:15" LinkImportStamp="file 129821703152428740 25953" ExportPolicy="NoAutoExport" ImportPolicy="NoAutoImport" CanPackage="true" CanUnembed="true" CanEmbed="true" ShowInUI="true" LinkObjectModified="false" LinkResourceModified="false" LinkClientID="257" LinkClassID="35906" StoredState="Normal" LinkResourceFormat="$ID/JPEG" LinkResourceURI="file:D:/Pictures/hkp.jpg" AssetID="$ID/" AssetURL="$ID/"/>
<ClippingPathSettings IncludeInsideEdges="false" Index="-1" AppliedPathName="$ID/" InsetFrame="0" Tolerance="2" Threshold="25" UseHighResolutionImage="true" RestrictToFrame="false" InvertPath="false" ClippingType="None"/>
<ImageIOPreference AlphaChannelName="$ID/" AllowAutoEmbedding="true" ApplyPhotoshopClippingPath="true"/>
</Image>
To find the image, you need to find the Link node that is a child of the Image node, and extract the value of the LinkResourceURI attribute, which is the path to the image. This is a local path, so you need to do all this on the same machine the IDML was authored on.
For an IDML document to be portable between machines, you need to embed the images using the Links panel in InDesign.
IDML files, very famously, do not 'contain' the base-64 encoded image data for linked images, only for embedded ones. For linked images only their physical locations on the original machine are stored.
Embedded images are found inside "Spread_uXX.xml" files, in a tag <Image>. This tag contains the image dimensions and some other meta-information, and a sub-tag <Contents> that lists the CDATA in Base-64. Be warned: there may be more than a single block of CDATA for each image.
The type of embedded images may or may not be the same as the original; the Image tag should declare the type in an attribute ImageTypeName. If the file format is not one you can use 'for the web', you need to convert it yourself.
I don't use IDMLlib so I cannot comment on its examples style.

How to render images in JSF 2.0

According to the JSF 2.0 specification, there are three ways to use h:graphicImage depending on the way by which JSF generates the "src" attribute of the HTML tag:
<h:graphicImage value="#{resource['images:next.gif']}"/>
<h:graphicImage library="images" name="next.gif"/>
<h:graphicImage url="/resources/images/next.gif"/>
The specification states that the first two should render exactly the same markup. In my JSF implementation (MyFaces 2.0.2), here is the output HTML that is generated:
<img src="/AppName/faces/javax.faces.resource/next.gif?ln=images">
<img src="/AppName/faces/javax.faces.resource/next.gif?ln=images">
<img src="/AppName/resources/images/next.gif">
So it seems that if I use (name, library) or (value) attributes, the image is always going to be streamed to the client by JSF's servlet. If I use (url) attribute, I can give direct link to the resource with no servlet intervention.
For me, the second approach - direct server URL to resource, is faster.
In what cases the first approach - specifying (name, library) or (value) attributes, be used?
For me, the second approach - direct server URL to resource, is faster.
The difference should be totally negligible. The "direct server URL to resource" approach also uses a servlet (the default servlet which is provided by the container). Please show your benchmark results.
In what cases the first approach - specifying (name, library) or (value) attributes, be used?
It allows you for serving the resources from within a JAR file. It also allows you for a nicer way of dynamically switching the library in the following manner:
<h:graphicImage library="#{user.prefs.looknfeel}" name="next.gif"/>
The library should actually point to a common resource library with all CSS/JS/images, not to a specific "images" library.
Related questions:
How to reference JSF image resource as CSS background image url
Changing JSF prefix to suffix mapping forces me to reapply the mapping on CSS background images

collective.xdv and multiple theme files

I am having different theme HTML files for different site sections. There are some major layout differences depending if the page is the front page, or a certain subsection.
As far as I see the default behavior is just to have one HTML file:
http://pypi.python.org/pypi/collective.xdv#usage
What would be the best strategy to use multiple theme files, slight rule variations and collective.xdv?
Plone 4.1b.
We usually just utilize plain xdv and use the rules.xml (or whatever you want to call it) file to setup the theme templates leaving the corresponding properties in the collective.xdv controlpanel empty. Nesting rules gives you quite some fexibility when asigning different templates:
<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns="http://namespaces.plone.org/xdv"
xmlns:css="http://namespaces.plone.org/xdv+css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<theme css:if-content="body.section-front-page" href="frontpage.html" />
<theme css:if-path="/section/subsection/somefolder" href="somefolder.html" />
...
<rules css:if-content="#visual-portal-wrapper">
<!-- The default theme -->
<theme href="theme.html" />
<rules css:if-content="body.section-somefolder">
<!-- Secific rules for somefolder go here -->
...
</rules>
</rules>
You should use the Alternate Themes settings to define alternative layouts when the url matches a specific regular expression.
For example, we have a Plone site named "Plone" and accessible at url localhost:8080/Plone. To provide a different layout for the Home page, we can define the following in the registry (or TTW in the Plone Control Panel > XDV Settings section):
<record field="alternate_themes" interface="collective.xdv.interfaces.ITransformSettings" name="collective.xdv.interfaces.ITransformSettings.alternate_themes">
<field type="plone.registry.field.List">
<description>Define alternate themes and rules files depending on a given path. Should be of a form 'path theme rules' (or 'path rules' with xdv 0.4), where path may use a regular expression syntax, theme is a file path or URL to the theme template and rule is a file path to the rules file.</description>
<required>False</required>
<title>Alternate themes</title>
<value_type type="plone.registry.field.TextLine">
<title>Theme</title>
</value_type>
</field>
<value>
<element>^.*/Plone(/)?$ python://my.xdvtheme/templates/alternative/index.html python://my.xdvtheme/rules/alternative/index-rules.xml</element>
</value>
</record>
This way, the home page will use the alternative layout, while all the other pages will use the main layout specified in Theme template and Rules template
You can provide multiple definitions according to the different sections of your site.
My personal Plone site uses different theme and rules files for different parts.
Are you using the XDV control panel at /##xdv-settings?
In the Theme template and Rules File fields I put my default (i.e most used) files.
In the Alternate Themes textbox you can then provide alternate theme and rules files depending on a given path.
The format is path theme rules.
Here are some examples from my website's config:
.*/login_form|.*logged_out
/home/zope/production/theme/theme.html
/home/zope/production/theme/login.xml
/media/blog$
/home/zope/production/theme/blog.html
/home/zope/production/theme/blog.xml
/media/software
/home/zope/production/theme/software.html
/home/zope/production/theme/media.xml
As you can see, you can use regular expression syntax to match the paths.
The first line is for styling the login and logout pages.
The second for styling only my blog's landing page (henche the $)
the third styles my software page.
Works like a charm.

Resources