Java tutorial
/* uDig - User Friendly Desktop Internet GIS client * http://udig.refractions.net * (C) 2004-2008, Refractions Research Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package net.refractions.udig.catalog.internal.worldimage; import static net.refractions.udig.catalog.worldimage.internal.Messages.InMemoryCoverageLoader_close_button; import static net.refractions.udig.catalog.worldimage.internal.Messages.InMemoryCoverageLoader_message; import static net.refractions.udig.catalog.worldimage.internal.Messages.InMemoryCoverageLoader_msgTitle; import static net.refractions.udig.catalog.worldimage.internal.Messages.InMemoryCoverageLoader_restart_button; import static org.eclipse.jface.dialogs.MessageDialog.QUESTION; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.IOException; import java.lang.ref.SoftReference; import java.text.MessageFormat; import java.util.Hashtable; import net.refractions.udig.catalog.rasterings.AbstractRasterGeoResource; import net.refractions.udig.catalog.rasterings.GridCoverageLoader; import net.refractions.udig.catalog.rasterings.RasteringsPlugin; import net.refractions.udig.internal.ui.UiPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.geotools.coverage.grid.GeneralGridGeometry; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.ViewType; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.geometry.GeneralEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.coverage.grid.GridCoverage; import org.opengis.coverage.grid.GridEnvelope; import org.opengis.geometry.Envelope; /** * Keeps the full coverage in memory and returns the same instance * * @author jeichar * @since 1.1.0 */ public class InMemoryCoverageLoader extends GridCoverageLoader { private static final GridCoverage EMPTY_COVERAGE; static { Envelope envelope = new ReferencedEnvelope(0, .00001, 0, 0.00001, DefaultGeographicCRS.WGS84); BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY); Graphics2D createGraphics = image.createGraphics(); createGraphics.drawRect(0, 0, 1, 1); createGraphics.dispose(); EMPTY_COVERAGE = new GridCoverageFactory().create("placeholder", image, envelope); //$NON-NLS-1$ } private volatile SoftReference<GridCoverage> coverage = new SoftReference<GridCoverage>(null); private String fileName; public InMemoryCoverageLoader(AbstractRasterGeoResource resource, String fileName) throws IOException { super(resource); this.fileName = fileName; } @Override public synchronized GridCoverage load(GeneralGridGeometry geom, IProgressMonitor monitor) throws IOException { if (coverage.get() == null) { try { AbstractGridCoverage2DReader reader = resource.resolve(AbstractGridCoverage2DReader.class, monitor); GridEnvelope range = reader.getOriginalGridRange(); GeneralEnvelope env = reader.getOriginalEnvelope(); GridGeometry2D all = new GridGeometry2D(range, env); GridCoverage2D coverage2d = (GridCoverage2D) super.load(all, monitor); RenderedImage image = coverage2d.view(ViewType.RENDERED).getRenderedImage(); RasteringsPlugin.log("WARNING. Loading image fully into memory. It is about " + size(image) //$NON-NLS-1$ + " MB in size decompressed", null); //$NON-NLS-1$ @SuppressWarnings("rawtypes") BufferedImage bi = new BufferedImage(image.getColorModel(), (WritableRaster) image.getData(), false, new Hashtable()); GridCoverageFactory fac = new GridCoverageFactory(); GridCoverage2D c = fac.create(fileName, bi, env); coverage = new SoftReference<GridCoverage>(c); } catch (OutOfMemoryError e) { updateMemoryLevel(); } catch (Exception t) { updateMemoryLevel(); } } return coverage.get(); } private void updateMemoryLevel() throws IOException { int heap; int originalHeap = UiPlugin.getMaxHeapSize(); if (originalHeap < 700) { heap = 1024; } else if (originalHeap < 1500) { heap = 2048; } else { heap = originalHeap * 2; } String os = Platform.getOS(); if (heap > 1024 && os == Platform.OS_WIN32) { heap = 1024; } final int finalHeap = heap; coverage = new SoftReference<GridCoverage>(EMPTY_COVERAGE); Display.getDefault().asyncExec(new Runnable() { public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); String title = InMemoryCoverageLoader_msgTitle; String desc = MessageFormat.format(InMemoryCoverageLoader_message, resource.getIdentifier(), finalHeap); String[] buttons = { InMemoryCoverageLoader_restart_button, InMemoryCoverageLoader_close_button }; MessageDialog dialog = new MessageDialog(shell, title, null, desc, QUESTION, buttons, 0) { @Override protected void buttonPressed(int buttonId) { if (buttonId == 0) { try { UiPlugin.setMaxHeapSize(String.valueOf(finalHeap)); PlatformUI.getWorkbench().restart(); } catch (IOException e) { throw (RuntimeException) new RuntimeException().initCause(e); } } super.buttonPressed(buttonId); } }; dialog.open(); } }); } private double size(RenderedImage bi) { double bitPerPixel = 0; for (int elem : bi.getColorModel().getComponentSize()) { bitPerPixel += elem; } double width = (double) bi.getWidth(); double height = (double) bi.getHeight(); double pixelNum = width * height; double bitsNum = pixelNum * bitPerPixel; double bytesNum = bitsNum / 8.0; double megNum = bytesNum / 1024.0; return megNum; } }