예제 #1
1
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and shape.
  *
  * @return Returns true, if the polygon is inside of the image bounds.
  */
 private boolean writePolyAttributes(IXMLElement elem, SVGFigure f, Shape shape) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     StringBuilder buf = new StringBuilder();
     float[] coords = new float[6];
     GeneralPath path = new GeneralPath();
     for (PathIterator i = shape.getPathIterator(t, 1.5f);
     ! i.isDone(); i.next()) {
         switch (i.currentSegment(coords)) {
             case PathIterator.SEG_MOVETO :
                 if (buf.length() != 0) {
                     throw new IllegalArgumentException("Illegal shape "+shape);
                 }
                 if (buf.length() != 0) {
                     buf.append(',');
                 }
                 buf.append((int) coords[0]);
                 buf.append(',');
                 buf.append((int) coords[1]);
                 path.moveTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_LINETO :
                 if (buf.length() != 0) {
                     buf.append(',');
                 }
                 buf.append((int) coords[0]);
                 buf.append(',');
                 buf.append((int) coords[1]);
                 path.lineTo(coords[0], coords[1]);
                 break;
             case PathIterator.SEG_CLOSE :
                 path.closePath();
                 break;
             default :
                 throw new InternalError("Illegal segment type "+i.currentSegment(coords));
         }
     }
     elem.setAttribute("shape", "poly");
     elem.setAttribute("coords", buf.toString());
     writeHrefAttribute(elem, f);
     return path.intersects(new Rectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height));
 }
예제 #2
0
  /**
   * returns the skew transform
   *
   * @param svgHandle a svg handle
   * @param bounds the bounds of the area to transform
   * @param firstPoint the first clicked point by the user
   * @param currentPoint the current point of the drag action by the user
   * @param item the selection item
   * @return the skew transform
   */
  protected AffineTransform getSkewTransform(
      SVGHandle svgHandle,
      Rectangle2D bounds,
      Point2D firstPoint,
      Point2D currentPoint,
      SelectionItem item) {

    // getting the skew factor
    double skewX = 0, skewY = 0;
    boolean isHorizontal =
        (item.getType() == SelectionItem.NORTH || item.getType() == SelectionItem.SOUTH);

    if (bounds.getWidth() > 0 && bounds.getHeight() > 0) {

      if (isHorizontal) {

        skewX = (currentPoint.getX() - firstPoint.getX()) / bounds.getHeight();

      } else {

        skewY = (currentPoint.getY() - firstPoint.getY()) / bounds.getWidth();
      }
    }

    // getting the center point
    Point2D centerPoint = getRotationSkewCenterPoint(svgHandle, bounds);

    // creating the affine transform
    AffineTransform af =
        AffineTransform.getTranslateInstance(-centerPoint.getX(), -centerPoint.getY());
    af.preConcatenate(AffineTransform.getShearInstance(skewX, skewY));
    af.preConcatenate(AffineTransform.getTranslateInstance(centerPoint.getX(), centerPoint.getY()));

    return af;
  }
예제 #3
0
 /**
  * Perform a zooming operation centered on the given point (dx, dy) and using the given scale
  * factor. The given AffineTransform instance is preconcatenated.
  *
  * @param dx center x
  * @param dy center y
  * @param scale zoom rate
  * @param af original affinetransform
  */
 public void centerZoom(double dx, double dy, double scale, AffineTransform af) {
   af.preConcatenate(AffineTransform.getTranslateInstance(-dx, -dy));
   af.preConcatenate(AffineTransform.getScaleInstance(scale, scale));
   af.preConcatenate(AffineTransform.getTranslateInstance(dx, dy));
   transform = af;
   syncScrollBars();
 }
예제 #4
0
    public GranuleOverviewLevelDescriptor(
        final double scaleX, final double scaleY, final int width, final int height) {
      this.scaleX = scaleX;
      this.scaleY = scaleY;
      this.baseToLevelTransform =
          new AffineTransform2D(XAffineTransform.getScaleInstance(scaleX, scaleY, 0, 0));

      final AffineTransform gridToWorldTransform_ = new AffineTransform(baseToLevelTransform);
      gridToWorldTransform_.preConcatenate(CoverageUtilities.CENTER_TO_CORNER);
      gridToWorldTransform_.preConcatenate(baseGridToWorld);
      this.gridToWorldTransformCorner = new AffineTransform2D(gridToWorldTransform_);
      this.width = width;
      this.height = height;
      this.rasterDimensions = new Rectangle(0, 0, width, height);
    }
예제 #5
0
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and ellipse.
  *
  * @return Returns true, if the circle is inside of the image bounds.
  */
 private boolean writeCircleAttributes(IXMLElement elem, SVGFigure f, Ellipse2D.Double ellipse) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType() &&
             ellipse.width == ellipse.height
             ) {
         
         Point2D.Double start = new Point2D.Double(ellipse.x, ellipse.y);
         Point2D.Double end = new Point2D.Double(ellipse.x + ellipse.width, ellipse.y + ellipse.height);
         t.transform(start, start);
         t.transform(end, end);
         ellipse.x = Math.min(start.x, end.x);
         ellipse.y = Math.min(start.y, end.y);
         ellipse.width = Math.abs(start.x - end.x);
         ellipse.height = Math.abs(start.y - end.y);
         
         elem.setAttribute("shape", "circle");
         elem.setAttribute("coords",
                 (int) (ellipse.x + ellipse.width / 2d)+","+
                 (int) (ellipse.y + ellipse.height / 2d)+","+
                 (int) (ellipse.width / 2d)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(ellipse.getBounds());
     } else {
         return writePolyAttributes(elem, f, (Shape) ellipse);
     }
 }
예제 #6
0
 @Override
 public void paintPreview(JEnvironment env, JRequest req, Graphics2D g) {
   g.setColor(getPreviewColor());
   AffineTransform af = new AffineTransform(totalTransform);
   if (addingTransform != null) af.preConcatenate(addingTransform);
   Shape s = getShape();
   if (addingTransform != null) s = addingTransform.createTransformedShape(s);
   s = env.getToScreenTransform().createTransformedShape(s);
   g.draw(s);
   PathIterator path = s.getPathIterator(null);
   double radius = JEnvironment.PATH_SELECTOR_SIZE / 2;
   Rectangle2D.Double sr = new Rectangle2D.Double(0, 0, radius * 2, radius * 2);
   double[] coords = new double[6];
   while (!path.isDone()) {
     int type = path.currentSegment(coords);
     if (type == path.SEG_MOVETO || type == path.SEG_LINETO) {
       sr.x = coords[0] - radius;
       sr.y = coords[1] - radius;
       g.fill(sr);
     } else if (type == path.SEG_CUBICTO) {
       sr.x = coords[4] - radius;
       sr.y = coords[5] - radius;
       g.fill(sr);
     } else if (type == path.SEG_QUADTO) {
       sr.x = coords[2] - radius;
       sr.y = coords[3] - radius;
       g.fill(sr);
     }
     path.next();
   }
 }
예제 #7
0
 /**
  * Transforms the figure.
  *
  * @param tx the transformation.
  */
 public void transform(AffineTransform tx) {
   if (TRANSFORM.get(this) != null
       || tx.getType() != (tx.getType() & AffineTransform.TYPE_TRANSLATION)) {
     if (TRANSFORM.get(this) == null) {
       TRANSFORM.basicSet(this, (AffineTransform) tx.clone());
     } else {
       AffineTransform t = TRANSFORM.getClone(this);
       t.preConcatenate(tx);
       TRANSFORM.basicSet(this, t);
     }
   } else {
     for (int i = 0; i < coordinates.length; i++) {
       tx.transform(coordinates[i], coordinates[i]);
     }
     if (FILL_GRADIENT.get(this) != null && !FILL_GRADIENT.get(this).isRelativeToFigureBounds()) {
       Gradient g = FILL_GRADIENT.getClone(this);
       g.transform(tx);
       FILL_GRADIENT.basicSet(this, g);
     }
     if (STROKE_GRADIENT.get(this) != null
         && !STROKE_GRADIENT.get(this).isRelativeToFigureBounds()) {
       Gradient g = STROKE_GRADIENT.getClone(this);
       g.transform(tx);
       STROKE_GRADIENT.basicSet(this, g);
     }
   }
   invalidate();
 }
예제 #8
0
  public static BufferedImage rotateImage(BufferedImage image, double theta) {
    int degrees = (int) Math.abs(Math.toDegrees(theta));
    double xCenter = image.getWidth() / 2;
    double yCenter = image.getHeight() / 2;
    AffineTransform rotateTransform = AffineTransform.getRotateInstance(-theta, xCenter, yCenter);

    // Translation adjustments so image still centered after rotate width/height changes
    if (image.getHeight() != image.getWidth() && degrees != 180 && degrees != 0) {
      Point2D origin = new Point2D.Double(0.0, 0.0);
      origin = rotateTransform.transform(origin, null);
      double yTranslate = origin.getY();

      Point2D yMax = new Point2D.Double(0, image.getHeight());
      yMax = rotateTransform.transform(yMax, null);
      double xTranslate = yMax.getX();

      AffineTransform translationAdjustment =
          AffineTransform.getTranslateInstance(-xTranslate, -yTranslate);
      rotateTransform.preConcatenate(translationAdjustment);
    }

    AffineTransformOp op = new AffineTransformOp(rotateTransform, AffineTransformOp.TYPE_BILINEAR);
    // Have to recopy image because of JDK bug #4723021, AffineTransformationOp throwing exception
    // sometimes
    image = copyImage(image, BufferedImage.TYPE_INT_ARGB);

    // Need to create filter dest image ourselves since AffineTransformOp's own dest image creation
    // throws exceptions in some cases.
    Rectangle bounds = op.getBounds2D(image).getBounds();
    BufferedImage finalImage =
        new BufferedImage(
            (int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB);

    return op.filter(image, finalImage);
  }
예제 #9
0
파일: IconIO.java 프로젝트: munix/jdget
  /**
   * @param drop
   * @param i
   * @return
   */
  public static BufferedImage rotate(final BufferedImage src, final int degree) {
    final int w = src.getWidth(null);
    final int h = src.getHeight(null);

    // final Graphics2D g = image.createGraphics();
    // g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    // RenderingHints.VALUE_ANTIALIAS_ON);

    final AffineTransform at = new AffineTransform();
    at.rotate(degree * Math.PI / 180.0);
    Point2D p2din, p2dout;

    p2din = new Point2D.Double(0.0, 0.0);
    p2dout = at.transform(p2din, null);
    double ytrans = p2dout.getY();
    double xtrans = p2dout.getX();
    p2din = new Point2D.Double(0, h);
    p2dout = at.transform(p2din, null);
    ytrans = Math.min(ytrans, p2dout.getY());
    xtrans = Math.min(xtrans, p2dout.getX());
    p2din = new Point2D.Double(w, h);
    p2dout = at.transform(p2din, null);
    ytrans = Math.min(ytrans, p2dout.getY());
    xtrans = Math.min(xtrans, p2dout.getX());
    p2din = new Point2D.Double(w, 0);
    p2dout = at.transform(p2din, null);
    ytrans = Math.min(ytrans, p2dout.getY());
    xtrans = Math.min(xtrans, p2dout.getX());

    final AffineTransform tat = new AffineTransform();
    tat.translate(-xtrans, -ytrans);

    at.preConcatenate(tat);
    final AffineTransformOp bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

    final Rectangle r = bio.getBounds2D(src).getBounds();

    BufferedImage image = new BufferedImage(r.width, r.height, BufferedImage.TYPE_INT_ARGB);

    image = bio.filter(src, image);
    // final Graphics g = image.getGraphics();
    // g.setColor(Color.RED);
    // g.drawRect(0, 0, image.getWidth() - 1, image.getHeight() - 1);
    // g.dispose();
    // try {
    // Dialog.getInstance().showConfirmDialog(0, "", "", new
    // ImageIcon(image), null, null);
    // } catch (final DialogClosedException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // } catch (final DialogCanceledException e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
    return image;
  }
예제 #10
0
  /* Scroll horizontally */
  private void scrollHorizontally(ScrollBar scrollBar) {
    if (sourceImage == null) return;

    AffineTransform af = transform;
    double tx = af.getTranslateX();
    double select = -scrollBar.getSelection();
    af.preConcatenate(AffineTransform.getTranslateInstance(select - tx, 0));
    transform = af;
    syncScrollBars();
  }
예제 #11
0
  /* Scroll vertically */
  private void scrollVertically(ScrollBar scrollBar) {
    if (sourceImage == null) return;

    AffineTransform af = transform;
    double ty = af.getTranslateY();
    double select = -scrollBar.getSelection();
    af.preConcatenate(AffineTransform.getTranslateInstance(0, select - ty));
    transform = af;
    syncScrollBars();
  }
예제 #12
0
  /**
   * Performs a translation using the "Resample" operation.
   *
   * @param grid the {@link GridCoverage2D} to apply the translation on.
   * @throws NoninvertibleTransformException If a "grid to CRS" transform is not invertible.
   */
  private void doTranslation(GridCoverage2D grid) throws NoninvertibleTransformException {
    final int transX = -253;
    final int transY = -456;
    final double scaleX = 0.04;
    final double scaleY = -0.04;
    final ParameterBlock block =
        new ParameterBlock()
            .addSource(grid.getRenderedImage())
            .add((float) transX)
            .add((float) transY);
    RenderedImage image = JAI.create("Translate", block);
    assertEquals("Incorrect X translation", transX, image.getMinX());
    assertEquals("Incorrect Y translation", transY, image.getMinY());

    /*
     * Create a grid coverage from the translated image but with the same envelope.
     * Consequently, the 'gridToCoordinateSystem' should be translated by the same
     * amount, with the opposite sign.
     */
    AffineTransform expected = getAffineTransform(grid);
    assertNotNull(expected);
    expected = new AffineTransform(expected); // Get a mutable instance.
    final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);
    grid =
        factory.create(
            "Translated",
            image,
            grid.getEnvelope(),
            grid.getSampleDimensions(),
            new GridCoverage2D[] {grid},
            grid.getProperties());
    expected.translate(-transX, -transY);
    assertTransformEquals(expected, getAffineTransform(grid));

    /*
     * Apply the "Resample" operation with a specific 'gridToCoordinateSystem' transform.
     * The envelope is left unchanged. The "Resample" operation should compute automatically
     * new image bounds.
     */
    final AffineTransform at = AffineTransform.getScaleInstance(scaleX, scaleY);
    final MathTransform tr = ProjectiveTransform.create(at);
    // account for the half pixel correction between the two spaces since we are talking raster here
    // but the resample will talk model!
    final MathTransform correctedTransform =
        PixelTranslation.translate(tr, PixelInCell.CELL_CORNER, PixelInCell.CELL_CENTER);
    final GridGeometry2D geometry = new GridGeometry2D(null, correctedTransform, null);
    final GridCoverage2D newGrid =
        (GridCoverage2D)
            Operations.DEFAULT.resample(grid, grid.getCoordinateReferenceSystem(), geometry, null);
    assertEquals(correctedTransform, getAffineTransform(newGrid));
    image = newGrid.getRenderedImage();
    expected.preConcatenate(at.createInverse());
    final Point point = new Point(transX, transY);
    assertSame(point, expected.transform(point, point)); // Round toward neareast integer
  }
예제 #13
0
  /**
   * Returns a Filter that represents a svg document or element as an image.
   *
   * @param ctx the bridge context
   * @param primitiveRegion the primitive region
   * @param refElement the referenced element
   * @param toBBoxNeeded true if there is a need to transform to ObjectBoundingBox space
   * @param filterElement parent filter element
   * @param filteredNode node to which the filter applies
   */
  protected static Filter createSVGFeImage(
      BridgeContext ctx,
      Rectangle2D primitiveRegion,
      Element refElement,
      boolean toBBoxNeeded,
      Element filterElement,
      GraphicsNode filteredNode) {

    //
    // <!> FIX ME
    // Unresolved issue on the feImage behavior when referencing an
    // image (PNG, JPEG or SVG image).
    // VH & TK, 03/08/2002
    // Furthermore, for feImage referencing doc fragment, should act
    // like a <use>, i.e., CSS cascading and the whole zing bang.
    //
    GraphicsNode node = ctx.getGVTBuilder().build(ctx, refElement);
    Filter filter = node.getGraphicsNodeRable(true);

    AffineTransform at = new AffineTransform();

    if (toBBoxNeeded) {
      // 'primitiveUnits' attribute - default is userSpaceOnUse
      short coordSystemType;
      Element filterDefElement = (Element) (filterElement.getParentNode());
      String s =
          SVGUtilities.getChainableAttributeNS(
              filterDefElement, null, SVG_PRIMITIVE_UNITS_ATTRIBUTE, ctx);
      if (s.length() == 0) {
        coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
      } else {
        coordSystemType =
            SVGUtilities.parseCoordinateSystem(
                filterDefElement, SVG_PRIMITIVE_UNITS_ATTRIBUTE, s, ctx);
      }

      if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
        at = SVGUtilities.toObjectBBox(at, filteredNode);
      }

      Rectangle2D bounds = filteredNode.getGeometryBounds();
      at.preConcatenate(
          AffineTransform.getTranslateInstance(
              primitiveRegion.getX() - bounds.getX(), primitiveRegion.getY() - bounds.getY()));

    } else {

      // Need to translate the image to the x, y coordinate to
      // have the same behavior as the <use> element
      at.translate(primitiveRegion.getX(), primitiveRegion.getY());
    }

    return new AffineRable8Bit(filter, at);
  }
예제 #14
0
  /**
   * Synchronize the scrollbar with the image. If the transform is out of range, it will correct it.
   * This function considers only following factors :<b> transform, image size, client area</b>.
   */
  public void syncScrollBars() {
    if (sourceImage == null) {
      redraw();
      return;
    }

    AffineTransform af = transform;
    double sx = af.getScaleX(), sy = af.getScaleY();
    double tx = af.getTranslateX(), ty = af.getTranslateY();
    if (tx > 0) tx = 0;
    if (ty > 0) ty = 0;

    ScrollBar horizontal = getHorizontalBar();
    horizontal.setIncrement((int) (getClientArea().width / 20));
    horizontal.setPageIncrement(getClientArea().width);
    Rectangle imageBound = sourceImage.getBounds();
    int cw = getClientArea().width, ch = getClientArea().height;
    if (imageBound.width * sx > cw) {
        /* image is wider than client area */
      horizontal.setMaximum((int) (imageBound.width * sx));
      horizontal.setEnabled(true);
      if (((int) -tx) > horizontal.getMaximum() - cw) tx = -horizontal.getMaximum() + cw;
    } else {
        /* image is narrower than client area */
      horizontal.setEnabled(false);
      tx = (cw - imageBound.width * sx) / 2; // center if too small.
    }
    horizontal.setSelection((int) (-tx));
    horizontal.setThumb((int) (getClientArea().width));

    ScrollBar vertical = getVerticalBar();
    vertical.setIncrement((int) (getClientArea().height / 20));
    vertical.setPageIncrement((int) (getClientArea().height));
    if (imageBound.height * sy > ch) {
        /* image is higher than client area */
      vertical.setMaximum((int) (imageBound.height * sy));
      vertical.setEnabled(true);
      if (((int) -ty) > vertical.getMaximum() - ch) ty = -vertical.getMaximum() + ch;
    } else {
        /* image is less higher than client area */
      vertical.setEnabled(false);
      ty = (ch - imageBound.height * sy) / 2; // center if too small.
    }
    vertical.setSelection((int) (-ty));
    vertical.setThumb((int) (getClientArea().height));

    /* update transform. */
    af = AffineTransform.getScaleInstance(sx, sy);
    af.preConcatenate(AffineTransform.getTranslateInstance(tx, ty));
    transform = af;

    redraw();
  }
  private void inspectCoordinateReferenceSystems() throws DataSourceException {
    // get the crs for the requested bbox
    requestCRS = CRS.getHorizontalCRS(requestedBBox.getCoordinateReferenceSystem());

    //
    // Check if the request CRS is different from the coverage native CRS
    //
    if (!CRS.equalsIgnoreMetadata(requestCRS, coverageProperties.crs2D))
      try {
        destinationToSourceTransform =
            CRS.findMathTransform(requestCRS, coverageProperties.crs2D, true);
      } catch (FactoryException e) {
        throw new DataSourceException("Unable to inspect request CRS", e);
      }
    // now transform the requested envelope to source crs
    if (destinationToSourceTransform != null && destinationToSourceTransform.isIdentity()) {
      destinationToSourceTransform = null; // the CRS is basically the same
    } else if (destinationToSourceTransform instanceof AffineTransform) {
      needsReprojection = true;
      //
      // k, the transformation between the various CRS is not null or the
      // Identity, let's see if it is an affine transform, which case we
      // can incorporate it into the requested grid to world
      //
      // we should not have any problems with regards to BBOX reprojection
      // update the requested grid to world transformation by pre concatenating the destination to
      // source transform
      AffineTransform mutableTransform = (AffineTransform) requestedGridToWorld.clone();
      mutableTransform.preConcatenate((AffineTransform) destinationToSourceTransform);

      // update the requested envelope
      try {
        final MathTransform tempTransform =
            PixelTranslation.translate(
                ProjectiveTransform.create(mutableTransform),
                PixelInCell.CELL_CENTER,
                PixelInCell.CELL_CORNER);
        requestedBBox =
            new ReferencedEnvelope(
                CRS.transform(tempTransform, new GeneralEnvelope(requestedRasterArea)));

      } catch (MismatchedDimensionException e) {
        throw new DataSourceException("Unable to inspect request CRS", e);
      } catch (TransformException e) {
        throw new DataSourceException("Unable to inspect request CRS", e);
      }

      // now clean up all the traces of the transformations
      destinationToSourceTransform = null;
    }
  }
예제 #16
0
 @Override
 public void transform(AffineTransform tx) {
   if (get(TRANSFORM) != null
       || (tx.getType() & (AffineTransform.TYPE_TRANSLATION)) != tx.getType()) {
     if (get(TRANSFORM) == null) {
       TRANSFORM.setClone(this, tx);
     } else {
       AffineTransform t = TRANSFORM.getClone(this);
       t.preConcatenate(tx);
       set(TRANSFORM, t);
     }
   } else {
     super.transform(tx);
   }
 }
  @Override
  public AffineTransform convertViewCoordinatesToNormalizedPointAT(double scale) {
    Rectangle bounds = getNormalizedBounds(scale);

    // return AffineTransform.getScaleInstance(1.0/bounds.width, 1.0/bounds.height);

    AffineTransform returned =
        AffineTransform.getTranslateInstance(
            minX < 0 ? minX * bounds.width : 0, minY < 0 ? minY * bounds.height : 0);

    returned.preConcatenate(
        AffineTransform.getScaleInstance(1.0 / bounds.width, 1.0 / bounds.height));

    return returned;
  }
 public void mouseWheelMoved(MouseWheelEvent event) {
   JGVTComponent component = (JGVTComponent) event.getSource();
   double scale = 1 - 0.2 * event.getWheelRotation();
   int x = event.getX();
   int y = event.getY();
   AffineTransform at = AffineTransform.getTranslateInstance(x, y);
   at.scale(scale, scale);
   at.translate(-x, -y);
   AffineTransform rt = (AffineTransform) component.getRenderingTransform().clone();
   rt.preConcatenate(at);
   if (rt.getDeterminant() < MAX_ZOOM_DETERMINANT) {
     return;
   }
   component.setRenderingTransform(rt);
   calculator.reset();
 }
예제 #19
0
파일: Utils.java 프로젝트: vara/navigps
  /**
   * Derives the "magic" transform that can transform source points to destination points.
   *
   * @param srcPoints Three points representing the source parallelogram.
   * @param destPoints Three points representing the destination parallelogram.
   *     <p>Matrix is represent [m00 m01 m02] [m10 m11 m12] [ 0 0 1 ]
   * @return A transform as described above.
   */
  public static AffineTransform deriveTransform(Point2D[] srcPoints, Point2D[] destPoints)
      throws NoninvertibleTransformException {
    if ((srcPoints == null) || (srcPoints.length != 3)) {
      throw new IllegalArgumentException("Source points must contain three points!");
    } else if ((destPoints == null) || (destPoints.length != 3)) {
      throw new IllegalArgumentException("Destination points must contain three points!");
    }
    AffineTransform returnTransform = null;

    // System.out.println(srcPoints[0]+","+srcPoints[1]+","+srcPoints[2]);
    final double m00 = srcPoints[1].getX() - srcPoints[0].getX();
    final double m10 = srcPoints[1].getY() - srcPoints[0].getY();
    final double m01 = srcPoints[2].getX() - srcPoints[0].getX();
    final double m11 = srcPoints[2].getY() - srcPoints[0].getY();
    final double m02 = srcPoints[0].getX();
    final double m12 = srcPoints[0].getY();

    final double n00 = destPoints[1].getX() - destPoints[0].getX();
    final double n10 = destPoints[1].getY() - destPoints[0].getY();
    final double n01 = destPoints[2].getX() - destPoints[0].getX();
    final double n11 = destPoints[2].getY() - destPoints[0].getY();
    final double n02 = destPoints[0].getX();
    final double n12 = destPoints[0].getY();

    // Build the transform based on the source points.
    final AffineTransform srcTransform =
        new AffineTransform(new double[] {m00, m10, m01, m11, m02, m12});
    // System.out.println("src Tran "+srcTransform);

    final AffineTransform destTransform =
        new AffineTransform(new double[] {n00, n10, n01, n11, n02, n12});
    // System.out.println("destTran "+destTransform);

    try {

      returnTransform = srcTransform.createInverse();
      returnTransform.preConcatenate(destTransform);

    } catch (NoninvertibleTransformException e) {
      NaviLogger.logger.severe(e.getMessage());
    }
    // System.out.println("retTran "+returnTransform);
    return returnTransform;
  }
예제 #20
0
  /**
   * computes the new coordinates of the element according to the transform a returns an undo/redo
   * action
   *
   * @param handle a svg handle
   * @param element the element that will be transformed
   * @param transform the transform to apply
   * @param actionUndoRedoLabel the action undo/redo label
   * @return an undo/redo action
   */
  protected UndoRedoAction applyTransform(
      final SVGHandle handle,
      final Element element,
      AffineTransform transform,
      String actionUndoRedoLabel) {

    // getting the initial transform
    final AffineTransform initialTransform = handle.getSvgElementsManager().getTransform(element);

    // getting the new transform
    final AffineTransform newTransform = new AffineTransform(initialTransform);
    newTransform.preConcatenate(transform);

    // setting the new x and y attributes for the elements
    Runnable executeRunnable =
        new Runnable() {

          @Override
          public void run() {

            handle.getSvgElementsManager().setTransform(element, newTransform);
          }
        };

    // the undo runnable
    Runnable undoRunnable =
        new Runnable() {

          @Override
          public void run() {

            handle.getSvgElementsManager().setTransform(element, initialTransform);
          }
        };

    // executing the action and creating the undo/redo action
    HashSet<Element> elements = new HashSet<Element>();
    elements.add(element);
    UndoRedoAction undoRedoAction =
        ShapeToolkit.getUndoRedoAction(
            actionUndoRedoLabel, executeRunnable, undoRunnable, elements);

    return undoRedoAction;
  }
예제 #21
0
  /**
   * Función de pintado del canvas. Pintamos un marco a la imagen para saber donde la movemos.
   *
   * <p>Para dibujar el marco alrededor del raster hacemos lo mismo que para pintar el raster
   * rotado. En realidad dibujamos un cuadrado y luego le aplicamos las transformaciones necesarias
   * para que se vea con la misma forma del raster al que representa.
   */
  public void paintComponent(Graphics g) {
    if (isMoveable && lyr != null && ptoFin != null && ptoIni != null) {
      try {
        ViewPort vp = grBehavior.getMapControl().getMapContext().getViewPort();
        AffineTransform at = (AffineTransform) lyr.getAffineTransform().clone();
        at.preConcatenate(vp.getAffineTransform());
        Extent ext = lyr.getFullRasterExtent();

        Point2D pt = new Point2D.Double(ext.getULX(), ext.getULY());
        vp.getAffineTransform().transform(pt, pt);
        at.inverseTransform(pt, pt);

        Point2D size = new Point2D.Double(ext.getLRX(), ext.getLRY());
        vp.getAffineTransform().transform(size, size);
        at.inverseTransform(size, size);

        double distX = ptoFin.getX() - ptoIni.getX();
        double distY = ptoFin.getY() - ptoIni.getY();
        Point2D d = new Point2D.Double(ext.getULX() + distX, ext.getULY() + distY);
        vp.getAffineTransform().transform(d, d);
        at.inverseTransform(d, d);

        // Giramos el graphics se dibuja y se vuelve a dejar como estaba
        ((Graphics2D) g).transform(at);
        g.setColor(rectangleColor);
        AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
        ((Graphics2D) g).setComposite(alpha);
        g.fillRect(
            (int) pt.getX() + (int) d.getX(),
            (int) pt.getY() + (int) d.getY(),
            (int) size.getX(),
            (int) size.getY());
        ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        g.drawRect(
            (int) pt.getX() + (int) d.getX(),
            (int) pt.getY() + (int) d.getY(),
            (int) size.getX(),
            (int) size.getY());
        ((Graphics2D) g).transform(at.createInverse());
      } catch (NoninvertibleTransformException e1) {
        RasterToolsUtil.messageBoxError("error_transformacion1", this, e1);
      }
    }
  }
  /** {@inheritDoc } */
  @Override
  public void setGraphicsCRS(CoordinateReferenceSystem crs) throws TransformException {

    if (crs == displayCRS) {
      switchToDisplayCRS();
    } else if (crs == objectiveCRS || crs == objectiveCRS2D) {
      switchToObjectiveCRS();
    } else
      try {
        crs = CRSUtilities.getCRS2D(crs);
        AffineTransform at = getAffineTransform(crs, displayCRS);
        at.preConcatenate(displayToDevice);
        current = OTHER_TRS;
        graphics.setTransform(at);
      } catch (FactoryException e) {
        throw new TransformException(
            Errors.format(Errors.Keys.ILLEGAL_COORDINATE_REFERENCE_SYSTEM), e);
      }
  }
예제 #23
0
파일: WorldView.java 프로젝트: pidigi/apple
 @Override
 public void draw(Graphics2D g2d) {
   double radius = facade.getShipRadius(getObject());
   double angle = -facade.getShipDirection(getObject());
   double x = facade.getShipX(getObject());
   double y = facade.getWorldHeight(world) - facade.getShipY(getObject());
   g2d.setColor(getColor());
   if (getImage() == null) {
     g2d.drawOval(
         (int) (x - radius), (int) (y - radius), (int) (2 * radius), (int) (2 * radius));
   } else {
     AffineTransform T = AffineTransform.getTranslateInstance(radius, radius);
     T.rotate(angle);
     T.translate(-radius, -radius);
     T.preConcatenate(AffineTransform.getTranslateInstance(x - radius, y - radius));
     g2d.drawImage(getImage(), T, null);
   }
   g2d.drawLine(
       (int) x, (int) y, (int) (x + Math.cos(angle) * radius), (int) (y + sin(angle) * radius));
 }
예제 #24
0
파일: WorldView.java 프로젝트: pidigi/apple
 @Override
 public void draw(Graphics2D g2d) {
   World world = facade.getAsteroidWorld(getObject());
   if (world != null) {
     double radius = facade.getAsteroidRadius(getObject());
     double x = facade.getAsteroidX(getObject());
     double y = facade.getWorldHeight(world) - facade.getAsteroidY(getObject());
     if (getImage() == null) {
       g2d.setColor(getColor());
       g2d.drawOval(
           (int) (x - radius), (int) (y - radius), (int) (2 * radius), (int) (2 * radius));
     } else {
       AffineTransform T =
           AffineTransform.getScaleInstance(
               2 * radius / getImage().getWidth(null), 2 * radius / getImage().getHeight(null));
       T.preConcatenate(AffineTransform.getTranslateInstance(x - radius, y - radius));
       g2d.drawImage(this.getImage(), T, null);
     }
   }
 }
예제 #25
0
파일: JImage.java 프로젝트: RussTedrake/lcm
  public synchronized void paint(Graphics gin) {
    Graphics2D g = (Graphics2D) gin;

    if (im == null) return;

    int height = getHeight();
    int width = getWidth();

    if (fit) {
      t = new AffineTransform();
      double scale = Math.min(((double) width) / im.getWidth(), ((double) height) / im.getHeight());
      // we'll re-center the transform in a moment.
      t.scale(scale, scale);
    }

    // if the image (in either X or Y) is smaller than the view port, then center
    // the image with respect to that axis.
    double mwidth = im.getWidth() * t.getScaleX();
    double mheight = im.getHeight() * t.getScaleY();
    if (mwidth < width)
      t.preConcatenate(
          AffineTransform.getTranslateInstance((width - mwidth) / 2.0 - t.getTranslateX(), 0));
    if (mheight < height)
      t.preConcatenate(
          AffineTransform.getTranslateInstance(0, (height - mheight) / 2.0 - t.getTranslateY()));

    // if we're allowing panning (because only a portion of the image is visible),
    // don't allow translations that show less information that is possible.
    Point2D topleft = t.transform(new Point2D.Double(0, 0), null);
    Point2D bottomright = t.transform(new Point2D.Double(im.getWidth(), im.getHeight()), null);

    if (mwidth > width) {
      if (topleft.getX() > 0)
        t.preConcatenate(AffineTransform.getTranslateInstance(-topleft.getX(), 0));
      if (bottomright.getX() < width)
        t.preConcatenate(AffineTransform.getTranslateInstance(width - bottomright.getX(), 0));
      //		    t.translate(width-bottomright.getX(), 0);
    }
    if (mheight > height) {
      if (topleft.getY() > 0)
        t.preConcatenate(AffineTransform.getTranslateInstance(0, -topleft.getY()));
      if (bottomright.getY() < height)
        t.preConcatenate(AffineTransform.getTranslateInstance(0, height - bottomright.getY()));
    }

    g.drawImage(im, t, null);
  }
예제 #26
0
 /**
  * Writes the <code>shape</code>, <code>coords</code>, <code>href</code>,
  * <code>nohref</code> Attribute for the specified figure and rectangle.
  *
  * @return Returns true, if the rect is inside of the image bounds.
  */
 private boolean writeRectAttributes(IXMLElement elem, SVGFigure f, Rectangle2D.Double rect) {
     AffineTransform t = TRANSFORM.getClone(f);
     if (t == null) {
         t = drawingTransform;
     } else {
         t.preConcatenate(drawingTransform);
     }
     
     if ((t.getType() &
             (AffineTransform.TYPE_UNIFORM_SCALE | AffineTransform.TYPE_TRANSLATION)) ==
             t.getType()
             ) {
         
         Point2D.Double start = new Point2D.Double(rect.x, rect.y);
         Point2D.Double end = new Point2D.Double(rect.x + rect.width, rect.y + rect.height);
         t.transform(start, start);
         t.transform(end, end);
         Rectangle r = new Rectangle(
                 (int) Math.min(start.x, end.x),
                 (int) Math.min(start.y, end.y),
                 (int) Math.abs(start.x - end.x),
                 (int) Math.abs(start.y - end.y)
                 );
         
         elem.setAttribute("shape", "rect");
         elem.setAttribute("coords",
                 r.x + ","+
                 r.y + ","+
                 (r.x + r.width) + ","+
                 (r.y + r.height)
                 );
         writeHrefAttribute(elem, f);
         return bounds.intersects(r);
     } else {
         return writePolyAttributes(elem, f, (Shape) rect);
     }
 }
예제 #27
0
파일: AffineRed.java 프로젝트: srnsw/xena
  public void genRect(WritableRaster wr) {
    if (me2src == null) return;

    Rectangle srcR = me2src.createTransformedShape(wr.getBounds()).getBounds();

    // System.out.println("Affine wrR: " + wr.getBounds());
    // System.out.println("Affine srcR: " + srcR);

    // Outset by two pixels so we get context for interpolation...
    srcR.setBounds(srcR.x - 1, srcR.y - 1, srcR.width + 2, srcR.height + 2);

    // Don't try and get data from src that it doesn't have...
    CachableRed src = (CachableRed) getSources().get(0);

    // Raster srcRas = src.getData(srcR);

    if (!srcR.intersects(src.getBounds())) return;
    Raster srcRas = src.getData(srcR.intersection(src.getBounds()));

    if (srcRas == null) return;

    // This works around the problem that the buffered ops
    // completely ignore the coords of the Rasters passed in.
    AffineTransform aff = (AffineTransform) src2me.clone();

    // Translate what is at 0,0 (which will be what our current
    // minX/Y is) to our current minX,minY.
    aff.concatenate(AffineTransform.getTranslateInstance(srcRas.getMinX(), srcRas.getMinY()));

    Point2D srcPt = new Point2D.Float(wr.getMinX(), wr.getMinY());
    srcPt = me2src.transform(srcPt, null);

    Point2D destPt =
        new Point2D.Double(srcPt.getX() - srcRas.getMinX(), srcPt.getY() - srcRas.getMinY());

    destPt = aff.transform(destPt, null);

    // Translate what will be at minX,minY to zero, zero
    // which where java2d will think the real minX,minY is.
    aff.preConcatenate(AffineTransform.getTranslateInstance(-destPt.getX(), -destPt.getY()));

    AffineTransformOp op = new AffineTransformOp(aff, hints);

    BufferedImage srcBI, myBI;
    ColorModel srcCM = src.getColorModel();
    ColorModel myCM = getColorModel();

    WritableRaster srcWR = (WritableRaster) srcRas;
    // If the output buffer is not premultiplied in certain cases
    // it fails to properly divide out the Alpha (it always does
    // the affine on premultiplied data). We help it out by
    // premultiplying for it.
    srcCM = GraphicsUtil.coerceData(srcWR, srcCM, true);
    srcBI =
        new BufferedImage(
            srcCM, srcWR.createWritableTranslatedChild(0, 0), srcCM.isAlphaPremultiplied(), null);

    myBI =
        new BufferedImage(
            myCM, wr.createWritableTranslatedChild(0, 0), myCM.isAlphaPremultiplied(), null);

    op.filter(srcBI, myBI);

    // if ((count % 40) == 0) {
    //     org.apache.batik.ImageDisplay.showImage("Src: " , srcBI);
    //     org.apache.batik.ImageDisplay.showImage("Dst: " , myBI);
    // }
    // count++;
  }
예제 #28
0
  public AffineTransform getAffineTransform(
      int width, int height, double[] _xyzSW, double[] _xyzSE, double[] _xyzNW) {
    int[] cornerNW = projection.screenProjection(_xyzNW);
    int[] cornerSE = projection.screenProjection(_xyzSE);
    int[] cornerSW = projection.screenProjection(_xyzSW);

    double[] vectWE = {
      (double) cornerSE[0] - (double) cornerSW[0], (double) cornerSE[1] - (double) cornerSW[1]
    };
    double normvectWE = sqrt(sqr(vectWE[0]) + sqr(vectWE[1]));
    double[] vectSN = {
      (double) cornerNW[0] - (double) cornerSW[0], (double) cornerNW[1] - (double) cornerSW[1]
    };
    double normvectSN = sqrt(sqr(vectSN[0]) + sqr(vectSN[1]));
    double angleSW =
        acos((vectWE[0] * vectSN[0] + vectWE[1] * vectSN[1]) / (normvectWE * normvectSN));

    if (angleSW == 0.0) {
      return null;
    }

    AffineTransform t = new AffineTransform();

    t.translate(cornerNW[0], cornerNW[1]);
    t.scale(sign(vectWE[0]), -sign(vectSN[1]));
    t.rotate(-atan(vectSN[0] / vectSN[1]));
    t.shear(0, 1 / tan(PI - angleSW));
    t.scale(normvectWE * cos(angleSW - PI / 2) / (double) width, normvectSN / (double) height);

    double[] _cornerSE_tr = new double[2];
    double[] _cornerSE = {width, height};
    t.transform(_cornerSE, 0, _cornerSE_tr, 0, 1);

    if (isDiff(_cornerSE_tr, cornerSE)) {
      double[] vectSE_NW_1 = {
        (double) cornerNW[0] - (double) cornerSE[0], (double) cornerNW[1] - (double) cornerSE[1]
      };
      double[] vectSE_NW_2 = {
        (double) cornerNW[0] - (double) _cornerSE_tr[0],
        (double) cornerNW[1] - (double) _cornerSE_tr[1]
      };

      double normvect_1 = sqrt(sqr(vectSE_NW_1[0]) + sqr(vectSE_NW_1[1]));
      double normvect_2 = sqrt(sqr(vectSE_NW_1[0]) + sqr(vectSE_NW_1[1]));

      double cos_angle =
          (((vectSE_NW_1[0] * vectSE_NW_2[0] + vectSE_NW_1[1] * vectSE_NW_2[1])
              / (normvect_1 * normvect_2)));
      double vect = (vectSE_NW_1[0] * vectSE_NW_2[1] - vectSE_NW_1[1] * vectSE_NW_2[0]);

      AffineTransform t2 = new AffineTransform();
      if (vect < 0) {
        t2.rotate(acos(cos_angle), cornerNW[0], cornerNW[1]);
      } else {
        t2.rotate(-acos(cos_angle), cornerNW[0], cornerNW[1]);
      }
      t.preConcatenate(t2);
    }

    // TODO patch for many cases...

    /*double[] _cornerSW_tr = new double[2];
    double[] _cornerSW = { 0, img.getHeight(canvas) };
    t.transform(_cornerSW, 0, _cornerSW_tr, 0, 1);

    if (isDiff(_cornerSW_tr, cornerSW)) {
    double[] vectSW_NW_1 = { (double) cornerNW[0] - (double) cornerSW[0], (double) cornerNW[1] - (double) cornerSW[1] };
    double[] vectSW_NW_2 = { (double) cornerNW[0] - (double) _cornerSW_tr[0], (double) cornerNW[1] - (double) _cornerSW_tr[1] };

    double normvect_1 = sqrt(sqr(vectSW_NW_1[0]) + sqr(vectSW_NW_1[1]));
    double normvect_2 = sqrt(sqr(vectSW_NW_1[0]) + sqr(vectSW_NW_1[1]));

    double cos_angle = (((vectSW_NW_1[0] * vectSW_NW_2[0] + vectSW_NW_1[1] * vectSW_NW_2[1]) / (normvect_1 * normvect_2)));
    double vect = (vectSW_NW_1[0] * vectSW_NW_2[1] - vectSW_NW_1[1] * vectSW_NW_2[0]);

    System.out.println(cos_angle + " " + vect + " -> " + toDegrees(acos(cos_angle)));

    //System.out.println(" "+vectSE_NW_1[0]+","+vectSE_NW_1[1]+"  "+vectSE_NW_2[0]+","+vectSE_NW_2[1]);
    AffineTransform t2 = new AffineTransform();
    if (vect > 0)
    t2.rotate(acos(cos_angle), cornerNW[0], cornerNW[1]);
    else
    t2.rotate(-acos(cos_angle), cornerNW[0], cornerNW[1]);
    t.preConcatenate(t2);

    }*/
    return t;
  }
예제 #29
0
  /**
   * Load a specified a raster as a portion of the granule describe by this {@link
   * GranuleDescriptor}.
   *
   * @param imageReadParameters the {@link ImageReadParam} to use for reading.
   * @param index the index to use for the {@link ImageReader}.
   * @param cropBBox the bbox to use for cropping.
   * @param mosaicWorldToGrid the cropping grid to world transform.
   * @param request the incoming request to satisfy.
   * @param hints {@link Hints} to be used for creating this raster.
   * @return a specified a raster as a portion of the granule describe by this {@link
   *     GranuleDescriptor}.
   * @throws IOException in case an error occurs.
   */
  public GranuleLoadingResult loadRaster(
      final ImageReadParam imageReadParameters,
      final int index,
      final ReferencedEnvelope cropBBox,
      final MathTransform2D mosaicWorldToGrid,
      final RasterLayerRequest request,
      final Hints hints)
      throws IOException {

    if (LOGGER.isLoggable(java.util.logging.Level.FINER)) {
      final String name = Thread.currentThread().getName();
      LOGGER.finer(
          "Thread:" + name + " Loading raster data for granuleDescriptor " + this.toString());
    }
    ImageReadParam readParameters = null;
    int imageIndex;
    final ReferencedEnvelope bbox =
        inclusionGeometry != null
            ? new ReferencedEnvelope(
                granuleBBOX.intersection(inclusionGeometry.getEnvelopeInternal()),
                granuleBBOX.getCoordinateReferenceSystem())
            : granuleBBOX;
    boolean doFiltering = false;
    if (filterMe) {
      doFiltering = Utils.areaIsDifferent(inclusionGeometry, baseGridToWorld, granuleBBOX);
    }

    // intersection of this tile bound with the current crop bbox
    final ReferencedEnvelope intersection =
        new ReferencedEnvelope(
            bbox.intersection(cropBBox), cropBBox.getCoordinateReferenceSystem());
    if (intersection.isEmpty()) {
      if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
        LOGGER.fine(
            new StringBuilder("Got empty intersection for granule ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString());
      }
      return null;
    }

    ImageInputStream inStream = null;
    ImageReader reader = null;
    try {
      //
      // get info about the raster we have to read
      //

      // get a stream
      assert cachedStreamSPI != null : "no cachedStreamSPI available!";
      inStream =
          cachedStreamSPI.createInputStreamInstance(
              granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
      if (inStream == null) return null;

      // get a reader and try to cache the relevant SPI
      if (cachedReaderSPI == null) {
        reader = ImageIOExt.getImageioReader(inStream);
        if (reader != null) cachedReaderSPI = reader.getOriginatingProvider();
      } else reader = cachedReaderSPI.createReaderInstance();
      if (reader == null) {
        if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
          LOGGER.warning(
              new StringBuilder("Unable to get s reader for granuleDescriptor ")
                  .append(this.toString())
                  .append(" with request ")
                  .append(request.toString())
                  .append(" Resulting in no granule loaded: Empty result")
                  .toString());
        }
        return null;
      }
      // set input
      reader.setInput(inStream);

      // Checking for heterogeneous granules
      if (request.isHeterogeneousGranules()) {
        // create read parameters
        readParameters = new ImageReadParam();

        // override the overviews controller for the base layer
        imageIndex =
            ReadParamsController.setReadParams(
                request.getRequestedResolution(),
                request.getOverviewPolicy(),
                request.getDecimationPolicy(),
                readParameters,
                request.rasterManager,
                overviewsController);
      } else {
        imageIndex = index;
        readParameters = imageReadParameters;
      }

      // get selected level and base level dimensions
      final GranuleOverviewLevelDescriptor selectedlevel = getLevel(imageIndex, reader);

      // now create the crop grid to world which can be used to decide
      // which source area we need to crop in the selected level taking
      // into account the scale factors imposed by the selection of this
      // level together with the base level grid to world transformation
      AffineTransform2D cropWorldToGrid =
          new AffineTransform2D(selectedlevel.gridToWorldTransformCorner);
      cropWorldToGrid = (AffineTransform2D) cropWorldToGrid.inverse();
      // computing the crop source area which lives into the
      // selected level raster space, NOTICE that at the end we need to
      // take into account the fact that we might also decimate therefore
      // we cannot just use the crop grid to world but we need to correct
      // it.
      final Rectangle sourceArea =
          CRS.transform(cropWorldToGrid, intersection).toRectangle2D().getBounds();
      // gutter
      if (selectedlevel.baseToLevelTransform.isIdentity()) sourceArea.grow(2, 2);
      XRectangle2D.intersect(
          sourceArea,
          selectedlevel.rasterDimensions,
          sourceArea); // make sure roundings don't bother us
      // is it empty??
      if (sourceArea.isEmpty()) {
        if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
          LOGGER.fine(
              "Got empty area for granuleDescriptor "
                  + this.toString()
                  + " with request "
                  + request.toString()
                  + " Resulting in no granule loaded: Empty result");
        }
        return null;

      } else if (LOGGER.isLoggable(java.util.logging.Level.FINER)) {
        LOGGER.finer(
            "Loading level "
                + imageIndex
                + " with source region: "
                + sourceArea
                + " subsampling: "
                + readParameters.getSourceXSubsampling()
                + ","
                + readParameters.getSourceYSubsampling()
                + " for granule:"
                + granuleUrl);
      }

      // Setting subsampling
      int newSubSamplingFactor = 0;
      final String pluginName = cachedReaderSPI.getPluginClassName();
      if (pluginName != null && pluginName.equals(ImageUtilities.DIRECT_KAKADU_PLUGIN)) {
        final int ssx = readParameters.getSourceXSubsampling();
        final int ssy = readParameters.getSourceYSubsampling();
        newSubSamplingFactor = ImageIOUtilities.getSubSamplingFactor2(ssx, ssy);
        if (newSubSamplingFactor != 0) {
          if (newSubSamplingFactor > maxDecimationFactor && maxDecimationFactor != -1) {
            newSubSamplingFactor = maxDecimationFactor;
          }
          readParameters.setSourceSubsampling(newSubSamplingFactor, newSubSamplingFactor, 0, 0);
        }
      }

      // set the source region
      readParameters.setSourceRegion(sourceArea);
      final RenderedImage raster;
      try {
        // read
        raster =
            request
                .getReadType()
                .read(
                    readParameters,
                    imageIndex,
                    granuleUrl,
                    selectedlevel.rasterDimensions,
                    reader,
                    hints,
                    false);

      } catch (Throwable e) {
        if (LOGGER.isLoggable(java.util.logging.Level.FINE)) {
          LOGGER.log(
              java.util.logging.Level.FINE,
              "Unable to load raster for granuleDescriptor "
                  + this.toString()
                  + " with request "
                  + request.toString()
                  + " Resulting in no granule loaded: Empty result",
              e);
        }
        return null;
      }

      // use fixed source area
      sourceArea.setRect(readParameters.getSourceRegion());

      //
      // setting new coefficients to define a new affineTransformation
      // to be applied to the grid to world transformation
      // -----------------------------------------------------------------------------------
      //
      // With respect to the original envelope, the obtained planarImage
      // needs to be rescaled. The scaling factors are computed as the
      // ratio between the cropped source region sizes and the read
      // image sizes.
      //
      // place it in the mosaic using the coords created above;
      double decimationScaleX = ((1.0 * sourceArea.width) / raster.getWidth());
      double decimationScaleY = ((1.0 * sourceArea.height) / raster.getHeight());
      final AffineTransform decimationScaleTranform =
          XAffineTransform.getScaleInstance(decimationScaleX, decimationScaleY);

      // keep into account translation  to work into the selected level raster space
      final AffineTransform afterDecimationTranslateTranform =
          XAffineTransform.getTranslateInstance(sourceArea.x, sourceArea.y);

      // now we need to go back to the base level raster space
      final AffineTransform backToBaseLevelScaleTransform = selectedlevel.baseToLevelTransform;

      // now create the overall transform
      final AffineTransform finalRaster2Model = new AffineTransform(baseGridToWorld);
      finalRaster2Model.concatenate(CoverageUtilities.CENTER_TO_CORNER);
      final double x = finalRaster2Model.getTranslateX();
      final double y = finalRaster2Model.getTranslateY();

      if (!XAffineTransform.isIdentity(backToBaseLevelScaleTransform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(backToBaseLevelScaleTransform);
      if (!XAffineTransform.isIdentity(afterDecimationTranslateTranform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(afterDecimationTranslateTranform);
      if (!XAffineTransform.isIdentity(decimationScaleTranform, Utils.AFFINE_IDENTITY_EPS))
        finalRaster2Model.concatenate(decimationScaleTranform);

      // keep into account translation factors to place this tile
      finalRaster2Model.preConcatenate((AffineTransform) mosaicWorldToGrid);
      final Interpolation interpolation = request.getInterpolation();
      // paranoiac check to avoid that JAI freaks out when computing its internal layouT on images
      // that are too small
      Rectangle2D finalLayout =
          ImageUtilities.layoutHelper(
              raster,
              (float) finalRaster2Model.getScaleX(),
              (float) finalRaster2Model.getScaleY(),
              (float) finalRaster2Model.getTranslateX(),
              (float) finalRaster2Model.getTranslateY(),
              interpolation);
      if (finalLayout.isEmpty()) {
        if (LOGGER.isLoggable(java.util.logging.Level.INFO))
          LOGGER.info(
              "Unable to create a granuleDescriptor "
                  + this.toString()
                  + " due to jai scale bug creating a null source area");
        return null;
      }
      ROI granuleLoadingShape = null;
      if (granuleROIShape != null) {

        final Point2D translate =
            mosaicWorldToGrid.transform(new DirectPosition2D(x, y), (Point2D) null);
        AffineTransform tx2 = new AffineTransform();
        tx2.preConcatenate(
            AffineTransform.getScaleInstance(
                ((AffineTransform) mosaicWorldToGrid).getScaleX(),
                -((AffineTransform) mosaicWorldToGrid).getScaleY()));
        tx2.preConcatenate(
            AffineTransform.getScaleInstance(
                ((AffineTransform) baseGridToWorld).getScaleX(),
                -((AffineTransform) baseGridToWorld).getScaleY()));
        tx2.preConcatenate(
            AffineTransform.getTranslateInstance(translate.getX(), translate.getY()));
        granuleLoadingShape = (ROI) granuleROIShape.transform(tx2);
      }
      // apply the affine transform  conserving indexed color model
      final RenderingHints localHints =
          new RenderingHints(
              JAI.KEY_REPLACE_INDEX_COLOR_MODEL,
              interpolation instanceof InterpolationNearest ? Boolean.FALSE : Boolean.TRUE);
      if (XAffineTransform.isIdentity(finalRaster2Model, Utils.AFFINE_IDENTITY_EPS)) {
        return new GranuleLoadingResult(raster, granuleLoadingShape, granuleUrl, doFiltering);
      } else {
        //
        // In case we are asked to use certain tile dimensions we tile
        // also at this stage in case the read type is Direct since
        // buffered images comes up untiled and this can affect the
        // performances of the subsequent affine operation.
        //
        final Dimension tileDimensions = request.getTileDimensions();
        if (tileDimensions != null && request.getReadType().equals(ReadType.DIRECT_READ)) {
          final ImageLayout layout = new ImageLayout();
          layout.setTileHeight(tileDimensions.width).setTileWidth(tileDimensions.height);
          localHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
        } else {
          if (hints != null && hints.containsKey(JAI.KEY_IMAGE_LAYOUT)) {
            final Object layout = hints.get(JAI.KEY_IMAGE_LAYOUT);
            if (layout != null && layout instanceof ImageLayout) {
              localHints.add(
                  new RenderingHints(JAI.KEY_IMAGE_LAYOUT, ((ImageLayout) layout).clone()));
            }
          }
        }
        if (hints != null && hints.containsKey(JAI.KEY_TILE_CACHE)) {
          final Object cache = hints.get(JAI.KEY_TILE_CACHE);
          if (cache != null && cache instanceof TileCache)
            localHints.add(new RenderingHints(JAI.KEY_TILE_CACHE, (TileCache) cache));
        }
        if (hints != null && hints.containsKey(JAI.KEY_TILE_SCHEDULER)) {
          final Object scheduler = hints.get(JAI.KEY_TILE_SCHEDULER);
          if (scheduler != null && scheduler instanceof TileScheduler)
            localHints.add(new RenderingHints(JAI.KEY_TILE_SCHEDULER, (TileScheduler) scheduler));
        }
        boolean addBorderExtender = true;
        if (hints != null && hints.containsKey(JAI.KEY_BORDER_EXTENDER)) {
          final Object extender = hints.get(JAI.KEY_BORDER_EXTENDER);
          if (extender != null && extender instanceof BorderExtender) {
            localHints.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER, (BorderExtender) extender));
            addBorderExtender = false;
          }
        }
        // border extender
        if (addBorderExtender) {
          localHints.add(ImageUtilities.BORDER_EXTENDER_HINTS);
        }
        //                boolean hasScaleX=!(Math.abs(finalRaster2Model.getScaleX()-1) <
        // 1E-2/(raster.getWidth()+1-raster.getMinX()));
        //                boolean hasScaleY=!(Math.abs(finalRaster2Model.getScaleY()-1) <
        // 1E-2/(raster.getHeight()+1-raster.getMinY()));
        //                boolean hasShearX=!(finalRaster2Model.getShearX() == 0.0);
        //                boolean hasShearY=!(finalRaster2Model.getShearY() == 0.0);
        //                boolean hasTranslateX=!(Math.abs(finalRaster2Model.getTranslateX()) <
        // 0.01F);
        //                boolean hasTranslateY=!(Math.abs(finalRaster2Model.getTranslateY()) <
        // 0.01F);
        //                boolean isTranslateXInt=!(Math.abs(finalRaster2Model.getTranslateX() -
        // (int) finalRaster2Model.getTranslateX()) <  0.01F);
        //                boolean isTranslateYInt=!(Math.abs(finalRaster2Model.getTranslateY() -
        // (int) finalRaster2Model.getTranslateY()) <  0.01F);
        //
        //                boolean isIdentity = finalRaster2Model.isIdentity() &&
        // !hasScaleX&&!hasScaleY &&!hasTranslateX&&!hasTranslateY;

        //                // TODO how can we check that the a skew is harmelss????
        //                if(isIdentity){
        //                    // TODO check if we are missing anything like tiling or such that
        // comes from hints
        //                    return new GranuleLoadingResult(raster, granuleLoadingShape,
        // granuleUrl, doFiltering);
        //                }
        //
        //                // TOLERANCE ON PIXELS SIZE
        //
        //                // Check and see if the affine transform is in fact doing
        //                // a Translate operation. That is a scale by 1 and no rotation.
        //                // In which case call translate. Note that only integer translate
        //                // is applicable. For non-integer translate we'll have to do the
        //                // affine.
        //                // If the hints contain an ImageLayout hint, we can't use
        //                // TranslateIntOpImage since it isn't capable of dealing with that.
        //                // Get ImageLayout from renderHints if any.
        //                ImageLayout layout = RIFUtil.getImageLayoutHint(localHints);
        //                if ( !hasScaleX &&
        //                     !hasScaleY  &&
        //                      !hasShearX&&
        //                      !hasShearY&&
        //                      isTranslateXInt&&
        //                      isTranslateYInt&&
        //                    layout == null) {
        //                    // It's a integer translate
        //                    return new GranuleLoadingResult(new TranslateIntOpImage(raster,
        //                                                    localHints,
        //                                                   (int) finalRaster2Model.getShearX(),
        //                                                   (int)
        // finalRaster2Model.getShearY()),granuleLoadingShape, granuleUrl, doFiltering);
        //                }

        ImageWorker iw = new ImageWorker(raster);
        iw.setRenderingHints(localHints);
        iw.affine(finalRaster2Model, interpolation, request.getBackgroundValues());
        return new GranuleLoadingResult(
            iw.getRenderedImage(), granuleLoadingShape, granuleUrl, doFiltering);
      }

    } catch (IllegalStateException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;
    } catch (org.opengis.referencing.operation.NoninvertibleTransformException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;
    } catch (TransformException e) {
      if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) {
        LOGGER.log(
            java.util.logging.Level.WARNING,
            new StringBuilder("Unable to load raster for granuleDescriptor ")
                .append(this.toString())
                .append(" with request ")
                .append(request.toString())
                .append(" Resulting in no granule loaded: Empty result")
                .toString(),
            e);
      }
      return null;

    } finally {
      try {
        if (request.getReadType() != ReadType.JAI_IMAGEREAD && inStream != null) {
          inStream.close();
        }
      } finally {
        if (request.getReadType() != ReadType.JAI_IMAGEREAD && reader != null) {
          reader.dispose();
        }
      }
    }
  }
예제 #30
0
  @Override
  public CanvasPainter showAction(
      SVGHandle handle,
      int level,
      Set<Element> elementSet,
      SelectionItem item,
      Point2D firstPoint,
      Point2D currentPoint) {

    // getting the element that will undergo the action
    Element element = elementSet.iterator().next();

    // the canvas painter that should be returned
    CanvasPainter painter = null;

    // whether the shape should be painted
    boolean canPaintShape = true;

    // the shape that will be painted
    Shape shape = null;

    // getting the action transform
    AffineTransform actionTransform = null;

    switch (level) {
      case 0:

        // getting the resize transform
        actionTransform = getResizeTransform(handle, element, item, firstPoint, currentPoint);
        break;

      case 1:
        if (item.getType() == SelectionItem.CENTER) {

          // storing the center point for the rotate action
          rotationSkewSelectionItemCenterPoint = currentPoint;
          item.setPoint(currentPoint);
          canPaintShape = false;

        } else if (item.getType() == SelectionItem.NORTH_WEST
            || item.getType() == SelectionItem.NORTH_EAST
            || item.getType() == SelectionItem.SOUTH_EAST
            || item.getType() == SelectionItem.SOUTH_WEST) {

          // getting the rotation transform
          actionTransform = getRotationTransform(handle, element, firstPoint, currentPoint);

        } else {

          // getting the skew transform
          actionTransform = getSkewTransform(handle, element, firstPoint, currentPoint, item);
        }

        break;
    }

    if (actionTransform != null) {

      // getting the initial shape
      shape = getShape(handle, element, true);

      // getting the element's transform
      AffineTransform transform = handle.getSvgElementsManager().getTransform(element);

      // concatenating the action transform to the element's transform
      transform.preConcatenate(actionTransform);

      // computing the screen scaled shape
      shape = handle.getTransformsManager().getScaledShape(shape, false, transform);
    }

    if (canPaintShape && shape != null) {

      final Shape fshape = shape;

      // creating the set of the clips
      final HashSet<Rectangle2D> fclips = new HashSet<Rectangle2D>();
      fclips.add(fshape.getBounds2D());

      painter =
          new CanvasPainter() {

            @Override
            public void paintToBeDone(Graphics2D g) {

              g = (Graphics2D) g.create();
              g.setRenderingHint(
                  RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              g.setColor(strokeColor);
              g.draw(fshape);
              g.dispose();
            }

            @Override
            public Set<Rectangle2D> getClip() {

              return fclips;
            }
          };
    }

    return painter;
  }