package aimax.osm.applications; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.Locale; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JToolBar; import aimax.osm.data.DataResource; import aimax.osm.data.MapEvent; import aimax.osm.data.MapEventListener; import aimax.osm.data.OsmMap; import aimax.osm.data.Position; import aimax.osm.routing.RouteCalculator; import aimax.osm.viewer.MapViewFrame; /** * Implements a simple route planning tool. It extends the OSM map viewer by a * little search engine for shortest paths using the A* algorithm. Set two * markers (mouse left) before starting route calculation! * * @author Ruediger Lunde */ public class RoutePlannerApp implements ActionListener { public final static String ROUTE_TRACK_NAME = "Route"; protected MapViewFrame frame; protected JComboBox<String> waySelection; protected JButton calcButton; protected RouteCalculator routeCalculator; public RoutePlannerApp() { this(new String[0]); } public RoutePlannerApp(String[] args) { frame = new MapViewFrame(args); frame.setTitle("OSM Route Planner"); routeCalculator = createRouteCalculator(); JToolBar toolbar = frame.getToolbar(); toolbar.addSeparator(); waySelection = new JComboBox<String>( routeCalculator.getWaySelectionOptions()); toolbar.add(waySelection); toolbar.addSeparator(); calcButton = new JButton("Calculate Route"); calcButton.setEnabled(frame.getMap().getMarkers().size() >= 2); calcButton.addActionListener(this); toolbar.add(calcButton); frame.getMap().addMapDataEventListener(new MapDataEventHandler()); } /** * Factory method for the routing component. Subclasses can override it and * provide more advanced routing algorithms. */ protected RouteCalculator createRouteCalculator() { return new RouteCalculator(); } public MapViewFrame getFrame() { return frame; } public void showFrame() { frame.setSize(800, 600); frame.setVisible(true); } /** * Loads the default map if necessary and returns the frame (useful for * integration into an AIMA demo application). */ public MapViewFrame constructApplicationFrame() { if (frame.getMap().isEmpty()) frame.readMap(DataResource.getULMFileResource()); return frame; } /** Starts route generation after the calculate button has been pressed. */ public void actionPerformed(ActionEvent e) { if (e.getSource() == calcButton) { OsmMap map = frame.getMap(); List<Position> positions = routeCalculator.calculateRoute( map.getMarkers(), map, waySelection.getSelectedIndex()); frame.getMap().createTrack(ROUTE_TRACK_NAME, positions); } } /** * Updates the info field based on events sent by the MapViewPane. * * @author Ruediger Lunde */ class MapDataEventHandler implements MapEventListener { @Override public void eventHappened(MapEvent event) { calcButton.setEnabled(frame.getMap().getMarkers().size() > 1); } } /** * Start application with program arg <code>-screenwidth=xx</code> (with xx * the width in cm) or <code>-screensize=yy</code> (with yy measured * diagonally in inch). */ public static void main(String[] args) { // indicates progress when reading large maps (for testing only) // Logger.getLogger("aimax.osm").setLevel(Level.FINEST); // Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE); Locale.setDefault(Locale.US); RoutePlannerApp demo = new RoutePlannerApp(args); demo.getFrame().readMap(DataResource.getULMFileResource()); demo.showFrame(); } }