21 package org.matsim.core.network;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
27 import org.apache.logging.log4j.LogManager;
28 import org.apache.logging.log4j.Logger;
39 import com.google.common.collect.ImmutableSortedSet;
41 class LinkImpl
implements Link {
43 private final static Logger log = LogManager.getLogger(Link.class);
49 private final Id<Link> id;
54 private double length = Double.NaN;
55 private double freespeed;
56 private double capacity;
57 private double nofLanes;
59 private Set<String> allowedModes = DEFAULT_ALLOWED_MODES;
61 private final Network network;
63 private static int fsWarnCnt = 0 ;
64 private static int cpWarnCnt = 0 ;
65 private static int plWarnCnt = 0 ;
66 private static int lengthWarnCnt = 0;
67 private static final int maxFsWarnCnt = 1;
68 private static final int maxCpWarnCnt = 1;
69 private static final int maxPlWarnCnt = 1;
70 private static final int maxLengthWarnCnt = 1;
72 private static final Set<String> DEFAULT_ALLOWED_MODES = HashSetCache.get(Set.of(TransportMode.car));
74 private final Attributes attributes =
new AttributesImpl();
76 LinkImpl(
final Id<Link>
id,
final Node from,
final Node to,
final Network network,
final double length,
final double freespeed,
final double capacity,
final double lanes) {
78 this.network = network;
81 this.setLength(length);
84 this.freespeed = freespeed;
85 this.checkFreespeedSemantics();
86 this.capacity = capacity;
87 this.checkCapacitySemantics();
88 this.nofLanes = lanes;
89 this.checkNumberOfLanesSemantics();
93 private void checkCapacitySemantics() {
100 if ((this.capacity <= 0.0) && (cpWarnCnt < maxCpWarnCnt) ) {
102 log.warn(
"capacity=" + this.capacity +
" of link id " + this.getId() +
" may cause problems");
103 if ( cpWarnCnt==maxCpWarnCnt ){
104 log.warn( Gbl.FUTURE_SUPPRESSED );
109 private void checkFreespeedSemantics() {
110 if ((this.freespeed <= 0.0) && (fsWarnCnt < maxFsWarnCnt) ) {
112 log.warn(
"freespeed=" + this.freespeed +
" of link id " + this.getId() +
" may cause problems");
113 if ( fsWarnCnt == maxFsWarnCnt )
114 log.warn( Gbl.FUTURE_SUPPRESSED) ;
118 private void checkNumberOfLanesSemantics(){
119 if ((this.nofLanes < 1) && (plWarnCnt < maxPlWarnCnt) ) {
121 log.warn(
"permlanes=" + this.nofLanes +
" of link id " + this.getId() +
" may cause problems");
122 if ( plWarnCnt == maxPlWarnCnt )
123 log.warn( Gbl.FUTURE_SUPPRESSED ) ;
127 private void checkLengthSemantics(){
128 if ((this.getLength() <= 0.0) && (lengthWarnCnt < maxLengthWarnCnt)) {
130 log.warn(
"length=" + this.length +
" of link id " + this.getId() +
" may cause problems");
131 if ( lengthWarnCnt == maxLengthWarnCnt )
132 log.warn(Gbl.FUTURE_SUPPRESSED) ;
143 public Node getFromNode() {
148 public final boolean setFromNode(
final Node node) {
154 public Node getToNode() {
159 public final boolean setToNode(
final Node node) {
167 public void setCapacity(
double capacityPerNetworkCapcityPeriod){
168 this.capacity = capacityPerNetworkCapcityPeriod;
169 this.checkCapacitySemantics();
173 public double getCapacity() {
174 return this.capacity;
178 public double getCapacity(
final double time) {
179 return this.capacity;
182 public double getCapacityPeriod() {
185 return network.getCapacityPeriod() ;
191 public double getFreespeed() {
192 return this.freespeed;
202 public double getFreespeed(
final double time) {
203 return this.freespeed;
207 public void setFreespeed(
double freespeed) {
208 this.freespeed = freespeed;
209 this.checkFreespeedSemantics();
213 public double getLength() {
218 public final void setLength(
double length) {
219 this.length = length;
220 this.checkLengthSemantics();
224 public double getNumberOfLanes() {
225 return this.nofLanes;
229 public double getNumberOfLanes(
final double time) {
230 return this.nofLanes;
234 public void setNumberOfLanes(
double lanes) {
235 this.nofLanes = lanes;
236 this.checkNumberOfLanesSemantics();
240 public final Set<String> getAllowedModes() {
241 return this.allowedModes;
245 public final void setAllowedModes(
final Set<String> modes) {
246 this.allowedModes = HashSetCache.get(modes);
250 public String toString() {
251 return super.toString() +
252 "[id=" + this.getId() +
"]" +
253 "[from_id=" + this.from.getId() +
"]" +
254 "[to_id=" + this.to.getId() +
"]" +
255 "[length=" + this.length +
"]" +
256 "[freespeed=" + this.freespeed +
"]" +
257 "[capacity=" + this.capacity +
"]" +
258 "[permlanes=" + this.nofLanes +
"]" +
259 "[modes=" + this.allowedModes ;
263 public Id<Link> getId() {
268 public Coord getCoord() {
269 Coord fromXY = getFromNode().getCoord();
270 Coord toXY = getToNode().getCoord();
271 return new Coord((fromXY.getX() + toXY.getX()) / 2.0, (fromXY.getY() + toXY.getY()) / 2.0);
275 public Attributes getAttributes() {
279 abstract static class HashSetCache {
280 private final static ConcurrentMap<Integer, Set<String>> cache =
new ConcurrentHashMap<>();
282 public static Set<String>
get(
final Set<String>
set) {
286 return cache.computeIfAbsent(
set.hashCode(), key -> ImmutableSortedSet.copyOf(
set));