package iamrescue.agent.firebrigade;
import iamrescue.belief.IAMWorldModel;
import iamrescue.routing.costs.BlockCheckerUtil;
import iamrescue.util.PositionXY;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import javolution.util.FastMap;
import javolution.util.FastSet;
import rescuecore2.misc.geometry.Line2D;
import rescuecore2.standard.entities.Area;
import rescuecore2.standard.entities.Building;
import rescuecore2.standard.entities.Road;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.worldmodel.EntityID;
public class VisibilityMap {
private Map<EntityID, Set<EntityID>> buildingToRoadMap;
private static final Logger LOGGER = Logger.getLogger(VisibilityMap.class);
public VisibilityMap(IAMWorldModel worldModel, int viewDistance) {
long time = System.currentTimeMillis();
LOGGER.info("Starting building visbility map.");
Collection<StandardEntity> buildings = worldModel.getEntitiesOfType(
StandardEntityURN.BUILDING, StandardEntityURN.REFUGE,
StandardEntityURN.POLICE_OFFICE,
StandardEntityURN.FIRE_STATION,
StandardEntityURN.AMBULANCE_CENTRE);
/*
* Collection<StandardEntity> roads = worldModel
* .getEntitiesOfType(StandardEntityURN.ROAD);
*/
buildingToRoadMap = new FastMap<EntityID, Set<EntityID>>(buildings
.size());
for (StandardEntity building : buildings) {
Set<EntityID> canView = new FastSet<EntityID>();
// Get nearby roads
Collection<StandardEntity> possibleExtinguishPositions = worldModel
.getObjectsInRange(building, viewDistance);
PositionXY buildingPosition = new PositionXY(building
.getLocation(worldModel));
for (StandardEntity standardEntity : possibleExtinguishPositions) {
if (standardEntity instanceof Road) {
Road road = (Road) standardEntity;
PositionXY locationXY = new PositionXY(road.getX(), road
.getY());
if (locationXY.distanceTo(buildingPosition) < viewDistance) {
Line2D myLineOfSight = new Line2D(locationXY
.toPoint2D(), buildingPosition.toPoint2D());
boolean blocking = false;
for (StandardEntity inRange : possibleExtinguishPositions) {
if (inRange instanceof Building
&& !inRange.getID()
.equals(building.getID())) {
if (BlockCheckerUtil.isIntersecting(
(Area) inRange, myLineOfSight, false)) {
blocking = true;
break;
}
}
}
if (!blocking) {
canView.add(road.getID());
}
}
}
}
buildingToRoadMap.put(building.getID(), canView);
}
LOGGER.info("Done building visbility map after "
+ (System.currentTimeMillis() - time) + " ms.");
}
public Set<EntityID> getRoadsToExtinguishFrom(EntityID buildingID) {
return buildingToRoadMap.get(buildingID);
}
}