Andrea Aime wrote:

Hum.... I'm wondering what changes did you made. It's easy to make decimation more efficient by making it more aggressive, but a properly working decimation generates results that cannot
be distinguished from not having applied decimation at all.
When I coded it, I made sure the decimation distance was not over 1 pixel on screen, but I
don't really know what happened in the meantime.


It, basically, wasnt actually decimating. It would, however, generate lines with 0 or 1 point in them, and polygon rings with 0, 1, 2 points and 1st point != last point. These geometry issues were causing problems, which this version solves. Note - MathTransform in this code is always an affine transform (see my earlier message about CRS being done in the wrong place). Also note that this is always done on a copy of the geometry since its destructive.

A better way to do this would be to generate a spanx/spany for each geometry instead of one thats "good for all geometries", then (hopefully) you'll be able to do this in 1 step instead of 2.

dave




/**
* 1. remove any points that are within the spanx,spany. We ALWAYS keep 1st and last point
    *   2. transform to screen coordinates
    *   3. remove any points that are close (span <1)
* * @param seq
    * @param tranform
    */
private final void decimateTransformGeneralize(LiteCoordinateSequence seq,MathTransform transform) throws TransformException
   {
         //decimates before XFORM
         int ncoords = seq.size();
         double  originalOrds[] = seq.getXYArray(); // 2*#of points
if (ncoords <2)
         {
             if (ncoords ==1)  // 1 coordinate -- just xform it
             {
                 double[] newCoordsXformed2= new double[2];
transform.transform(originalOrds, 0, newCoordsXformed2, 0, 1);
                 seq.setArray(newCoordsXformed2);
                 return;
             }
             else
                 return;  // ncoords =0
         }
// unfortunately, we have to keep things in double precion until after the transform or we could move things. double[] allCoords = new double[ncoords*2]; // preallocate -- might not be full (throw away Z) allCoords[0] = originalOrds[0]; //allways have 1st one
         allCoords[1] = originalOrds[1];
int actualCoords = 1;
           double lastX = allCoords[0];
           double lastY = allCoords[1];
           for (int t=1;t<(ncoords-1);t++)
           {
               //see if this one should be added
               double  x =  originalOrds[t*2];
               double  y =   originalOrds[t*2+1];
if ( (Math.abs(x-lastX )> spanx) || ( Math.abs(y-lastY )) >spany)
               {
                   allCoords[actualCoords*2] = x;
                   allCoords[actualCoords*2+1] = y;
                   lastX = x;
                   lastY = y;
actualCoords++; } } allCoords[actualCoords*2] = originalOrds[(ncoords-1)*2]; //always have last one
           allCoords[actualCoords*2+1] = originalOrds[(ncoords-1)*2+1];
actualCoords++; double[] newCoordsXformed;
           //DO THE XFORM
if ((transform == null) || (transform.isIdentity()) ) // no actual xform
           {
               newCoordsXformed = allCoords;
           }
           else
           {
               newCoordsXformed= new double[actualCoords*2];
transform.transform(allCoords, 0, newCoordsXformed, 0, actualCoords);
           }
//GENERLIZE -- we should be in screen space so spanx=spany=1.0 // unfortunately, we have to keep things in double precion until after the transform or we could move things. double[] finalCoords = new double[ncoords*2]; // preallocate -- might not be full (throw away Z) finalCoords[0] = newCoordsXformed[0]; //allways have 1st one
              finalCoords[1] = newCoordsXformed[1];
int actualCoordsGen = 1;
               lastX = newCoordsXformed[0];
               lastY = newCoordsXformed[1];
for (int t=1;t<(actualCoords-1);t++)
               {
                   //see if this one should be added
                   double  x =   newCoordsXformed[t*2];
                   double  y =   newCoordsXformed[t*2+1];
if ( (Math.abs(x-lastX )> 1) || ( Math.abs(y-lastY )) >1)
                   {
                       finalCoords[actualCoordsGen*2] = x;
                       finalCoords[actualCoordsGen*2+1] = y;
                       lastX = x;
                       lastY = y;
actualCoordsGen++; } } finalCoords[actualCoordsGen*2] = newCoordsXformed[(actualCoords-1)*2]; //always have last one finalCoords[actualCoordsGen*2+1] = newCoordsXformed[(actualCoords-1)*2+1]; actualCoordsGen++; //stick back in
               double[] seqDouble = new double[2*actualCoordsGen];
System.arraycopy(finalCoords,0,seqDouble, 0, actualCoordsGen*2);
               seq.setArray(seqDouble);
}


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Geotools-devel mailing list
Geotools-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to