package aimax.osm.gui.swing.applications;
import java.util.HashSet;
import java.util.List;
import aima.core.agent.Agent;
import aima.core.environment.map.BidirectionalMapProblem;
import aima.core.environment.map.SimpleMapAgent;
import aima.core.environment.map.MapFunctionFactory;
import aima.core.search.framework.Node;
import aima.core.search.framework.NodeExpander.NodeListener;
import aima.core.search.framework.problem.Problem;
import aima.core.search.online.LRTAStarAgent;
import aima.core.search.online.OnlineSearchProblem;
import aima.core.util.math.geom.shapes.Point2D;
import aima.gui.swing.applications.agent.map.MapAgentFrame;
import aima.gui.swing.framework.AgentAppController;
import aima.gui.swing.framework.AgentAppFrame;
import aima.gui.swing.framework.MessageLogger;
import aima.gui.util.SearchFactory;
import aimax.osm.data.DataResource;
import aimax.osm.data.entities.MapNode;
import aimax.osm.data.entities.MapWay;
import aimax.osm.routing.MapAdapter;
import aimax.osm.gui.swing.viewer.agent.OsmAgentController;
import aimax.osm.gui.swing.viewer.agent.OsmAgentFrame;
import aimax.osm.gui.swing.viewer.agent.OsmAgentView;
import aimax.osm.viewer.DefaultEntityRenderer;
import aimax.osm.viewer.DefaultEntityViewInfo;
import aimax.osm.viewer.MapStyleFactory;
import aimax.osm.viewer.UColor;
/**
* This application demonstrates, how different search strategies explore the
* state space. All locations which correspond to expanded nodes are highlighted
* in the map. If you don't see any expanded node, just zoom in!
*
* @author Ruediger Lunde
*/
public class SearchDemoOsmAgentApp extends OsmAgentApp {
/**
* Stores those states (Strings with map node ids), whose corresponding
* search nodes have been expanded during the last search. Quick and dirty
* solution...
*/
static final HashSet<Object> visitedStates = new HashSet<Object>();
/** Creates an <code>OsmAgentView</code>. */
@Override
public OsmAgentView createEnvironmentView() {
OsmAgentView result = super.createEnvironmentView();
result.getMapViewPane().setRenderer(new SDMapEntityRenderer());
return result;
}
@Override
public AgentAppFrame createFrame() {
return new SDFrame();
}
@Override
public AgentAppController createController() {
return new SDController(map);
}
// ///////////////////////////////////////////////////////////////
// inner classes
/** Variant of the <code>OsmAgentFrame</code>. */
private class SDFrame extends OsmAgentFrame {
private static final long serialVersionUID = 1L;
SDFrame() {
setTitle("OSDA - the OSM Search Demo Agent Application");
// this.setSelectorItems(AGENT_SEL, new String[]{}, -1);
}
}
/**
* Variant of the <code>OsmAgentController</code> which starts an agent with
* a slightly modified goal test function.
*/
private static class SDController extends OsmAgentController {
SDController(MapAdapter map) {
super(map);
}
@Override
public void prepare(String changedSelector) {
super.prepare(changedSelector);
visitedStates.clear();
}
/** Creates new agents and adds them to the current environment. */
protected void initAgents(MessageLogger logger) {
List<MapNode> markers = map.getOsmMap().getMarkers();
if (markers.size() < 2) {
logger.log("Error: Please set two markers with mouse-left.");
return;
}
visitedStates.clear();
String[] locs = new String[markers.size()];
for (int i = 0; i < markers.size(); i++) {
MapNode node = markers.get(i);
Point2D pt = new Point2D(node.getLon(), node.getLat());
locs[i] = map.getNearestLocation(pt);
}
MapAgentFrame.SelectionState state = frame.getSelection();
heuristic = createHeuristic(state.getIndex(MapAgentFrame.HEURISTIC_SEL), locs[1]);
search = SearchFactory.getInstance().createSearch(state.getIndex(MapAgentFrame.SEARCH_SEL),
state.getIndex(MapAgentFrame.Q_SEARCH_IMPL_SEL), heuristic);
search.getNodeExpander().addNodeListener(new NodeListener() {
@Override
public void onNodeExpanded(Node node) {
visitedStates.add(node.getState());
}
});
Agent agent = null;
switch (state.getIndex(MapAgentFrame.AGENT_SEL)) {
case 0:
agent = new SimpleMapAgent(map, env, search, new String[] { locs[1] });
break;
case 1:
Problem p = new BidirectionalMapProblem(map, null, locs[1]);
OnlineSearchProblem osp = new OnlineSearchProblem(p.getActionsFunction(), p.getGoalTest(),
p.getStepCostFunction());
agent = new LRTAStarAgent(osp, MapFunctionFactory.getPerceptToStateFunction(), heuristic);
break;
}
env.addAgent(agent, locs[0]);
}
}
/**
* Variant of the <code>DefaultMapEntityRenderer</code> which highlights way
* nodes mentioned in {@link SearchDemoOsmAgentApp#visitedStates}.
*/
private static class SDMapEntityRenderer extends DefaultEntityRenderer {
DefaultEntityViewInfo highlightProp = new MapStyleFactory().createPoiInfo(0, 0, 5, UColor.GREEN,
MapStyleFactory.createRectangle(4, UColor.GREEN), false);
@Override
public void printWay(MapWay way, DefaultEntityViewInfo eprop, boolean asArea) {
super.printWay(way, eprop, asArea);
if (scale >= highlightProp.minVisibleScale * displayFactor) {
for (MapNode node : getWayNodes(way))
if (visitedStates.contains(Long.toString(node.getId())))
printPoint(imageBdr, node, highlightProp, null);
// highlight(node);
}
}
// private void highlight(MapNode node) {
// int offs = (int) displayFactor;
// int x = transformer.x(node.getLon()) - offs;
// int y = transformer.y(node.getLat()) - offs;
// g2.setColor(Color.YELLOW);
// g2.setStroke(new BasicStroke(1f));
// g2.fillRect(x, y, 2*offs, 2*offs);
// }
}
// ///////////////////////////////////////////////////////////////
// starter method
/** Application starter. */
public static void main(String args[]) {
// Logger.getLogger("aimax.osm").setLevel(Level.FINEST);
// Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);
SearchDemoOsmAgentApp demo = new SearchDemoOsmAgentApp();
demo.readMap(DataResource.getULMFileResource());
demo.startApplication();
}
}