diff --git a/src/movement/LinearMovement.java b/src/movement/LinearMovement.java
index 5b23deeb1..dc0127f0b 100644
--- a/src/movement/LinearMovement.java
+++ b/src/movement/LinearMovement.java
@@ -6,8 +6,6 @@
import core.Coord;
import core.Settings;
-import movement.MovementModel;
-import movement.Path;
/**
* Movement model where all nodes move on a line
@@ -27,8 +25,11 @@ public class LinearMovement extends MovementModel {
* Nodes' initial location type
*
- 0: random (evenly distributed)
*
- 1: evenly spaced
+ *
- 2: static location at the start of line
+ *
- 3: evenly spaced among subsegment (needs startSegmentEndLocation)
*
*/
+ public static final String INIT_LOC_SEGMENT_END = "initLocSegmentEnd";
public static final String INIT_LOC_S = "initLocType";
/**
* Nodes' target (where they're heading) type
@@ -37,6 +38,7 @@ public class LinearMovement extends MovementModel {
*
*/
public static final String TARGET_S = "targetType";
+ private Coord initLocSegmentEnd; /** Used for node initial location distribution among segment*/
/* values for the prototype */
private Coord startLoc; /** The start location of the line */
@@ -62,6 +64,10 @@ public LinearMovement(Settings s) {
this.startLoc = new Coord(coords[0], coords[1]);
coords = s.getCsvInts(LINEAR_MOVEMENT_NS + END_LOCATION_S, 2);
this.endLoc = new Coord(coords[0], coords[1]);
+ if (s.contains(LINEAR_MOVEMENT_NS + INIT_LOC_SEGMENT_END)){
+ coords = s.getCsvInts(LINEAR_MOVEMENT_NS + INIT_LOC_SEGMENT_END);
+ this.initLocSegmentEnd = new Coord(coords[0], coords[1]);
+ }
this.initLocType = s.getInt(LINEAR_MOVEMENT_NS + INIT_LOC_S);
this.targetType = s.getInt(LINEAR_MOVEMENT_NS + TARGET_S);
this.nodeCount = s.getInt(core.SimScenario.NROF_HOSTS_S);
@@ -75,7 +81,12 @@ public LinearMovement(Settings s) {
*/
public LinearMovement(LinearMovement ilm) {
super(ilm);
- this.initLoc = calculateLocation(ilm, (ilm.initLocType == 1));
+ if (ilm.initLocType == 2)
+ this.initLoc = ilm.startLoc;
+ else if (ilm.initLocType == 3)
+ this.initLoc = calculateLocationForSegment(ilm);
+ else
+ this.initLoc = calculateLocation(ilm, (ilm.initLocType == 1));
this.nextPath = new Path(generateSpeed());
this.nextPath.addWaypoint(initLoc);
@@ -88,6 +99,25 @@ public LinearMovement(LinearMovement ilm) {
ilm.lastIndex++;
}
+ /** Spreads locations out evenly among the segment defined by initLocSegmentEnd (initLocType 3)*/
+ private Coord calculateLocationForSegment(LinearMovement proto) {
+ double dx = 0;
+ double dy = 0;
+ double placementFraction;
+
+ double xDiff = (proto.initLocSegmentEnd.getX() - proto.startLoc.getX());
+ double yDiff = (proto.initLocSegmentEnd.getY() - proto.startLoc.getY());
+ Coord c = proto.startLoc.clone();
+
+
+ placementFraction = (1.0 * proto.lastIndex / proto.nodeCount);
+ dx = placementFraction * xDiff;
+ dy = placementFraction * yDiff;
+
+ c.translate(dx, dy);
+ return c;
+ }
+
/**
* Calculates and returns a location in the line
* @param proto The movement model prototype
diff --git a/src/movement/StaticMovement.java b/src/movement/StaticMovement.java
new file mode 100644
index 000000000..4c2767362
--- /dev/null
+++ b/src/movement/StaticMovement.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2010 Aalto University, ComNet
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package movement;
+
+import core.Coord;
+import core.Settings;
+import core.SimError;
+import input.WKTMapReader;
+import movement.map.SimMap;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static core.SimScenario.NROF_HOSTS_S;
+
+/**
+ * A model where nodes do not move. Locations are defined in reference to a map,
+ * as points in .wkt file.
+ * Example settings:
+ * Group1.movementModel = StaticMovement
+ * Group1.staticLocationFile = staticLocs.wkt
+ * MapBasedMovement.nrofMapFiles = 1
+ * MapBasedMovement.mapFile1 = map.wkt
+ *
+ * Might be useful for simulations with only external connection events.
+ */
+public class StaticMovement extends MapBasedMovement {
+ /** Per node group setting for setting the location ({@value}) */
+ public static final String LOCATION_S = "nodeLocations";
+ private static final String STATIC_MOVEMENT_NS = "StaticMovement";
+ private static final String LOCATION_FILE = "staticLocationFile";
+ private Coord loc; /** The location of the nodes */
+
+ private List locations;
+ private int lastIndex; /** index of the previous node */
+
+ /**
+ * Creates a new movement model based on a Settings object's settings.
+ * @param s The Settings object where the settings are read from
+ */
+ public StaticMovement(Settings s) {
+ super(s);
+
+ String path = s.getSetting(LOCATION_FILE);
+ int nodeCount = s.getInt(NROF_HOSTS_S);
+
+ try {
+ WKTMapReader r = new WKTMapReader(true);
+
+ locations = r.readPoints(new File(path));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (locations.size() < nodeCount){
+ throw new SimError("Locations file has less points than nrOfHosts!");
+ }
+ SimMap map = getMap();
+ Coord offset = map.getOffset();
+
+ for (Coord c : locations) {
+ if (map.isMirrored()) { // mirror POIs if map data is also mirrored
+ c.setLocation(c.getX(), -c.getY()); // flip around X axis
+ }
+ // translate to match map data
+ c.translate(offset.getX(), offset.getY());
+ }
+
+ lastIndex = 0;
+ }
+
+ /**
+ * Copy constructor.
+ * @param sm The StationaryMovement prototype
+ */
+ public StaticMovement(StaticMovement sm) {
+ super(sm);
+ this.loc = sm.locations.get(sm.lastIndex++);
+ }
+
+ /**
+ * Returns the only location of this movement model
+ * @return the only location of this movement model
+ */
+ @Override
+ public Coord getInitialLocation() {
+ return loc;
+ }
+
+ /**
+ * Returns a single coordinate path (using the only possible coordinate)
+ * @return a single coordinate path
+ */
+ @Override
+ public Path getPath() {
+ Path p = new Path(0);
+ p.addWaypoint(loc);
+ return p;
+ }
+
+ @Override
+ public double nextPathAvailable() {
+ return Double.MAX_VALUE; // no new paths available
+ }
+
+ @Override
+ public StaticMovement replicate() {
+ return new StaticMovement(this);
+ }
+
+}