/** Returns a (random) coordinate that is between two adjacent MapNodes */ @Override public Coord getInitialLocation(boolean translate) { List<MapNode> nodes = map.getNodes(); MapNode n, n2; Coord n2Location, nLocation, placement; double dx, dy; double rnd = rng.nextDouble(); // choose a random node (from OK types if such are defined) do { n = nodes.get(rng.nextInt(nodes.size())); } while (okMapNodeTypes != null && !n.isType(okMapNodeTypes)); // choose a random neighbor of the selected node n2 = n.getNeighbors().get(rng.nextInt(n.getNeighbors().size())); nLocation = n.getLocation(); n2Location = n2.getLocation(); placement = n.getLocation().clone(); dx = rnd * (n2Location.getX() - nLocation.getX()); dy = rnd * (n2Location.getY() - nLocation.getY()); if (translate == false) { dx = 0; dy = 0; } placement.translate(dx, dy); // move coord from n towards n2 this.lastMapNode = n; return placement; }
/** * Creates a new instance of HomeActivityMovement * * @param settings */ public HomeActivityMovement(Settings settings) { super(settings); distance = 100; pathFinder = new DijkstraPathFinder(null); mode = WALKING_HOME_MODE; String homeLocationsFile = null; try { homeLocationsFile = settings.getSetting(HOME_LOCATIONS_FILE_SETTING); } catch (Throwable t) { // Do nothing; } timeDiffSTD = settings.getInt(STD_FOR_TIME_DIFF_SETTING); if (homeLocationsFile == null) { MapNode[] mapNodes = (MapNode[]) getMap().getNodes().toArray(new MapNode[0]); int homeIndex = rng.nextInt(mapNodes.length - 1); homeLocation = mapNodes[homeIndex].getLocation().clone(); } else { try { allHomes = new LinkedList<Coord>(); List<Coord> locationsRead = (new WKTReader()).readPoints(new File(homeLocationsFile)); for (Coord coord : locationsRead) { SimMap map = getMap(); Coord offset = map.getOffset(); // mirror points if map data is mirrored if (map.isMirrored()) { coord.setLocation(coord.getX(), -coord.getY()); } coord.translate(offset.getX(), offset.getY()); allHomes.add(coord); } homeLocation = allHomes.get(rng.nextInt(allHomes.size())).clone(); } catch (Exception e) { e.printStackTrace(); } } if (timeDiffSTD == -1) { timeDifference = rng.nextInt(DAY_LENGTH) - DAY_LENGTH / 2; } else if (timeDiffSTD == 0) { timeDifference = 0; } else { timeDifference = (int) Math.min( Math.max((rng.nextGaussian() * timeDiffSTD), -DAY_LENGTH / 2), DAY_LENGTH / 2); } }
/** * Visualize node's location, radio ranges and connections * * @param g2 The graphic context to draw to */ private void drawHost(Graphics2D g2) { Coord loc = node.getLocation(); if (drawCoverage && node.isRadioActive()) { ArrayList<NetworkInterface> interfaces = new ArrayList<NetworkInterface>(); interfaces.addAll(node.getInterfaces()); for (NetworkInterface ni : interfaces) { double range = ni.getTransmitRange(); Ellipse2D.Double coverage; coverage = new Ellipse2D.Double( scale(loc.getX() - range), scale(loc.getY() - range), scale(range * 2), scale(range * 2)); // draw the "range" circle g2.setColor(rangeColor); g2.draw(coverage); } } if (drawConnections) { g2.setColor(conColor); Coord c1 = node.getLocation(); ArrayList<Connection> conList = new ArrayList<Connection>(); // create a copy to prevent concurrent modification exceptions conList.addAll(node.getConnections()); for (Connection c : conList) { DTNHost otherNode = c.getOtherNode(node); Coord c2; if (otherNode == null) { continue; /* disconnected before drawn */ } c2 = otherNode.getLocation(); g2.drawLine(scale(c1.getX()), scale(c1.getY()), scale(c2.getX()), scale(c2.getY())); } } /* draw node rectangle */ g2.setColor(hostColor); g2.drawRect(scale(loc.getX() - 1), scale(loc.getY() - 1), scale(2), scale(2)); if (isHighlighted()) { g2.setColor(highlightedNodeColor); g2.fillRect(scale(loc.getX()) - 3, scale(loc.getY()) - 3, 6, 6); } if (drawNodeName) { g2.setColor(hostNameColor); // Draw node's address next to it g2.drawString(node.toString(), scale(loc.getX()), scale(loc.getY())); } }
/** * Reads a sim map from location set to the settings, mirrors the map and moves its upper left * corner to origo. * * @return A new SimMap based on the settings */ private SimMap readMap() { SimMap simMap; Settings settings = new Settings(MAP_BASE_MOVEMENT_NS); WKTMapReader r = new WKTMapReader(true); if (cachedMap == null) { cachedMapFiles = new ArrayList<String>(); // no cache present } else { // something in cache // check out if previously asked map was asked again SimMap cached = checkCache(settings); if (cached != null) { nrofMapFilesRead = cachedMapFiles.size(); return cached; // we had right map cached -> return it } else { // no hit -> reset cache cachedMapFiles = new ArrayList<String>(); cachedMap = null; } } try { int nrofMapFiles = settings.getInt(NROF_FILES_S); for (int i = 1; i <= nrofMapFiles; i++) { String pathFile = settings.getSetting(FILE_S + i); cachedMapFiles.add(pathFile); r.addPaths(new File(pathFile), i); } nrofMapFilesRead = nrofMapFiles; } catch (IOException e) { throw new SimError(e.toString(), e); } simMap = r.getMap(); checkMapConnectedness(simMap.getNodes()); // mirrors the map (y' = -y) and moves its upper left corner to origo simMap.mirror(); Coord offset = simMap.getMinBound().clone(); simMap.translate(-offset.getX(), -offset.getY()); checkCoordValidity(simMap.getNodes()); cachedMap = simMap; return simMap; }
@Override public Path getPath() { if (mode == WALKING_HOME_MODE) { // Try to find home SimMap map = super.getMap(); if (map == null) { return null; } MapNode thisNode = map.getNodeByCoord(lastWaypoint); MapNode destinationNode = map.getNodeByCoord(homeLocation); List<MapNode> nodes = pathFinder.getShortestPath(thisNode, destinationNode); Path path = new Path(generateSpeed()); for (MapNode node : nodes) { path.addWaypoint(node.getLocation()); } lastWaypoint = homeLocation.clone(); mode = AT_HOME_MODE; double newX = lastWaypoint.getX() + (rng.nextDouble() - 0.5) * distance; if (newX > getMaxX()) { newX = getMaxX(); } else if (newX < 0) { newX = 0; } double newY = lastWaypoint.getY() + (rng.nextDouble() - 0.5) * distance; if (newY > getMaxY()) { newY = getMaxY(); } else if (newY < 0) { newY = 0; } Coord c = new Coord(newX, newY); path.addWaypoint(c); return path; } else { Path path = new Path(1); path.addWaypoint(lastWaypoint.clone()); mode = READY_MODE; return path; } }
/** * Draws a bar (stack of squares) next to a location * * @param g2 The graphic context to draw to * @param loc The location where to draw * @param nrof How many squares in the stack * @param col Which column */ private void drawBar(Graphics2D g2, Coord loc, int nrof, int col) { final int BAR_HEIGHT = 5; final int BAR_WIDTH = 5; final int BAR_DISPLACEMENT = 2; // draws a stack of squares next loc for (int i = 1; i <= nrof; i++) { if (i % 2 == 0) { // use different color for every other msg g2.setColor(msgColor1); } else { if (col > 1) { g2.setColor(msgColor3); } else { g2.setColor(msgColor2); } } g2.fillRect( scale(loc.getX() - BAR_DISPLACEMENT - (BAR_WIDTH * col)), scale(loc.getY() - BAR_DISPLACEMENT - i * BAR_HEIGHT), scale(BAR_WIDTH), scale(BAR_HEIGHT)); } }