GeoServer LineSymbolizer avoid overlapping and graphic bending - styling

Under the geoserver styling, how to set the LineSymbolizer tag to avoid line-overlapping. When I am zooming out, the geoserver is arbitrarily putting one line on top of another if they are too close to each other.
Additionally, the following XML code is allowing me to use "arrow" graphics for LineSymbolizer. But how to allow these arrows to bend at the corners?
<LineSymbolizer>
<Stroke>
<GraphicStroke>
<Graphic>
<Mark>
<WellKnownName>ttf://FreeSerif#0x279f</WellKnownName>
<Fill>
<CssParameter name="fill">#00B22D</CssParameter>
</Fill>
</Mark>
<Size>30</Size>
</Graphic>
</GraphicStroke>
</Stroke>
</LineSymbolizer>

We hide some line objects depending on the zoom level. For example, in small scale we show just big rivers. Try to use Zoom-based lines http://docs.geoserver.org/2.5.x/en/user/styling/sld-cookbook/lines.html#zoom-based-line .
For setting arrows' direction try to use attribute followLine http://docs.geoserver.org/stable/en/user/styling/sld-cookbook/lines.html#label-following-line .

Related

SVGPanZoom discards original viewBox

I am using SVGPanZoom to manage the zooming of an SVG image in my hybrid Android (for all intents and purposes the same behavior as in Chrome) app. While zooming works well I have found a strange issue. My original inline SVG element goes like this
<svg id='puzzle' viewBox='0 0 1600 770' preserveAspectRatio='none'
width='100vw' height='85.5vh' fill-rule='evenodd' clip-rule='evenodd'
stroke-linejoin='round' stroke-miterlimit='1.414'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://
www.w3.org/1999/xlink'>
Initially this SVG element is empty and gets populated programmatically from JavaScript at run time after which I initiate SVGPanZoom as follows
var panZoom = svgPanZoom('#puzzle',
{panEnabled:false,controlIconsEnabled:false,
zoomEnabled:true,dblClickZoomEnabled:true,onZoom:postZoom});
panZoom.refreshRate = 10;
panZoom.zoomScaleSensitivity = 0.02;
The problem I have run into is this - I want my SVG image to fill the available area, 100vw x 85.5vhcompletely to do which I instruct it via the preserveAspectRatio="none"attribute above along with the viewBox="0 0 1600 770" attribute. I have found that this works - so long as I don't use SVGPanZoom. As soon as I initiate panZoom thezoomBox`attribute gets stripped out and I end up with an image that does not quite behave in terms of its default stretching/filling behavior.
SVGPanZoom is widely used so I assume that this behavior is down to me not quite setting it up properly. Dipping into the code I have found SVGPanZoom creates a cacheViewBoxand then proceeds to remove the original zoomBox attribute.
Which is fine if after that zooming works and the original behavior of the application does not change which is not what I find. What am I doing wrong here?
I've also run into this issue recently. From my research, this is just how the library works. I chose to live with this limitation for now but I found a couple other libraries that may work the way you intend (I haven't tried them yet):
jquery.panzoom is a jquery library that provides this functionality and also has some nice features. I know many people try to avoid jquery but it's pretty small and may do what you want. It handles SVG but I don't know what it does with the viewBox attribute.
react-svg-pan-zoom is a react component which may be useful if you are working in react.
I've also tried the PanZoom library but this also suffers the same viewBox limitation.
A note for anyone running into this thread. In the end I abandoned SVGPanZoom and decided to eschew the route of using any pan/zoom library at all. At the same time I decided to completely stop using the SVG viewBox and handle all zooming/panning entirely on my own through SVG transforms. The core steps involved
Wrap the entire SVG contents in a group to make it easier to manage the transform. I use the id attribute gOuter for this group
Set an initial scale for the SVG to occupy the desired client rectangle. In my case I had an original viewBox of 0 0 1600 770 intended to occupy 100% of screen width and 85% of screen height. So my scaling was scaleX = 1600/window.innerWidth and scaleY = 770/)0.85*window.innerHeight).
Apply this initial transform to the wrapping outer group, gOuter.setAttribute('transform','0 0 scaleX,scaleY)
Now in order to zoom to a an object whose virtual top left hand coordinates in the original viewBox were Ox,Oy you would use the transform
gOuter.setAttribute('transform',
scale(scaleX,scaleY) translate(-Ox,-Oy) scale(2*scaleX,2*scaleY) translate(Ox,Oy))
to zoom in by a factor of x 2. The important things to understand here
In SVG transformations are applied right to left.
Here we are translating the zoom point to the top l.h.s. scaling and then translating it back to its original location.
The problem is that we also need to allow for the original level of zoom through the initial scaling so we tag that on as one last transform
This leaves you in complete control of the zooming process and as a fringe benefit the operation becomes considerably more smooth than when using a pan/zoom library.

SVG Drop Shadow Spread

I'm trying to manipulate SVG drop shadows (to emulate material design elements).
An element in material design contains 3 drop shadows of varying values depending on what level of elevation they are at. The best solution I have found to emulate this with an SVG element is to use CSS filter's drop shadow. This, however, doesn't support spread. Does anyone know a workaround that would allow me to manipulate the spread of the shadow? The only solution I can think of is creating 3 separate elements, 1 for each shadow and scaling that actual element, which seems over the top.
You can manipulate the spread of a shadow using feComponentTransfer/feFuncA. For example:
<feGaussianBlur stdDeviation="5"/>
<feComponentTransfer>
<feFuncA type="gamma" exponent="0.5" amplitude="2"/>
</feComponentTransfer>
I wrote a tool mimicking Photoshop's dropshadow control outputting a valid SVG filter: you can use it (and see the source) here:http://codepen.io/mullany/pen/sJopz

Change multiple colors of a SVG object

I have a SVG logo rendered to the canvas using fabric.js, the original SVG is all black in color but I need the user to be able to change the color of each different parts of the logo, resulting in a object with multiple colors, e.g.:
wikimediauruguay.org/images/5/53/Wikimedia-logo.png
How can I achieve this? If I just use object.setFill() it changes the color of the entire object but I need to change the color of every part separately to whatever colors the user choose. Thanks.
EDIT: found the solution, just posted my answer below in case somebody else has the same question.
Perhaps someone who knows something about fabric.js would answer in a way that makes more sense for your case, but with plain old svg, an object is often a <g< element with things ( like <rect>, <path>, <ellipse>) inside. Each child of the group, can have its own event handler:
<g>
<path onclick='handle(evt)' attrs=stuff />
<rect onclick='handle(evt)' attrs=stuff />
<circle onclick='handle(evt)' attrs=stuff />
</g>
The function activated by the click can then interrogate evt.target to see which of the subelements received the click, sorta like this:
if (evt.target.nodeName=="path") {evt.target.setAttribute("fill","purple")}
Solved mi problem in a very simple way: I just needed to edit the SVG on Illustrator so that every different colored part of the logo will be on a different layer, then when I loaded the SVG via fabric.loadSVGFromURL() each layer will be treated as a different object by fabric.js, then I just could edit each object (layer) separately (setFill(), etc).

Writing a custom text at an arbitrary position in a chart

I've created a nice chart but there's one thing missing. I'd like to be able to set a text somewhere in it. The optimal solution would be e.g. the current date smacked in huge yellow letters right in the middle of my graph.
I've googled for such a thing but none of the links (proof that I've googled #1, proof that I've googled #2) gave any hints on whether it's possible or not. In fact, the mock-up image in the second link would be something for me if the descriptions and arrows weren't drawn afterwards in an image processor.
NB. It's not a report at all. It's just a chart - a single, lonely chart - that displays values of a couple of series. I get to control the appearance, the legend etc. However, I'd like to put a floating text object (DIV formatable by CSS would be perfect), sprite, overlay, call it whatever you'd like, that will get its value from a given field (e.g. the current date).
And if I can position it freely anywhere over the graph, that'd be even "perfecter" but I'd settle for placement on form "top-right" or such. Alternatively, if there's an option to combine two "views" on top of each other or anything like that (I'm beating around the bushes with this).
Is that achievable and if so how?
Right, I've had a play, a good dig around with the SDK, a bit of a google and this is the best I can come up with.
I know how to place text at arbitary positions on the chart, but only with static text, e.g. I don't know how to bind the text dynamically to anything - I suspect this is more to do with CRM than Charts, I couldnt find much documentation for CRM and Charts.
So I've found that TextAnnotation allow you to bascially place text wherever you like. This is contained within theAnnotations collections.
For example:
<Chart>
...
<Annotations>
<TextAnnotation Text="This is an annotation" Name="TextAnnotation1" X="20" Y="50">
</TextAnnotation>
</Annotations>
...
</Chart>
So important to note that the position of the TextAnnotation is relative, e.g. the annotation will appear 20% of the width of the chart from the left. 0,0 is the top left corner. The MSDN has some more detail on positioning.
So I can create a chart like this:
HELLO WORLD! is the annotation.
Using this xml:
<Chart Palette="None" PaletteCustomColors="55,118,193; 197,56,52; 149,189,66; 117,82,160; 49,171,204; 255,136,35; 97,142,206; 209,98,96; 168,203,104; 142,116,178; 93,186,215; 255,155,83">
<Series>
<Series ShadowOffset="0" IsValueShownAsLabel="True" Font="{0}, 9.5px" LabelForeColor="59, 59, 59" CustomProperties="PieLabelStyle=Inside, PieDrawingStyle=Default" ChartType="pie">
<SmartLabelStyle Enabled="True" />
</Series>
</Series>
<ChartAreas>
<ChartArea>
<Area3DStyle Enable3D="false" />
</ChartArea>
</ChartAreas>
<Legends>
<Legend Alignment="Center" LegendStyle="Table" Docking="right" IsEquallySpacedItems="True" Font="{0}, 11px" ShadowColor="0, 0, 0, 0" ForeColor="59, 59, 59" />
</Legends>
<Titles>
<Title Alignment="TopLeft" DockingOffset="-3" Font="{0}, 13px" ForeColor="0, 0, 0"></Title>
</Titles>
<Annotations>
<TextAnnotation Text="HELLO WORLD!" Font="Stencil, 15.75pt, style=Bold, Italic, GdiCharSet=0" Name="TextAnnotation1" X="20" Y="50" ForeColor="Orange">
</TextAnnotation>
</Annotations>
</Chart>
If that doesnt achieve your requirements I would suggest having a look at an SSRS report or some other custom piece IFramed into the dashboard.
You might want to check this link where they put descriptive text on a map. I haven't got that to work (didn't try very hard, either) but it's pretty easy to set just some text instead of a graph by the following code.
<visualization>
<primaryentitytypecode>blobb</primaryentitytypecode>
<name>My custom name</name>
<webresourcename>MyCustomHttpFile</webresourcename>
</visualization>
I would be nice indeed to surprise a customer with a flash text sometimes so the idea is worth exploring. Strangely, I haven't found any good guide on how to do that.

Windows Store App: using XAML paths in Grid layouts (C#/XAML)

I'm starting out the design of my app by using one of the templates provided with VS2012, where you have an Image displayed next to some TextBlocks. I want the user to be able to pick a photo or similar to be the image but, in the event that they haven't done this, I want to provide a default icon.
My initial thinking was to create PNGs of the different default icons, at the different sizes that the Image icons appear at and just return those from the binding if the user hasn't specified an image, but it occurred to me that if I can use XAML Paths instead, the default icons will appear crisper because they will be drawn as vectors rather than bitmaps.
I'm not sure if that decision is a mistake but it is causing me a few headaches :-(.
The first challenge I've tried to solve is how to use binding to display either an image or the XAML Paths. My solution here was to use a Button instead of the Image, and bind Content. The Content binding returns a Canvas object that either holds the Image or the set of Paths that define the icon.
That works until I change to the snapped view, which then has smaller Image/Button elements than the unsnapped view.
So the second challenge, and the primary reason for this question, is to seek advice on how best to deal with the differing sizes of the Buttons. In the unsnapped view, the Button is 110x110. In the snapped view, the Button is 60x60. In the research I've done, the simplest way to resize the paths seems to be to use a Transform on the Canvas but since the Canvas is being returned from the Binding call, the code-behind won't necessarily know what size the parent Button is and therefore won't be able to include the Transform.
I can't use a DrawingBrush because these aren't valid in Windows Store Apps.
Is there a clean solution to this or should I go back to the simpler but slightly lower quality solution of using pre-created PNGs?
Thanks.
The solution I adopted in the end was to use two items - a button and an image - each wrapped in a border that allowed me to make only one of the items visible, depending on whether or not a bitmap image was available:
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="250" Height="250" Visibility="{Binding ImageIsAvailable, Converter={StaticResource HideIfTrue}}">
<Button Content="{Binding ImageContent}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20,0,0" Style="{StaticResource UnstyledGraphicsButtonStyle}" Width="{Binding ImageWidth210}" Height="{Binding ImageHeight210}" Foreground="white" Padding="0" Background="Transparent" BorderBrush="{x:Null}" IsEnabled="False" />
</Border>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Visibility="{Binding ImageIsAvailable, Converter={StaticResource DisplayIfTrue}}">
<Image Source="{Binding Image250}" Stretch="{Binding Stretch250}" AutomationProperties.Name="{Binding Title}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
In this example, I'm wanting the item to be 250px by 250px. The binding for Stretch is so that I can handle images that are bigger and smaller than 250px and stretch accordingly.
For the button, the content actually comes from a declared string resource, e.g.:
<x:String x:Key="building">M13.982995,32.651007L13.982995,37.332006 18.665994,37.332006 18.665994,32.651007z M5.3319988,32.440006L5.3319988,37.332006 10.225996,37.332006 10.225996,32.440006z M34.665606,29.33198L34.665606,37.313 37.332797,37.313 37.332797,29.33198z M29.332198,29.33198L29.332198,37.340984 31.999405,37.340984 31.999405,29.33198z M13.923995,24.000005L13.923995,28.740005 18.665994,28.740005 18.665994,24.000005z M5.3319988,24.000005L5.3319988,28.839005 10.171997,28.839005 10.171997,24.000005z M34.665606,18.665992L34.665606,26.684976 37.332797,26.684976 37.332797,18.665992z M29.332198,18.665992L29.332198,26.644998 31.999405,26.644998 31.999405,18.665992z M13.331995,16.000003L13.331995,18.666003 15.998995,18.666003 15.998995,16.000003z M7.9989967,16.000003L7.9989967,18.666003 10.665997,18.666003 10.665997,16.000003z M26.665998,13.331976L39.998998,13.331976 39.998998,42.666973 26.665998,42.666973z M13.331995,10.666002L13.331995,13.332002 15.998995,13.332002 15.998995,10.666002z M7.9989967,10.666002L7.9989967,13.332002 10.665997,13.332002 10.665997,10.666002z M10.665997,0L13.331995,0 13.331995,5.3340011 15.998995,5.3340011 18.665994,10.666002 18.665994,18.666003 21.331993,18.666003 23.998992,21.332004 23.998992,42.667007 0,42.667007 0,21.332004 2.6659985,18.666003 5.3319988,18.666003 5.3319988,10.666002 7.9969978,5.3340011 10.665997,5.3340011z</x:String>
This comes from Metro Studio.
The height and width bindings are because my different SVG items have different width & height ratios so I bind to code-behind to return the correct figures for the desired size. Unfortunately because you can't pass parameters, I end up with different "ImageHeightXXX" calls for different values of XXX depending on the XAML.
Advice on how to get the string defined can be found here: http://www.jayway.com/2012/11/27/styling-windows-8-4-the-button/

Resources