Default Style Rule in Mapnik - mapnik

In a Mapnik XML Style element, is there any way to set defaults for a given symbolizer? In the following example, I want the first rule to be the default and the second to change only the polygon color, i.e., use my default opacity of 0.5:
<Style name="MyStyle">
<Rule>
<PolygonSymbolizer fill="gray" fill-opacity="0.5"/>
</Rule>
<Rule>
<Filter>([some_field] < 2)</Filter>
<PolygonSymbolizer fill="red"/>
</Rule>
</Style>
What actually happens is that features matching the filter turn red AND have their opacity set to 1. Is there any way to get what I want without repeating the fill opacity in every rule?

As I know, you can not do that with rules. But you can use rgba colors for fill polygons with opacity.
Try this:
<Style name="MyStyle">
<Rule>
<PolygonSymbolizer fill="rgba(204, 204, 204, 0.5)" />
</Rule>
<Rule>
<Filter>([some_field] < 2)</Filter>
<PolygonSymbolizer fill="rgba(255, 0, 0, 0.5)" />
</Rule>
</Style>

Both what I originally thought was happening and Sergey's answer are only partially correct, so I'll post a fuller explanation here.
In Mapnik, all matching rules are applied in the order matched (given the default value for filter-mode). The examples in my question and Sergey's answer will render both polygon symbolizers, one on top of the other. In other words, a symbolizer in one rule really has nothing to do with a symbolizer in other rules, except that they all get stacked on top of each other unless filters are mutually exclusive. I can't think of a use for this behavior, but that's how it appears to work.
Summary: alternate versions of the same symbolizer must be placed in mutually exclusive rules and must explicitly set all desired options. There is no way to set a default symbolizer and partially override it.

Related

Proper accessibility for inline svg used multiple times on the same page

What is the proper way to make an inline svg accessible when it is used multiple times on the same page? An example would be a twitter icon in the header and footer, or a logo that is repeated throughout the page. From my research I believe the following is best for unique svgs:
<svg aria-labelledby="title">
<title id="title" lang="en">Red Rectangle</title>
<g>
<rect x="0" y="0" width="100" height="50" fill="red" />
</g>
</svg>
Using aria-labelledby and title, as well as description if needed. However in the case of an inline svg that is repeated, I have not been able to find an answer on the web. Is something like the following acceptable?
<svg role="img">
<title>Red Rectangle</title>
<g>
<rect x="0" y="0" width="100" height="50" fill="red" />
</g>
</svg>
Or what about just using aria-label? Thanks in advance!
The human side
Why your image is repeated multiple times ?
While choosing an alternative text for your image, remember that there are two kind of images on the web: illustrative images, and functional images.
The former don't absolutely need an alt text, while the later absolutely requires an alt text.
IF you give an alt text for the former, it should be a description of the image, while the alt text for the later must rather tell what the action is about than a simple visual description.
You can look at this question and my answer for more details about that.
IF your images are repeated multiple times, it's quite probable that they are functional ones. If we assume that it's the case:
If they all trigger exactly the same action, they must all have exactly the same label. Examples: several links to the same page, or a share icon at the beginning and the end of an article
If they don't trigger exactly the same action, or not on the same item, then they must all have different label. Example: add an item to cart. In that case, ideally, the label of the image should also tell on which item it operates.
The technical side
If your images are functional and all doing exactly the same action (see above), your problem is that you can't have multiple times the same id for a whole page.
Technically, referencing a <title> present in another SVG should work, but I would still prefer avoid it just in case. Inline SVG aren't as well supported than good old <img/> by screen readers.
It would be better to use good old <img/>, or generate unique ids.
Note that aria-label and aria-labelledby are guaranteed to work with all screen readers only on interactive/focusable elements.
If your images are focusable, then fine as long as all id are unique, although it would even be better to have the alt text as a visually hidden text in an enclosing link or button.
IF your images aren't focusable, keep in mind that aria-label/aria-labelledby may be totally ignored, but anyway in that case you have another accessibility problem: in principle, functional image should be made focusable, otherwise keyboard only users won't be able to trigger the action.

Is g id needed in SVG

This is a simple question but I can't find an answer that seems certain.
In an SVG where you'd see something like
<g id="Layer_3" data-name="Layer 3"><g id="Layer_3-1" data-name="Layer 1">
Is this something the SVG actually needs to have? They look the same when removed so I'm wondering if they're solely for identification?
No they are not required.
Even though if you are re-using same svg on a single page.
For example two SVG's with id="edit" it will cause ADA Compliance issue.

SVG USE XLINK sibling?

I have a reusable SVG component that contains some templated content. As part of the component default function, I'd like to include a shadow/reflection visual effect.
So, easy, right; use and done. Except, here's a reduced example to show the problem I'm having:
<svg>
<use xlink:href="#reflect"></use>
<g id="reflect">
<templated-content class="blue" />
</g>
</svg>
<svg>
<use xlink:href="#reflect"></use>
<g id="reflect">
<templated-content class="red" />
</g>
</svg>
Will each reflection be red, or blue? Because the element can be reused, and each instance is potentially different, I can't rely on a constant id attribute.
I'd prefer to avoid assigning id pairs to each instance via script. I couldn't find anything useful in the W3C xlink spec, but there's enough jargon there that I may have missed something.
Is there a supported way to include a relative use, or perhaps a similar result via another declarative feature?
EDIT: I know it is invalid to include multiple elements with the same id. That is why I want a way to create a reflection from a relative declarative reference. Can this be done?
Having two items with the same id in the same document is invalid.
A <use> element must point to an id and each id must be unique, there's no such thing as a relative <use>
Each reflection should be blue.
You'll need to generate unique ids.

set multiple 'begin' attributes for one 'set' element in svg

I'm currently creating an interactive SVG world map with a list of world language down the left and the map on the right. As the user hovers over the language names, the countries where it is spoken change their fill value. This works fine until I get to India, where I have Punjabi, Gujarati, and Hindi all spoken. The basic code works like this:
<g id="RussianL">
<path id="russia" d="blah blah blah" />
<set attributeName="fill" to="#CC3232" begin="Russian.mouseover" end="Russian.mouseout" />
</g>
...where 'Russian' is a text object corresponding to the word 'russian' on the left menu. Can I use this same strategy to represent India's languages (3 of which need to appear on this map)? I have tried just putting in three 'begin' attributes but that results in none of them working (in my up-to-date Chrome and Firefox at least).
So, is there a way to do this with inline code, or will I need to use javascript/jquery, or am I just using the wrong filetype for what I'm hoping to accomplish?
Thanks!
You want multiple set elements each with their own begin/end.
<set attributeName="fill" to="blue" begin="Punjabi.mouseover" end="Punjabi.mouseout" />
<set attributeName="fill" to="orange" begin="Gujarati.mouseover" end="Gujarati.mouseout" />
<set attributeName="fill" to="pink" begin="Hindi.mouseover" end="Hindi.mouseout" />

How can I scale an SVG <image> while maintaining whole pixels?

I have a pixelart-style image which intend to scale to 4x size with SVG. However, the following code blurs the pixels of the image:
<image x="0" y="0" width="1024" height="1024"
image-rendering="optimizeSpeed"
xlink:href="pixelart.bmp" />
Is there some attribute which will resolve this?
I think that image-rendering="optimizeSpeed" is the closest you can get. As the specs for that property state, it "should use a resampling algorithm which achieves the goal of fast rendering, with the requirement that the resampling algorithm shall be at least as good as nearest neighbor resampling." As this is the only section of the spec that mentions "nearest neighbor", I don't think you have any other option.
The only other related thing I can find is the IE9 property -ms-interpolation-mode:nearest-neighbor. This is (of course) IE specific, and is listed as a CSS property (so possibly only applicable to HTML).
Which OS/browser/version is giving you interpolated pixels as a result of upsizing with that attribute?
Also, note that you can use a combination of HTML5 Canvas and SVG to perfectly recreate your image with one SVG <rect> per pixel:
http://phrogz.net/tmp/canvas_image_zoom_svg.xhtml
CSS value image-rendering:pixelated; so:
<image x="0" y="0" width="1024" height="1024"
style="image-rendering:pixelated"
xlink:href="pixelart.bmp" />
This is from reading through the answer link above, in the "accepted" answer. It is not official as of time of writing, still "Proposed" for CSS4, but appears to be supported by Chrome already.

Resources