|
View:
New views
17 Messages
—
Rating Filter:
Alert me
|
|
|
Dynamic Elements on zoomI need to build a map system for a GIS with some elements' size independent by the zoom level applied.
I've found a lot of questions about this issue but nobody looks like to have an idea on what to do, so I hope the Batik's designers could give an idea on what to do, or take this topic as an idea for improving a new functionality to this really useful library (this would give Batik even more value, because this kind of applications erally need these features). Such zoom-invariant elements are for example the stroke size of the streets, the size of text, some drawings size (like the car accident), ecc.. I understand it's a large problem. The approach about stroke sizes could be to modify the DOM element's property with: element.setAttributeNS("stroke-size", ..whatever..); This works, but this approach modifies the DOM elements properties and is not really elegant. So another solution could be to bind DOM with GVT using the rendered objects of the GVT by the BridgeContext and modifying the affinetransform of them, like: GraphicsNode graphicsNode = bridgeContext.getGraphicsNode(element); AffineTransform at = graphicsNode.getTransform(); ..and then applying it the inverse CTM of the root node. But this even doesn't work, because the transformation gives back an element which doesn't fit on the previous Bounding Box. I was thinking to try to apply also the previous bounding box to the element, but how? Another approach could be to modify the stroke rendering size with the StrokeShapePainter, like: StrokeShapePainter ssp = new StrokeShapePainter(); ssp.setShape(elementShape); ssp.setStroke(new Stroke(..whatever..)); ..but how to determine the elementStroke Shape object? I can't understand which Java interfaces and object to call. Maybe the org.apache.batik.gvt.ShapeNode class, but how? And what about text size? How could I change it dinamically depending on zoom size if I neither can get a zoom factor? There are no examples for these issues and following the abstract dependencies of the library is really hard. It would be nice to have some "generic example code" to insert inside mine, like the great examples that are actually on the site. Please help, I'm not an experienced Java programmer and my work actually depends on this. Waiting for an answer of yours I congratulate for the work you've done for supporting the SVG format on Java with such a big open project. Thank you. |
|
|
Re: Dynamic Elements on zoomHi mistercase,
> I need to build a map system for a GIS with some elements' size independent > by the zoom level applied. Humm... This sounds like another 'déjà vu' from a similar, recent thread [1]. ;-) (Weirdly, the message didn't seem to show up in Nabble, so I'm not sure if that was why it was issued again.) Note that mailing list messages can get lost sometimes so feel free to "ping" after a while just to make sure that it wasn't the case, but please try to do it within the same thread whenever possible. In this particular case, for example, I still had the previous one in my list for processing whenever possible (time is a finite resource, unfortunately!). > I've found a lot of questions about this issue but nobody looks like to have > an idea on what to do [...] Well, I wouldn't put things that way. There's at least a related thread [2] and, given that it was found in a few seconds, I'm convinced the proper keywords will find a lot more. Also, I recall somehow recent (deep!) debates on affine transforms, which would be pretty useful for getting this sort of effects! ;-) > Such zoom-invariant elements are for example the stroke size of the streets, > the size of text, some drawings size (like the car accident), ecc.. I > understand it's a large problem. In terms of invariable stroke width, SVG Tiny 1.2 specifically defines that in the "non-scaling-stroke" value for the "vector-effect" property [3]. Unfortunately, as far as I know, Batik doesn't implement this yet (anyone feels like contributing this simple and yet interesting/valuable feature?). > ..and then applying it the inverse CTM of the root node. But this even > doesn't work, because the transformation gives back an element which doesn't > fit on the previous Bounding Box. Well, I'm convinced an approach like this will work. Samuel Dagan's Zoom and Pan [4] proof-of-concept employs this in a scripted environment. By using Batik's infrastructure performance will certainly improve. The sample makes the control element the same size relative to document size; if one would want that but relative to an absolute size, just needs to apply a similar transform during the document load event. ;-) > Waiting for an answer of yours [...] Hope this helps, Helder [1] http://mail-archives.apache.org/mod_mbox/xmlgraphics-batik-users/200904.mbox/%3C23138230.post@...%3E [2] http://www.nabble.com/Custom-Scaling-tt13513744.html [3] http://www.w3.org/TR/SVGTiny12/painting.html#VectorEffectProperty [4] http://alzt.tau.ac.il/~dagan/tools/#zoom --------------------------------------------------------------------- To unsubscribe, e-mail: batik-users-unsubscribe@... For additional commands, e-mail: batik-users-help@... |
|
|
Re: Dynamic Elements on zoomThis is what I call a speedy answer :-)
I will try immediately. Thank you!
|
|
|
Re: Dynamic Elements on zoom>> Such zoom-invariant elements are for example the stroke size of the streets,
>> the size of text, some drawings size (like the car accident), ecc.. I >> understand it's a large problem. >In terms of invariable stroke width, SVG Tiny 1.2 specifically defines >that in the "non-scaling-stroke" value for the "vector-effect" >property [3]. Unfortunately, as far as I know, Batik doesn't implement >this yet (anyone feels like contributing this simple and yet >interesting/valuable feature?). My first subproblem is how to set the size of the rendered Shape on the GVT. I tried to solve this feature working on the StrokeShapePainter. BridgeContext bc = ((JSVGCanvas)c).getUpdateManager().getBridgeContext(); GraphicsNode gn = (GraphicsNode)bc.getGraphicsNode(element); StrokeShapePainter ssp = new StrokeShapePainter(gn.getOutline()); ssp.setStroke(new BasicStroke(...whatever...)); ...but then how can I do for updating the GraphicsNode on this Shape? I tried to get the Paint object and set it on a Graphics2D instance but it doesn't work.. or at least I don't know how to make it work. |
|
|
Re: Dynamic Elements on zoomHi mistercaste,
> My first subproblem is how to set the size of the rendered Shape on the GVT. > I tried to solve this feature working on the StrokeShapePainter. Have you crawled the mailing list for answers? Most of the questions asked have usually already been in the past! ;-) I'd suggest the Nabble front-end to the mailing list [1], which makes searching a bit more comfortable. > ...but then how can I do for updating the GraphicsNode on this Shape? > I tried to get the Paint object and set it on a Graphics2D instance but > it doesn't work.. or at least I don't know how to make it work. Note that the Batik site holds a small yet very useful set of documentation (including sample code) from which I'd quickly suggest a couple of pages [2] [3] which seem appropriate. Hope this helps, Helder [1] http://www.nabble.com/Batik-f308.html [2] http://xmlgraphics.apache.org/batik/using/scripting/java.html [3] http://xmlgraphics.apache.org/batik/using/dom-api.html --------------------------------------------------------------------- To unsubscribe, e-mail: batik-users-unsubscribe@... For additional commands, e-mail: batik-users-help@... |
|
|
Re: Dynamic Elements on zoomHi Mistercaste, mistercaste <mistercaste@...> wrote on 05/20/2009 05:38:12 AM: > >> Such zoom-invariant elements are for example the stroke size of the > >> streets, the size of text, some drawings size (like the car accident), > >> ecc.. I understand it's a large problem. > > >In terms of invariable stroke width, SVG Tiny 1.2 specifically defines > >that in the "non-scaling-stroke" value for the "vector-effect" > >property [3]. Unfortunately, as far as I know, Batik doesn't implement > >this yet (anyone feels like contributing this simple and yet > >interesting/valuable feature?). Let me first say that this isn't particularly simple. The main problem is that the BBOx of an element will change when the transform on another element changes - which trust me is just weird. To really support this (and the perhaps more interesting vector effects in general) you need to support a fairly robust 'event' tracking system in the GVT. So the child GN can register with all the elements in the tree above it for transform changes and then update it's stroke (and hence it bounds when any of them changes). The problem is that such systems while simple in concept are extremely prone to causing memory leaks. > My first subproblem is how to set the size of the rendered Shape on the GVT. > I tried to solve this feature working on the StrokeShapePainter. > > BridgeContext bc = ((JSVGCanvas)c).getUpdateManager().getBridgeContext(); > GraphicsNode gn = (GraphicsNode)bc.getGraphicsNode(element); > > StrokeShapePainter ssp = new StrokeShapePainter(gn.getOutline()); > ssp.setStroke(new BasicStroke(...whatever...)); > ...but then how can I do for updating the GraphicsNode on this Shape? ShapeNode.setShapePainter(ShapePainter painter) Be aware that you will need to account for any possible fill and marker painters in addition to the stroke painter. > I tried to get the Paint object and set it on a Graphics2D instance but > it doesn't work.. or at least I don't know how to make it work. Since you are hitting the GVT tree directly (as opposed to say updating the 'stroke-width' attribute in the DOM (or better adjusting a stylesheet) I'm not sure how you are rendering the document. Also if the DOM tree is live you need to be careful that DOM tree doesn't overwrite your changes to the GVT tree. |
|
|
Re: Dynamic Elements on zoomThank you Thomas, I was feeling a little bit incapable ;-p
I tried to use the ShapeNode as follows: BridgeContext bc = ((JSVGCanvas)c).getUpdateManager().getBridgeContext(); GraphicsNode gn = (GraphicsNode)bc.getGraphicsNode(element); StrokeShapePainter ssp = new StrokeShapePainter(gn.getOutline()); ssp.setStroke(new BasicStroke(...whatever...)); ShapeNode sn = new ShapeNode(); sn.setShapePainter(ssp); ..but it doesn't update the element :-( I actually render everything on a JSVGCanvas with the default Swing components. I'm not really experienced, so... help me please :-) |
|
|
Re: Dynamic Elements on zoomI realized that in the BridgeContext class when i get a GraphicsNode like in the following code i get a null return value.
BridgeContext bc = ((JSVGCanvas)c).getUpdateManager().getBridgeContext(); GraphicsNode gn = (GraphicsNode)bc.getGraphicsNode(element); System.out.println(gn); --------------> null What can I do? The "c" element is an element i get by clicking on the canvas, so it shouldn't give any problem, but when i get it's BridgeContext (which is not null) I can't get the corresponding element. Any help/suggestion appreciated. Thx |
|
|
Re: Dynamic Elements on zoomHi Mistercaste,
mistercaste <mistercaste@...> wrote on 10/21/2009 03:19:42 PM: > I realized that in the BridgeContext class when i get a GraphicsNode like in > the following code i get a null return value. > > > BridgeContext bc = ((JSVGCanvas)c).getUpdateManager().getBridgeContext(); > GraphicsNode gn = (GraphicsNode)bc.getGraphicsNode(element); > System.out.println(gn); > > What can I do? The "c" element is an element i get by clicking on the > canvas, This doesn't make sense, "c" must be the JSVGCanvas (otherwise the cast would fail). I'm much more interested in knowing where 'element' comes from. > so it shouldn't give any problem, but when i get it's BridgeContext > (which is not null) I can't get the corresponding element. Typically the problem is that 'element' isn't the right element. There can be a number of possible reasons for this. How do you get 'element' and what does the structure of the SVG document look like around the element you are trying to find the GN for? |
|
|
Re: Dynamic Elements on zoomI get the Element with the getElementById(String) method. It surely works, I tried to print the result. Here is the code. I based my work on the Batik sources. Sorry for it's longness.
canvas.getInteractors().add(new AbstractZoomInteractor() { ... @Override public void mouseReleased(MouseEvent e) { finished = true; JGVTComponent c = (JGVTComponent) e.getSource(); <------------- HERE I GET THE COMPONENT c.getOverlays().remove(overlay); overlay.paint(c.getGraphics()); xCurrent = e.getX(); yCurrent = e.getY(); if ((xCurrent - xStart) != 0 && (yCurrent - yStart) != 0) { int dx = xCurrent - xStart; int dy = yCurrent - yStart; if (dx < 0) { dx = -dx; xStart = xCurrent; } if (dy < 0) { dy = -dy; yStart = yCurrent; } Dimension size = c.getSize(); float scaleX = size.width / (float) dx; float scaleY = size.height / (float) dy; float scale = (scaleX < scaleY) ? scaleX : scaleY; AffineTransform at = new AffineTransform(); at.scale(scale, scale); at.translate(-xStart, -yStart); at.concatenate(c.getRenderingTransform()); c.setRenderingTransform(at); SVGDocument docum = canvas.getSVGDocument(); Element element = docum.getElementById("MySvgElement"); <- HERE I GET THE SVG ELEMENT UpdateManager um = ((JSVGCanvas) c).getUpdateManager(); <- JGVTComponent to JSVGCanvas BridgeContext bc = um.getBridgeContext(); System.out.println("BC: " + bc.toString()); <-------------- THIS RETURNS SOMETHING GraphicsNode gn = (GraphicsNode) bc.getGraphicsNode(element); System.out.println("GN: " + gn); <------------------------- THIS RETURNS NULL } } }); thx |
|
|
Re: Dynamic Elements on zoomHi Mistercaste,
mistercaste <mistercaste@...> wrote on 10/22/2009 07:24:44 AM: > I get the Element with the getElementById(String) method. Ok, most of the stuff looks fine. So I suspect your element is in a 'defs' or perhaps part of a subtree that has 'display="none"' set on it. You may still think the element should have a graphics node because there may be a use element that references it but it doesn't (we create a 'copy' since a used element may actually be associated with many GN). The one thing that isn't quite right here is that you should really only look at the DOM/GN tree from the UpdateManager. I don't think this is your problem but I mention it for the benefit of others. > SVGDocument docum = canvas.getSVGDocument(); BTW it's important to make sure the document you are working with came from the canvas. If your document isn't using the Batik DOM then we need to copy it so that it Does use the Batik DOM (with CSS, DOM events, etc support). > Element element = docum.getElementById("MySvgElement"); <- HERE I GET THE SVG ELEMENT Can you forward a skeleton SVG file that shows where/what MySvgElement is? > UpdateManager um = ((JSVGCanvas) c).getUpdateManager(); <- JGVTComponent to JSVGCanvas > BridgeContext bc = um.getBridgeContext(); > System.out.println("BC: " + bc.toString()); <-------------- THIS RETURNS SOMETHING > GraphicsNode gn = (GraphicsNode) bc.getGraphicsNode(element); > System.out.println("GN: " + gn); <------------------------- THIS RETURNS NULL |
|
|
Re: Dynamic Elements on zoomI verified the Element source (actually I'm adjusting a code
inherited by someone else), and it has a "use" property as predicted. Is it possible to get it's GraphicNode? I post here a piece of my code as example. It may be useful to other users (draws an accident signal). public void defineSymbol() { Element symbol = m_doc.createElementNS(STRSVGNS, "symbol"); symbol.setAttribute("id", "MySvgElement"); symbol.setAttributeNS(null, "viewBox", "0 0 200 200"); m_elDefs.appendChild(symbol); Element element = m_doc.createElementNS(STRSVGNS, "rect"); element.setAttributeNS(null, "height", "200"); element.setAttributeNS(null, "width", "200"); element.setAttributeNS(null, "style", "fill:#d40000"); symbol.appendChild(element); Element elGroup = m_doc.createElementNS(STRSVGNS, "g"); elGroup.setAttributeNS(null, "style", "fill:white"); symbol.appendChild(elGroup); // Auto element = m_doc.createElementNS(STRSVGNS, "path"); element.setAttributeNS(null, "d", "M 137 73 L 88 76 L 84 93 L 84 93 L 84 93 L 84 93 " + "L 84 93 L 88 110 L 137 114 L 188 112 L 188 93 L 188 93 " + "L 188 75 L 137 73 z M 139 75 L 139 80 L 124 80 L 115 76 " + "L 139 75 z M 141 75 L 164 76 L 157 80 L 141 80 L 141 75 z " + "M 169 76 L 169 93 L 169 93 L 169 110 L 161 106 L 161 93 L 161 93 " + "L 161 80 L 169 76 z M 113 78 L 124 81 L 124 93 L 124 93 " + "L 124 106 L 113 109 L 113 93 L 113 93 L 113 78 z M 124 107 " + "L 139 107 L 139 112 L 115 110 L 124 107 z M 141 107 " + "L 157 107 L 164 111 L 141 112 L 141 107 z"); element.setAttributeNS(null, "id", "auto"); elGroup.appendChild(element); element = m_doc.createElementNS(STRSVGNS, "use"); <------------------- USE ELEMENT element.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#auto"); element.setAttributeNS(null, "transform", "rotate(242) translate(-257,-90)"); elGroup.appendChild(element); element = m_doc.createElementNS(STRSVGNS, "path"); element.setAttributeNS(null, "d", "M 76.463263,77 L 60.523039,42 L 64.508095,40 L 76.463263,77 z " + "M 80.697385,75 L 74.470735,35 L 79.202989,35 L 80.697385,75 z " + "M 84.433375,76 L 89.912827,38 L 94.146949,38 L 84.433375,76 z " + "M 106.35118,122 L 135.74097,134 L 134.49564,137 L 106.35118,122 z " + "M 110.08717,127 L 134.49564,150 L 130.51059,152 L 110.08717,127 z " + "M 105.60399,129 L 122.78954,156 L 118.80448,158 L 105.60399,129 z"); elGroup.appendChild(element); } |
|
|
Re: Dynamic Elements on zoomHi Mistercaste,
mistercaste <mistercaste@...> wrote on 10/23/2009 10:35:27 AM: > I verified the Element source (actually I'm adjusting a code > inherited by someone else), and it has a "use" property as > predicted. Is it possible to get it's GraphicNode? No, because 'used' elements may have many Graphics Nodes. So it comes down to why do you need the GraphicsNode? As there may be another way to achieve the desired effect. |
|
|
Re: Dynamic Elements on zoomI'm working on a GIS road-map visualizer.
Actually I'm interested on the zoom problem and in particular in having some elements invariant to the affine transformation. For example zooming will not make bigger the road signals. Signals should have always the same size on screen, independently by the zoom factor applied to the rest of the elements. Same thing for the text on the SVGCanvas. I have some texts on my map indicating the names of the places, and these texts shouldn't get bigger when I zoom-in into the canvas. I tryed the GraphicsNode approach with in my mind to use the inverse affine transforms. I mean that I wanted to apply the inverse transform on the GraphicsNodes that I wanted to keep "constant", like the road signals and the texts. What approach should I follow? Thanks. |
|
|
Re: Dynamic Elements on zoomHi Mistercaste,
mistercaste <mistercaste@...> wrote on 10/26/2009 09:45:22 AM: > I tryed the GraphicsNode approach with in my mind to use > the inverse affine transforms. I mean that I wanted to apply the > inverse transform on the GraphicsNodes that I wanted to keep > "constant", like the road signals and the texts. I have typically done this in the past by using a the inverse transform of the group that contains the 'use' elements. Since all of the elements experience the same change in global transform. From the group you can calculate the new scale factor (and the anti-scale factor you need to apply). You should then be able to apply that to the symbols. Note that all of this can be done with the SVG DOM (use getTransformToElement or getScreenCTM). |
|
|
Re: Dynamic Elements on zoomI've solved the texts auto-size problem, as soon I will proudly post my solution in the forum. Thank you Thomas!
Actually a problem with the group that contains the 'use' elements persists. My DOM is something like the following: ROOT | + ELEMENT g - id="signals" | | | + ELEMENT use - id="accident" | | | + ELEMENT use - id="works" | | | + ELEMENT use - id="danger" | | + ...whatever... | ... I can't take control of the group "signal" properties. For example I tried to set the "signals" properties as display=none and visibility=hidden but nothing happens in my JSVGCanvas with the childs use elements. So obviously I can't get updates on the scaling system. What to do? :-\ |
|
|
Re: Dynamic Elements on zoomHi Mistercaste,
mistercaste <mistercaste@...> wrote on 11/04/2009 07:58:44 AM: > I've solved the texts auto-size problem, as soon I will proudly post my > solution in the forum. Thank you Thomas! Good to hear. > Actually a problem with the group that contains the 'use' elements persists. [...] > I can't take control of the group "signal" properties. For example I tried > to set the "signals" properties as display=none and visibility=hidden but > nothing happens in my JSVGCanvas with the childs use elements. What you describe doesn't match any known limitation in Batik that I am aware of. I suggest posting the code that tries to set these properties. Also you might make sure that you don't have another element with 'id="signals"' in your DOM as that could appear to cause this sort of a problem s well. > So obviously I can't get updates on the scaling system. What to do? :-\ > My DOM is something like the following: > > ROOT > | > + ELEMENT g - id="signals" > | | > | + ELEMENT use - id="accident" > | | > | + ELEMENT use - id="works" > | | > | + ELEMENT use - id="danger" > | > | > + ...whatever... |
| Free embeddable forum powered by Nabble | Forum Help |