Rev 410 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2014 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 as published by the Free Software Foundation.
*
* This program 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.
*/
package test.files;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import uk.me.parabola.imgfmt.app.Coord;
import static test.util.ArcFlags.ARC_CLASSMASK;
/**
* A node from NOD 1 of the routing network.
*
* Each node is in a group we call the RouteCenter. A node has zero or more arcs that lead to
* other nodes.
*
* @author Steve Ratcliffe
*/
public class RouteNode
{
private final int offset
;
private final RouteCenter center
;
private int flags
;
private Coord coord
;
private final List<RouteArc
> arcs =
new ArrayList<>();
private final List<RoadData
> roads =
new ArrayList<>();
private List<RouteCenter.
Restriction> restrictions
;
private boolean bad
;
private boolean problem
;
private long nextStart
;
// NET1 points to one entry in NOD2, which points to one node. If this is such a node, then
// save the road here.
private RoadData linkedRoad
;
private int nodeClass
;
private int[] classes =
new int[5];
private int classSet
; // a bit set
public RouteNode
(RouteCenter center,
long offset
) {
this.
center = center
;
this.
offset =
(int) offset
;
}
public int getOffset
() {
return offset
;
}
public void setFlags
(int flags
) {
this.
flags = flags
;
}
public int getFlags
() {
return flags
;
}
public boolean hasArcs
() {
return (flags
& 0x40
) !=
0;
}
public boolean hasLargeCoordOffsets
() {
return (flags
& 0x20
) !=
0;
}
public boolean hasRestrictions
() {
return (flags
& 0x10
) !=
0;
}
public boolean isBoundary
() {
return (flags
& 0x08
) !=
0;
}
public void setCoord
(Coord coord
) {
this.
coord = coord
;
}
public Coord getCoord
() {
return coord
;
}
public void addArc
(RouteArc arc
) {
arcs.
add(arc
);
}
public List<RouteArc
> getArcs
() {
return arcs
;
}
public String flagString
() {
StringBuilder sb =
new StringBuilder();
if (hasArcs
())
sb.
append(" arcs");
if (hasLargeCoordOffsets
())
sb.
append(" big");
if (hasRestrictions
())
sb.
append(" restrictions");
if (isBoundary
())
sb.
append(" boundary");
return sb.
toString();
}
public void setBad
(boolean bad
) {
this.
bad = bad
;
}
public boolean isBad
() {
return bad
;
}
public RouteCenter getCenter
() {
return center
;
}
public void setProblem
(boolean problem
) {
this.
problem = problem
;
}
public boolean isProblem
() {
return problem
;
}
public void setNextStart
(long nextStart
) {
this.
nextStart = nextStart
;
}
public long getNextStart
() {
return nextStart
;
}
public int getDestclass
() {
return flags
& ARC_CLASSMASK
;
}
public void setLinkedRoad
(RoadData linkedRoad
) {
this.
linkedRoad = linkedRoad
;
}
/**
* A road points (via NET1->NOD2) to exactly one node. If this is such a node, then the
* road is recorded here. It is not particularly interesting.
*/
public RoadData getLinkedRoad
() {
return linkedRoad
;
}
public void updateDestClass
(int roadClass
) {
classes
[roadClass
]++
;
classSet |=
1<<roadClass
;
}
public void addRoad
(RoadData road
) {
roads.
add(road
);
}
public List<RoadData
> getRoads
() {
return roads
;
}
public int getMinDestclass
() {
return Integer.
numberOfTrailingZeros(classSet
);
}
public int getMaxDestclass
() {
return 31 -
Integer.
numberOfLeadingZeros(classSet
);
}
public boolean connectsToClass
(int roadClass
) {
return classes
[roadClass
] > 0;
}
public String getClasses
() {
Formatter fmt =
new Formatter();
fmt.
format("[");
for (int c =
0; c
< 5; c++
) {
int n = classes
[c
];
if (n
> 0) {
fmt.
format("%d", c
);
if (n
> 1)
fmt.
format("(%d)", n
);
fmt.
format(",");
}
}
fmt.
format("]");
return fmt.
toString();
}
public int getNodeClass
() {
return nodeClass
;
}
public void setNodeClass
(int nodeClass
) {
this.
nodeClass = nodeClass
;
}
public int most
(int roadClass
) {
int f = classes
[roadClass
];
if (f ==
1) {
int higher =
0;
for (int c = roadClass +
1; c
< 5; c++
) {
higher += classes
[c
];
}
if (higher ==
0) {
for (int c =
0; c
< roadClass
; c++
) {
if (classes
[c
] > 0)
return c
;
}
}
}
return roadClass
;
}
public int findFirstCross
() {
int high =
0;
for (int c =
1; c
< 5; c++
) {
high += classes
[c
];
}
if (high
> 1) {
for (int c =
1; c
< 5; c++
) {
if (classes
[c
] > 0)
return c
;
}
}
return 0;
}
public int connectionsAtClass
(int roadClass
) {
return classes
[roadClass
];
}
public int higherConnectionsCount
(int roadClass
) {
int count =
0;
for (int c = roadClass+
1; c
< 5; c++
)
count += classes
[c
];
return count
;
}
public int nClasses
() {
return Integer.
bitCount(classSet
);
}
public void addRestriction
(RouteCenter.
Restriction restr
) {
if (restrictions ==
null)
restrictions =
new ArrayList<>();
restrictions.
add(restr
);
}
public List<RouteCenter.
Restriction> getRestrictions
() {
return restrictions
;
}
}