Commit df17fe5a authored by Martin Hellwig's avatar Martin Hellwig
Browse files

Added Movement of objects on real world streets based on osm-data

parent 66d66180
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.topology.movement.local;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Locale;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.openstreetmap.osmosis.osmbinary.Osmformat;
import com.graphhopper.GHRequest;
import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint3D;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.Topology;
import de.tud.kom.p2psim.impl.util.Either;
import de.tud.kom.p2psim.impl.util.Left;
/**
* This movement strategy uses the data from osm and navigates the nodes throught streets to the destination
*
* @author Martin Hellwig
* @version 1.0, 07.07.2015
*/
public class RealWorldStreetsMovement extends AbstractLocalMovementStrategy {
private PositionVector worldDimensions;
private GraphHopper hopper;
private boolean init = false;
private String osmFileLocation; //use pbf-format, because osm-format causes problems (xml-problems)
private String graphFolderFiles;
private String movementType; //car, bike or foot
private String navigationalType; //fastest,
private double latLeft; //Values from -90 to 90; always smaller than latRight
private double latRight; //Values from -90 to 90
private double lonLeft; //Values from -180 to 180; Always smaller than lonRight
private double lonRight; //Values from -180 to 180
public RealWorldStreetsMovement() {
this.worldDimensions = Topology.getWorldDimension();
}
private void init() {
hopper = new GraphHopper().forServer();
hopper.setOSMFile(osmFileLocation);
// where to store graphhopper files?
hopper.setGraphHopperLocation(graphFolderFiles);
hopper.setEncodingManager(new EncodingManager(movementType));
hopper.importOrLoad();
init = true;
}
public Either<PositionVector, Boolean> nextPosition(MovementSupported comp,
PositionVector destination) {
if(!init) init();
PositionVector newPosition = null;
if (destination.getDistance(comp.getRealPosition()) < getMovementSpeed(comp)) {
newPosition = destination.clone();
} else {
double[] startPosition = transformOwnWorldWindowToGPS(comp.getRealPosition().getX(), comp.getRealPosition().getY());
double[] destinationPosition = transformOwnWorldWindowToGPS(destination.getX(), destination.getY());
GHRequest req = new GHRequest(startPosition[0], startPosition[1], destinationPosition[0], destinationPosition[1]).
setWeighting(navigationalType).
setVehicle(movementType).
setLocale(Locale.GERMANY);
GHResponse rsp = hopper.route(req);
PointList pointList = rsp.getPoints();
int bla = 0;
for(GHPoint3D temp : pointList) {
PositionVector nextPoint = transformGPSWindowToOwnWorld(temp.getLat(), temp.getLon());
newPosition = comp.getRealPosition().moveStep(nextPoint, 10*getMovementSpeed(comp));
bla++;
if(bla == 2) break;
}
//newPosition = comp.getRealPosition().moveStep(destination, getMovementSpeed(comp));
}
return new Left<PositionVector, Boolean>(newPosition);
}
/**
* Projects the world coordinates in the given gps window to the gps-coordinates
* @param x
* @param y
* @return The projected position in gps-coordinates (lat, long)
*/
private double[] transformOwnWorldWindowToGPS(double x, double y) {
double[] gps_coordinates = new double[2];
gps_coordinates[0] = latLeft + (latRight - latLeft) * y/worldDimensions.getY();
gps_coordinates[1] = lonLeft + (lonRight - lonLeft) * x/worldDimensions.getX();
return gps_coordinates;
}
/**
* Projects the gps coordinates in the given gps window to the world-coordinates given in world-dimensions
* @param lat
* @param lon
* @return The projected position in world-dimensions
*/
private PositionVector transformGPSWindowToOwnWorld(double lat, double lon) {
double x = worldDimensions.getX() * (lon - lonLeft)/(lonRight - lonLeft);
double y = worldDimensions.getY() * (lat - latLeft)/(latRight - latLeft);
return new PositionVector(x, y);
}
public void setOsmFileLocation(String osmFileLocation) {
this.osmFileLocation = osmFileLocation;
}
public void setGraphFolderFiles(String graphFolderFiles) {
this.graphFolderFiles = graphFolderFiles;
}
public void setMovementType(String movementType) {
this.movementType = movementType;
}
public void setNavigationalType(String navigationalType) {
this.navigationalType = navigationalType;
}
public void setLatLeft(double latLeft) {
this.latLeft = latLeft;
}
public void setLatRight(double latRight) {
this.latRight = latRight;
}
public void setLonLeft(double lonLeft) {
this.lonLeft = lonLeft;
}
public void setLonRight(double lonRight) {
this.lonRight = lonRight;
}
}
......@@ -48,10 +48,11 @@ import de.tudarmstadt.maki.simonstrator.api.Randoms;
/**
* Modular Movement Model uses different models/strategies to create a movement
* model. In this implementation, it has 4 different models/strategies.
* model. In this implementation, it has 3 different models/strategies.
* <p>
* M0: AttractionGenerator -> Generates the {@link AttractionPoint}s and place
* them on the map. The {@link AttractionPoint}s can be moved!
* them on the map. The {@link AttractionPoint}s can't be moved, because they are
* static POIs from real-world data!
* <p>
* M1: A general {@link MovementModel} is not used, because we use static attraction points.
* <p>
......@@ -66,7 +67,7 @@ import de.tudarmstadt.maki.simonstrator.api.Randoms;
* {@link LocalMovementStrategy} will be called from the
* {@link ModularMovementModel} to do a Movement!
* <p>
* This class contains all four components and manage the data exchange.
* This class contains all three components and manage the data exchange.
* Additionally it contains an periodic operation, which handle the movement of
* all hosts. This mean, that it will be call the {@link LocalMovementStrategy}
* with the destination. Please take care, that the handling of the movement of
......@@ -77,15 +78,15 @@ import de.tudarmstadt.maki.simonstrator.api.Randoms;
*
*
*
* @author Christoph Muenker
* @version 1.0, 02.07.2013
* @author Martin Hellwig
* @version 1.0, 07.07.2015
*/
public class ModularMovementModel implements MovementModel, EventHandler {
private final int EVENT_MOVE = 1;
private final int EVENT_INIT = 2;
protected PositionVector worldDimensions;
protected ITransitionStrategy transition;
......@@ -134,7 +135,8 @@ public class ModularMovementModel implements MovementModel, EventHandler {
List<AttractionPoint> attractionPoints = attractionGenerator.getAttractionPoints();
transition.setAttractionPoints(attractionPoints);
//This adds the mobile hosts (smartphones/users) to the transition strategy
for (MovementSupported ms : moveableHosts) {
transition.addComponent(ms);
}
......@@ -281,7 +283,6 @@ public class ModularMovementModel implements MovementModel, EventHandler {
* @return
*/
protected List<AttractionPoint> getAttractionPoints() {
return attractionGenerator.getAttractionPoints();
//return new Vector<AttractionPoint>(transition.getAssignments().values());
return new Vector<AttractionPoint>(attractionGenerator.getAttractionPoints());
}
}
......@@ -65,7 +65,6 @@ public class ModularMovementModelViz extends JComponent {
g2.setStroke(new BasicStroke(1f));
g2.drawOval(point.x - 15, point.y - 15, 30, 30);
g2.drawString(aPoint.getName(), point.x - 15, point.y - 15);
//System.out.println(movementModel.getAttractionPoints().size() + ";" + aPoint.getRealPosition().toString() + ";" + aPoint.getName());
g2.setColor(new Color(0.2f, 0.8f, 0.2f, 0.6f));
g2.fillOval(point.x - 15, point.y - 15, 30, 30);
......
......@@ -56,11 +56,14 @@ public class JSONAttractionGenerator implements IAttractionGenerator {
private double lonRight; //Values from -180 to 180
/**
*
* You have to set a json-file, which has set some POIs
* Sample-query for "bar"-POIs in Darmstadt (Bounding Box from [49.4813, 8.5590] to [49.9088, 8,7736]:
http://overpass.osm.rambler.ru/cgi/interpreter?data=%5Bout:json%5D;node%5Bamenity=bar%5D%2849%2E4813%2C8%2E5590%2C49%2E9088%2C8%2E7736%29%3Bout%3B
* @param file
*/
public JSONAttractionGenerator() {
this.worldDimensions = Topology.getWorldDimension();
attractionPoints = new LinkedList<AttractionPoint>();
}
/**
......@@ -82,7 +85,6 @@ public class JSONAttractionGenerator implements IAttractionGenerator {
@Override
public List<AttractionPoint> getAttractionPoints() {
attractionPoints = new LinkedList<AttractionPoint>();
if(attractionPoints.size() == 0) {
String poiString = "";
JSONArray allPOI = null;
......@@ -113,9 +115,7 @@ public class JSONAttractionGenerator implements IAttractionGenerator {
}
}
}
}
System.out.println(attractionPoints.size());
}
if(maxNumberOfAttractionPoints == 0) maxNumberOfAttractionPoints = Integer.MAX_VALUE;
List<AttractionPoint> result = new LinkedList<AttractionPoint>();
......
......@@ -25,30 +25,22 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.common.SimHostComponent;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tud.kom.p2psim.impl.topology.PositionVector;
import de.tud.kom.p2psim.impl.topology.movement.CsvMovement;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.ModularMovementModel;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction.AttractionPoint;
import de.tudarmstadt.maki.simonstrator.api.Randoms;
/**
* A {@link TransitionStrategy} for a case in which nodes (
* {@link MovementSupported}) are affiliated to an {@link AttractionPoint} only
* in the beginning. No further transition will take place.
*
* @author Nils Richerzhagen
* @version 1.0, 04.08.2014
* @author Martin Hellwig
* @version 1.0, 07.07.2015
*/
public class FixedAssignmentStrategy implements ITransitionStrategy {
private Random rnd;
private List<MovementSupported> comps = new LinkedList<MovementSupported>();
private List<AttractionPoint> aPoints = new LinkedList<AttractionPoint>();
......@@ -62,10 +54,6 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
private Map<String, AttractionPoint> mappingGroupIdAP = new LinkedHashMap<String, AttractionPoint>();
private Map<AttractionPoint, String> mappingAPGroupId = new LinkedHashMap<AttractionPoint, String>();
public FixedAssignmentStrategy() {
rnd = Randoms.getRandom(FixedAssignmentStrategy.class);
}
@Override
public Map<MovementSupported, AttractionPoint> getAssignments() {
......@@ -80,14 +68,13 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
@Override
public void addComponent(MovementSupported ms) {
comps.add(ms);
mappingHost(ms);
mappingHost(ms);
// No assignments been done before.
if (assignments.isEmpty()) {
AttractionPoint aPoint = aPoints.iterator().next();
assignments.put(ms, aPoint);
mappingGroupId(ms, aPoint);
setStartPosition(ms, aPoint.getRealPosition());
}
// GroupId is not mapped.
else if (!mappingGroupIdAP.containsKey(mappingMSHost.get(ms)
......@@ -96,7 +83,6 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
if (!mappingAPGroupId.containsKey(actAP)) {
assignments.put(ms, actAP);
mappingGroupId(ms, actAP);
setStartPosition(ms, actAP.getRealPosition());
break;
}
}
......@@ -107,7 +93,6 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
AttractionPoint aPoint = mappingGroupIdAP.get(mappingMSHost.get(ms)
.getProperties().getGroupID());
assignments.put(ms, aPoint);
setStartPosition(ms, aPoint.getRealPosition());
} else {
throw new Error("Should not happen.");
}
......@@ -137,21 +122,7 @@ public class FixedAssignmentStrategy implements ITransitionStrategy {
mappingGroupIdAP.put(
mappingMSHost.get(ms).getProperties().getGroupID(), AP);
}
private void setStartPosition(MovementSupported ms,
PositionVector aPointReferencePosition) {
double minJitter = 50.0;
double maxJitter = 100.0;
PositionVector nodePosition = ms.getRealPosition();
nodePosition.replace(aPointReferencePosition);
double xJitter = (rnd.nextDouble() * (maxJitter - minJitter)) + minJitter;
double yJitter = (rnd.nextDouble() * (maxJitter - minJitter)) + minJitter;
PositionVector jitterVector = new PositionVector(xJitter, yJitter);
nodePosition.add(jitterVector);
ms.positionChanged();
}
/**
* Used by the MobilityModel (M1) of the {@link ModularMovementModel} to get
* the groupId of the affiliated nodes to that {@link AttractionPoint}. Once
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment