RealWorldStreetsMovement.java 5.69 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
23
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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
/*
 * 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;
	}
}