Java tutorial
/** * Copyright (C) 2010, Emergya (http://www.emergya.es) * * @author <a href="mailto:marias@emergya.es">Mara Arias de Reyna</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. */ package org.gofleet.module.routing; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dialog.ModalityType; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JProgressBar; import javax.swing.JTextField; import javax.swing.SwingWorker; import javax.swing.filechooser.FileFilter; import org.apache.commons.logging.LogFactory; import org.gofleet.context.GoWired; import org.gofleet.internacionalization.I18n; import org.gofleet.openls.RoutingServiceStub; import org.gofleet.openls.RoutingServiceStub.GetTravellingSalesmanPlan; import org.gofleet.openls.RoutingServiceStub.GetTravellingSalesmanPlanResponse; import org.gofleet.openls.RoutingServiceStub.TSPPlan; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.gpx.GpxData; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.gui.layer.GpxLayer; import org.openstreetmap.josm.gui.layer.Layer; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; import org.openstreetmap.josm.gui.mappaint.LineElemStyle; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.io.WKTReader; import edu.emory.mathcs.backport.java.util.Collections; import es.emergya.actions.Authentication; import es.emergya.cliente.constants.LogicConstants; import es.emergya.consultas.IncidenciaConsultas; import es.emergya.consultas.RecursoConsultas; import es.emergya.ui.base.BasicWindow; import es.emergya.ui.base.plugins.PluginType; import es.emergya.ui.gis.CustomMapView.InitAdapter; import es.emergya.ui.gis.MapViewer; public class RoutingMap extends MapViewer implements ActionListener { private static final org.apache.commons.logging.Log log = LogFactory.getLog(RoutingMap.class); private static final long serialVersionUID = -1837324556102054550L; private final WKTReader wktReader = new WKTReader(); /** * @param title * @param type * @param order * @param icon * @param layers * @param mouseWheelListener * @param mouseListener * @param mouseMotionListener * @param initAdapter */ public RoutingMap(String title, PluginType type, int order, String icon, List<MarkerLayer> layers, MouseWheelListener mouseWheelListener, MouseListener mouseListener, MouseMotionListener mouseMotionListener, InitAdapter initAdapter) { super(title, type, order, icon, layers, mouseWheelListener, mouseListener, mouseMotionListener, initAdapter); } @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; } @GoWired public BasicWindow basicWindow; /** * @return the i18n */ public BasicWindow getBasicWindow() { return basicWindow; } /** * @param i18n * the i18n to set */ public void setBasicWindow(BasicWindow basicWindow) { this.basicWindow = basicWindow; } /** * @param title * @param type * @param order * @param icon * @param layers */ public RoutingMap(String title, PluginType type, int order, String icon, List<MarkerLayer> layers) { super(title, type, order, icon, layers); } /** * @param title * @param type * @param order * @param icon */ public RoutingMap(String title, PluginType type, int order, String icon) { super(title, type, order, icon); } @Override public void actionPerformed(final ActionEvent e) { SwingWorker<Object, Object> sw = new SwingWorker<Object, Object>() { @Override protected Object doInBackground() throws Exception { String mapMenuNewPlanning = i18n.getString("map.menu.new.planning"); try { if (e.getActionCommand().equals(mapMenuNewPlanning)) { LatLon from = RoutingMap.this.mapView.getLatLon( RoutingMap.this.mapView.lastMEvent.getPoint().x, RoutingMap.this.mapView.lastMEvent.getPoint().y); newPlan(from); } else { log.error( "ActionCommand desconocido: " + e.getActionCommand() + " vs " + mapMenuNewPlanning); } } catch (Throwable t) { log.error("Error al ejecutar la accion del menu contextual", t); } return null; } }; sw.execute(); } private void newPlan(LatLon from) { JDialog d = new JDialog(basicWindow.getFrame(), "Generating New Plan"); try { JFileChooser fc = new JFileChooser(); fc.addChoosableFileFilter(new RoutingFilter()); fc.setAcceptAllFileFilterUsed(true); int returnVal = fc.showOpenDialog(basicWindow.getFrame()); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); log.debug("Opening: " + file.getName()); JProgressBar progressBar = new JProgressBar(0, getNumberLines(file) * 2); progressBar.setValue(0); progressBar.setPreferredSize(new Dimension(150, 50)); progressBar.setStringPainted(true); d.add(progressBar); d.pack(); d.setVisible(true); TSPPlan[] param = processFile(file, progressBar); Map<String, String> values = getValues(from); double[] origin = new double[2]; origin[0] = new Double(values.get("origin_x")); origin[1] = new Double(values.get("origin_y")); TSPPlan[] res = calculateRouteOnWS(new Integer(values.get("maxDistance")), new Integer(values.get("maxTime")), origin, new Integer(values.get("startTime")), param, new Integer(values.get("timeSpentOnStop"))); progressBar.setValue(progressBar.getMaximum() - res.length); processTSPPlan(res, progressBar); } else { log.trace("Open command cancelled by user."); } } catch (Throwable t) { log.error("Error computing new plan", t); JOptionPane.showMessageDialog(basicWindow.getFrame(), "<html><p>" + i18n.getString("Main.Error") + ":</p><p>" + t.toString() + "</p><html>", i18n.getString("Main.Error"), JOptionPane.ERROR_MESSAGE); } finally { d.setVisible(false); d.dispose(); } } private Map<String, String> getValues(LatLon from) { final Map<String, String> mapa = new HashMap<String, String>(); final JDialog frame = new JDialog(basicWindow.getFrame(), "Configuration"); JPanel panel = new JPanel(new GridLayout(0, 2)); int width = 10; final JTextField maxDistance = new JTextField(width); maxDistance.setText("10"); final JTextField maxTime = new JTextField(width); maxTime.setText("8"); final JTextField origin_x = new JTextField(width / 2); origin_x.setText((new Double(from.getX())).toString()); final JTextField origin_y = new JTextField(width / 2); origin_y.setText((new Double(from.getY())).toString()); final JTextField startTime = new JTextField(width); startTime.setText("7"); final JTextField timeSpentOnStop = new JTextField(width); timeSpentOnStop.setText("1"); JLabel lmaxDistance = new JLabel("Maximum Distance (km)"); lmaxDistance.setLabelFor(maxDistance); JLabel lmaxTime = new JLabel("Maximum Time (hours)"); lmaxTime.setLabelFor(maxTime); JLabel lorigin = new JLabel("Point of Origin"); lorigin.setLabelFor(origin_x); JLabel lstartTime = new JLabel("Start Time of Plan (0-24)"); lstartTime.setLabelFor(startTime); JLabel ltimeSpentOnStop = new JLabel("Time Spent on Stop (hours)"); ltimeSpentOnStop.setLabelFor(timeSpentOnStop); JButton close = new JButton("OK"); close.addActionListener(new AbstractAction() { private static final long serialVersionUID = -8912729211256933464L; @Override public void actionPerformed(ActionEvent arg0) { try { mapa.put("maxDistance", maxDistance.getText()); mapa.put("maxTime", maxTime.getText()); mapa.put("origin_x", origin_x.getText()); mapa.put("origin_y", origin_y.getText()); mapa.put("startTime", startTime.getText()); mapa.put("timeSpentOnStop", timeSpentOnStop.getText()); frame.dispose(); } catch (Throwable t) { log.error("Error configuring New Route Plan" + t); JOptionPane.showMessageDialog(RoutingMap.this, "Some values are wrong. Check them again."); } } }); panel.add(lmaxDistance); panel.add(maxDistance); panel.add(lmaxTime); panel.add(maxTime); panel.add(lorigin); JPanel panel_origin = new JPanel(); panel_origin.add(origin_x); panel_origin.add(origin_y); panel.add(panel_origin); panel.add(lstartTime); panel.add(startTime); panel.add(ltimeSpentOnStop); panel.add(timeSpentOnStop); panel.add(close); frame.add(panel, BorderLayout.CENTER); frame.pack(); frame.setModalityType(ModalityType.APPLICATION_MODAL); frame.setVisible(true); return mapa; } private void processTSPPlan(TSPPlan[] res, JProgressBar progressBar) { Random random = new Random(); try { @SuppressWarnings("unchecked") Collection<Layer> allLayers = Collections.unmodifiableCollection(this.mapView.getAllLayers()); List<Layer> toremove = new LinkedList<Layer>(); for (Layer l : allLayers) { if (l.name.startsWith("Route Plan") || l.name.startsWith("Stops")) toremove.add(l); } for (Layer l : toremove) this.mapView.removeLayer(l); LatLon latlon_origin = null; int id_layer = 0; for (TSPPlan plan : res) { latlon_origin = new LatLon(plan.getOrigin()[1], plan.getOrigin()[0]); log.info(latlon_origin); LineElemStyle ls = new LineElemStyle(); float f = random.nextFloat(); ls.color = Color.getHSBColor(f * random.nextFloat(), 0.9f, 0.9f); ls.width = LogicConstants.getInt("PLAN_WAY_WIDTH", 2); MarkerLayer stops = new MarkerLayer(new GpxData(), "Stops " + id_layer, File.createTempFile("stops", "tmp"), new GpxLayer(new GpxData()), this.mapView); stops.data.add(new StopMarker(latlon_origin, "origin", "tsp_stop", stops, 0, 0, ls.color)); for (String stop : plan.getStops()) { String[] array = stop.split(","); double[] point = new double[2]; point[1] = new Double(array[0]); point[0] = new Double(array[1]); LatLon ll = new LatLon(point[0], point[1]); log.info(ll); stops.data.add(new StopMarker(ll, array[2], "tsp_stop", stops, 0, 0, ls.color)); } this.mapView.addLayer(stops, true); OsmDataLayer layer = new OsmDataLayer(new DataSet(), "Route Plan " + id_layer++, File.createTempFile("planning", "route")); String way2 = plan.getWay(); if (way2 != null) { Way way = new Way(); LatLon info = null; MultiLineString multilinestring = (MultiLineString) wktReader.read(way2); multilinestring.getLength(); int numGeometries = multilinestring.getNumGeometries(); for (int i = 0; i < numGeometries; i++) { for (Coordinate coordenada : multilinestring.getGeometryN(i).getCoordinates()) { LatLon ll = new LatLon(coordenada.y, coordenada.x); way.addNode(new Node(ll)); if (info == null) info = ll; } way.mappaintStyle = ls; layer.data.ways.add(way); way = new Way(); } progressBar.setValue(progressBar.getValue() + 1); StopMarker marker = new StopMarker(info, (new Double(plan.getDistance())).toString().substring(0, 5) + " km in " + (new Double(plan.getTime() / 60)).toString().substring(0, 3) + " hours", "tsp_stop", stops, 0, 0, ls.color); marker.setPaintIcon(false); stops.data.add(marker); } this.mapView.addLayer(layer, true); layer.visible = true; stops.visible = true; } } catch (Throwable e) { log.error("Error painting plan", e); } } private TSPPlan[] calculateRouteOnWS(Integer maxDistance, Integer maxTime, double[] doubles, Integer startTime, TSPPlan[] stops, Integer timeSpentOnStop) { try { TSPPlan[] tspplan = new TSPPlan[stops.length]; RoutingServiceStub rss = new RoutingServiceStub(LogicConstants.get("URL_ROUTING", "http://46.105.24.58:8080/openLS/services/RoutingService.RoutingServiceHttpSoap12Endpoint/")); for (int i = 0; i < tspplan.length; i++) { final TSPPlan tspPlan2 = new TSPPlan(); tspPlan2.setDistance(-1); tspPlan2.setOrigin(doubles); tspPlan2.setTime(-1); tspPlan2.setWay(null); tspPlan2.setStops(stops[i].getStops()); tspplan[i] = tspPlan2; GetTravellingSalesmanPlan param = new GetTravellingSalesmanPlan(); param.setMaxDistance(maxDistance); param.setMaxTime(maxTime); param.setStartTime(startTime); param.setTimeSpentOnStop(timeSpentOnStop); param.setParam(tspplan[i]); try { GetTravellingSalesmanPlanResponse res = rss.getTravellingSalesmanPlan(param); tspplan[i] = res.get_return(); } catch (Throwable t) { log.error("error computing " + i + " plan", t); } } return tspplan; } catch (Throwable t) { JOptionPane.showMessageDialog(basicWindow.getFrame(), "<html><p>" + "Error" + ":</p><p>" + t.toString() + "</p><html>", i18n.getString("Main.Error"), JOptionPane.ERROR_MESSAGE); log.error(t, t); } return new TSPPlan[0]; } private TSPPlan[] processFile(File file, JProgressBar progressbar) { try { LinkedList<TSPPlan> res = new LinkedList<TSPPlan>(); BufferedReader br = new BufferedReader(new FileReader(file)); String line; int i = 0; TSPPlan plan = new TSPPlan(); while ((line = br.readLine()) != null) { log.trace(line); progressbar.setValue(i++); if (!line.isEmpty()) plan.addStops(line); else { res.add(plan); plan = new TSPPlan(); } } res.add(plan); return res.toArray(new TSPPlan[0]); } catch (Throwable e) { log.error("Error processing file", e); } return null; } private int getNumberLines(File f) { LineNumberReader lineCounter; try { lineCounter = new LineNumberReader(new InputStreamReader(new FileInputStream(f.getPath()))); while (lineCounter.readLine() != null) ; return lineCounter.getLineNumber(); } catch (Exception done) { log.error(done, done); return -1; } } @Override protected JPopupMenu getContextMenu() { JPopupMenu menu = new JPopupMenu(); menu.setBackground(Color.decode("#E8EDF6")); String mapMenuTituloPlanning = i18n.getString("map.menu.titulo.planning"); String mapMenuNewPlanning = i18n.getString("map.menu.new.planning"); // Ttulo final JMenuItem titulo = new JMenuItem(mapMenuTituloPlanning); titulo.setFont(LogicConstants.deriveBoldFont(10.0f)); titulo.setBackground(Color.decode("#A4A4A4")); titulo.setFocusable(false); menu.add(titulo); // New Planning final JMenuItem to = new JMenuItem(mapMenuNewPlanning, KeyEvent.VK_F6); to.setIcon(LogicConstants.getIcon("menucontextual_icon_destinoruta")); to.addActionListener(this); menu.add(to); menu.addSeparator(); return menu; } @Override protected void initializeLayers() { super.initializeLayers(); } @SuppressWarnings("unchecked") @Override protected void updateControls() { if (Authentication.isAuthenticated()) { controlPanel.setAvaliableResources( Collections.synchronizedCollection(RecursoConsultas.getAll(Authentication.getUsuario()))); controlPanel .setAvaliableIncidences(Collections.synchronizedCollection(IncidenciaConsultas.getOpened())); } } } class RoutingFilter extends FileFilter { // gfr, GoFleetRouting @Override public boolean accept(File arg0) { return arg0.getName().endsWith(".gfr"); } @Override public String getDescription() { return "GoFleet Routing files."; } }