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

fr.ird.observe.client.util.tripMap.TripMapUIHandler Maven / Gradle / Ivy

package fr.ird.observe.client.util.tripMap;

/*
 * #%L
 * ObServe Toolkit :: Common Client
 * %%
 * Copyright (C) 2008 - 2017 IRD, Ultreia.io
 * %%
 * 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 3 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, see
 * .
 * #L%
 */

import com.google.common.collect.Lists;
import fr.ird.observe.client.MainUI;
import fr.ird.observe.client.ObserveClientTechnicalException;
import fr.ird.observe.client.action.ObserveActionMap;
import fr.ird.observe.client.action.tripMap.TripMapActionSupport;
import fr.ird.observe.dto.IdHelper;
import fr.ird.observe.dto.data.TripMapConfig;
import fr.ird.observe.dto.data.TripMapDto;
import fr.ird.observe.dto.data.TripMapPoint;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.File;
import java.util.List;
import java.util.Objects;
import javax.swing.AbstractButton;
import javax.swing.InputMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.swing.JMapPane;
import org.geotools.swing.event.MapPaneEvent;
import org.geotools.swing.event.MapPaneListener;
import org.nuiton.jaxx.runtime.spi.UIHandler;


import static fr.ird.observe.client.form.FormUIHandler.OBSERVE_ACTION;

/**
 * @author Tony Chemit - [email protected]
 */
public class TripMapUIHandler implements UIHandler {

    public static final double ZOOM_STEP_RATIO = 0.1;

    private static final Log log = LogFactory.getLog(TripMapUIHandler.class);

    private TripMapUI ui;
    private TripMapConfig config;
    private ReferencedEnvelope tripArea;
    private boolean rendererRunning;
    private double zoomRatio = 1;
    private Point zoomCenter;

    public void setConfig(TripMapConfig config) {
        this.config = config;

        JMapPane mapPane = getObserveMapPane();
        mapPane.setBackground(config.getMapBackgroundColor());
    }

    private ObserveMapPane getObserveMapPane() {
        return ui.getObserveMapPane();
    }

    public void doOpenMap(MainUI mainUI, TripMapDto tripMapDto) {

        try {
            flipContent();
            mainUI.setBusy(true);

            ObserveMapPane mapPane = getObserveMapPane();

            if (mapPane.getMapContent() != null) {
                // appeler pour libéré les listeners
                mapPane.getMapContent().dispose();
            }

            List tripMapPoints = Lists.newArrayList(tripMapDto.getPoints());


            TripMapContentBuilder mapContentBuilder = new TripMapContentBuilder();
            mapContentBuilder.setStyledLayerDescriptor(config.getMapStyleFile());

            for (File layerFile : config.getMapLayerFiles()) {
                mapContentBuilder.addLayer(layerFile);
            }

            if (IdHelper.isSeineId(tripMapDto.getId())) {

                mapContentBuilder.addTripLine(tripMapPoints);

            } else if (IdHelper.isLonglineId(tripMapDto.getId())) {

                mapContentBuilder.addLonglineFishingZone(tripMapPoints);
                mapContentBuilder.addLonglineLine(tripMapPoints);

            }

            mapContentBuilder.addPoints(tripMapPoints);

            // set zoom
            tripArea = new ReferencedEnvelope();
            for (TripMapPoint point : tripMapPoints) {
                tripArea.expandToInclude(new DirectPosition2D(point.getLongitude(), point.getLatitude()));
            }
            tripArea.expandBy(1.1);

            mapPane.setMapContent(mapContentBuilder.getMapContent());
            mapPane.setLegendItems(mapContentBuilder.getLegendItems());

        } catch (Exception e) {
            throw new ObserveClientTechnicalException("Unable to load trip map activity points", e);
        } finally {
            mainUI.setBusy(false);
        }

    }

    private void flipContent() {
        ui.getContentLayout().first(ui.getContent());
    }

    public void doCloseMap() {
        flipContent();
    }

    public void zoomApply() {
        if (zoomRatio != 1 && !rendererRunning) {

            JMapPane mapPane = getObserveMapPane();

            ReferencedEnvelope displayArea = mapPane.getDisplayArea();

            double deltaWidth = displayArea.getWidth() * (zoomRatio - 1);
            double deltaHeight = displayArea.getHeight() * (zoomRatio - 1);

            double ratioLeft = zoomCenter.getX() * 1d / mapPane.getWidth();

            // l'axe de Y est inversé entre le référentiel du composant swing et le référentiel géographique
            double ratioTop = 1 - (zoomCenter.getY() * 1d / mapPane.getHeight());

            double deltaLeft = deltaWidth * ratioLeft;
            double deltaRight = deltaLeft - deltaWidth;

            double deltaTop = deltaHeight * ratioTop;
            double deltaBottom = deltaTop - deltaHeight;

            if (log.isDebugEnabled()) {
                log.debug(String.format("Map mouse zoom (zoom ratio : %s, deltaLeft : %s, deltaRight : %s, deltaTop : %s, deltaBottom : %s)",
                                        zoomRatio, deltaLeft, deltaRight, deltaRight, deltaBottom));
            }

            ReferencedEnvelope newDisplayArea = new ReferencedEnvelope(
                    displayArea.getMinX() + deltaLeft,
                    displayArea.getMaxX() + deltaRight,
                    displayArea.getMinY() + deltaTop,
                    displayArea.getMaxY() + deltaBottom,
                    displayArea.getCoordinateReferenceSystem()
            );
            // -230 is the good value (don't ask me why ?)
            if (newDisplayArea.getLowerCorner().getOrdinate(0) > -230) {
                mapPane.setDisplayArea(newDisplayArea);
            }

            zoomRatio = 1;

        }

    }

    @Override
    public void beforeInit(TripMapUI ui) {
        this.ui = ui;
    }

    @Override
    public void afterInit(TripMapUI ui) {

        ObserveMapPane mapPane = getObserveMapPane();

        MouseMapListener mouseMapListener = new MouseMapListener();
        mapPane.addMouseWheelListener(mouseMapListener);
        mapPane.addMouseMotionListener(mouseMapListener);
        mapPane.addMouseListener(mouseMapListener);
        mapPane.addMapPaneListener(new TripMapListener());

        rendererRunning = false;

    }

    public void init(InputMap inputMap, ObserveActionMap actionMap) {

        init(actionMap, inputMap, ui.zoomIt);
        init(actionMap, inputMap, ui.zoomMoins);
        init(actionMap, inputMap, ui.zoomPlus);
        init(actionMap, inputMap, ui.exportPng);

    }

    public ReferencedEnvelope getTripArea() {
        return tripArea;
    }

    public double getZoomRatio() {
        return zoomRatio;
    }

    public void setZoomRatio(double zoomRatio) {
        this.zoomRatio = zoomRatio;
    }

    public void setZoomCenter(Point zoomCenter) {
        this.zoomCenter = zoomCenter;
    }

    private class MouseMapListener implements MouseWheelListener, MouseListener, MouseMotionListener {

        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            int notches = e.getWheelRotation();
            zoomRatio = zoomRatio * (1 + (ZOOM_STEP_RATIO * notches * -1));
            zoomCenter = e.getPoint();
            zoomApply();
        }

        @Override
        public void mouseClicked(MouseEvent e) {

        }

        Point2D startPointInWorld;
        AffineTransform startScreenToWorldTransform;
        ReferencedEnvelope startDisplayArea;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON1) {
                startMove(e.getPoint());
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON1) {
                endMove(e.getPoint());
            }
        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }

        @Override
        public void mouseDragged(MouseEvent e) {
//            endMove(e.getPoint());
        }

        @Override
        public void mouseMoved(MouseEvent e) {

        }

        void startMove(Point2D startPointInScreen) {
            JMapPane mapPane = getObserveMapPane();

            startDisplayArea = mapPane.getDisplayArea();

            startScreenToWorldTransform = mapPane.getScreenToWorldTransform();

            startPointInWorld = new Point2D.Double();

            startScreenToWorldTransform.transform(startPointInScreen, startPointInWorld);

        }

        void endMove(Point2D endPointInScreen) {

            Point2D endPointInWorld = new Point2D.Double();

            startScreenToWorldTransform.transform(endPointInScreen, endPointInWorld);

            double transX = startPointInWorld.getX() - endPointInWorld.getX();
            double transY = startPointInWorld.getY() - endPointInWorld.getY();

            ReferencedEnvelope endDisplayArea = new ReferencedEnvelope(startDisplayArea);

            endDisplayArea.translate(transX, transY);

            JMapPane mapPane = getObserveMapPane();

            mapPane.setDisplayArea(endDisplayArea);

            if (log.isDebugEnabled()) {
                log.debug(String.format("Translate (x : %s, y : %s)", transX, transY));
            }
        }
    }

    protected class TripMapListener implements MapPaneListener {

        boolean firstRendering;

        @Override
        public void onNewMapContent(MapPaneEvent ev) {
            firstRendering = true;
        }

        @Override
        public void onDisplayAreaChanged(MapPaneEvent ev) {
        }

        @Override
        public void onRenderingStarted(MapPaneEvent ev) {
            rendererRunning = true;
        }

        @Override
        public void onRenderingStopped(MapPaneEvent ev) {
            rendererRunning = false;
            if (firstRendering) {

                if (!tripArea.isEmpty()) {
                    JMapPane mapPane = getObserveMapPane();
                    mapPane.setDisplayArea(tripArea);
                }

                ui.getContentLayout().last(ui.getContent());
                firstRendering = false;
            } else {
                zoomApply();
            }
        }
    }

    protected void init(ObserveActionMap actionMap, InputMap inputMap, AbstractButton editor) {
        String actionId = (String) editor.getClientProperty(OBSERVE_ACTION);

        TripMapActionSupport action = (TripMapActionSupport) actionMap.get(actionId);
        Objects.requireNonNull(action, "action [" + actionId + "] not found for ui " + ui.getClass().getName());

        if (log.isDebugEnabled()) {
            log.debug("init common action " + actionId);
        }

        action.setUi(ui);
        action.initForMainUi(editor, inputMap, actionMap);

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy