/* **********************************************************************
*
* Use, duplication, or disclosure by the Government is subject to
* restricted rights as set forth in the DFARS.
*
* BBN Technologies
* A Division of
* BBN Corporation
* 10 Moulton Street
* Cambridge, MA 02138
* (617) 873-3000
*
* Copyright 1998 by BBN Technologies, A Division of
* BBN Corporation, all rights reserved.
*
* **********************************************************************
*
* $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/shape/MultiRoadLayer.java,v $
* $RCSfile: MultiRoadLayer.java,v $
* $Revision: 1.4 $
* $Date: 2005/08/12 21:47:49 $
* $Author: dietrick $
*
* **********************************************************************
*/
package com.bbn.openmap.layer.shape;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.bbn.openmap.event.ProjectionEvent;
import com.bbn.openmap.event.ProjectionListener;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.omGraphics.OMGraphicList;
import com.bbn.openmap.proj.coords.LatLonPoint;
import com.bbn.openmap.tools.roads.LayerView;
import com.bbn.openmap.tools.roads.RoadFinder;
import com.bbn.openmap.tools.roads.RoadServices;
import com.bbn.openmap.tools.roads.Route;
import com.bbn.openmap.util.PropUtils;
/**
* Imposes a road layer on the multi shape layer.
*
* The important method here is getPathOnRoad(implemented for the
* RoadServices interface) which returns a list of points on the road
* found between a start and an end point.
*
* You can see more about what the road layer is doing by setting
* drawIntersections to true, which will reveal what the road finder
* thinks are roads on the road layer, and drawResults to true, which
* will show each road path request and its result. The results shown
* accumulate over time.
*
* @see com.bbn.openmap.tools.roads.RoadServices
*/
public class MultiRoadLayer extends MultiShapeLayer implements RoadServices,
ProjectionListener, LayerView {
Logger logger = Logger.getLogger(this.getClass().getName());
RoadFinder helper;
/**
* list of extra OMGraphics that represent intersections or
* results
*/
List toDraw = new ArrayList();
boolean drawIntersections = false;
boolean drawResults = false;
/**
* Property 'drawIntersections' will display the intersections on
* the road layer False by default.
*/
public static final String DrawIntersectionsProperty = "drawIntersections";
/**
* Property 'drawResults' will display the results of each road
* request on the road layer False by default.
*/
public static final String DrawResultsProperty = "drawResults";
public void setProperties(String prefix, Properties props) {
super.setProperties(prefix, props);
String realPrefix = PropUtils.getScopedPropertyPrefix(prefix);
setDrawIntersections(PropUtils.booleanFromProperties(props, realPrefix
+ DrawIntersectionsProperty, drawIntersections));
setDrawResults(PropUtils.booleanFromProperties(props, realPrefix
+ DrawResultsProperty, drawResults));
setHelper();
}
protected void setDrawIntersections(boolean val) {
drawIntersections = val;
}
protected void setDrawResults(boolean val) {
drawResults = val;
}
protected void setHelper() {
logger.info("draw inter " + drawIntersections);
helper = new RoadFinder((LayerView) this, drawIntersections, drawResults);
}
/**
* Get points on the road between start and end
*
* Implemented for the RoadService interface
*
* @param start from here
* @param end to there
* @param segments populated with road segments
* @return list of points on path
*/
public List getPathOnRoad(Point start, Point end, List segments) {
return helper.getPathOnRoad(start, end, segments);
}
/**
* @see RoadServices#getPathOnRoad(LatLonPoint, LatLonPoint)
*/
public Route getPathOnRoad(LatLonPoint start, LatLonPoint end) {
return helper.getPathOnRoad(start, end);
}
/**
* @see RoadServices#displayPathOnRoad(Point, Point, Route, List)
*/
public List displayPathOnRoad(Point start, Point end, Route route, List segments) {
return helper.displayPathOnRoad(start, end, route, segments);
}
/**
* Returns the RoadServices instance.
* <p>
*
* @return the RoadServices instance.
*/
public RoadServices getRoadServices() {
return helper;
}
/**
* Implemented for ProjectionListener
*/
public void projectionChanged(ProjectionEvent e) {
super.projectionChanged(e);
logger.info("calling helper - projection changed.");
synchronized (this) {
if (helper == null) {
setHelper();
}
helper.projectionChanged(e);
}
}
/**
* Flattens nested OMGraphicLists of lists into one level list of
* OMGraphic items. Gets the original list of graphics items from
* getList.
*
* @return List of OMGraphic items that will be used to create
* roads
*/
public List getGraphicList() {
OMGraphicList list = getList();
List out = new ArrayList();
Set seen = new HashSet();
if (list != null) {
if (logger.isLoggable(Level.INFO))
logger.info("size is " + list.size());
for (int i = 0; i < list.size(); i++) {
OMGraphic graphic = list.getOMGraphicAt(i);
if (seen.contains(graphic))
continue; // let's not re-add it
seen.add(graphic);
if (logger.isLoggable(Level.INFO))
logger.info(i + " - " + graphic);
if (graphic instanceof OMGraphicList) {
if (logger.isLoggable(Level.INFO))
logger.info("size of " + graphic + " is "
+ ((OMGraphicList) graphic).size());
for (Iterator iter = ((OMGraphicList) graphic).iterator(); iter.hasNext();) {
Object inner = iter.next();
if (inner instanceof OMGraphicList) {
if (logger.isLoggable(Level.INFO))
logger.info("size of " + inner + " is "
+ ((OMGraphicList) inner).size());
for (Iterator iter2 = ((OMGraphicList) inner).iterator(); iter2.hasNext();) {
Object inner2 = iter2.next();
if (logger.isLoggable(Level.INFO))
logger.info("1) adding - " + inner2);
out.add(inner2);
}
} else {
if (logger.isLoggable(Level.INFO))
logger.info("2) adding - " + inner);
out.add(inner);
}
}
} else {
if (logger.isLoggable(Level.INFO))
logger.info("3) adding " + graphic);
out.add(graphic);
}
}
}
return out;
}
/**
* Called from RoadFinder to tell it what extra to render (e.g.
* intersections, roads).
*/
public void setExtraGraphics(List toDraw) {
if (logger.isLoggable(Level.INFO)) {
logger.info("setting to draw " + toDraw.size() + " new graphics.");
}
this.toDraw = toDraw;
}
/**
* If drawIntersections or drawResults is true, will add
* intersection markers or returned road lines to what is
* rendered.
*/
public void paint(Graphics g) {
super.paint(g);
if (drawIntersections || drawResults) {
OMGraphicList graphics;
graphics = new OMGraphicList(toDraw);
graphics.generate(getProjection(), true);//all new
// graphics
if (logger.isLoggable(Level.INFO)) {
logger.info("rendering toDraw " + toDraw.size() + " items");
}
graphics.render(g);
}
}
}