Package org.locationtech.udig.printing.ui.internal.editor

Source Code of org.locationtech.udig.printing.ui.internal.editor.SetScaleAction$ScaleDialog

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004, 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.printing.ui.internal.editor;

import java.awt.Dimension;

import org.locationtech.udig.printing.model.AbstractBoxPrinter;
import org.locationtech.udig.printing.model.Page;
import org.locationtech.udig.printing.model.impl.MapBoxPrinter;
import org.locationtech.udig.printing.ui.IBoxEditAction;
import org.locationtech.udig.printing.ui.internal.editor.parts.BoxPart;
import org.locationtech.udig.project.internal.render.ViewportModel;
import org.locationtech.udig.project.internal.render.impl.ScaleUtils;
import org.locationtech.udig.project.render.IViewportModel;

import org.eclipse.gef.commands.Command;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.geotools.geometry.jts.ReferencedEnvelope;

/**
* Sets the scale on a map in the MapBox
*
* <p>
*  The scale is calculated and set taking into account
*  the real dimension of the currently used paper
*  type.
* </p>
*
* @author jesse
* @author Andrea Antonello (www.hydrologis.com)
* @since 1.1.0
*/
public class SetScaleAction implements IBoxEditAction {

    private BoxPart owner;
    Double scale;

    public Command getCommand() {
        final double newScale = scale;
        scale = null;

        final double oldScale = calculateScale();
        return new Command(){
            private void setScale( double scale ) {
                applyNewScale(scale);
            }
            @Override
            public void execute() {
                setScale(newScale);
            }

            @Override
            public void undo() {
                setScale(oldScale);
            }
        };
    }

    public void init( BoxPart owner ) {
        this.owner = owner;
    }

    private MapBoxPrinter getMapBoxPrinter() {
        return (MapBoxPrinter) owner.getBoxPrinter();
    }

    public boolean isDone() {
        return true;
    }

    public void perform() {
        scale = null;

        double scaleDenominator = calculateScale();

        Shell parentShell = Display.getCurrent().getActiveShell();
        if (scaleDenominator < .01) {
            MessageDialog
                    .openInformation(
                            parentShell,
                            "Set Scale",
                            "The map scale cannot be accurately calculated because of the map's projection.\n\nTry Changing the projection of the map");
            return;
        }

        ScaleDialog dialog = new ScaleDialog(parentShell, scaleDenominator);
        dialog.setBlockOnOpen(true);

        int result = dialog.open();

        if (result == Window.OK) {
            this.scale = dialog.getScale();
        } else {
            this.scale = scaleDenominator;
        }

    }

    /**
     * Calculates the scale of the map taking into account the paper size.
     *
     * @return the scale of the map on the current paper type.
     */
    private double calculateScale() {
        IViewportModel viewportModel = getMapBoxPrinter().getMap().getViewportModel();
        // get page size in pixels and in mm
        Page page = getMapBoxPrinter().getBox().getPage();
        org.eclipse.draw2d.geometry.Dimension pageSize = page.getSize();
        org.eclipse.draw2d.geometry.Dimension paperSize = page.getPaperSize();
        // map box size in pixels
        org.eclipse.draw2d.geometry.Dimension mapSize = owner.getBoxPrinter().getBox().getSize();
        // map box size in points and then in meters on paper
        float mapPaperWidthPoints = (float) paperSize.width * (float) mapSize.width
                / (float) pageSize.width;
        float mapPaperWidthMeters = AbstractBoxPrinter.point2cm(mapPaperWidthPoints) / 100f;
        // map bounds in meters
        ReferencedEnvelope mapEnvelope = (ReferencedEnvelope) viewportModel.getBounds();
        double mapWorldWidthMeters = mapEnvelope.getWidth();

        double thescale = mapWorldWidthMeters / mapPaperWidthMeters;
        return thescale;
    }

    /**
     * Applies the supplied scale on the map on the current type of paper.
     *
     * @param scale the scale to apply to the map.
     */
    private void applyNewScale( double scale ) {
        ViewportModel viewportModel = getMapBoxPrinter().getMap().getViewportModelInternal();
        // get page size in pixels and in mm
        Page page = getMapBoxPrinter().getBox().getPage();
        org.eclipse.draw2d.geometry.Dimension pageSize = page.getSize();
        org.eclipse.draw2d.geometry.Dimension paperSize = page.getPaperSize();
        // map box size in pixels
        org.eclipse.draw2d.geometry.Dimension mapSize = owner.getBoxPrinter().getBox().getSize();
        // map box size in points and then in meters on paper
        float mapPaperWidthPoints = (float) paperSize.width * (float) mapSize.width
                / (float) pageSize.width;
        float mapPaperWidthMeters = AbstractBoxPrinter.point2cm(mapPaperWidthPoints) / 100f;
        float mapPaperHeightPoints = (float) paperSize.height * (float) mapSize.height
                / (float) pageSize.height;
        float mapPaperHeightMeters = AbstractBoxPrinter.point2cm(mapPaperHeightPoints) / 100f;

        double mapWorldWidthMeters = scale * mapPaperWidthMeters;
        double mapWorldHeightMeters = scale * mapPaperHeightMeters;

        // current map bounds in meters
        ReferencedEnvelope mapEnvelope = (ReferencedEnvelope) viewportModel.getBounds();
        double centerX = (mapEnvelope.getMaxX() + mapEnvelope.getMinX()) / 2.0;
        double centerY = (mapEnvelope.getMaxY() + mapEnvelope.getMinY()) / 2.0;

        double minX = centerX - mapWorldWidthMeters / 2.0;
        double maxX = centerX + mapWorldWidthMeters / 2.0;
        double minY = centerY - mapWorldHeightMeters / 2.0;
        double maxY = centerY + mapWorldHeightMeters / 2.0;

        viewportModel.setBounds(minX, maxX, minY, maxY);
    }

    private Dimension getDisplaySize() {
        org.eclipse.draw2d.geometry.Dimension gefDim = owner.getBoxPrinter().getBox().getSize();
        Dimension size = new Dimension(gefDim.width, gefDim.height);
        return size;
    }

    /**
     * A dialog with a Spinner for setting the scale of a map.
     *
     * @author jesse
     * @since 1.1.0
     */
    private static class ScaleDialog extends Dialog implements Listener {

        private Spinner spinner;
        private double scale;

        protected ScaleDialog( Shell parentShell, double scale ) {
            super(parentShell);
            this.scale = scale;
            setShellStyle(SWT.CLOSE | SWT.TITLE);
        }

        @Override
        protected Point getInitialSize() {
            Point tmp = super.getInitialSize();
            return new Point(200, tmp.y);
        }

        @Override
        protected Control createContents( Composite parent ) {
            getShell().setText("Set Scale");

            Composite container = new Composite(parent, SWT.NONE);
            container.setLayoutData(new GridData(GridData.FILL_BOTH));
            container.setLayout(new FillLayout());

            spinner = new Spinner(container, SWT.BORDER);
            spinner.setMinimum(1);
            spinner.setMaximum(Integer.MAX_VALUE);
            spinner.setIncrement(1000);
            spinner.setPageIncrement(1000000);
            spinner.setSelection((int) scale);

            spinner.addListener(SWT.Modify, this);
            spinner.addListener(SWT.KeyUp, this);
            return container;
        }

        public void handleEvent( Event event ) {
            if (event.type == SWT.Modify) {
                this.scale = spinner.getSelection();
            } else if (event.type == SWT.KeyUp) {
                if (event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR
                        || event.keyCode == SWT.LF) {
                    okPressed();
                }
            }
        }

        public double getScale() {
            return scale;
        }

    }

}
TOP

Related Classes of org.locationtech.udig.printing.ui.internal.editor.SetScaleAction$ScaleDialog

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.