Improve arc memory management.
This commit is contained in:
parent
be1176c1e3
commit
98aba8dd06
45
src/main/org/insa/graph/Arc.java
Normal file
45
src/main/org/insa/graph/Arc.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package org.insa.graph;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface representing an arc in the graph - Arc is an interface and not a
|
||||||
|
* class to allow us to represent two-ways roads in a memory efficient manner
|
||||||
|
* (without having to duplicate attributes).
|
||||||
|
*
|
||||||
|
* @see ArcForward
|
||||||
|
* @see ArcBackward
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Arc {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Origin node of this arc.
|
||||||
|
*/
|
||||||
|
public Node getOrigin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Destination node of this arc.
|
||||||
|
*/
|
||||||
|
public Node getDestination();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Length of this arc, in meters.
|
||||||
|
*/
|
||||||
|
public int getLength();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Minimum time required to travel this arc, in seconds.
|
||||||
|
*/
|
||||||
|
public double getMinimumTravelTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Road information for this arc.
|
||||||
|
*/
|
||||||
|
public RoadInformation getRoadInformation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Points representing segments of this arc.
|
||||||
|
*/
|
||||||
|
public List<Point> getPoints();
|
||||||
|
}
|
61
src/main/org/insa/graph/ArcBackward.java
Normal file
61
src/main/org/insa/graph/ArcBackward.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package org.insa.graph;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Arc that represents a "backward" arc in a graph, i.e. an
|
||||||
|
* arc that is the reverse of another one. This arc only holds a reference to
|
||||||
|
* the original arc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ArcBackward implements Arc {
|
||||||
|
|
||||||
|
// Original arc
|
||||||
|
private final ArcForward originalArc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new backward arc which corresponds to the reverse arc of the given
|
||||||
|
* arc.
|
||||||
|
*
|
||||||
|
* @param originalArc
|
||||||
|
*/
|
||||||
|
public ArcBackward(ArcForward originalArc) {
|
||||||
|
this.originalArc = originalArc;
|
||||||
|
this.originalArc.getDestination().addSuccessor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getOrigin() {
|
||||||
|
return this.originalArc.getDestination();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getDestination() {
|
||||||
|
return this.originalArc.getOrigin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLength() {
|
||||||
|
return this.originalArc.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getMinimumTravelTime() {
|
||||||
|
return this.originalArc.getMinimumTravelTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RoadInformation getRoadInformation() {
|
||||||
|
return this.originalArc.getRoadInformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Point> getPoints() {
|
||||||
|
List<Point> pts = new ArrayList<>(this.originalArc.getPoints());
|
||||||
|
Collections.reverse(pts);
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Arc {
|
/**
|
||||||
|
* Implementation of Arc that represents a "forward" arc in a graph, this is the
|
||||||
|
* arc implementation that stores data relative to the arc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ArcForward implements Arc {
|
||||||
|
|
||||||
// Destination node.
|
// Destination node.
|
||||||
private final Node origin, destination;
|
private final Node origin, destination;
|
||||||
@ -27,7 +32,8 @@ public class Arc {
|
|||||||
* @param roadInformation Road information for this arc.
|
* @param roadInformation Road information for this arc.
|
||||||
* @param points Points representing this arc.
|
* @param points Points representing this arc.
|
||||||
*/
|
*/
|
||||||
public Arc(Node origin, Node dest, int length, RoadInformation roadInformation, ArrayList<Point> points) {
|
public ArcForward(Node origin, Node dest, int length, RoadInformation roadInformation,
|
||||||
|
ArrayList<Point> points) {
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.destination = dest;
|
this.destination = dest;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
@ -37,42 +43,42 @@ public class Arc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Origin node of this arc.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public Node getOrigin() {
|
public Node getOrigin() {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Destination node of this arc.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public Node getDestination() {
|
public Node getDestination() {
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Length of this arc, in meters.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Minimum time required to travel this arc, in seconds.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public double getMinimumTravelTime() {
|
public double getMinimumTravelTime() {
|
||||||
return getLength() * 3600.0 / (info.getMaximumSpeed() * 1000.0);
|
return getLength() * 3600.0 / (info.getMaximumSpeed() * 1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Road information for this arc.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public RoadInformation getRoadInformation() {
|
public RoadInformation getRoadInformation() {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Points representing segments of this arc.
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public List<Point> getPoints() {
|
public List<Point> getPoints() {
|
||||||
return Collections.unmodifiableList(points);
|
return Collections.unmodifiableList(points);
|
||||||
|
@ -59,7 +59,6 @@ public class Node implements Comparable<Node> {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -72,7 +71,6 @@ public class Node implements Comparable<Node> {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
|
||||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,21 +17,23 @@ public class Point {
|
|||||||
* @return Distance between the two given points, in meters.
|
* @return Distance between the two given points, in meters.
|
||||||
*/
|
*/
|
||||||
public static double distance(Point p1, Point p2) {
|
public static double distance(Point p1, Point p2) {
|
||||||
double sinLat = Math.sin(Math.toRadians(p1.getLatitude())) * Math.sin(Math.toRadians(p2.getLatitude()));
|
double sinLat = Math.sin(Math.toRadians(p1.getLatitude()))
|
||||||
double cosLat = Math.cos(Math.toRadians(p1.getLatitude())) * Math.cos(Math.toRadians(p2.getLatitude()));
|
* Math.sin(Math.toRadians(p2.getLatitude()));
|
||||||
|
double cosLat = Math.cos(Math.toRadians(p1.getLatitude()))
|
||||||
|
* Math.cos(Math.toRadians(p2.getLatitude()));
|
||||||
double cosLong = Math.cos(Math.toRadians(p2.getLongitude() - p1.getLongitude()));
|
double cosLong = Math.cos(Math.toRadians(p2.getLongitude() - p1.getLongitude()));
|
||||||
return EARTH_RADIUS * Math.acos(sinLat + cosLat * cosLong);
|
return EARTH_RADIUS * Math.acos(sinLat + cosLat * cosLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Longitude and latitude of the point.
|
// Longitude and latitude of the point.
|
||||||
private final double longitude, latitude;
|
private final float longitude, latitude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param longitude Longitude of the point, in degrees.
|
* @param longitude Longitude of the point, in degrees.
|
||||||
* @param latitude Latitude of the point, in degrees.
|
* @param latitude Latitude of the point, in degrees.
|
||||||
*/
|
*/
|
||||||
public Point(double longitude, double latitude) {
|
public Point(float longitude, float latitude) {
|
||||||
this.longitude = longitude;
|
this.longitude = longitude;
|
||||||
this.latitude = latitude;
|
this.latitude = latitude;
|
||||||
}
|
}
|
||||||
@ -39,14 +41,14 @@ public class Point {
|
|||||||
/**
|
/**
|
||||||
* @return Longitude of this point (in degrees).
|
* @return Longitude of this point (in degrees).
|
||||||
*/
|
*/
|
||||||
public double getLongitude() {
|
public float getLongitude() {
|
||||||
return longitude;
|
return longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Latitude of this point (in degrees).
|
* @return Latitude of this point (in degrees).
|
||||||
*/
|
*/
|
||||||
public double getLatitude() {
|
public float getLatitude() {
|
||||||
return latitude;
|
return latitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +65,6 @@ public class Point {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,7 +45,8 @@ public class RoadInformation {
|
|||||||
// Name of the road.
|
// Name of the road.
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public RoadInformation(RoadType roadType, AccessRestrictions access, boolean isOneWay, int maxSpeed, String name) {
|
public RoadInformation(RoadType roadType, AccessRestrictions access, boolean isOneWay,
|
||||||
|
int maxSpeed, String name) {
|
||||||
this.type = roadType;
|
this.type = roadType;
|
||||||
this.access = access;
|
this.access = access;
|
||||||
this.oneway = isOneWay;
|
this.oneway = isOneWay;
|
||||||
@ -53,8 +54,6 @@ public class RoadInformation {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access information
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this is a private road.
|
* @return true if this is a private road.
|
||||||
*/
|
*/
|
||||||
@ -92,7 +91,6 @@ public class RoadInformation {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -104,7 +102,8 @@ public class RoadInformation {
|
|||||||
if (getType() == RoadType.MOTORWAY) {
|
if (getType() == RoadType.MOTORWAY) {
|
||||||
typeAsString = "highway";
|
typeAsString = "highway";
|
||||||
}
|
}
|
||||||
return typeAsString + " : " + getName() + " " + (isOneWay() ? " (oneway) " : "") + maxSpeed + " km/h (max.)";
|
return typeAsString + " : " + getName() + " " + (isOneWay() ? " (oneway) " : "") + maxSpeed
|
||||||
|
+ " km/h (max.)";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ package org.insa.graph.io;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
|
||||||
import org.insa.graph.AccessRestrictions;
|
import org.insa.graph.AccessRestrictions;
|
||||||
import org.insa.graph.AccessRestrictions.AccessMode;
|
import org.insa.graph.AccessRestrictions.AccessMode;
|
||||||
import org.insa.graph.AccessRestrictions.AccessRestriction;
|
import org.insa.graph.AccessRestrictions.AccessRestriction;
|
||||||
import org.insa.graph.Arc;
|
import org.insa.graph.ArcForward;
|
||||||
|
import org.insa.graph.ArcBackward;
|
||||||
import org.insa.graph.Graph;
|
import org.insa.graph.Graph;
|
||||||
import org.insa.graph.GraphInformation;
|
import org.insa.graph.GraphInformation;
|
||||||
import org.insa.graph.Node;
|
import org.insa.graph.Node;
|
||||||
@ -41,16 +41,17 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
// the order correspond to the 4 bits value (i.e. FORBIDDEN is 0 or PRIVATE is
|
// the order correspond to the 4 bits value (i.e. FORBIDDEN is 0 or PRIVATE is
|
||||||
// 2) - UKNOWN is not included because value above 6 (FORESTRY) are all
|
// 2) - UKNOWN is not included because value above 6 (FORESTRY) are all
|
||||||
// considered unknown.
|
// considered unknown.
|
||||||
final AccessRestriction[] allRestrictions = new AccessRestriction[] { AccessRestriction.FORBIDDEN,
|
final AccessRestriction[] allRestrictions = new AccessRestriction[]{
|
||||||
AccessRestriction.ALLOWED, AccessRestriction.PRIVATE, AccessRestriction.DESTINATION,
|
AccessRestriction.FORBIDDEN, AccessRestriction.ALLOWED, AccessRestriction.PRIVATE,
|
||||||
AccessRestriction.DELIVERY, AccessRestriction.CUSTOMERS, AccessRestriction.FORESTRY };
|
AccessRestriction.DESTINATION, AccessRestriction.DELIVERY,
|
||||||
|
AccessRestriction.CUSTOMERS, AccessRestriction.FORESTRY };
|
||||||
|
|
||||||
// The order of values inside this array is VERY IMPORTANT: The order is such
|
// The order of values inside this array is VERY IMPORTANT: The order is such
|
||||||
// that each 4-bits group of the long value is processed in the correct order,
|
// that each 4-bits group of the long value is processed in the correct order,
|
||||||
// i.e. FOOT is processed first (4 lowest bits), and so on.
|
// i.e. FOOT is processed first (4 lowest bits), and so on.
|
||||||
final AccessMode[] allModes = new AccessMode[] { AccessMode.FOOT, null, AccessMode.BICYCLE,
|
final AccessMode[] allModes = new AccessMode[]{ AccessMode.FOOT, null, AccessMode.BICYCLE,
|
||||||
AccessMode.SMALL_MOTORCYCLE, AccessMode.AGRICULTURAL, AccessMode.MOTORCYCLE, AccessMode.MOTORCAR,
|
AccessMode.SMALL_MOTORCYCLE, AccessMode.AGRICULTURAL, AccessMode.MOTORCYCLE,
|
||||||
AccessMode.HEAVY_GOODS, null, AccessMode.PUBLIC_TRANSPORT };
|
AccessMode.MOTORCAR, AccessMode.HEAVY_GOODS, null, AccessMode.PUBLIC_TRANSPORT };
|
||||||
|
|
||||||
// fill maps...
|
// fill maps...
|
||||||
EnumMap<AccessMode, AccessRestriction> restrictions = new EnumMap<>(AccessMode.class);
|
EnumMap<AccessMode, AccessRestriction> restrictions = new EnumMap<>(AccessMode.class);
|
||||||
@ -69,7 +70,7 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
copyAccess = copyAccess >> 4;
|
copyAccess = copyAccess >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AccessRestrictions(restrictions, access);
|
return new AccessRestrictions(restrictions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,7 +229,8 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
float dlon = (dis.readShort()) / 2.0e5f;
|
float dlon = (dis.readShort()) / 2.0e5f;
|
||||||
float dlat = (dis.readShort()) / 2.0e5f;
|
float dlat = (dis.readShort()) / 2.0e5f;
|
||||||
|
|
||||||
points.add(new Point(lastPoint.getLongitude() + dlon, lastPoint.getLatitude() + dlat));
|
points.add(new Point(lastPoint.getLongitude() + dlon,
|
||||||
|
lastPoint.getLatitude() + dlat));
|
||||||
}
|
}
|
||||||
|
|
||||||
points.add(nodes.get(destNode).getPoint());
|
points.add(nodes.get(destNode).getPoint());
|
||||||
@ -238,14 +240,15 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
Node dest = nodes.get(destNode);
|
Node dest = nodes.get(destNode);
|
||||||
|
|
||||||
// Add successor to initial arc.
|
// Add successor to initial arc.
|
||||||
Arc arc = new Arc(orig, dest, length, info, points);
|
ArcForward arc = new ArcForward(orig, dest, length, info, points);
|
||||||
|
|
||||||
// And reverse arc if its a two-way road.
|
// And reverse arc if its a two-way road.
|
||||||
if (!info.isOneWay()) {
|
if (!info.isOneWay()) {
|
||||||
// Add without segments.
|
// Add without segments.
|
||||||
ArrayList<Point> rPoints = new ArrayList<Point>(points);
|
// ArrayList<Point> rPoints = new ArrayList<Point>(points);
|
||||||
Collections.reverse(rPoints);
|
// Collections.reverse(rPoints);
|
||||||
new Arc(dest, orig, length, info, rPoints);
|
// new Arc(dest, orig, length, info, null);
|
||||||
|
new ArcBackward(arc);
|
||||||
}
|
}
|
||||||
observers.forEach((observer) -> observer.notifyNewArcRead(arc));
|
observers.forEach((observer) -> observer.notifyNewArcRead(arc));
|
||||||
}
|
}
|
||||||
@ -273,7 +276,12 @@ public class BinaryGraphReaderInsa2018 extends BinaryReader implements GraphRead
|
|||||||
if (getCurrentVersion() >= 7) {
|
if (getCurrentVersion() >= 7) {
|
||||||
access = toAccessInformationV7(dis.readLong());
|
access = toAccessInformationV7(dis.readLong());
|
||||||
}
|
}
|
||||||
return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5, dis.readUTF());
|
else if (getCurrentVersion() >= 6) {
|
||||||
|
// TODO: Try to create something...
|
||||||
|
dis.readUnsignedShort();
|
||||||
|
}
|
||||||
|
return new RoadInformation(toRoadType(type), access, (x & 0x80) > 0, (x & 0x7F) * 5,
|
||||||
|
dis.readUTF());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
import org.insa.graph.ArcForward;
|
||||||
import org.insa.graph.Arc;
|
import org.insa.graph.Arc;
|
||||||
import org.insa.graph.Graph;
|
import org.insa.graph.Graph;
|
||||||
import org.insa.graph.Node;
|
import org.insa.graph.Node;
|
||||||
@ -132,8 +133,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
int px = BasicDrawing.this.projx(getPoint().getLongitude());
|
int px = BasicDrawing.this.projx(getPoint().getLongitude());
|
||||||
int py = BasicDrawing.this.projy(getPoint().getLatitude());
|
int py = BasicDrawing.this.projy(getPoint().getLatitude());
|
||||||
|
|
||||||
graphics.drawImage(this.image, px - MARKER_WIDTH / 2, py - MARKER_HEIGHT, MARKER_WIDTH, MARKER_HEIGHT,
|
graphics.drawImage(this.image, px - MARKER_WIDTH / 2, py - MARKER_HEIGHT, MARKER_WIDTH,
|
||||||
BasicDrawing.this);
|
MARKER_HEIGHT, BasicDrawing.this);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -282,7 +283,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
private Graphics2D graphGraphics = null;
|
private Graphics2D graphGraphics = null;
|
||||||
|
|
||||||
// List of image for markers
|
// List of image for markers
|
||||||
private List<BasicOverlay> overlays = Collections.synchronizedList(new ArrayList<BasicOverlay>());
|
private List<BasicOverlay> overlays = Collections
|
||||||
|
.synchronizedList(new ArrayList<BasicOverlay>());
|
||||||
|
|
||||||
// Mapping DrawingClickListener -> MouseEventListener
|
// Mapping DrawingClickListener -> MouseEventListener
|
||||||
private List<DrawingClickListener> drawingClickListeners = new ArrayList<>();
|
private List<DrawingClickListener> drawingClickListeners = new ArrayList<>();
|
||||||
@ -295,11 +297,13 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public BasicDrawing() {
|
public BasicDrawing() {
|
||||||
this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
|
this.zoomAndPanListener = new ZoomAndPanListener(this,
|
||||||
|
ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
|
||||||
|
|
||||||
// Try...
|
// Try...
|
||||||
try {
|
try {
|
||||||
this.zoomControls = new MapZoomControls(this, 0, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20);
|
this.zoomControls = new MapZoomControls(this, 0,
|
||||||
|
ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20);
|
||||||
this.zoomControls.addZoomInListener(new ActionListener() {
|
this.zoomControls.addZoomInListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
@ -394,7 +398,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
// Get the point using the inverse transform of the Zoom/Pan object, this gives
|
// Get the point using the inverse transform of the Zoom/Pan object, this gives
|
||||||
// us
|
// us
|
||||||
// a point within the drawing box (between [0, 0] and [width, height]).
|
// a point within the drawing box (between [0, 0] and [width, height]).
|
||||||
Point2D ptDst = this.zoomAndPanListener.getCoordTransform().inverseTransform(event.getPoint(), null);
|
Point2D ptDst = this.zoomAndPanListener.getCoordTransform()
|
||||||
|
.inverseTransform(event.getPoint(), null);
|
||||||
|
|
||||||
// Inverse the "projection" on x/y to get longitude and latitude.
|
// Inverse the "projection" on x/y to get longitude and latitude.
|
||||||
double lon = ptDst.getX();
|
double lon = ptDst.getX();
|
||||||
@ -403,7 +408,7 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
lat = (1 - lat / this.height) * (this.lat2 - this.lat1) + this.lat1;
|
lat = (1 - lat / this.height) * (this.lat2 - this.lat1) + this.lat1;
|
||||||
|
|
||||||
// Return a new point.
|
// Return a new point.
|
||||||
return new Point(lon, lat);
|
return new Point((float) lon, (float) lat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -463,7 +468,7 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
* @param palette Palette to use to retrieve color and width for arc, or null to
|
* @param palette Palette to use to retrieve color and width for arc, or null to
|
||||||
* use current settings.
|
* use current settings.
|
||||||
*/
|
*/
|
||||||
protected void drawArc(Arc arc, GraphPalette palette, boolean repaint) {
|
protected void drawArc(ArcForward arc, GraphPalette palette, boolean repaint) {
|
||||||
List<Point> pts = arc.getPoints();
|
List<Point> pts = arc.getPoints();
|
||||||
if (!pts.isEmpty()) {
|
if (!pts.isEmpty()) {
|
||||||
if (palette != null) {
|
if (palette != null) {
|
||||||
@ -500,8 +505,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
// Find minimum/maximum longitude and latitude.
|
// Find minimum/maximum longitude and latitude.
|
||||||
double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, maxLon = Double.NEGATIVE_INFINITY,
|
double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY,
|
||||||
maxLat = Double.NEGATIVE_INFINITY;
|
maxLon = Double.NEGATIVE_INFINITY, maxLat = Double.NEGATIVE_INFINITY;
|
||||||
for (Node node: graph.getNodes()) {
|
for (Node node: graph.getNodes()) {
|
||||||
Point pt = node.getPoint();
|
Point pt = node.getPoint();
|
||||||
if (pt.getLatitude() < minLat) {
|
if (pt.getLatitude() < minLat) {
|
||||||
@ -539,7 +544,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the image
|
// Create the image
|
||||||
BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
|
BufferedImage img = new BufferedImage(this.width, this.height,
|
||||||
|
BufferedImage.TYPE_3BYTE_BGR);
|
||||||
this.graphImage = img;
|
this.graphImage = img;
|
||||||
this.graphGraphics = img.createGraphics();
|
this.graphGraphics = img.createGraphics();
|
||||||
this.graphGraphics.setBackground(Color.WHITE);
|
this.graphGraphics.setBackground(Color.WHITE);
|
||||||
@ -547,10 +553,12 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
|
|
||||||
// Set the zoom and pan listener
|
// Set the zoom and pan listener
|
||||||
|
|
||||||
double scale = 1 / Math.max(this.width / (double) this.getWidth(), this.height / (double) this.getHeight());
|
double scale = 1 / Math.max(this.width / (double) this.getWidth(),
|
||||||
|
this.height / (double) this.getHeight());
|
||||||
|
|
||||||
this.zoomAndPanListener.setCoordTransform(this.graphGraphics.getTransform());
|
this.zoomAndPanListener.setCoordTransform(this.graphGraphics.getTransform());
|
||||||
this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2,
|
this.zoomAndPanListener.getCoordTransform().translate(
|
||||||
|
(this.getWidth() - this.width * scale) / 2,
|
||||||
(this.getHeight() - this.height * scale) / 2);
|
(this.getHeight() - this.height * scale) / 2);
|
||||||
this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
|
this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
|
||||||
this.zoomAndPanListener.setZoomLevel(0);
|
this.zoomAndPanListener.setZoomLevel(0);
|
||||||
@ -575,8 +583,8 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
|
|
||||||
for (Node node: graph.getNodes()) {
|
for (Node node: graph.getNodes()) {
|
||||||
for (Arc arc: node.getSuccessors()) {
|
for (Arc arc: node.getSuccessors()) {
|
||||||
if (arc.getRoadInformation().isOneWay() || arc.getOrigin().compareTo(arc.getDestination()) < 0) {
|
if (arc instanceof ArcForward) { // draw only "true" arcs
|
||||||
drawArc(arc, palette, false);
|
drawArc((ArcForward) arc, palette, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.getId() % repaintModulo == 0) {
|
if (node.getId() % repaintModulo == 0) {
|
||||||
|
@ -22,7 +22,7 @@ public class PathTest {
|
|||||||
|
|
||||||
// List of arcs in the graph, a2b is the arc from node A (0) to B (1).
|
// List of arcs in the graph, a2b is the arc from node A (0) to B (1).
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static Arc a2b, a2c, a2e, b2c, c2d_1, c2d_2, c2d_3, c2a, d2a, d2e, e2d;
|
private static ArcForward a2b, a2c, a2e, b2c, c2d_1, c2d_2, c2d_3, c2a, d2a, d2e, e2d;
|
||||||
|
|
||||||
// Some paths...
|
// Some paths...
|
||||||
private static Path emptyPath, shortPath, longPath, loopPath, longLoopPath, invalidPath;
|
private static Path emptyPath, shortPath, longPath, loopPath, longLoopPath, invalidPath;
|
||||||
@ -41,25 +41,26 @@ public class PathTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add arcs...
|
// Add arcs...
|
||||||
a2b = new Arc(nodes[0], nodes[1], 10, speed10, null);
|
a2b = new ArcForward(nodes[0], nodes[1], 10, speed10, null);
|
||||||
a2c = new Arc(nodes[0], nodes[2], 15, speed10, null);
|
a2c = new ArcForward(nodes[0], nodes[2], 15, speed10, null);
|
||||||
a2e = new Arc(nodes[0], nodes[4], 15, speed20, null);
|
a2e = new ArcForward(nodes[0], nodes[4], 15, speed20, null);
|
||||||
b2c = new Arc(nodes[1], nodes[2], 10, speed10, null);
|
b2c = new ArcForward(nodes[1], nodes[2], 10, speed10, null);
|
||||||
c2d_1 = new Arc(nodes[2], nodes[3], 20, speed10, null);
|
c2d_1 = new ArcForward(nodes[2], nodes[3], 20, speed10, null);
|
||||||
c2d_2 = new Arc(nodes[2], nodes[3], 10, speed10, null);
|
c2d_2 = new ArcForward(nodes[2], nodes[3], 10, speed10, null);
|
||||||
c2d_3 = new Arc(nodes[2], nodes[3], 15, speed20, null);
|
c2d_3 = new ArcForward(nodes[2], nodes[3], 15, speed20, null);
|
||||||
d2a = new Arc(nodes[3], nodes[0], 15, speed10, null);
|
d2a = new ArcForward(nodes[3], nodes[0], 15, speed10, null);
|
||||||
d2e = new Arc(nodes[3], nodes[4], 20, speed20, null);
|
d2e = new ArcForward(nodes[3], nodes[4], 20, speed20, null);
|
||||||
e2d = new Arc(nodes[4], nodes[0], 10, speed10, null);
|
e2d = new ArcForward(nodes[4], nodes[0], 10, speed10, null);
|
||||||
|
|
||||||
graph = new Graph("ID", "", Arrays.asList(nodes), null);
|
graph = new Graph("ID", "", Arrays.asList(nodes), null);
|
||||||
|
|
||||||
emptyPath = new Path(graph, new ArrayList<Arc>());
|
emptyPath = new Path(graph, new ArrayList<Arc>());
|
||||||
shortPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1 }));
|
shortPath = new Path(graph, Arrays.asList(new ArcForward[]{ a2b, b2c, c2d_1 }));
|
||||||
longPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2e }));
|
longPath = new Path(graph, Arrays.asList(new ArcForward[]{ a2b, b2c, c2d_1, d2e }));
|
||||||
loopPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2a }));
|
loopPath = new Path(graph, Arrays.asList(new ArcForward[]{ a2b, b2c, c2d_1, d2a }));
|
||||||
longLoopPath = new Path(graph, Arrays.asList(new Arc[] { a2b, b2c, c2d_1, d2a, a2c, c2d_3, d2a, a2b, b2c }));
|
longLoopPath = new Path(graph,
|
||||||
invalidPath = new Path(graph, Arrays.asList(new Arc[] { a2b, c2d_1, d2e }));
|
Arrays.asList(new ArcForward[]{ a2b, b2c, c2d_1, d2a, a2c, c2d_3, d2a, a2b, b2c }));
|
||||||
|
invalidPath = new Path(graph, Arrays.asList(new ArcForward[]{ a2b, c2d_1, d2e }));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +122,12 @@ public class PathTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateFastestPathFromNodes() {
|
public void testCreateFastestPathFromNodes() {
|
||||||
Path path;
|
Path path;
|
||||||
Arc[] expected;
|
ArcForward[] expected;
|
||||||
|
|
||||||
// Simple construction
|
// Simple construction
|
||||||
path = Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2] }));
|
path = Path.createFastestPathFromNodes(graph,
|
||||||
expected = new Arc[] { a2b, b2c };
|
Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2] }));
|
||||||
|
expected = new ArcForward[]{ a2b, b2c };
|
||||||
assertEquals(expected.length, path.getArcs().size());
|
assertEquals(expected.length, path.getArcs().size());
|
||||||
for (int i = 0; i < expected.length; ++i) {
|
for (int i = 0; i < expected.length; ++i) {
|
||||||
assertEquals(expected[i], path.getArcs().get(i));
|
assertEquals(expected[i], path.getArcs().get(i));
|
||||||
@ -133,8 +135,8 @@ public class PathTest {
|
|||||||
|
|
||||||
// Not so simple construction
|
// Not so simple construction
|
||||||
path = Path.createFastestPathFromNodes(graph,
|
path = Path.createFastestPathFromNodes(graph,
|
||||||
Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2], nodes[3] }));
|
Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2], nodes[3] }));
|
||||||
expected = new Arc[] { a2b, b2c, c2d_3 };
|
expected = new ArcForward[]{ a2b, b2c, c2d_3 };
|
||||||
assertEquals(expected.length, path.getArcs().size());
|
assertEquals(expected.length, path.getArcs().size());
|
||||||
for (int i = 0; i < expected.length; ++i) {
|
for (int i = 0; i < expected.length; ++i) {
|
||||||
assertEquals(expected[i], path.getArcs().get(i));
|
assertEquals(expected[i], path.getArcs().get(i));
|
||||||
@ -144,11 +146,12 @@ public class PathTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateShortestPathFromNodes() {
|
public void testCreateShortestPathFromNodes() {
|
||||||
Path path;
|
Path path;
|
||||||
Arc[] expected;
|
ArcForward[] expected;
|
||||||
|
|
||||||
// Simple construction
|
// Simple construction
|
||||||
path = Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2] }));
|
path = Path.createShortestPathFromNodes(graph,
|
||||||
expected = new Arc[] { a2b, b2c };
|
Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2] }));
|
||||||
|
expected = new ArcForward[]{ a2b, b2c };
|
||||||
assertEquals(expected.length, path.getArcs().size());
|
assertEquals(expected.length, path.getArcs().size());
|
||||||
for (int i = 0; i < expected.length; ++i) {
|
for (int i = 0; i < expected.length; ++i) {
|
||||||
assertEquals(expected[i], path.getArcs().get(i));
|
assertEquals(expected[i], path.getArcs().get(i));
|
||||||
@ -156,8 +159,8 @@ public class PathTest {
|
|||||||
|
|
||||||
// Not so simple construction
|
// Not so simple construction
|
||||||
path = Path.createShortestPathFromNodes(graph,
|
path = Path.createShortestPathFromNodes(graph,
|
||||||
Arrays.asList(new Node[] { nodes[0], nodes[1], nodes[2], nodes[3] }));
|
Arrays.asList(new Node[]{ nodes[0], nodes[1], nodes[2], nodes[3] }));
|
||||||
expected = new Arc[] { a2b, b2c, c2d_2 };
|
expected = new ArcForward[]{ a2b, b2c, c2d_2 };
|
||||||
assertEquals(expected.length, path.getArcs().size());
|
assertEquals(expected.length, path.getArcs().size());
|
||||||
for (int i = 0; i < expected.length; ++i) {
|
for (int i = 0; i < expected.length; ++i) {
|
||||||
assertEquals(expected[i], path.getArcs().get(i));
|
assertEquals(expected[i], path.getArcs().get(i));
|
||||||
@ -166,12 +169,12 @@ public class PathTest {
|
|||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testCreateFastestPathFromNodesException() {
|
public void testCreateFastestPathFromNodesException() {
|
||||||
Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[1], nodes[0] }));
|
Path.createFastestPathFromNodes(graph, Arrays.asList(new Node[]{ nodes[1], nodes[0] }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testCreateShortestPathFromNodesException() {
|
public void testCreateShortestPathFromNodesException() {
|
||||||
Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[] { nodes[1], nodes[0] }));
|
Path.createShortestPathFromNodes(graph, Arrays.asList(new Node[]{ nodes[1], nodes[0] }));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user