package com.vividsolutions.jump.workbench.imagery.ecw; /* * 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 */ import java.awt.image.BufferedImage; import java.awt.geom.Rectangle2D; import java.awt.geom.Point2D; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jump.JUMPException; import com.vividsolutions.jump.feature.Feature; import com.vividsolutions.jump.workbench.imagery.ReferencedImage; import com.vividsolutions.jump.workbench.ui.Viewport; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Color; /** * A {@link ReferencedImage} for ECW files */ public class ECWImage implements ReferencedImage { private Envelope imageEnv = new Envelope(); private JNCSRendererProxy renderer; private int[] bandlist; private boolean validSetView = false; private Envelope lastViewportEnv = new Envelope(); // debugging only // int count = 0; public ECWImage(String location) throws JUMPException { init(location); } private void init(String location) throws JUMPException { try { renderer = new JNCSRendererProxy(location, false); double xm = renderer.getOriginX(); double yM = renderer.getOriginY(); double xM = xm + (double)renderer.getWidth()*renderer.getCellIncrementX(); double ym = yM + (double)renderer.getHeight()*renderer.getCellIncrementY(); // image enveloppe imageEnv = new Envelope(xm, xM, ym, yM); // use all bands bandlist = new int[renderer.getNumBands()]; for (int i = 0; i < bandlist.length; ++i) { bandlist[i] = i; } } catch (Exception e) { throw new JUMPException(e.getMessage()); } } public Envelope getEnvelope() { return imageEnv; } public void paint( Feature f, Graphics2D g, Viewport viewport ) throws JUMPException { Envelope viewportEnv = viewport.getEnvelopeInModelCoordinates(); if (!imageEnv.intersects(viewportEnv)) { return; } // only set view if viewport has changed if (!viewportEnv.equals(lastViewportEnv)) { validSetView = false; lastViewportEnv = viewportEnv; } try { // width and height of the viewport int width = viewport.getPanel().getWidth(); int height = viewport.getPanel().getHeight(); // viewport in model coordinates double dWorldTLX = viewportEnv.getMinX(); double dWorldTLY = viewportEnv.getMaxY(); double dWorldBRX = viewportEnv.getMaxX(); double dWorldBRY = viewportEnv.getMinY(); // only set view if viewport has changed if (!validSetView) { // Compute the rectangle including all the pixels to display // Compute topleft corner // As convertWorldToDataset returns 0 from dWorldTLX-incr/2 to // dWorldTLX+incr/2, we have to translate the topleft corner to make // sure the topleft pixel will be displayed Point firstCell = renderer.convertWorldToDataset( dWorldTLX - renderer.getCellIncrementX()/2.0, dWorldTLY - renderer.getCellIncrementY()/2.0); // If the top left corner of the viewport is negative (image corner is // inside the viewport), display the image from column 0 int firstColumn = Math.max(0, firstCell.x); int firstLine = Math.max(0, firstCell.y); // tlCorner is the world coordinate of the topleft corner of the topleft // pixel to be drawn Point2D.Double tlCorner = renderer.convertDatasetToWorld( firstColumn, firstLine); // Compute bottomRight corner // As convertWorldToDataset returns 0 from dWorldTLX-incr/2 to // dWorldTLX+incr/2, we have to translate the topleft corner to make // sure the bottomRight pixel will be displayed Point lastCell = renderer.convertWorldToDataset( dWorldBRX - renderer.getCellIncrementX()/2.0, dWorldBRY - renderer.getCellIncrementY()/2.0); // If the image bottomRight corner is inside the viewport, // display the image up to lastCell + 1 int lastColumn = (int)Math.min( renderer.getWidth() - 1, lastCell.x + 1); int lastLine = (int)Math.min( renderer.getHeight() - 1, lastCell.y + 1); // brCorner is the world coordinate of the bottomRight corner of the // bottomRight pixel to be drawn Point2D.Double brCorner = renderer.convertDatasetToWorld( lastColumn + 1, lastLine + 1); Envelope finalEnvelope = new Envelope( tlCorner.x, brCorner.x, brCorner.y, tlCorner.y); int nbColumns = (lastColumn - firstColumn) + 1; int nbLines = (lastLine - firstLine) + 1; width = width <= nbColumns ? width : nbColumns; height = height <= nbLines ? height : nbLines; BufferedImage ecwImage = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB); int [] pRGBArray = new int[width]; try { renderer.setView( renderer.getNumBands(), bandlist, firstColumn, firstLine, lastColumn, lastLine, width, height); } catch (Exception e) { e.printStackTrace(); } for (int line = 0; line < height; line++) { renderer.readLineRGBA(pRGBArray); ecwImage.setRGB(0, line, width, 1, pRGBArray, 0, width); } Rectangle2D finalRect = viewport.toViewRectangle(finalEnvelope); // debugging only //System.out.println("Image size : " + renderer.getWidth() + " x " + renderer.getHeight()); //System.out.println("Pixel size : " + renderer.getCellIncrementX() + " x " + renderer.getCellIncrementY()); //System.out.println("Image envelope : " + imageEnv); //System.out.println("First pixel to display : " + firstColumn + "," + firstLine); //System.out.println("Last pixel to display : " + lastColumn + "," + lastLine); g.drawImage(ecwImage, (int)finalRect.getMinX(), (int)finalRect.getMinY(), (int)finalRect.getMaxX(), (int)finalRect.getMaxY(), 0, 0, ecwImage.getWidth(), ecwImage.getHeight(), Color.WHITE, viewport.getPanel()); } // if (!validSetView) } catch (Exception e) { validSetView = false; throw new JUMPException(e.getMessage()); } } public void close() { renderer.close(true); } public String getType() { return "ECW"; } }