package nl.tudelft.bw4t.server.util; import java.awt.geom.Point2D; import java.util.LinkedList; import java.util.List; import nl.tudelft.bw4t.server.environment.BW4TEnvironment; import nl.tudelft.bw4t.server.model.zone.Room; import nl.tudelft.bw4t.server.model.zone.Zone; import repast.simphony.space.continuous.NdPoint; /** Utility class to find a {@link Zone} based on location, name or proximity. */ public final class ZoneLocator { /** Should never be instantiated.*/ private ZoneLocator() { } /** * Find {@link Zone} containing given point. * If there are multiple Zones at the given point, the result is one of these. * * @param x * - The {@code x} coordinate of a point. * @param y * - The {@code y} coordinate of a point. * @return {@link Zone} or {@code null} if no Zone contains the given point. */ public static Zone getZoneAt(double x, double y) { Point2D location = new Point2D.Double(x, y); Iterable<Object> zones = BW4TEnvironment.getInstance().getContext().getObjects(Zone.class); for (Object r : zones) { Zone zone = (Zone) r; if (zone.getBoundingBox().contains(location)) { return zone; } } return null; } /** * Find ALL {@link Zone} containing given point. * * @param x * - The {@code x} coordinate of a point. * @param y * - The {@code y} coordinate of a point. * @return A {@link List} of Zones containing the given point. */ public static List<Zone> getZonesAt(double x, double y) { Point2D location = new Point2D.Double(x, y); List<Zone> zones = new LinkedList<Zone>(); Iterable<Object> zoneit = BW4TEnvironment.getInstance().getContext().getObjects(Zone.class); for (Object r : zoneit) { Zone zone = (Zone) r; if (zone.getBoundingBox().contains(location)) { zones.add(zone); } } return zones; } /** * Find a {@link Zone} with the given name. * * @param name * - The name of the Zone to find. * @return {@link Zone} or {@code null} if no Zone exists with that name. */ public static Zone getZone(String name) { Iterable<Object> zones = BW4TEnvironment.getInstance().getContext().getObjects(Zone.class); for (Object r : zones) { Zone zone = (Zone) r; if (name.equals(zone.getName())) { return zone; } } return null; } /** * Get zone at given point. * If there are multiple zones at the given point, the result is one of these. * * @param location * - A {@link NdPoint} containing the {@code x} and {@code y} coordinates. * @return {@link Zone} or {@code null} if no Zone contains the given point. */ public static Zone getZoneAt(NdPoint location) { return getZoneAt(location.getX(), location.getY()); } /** * Find the {@link Zone} that is nearest to given point. If point is in a Zone, we always return that Zone. * If the point is not in a zone, we return the nearest Zone. * * @param location * - The location to search for nearby Zones. * @return The nearest Zone to the given point. {@code null} if there are no Zones whatsoever. */ public static Zone getNearestZone(NdPoint location) { Zone z = ZoneLocator.getZoneAt(location); if (z != null) { return z; } return getNearestZoneNotNullNotRoom(location); } /** * Find the {@link Zone} that is nearest to given point. See also {@link #getNearestZone(NdPoint)}. * * @param location * - The location to search for nearby Zones. * @return The nearest Zone to the given point. {@code null} if there are no Zones whatsoever. */ private static Zone getNearestZoneNotNullNotRoom(NdPoint location) { Iterable<Object> zones = BW4TEnvironment.getInstance().getContext().getObjects(Zone.class); Object nearest = null; double nearestdist = Double.MAX_VALUE; for (Object zone : zones) { if (zone instanceof Room) { continue; } double dist = ((Zone)zone).distanceTo(location); if (dist < nearestdist) { nearest = zone; nearestdist = dist; } } return (Zone)nearest; } }