Clean code.
This commit is contained in:
parent
84f01ce47e
commit
094a2331af
@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
package org.insa.algo.datastructures;
|
package org.insa.algo.datastructures;
|
||||||
|
|
||||||
import java.util.* ;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a binary heap.
|
* Implements a binary heap. Note that all "matching" is based on the compareTo
|
||||||
* Note that all "matching" is based on the compareTo method.
|
* method.
|
||||||
|
*
|
||||||
* @author Mark Allen Weiss
|
* @author Mark Allen Weiss
|
||||||
* @author DLB
|
* @author DLB
|
||||||
*/
|
*/
|
||||||
@ -30,105 +31,115 @@ public class BinaryHeap<E extends Comparable<E>> {
|
|||||||
*/
|
*/
|
||||||
public BinaryHeap() {
|
public BinaryHeap() {
|
||||||
this.currentSize = 0;
|
this.currentSize = 0;
|
||||||
this.array = new ArrayList<E>() ;
|
this.array = new ArrayList<E>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor used for debug.
|
// Constructor used for debug.
|
||||||
public BinaryHeap(BinaryHeap<E> heap) {
|
public BinaryHeap(BinaryHeap<E> heap) {
|
||||||
this.currentSize = heap.currentSize ;
|
this.currentSize = heap.currentSize;
|
||||||
this.array = new ArrayList<E>(heap.array) ;
|
this.array = new ArrayList<E>(heap.array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets an element in the array
|
// Sets an element in the array
|
||||||
private void arraySet(int index, E value) {
|
private void arraySet(int index, E value) {
|
||||||
if (index == this.array.size()) {
|
if (index == this.array.size()) {
|
||||||
this.array.add(value) ;
|
this.array.add(value);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.array.set(index, value) ;
|
this.array.set(index, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the heap is logically empty.
|
* Test if the heap is logically empty.
|
||||||
|
*
|
||||||
* @return true if empty, false otherwise.
|
* @return true if empty, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty() { return this.currentSize == 0; }
|
public boolean isEmpty() {
|
||||||
|
return this.currentSize == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns size.
|
* Returns size.
|
||||||
|
*
|
||||||
* @return current size.
|
* @return current size.
|
||||||
*/
|
*/
|
||||||
public int size() { return this.currentSize; }
|
public int size() {
|
||||||
|
return this.currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns index of parent.
|
* Returns index of parent.
|
||||||
*/
|
*/
|
||||||
private int index_parent(int index) {
|
private int index_parent(int index) {
|
||||||
return (index - 1) / 2 ;
|
return (index - 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns index of left child.
|
* Returns index of left child.
|
||||||
*/
|
*/
|
||||||
private int index_left(int index) {
|
private int index_left(int index) {
|
||||||
return index * 2 + 1 ;
|
return index * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert into the heap.
|
* Insert into the heap.
|
||||||
|
*
|
||||||
* @param x the item to insert.
|
* @param x the item to insert.
|
||||||
*/
|
*/
|
||||||
public void insert(E x) {
|
public void insert(E x) {
|
||||||
int index = this.currentSize++ ;
|
int index = this.currentSize++;
|
||||||
this.arraySet(index, x) ;
|
this.arraySet(index, x);
|
||||||
this.percolateUp(index) ;
|
this.percolateUp(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method to percolate up in the heap.
|
* Internal method to percolate up in the heap.
|
||||||
|
*
|
||||||
* @param index the index at which the percolate begins.
|
* @param index the index at which the percolate begins.
|
||||||
*/
|
*/
|
||||||
private void percolateUp(int index) {
|
private void percolateUp(int index) {
|
||||||
E x = this.array.get(index) ;
|
E x = this.array.get(index);
|
||||||
|
|
||||||
for( ; index > 0 && x.compareTo(this.array.get(index_parent(index)) ) < 0; index = index_parent(index) ) {
|
for (; index > 0
|
||||||
E moving_val = this.array.get(index_parent(index)) ;
|
&& x.compareTo(this.array.get(index_parent(index))) < 0; index = index_parent(
|
||||||
this.arraySet(index, moving_val) ;
|
index)) {
|
||||||
|
E moving_val = this.array.get(index_parent(index));
|
||||||
|
this.arraySet(index, moving_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.arraySet(index, x) ;
|
this.arraySet(index, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method to percolate down in the heap.
|
* Internal method to percolate down in the heap.
|
||||||
|
*
|
||||||
* @param index the index at which the percolate begins.
|
* @param index the index at which the percolate begins.
|
||||||
*/
|
*/
|
||||||
private void percolateDown(int index) {
|
private void percolateDown(int index) {
|
||||||
int ileft = index_left(index) ;
|
int ileft = index_left(index);
|
||||||
int iright = ileft + 1 ;
|
int iright = ileft + 1;
|
||||||
|
|
||||||
if (ileft < this.currentSize) {
|
if (ileft < this.currentSize) {
|
||||||
E current = this.array.get(index) ;
|
E current = this.array.get(index);
|
||||||
E left = this.array.get(ileft) ;
|
E left = this.array.get(ileft);
|
||||||
boolean hasRight = iright < this.currentSize ;
|
boolean hasRight = iright < this.currentSize;
|
||||||
E right = (hasRight)?this.array.get(iright):null ;
|
E right = (hasRight) ? this.array.get(iright) : null;
|
||||||
|
|
||||||
if (!hasRight || left.compareTo(right) < 0) {
|
if (!hasRight || left.compareTo(right) < 0) {
|
||||||
// Left is smaller
|
// Left is smaller
|
||||||
if (left.compareTo(current) < 0) {
|
if (left.compareTo(current) < 0) {
|
||||||
this.arraySet(index, left) ;
|
this.arraySet(index, left);
|
||||||
this.arraySet(ileft, current) ;
|
this.arraySet(ileft, current);
|
||||||
this.percolateDown( ileft ) ;
|
this.percolateDown(ileft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Right is smaller
|
// Right is smaller
|
||||||
if (right.compareTo(current) < 0) {
|
if (right.compareTo(current) < 0) {
|
||||||
this.arraySet(index, right) ;
|
this.arraySet(index, right);
|
||||||
this.arraySet(iright, current) ;
|
this.arraySet(iright, current);
|
||||||
this.percolateDown( iright ) ;
|
this.percolateDown(iright);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,25 +147,29 @@ public class BinaryHeap<E extends Comparable<E>> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the smallest item in the heap.
|
* Find the smallest item in the heap.
|
||||||
* @return the smallest item.
|
*
|
||||||
* @throws Exception if empty.
|
* @return the smallest item in the heap.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException if this heap is empty.
|
||||||
*/
|
*/
|
||||||
public E findMin( ) {
|
public E findMin() throws RuntimeException {
|
||||||
if( isEmpty() )
|
if (isEmpty())
|
||||||
throw new RuntimeException( "Empty binary heap" );
|
throw new RuntimeException("Empty binary heap");
|
||||||
return this.array.get(0);
|
return this.array.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the smallest item from the heap.
|
* Remove the smallest item from the heap.
|
||||||
* @return the smallest item.
|
*
|
||||||
* @throws Exception if empty.
|
* @return the smallest item in the heap.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException if this heap is empty.
|
||||||
*/
|
*/
|
||||||
public E deleteMin( ) {
|
public E deleteMin() throws RuntimeException {
|
||||||
E minItem = findMin( );
|
E minItem = findMin();
|
||||||
E lastItem = this.array.get(--this.currentSize) ;
|
E lastItem = this.array.get(--this.currentSize);
|
||||||
this.arraySet(0, lastItem) ;
|
this.arraySet(0, lastItem);
|
||||||
this.percolateDown( 0 );
|
this.percolateDown(0);
|
||||||
return minItem;
|
return minItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,17 +177,17 @@ public class BinaryHeap<E extends Comparable<E>> {
|
|||||||
* Prints the heap
|
* Prints the heap
|
||||||
*/
|
*/
|
||||||
public void print() {
|
public void print() {
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
System.out.println("======== HEAP (size = " + this.currentSize + ") ========") ;
|
System.out.println("======== HEAP (size = " + this.currentSize + ") ========");
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
|
|
||||||
for (int i = 0 ; i < this.currentSize ; i++) {
|
for (int i = 0; i < this.currentSize; i++) {
|
||||||
System.out.println(this.array.get(i).toString()) ;
|
System.out.println(this.array.get(i).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
System.out.println("-------- End of heap --------") ;
|
System.out.println("-------- End of heap --------");
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,73 +195,19 @@ public class BinaryHeap<E extends Comparable<E>> {
|
|||||||
*/
|
*/
|
||||||
public void printSorted() {
|
public void printSorted() {
|
||||||
|
|
||||||
BinaryHeap<E> copy = new BinaryHeap<E>(this) ;
|
BinaryHeap<E> copy = new BinaryHeap<E>(this);
|
||||||
|
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
System.out.println("======== Sorted HEAP (size = " + this.currentSize + ") ========") ;
|
System.out.println("======== Sorted HEAP (size = " + this.currentSize + ") ========");
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
|
|
||||||
while (!copy.isEmpty()) {
|
while (!copy.isEmpty()) {
|
||||||
System.out.println(copy.deleteMin()) ;
|
System.out.println(copy.deleteMin());
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
System.out.println("-------- End of heap --------") ;
|
System.out.println("-------- End of heap --------");
|
||||||
System.out.println() ;
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Test program : compare with the reference implementation PriorityQueue.
|
|
||||||
public static void main(String [] args) {
|
|
||||||
BinaryHeap<Integer> heap = new BinaryHeap<Integer>() ;
|
|
||||||
PriorityQueue<Integer> queue = new PriorityQueue<Integer>() ;
|
|
||||||
|
|
||||||
int count = 0 ;
|
|
||||||
int blocksize = 10000 ;
|
|
||||||
|
|
||||||
System.out.println("Interrupt to stop the test.") ;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
// Insert up to blocksize elements
|
|
||||||
int nb_insert = (int)(Math.random() * (blocksize + 1)) ;
|
|
||||||
|
|
||||||
for (int i = 0 ; i < nb_insert ; i++) {
|
|
||||||
Integer obj = new Integer(i) ;
|
|
||||||
heap.insert(obj) ;
|
|
||||||
queue.add(obj) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove up to blocksize elements
|
|
||||||
int nb_remove = (int)(Math.random() * blocksize * 1.1) ;
|
|
||||||
|
|
||||||
if (nb_remove > queue.size()) {
|
|
||||||
nb_remove = queue.size() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0 ; i < nb_remove ; i++) {
|
|
||||||
|
|
||||||
int removed1 = queue.poll().intValue() ;
|
|
||||||
int removed2 = heap.deleteMin().intValue() ;
|
|
||||||
|
|
||||||
if (removed1 != removed2) {
|
|
||||||
System.out.println("Ouch : expected " + removed1 + " .. but got " + removed2) ;
|
|
||||||
System.exit(1) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heap.size() != queue.size()) {
|
|
||||||
System.out.println("Ouch : heap size = " + heap.size() + " queue size = " + queue.size() ) ;
|
|
||||||
System.exit(1) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
count += nb_remove ;
|
|
||||||
|
|
||||||
if (count > 1000000) {
|
|
||||||
System.out.println("" + count + " items successfully compared. Heap size : " + heap.size()) ;
|
|
||||||
count = 0 ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package org.insa.algo.strongconnectivity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.insa.graph.Node;
|
|
||||||
|
|
||||||
public interface StronglyConnectedComponentObserver {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify that the algorithm is entering a new component.
|
|
||||||
*
|
|
||||||
* @param curNode Starting node for the component.
|
|
||||||
*/
|
|
||||||
public void notifyStartComponent(Node curNode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify that a new node has been found for the current component.
|
|
||||||
*
|
|
||||||
* @param node New node found for the current component.
|
|
||||||
*/
|
|
||||||
public void notifyNewNodeInComponent(Node node);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify that the algorithm has computed a new component.
|
|
||||||
*
|
|
||||||
* @param nodes List of nodes in the component.
|
|
||||||
*/
|
|
||||||
public void notifyEndComponent(ArrayList<Node> nodes);
|
|
||||||
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package org.insa.algo.strongconnectivity;
|
|
||||||
|
|
||||||
import org.insa.algo.AbstractAlgorithm;
|
|
||||||
|
|
||||||
public abstract class StronglyConnectedComponentsAlgorithm
|
|
||||||
extends AbstractAlgorithm<StronglyConnectedComponentObserver> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
public StronglyConnectedComponentsAlgorithm(StronglyConnectedComponentsData data) {
|
|
||||||
super(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StronglyConnectedComponentsSolution run() {
|
|
||||||
return (StronglyConnectedComponentsSolution) super.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StronglyConnectedComponentsData getInputData() {
|
|
||||||
return (StronglyConnectedComponentsData) super.getInputData();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package org.insa.algo.strongconnectivity;
|
|
||||||
|
|
||||||
import org.insa.algo.AbstractInputData;
|
|
||||||
import org.insa.graph.Graph;
|
|
||||||
|
|
||||||
public class StronglyConnectedComponentsData extends AbstractInputData {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param graph
|
|
||||||
*/
|
|
||||||
public StronglyConnectedComponentsData(Graph graph) {
|
|
||||||
super(graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
package org.insa.algo.strongconnectivity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.insa.algo.AbstractSolution;
|
|
||||||
import org.insa.graph.Node;
|
|
||||||
|
|
||||||
public class StronglyConnectedComponentsSolution extends AbstractSolution {
|
|
||||||
|
|
||||||
// Components
|
|
||||||
private ArrayList<ArrayList<Node>> components;
|
|
||||||
|
|
||||||
protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData data) {
|
|
||||||
super(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected StronglyConnectedComponentsSolution(StronglyConnectedComponentsData data,
|
|
||||||
Status status, ArrayList<ArrayList<Node>> components) {
|
|
||||||
super(data, status);
|
|
||||||
this.components = components;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StronglyConnectedComponentsData getInputData() {
|
|
||||||
return (StronglyConnectedComponentsData) super.getInputData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Components of the solution, if any.
|
|
||||||
*/
|
|
||||||
public ArrayList<ArrayList<Node>> getComponents() {
|
|
||||||
return components;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
package org.insa.algo.strongconnectivity;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import org.insa.algo.AbstractSolution.Status;
|
|
||||||
import org.insa.graph.Arc;
|
|
||||||
import org.insa.graph.Graph;
|
|
||||||
import org.insa.graph.Node;
|
|
||||||
|
|
||||||
public class TarjanAlgorithm extends StronglyConnectedComponentsAlgorithm {
|
|
||||||
|
|
||||||
private final static int UNDEFINED = -1;
|
|
||||||
|
|
||||||
// Stack of nodes and flags.
|
|
||||||
private Stack<Node> stack;
|
|
||||||
private boolean[] inStack;
|
|
||||||
|
|
||||||
// Current index.
|
|
||||||
private int index;
|
|
||||||
|
|
||||||
// Information of nodes
|
|
||||||
private int[] indexes;
|
|
||||||
private int[] lowlink;
|
|
||||||
|
|
||||||
// Array of strongly connected components
|
|
||||||
ArrayList<ArrayList<Node>> components;
|
|
||||||
|
|
||||||
public TarjanAlgorithm(StronglyConnectedComponentsData data) {
|
|
||||||
super(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Push the given node to the stack.
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
*/
|
|
||||||
protected void pushNode(Node node) {
|
|
||||||
stack.push(node);
|
|
||||||
inStack[node.getId()] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pop and return a node from the stack.
|
|
||||||
*
|
|
||||||
* @return Node popped from the stack
|
|
||||||
*/
|
|
||||||
protected Node popNode() {
|
|
||||||
Node top = stack.pop();
|
|
||||||
inStack[top.getId()] = false;
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given node is in the stack.
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
*
|
|
||||||
* @return true if the given node is in the stack, false otherwize.
|
|
||||||
*/
|
|
||||||
protected boolean isInStack(Node node) {
|
|
||||||
return inStack[node.getId()];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the strong component containing the given node.
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
*
|
|
||||||
* @return The strong component containing the given node.
|
|
||||||
*/
|
|
||||||
protected void findAndAddStrongComponent(Node v) {
|
|
||||||
|
|
||||||
// Update node info, index and push the node.
|
|
||||||
indexes[v.getId()] = index;
|
|
||||||
lowlink[v.getId()] = index;
|
|
||||||
index += 1;
|
|
||||||
pushNode(v);
|
|
||||||
|
|
||||||
for (Arc a: v.getSuccessors()) {
|
|
||||||
Node w = a.getDestination();
|
|
||||||
if (!hasBeenVisited(w)) {
|
|
||||||
findAndAddStrongComponent(w);
|
|
||||||
lowlink[v.getId()] = Math.min(lowlink[v.getId()], lowlink[w.getId()]);
|
|
||||||
}
|
|
||||||
else if (isInStack(w)) {
|
|
||||||
lowlink[v.getId()] = Math.min(lowlink[v.getId()], indexes[w.getId()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the component (if any)
|
|
||||||
if (lowlink[v.getId()] == indexes[v.getId()]) {
|
|
||||||
ArrayList<Node> component = new ArrayList<Node>();
|
|
||||||
Node w;
|
|
||||||
do {
|
|
||||||
w = popNode();
|
|
||||||
component.add(w);
|
|
||||||
} while (!w.equals(v));
|
|
||||||
components.add(component);
|
|
||||||
System.out.println("Size of the stack: " + stack.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given node has not been visited yet.
|
|
||||||
*
|
|
||||||
* @return true if the node has been visited.
|
|
||||||
*/
|
|
||||||
protected boolean hasBeenVisited(Node node) {
|
|
||||||
return this.indexes[node.getId()] != UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected StronglyConnectedComponentsSolution doRun() {
|
|
||||||
Graph graph = getInputData().getGraph();
|
|
||||||
|
|
||||||
components = new ArrayList<ArrayList<Node>>();
|
|
||||||
|
|
||||||
// Initialize everything
|
|
||||||
final int nbNodes = graph.getNodes().size();
|
|
||||||
stack = new Stack<Node>();
|
|
||||||
inStack = new boolean[nbNodes];
|
|
||||||
|
|
||||||
// Current index.
|
|
||||||
index = 0;
|
|
||||||
|
|
||||||
// Information of nodes
|
|
||||||
indexes = new int[nbNodes];
|
|
||||||
Arrays.fill(indexes, UNDEFINED);
|
|
||||||
lowlink = new int[nbNodes];
|
|
||||||
|
|
||||||
// Find components
|
|
||||||
for (Node node: graph.getNodes()) {
|
|
||||||
if (!hasBeenVisited(node)) {
|
|
||||||
findAndAddStrongComponent(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new StronglyConnectedComponentsSolution(getInputData(), Status.OPTIMAL, components);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
|||||||
* (without having to duplicate attributes).
|
* (without having to duplicate attributes).
|
||||||
*
|
*
|
||||||
* Arc should never be created manually but always using the
|
* Arc should never be created manually but always using the
|
||||||
* {@link Node#linkNodes(Node, Node, int, RoadInformation, java.util.ArrayList)}
|
* {@link Node#linkNodes(Node, Node, float, RoadInformation, java.util.ArrayList)}
|
||||||
* method to ensure proper instantiation of the {@link ArcForward} and
|
* method to ensure proper instantiation of the {@link ArcForward} and
|
||||||
* {@link ArcBackward} classes.
|
* {@link ArcBackward} classes.
|
||||||
*
|
*
|
||||||
|
@ -10,6 +10,12 @@ package org.insa.graph;
|
|||||||
*/
|
*/
|
||||||
public class GraphStatistics {
|
public class GraphStatistics {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special value used to indicate that the graph has no maximum speed limit
|
||||||
|
* (some roads are not limited).
|
||||||
|
*/
|
||||||
|
public static final int NO_MAXIMUM_SPEED = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a bounding box for a graph (a rectangle that contains all
|
* Class representing a bounding box for a graph (a rectangle that contains all
|
||||||
* nodes in the graph).
|
* nodes in the graph).
|
||||||
@ -59,8 +65,10 @@ public class GraphStatistics {
|
|||||||
/**
|
/**
|
||||||
* Create a new GraphStatistics instance with the given value.
|
* Create a new GraphStatistics instance with the given value.
|
||||||
*
|
*
|
||||||
* @param maximumSpeed Maximum speed of any road of the graph. A value of 0 may
|
* @param boundingBox Bounding-box for the graph.
|
||||||
* be used to indicate that this graph has no maximum limitation.
|
* @param maximumSpeed Maximum speed of any road of the graph. You can use
|
||||||
|
* {@link #NO_MAXIMUM_SPEED} to indicate that the graph has no maximum
|
||||||
|
* speed limit.
|
||||||
* @param maximumLength Maximum length of any arc of the graph.
|
* @param maximumLength Maximum length of any arc of the graph.
|
||||||
*/
|
*/
|
||||||
public GraphStatistics(BoundingBox boundingBox, int maximumSpeed, float maximumLength) {
|
public GraphStatistics(BoundingBox boundingBox, int maximumSpeed, float maximumLength) {
|
||||||
@ -77,8 +85,15 @@ public class GraphStatistics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Maximum speed of any arc in the graph, or 0 if some road have no
|
* @return true if this graph has a maximum speed limit, false otherwise.
|
||||||
* speed limitations.
|
*/
|
||||||
|
public boolean hasMaximumSpeed() {
|
||||||
|
return this.maximumLength != NO_MAXIMUM_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Maximum speed of any arc in the graph, or {@link #NO_MAXIMUM_SPEED}
|
||||||
|
* if some roads have no speed limitation.
|
||||||
*/
|
*/
|
||||||
public int getMaximumSpeed() {
|
public int getMaximumSpeed() {
|
||||||
return this.maximumSpeed;
|
return this.maximumSpeed;
|
||||||
|
@ -8,19 +8,10 @@ import org.insa.graph.RoadInformation.RoadType;
|
|||||||
public class BasicGraphPalette implements GraphPalette {
|
public class BasicGraphPalette implements GraphPalette {
|
||||||
|
|
||||||
// Color types for arc.
|
// Color types for arc.
|
||||||
static final Color motorway = Color.RED;
|
private static final Color MOTORWAY_COLOR = Color.RED;
|
||||||
static final Color bigroad = new Color(255, 105, 0);
|
private static final Color BIG_ROAD_COLOR = new Color(255, 105, 0);
|
||||||
static final Color smallroad = new Color(255, 234, 0);
|
private static final Color SMALL_ROAD_COLOR = new Color(255, 234, 0);
|
||||||
static final Color coastline = Color.BLUE;
|
private static final Color COASTLINE_COLOR = Color.BLUE;
|
||||||
|
|
||||||
// Default point width
|
|
||||||
static final int DEFAULT_POINT_WIDTH = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public BasicGraphPalette() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDefaultPointWidth() {
|
public int getDefaultPointWidth() {
|
||||||
@ -35,19 +26,16 @@ public class BasicGraphPalette implements GraphPalette {
|
|||||||
@Override
|
@Override
|
||||||
public Color getColorForArc(Arc arc) {
|
public Color getColorForArc(Arc arc) {
|
||||||
RoadType type = arc.getRoadInformation().getType();
|
RoadType type = arc.getRoadInformation().getType();
|
||||||
Color color = Color.BLACK;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MOTORWAY:
|
case MOTORWAY:
|
||||||
color = motorway;
|
return MOTORWAY_COLOR;
|
||||||
break;
|
|
||||||
case TRUNK:
|
case TRUNK:
|
||||||
case PRIMARY:
|
case PRIMARY:
|
||||||
case SECONDARY:
|
case SECONDARY:
|
||||||
case MOTORWAY_LINK:
|
case MOTORWAY_LINK:
|
||||||
case TRUNK_LINK:
|
case TRUNK_LINK:
|
||||||
case PRIMARY_LINK:
|
case PRIMARY_LINK:
|
||||||
color = bigroad;
|
return BIG_ROAD_COLOR;
|
||||||
break;
|
|
||||||
case SECONDARY_LINK:
|
case SECONDARY_LINK:
|
||||||
case TERTIARY:
|
case TERTIARY:
|
||||||
case RESIDENTIAL:
|
case RESIDENTIAL:
|
||||||
@ -58,14 +46,12 @@ public class BasicGraphPalette implements GraphPalette {
|
|||||||
case PEDESTRIAN:
|
case PEDESTRIAN:
|
||||||
case CYCLEWAY:
|
case CYCLEWAY:
|
||||||
case TRACK:
|
case TRACK:
|
||||||
color = smallroad;
|
return SMALL_ROAD_COLOR;
|
||||||
break;
|
|
||||||
case COASTLINE:
|
case COASTLINE:
|
||||||
color = coastline;
|
return COASTLINE_COLOR;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return color;
|
return Color.BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,31 +14,34 @@ public interface Drawing {
|
|||||||
/**
|
/**
|
||||||
* Add a listener to click to this drawing.
|
* Add a listener to click to this drawing.
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener DrawingClickListener to add to this Drawing.
|
||||||
*/
|
*/
|
||||||
public void addDrawingClickListener(DrawingClickListener listener);
|
public void addDrawingClickListener(DrawingClickListener listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given listener from the drawing.
|
* Remove the given listener from the drawing.
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener DrawingClickListener to remove from this Drawing.
|
||||||
*/
|
*/
|
||||||
public void removeDrawingClickListener(DrawingClickListener listener);
|
public void removeDrawingClickListener(DrawingClickListener listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the drawing.
|
* Clear the drawing (overlays and underlying graph/map).
|
||||||
*/
|
*/
|
||||||
public void clear();
|
public void clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove overlays from the drawing.
|
* Remove overlays from the drawing (do not remove the underlying graph/map).
|
||||||
*/
|
*/
|
||||||
public void clearOverlays();
|
public void clearOverlays();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the given point with the given color.
|
* Draw a marker at the given position with the given color.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position of the marker to draw.
|
||||||
|
* @param color Color of the marker to draw.
|
||||||
|
*
|
||||||
|
* @return A MarkerOverlay instance representing the newly drawn marker.
|
||||||
*/
|
*/
|
||||||
public MarkerOverlay drawMarker(Point point, Color color);
|
public MarkerOverlay drawMarker(Point point, Color color);
|
||||||
|
|
||||||
@ -48,65 +51,86 @@ public interface Drawing {
|
|||||||
*
|
*
|
||||||
* PointSetOverlay are heavy memory resources, do not use one for each point!
|
* PointSetOverlay are heavy memory resources, do not use one for each point!
|
||||||
*
|
*
|
||||||
|
* @return A new PointSetOverlay for this drawing.
|
||||||
*/
|
*/
|
||||||
public PointSetOverlay createPointSetOverlay();
|
public PointSetOverlay createPointSetOverlay();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new PointSetOverlay with the original width and color that can be
|
* Create a new PointSetOverlay with the given initial width and color that can
|
||||||
* used to add overlay points to this drawing.
|
* be used to add overlay points to this drawing.
|
||||||
*
|
*
|
||||||
* PointSetOverlay are heavy memory resources, do not use one for each point!
|
* PointSetOverlay are heavy memory resources, do not use one for each point!
|
||||||
*
|
*
|
||||||
|
* @param width Initial width of points in the overlay.
|
||||||
|
* @param color Initial width of points in the overlay.
|
||||||
|
*
|
||||||
|
* @return A new PointSetOverlay for this drawing.
|
||||||
*/
|
*/
|
||||||
public PointSetOverlay createPointSetOverlay(int width, Color color);
|
public PointSetOverlay createPointSetOverlay(int width, Color color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the given graph using the given palette.
|
* Draw the given graph using the given palette.
|
||||||
*
|
*
|
||||||
* @param graph
|
* @param graph Graph to draw.
|
||||||
* @param palette
|
* @param palette Palette to use to draw the graph.
|
||||||
|
*
|
||||||
|
* @see BasicGraphPalette
|
||||||
|
* @see BlackAndWhiteGraphPalette
|
||||||
*/
|
*/
|
||||||
public void drawGraph(Graph graph, GraphPalette palette);
|
public void drawGraph(Graph graph, GraphPalette palette);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the given graph using a default palette specific to the implementation.
|
* Draw the given graph using a default palette specific to the implementation.
|
||||||
*
|
*
|
||||||
* @param graph
|
* @param graph Graph to draw.
|
||||||
*/
|
*/
|
||||||
public void drawGraph(Graph graph);
|
public void drawGraph(Graph graph);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a path using the given color.
|
* Draw a path using the given color.
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path Path to draw.
|
||||||
* @param color
|
* @param color Color of the path to draw.
|
||||||
* @param markers Show origin and destination markers.
|
* @param markers true to show origin and destination markers.
|
||||||
* @return
|
*
|
||||||
|
* @return A PathOverlay instance representing the newly drawn path.
|
||||||
*/
|
*/
|
||||||
public PathOverlay drawPath(Path path, Color color, boolean markers);
|
public PathOverlay drawPath(Path path, Color color, boolean markers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a path using the given color with markers.
|
* Draw a path with both origin and destination markers using the given color.
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path Path to draw.
|
||||||
* @param color
|
* @param color Color of the path to draw.
|
||||||
|
*
|
||||||
|
* @return A PathOverlay instance representing the newly drawn path.
|
||||||
|
*
|
||||||
|
* @see Drawing#drawPath(Path, Color, boolean)
|
||||||
*/
|
*/
|
||||||
public PathOverlay drawPath(Path path, Color color);
|
public PathOverlay drawPath(Path path, Color color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a path using a default color specific to the implementation
|
* Draw a path using a default color specific to the implementation
|
||||||
*
|
*
|
||||||
|
* @param path Path to draw.
|
||||||
|
* @param markers true to show origin and destination markers.
|
||||||
*
|
*
|
||||||
* @param path
|
* @return A PathOverlay instance representing the newly drawn path.
|
||||||
* @param markers Show origin and destination markers.
|
*
|
||||||
|
* @see Drawing#drawPath(Path, Color, boolean)
|
||||||
*/
|
*/
|
||||||
public PathOverlay drawPath(Path path, boolean markers);
|
public PathOverlay drawPath(Path path, boolean markers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw a path using a default color specific to the implementation
|
* Draw a path with both origin and destination markers using a default color
|
||||||
|
* specific to the implementation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path Path to draw.
|
||||||
|
*
|
||||||
|
* @return A PathOverlay instance representing the newly drawn path.
|
||||||
|
*
|
||||||
|
* @see Drawing#drawPath(Path, Color, boolean)
|
||||||
*/
|
*/
|
||||||
public PathOverlay drawPath(Path path);
|
public PathOverlay drawPath(Path path);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ public interface DrawingClickListener {
|
|||||||
/**
|
/**
|
||||||
* Event triggered when a click is made on the map.
|
* Event triggered when a click is made on the map.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position (on the map) of the mouse click.
|
||||||
*/
|
*/
|
||||||
public void mouseClicked(Point point);
|
public void mouseClicked(Point point);
|
||||||
|
|
||||||
|
@ -17,14 +17,14 @@ public interface GraphPalette {
|
|||||||
public Color getDefaultPointColor();
|
public Color getDefaultPointColor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param arc
|
* @param arc Arc for which color should be retrieved.
|
||||||
*
|
*
|
||||||
* @return Color associated with the given arc.
|
* @return Color associated with the given arc.
|
||||||
*/
|
*/
|
||||||
public Color getColorForArc(Arc arc);
|
public Color getColorForArc(Arc arc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param arc
|
* @param arc Arc for which width should be retrieved.
|
||||||
*
|
*
|
||||||
* @return Width associated with the given arc.
|
* @return Width associated with the given arc.
|
||||||
*/
|
*/
|
||||||
|
@ -449,11 +449,15 @@ public class BasicDrawing extends JPanel implements Drawing {
|
|||||||
* Return the longitude and latitude corresponding to the given position of the
|
* Return the longitude and latitude corresponding to the given position of the
|
||||||
* MouseEvent.
|
* MouseEvent.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event MouseEvent from which longitude/latitude should be retrieved.
|
||||||
*
|
*
|
||||||
* @return
|
* @return Point representing the projection of the MouseEvent position in the
|
||||||
|
* graph/map.
|
||||||
|
*
|
||||||
|
* @throws NoninvertibleTransformException if the actual transformation is
|
||||||
|
* invalid.
|
||||||
*/
|
*/
|
||||||
public Point getLongitudeLatitude(MouseEvent event) throws NoninvertibleTransformException {
|
protected Point getLongitudeLatitude(MouseEvent event) throws NoninvertibleTransformException {
|
||||||
// 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]).
|
||||||
|
@ -111,7 +111,7 @@ public class MapZoomControls {
|
|||||||
/**
|
/**
|
||||||
* Add a zoom-in listener.
|
* Add a zoom-in listener.
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener Zoom-in listener to add to this MapZoomControls instance.
|
||||||
*/
|
*/
|
||||||
public void addZoomInListener(ActionListener listener) {
|
public void addZoomInListener(ActionListener listener) {
|
||||||
this.zoomInListeners.add(listener);
|
this.zoomInListeners.add(listener);
|
||||||
@ -120,7 +120,7 @@ public class MapZoomControls {
|
|||||||
/**
|
/**
|
||||||
* Add a zoom-out listener.
|
* Add a zoom-out listener.
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener Zoom-out listener to add to this MapZoomControls instance.
|
||||||
*/
|
*/
|
||||||
public void addZoomOutListener(ActionListener listener) {
|
public void addZoomOutListener(ActionListener listener) {
|
||||||
this.zoomOutListeners.add(listener);
|
this.zoomOutListeners.add(listener);
|
||||||
@ -134,9 +134,9 @@ public class MapZoomControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current zoom level.
|
* Set the current zoom level without requesting a redraw.
|
||||||
*
|
*
|
||||||
* @param level
|
* @param level Zoom level to set.
|
||||||
*/
|
*/
|
||||||
public void setZoomLevel(int level) {
|
public void setZoomLevel(int level) {
|
||||||
this.currentLevel = level;
|
this.currentLevel = level;
|
||||||
@ -161,7 +161,7 @@ public class MapZoomControls {
|
|||||||
* Check if a point is contained inside an element of this zoom controls, useful
|
* Check if a point is contained inside an element of this zoom controls, useful
|
||||||
* to avoid spurious click listeners.
|
* to avoid spurious click listeners.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Point to check.
|
||||||
*
|
*
|
||||||
* @return true if the given point correspond to an element of this zoom
|
* @return true if the given point correspond to an element of this zoom
|
||||||
* controls.
|
* controls.
|
||||||
|
@ -11,11 +11,27 @@ import org.mapsforge.core.model.Point;
|
|||||||
import org.mapsforge.map.awt.graphics.AwtBitmap;
|
import org.mapsforge.map.awt.graphics.AwtBitmap;
|
||||||
import org.mapsforge.map.layer.overlay.Marker;
|
import org.mapsforge.map.layer.overlay.Marker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class extending the default Mapsforge's {@link Marker} with auto-scaling.
|
||||||
|
*
|
||||||
|
* Mapsforge's Markers do not scale with zoom level, this class aims at
|
||||||
|
* correcting this. Internally, this image stores an {@link Image} instance and
|
||||||
|
* scale it when a redraw is requested.
|
||||||
|
*
|
||||||
|
* @see MarkerUtils#getMarkerForColor(java.awt.Color)
|
||||||
|
* @see PaintUtils#getStrokeWidth(int, byte)
|
||||||
|
*/
|
||||||
public class MarkerAutoScaling extends Marker {
|
public class MarkerAutoScaling extends Marker {
|
||||||
|
|
||||||
// Original image.
|
// Original image.
|
||||||
private Image image;
|
private Image image;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MarkerAutoScaling at the given position with the given image.
|
||||||
|
*
|
||||||
|
* @param latLong Initial position of the marker.
|
||||||
|
* @param image Image for this marker.
|
||||||
|
*/
|
||||||
public MarkerAutoScaling(LatLong latLong, Image image) {
|
public MarkerAutoScaling(LatLong latLong, Image image) {
|
||||||
super(latLong, null, 0, 0);
|
super(latLong, null, 0, 0);
|
||||||
this.image = image;
|
this.image = image;
|
||||||
|
@ -5,12 +5,14 @@ import org.insa.graph.Point;
|
|||||||
public interface MarkerOverlay extends Overlay {
|
public interface MarkerOverlay extends Overlay {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The point associated with this marker.
|
* @return The current position of this marker.
|
||||||
*/
|
*/
|
||||||
public Point getPoint();
|
public Point getPoint();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Move this marker to the specified location.
|
||||||
*
|
*
|
||||||
|
* @param point New position for the marker.
|
||||||
*/
|
*/
|
||||||
public void moveTo(Point point);
|
public void moveTo(Point point);
|
||||||
|
|
||||||
|
@ -11,15 +11,17 @@ public class MarkerUtils {
|
|||||||
private static final String MARKER_MASK_FILE = "res/marker_mask.bin";
|
private static final String MARKER_MASK_FILE = "res/marker_mask.bin";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Bitmap representing a marker of the given color.
|
* Create an Image representing a marker of the given color.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color Color of the marker.
|
||||||
* @return
|
*
|
||||||
|
* @return A new Image representing a marker with the given color.
|
||||||
*/
|
*/
|
||||||
public static Image getMarkerForColor(Color color) {
|
public static Image getMarkerForColor(Color color) {
|
||||||
// create image
|
// create image
|
||||||
int[][] mask = readMarkerMask();
|
int[][] mask = readMarkerMask();
|
||||||
BufferedImage image = new BufferedImage(mask[0].length, mask.length, BufferedImage.TYPE_4BYTE_ABGR);
|
BufferedImage image = new BufferedImage(mask[0].length, mask.length,
|
||||||
|
BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
|
||||||
// Color[] map = getColorMapping(color);
|
// Color[] map = getColorMapping(color);
|
||||||
int rgb = color.getRGB() & 0x00ffffff;
|
int rgb = color.getRGB() & 0x00ffffff;
|
||||||
|
@ -4,6 +4,8 @@ import java.awt.Color;
|
|||||||
|
|
||||||
import org.mapsforge.core.graphics.GraphicFactory;
|
import org.mapsforge.core.graphics.GraphicFactory;
|
||||||
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
|
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
|
||||||
|
import org.mapsforge.map.layer.overlay.Marker;
|
||||||
|
import org.mapsforge.map.layer.overlay.Polyline;
|
||||||
|
|
||||||
public class PaintUtils {
|
public class PaintUtils {
|
||||||
|
|
||||||
@ -13,8 +15,9 @@ public class PaintUtils {
|
|||||||
/**
|
/**
|
||||||
* Convert the given AWT color to a mapsforge compatible color.
|
* Convert the given AWT color to a mapsforge compatible color.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color AWT color to convert.
|
||||||
* @return
|
*
|
||||||
|
* @return Integer value representing a corresponding mapsforge color.
|
||||||
*/
|
*/
|
||||||
public static int convertColor(Color color) {
|
public static int convertColor(Color color) {
|
||||||
return GRAPHIC_FACTORY.createColor(color.getAlpha(), color.getRed(), color.getGreen(),
|
return GRAPHIC_FACTORY.createColor(color.getAlpha(), color.getRed(), color.getGreen(),
|
||||||
@ -24,16 +27,23 @@ public class PaintUtils {
|
|||||||
/**
|
/**
|
||||||
* Convert the given mapsforge color to an AWT Color.
|
* Convert the given mapsforge color to an AWT Color.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color Integer value representing a mapsforge color.
|
||||||
* @return
|
*
|
||||||
|
* @return AWT color corresponding to the given value.
|
||||||
*/
|
*/
|
||||||
public static Color convertColor(int color) {
|
public static Color convertColor(int color) {
|
||||||
return new Color(color, true);
|
return new Color(color, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param width
|
* Compute an updated value for the given width at the given zoom level. This
|
||||||
* @return
|
* function can be used to automatically scale {@link Polyline} or
|
||||||
|
* {@link Marker} when zooming (which is not done by default in Mapsforge).
|
||||||
|
*
|
||||||
|
* @param width Original width to convert.
|
||||||
|
* @param zoomLevel Zoom level for which the width should be computed.
|
||||||
|
*
|
||||||
|
* @return Actual width at the given zoom level.
|
||||||
*/
|
*/
|
||||||
public static float getStrokeWidth(int width, byte zoomLevel) {
|
public static float getStrokeWidth(int width, byte zoomLevel) {
|
||||||
float mul = 1;
|
float mul = 1;
|
||||||
|
@ -9,48 +9,61 @@ public interface PointSetOverlay extends Overlay {
|
|||||||
/**
|
/**
|
||||||
* Set the width of this overlay for future addPoint().
|
* Set the width of this overlay for future addPoint().
|
||||||
*
|
*
|
||||||
* @param width
|
* @param width New default width for this overlay.
|
||||||
*/
|
*/
|
||||||
public void setWidth(int width);
|
public void setWidth(int width);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set color and width for this overlay for future addPoint().
|
* Set color and width for this overlay for future addPoint().
|
||||||
*
|
*
|
||||||
* @param width
|
* @param width New default width for this overlay.
|
||||||
* @param color
|
* @param color New default color for this overlay.
|
||||||
*/
|
*/
|
||||||
public void setWidthAndColor(int width, Color color);
|
public void setWidthAndColor(int width, Color color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new point using the current width and color.
|
* Add a new point using the current width and color.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position of the point to add.
|
||||||
|
*
|
||||||
|
* @see #setWidth(int)
|
||||||
|
* @see #setColor(Color)
|
||||||
*/
|
*/
|
||||||
public void addPoint(Point point);
|
public void addPoint(Point point);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current width and then add a new point.
|
* Set the current width and then add a new point.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position of the point to add.
|
||||||
* @param width
|
* @param width New default width for this overlay.
|
||||||
|
*
|
||||||
|
* @see #setWidth(int)
|
||||||
|
* @see PointSetOverlay#addPoint(Point)
|
||||||
*/
|
*/
|
||||||
public void addPoint(Point point, int width);
|
public void addPoint(Point point, int width);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current color and then add a new point.
|
* Set the current color and then add a new point.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position of the point to add.
|
||||||
* @param color
|
* @param color New default color for this overlay.
|
||||||
|
*
|
||||||
|
* @see #setColor(Color)
|
||||||
|
* @see PointSetOverlay#addPoint(Point)
|
||||||
*/
|
*/
|
||||||
public void addPoint(Point point, Color color);
|
public void addPoint(Point point, Color color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new point to this set at the given location, with the given color and
|
* Add a new point at the given location, with the given color and width, and
|
||||||
* width, and update the current color.
|
* update the current width and color.
|
||||||
*
|
*
|
||||||
* @param point
|
* @param point Position of the point to add.
|
||||||
* @param width
|
* @param width New default width for this overlay.
|
||||||
* @param color
|
* @param color New default color for this overlay.
|
||||||
|
*
|
||||||
|
* @see #setWidth(int)
|
||||||
|
* @see #setColor(Color)
|
||||||
|
* @see PointSetOverlay#addPoint(Point)
|
||||||
*/
|
*/
|
||||||
public void addPoint(Point point, int width, Color color);
|
public void addPoint(Point point, int width, Color color);
|
||||||
|
|
||||||
|
@ -12,6 +12,15 @@ import org.mapsforge.core.model.LatLong;
|
|||||||
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
|
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
|
||||||
import org.mapsforge.map.layer.overlay.Polyline;
|
import org.mapsforge.map.layer.overlay.Polyline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class extending the default Mapsforge's {@link Polyline} with auto-scaling.
|
||||||
|
*
|
||||||
|
* Mapsforge's Polylines do not scale with zoom level, this class aims at
|
||||||
|
* correcting this. When a redraw is requested, the width of the line is
|
||||||
|
* recomputed for the current zoom level.
|
||||||
|
*
|
||||||
|
* @see PaintUtils#getStrokeWidth(int, byte)
|
||||||
|
*/
|
||||||
public class PolylineAutoScaling extends Polyline {
|
public class PolylineAutoScaling extends Polyline {
|
||||||
|
|
||||||
// Graphic factory.
|
// Graphic factory.
|
||||||
@ -21,8 +30,12 @@ public class PolylineAutoScaling extends Polyline {
|
|||||||
private final int width;
|
private final int width;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param width
|
* Create a new PolylineAutoScaling with the given width and color.
|
||||||
* @param color
|
*
|
||||||
|
* @param width Original width of the line (independent of the zoom level).
|
||||||
|
* @param color Color of the line.
|
||||||
|
*
|
||||||
|
* @see PaintUtils#getStrokeWidth(int, byte)
|
||||||
*/
|
*/
|
||||||
public PolylineAutoScaling(int width, Color color) {
|
public PolylineAutoScaling(int width, Color color) {
|
||||||
super(GRAPHIC_FACTORY.createPaint(), GRAPHIC_FACTORY);
|
super(GRAPHIC_FACTORY.createPaint(), GRAPHIC_FACTORY);
|
||||||
@ -48,14 +61,14 @@ public class PolylineAutoScaling extends Polyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param point
|
* @param point Point to add to this line.
|
||||||
*/
|
*/
|
||||||
public void add(Point point) {
|
public void add(Point point) {
|
||||||
getLatLongs().add(new LatLong(point.getLatitude(), point.getLongitude()));
|
getLatLongs().add(new LatLong(point.getLatitude(), point.getLongitude()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param points
|
* @param points Points to add to this line.
|
||||||
*/
|
*/
|
||||||
public void add(List<Point> points) {
|
public void add(List<Point> points) {
|
||||||
for (Point point: points) {
|
for (Point point: points) {
|
||||||
|
Loading…
Reference in New Issue
Block a user