Hi Sascha;

Sounds interesting.
Please, let me some more time to have a closer look and see how your 
code compare to the one in CVS.
Note : I made a recent change in CVS to have the resolution as a 
property and modify it as needed (default=1/2 pixel) for special renderers.

Michael

Sascha L. Teichmann a écrit :

>Hi Larry, hi Michaël,
>
>I had a look at the decimation code in Java2DConverter.
>This is awesome! Congratulations! :-)
>
>But way not go step further and streamline the model to view
>coordination transform. Why to create all this temporary
>Coordinate[] stuff? In the end all what matters is a PathIterator
>that can handle an AffineTransform coming from Java2D.
>Instead of transform the data to a temporary Coordinate array
>and used this to construct GeneralPaths we can write a PathIterator
>that transforms and decimates the data on-the-fly.
>All we have to do is to concatenate the model to view transform to the
>incoming matrix.
>
>To archive this we must add a
>
>AffineTransform getModelToViewTransform();
>
>method to the Java2DConverter.PointConverter interface. This
>does not hurt because Viewport already implements it.
>
>To see what I mean, look at the DirectPolygonShape that I've
>attached. It handles the Polygon case of Java2DConverter.
>Add this class to the sources and change the toShape(Polygon)
>method to look as follow:
>
>  private Shape toShape(Polygon polygon) throws
>  NoninvertibleTransformException
>  {
>    return new DirectPolygonShape(
>      polygon,
>      pointConverter.getModelToViewTransform(),
>      1d / (2d*pointConverter.getScale()));
>  }
>
>Speaking of performance. On my computer
>(very old 1.2 GHz AMD/Athlon-T-Bird running GNU/Linux, Java 6)
>the burluc layer is rendered in full extend without the streamling
>in about 9.x seconds, with the streamling in about 8.x secs, with
>x varying a bit. It's just a second, but it's a second! ;-)
>
>What do you think?
>
>Regards, Sascha
>  
>
>------------------------------------------------------------------------
>
>
>/*
> * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI 
> * for visualizing and manipulating spatial features with geometry and 
> attributes.
> *
> * Copyright (C) 2003 Vivid Solutions
> * 
> * This program is free software; you can redistribute it and/or
> * modify it under the terms of the GNU General Public License
> * as published by the Free Software Foundation; either version 2
> * of the License, or (at your option) any later version.
> * 
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> * GNU General Public License for more details.
> * 
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> * 
> * For more information, contact:
> *
> * Vivid Solutions
> * Suite #1A
> * 2328 Government Street
> * Victoria BC  V8T 5G5
> * Canada
> *
> * (250)385-6040
> * www.vividsolutions.com
> */
>
>package com.vividsolutions.jump.workbench.ui.renderer.java2D;
>
>import com.vividsolutions.jts.geom.Coordinate;
>import com.vividsolutions.jts.geom.Polygon;
>
>import java.awt.Rectangle;
>import java.awt.Shape;
>import java.awt.geom.AffineTransform;
>import java.awt.geom.GeneralPath;
>import java.awt.geom.PathIterator;
>import java.awt.geom.Point2D;
>import java.awt.geom.Rectangle2D;
>
>import java.util.Iterator;
>import java.util.NoSuchElementException;
>
>// for more accurate (float instead of int) rendering.
>// From larry becker's SkyJUMP code to OpenJUMP [mmichaud]
>// Streamlined [s-l-teichmann]
>public class DirectPolygonShape 
>implements   Shape 
>{
>       private Polygon         polygon;
>       private AffineTransform model2view;
>       private double          halfPixel;
>
>       protected DirectPolygonShape(){
>       }
>       
>       /**
>        * @param polygon    the JTS polygon
>        * @param model2view the affine transform from model to view
>        * @param halfPixel  line segments shorter than halfPixel are ignored.
>        */
>       public DirectPolygonShape(
>               Polygon         polygon,
>               AffineTransform model2view,
>               double          halfPixel
>               ) {
>               this.polygon    = polygon;
>               this.model2view = model2view;
>               this.halfPixel  = halfPixel;
>       }
>
>       /**
>        * helper PathIterator that iterates over PathIterators
>        */
>       public final class PathIteratorsIterator 
>       implements         PathIterator
>       {
>    private Iterator     iterators;
>    private boolean      done;
>               private PathIterator current;
>
>    public PathIteratorsIterator(Iterator iterators) {
>                       this.iterators = iterators;
>
>                       if (!iterators.hasNext())
>                               done = true;
>                       else
>                               current = (PathIterator)iterators.next();
>    }
>
>    public int getWindingRule() {
>                       return WIND_EVEN_ODD;
>    }
>
>    public boolean isDone() {
>                       return done;
>    }
>
>    public void next() {
>                       if (done)
>                               return;
>
>                       if (current.isDone()) {
>                               if (iterators.hasNext())
>                                       current = 
> (PathIterator)iterators.next();
>                               else
>                                       done = true;
>                       }
>                       else
>                               current.next();
>    }
>
>    public int currentSegment(float [] coords) {
>                       return current.currentSegment(coords);
>    }
>
>    public int currentSegment(double [] coords) {
>                       return current.currentSegment(coords);
>    }
>       } // class PathIteratorsIterator
>
>       /**
>        * Implements a PathIterator and Larry's decimator on-the-fly
>        */
>  public static final class AffinePolygonPath 
>       implements                PathIterator
>       {
>               private int             iterate;
>               private Coordinate []   points;
>               private Point2D.Double  tmp;
>               private AffineTransform xform;
>               private double          halfPixel;
>               private Coordinate      p0;
>               private int             segmentType;
>               
>               public AffinePolygonPath(
>                       Coordinate []   points, 
>                       AffineTransform xform, 
>                       double          halfPixel
>               ){
>                       this.xform     = xform;
>                       this.points    = points;
>                       this.halfPixel = halfPixel;
>                       tmp            = new Point2D.Double();
>                       internalNext();
>               }
>
>               /** Math.abs() is a known for being slow ... */
>               private static final double abs(double x) {
>                       return x < 0d ? -x : x;
>               }
>
>               private final void internalNext() {
>                       for (;;) {
>                               // issue SEG_CLOSE at end
>                               if (iterate >= points.length) {
>                                       segmentType = SEG_CLOSE;
>                                       break;
>                               }
>
>                               // issue first two and last
>                               if (iterate < 2 || iterate == points.length-1) {
>                                       Coordinate pi = points[iterate];
>                                       tmp.x = pi.x;
>                                       tmp.y = pi.y;
>                                       xform.transform(tmp, tmp);
>                                       p0 = pi;
>                               }
>                               else { // distance lesser than halfPixel?
>                                       Coordinate pi = points[iterate];
>                                       if (abs(p0.x-pi.x) > halfPixel || 
> abs(p0.y-pi.y) > halfPixel) {
>                                               tmp.x = pi.x;
>                                               tmp.y = pi.y;
>                                               xform.transform(tmp, tmp);
>                                               p0 = pi;
>                                       }
>                                       else { // yes: try next
>                                               ++iterate;
>                                               continue;
>                                       }
>                               }
>
>                               segmentType = iterate == 0
>                                       ? SEG_MOVETO
>                                       : SEG_LINETO;
>                               break;
>                       } // for (;;)
>               }
>
>               public int currentSegment(double[] coords) {
>                       coords[0] = tmp.x;
>                       coords[1] = tmp.y;
>                       return segmentType;
>               }
>
>
>               public int currentSegment(float[] coords) {
>                       coords[0] = (float)tmp.x;
>                       coords[1] = (float)tmp.y;
>                       return segmentType;
>               }
>
>               public int getWindingRule() {
>                       return GeneralPath.WIND_EVEN_ODD;
>               }
>
>               public boolean isDone() {
>                       return segmentType == SEG_CLOSE;
>               }
>
>               public void next() {
>                       ++iterate;
>                       internalNext();
>               }       
>       } // class AffinePolygonPath
>
>       public Rectangle getBounds() {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method getBounds() not yet 
> implemented.");
>       }
>
>       public Rectangle2D getBounds2D() {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method getBounds() not yet 
> implemented.");
>       }
>
>       public boolean contains(double x, double y) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method contains() not yet 
> implemented.");
>       }
>
>       public boolean contains(Point2D p) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method contains() not yet 
> implemented.");
>       }
>
>       public boolean intersects(double x, double y, double w, double h) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method intersects() not yet 
> implemented.");
>       }
>
>       public boolean intersects(Rectangle2D r) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method intersects() not yet 
> implemented.");
>       }
>
>       public boolean contains(double x, double y, double w, double h) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method contains() not yet 
> implemented.");
>       }
>
>       public boolean contains(Rectangle2D r) {
>                       /[EMAIL PROTECTED] Implement this java.awt.Shape 
> method*/
>                       throw new java.lang.UnsupportedOperationException(
>                                       "Method contains() not yet 
> implemented.");
>       }
>
>       public PathIterator getPathIterator(AffineTransform xform) {
>
>               if (xform == null)
>                       xform = model2view;
>               else {
>                       xform = new AffineTransform(xform);
>                       xform.concatenate(model2view);
>               }
>
>               final AffineTransform at = xform;
>
>               return new PathIteratorsIterator(new Iterator() {
>
>                       int ring;
>
>                       public boolean hasNext() {
>                               return ring < polygon.getNumInteriorRing() + 1;
>                       }
>
>                       public Object next() {
>                               if (!hasNext())
>                                       throw new NoSuchElementException();
>                               Object x = ring == 0
>                                       ? new 
> AffinePolygonPath(polygon.getExteriorRing().getCoordinates(),        at, 
> halfPixel)
>                                       : new 
> AffinePolygonPath(polygon.getInteriorRingN(ring-1).getCoordinates(), at, 
> halfPixel);
>                               ++ring;
>                               return x;
>                       }
>
>                       public void remove() {
>                               throw new UnsupportedOperationException();
>                       }
>               });
>
>       }
>
>       public PathIterator getPathIterator(AffineTransform at, double 
> flatness) {
>               // since we don't support curved geometries, can simply 
> delegate to the simple method
>               return getPathIterator(at);
>       }
>}
>// end of file
>  
>
>------------------------------------------------------------------------
>
>-------------------------------------------------------------------------
>This SF.net email is sponsored by DB2 Express
>Download DB2 Express C - the FREE version of DB2 express and take
>control of your XML. No limits. Just data. Click to get it now.
>http://sourceforge.net/powerbar/db2/
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Jump-pilot-devel mailing list
>Jump-pilot-devel@lists.sourceforge.net
>https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>  
>


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to