All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.cloudfarming.client.geoviewer.edit.GeoEditorController Maven / Gradle / Ivy

/**
 * Copyright (C) 2011 Agrosense 
 *
 * Licensed under the Eclipse Public License - v 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.cloudfarming.client.geoviewer.edit;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import nl.cloudfarming.client.geoviewer.GeometryEditor;
import nl.cloudfarming.client.model.Surface;
import org.netbeans.api.visual.action.AcceptProvider;
import org.netbeans.api.visual.action.ActionFactory;
import org.netbeans.api.visual.action.ConnectorState;
import org.netbeans.api.visual.action.PopupMenuProvider;
import org.netbeans.api.visual.widget.Widget;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;

/**
 * controller for the surface editor view 
 * 
 * @author Timon Veenstra
 */
@ServiceProvider(service = GeometryEditor.class)
@Messages("geo_editor.action_add_point=Add point")
public class GeoEditorController implements GeometryEditor {

    private static final double FORM_FACTOR = 100000.0;
    private static final int MARGIN_X = 100;
    private static final int MARGIN_Y = 100;
    private final GeoEditorScene scene = new GeoEditorScene();
    private JComponent view = scene.createView();
    private Geometry geometry;
    private Coordinate base;

    public GeoEditorController() {
        scene.getActions().addAction(ActionFactory.createPopupMenuAction(new EditPopupProvider()));
        scene.getActions().addAction(ActionFactory.createAcceptAction(new AcceptProvider() {

            @Override
            public ConnectorState isAcceptable(Widget widget, Point point, Transferable transferable) {
                if (transferable.isDataFlavorSupported(Surface.DATA_FLAVOR)) {
                    return ConnectorState.ACCEPT;
                }
                return ConnectorState.REJECT;
            }

            @Override
            public void accept(Widget widget, Point point, Transferable transferable) {
                try {
                    //TODO Timon Veenstra 20111006 refactor to accept nodes instead of Geometry
                    Geometry s = (Geometry) transferable.getTransferData(Surface.DATA_FLAVOR);
                    if (s != null) {
                        edit(s);
                    }
                } catch (UnsupportedFlavorException ex) {
                    Exceptions.printStackTrace(ex);
                } catch (IOException ex) {
                    Exceptions.printStackTrace(ex);
                }

            }
        }));
//        scene.getActions().addAction(new SceneCreateAction());
    }

    public JComponent getView() {
        return view;
    }

    @Override
    public void edit(Geometry geometry) {
        Geometry boundingBox = geometry.getEnvelope();
//        assert boundingBox.getCoordinates().length == 2;

        this.geometry = geometry;
        base = boundingBox.getCoordinates()[0];

        GeoNode prev = null;
        GeoNode first = null;

        for (int i = 0; i < geometry.getCoordinates().length - 1; i++) {
            Coordinate c = geometry.getCoordinates()[i];
            GeoNode geoNode = new GeoNode(new Coordinate(c.x, c.y));
            Widget w = scene.addNode(geoNode);
            //translate to coordinate to a point
            Point location = coordinateToPoint(geoNode.getCoordinate());
            // replace the point based on the widget size
            location.x = location.x - (w.getPreferredSize().width/2);
            location.y = location.y - (w.getPreferredSize().height/2);
            w.setPreferredLocation(location);

            if (first == null) {
                first = geoNode;
            } else {
                scene.connectNodes(geoNode, prev);

            }
            prev = geoNode;
        }
        scene.connectNodes(prev, first);
    }

    /**
     * translates a coordinate to a point on the screen
     * 
     * @param position
     * @return 
     */
    private Point coordinateToPoint(Coordinate position) {
        assert base != null;
        assert position != null;
        double relativeX = position.x - base.x;
        double relativeY = position.y - base.y;
        int x = (int) (relativeX * FORM_FACTOR) + MARGIN_X;
        int y = (int) (relativeY * FORM_FACTOR) + MARGIN_Y;
        System.out.println("x: " + x + "y : " + y);
        return new Point(x, y);
    }

    /**
     * translates a point on the screen into a coordinate
     * 
     * @param point
     * @return 
     */
    private Coordinate pointToCoordinate(Point point) {
        assert base != null;
        assert point != null;
        double x = (double) point.x / FORM_FACTOR + base.x;
        double y = (double) point.y / FORM_FACTOR + base.y;
        System.out.println("x: " + x + "y : " + y);
        return new Coordinate(x, y);
    }

    /**
     * Provides a popup menu for the edit component
     * 
     */
    private class EditPopupProvider implements PopupMenuProvider {

        @Override
        public JPopupMenu getPopupMenu(Widget widget, final Point localLocation) {
            JPopupMenu menu = new JPopupMenu();
            menu.add(new AbstractAction(NbBundle.getMessage(this.getClass(), "geo_editor.action_add_point")) {

                @Override
                public void actionPerformed(ActionEvent e) {
                    assert SwingUtilities.isEventDispatchThread();
                    Point p = localLocation;
                    p.x = p.x - MARGIN_X;
                    p.y = p.y - MARGIN_Y;
                    GeoNode geoNode = new GeoNode(pointToCoordinate(localLocation));
                    scene.addNode(geoNode).setPreferredLocation(coordinateToPoint(geoNode.getCoordinate()));
                    scene.validate();
                }
            });
            return menu;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy