Package es.emergya.ui.gis

Source Code of es.emergya.ui.gis.CustomMapView$InitAdapter

/*
* Copyright (C) 2010, Emergya (http://www.emergya.es)
*
* @author <a href="mailto:jlrodriguez@emergya.es">Juan Luís Rodríguez</a>
* @author <a href="mailto:marias@emergya.es">María Arias</a>
* @author <a href="mailto:fario@emergya.es">Félix del Río Beningno</a>
*
* This file is part of GoFleet
*
* This software 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 2 of the License, or
* (at your option) any later version.
*
* This software 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*
* As a special exception, if you link this library with other files to
* produce an executable, this library does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* This exception does not however invalidate any other reasons why the
* executable file might be covered by the GNU General Public License.
*/
/*
* 01/07/2009
*/
package es.emergya.ui.gis;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.LinkedList;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JToggleButton;
import javax.swing.SwingWorker;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gofleet.context.GoWired;
import org.gofleet.internacionalization.I18n;
import org.openstreetmap.gui.jmapviewer.JobDispatcher;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.gpx.WayPoint;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.gui.MainMenu;
import org.openstreetmap.josm.gui.MapMover;
import org.openstreetmap.josm.gui.MapView;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;

import es.emergya.actions.Authentication;
import es.emergya.actions.UsuarioAdmin;
import es.emergya.bbdd.bean.HistoricoGPS;
import es.emergya.bbdd.bean.Incidencia;
import es.emergya.bbdd.bean.Recurso;
import es.emergya.bbdd.bean.Usuario;
import es.emergya.cliente.constants.LogicConstants;
import es.emergya.consultas.IncidenciaConsultas;
import es.emergya.consultas.RecursoConsultas;
import es.emergya.consultas.UsuarioConsultas;
import es.emergya.ui.gis.layers.MapViewerLayer;
import es.emergya.ui.gis.markers.CustomMarker;
import es.emergya.ui.gis.markers.CustomMarker.Type;
import es.emergya.ui.gis.paintingThreads.Updatable;
import es.emergya.ui.plugins.LayerSelectionDialog;
import es.emergya.ui.plugins.ZoomPerformed;

/**
* Extends the functionality of {@link MapView} Allowing access to some private
* or protected methods, limiting the zoom scale to osm zoom factor equivalents
* and enabling rotation operation
*
* @author fario
*/
public class CustomMapView extends MapView implements RotatableView,
    MapMoveListener, ZoomPerformed, Contextful, ICustomMapView {

  // Constantes de utilidad
  private static final double PI2 = Math.PI * 2;
  private static final double PI_MEDIO = Math.PI / 2;
  /** Distancia (EastNorthing) minimo a partir del cual se seguira un marcador */
  private static final double FOLLOW_THRESSHOLD = Double
      .parseDouble(LogicConstants.get("FOLLOW_THRESSHOLD")); // in
  // eastnorthing
  // units
  private static final Log log = LogFactory.getLog(CustomMapView.class);
  public double fps = 2; // solo util para la obu
  private static final long serialVersionUID = 734833313834536432L;
  /** factor de zoom de mapnik */
  protected int zoomFactor;
  /** limites de zoom la capa raster base */
  protected int minZoom = LogicConstants.getInt("MIN_TILE_ZOOM"),
      maxZoom = LogicConstants.getInt("MAX_TILE_ZOOM"); // por defecto,
  // luego se les
  // da
  // valores
  /** Giro actual */
  protected double angle;
  protected double sin, cos = 1; // es util tenerlos a mano, Math.sin/cos son
  // lentos
  /**
   * Este marcador estara siempre en el centro del mapa y si se mueve el mapa
   * lo seguira
   */
  protected Marker follow;
  /**
   * Hacer zoom a una distancia apropiada para que
   * {@link CustomMapView#follow} se vea
   */
  protected boolean autoZoom = true;
  /** Girar en la direccion en la que {@link CustomMapView#follow} se mueve */
  protected boolean autoTurn = true;
  /** Suavizar el giro si autoTurn esta activado */
  protected boolean smoothTurn = true;
  /** Ultima posicion de {@link CustomMapView#follow} */
  private EastNorth lastFollowPos; // se usa para ver en que direccion se
  // mueve
  /** Ultima direccion en la que se movia {@link CustomMapView#follow} */
  private double lastFollowAngle = 0; // se usa para hacer smoothTurn
  /** La distancia que se movio {@link CustomMapView#follow} la ultima vez */
  private double lastDistance = 0; // se usa para hacer autoZoom
  protected Updater positionUpdater;
  protected JPanel layerControlPanel; // controles para mostrar/ocultar capas
  protected LayerSelectionDialog layerDialog;
  // protected JPanel controlPanel; // Diversos controles
  // protected ZoomControlPanel zoom; // controles para hacer zoom
  // contiene los botones de layerControlPanel, para poder ocultarlos o
  // mostrarlos
  protected JPanel zoom;
  protected List<JToggleButton> layerControls;
  protected ActionListener layerControlListener = new LayerControl();
  // lista de callbacks para movimiento y zoom (se necesitan para implementar
  // los listeners
  protected List<MapMoveListener.MapMovedCallback> movedCallbacks = new ArrayList<MapMovedCallback>();
  protected List<ZoomPerformed.ZoomCallback> zoomedCallbacks = new ArrayList<ZoomCallback>();
  protected JPopupMenu contextMenu;
  // metodos de utilidad de josm
  /**
   * Use this to register shortcuts to
   */
  public final JPanel contentPane = new JPanel(new BorderLayout());
  /**
   * The MOTD Layer.
   */
  // private GettingStarted gettingStarted = new GettingStarted();
  /**
   * The main menu bar at top of screen.
   */
  public final MainMenu menu;

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getMenu()
   */
  @Override
  public MainMenu getMenu() {
    return menu;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getContentPane()
   */
  @Override
  public JPanel getContentPane() {
    return contentPane;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getPanel()
   */
  @Override
  public JPanel getPanel() {
    return panel;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setPanel(javax.swing.JPanel)
   */
  @Override
  public void setPanel(JPanel panel) {
    this.panel = panel;
  }

  public JPanel panel = new JPanel(new BorderLayout());
  /**
   * The toolbar preference control to register new actions.
   */
  public ToolbarPreferences toolbar;

  @GoWired
  public I18n i18n;

  /**
   * @return the i18n
   */
  public I18n getI18n() {
    return i18n;
  }

  /**
   * @param i18n the i18n to set
   */
  public void setI18n(I18n i18n) {
    this.i18n = i18n;
  }

  public CustomMapView() {
    super();
    menu = new MainMenu();
    contentPane.add(panel, BorderLayout.CENTER);

    // iniciar los controles mostrar/ocultar capas
    layerControls = new LinkedList<JToggleButton>();

    JToggleButton botonMostrarOcultarBotones = new JToggleButton(
        getI18n().getString("map.layers.hideButtons"),
        LogicConstants.getIcon("capas_button_mostrar"), false);
    botonMostrarOcultarBotones.setSelected(true);
    botonMostrarOcultarBotones.setActionCommand("#hide");
    // b.setVerticalTextPosition(SwingConstants.BOTTOM);
    // b.setHorizontalTextPosition(SwingConstants.CENTER);
    botonMostrarOcultarBotones.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        JToggleButton b = (JToggleButton) e.getSource();
        if (e.getActionCommand().equals("#hide")) {
          layerControlPanel.removeAll();
          layerControlPanel.add(Box.createHorizontalStrut(10));
          layerControlPanel.add(b);
          b.setActionCommand("#show");
          b.setText(getI18n().getString("map.layers.showButtons"));
        } else {
          layerControlPanel.removeAll();
          layerControlPanel.add(Box.createHorizontalStrut(10));
          for (JToggleButton bt : layerControls) {
            layerControlPanel.add(bt);
            layerControlPanel.add(Box.createHorizontalGlue());
          }
          b.setActionCommand("#hide");
          b.setText(getI18n().getString("map.layers.hideButtons"));
        }
        layerControlPanel.updateUI();
      }
    });
    layerControls.add(botonMostrarOcultarBotones);

    final JToggleButton botonTodoasLasCapas = new JToggleButton(
        getI18n().getString("map.layers.allLayers"),
        LogicConstants.getIcon("capas_button_mostrar"), false);
    layerDialog = new LayerSelectionDialog(this);
    layerDialog.addWindowListener(new WindowAdapter() {

      @Override
      public void windowClosing(WindowEvent e) {
        botonTodoasLasCapas.setSelected(false);
      }
    });
    botonTodoasLasCapas.setSelected(false);
    botonTodoasLasCapas.setActionCommand("#all");
    // all.setVerticalTextPosition(SwingConstants.BOTTOM);
    // all.setHorizontalTextPosition(SwingConstants.CENTER);
    botonTodoasLasCapas.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        layerDialog.setLocationRelativeTo((Component) e.getSource());
        layerDialog.setVisible(!layerDialog.isShowing());
      }
    });
    layerControls.add(botonTodoasLasCapas);

    layerControlPanel = new JPanel();
    layerControlPanel.setLayout(new BoxLayout(layerControlPanel,
        BoxLayout.X_AXIS));

    Main.main.menu = this.menu;
    toolbar = new ToolbarPreferences();
    toolbar.refreshToolbarControl();
    // toolbar.control.updateUI();
    // contentPane.add(toolbar.control, BorderLayout.NORTH);

    contentPane.updateUI();
    panel.updateUI();
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#addLayer(org.openstreetmap.josm.gui.
   * layer.Layer, boolean)
   */
  @Override
  public void addLayer(Layer layer, boolean showOnButtonList) {
    addLayer(layer, showOnButtonList, 0);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#addLayer(org.openstreetmap.josm.gui.
   * layer.Layer, boolean, int)
   */
  @Override
  public void addLayer(Layer layer, boolean showOnButtonList, int pos) {
    if (layer instanceof MapViewerLayer) {
      minZoom = Math.max(((MapViewerLayer) layer).getMinZoomLevel(),
          getMinZoom());
      maxZoom = Math.min(((MapViewerLayer) layer).getMaxZoomLevel(),
          getMaxZoom());
      if (zoomFactor > maxZoom || zoomFactor < minZoom) {
        zoomFactor = (maxZoom + minZoom) / 2;
      }
      zoomTo(center, zoom2Scale(zoomFactor));
    }
    if (showOnButtonList) {
      JToggleButton b = new JToggleButton(layer.name,
          LogicConstants.getIcon("capas_button_"
              + layer.name.toLowerCase()), layer.visible);
      // b.setVerticalTextPosition(SwingConstants.BOTTOM);
      // b.setHorizontalTextPosition(SwingConstants.CENTER);
      b.setActionCommand(layer.name);
      b.addActionListener(layerControlListener);
      layerControls.add(b);
      layerControlPanel.removeAll();
      layerControlPanel.add(Box.createHorizontalStrut(10));
      for (JToggleButton bt : layerControls) {
        layerControlPanel.add(bt);
        layerControlPanel.add(Box.createHorizontalGlue());
      }
      layerControlPanel.updateUI();
    }

    super.addLayer(layer, pos);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#addLayer(org.openstreetmap.josm.gui.
   * layer.Layer, boolean, java.lang.String)
   */
  @Override
  public void addLayer(Layer layer, boolean showOnButtonList, String icon) {
    if (layer instanceof MapViewerLayer) {
      minZoom = Math.max(((MapViewerLayer) layer).getMinZoomLevel(),
          getMinZoom());
      maxZoom = Math.min(((MapViewerLayer) layer).getMaxZoomLevel(),
          getMaxZoom());
      if (zoomFactor > maxZoom || zoomFactor < minZoom) {
        zoomFactor = (maxZoom + minZoom) / 2;
      }
      zoomTo(center, zoom2Scale(zoomFactor));
    }
    if (showOnButtonList) {
      JToggleButton b = new JToggleButton(layer.name,
          LogicConstants.getIcon(icon), layer.visible);
      // b.setVerticalTextPosition(SwingConstants.BOTTOM);
      // b.setHorizontalTextPosition(SwingConstants.CENTER);
      b.setActionCommand(layer.name);
      b.addActionListener(layerControlListener);
      layerControls.add(b);
      layerControlPanel.removeAll();
      layerControlPanel.add(Box.createHorizontalStrut(10));
      for (JToggleButton bt : layerControls) {
        layerControlPanel.add(bt);
        layerControlPanel.add(Box.createHorizontalGlue());
      }
      layerControlPanel.updateUI();
    }

    super.addLayer(layer);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#addLayer(org.openstreetmap.josm.gui.
   * layer.Layer)
   */
  @Override
  public void addLayer(Layer layer) {
    addLayer(layer, true);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#setActiveLayer(org.openstreetmap.josm
   * .gui.layer.Layer)
   */
  @Override
  public void setActiveLayer(Layer layer) { // modificado para que no pete
    if (!getAllLayers().contains(layer)) {
      throw new IllegalArgumentException("Layer must be in layerlist");
    }
    if (layer instanceof OsmDataLayer) {
      editLayer = (OsmDataLayer) layer;
      Main.ds = editLayer.data;
    } else {
      Main.ds.setSelected();
    }
    DataSet.fireSelectionChanged(Main.ds.getSelected());
    Layer old = getActiveLayer();
    setActiveLayerReflect(layer);

    if (old != layer) {
      for (Layer.LayerChangeListener l : Layer.listeners) {
        l.activeLayerChange(old, layer);
      }
    }

    repaint();
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#zoomToEditLayerBoundingBox()
   */
  @Override
  public boolean zoomToEditLayerBoundingBox() {
    return false;
  }

  /**
   * Tries to bypass private field declaration for activeLayer field
   *
   * @param layer
   */
  private void setActiveLayerReflect(Layer layer) {
    activeLayer = layer;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#zoomTo(org.openstreetmap.josm.data.coor
   * .EastNorth, double)
   */
  @Override
  public void zoomTo(EastNorth newCenter, double scale) {
    int factor = zoomFactor;
    if (this.scale > scale) {
      if (zoomFactor == getMaxZoom()) {
        return;
      }
      factor = Math.min(zoomFactor + 1, getMaxZoom());
    } else if (this.scale < scale) {
      if (zoomFactor == getMinZoom()) {
        return;
      }
      factor = Math.max(zoomFactor - 1, getMinZoom());
    }
    zoomToFactor(newCenter, factor);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setAutoZoom(boolean)
   */
  @Override
  public void setAutoZoom(boolean autoZoom) {
    this.autoZoom = autoZoom;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setAutoTurn(boolean)
   */
  @Override
  public void setAutoTurn(boolean autoTurn) {
    this.autoTurn = autoTurn;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setSmoothTurn(boolean)
   */
  @Override
  public void setSmoothTurn(boolean smoothTurn) {
    this.smoothTurn = smoothTurn;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#setContextMenu(javax.swing.JPopupMenu)
   */
  @Override
  public void setContextMenu(JPopupMenu contextMenu) {
    this.contextMenu = contextMenu;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#showMenu(java.awt.Component, int,
   * int)
   */
  @Override
  public void showMenu(Component parent, int x, int y) {
    if (this.contextMenu != null) { // si hay contextmenu
      this.contextMenu.show(parent, x, y);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#zoomPerformed()
   */
  @Override
  public void zoomPerformed() {
    JobDispatcher.getInstance().cancelOutstandingJobs();
    updateMarkers();
    for (ZoomCallback zc : zoomedCallbacks) {
      zc.action();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#addCallback(es.emergya.ui.plugins.
   * ZoomPerformed.ZoomCallback)
   */
  @Override
  public void addCallback(ZoomCallback zcb) {
    if (!zoomedCallbacks.contains(zcb)) {
      zoomedCallbacks.add(zcb);
    }
  }

  // @Override
  // public void clearCallbacks() { zoomedCallbacks.clear(); }
  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#removeCallback(es.emergya.ui.plugins
   * .ZoomPerformed.ZoomCallback)
   */
  @Override
  public boolean removeCallback(ZoomCallback zcb) {
    return zoomedCallbacks.remove(zcb);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#zoomToFactor(org.openstreetmap.josm.
   * data.coor.EastNorth, int)
   */
  @Override
  public void zoomToFactor(EastNorth newCenter, int zoomFactor) {
    if (zoomFactor < getMinZoom() || zoomFactor > getMaxZoom()) {
      return;
    }
    this.zoomFactor = zoomFactor;
    super.zoomTo(newCenter, zoom2Scale(zoomFactor));
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#zoomToFactor(org.openstreetmap.josm.
   * data.coor.EastNorth, int, double)
   */
  @Override
  public void zoomToFactor(EastNorth newCenter, int zoomFactor, double angle) {
    this.angle = normalizeAngle(angle);
    this.sin = Math.sin(angle);
    this.cos = Math.cos(angle);
    this.zoomToFactor(newCenter, zoomFactor);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#zoomTo(org.openstreetmap.josm.data.coor
   * .EastNorth, double, double)
   */
  @Override
  public void zoomTo(EastNorth newCenter, double scale, double angle) {
    this.angle = normalizeAngle(angle);
    this.sin = Math.sin(angle);
    this.cos = Math.cos(angle);
    this.zoomTo(newCenter, scale);
  }

  /**
   * @param angle
   * @return el equivalente a angle entre 0 y 2*PI
   */
  private double normalizeAngle(double angle) {
    while (angle > PI2) {
      angle -= PI2;
    }
    while (angle < -PI2) {
      angle += PI2;
    }
    return angle;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#paint(java.awt.Graphics)
   */
  @Override
  public void paint(Graphics g) {
    Main.mapView = this;
    if (follow != null) {
      follow();
    }
    try {
      super.paint(g); // Esto ya llama a paintComponents
    } catch (ConcurrentModificationException ex) {
      log.warn("Redibujando, datos aun no cargados...");
      return;
    }

    // ============= DEBUG DEBAJO DE ESTA LINEA ================

    // g.drawString(
    // "zoom: " + zoomFactor + ", angle:" + Math.toDegrees(angle),
    // 300, 15);
    // g.drawString((Runtime.getRuntime().freeMemory() / (1024 * 1024))
    // + "M / " + (Runtime.getRuntime().totalMemory() / (1024 * 1024))
    // + "M", 20, getHeight() - 5);

    // Rectangle r = getBoundingBox();
    // // g.drawRect(r.x + 200, r.y + 200, r.width - 400, r.height - 400);
    // LatLon tl, br;
    // tl = getLatLon(r.x, r.y);
    // br = getLatLon(r.x + r.width, r.y + r.height);
    // UTM u = new UTM();
    // // EastNorth etl = u.latlon2eastNorth(tl);
    // // EastNorth ebr = u.latlon2eastNorth(br);
    // EastNorth etl = Main.proj.latlon2eastNorth(tl);
    // EastNorth ebr = Main.proj.latlon2eastNorth(br);
    // Point pmi, pma;
    // pmi = getPoint(etl);
    // pma = getPoint(ebr);
    // Rectangle draw = new Rectangle(pmi.x, pma.y, pma.x - pmi.x, pma.y -
    // pmi.y);
    // g.setColor(Color.GREEN);
    // g.drawRect(draw.x + 201, draw.y + 201, draw.width - 402, draw.height
    // - 402);
    // g.drawString("+  " + draw, getWidth() / 2, 300);

    // g.setColor(Color.RED);
    // g.drawRect(200, 200, getWidth() - 400, getHeight() - 400);

    // g.setColor(Color.RED);
    // Point p = getPoint(Main.proj.latlon2eastNorth(getLatLon(getWidth() /
    // 2,
    // getHeight() / 2 - 200)));
    // g.fillOval(p.x - 10, p.y - 10, 20, 20);
    // g.setColor(Color.BLACK);
    // g.fillRect(getWidth() / 2 - 5, getHeight() / 2 - 5, 10, 10);

    // EastNorth mi = getEastNorth(0, getHeight() - 1);
    // EastNorth ma = getEastNorth(getWidth() - 1, 0);
    // Point pmi, pma;
    // pmi = getPoint(mi);
    // pma = getPoint(ma);
    // Rectangle r = new Rectangle(pmi.x, pma.y, pma.x - pmi.x, pmi.y -
    // pma.y);
    // g.drawString("+  " + r, getWidth() / 2, 300);
    // g.drawRect(r.x + 200, r.y + 200, r.width - 400, r.height - 400);
    // LatLon ll = getLatLon(getWidth()/2, getHeight()/2);
    // g.drawString("+  " + ll.lat() + " x " + ll.lon(), getWidth()/2,
    // getHeight()/2);
    // drawCompass(g);

  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#updateMousePosition()
   */
  @Override
  public void updateMousePosition() {
  }

  private Thread turner; // se usa para el giro suave

  /**
   * Si algun {@link Marker} esta en {@link CustomMapView#follow} lo sigue,
   * gira y hace zoom si corresponde.
   */
  protected void follow() {
    if (lastFollowPos == null) {
      lastFollowPos = follow.eastNorth;
    } else {
      // distancias
      double dy = follow.eastNorth.getY() - lastFollowPos.getY();
      double dx = follow.eastNorth.getX() - lastFollowPos.getX();
      // si se ha movido lo bastante...
      if (Math.abs(dx) > FOLLOW_THRESSHOLD
          || Math.abs(dy) > FOLLOW_THRESSHOLD) {
        if (autoTurn) {
          double na = Math.atan2(dy, dx);
          na -= lastFollowAngle;
          // Normalize the angle
          if (na < -Math.PI) {
            na += PI2;
          }
          if (na > Math.PI) {
            na -= PI2;
          }

          if (smoothTurn) {
            final double target = na; // para usarlo enel thread
            if (turner != null && turner.isAlive()) // paramos el
            // thread si
            // vamos a girar
            // otra vez
            {
              turner.interrupt();
            }
            turner = new Thread(new Runnable() {

              public void run() {
                double na = target;
                while (Math.abs(na) > 0) { // vamos girando 0.5
                  // de lo que
                  // queremos
                  na /= 2;
                  lastFollowAngle += na;
                  zoomToFactor(center, zoomFactor, PI_MEDIO
                      - lastFollowAngle);
                  try {
                    Thread.sleep(60);
                  } catch (InterruptedException e) {
                  }
                }
              }
            });
            turner.start();
          } else {
            lastFollowAngle += na; // giro brusco
          }

          // Normalize the angle
          if (lastFollowAngle < 0) {
            lastFollowAngle += PI2;
          }
          if (lastFollowAngle > PI2) {
            lastFollowAngle -= PI2;
          }
        } else {
          lastFollowAngle = -getAngle() + PI_MEDIO; // deshacemos el
          // giro si no se
          // gira
        }
        if (autoZoom) {
          // Adjusts the current zoom factor to match an appropiate
          // zoom
          // level for the speed of the followed object
          double dist = (lastDistance + Main.proj.eastNorth2latlon(
              follow.eastNorth).greatCircleDistance(
              Main.proj.eastNorth2latlon(lastFollowPos))) / 2;
          LatLon ll1 = getLatLon(0, 0);
          LatLon ll2 = getLatLon((int) (40 / fps), 0);
          double sampledist = ll1.greatCircleDistance(ll2); // get a
          // sample distance of 20px on the screen
          if (dist > sampledist * 1.5) { // if we move more than +-50%
            // of 20px -> zoom out
            zoomFactor = Math.max(zoomFactor - 1, getMinZoom());
            ;
          } else if (dist < sampledist * 0.5) { // if we move less
            // than +-50% of
            // 20px -> zoom in
            zoomFactor = Math.min(zoomFactor + 1, getMaxZoom());
            ;
          }
          lastDistance = dist;
        }

        zoomToFactor(follow.eastNorth, zoomFactor, PI_MEDIO
            - lastFollowAngle);

        lastFollowPos = new EastNorth(follow.eastNorth.east(),
            follow.eastNorth.north());

        // zoomTo(follow.eastNorth, getScale(), PI_MEDIO -
        // lastFollowAngle);
      }
    }
  }

  /**
   * Dibuja una brujula apuntando al norte
   *
   * @param g
   */
  @SuppressWarnings("unused")
  private void drawCompass(Graphics g) {
    int x = 50, y = getHeight() - 50;
    // ((Graphics2D)g).rotate(Math.PI + lastFollowAngle, x, y);
    ((Graphics2D) g).rotate(-PI_MEDIO - getAngle(), x, y);
    g.setColor(Color.LIGHT_GRAY);
    g.fillOval(0, getHeight() - 100, 100, 100);
    g.setColor(Color.BLACK);
    g.fillRect(x - 3, y - 3, 50, 6);
    g.setColor(Color.RED);
    g.fillRect(x + 42, y - 3, 6, 6);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#zoom()
   */
  @Override
  public int zoom() {
    return zoomFactor;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#zoom2Scale(int)
   */
  @Override
  public double zoom2Scale(int zoom) {
    return Math.max(world.east() / OsmMercator.falseEasting(zoom),
        world.north() / OsmMercator.falseNorthing(zoom));
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getMinZoom()
   */
  @Override
  public int getMinZoom() {
    return minZoom;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getMaxZoom()
   */
  @Override
  public int getMaxZoom() {
    return maxZoom;
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setInitAdapter(es.emergya.ui.gis.
   * CustomMapView.InitAdapter)
   */
  public void setInitAdapter(InitAdapter initAdapter) {
    for (ComponentListener l : this.getComponentListeners()) {
      this.removeComponentListener(l);
    }
    this.addComponentListener(initAdapter);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#setDefaultInitAdapter()
   */
  @Override
  public void setDefaultInitAdapter() {
    setInitAdapter(new InitAdapter());
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#rotate(double)
   */
  @Override
  public void rotate(double r) {
    angle += r;
    if (r > Math.PI * 2) {
      angle -= Math.PI * 2;
    }
    if (r < -Math.PI * 2) {
      angle += Math.PI * 2;
    }
    sin = Math.sin(getAngle());
    cos = Math.cos(getAngle());
    repaint();
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getAngle()
   */
  @Override
  public double getAngle() {
    return angle;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#setFollow(org.openstreetmap.josm.gui
   * .layer.markerlayer.Marker)
   */
  @Override
  public void setFollow(Marker m) {
    this.follow = m;
    this.lastFollowPos = m.eastNorth;
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * es.emergya.ui.gis.ICustomMapView#getPoint(org.openstreetmap.josm.data
   * .coor.EastNorth)
   */
  @Override
  public Point getPoint(EastNorth p) {
    Point pt = super.getPoint(p);
    return translateR(pt.x, pt.y);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getEastNorth(int, int)
   */
  @Override
  public EastNorth getEastNorth(int x, int y) {
    Point p = translate(x, y);
    return super.getEastNorth(p.x, p.y);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getLatLon(int, int)
   */
  @Override
  public LatLon getLatLon(int x, int y) {
    Point p = translate(x, y);
    return super.getLatLon(p.x, p.y);
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#getBoundingBox()
   */
  @Override
  public Rectangle getBoundingBox() {
    int minx = 0;
    int miny = 0;
    int maxx = getWidth();
    int maxy = getHeight();
    Point p0 = translateR(minx, miny);// tl
    Point p1 = translateR(minx, maxy);// bl
    Point p2 = translateR(maxx, maxy);// br
    Point p3 = translateR(maxx, miny);// tr

    int[] x = { p0.x, p1.x, p2.x, p3.x };
    Arrays.sort(x);

    int[] y = { p0.y, p1.y, p2.y, p3.y };
    Arrays.sort(y);

    return new Rectangle(x[0], y[0], x[x.length - 1] - x[0],
        y[y.length - 1] - y[0]);
  }

  /**
   * Returns the position of the point rotated the current rotation from the
   * center
   */
  private Point translate(Point p) {
    return translate(p.x, p.y);
  }

  /**
   * Returns the position of the point rotated the oposite to the current
   * rotation from the center
   */
  private Point translateR(int x, int y) {
    double x0 = getWidth() / 2;
    double y0 = getHeight() / 2;
    double nx = x0 + cos * (x - x0) + sin * (y - y0);
    double ny = y0 - sin * (x - x0) + cos * (y - y0);
    return new Point((int) nx, (int) ny);
  }

  /**
   * Returns the position of the point rotated the current rotation from the
   * center
   */
  private Point translate(int x, int y) {
    int x0 = getWidth() >> 1;
    int y0 = getHeight() >> 1;
    double nx = x0 + cos * (x - x0) - sin * (y - y0);
    double ny = y0 + sin * (x - x0) + cos * (y - y0);
    return new Point((int) nx, (int) ny);
  }

  public class InitAdapter extends ComponentAdapter {

    @Override
    public void componentResized(ComponentEvent e) {
      removeComponentListener(this);

      setMouseListeners();

      initControlPanels();

      setResizeListeners();

      // startPositionUpdater();

      zoomPerformed();
    }

    protected void setMouseListeners() {
      MapMover m = new MapMover(CustomMapView.this,
          CustomMapView.this.contentPane);
      m.setPanButton(MouseEvent.BUTTON1);
    }

    protected void startPositionUpdater() {
      positionUpdater = new Updater();
      new Thread(positionUpdater).start();
    }

    protected void setResizeListeners() {
      CustomMapView.this.addComponentListener(new ComponentAdapter() {

        @Override
        public void componentResized(ComponentEvent e) {
          super.componentResized(e);
          int h = e.getComponent().getHeight();
          int w = e.getComponent().getWidth();
          layerControlPanel.setBounds(0, h - 100, w, 100);
          // controlPanel.setBounds(0, 0, w,
          // controlPanel.getHeight());
          zoom.setBounds(zoom.getX(), zoom.getY(), zoom.getWidth(),
              zoom.getHeight());
          layerControlPanel.updateUI();
          zoom.updateUI();
        }
      });
    }

    protected void initControlPanels() {
      // zoom = new ZoomControlPanel(CustomMapView.this);
      // add(zoom);
      // zoom.setBounds(0, 0, getWidth(), 100);
      zoom = new JPanel(new BorderLayout());
      zoom.setOpaque(false);
      zoom.setLayout(new BoxLayout(zoom, BoxLayout.Y_AXIS));
      JButton in = new JButton(
          LogicConstants.getIcon("map_button_zoommas"));
      in.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
          zoomToFactor(getCenter(), zoom() + 1);
        }
      });
      zoom.add(in, BorderLayout.NORTH);
      JPanel foo = new JPanel();
      foo.setOpaque(false);
      foo.add(new ZoomMapSlider(CustomMapView.this));
      zoom.add(foo, BorderLayout.CENTER);
      JButton out = new JButton(
          LogicConstants.getIcon("map_button_zoommenos"));
      out.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
          zoomToFactor(getCenter(), zoom() - 1);
        }
      });
      zoom.add(out, BorderLayout.SOUTH);
      add(zoom);
      zoom.setBounds(0, 10, 70, 270);

      // controlPanel = new ControlPanel(CustomMapView.this);
      //
      // add(controlPanel);
      // controlPanel.setBounds(0, 0, getWidth(), 40);

      layerDialog.init();

      layerControlPanel.setOpaque(false);
      layerControlPanel.removeAll();
      layerControlPanel.add(Box.createHorizontalStrut(10));
      for (JToggleButton bt : layerControls) {
        layerControlPanel.add(bt);
        layerControlPanel.add(Box.createHorizontalGlue());
      }
      add(layerControlPanel);
      layerControlPanel.setBounds(0, getHeight() - 100, getWidth(), 100);
    }
  }

  /**
   * Cambia la visibilidad de los botones de
   * {@link CustomMapView#layerControlPanel}
   *
   * @author fario
   *
   */
  private class LayerControl implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
      try {
        boolean status = false;
        final String nombreCapa = e.getActionCommand();
        for (Layer l : getAllLayers()) {
          if (l.name.indexOf(nombreCapa) == 0) {
            l.visible = !l.visible;
            status = l.visible;
            updateMarkers();
          }
        }

        // vehiculos_visibles
        // personas_visibles
        // incidencias_visibles
        String capa_incidences = getI18n()
            .getString("Incidences.incidences");
        String capa_vehiculos = getI18n()
            .getString("Resources.resources.vehicles");
        String capa_people = getI18n()
            .getString("Resources.resources.people");
        Usuario u = UsuarioConsultas.find(Authentication.getUsuario()
            .getNombreUsuario());

        if (u != null) {
          if (nombreCapa.equalsIgnoreCase(capa_incidences))
            u.setIncidenciasVisibles(status);
          else if (nombreCapa.equalsIgnoreCase(capa_vehiculos))
            u.setVehiculosVisibles(status);
          else if (nombreCapa.equalsIgnoreCase(capa_people))
            u.setPersonasVisibles(status);

          UsuarioAdmin.saveOrUpdate(u);
        }

      } catch (Throwable t) {
        log.error("Error actualizando el estado de la capa", t);
      }

    }
  };

  /**
   * Actualiza la capa con marcadores que simulan vehiculos que se mueven
   *
   * @author fario
   *
   */
  @Deprecated
  private class Updater implements Runnable {

    private boolean running = true;

    @Override
    public void run() {
      running = true;
      while (running) {
        // if(System.currentTimeMillis() - time > 1000/fps){
        // buscar todos los markers que son updatable en todas las
        // marker layers
        for (Layer l : getAllLayers()) {
          if (l instanceof MarkerLayer) {
            for (Marker m : ((MarkerLayer) l).data) {
              if (m instanceof Updatable) {
                ((Updatable) m).update();
              }
            }
          }
        }

        repaint();
        // } else {
        try {
          Thread.sleep((long) (1000 / fps));
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        // }
      }
    }

    public void stop() {
      this.running = false;
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#movementEnded()
   */
  @Override
  public void movementEnded() {
    updateMarkers();
    for (MapMovedCallback m : this.movedCallbacks) {
      m.action();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#movementStarted()
   */
  @Override
  public void movementStarted() {
  }

  ;

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#addCallback(es.emergya.ui.gis.
   * MapMoveListener.MapMovedCallback)
   */
  @Override
  public void addCallback(MapMovedCallback mmc) {
    if (!this.movedCallbacks.contains(mmc)) {
      this.movedCallbacks.add(mmc);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#clearCallbacks()
   */
  @Override
  public void clearCallbacks() {
    this.movedCallbacks.clear();
    this.zoomedCallbacks.clear();
  }

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#removeCallback(es.emergya.ui.gis.
   * MapMoveListener.MapMovedCallback)
   */
  @Override
  public boolean removeCallback(MapMovedCallback mmc) {
    return this.movedCallbacks.remove(mmc);
  }

  // Separate threads to reload the markers
  private SwingWorker<Object, Object> mapUpdater;

  /*
   * (non-Javadoc)
   *
   * @see es.emergya.ui.gis.ICustomMapView#updateMarkers()
   */
  @Override
  public void updateMarkers() {
    Rectangle r = getBoundingBox();
    final LatLon tl, br;
    // tomamos los pois en un area de 3 pantallas cuadradas, de manera que
    // se pueda arrastrar sin notar que no estan cargados los poi de mas
    // allá, ya que solo se deberian cargar cuando deja de moverse.
    tl = getLatLon(r.x - r.width, r.y - r.height);
    br = getLatLon(r.x + 2 * r.width, r.y + 2 * r.height);

    if (mapUpdater == null || mapUpdater.isDone()) {
      mapUpdater = new SwingWorker<Object, Object>() {

        @Override
        protected Object doInBackground() throws Exception {
          try {
            updateIncidences(tl, br);
            updateResources(tl, br);
          } catch (Throwable t) {
            log.error("Error al actualizar marcadores", t);
          }
          return null;
        }

        @Override
        protected void done() {
          repaint();
        }
      };

      mapUpdater.execute();

    }
  }

  private void updateResources(final LatLon topleft, final LatLon bottomright) {
    MarkerLayer people = null, vehicles = null;
    // tomar las capas vehiculo y persona
    for (Layer l : getAllLayers()) {
      if (l.name.equalsIgnoreCase(getI18n()
          .getString("Resources.resources.people"))) {
        people = (MarkerLayer) l;
      }
      if (l.name.equalsIgnoreCase(getI18n()
          .getString("Resources.resources.vehicles"))) {
        vehicles = (MarkerLayer) l;
      }
      if (people != null && vehicles != null) {
        break;
      }
    }

    if (getParent() instanceof IMapViewer) { // actualizar los recursos
      // disponibles
      ((MapViewer) getParent()).updateControls();
    }

    List<Recurso> allres = RecursoConsultas.getAll(Authentication
        .getUsuario());

    boolean peopleShowing = people != null && people.visible;
    boolean vehiclesShowing = vehicles != null && vehicles.visible;

    Collection<Marker> peop = new LinkedList<Marker>();
    Collection<Marker> veh = new LinkedList<Marker>();
    for (Recurso r : allres) {
      HistoricoGPS h = r.getHistoricoGps();
      if (h == null) {
        continue;
      }
      WayPoint w = new WayPoint(new LatLon(h.getPosY(), h.getPosX()));
      String name = r.getNombre();

      if (r.getPatrullas() != null)
        name += " (" + r.getPatrullas().getNombre() + ")";

      w.attr.put("name", name);
      w.attr.put("symbol", LogicConstants.get("DIRECTORIO_ICONOS_FLOTAS")
          + "/" + r.getFlotas().getJuegoIconos());
      // w.attr.put("color", LogicConstants.get("COLOR_ESTADO_REC_"
      // + r.getEstadoEurocop().getId(), "#000000"));
      if (peopleShowing && r.getTipo().equalsIgnoreCase(Recurso.PERSONA)) {
        CustomMarker<String, Recurso> marker = new CustomMarker<String, Recurso>(
            w, people, r.getIdentificador(), Type.RESOURCE);
        marker.setObject(r);
        peop.add(marker);
      } else if (vehiclesShowing
          && r.getTipo().equalsIgnoreCase(Recurso.VEHICULO)) {

        CustomMarker<String, Recurso> marker = new CustomMarker<String, Recurso>(
            w, vehicles, r.getIdentificador(), Type.RESOURCE);
        marker.setObject(r);
        veh.add(marker);
      }
    }
    if (people != null) {
      people.data = peop;
    }
    if (vehicles != null) {
      vehicles.data = veh;
    }
  }

  private void updateIncidences(final LatLon topleft, final LatLon bottomright) {
    MarkerLayer layer = null;
    // tomar las capas vehiculo y persona
    for (Layer l : getAllLayers()) {
      if (l.name.equals(getI18n().getString("Incidences.incidences"))) {
        layer = (MarkerLayer) l;
        break;
      }
    }
    if (layer == null)
      return;

    List<Incidencia> allres = IncidenciaConsultas.getOpened();
    Collection<Marker> nuevoData = new LinkedList<Marker>();

    for (Incidencia i : allres) {
      try {
        if (i.getGeometria() != null) {
          final com.vividsolutions.jts.geom.Point centroid = i
              .getGeometria().getCentroid();
          if (centroid != null) {
            LatLon latlon = new LatLon(centroid.getCoordinate().y,
                centroid.getCoordinate().x);
            WayPoint w = new WayPoint(latlon);
            w.attr.put("name",
                i.getTitulo() + " (" + i.getPrioridad() + ")");
            w.attr.put(
                "symbol",
                LogicConstants.get(
                    "DIRECTORIO_ICONOS_INCIDENCIAS",
                    "incidencia/")
                    + "incidencia_"
                    + i.getEstado().toString()
                    + "_"
                    + i.getCategoria().toString()
                    + "_"
                    + i.getPrioridad().toString());
            w.attr.put(
                "color",
                LogicConstants.get("COLOR_ESTADO_INC_"
                    + i.getEstado().getId(), "#000000"));

            CustomMarker<Long, Incidencia> marker = new CustomMarker<Long, Incidencia>(
                w, layer, i.getId(), Type.INCIDENCE);
            marker.setObject(i);
            nuevoData.add(marker);
          }
        }
      } catch (Throwable t) {
        log.error("Error al intentar pintar una incidencia", t);
      }
    }

    layer.data = nuevoData;
  }
}
TOP

Related Classes of es.emergya.ui.gis.CustomMapView$InitAdapter

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.