package aimax.osm.routing.agent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; import aima.core.agent.Action; import aima.core.agent.Agent; import aima.core.agent.EnvironmentState; import aima.core.environment.map.MapEnvironment; import aima.core.environment.map.MoveToAction; import aima.gui.framework.AgentAppEnvironmentView; import aimax.osm.data.EntityClassifier; import aimax.osm.data.MapBuilder; import aimax.osm.data.OsmMap; import aimax.osm.data.Position; import aimax.osm.data.entities.EntityViewInfo; import aimax.osm.data.entities.MapNode; import aimax.osm.reader.Bz2OsmReader; import aimax.osm.reader.MapReader; import aimax.osm.viewer.MapStyleFactory; import aimax.osm.viewer.MapViewPane; import aimax.osm.viewer.MapViewPopup; /** * Visualizes agent positions and movements in an OSM map. It is assumed that * agents are only added but never removed from an environment. * * @author Ruediger Lunde */ public class OsmAgentView extends AgentAppEnvironmentView { private static final long serialVersionUID = 1L; public static final String TRACK_NAME = "Track"; MapViewPane mapViewPane; /** * Creates an agent view which displays agent positions within a map using * the given map data. This implementation assumes that for the same * <code>mapData</code> instance only one agent view is created. */ public OsmAgentView(OsmMap mapData) { MapStyleFactory msf = new MapStyleFactory(); EntityClassifier<EntityViewInfo> eClassifier = msf .createDefaultClassifier(); eClassifier.addRule("track_type", TRACK_NAME + 0, msf .createTrackInfo(Color.RED)); eClassifier.addRule("track_type", TRACK_NAME + 1, msf .createTrackInfo(Color.GREEN)); eClassifier.addRule("track_type", TRACK_NAME + 2, msf .createTrackInfo(Color.BLUE)); mapData.setEntityClassifier(eClassifier); mapViewPane = new MapViewPane(); mapViewPane.setMap(mapData); mapViewPane.setPopupMenu(new MapViewPopupWithLoad()); setLayout(new BorderLayout()); add(mapViewPane, BorderLayout.CENTER); } public MapViewPane getMapViewPane() { return mapViewPane; } protected MapEnvironment getMapEnv() { return (MapEnvironment) env; } /** * Reacts on environment changes and updates the tracks. */ @Override public void agentAdded(Agent agent, EnvironmentState resultingState) { String loc = getMapEnv().getAgentLocation(agent); updateTrack(agent, loc); } /** * Reacts on environment changes and updates the tracks. */ @Override public void agentActed(Agent agent, Action command, EnvironmentState state) { String msg = ""; if (env.getAgents().size() > 1) msg = "A" + env.getAgents().indexOf(agent) + ": "; notify(msg + command.toString()); if (command instanceof MoveToAction) { updateTrack(agent, getMapEnv().getAgentLocation(agent)); } } private void updateTrack(Agent agent, String location) { MapAdapter map = (MapAdapter) getMapEnv().getMap(); MapNode node = map.getWayNode(location); if (node != null) { int aIdx = getMapEnv().getAgents().indexOf(agent); map.getOsmMap().addToTrack(TRACK_NAME + aIdx, new Position(node.getLat(), node.getLon())); } } // //////////////////////////////////////////////////////////////////// // inner classes /** Extends the <code>MapViewPopup</code> by a load map menu item. */ private class MapViewPopupWithLoad extends MapViewPopup { private static final long serialVersionUID = 1L; MapReader mapReader; JMenuItem loadMenuItem; JFileChooser loadFileChooser; MapViewPopupWithLoad() { mapReader = new Bz2OsmReader(); loadMenuItem = new JMenuItem("Load Map"); loadMenuItem.addActionListener(this); add(loadMenuItem, 3); } /** * Creates a file chooser for map loading if necessary (lazy * instantiation). */ JFileChooser getLoadFileChooser() { JFileChooser result = loadFileChooser; if (result == null) { result = new JFileChooser(); String[] exts = mapReader.fileFormatDescriptions(); for (int i = 0; i < exts.length; i++) { FileFilter filter = new FileNameExtensionFilter(exts[i], mapReader.fileFormatExtensions()[i]); result.addChoosableFileFilter(filter); } result.setFileFilter(result.getChoosableFileFilters()[0]); loadFileChooser = result; } return result; } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == loadMenuItem) { JFileChooser fc = getLoadFileChooser(); int status = fc.showOpenDialog(pane); if (status == JFileChooser.APPROVE_OPTION) { MapBuilder mapBuilder = pane.getMap().getBuilder(); mapReader.readMap(fc.getSelectedFile(), mapBuilder); mapBuilder.buildMap(); } } else { super.actionPerformed(ae); } } } }