RealWorldStreetsMovement.java 6.58 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 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;

23
import java.util.HashMap;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.Locale;

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;
	
51
52
	private static HashMap<Integer, RealWorldMovementPoints> movementPoints = new HashMap<>();
	
53
54
55
56
57
58
59
60
	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
61
62
	private double maxDistanceNextPoint; //This defines the maximum distance to the next point in line; 
										//if the distance is smaller than the given one, the node will choose the next point in the list
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	
	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 {
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
			//if not set already for this node or new destination is different than last one
			PointList pointList;
			if(!movementPoints.containsKey(comp.hashCode()) || destination.distanceTo(movementPoints.get(comp.hashCode()).getDestination()) > 1.0) {
				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 = rsp.getPoints();
				movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(comp.getRealPosition(), destination, pointList, 0));
			}
			else {
				pointList = movementPoints.get(comp.hashCode()).getPointList();
			}
102
			
103
104
			int actualIndex = movementPoints.get(comp.hashCode()).getActualIndex();
			int i = 0;
105
			for(GHPoint3D temp : pointList) {
106
107
108
109
110
111
112
				if(i==actualIndex) {
					PositionVector nextPoint = transformGPSWindowToOwnWorld(temp.getLat(), temp.getLon());
					newPosition = comp.getRealPosition().moveStep(nextPoint, getMovementSpeed(comp));
					
					if(nextPoint.distanceTo(comp.getRealPosition()) < maxDistanceNextPoint) actualIndex++;
				}
				i++;
113
114
			}
			
115
			movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(movementPoints.get(comp.hashCode()).getStart(), destination, pointList, actualIndex));
116
117
118
119
120
121
122
123
124
125
126
127
		}
		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];
128
		gps_coordinates[0] = latLeft + (latRight - latLeft) * (worldDimensions.getY() - y)/worldDimensions.getY();
129
130
131
132
133
134
135
136
137
138
139
140
		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);
141
		double y = worldDimensions.getY() - worldDimensions.getY() * (lat - latLeft)/(latRight - latLeft);
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
		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;
	}
176
177
178
179
	
	public void setMaxDistanceNextPoint(double maxDistanceNextPoint) {
		this.maxDistanceNextPoint = maxDistanceNextPoint;
	}
180
}