Package org.locationtech.udig.project.ui.wizard.export.image

Source Code of org.locationtech.udig.project.ui.wizard.export.image.ExportMapToImageWizard

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004-2013, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.project.ui.wizard.export.image;

import java.awt.Graphics2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.locationtech.udig.catalog.CatalogPlugin;
import org.locationtech.udig.catalog.ICatalog;
import org.locationtech.udig.catalog.ID;
import org.locationtech.udig.catalog.IService;
import org.locationtech.udig.catalog.IServiceFactory;
import org.locationtech.udig.catalog.URLUtils;
import org.locationtech.udig.core.internal.Icons;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.render.RenderException;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.ApplicationGIS.DrawMapParameter;
import org.locationtech.udig.project.ui.BoundsStrategy;
import org.locationtech.udig.project.ui.internal.Messages;
import org.locationtech.udig.project.ui.internal.ProjectUIPlugin;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IExportWizard;
import org.eclipse.ui.IWorkbench;
import org.geotools.data.DataUtilities;
import org.opengis.referencing.operation.TransformException;

/**
* Wizard for exporting a collection of maps to a collection of images. One for each map.
*
* @author Jesse
*/
public class ExportMapToImageWizard extends Wizard implements IExportWizard {

    public static final String DIRECTORY_KEY = "exportDirectoryKey"; //$NON-NLS-1$
    public static final String FORMAT_KEY = "exportFormatKey"; //$NON-NLS-1$
    public static final String WIDTH_KEY = "widthKey"; //$NON-NLS-1$
    public static final String HEIGHT_KEY = Messages.ExportMapToImageWizard_3;
    public static final String SELECTION = "SELECTION_HANDLING"; //$NON-NLS-1$

    private ImageExportPage imageSettingsPage = new ImageExportPage();
    private MapSelectorPageWithScaleColumn mapSelectorPage;

    public ExportMapToImageWizard() {
        setWindowTitle(Messages.ExportMapToImageWizard_windowtitle);
        setDialogSettings(ProjectUIPlugin.getDefault().getDialogSettings());

        String title = null; // will use default title
        ImageDescriptor banner = ProjectUIPlugin.getDefault().getImageDescriptor(Icons.WIZBAN + "exportimage_wiz.gif"); //$NON-NLS-1$
        setDefaultPageImageDescriptor(banner);
        mapSelectorPage = new MapSelectorPageWithScaleColumn("Select Map With Scale", title, banner); //$NON-NLS-1$
        addPage(mapSelectorPage);
        addPage(imageSettingsPage);
        setNeedsProgressMonitor(true);
    }

    @Override
    public void setContainer( IWizardContainer wizardContainer ) {
        super.setContainer(wizardContainer);
        addPageChangeListener();
    }

    /**
     * Updates the Map selector page's description so that it indicates the File format that the
     * export will go to.
     */
    private void addPageChangeListener() {
        if (getContainer() instanceof WizardDialog) {
            WizardDialog dialog = (WizardDialog) getContainer();
            dialog.addPageChangedListener(new IPageChangedListener(){

                public void pageChanged( PageChangedEvent event ) {
                    WizardPage currentPage = (WizardPage) event.getSelectedPage();
                    if (currentPage == mapSelectorPage) {
                        String currentFormat = imageSettingsPage.getFormat().getName();
                        String description = MessageFormat.format(
                                "Select map to export to {0} images", currentFormat);
                        currentPage.setDescription(description);
                    }
                }

            });
        }
    }
    @Override
    public boolean performFinish() {

        final Collection<String> errors = new ArrayList<String>();
        final Collection<IMap> renderedMaps = new ArrayList<IMap>();
        try {
            getContainer().run(false, true, new IRunnableWithProgress(){

                public void run( IProgressMonitor monitor ) throws InvocationTargetException,
                        InterruptedException {

                    Collection<IMap> maps = mapSelectorPage.getMaps();

                    monitor.beginTask(Messages.ExportMapToImageWizard_exportMapsTaskName, maps
                            .size() * 3 + 1);
                    monitor.worked(1);
                    for( IMap map : maps ) {
                        try {
                            exportMap(map, new SubProgressMonitor(monitor, 3));
                        } catch (RenderException e) {

                            Object[] args = new Object[]{map.getName(), e.getLocalizedMessage()};
                            String pattern = Messages.ExportMapToImageWizard_renderingErrorMessage;
                            errors.add(MessageFormat.format(pattern, args));
                        } catch (IOException e) {
                            errors.add(Messages.ExportMapToImageWizard_ioexceptionErrorMessage
                                    + e.getLocalizedMessage());
                        } catch (TransformException e) {
                            errors
                                    .add("Failed to create world file.  This image can not be used as a Raster file in uDig");
                        } catch (NoninvertibleTransformException e) {
                            errors
                                    .add("Failed to create world file.  This image can not be used as a Raster file in uDig");
                        } catch (RuntimeException e) {
                            errors
                                    .add("An unexpected failure occurred: "
                                            + e.getLocalizedMessage());
                        }
                        renderedMaps.add(map);
                    }
                    mapSelectorPage.getMaps().remove(renderedMaps);
                    mapSelectorPage.updateMapList();
                }
            });
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

        if (!errors.isEmpty()) {
            ((WizardPage) getContainer().getCurrentPage())
                    .setErrorMessage(Messages.ExportMapToImageWizard_ShowErrorMessage
                            + errors.iterator().next());
            return false;
        }

        getDialogSettings().put(DIRECTORY_KEY, mapSelectorPage.getExportDir().getAbsolutePath());
        getDialogSettings().put(FORMAT_KEY, imageSettingsPage.getFormat().getName());

        return true;
    }

    private void exportMap( IMap map, IProgressMonitor monitor ) throws RenderException,
            IOException, TransformException, NoninvertibleTransformException {

        monitor.beginTask(Messages.ExportMapToImageWizard_RenderingTaskName, 10);
        String pattern = Messages.ExportMapToImageWizard_preparingTaskName;
        Object[] args = new Object[]{map.getName()};
        monitor.setTaskName(MessageFormat.format(pattern, args));
        File destination = determineDestinationFile(map);
        if (destination == null) {
            return;
        }

        int width = imageSettingsPage.getWidth(map.getViewportModel().getWidth(), map
                .getViewportModel().getHeight());
        int height = imageSettingsPage.getHeight(map.getViewportModel().getWidth(), map
                .getViewportModel().getHeight());

        // gdavis - ARGB won't output proper background color for non-alpha supporting
        // image types like jpg. Since the resulting image contains no alpha, RGB works
        // fine for all formats.
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // .TYPE_INT_ARGB);

        Graphics2D g = image.createGraphics();

        IMap renderedMap;
        try {
            monitor.worked(2);
            pattern = Messages.ExportMapToImageWizard_renderingTaskname;
            args = new Object[]{map.getName()};
            monitor.setTaskName(MessageFormat.format(pattern, args));
            int scaleDenom = MapSelectorPageWithScaleColumn.getScaleDenom(map);
            BoundsStrategy boundsStrategy = new BoundsStrategy(scaleDenom);

            DrawMapParameter drawMapParameter = new DrawMapParameter(g, new java.awt.Dimension(
                    width, height), map, boundsStrategy, imageSettingsPage.getFormat().getDPI(),
                    imageSettingsPage.getSelectionHandling(), monitor);

            renderedMap = ApplicationGIS.drawMap(drawMapParameter);
        } finally {
            g.dispose();
        }
        monitor.worked(3);
        pattern = Messages.ExportMapToImageWizard_writingTaskname;
        args = new Object[]{map.getName()};
        monitor.setTaskName(MessageFormat.format(pattern, args));
        imageSettingsPage.getFormat().write(renderedMap, image, destination);
       
        addToCatalog(destination );
       
        monitor.done();
    }

    private void addToCatalog( final File file ) throws IOException {
        if( !file.exists() ){
            throw new FileNotFoundException("Expected "+file+" was not created");
        }

        // try if the file isn't a pdf
        if ( file.getAbsolutePath().toLowerCase().endsWith("pdf") ) { //$NON-NLS-1$
            return;
        }

        Job addToCatalog = new Job("Add "+file.getName() ){
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                ICatalog localCatalog = CatalogPlugin.getDefault().getLocalCatalog();
                URL url = new ID( file, null ).toURL();
                IService service = null;
                try {
                    service = localCatalog.acquire( url, monitor );
                }
                catch( IOException unepected ){
                }
                return service != null ? Status.OK_STATUS : new Status( IStatus.ERROR, ProjectUIPlugin.ID, "Failed to add "+file );
            }
        };
        addToCatalog.schedule();
    }
    /**
     * This implementation is a bit more drastic then the usual catalog add method
     * as it will replace the existing contents if required.
     *
     * @param localCatalog
     * @param service
     */
    private void addToCatalog( ICatalog localCatalog, IService service ) {
        ID id = service.getID();
        IService found = localCatalog.getById(IService.class, id, new NullProgressMonitor());
        if (found != null) {
            // existing catalog entry to replace
            // (if this is only being done for a "refresh" we may be able to take less
            // drastic action)
            localCatalog.replace(service.getID(), service);
        } else {
            localCatalog.add(service);
        }
    }

    private File determineDestinationFile( IMap map ) {
        File exportDir = mapSelectorPage.getExportDir();
        String name = URLUtils.cleanFilename(map.getName());
        File destination = addSuffix(new File(exportDir, name));
        if (destination.exists()) {
            boolean overwrite = !MessageDialog
                    .openQuestion(getContainer().getShell(),
                            Messages.ExportMapToImageWizard_overwriteWarningTitle,
                            Messages.ExportMapToImageWizard_overwriteWarningMessage
                                    + destination.getName());

            if (!overwrite) {
                if (!destination.delete()) {
                    destination = selectFile(destination,
                            Messages.ExportMapToImageWizard_unableToDeleteMsg);
                }

            } else {
                destination = selectFile(destination,
                        Messages.ExportMapToImageWizard_selectFileTitle);
            }
        }

        if (destination == null) {
            return null;
        }

        return addSuffix(destination);
    }

    private File addSuffix( File file ) {
        String path = stripEndSlash(file.getPath());

        File destination;
        String extension = imageSettingsPage.getFormat().getExtension();
        if (!path.endsWith(extension)) {
            destination = new File(path + "." + extension); //$NON-NLS-1$
        } else {
            return file;
        }
        return destination;
    }

    private String stripEndSlash( String path ) {
        if (path.endsWith("/")) //$NON-NLS-1$
            return stripEndSlash(path.substring(0, path.length() - 1));
        return path;
    }

    private File selectFile( File destination, String string ) {
        FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
        dialog.setText(string);
        dialog.setFilterPath(destination.getParent());
        dialog.setFileName(destination.getName());
        String file = dialog.open();
        if (file == null) {
            destination = null;
        } else {
            destination = new File(file);
        }
        return destination;
    }

    @SuppressWarnings("unchecked")
    public void init( IWorkbench workbench, IStructuredSelection selection ) {
        mapSelectorPage.setSelection(selection);
    }

}
TOP

Related Classes of org.locationtech.udig.project.ui.wizard.export.image.ExportMapToImageWizard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.