Commit 2d41efcd authored by Martin Hellwig's avatar Martin Hellwig Committed by Björn Richerzhagen
Browse files

Added MapQuest Service for retrieving map Images and Directions

parent 6bf1d748
/*
* 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.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint;
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.topology.movement.modularosm.GPSCalculation;
import de.tud.kom.p2psim.impl.util.Either;
import de.tud.kom.p2psim.impl.util.Left;
/**
* This movement strategy uses the data from MapQuest
*
* @author Martin Hellwig
* @version 1.0, 24.07.2015
*/
public class OnlineMapQuestMovement extends AbstractLocalMovementStrategy {
private PositionVector worldDimensions;
private static HashMap<Integer, RealWorldMovementPoints> movementPoints = new HashMap<>();
private String movementType; // {Fastest, Shortest, Pedestrian, Bicycle}
private String mapQuestKey;
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
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
public OnlineMapQuestMovement() {
this.worldDimensions = Topology.getWorldDimension();
latLeft = GPSCalculation.getLatLower();
latRight = GPSCalculation.getLatUpper();
lonLeft = GPSCalculation.getLonLeft();
lonRight = GPSCalculation.getLonRight();
}
public Either<PositionVector, Boolean> nextPosition(MovementSupported comp,
PositionVector destination) {
PositionVector newPosition = null;
if (destination.getDistance(comp.getRealPosition()) < getMovementSpeed(comp)) {
newPosition = destination.clone();
} else {
//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());
//Get Json data from page
String directionsString = "";
JSONArray allDirections = null;
InputStream in;
try {
String url = "http://www.mapquestapi.com/directions/v2/route?key=" + mapQuestKey + "&outFormat=json&routeType=" + movementType +
"&shapeFormat=raw&locale=de_DE&unit=k&from=" + startPosition[0] + "," + startPosition[1] + "&to=" +
destinationPosition[0] + "," + destinationPosition[1];
in = new URL(url).openStream();
directionsString = IOUtils.toString(in);
JSONObject directionsData = new JSONObject(directionsString);
allDirections = directionsData.getJSONObject("route").getJSONArray("legs").getJSONObject(0).getJSONArray("maneuvers");
} catch (JSONException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//read in all waypoints
pointList = new PointList();
if(allDirections != null) {
for(int i = 0; i < allDirections.length(); i++) {
try {
double lat = allDirections.getJSONObject(i).getJSONObject("startPoint").getDouble("lat");
double lon = allDirections.getJSONObject(i).getJSONObject("startPoint").getDouble("lng");
pointList.add(new GHPoint(lat, lon));
}
catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad
}
}
}
movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(comp.getRealPosition(), destination, pointList, 0));
}
else {
pointList = movementPoints.get(comp.hashCode()).getPointList();
}
int actualIndex = movementPoints.get(comp.hashCode()).getActualIndex();
int i = 0;
for(GHPoint3D temp : pointList) {
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++;
}
movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(movementPoints.get(comp.hashCode()).getStart(), destination, pointList, actualIndex));
}
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) * (worldDimensions.getY() - 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() - worldDimensions.getY() * (lat - latLeft)/(latRight - latLeft);
return new PositionVector(x, y);
}
public void setMovementType(String movementType) {
this.movementType = movementType;
}
public void setMaxDistanceNextPoint(double maxDistanceNextPoint) {
this.maxDistanceNextPoint = maxDistanceNextPoint;
}
public void setMapQuestKey(String mapQuestKey) {
this.mapQuestKey = mapQuestKey;
}
}
......@@ -28,6 +28,7 @@ import com.graphhopper.GHResponse;
import com.graphhopper.GraphHopper;
import com.graphhopper.routing.util.EncodingManager;
import com.graphhopper.util.PointList;
import com.graphhopper.util.shapes.GHPoint;
import com.graphhopper.util.shapes.GHPoint3D;
import de.tud.kom.p2psim.api.topology.movement.MovementSupported;
......@@ -98,8 +99,19 @@ public class RealWorldStreetsMovement extends AbstractLocalMovementStrategy {
setVehicle(movementType).
setLocale(Locale.GERMANY);
GHResponse rsp = hopper.route(req);
pointList = rsp.getPoints();
movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(comp.getRealPosition(), destination, pointList, 0));
//If the requested point is not in the map data, simple return the destination as next point
if(rsp.hasErrors()) {
System.err.println("Requested Points (" + startPosition[0] + ", " + startPosition[1]
+ ") or (" + destinationPosition[0] + ", " + destinationPosition[1] + ") are out of the bounding box.");
pointList = new PointList();
pointList.add(new GHPoint(destination.getLatitude(), destination.getLongitude()));
movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(comp.getRealPosition(), destination, pointList, 0));
}
else {
pointList = rsp.getPoints();
movementPoints.put(comp.hashCode(), new RealWorldMovementPoints(comp.getRealPosition(), destination, pointList, 0));
}
}
else {
pointList = movementPoints.get(comp.hashCode()).getPointList();
......
......@@ -20,8 +20,12 @@
package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
......@@ -51,6 +55,9 @@ public class OnlineJSONAttractionGenerator implements IAttractionGenerator {
private int maxNumberOfAttractionPoints;
private String placementJsonFile;
private String placementJsonPath;
private String amenity;
private double latLeft; //Values from -90 to 90; always smaller than latRight
private double latRight; //Values from -90 to 90
......@@ -88,35 +95,84 @@ public class OnlineJSONAttractionGenerator implements IAttractionGenerator {
@Override
public List<AttractionPoint> getAttractionPoints() {
if(attractionPoints.size() == 0) {
String poiString = "";
JSONArray allPOI = null;
InputStream in;
try {
in = new URL( "http://overpass-api.de/api/interpreter?data=%5Bout:json%5D;node%5Bamenity=" + amenity + "%5D%28" + latLeft + "%2C" + lonLeft + "%2C" + latRight + "%2C" + lonRight + "%29%3Bout%3B" ).openStream();
poiString = IOUtils.toString(in);
JSONObject poiData = new JSONObject(poiString);
allPOI = poiData.getJSONArray("elements");
} catch (JSONException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(allPOI != null) {
for(int i = 0; i < allPOI.length(); i++) {
try {
String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name");
double lat = allPOI.getJSONObject(i).getDouble("lat");
double lon = allPOI.getJSONObject(i).getDouble("lon");
if(lat > latLeft && lat < latRight &&
lon > lonLeft && lon < lonRight) attractionPoints.add(new AttractionPoint(transformGPSWindowToOwnWorld(lat, lon), barname));
placementJsonFile = placementJsonPath +
"pois" +
GPSCalculation.getLatCenter() +
GPSCalculation.getLonCenter() +
GPSCalculation.getZoom() +
amenity + ".json";
//Check if the file with same properties (same location) already exists
File f = new File(placementJsonFile);
if(!f.exists()) {
String poiString = "";
JSONArray allPOI = null;
InputStream in;
try {
in = new URL( "http://overpass-api.de/api/interpreter?data=%5Bout:json%5D;node%5Bamenity=" + amenity + "%5D%28" + latLeft + "%2C" + lonLeft + "%2C" + latRight + "%2C" + lonRight + "%29%3Bout%3B" ).openStream();
poiString = IOUtils.toString(in);
//Save the json data in file
PrintWriter out = new PrintWriter(placementJsonFile);
out.print(poiString);
out.close();
JSONObject poiData = new JSONObject(poiString);
allPOI = poiData.getJSONArray("elements");
} catch (JSONException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(allPOI != null) {
for(int i = 0; i < allPOI.length(); i++) {
try {
String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name");
double lat = allPOI.getJSONObject(i).getDouble("lat");
double lon = allPOI.getJSONObject(i).getDouble("lon");
if(lat > latLeft && lat < latRight &&
lon > lonLeft && lon < lonRight) {
attractionPoints.add(new AttractionPoint(transformGPSWindowToOwnWorld(lat, lon), barname));
}
}
catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad
}
}
catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad
}
}
else {
//File already exists, now we have to parse this file
String poiString = "";
JSONArray allPOI = null;
FileInputStream inputStream;
try {
inputStream = new FileInputStream(placementJsonFile);
poiString = IOUtils.toString(inputStream);
JSONObject poiData = new JSONObject(poiString);
allPOI = poiData.getJSONArray("elements");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
if(allPOI != null) {
for(int i = 0; i < allPOI.length(); i++) {
try {
String barname = allPOI.getJSONObject(i).getJSONObject("tags").getString("name");
double lat = allPOI.getJSONObject(i).getDouble("lat");
double lon = allPOI.getJSONObject(i).getDouble("lon");
attractionPoints.add(new AttractionPoint(transformGPSWindowToOwnWorld(lat, lon), barname));
}
catch (JSONException e) {
//This bar had no name defined, so there was an error. Not so bad
}
}
}
}
......@@ -133,4 +189,8 @@ public class OnlineJSONAttractionGenerator implements IAttractionGenerator {
public void setAmenity(String amenity) {
this.amenity = amenity;
}
public void setPlacementJsonPath(String placementJsonPath) {
this.placementJsonPath = placementJsonPath;
}
}
......@@ -61,7 +61,7 @@ public class ShowGoogleMapsMapViz extends JComponent implements IMapVisualizatio
//Check if the file with same properties (same location) already exists
File f = new File(tempImageFilePath);
if(!(f.exists() && !f.isDirectory())) {
if(!f.exists()) {
try {
String imageUrl = "http://maps.google.com/maps/api/staticmap?center=" +
GPSCalculation.getLatCenter() + "," +
......
/*
* 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.modularosm.mapvisualization;
import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import javax.swing.JComponent;
import de.tud.kom.p2psim.impl.topology.movement.modularosm.GPSCalculation;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
public class ShowMapQuestMapViz extends JComponent implements IMapVisualization{
private String tempImageFilePath;
private String mapType;
private String mapQuestKey;
private boolean initialized = false;
public ShowMapQuestMapViz() {
setBounds(0, 0, VisualizationInjector.WORLD_X, VisualizationInjector.WORLD_Y);
setOpaque(true);
setVisible(true);
}
private void initializeImage() {
if(!initialized) {
tempImageFilePath = tempImageFilePath +
"mapquest" +
GPSCalculation.getLatCenter() +
GPSCalculation.getLonCenter() +
GPSCalculation.getZoom() +
mapType + ".jpg";
//Check if the file with same properties (same location) already exists
File f = new File(tempImageFilePath);
if(!f.exists()) {
try {
String imageUrl = "http://www.mapquestapi.com/staticmap/v4/getmap?key=" + mapQuestKey + "&type=" + mapType + "&imagetype=jpeg&center=" +
GPSCalculation.getLatCenter() + "," +
GPSCalculation.getLonCenter() + "&zoom=" +
((GPSCalculation.getZoom())+1) + "&size=1000,1000";
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(tempImageFilePath);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
initialized = true;
}
}
@Override
public void paint(Graphics g) {
initializeImage();
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
Image imageToDraw = resize(Toolkit.getDefaultToolkit().getImage(tempImageFilePath), VisualizationInjector.WORLD_X, VisualizationInjector.WORLD_Y);
g2.drawImage(imageToDraw , 0, 0, this);
}
public void setTempImageFilePath(String tempImageFilePath) {
this.tempImageFilePath = tempImageFilePath;
}
public void setMapType(String mapType) {
this.mapType = mapType;
}
public void setMapQuestKey(String mapQuestKey) {
this.mapQuestKey = mapQuestKey;
}
/**
* Resizes the given image to the given width and height
*
* @param originalImage
* @param width
* @param height
*/
private Image resize(Image originalImage, int width, int height) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(originalImage, 0, 0, width, height, this);
g.dispose();
return resizedImage;
}
}
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