MATSIM
LinkImpl.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * AbstractLink.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.network;
22 
23 import java.util.Set;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentMap;
26 
27 import org.apache.logging.log4j.LogManager;
28 import org.apache.logging.log4j.Logger;
29 import org.matsim.api.core.v01.Coord;
30 import org.matsim.api.core.v01.Id;
35 import org.matsim.core.gbl.Gbl;
38 
39 import com.google.common.collect.ImmutableSortedSet;
40 
41 /*deliberately package*/ class LinkImpl implements Link {
42 
43  private final static Logger log = LogManager.getLogger(Link.class);
44 
46  // member variables
48 
49  private final Id<Link> id;
50 
51  private Node from;
52  private Node to;
53 
54  private double length = Double.NaN;
55  private double freespeed;
56  private double capacity;
57  private double nofLanes;
58 
59  private Set<String> allowedModes = DEFAULT_ALLOWED_MODES;
60 
61  private final Network network;
62 
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;
71 
72  private static final Set<String> DEFAULT_ALLOWED_MODES = HashSetCache.get(Set.of(TransportMode.car));
73 
74  private final Attributes attributes = new AttributesImpl();
75 
76  /*deliberately package*/ 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) {
77  this.id = id;
78  this.network = network;
79  this.from = from;
80  this.to = to;
81  this.setLength(length);
82  //for the eventual time variant attributes don't call the setter as it must be overwritten in TimeVariantLinkImpl
83  //and thus causes problems during object initialization, dg nov 2010
84  this.freespeed = freespeed;
85  this.checkFreespeedSemantics();
86  this.capacity = capacity;
87  this.checkCapacitySemantics();
88  this.nofLanes = lanes;
89  this.checkNumberOfLanesSemantics();
90  // loop links have become an acceptable thing for matsim. kai, sep'19. --> warnings turned off
91  }
92 
93  private void checkCapacitySemantics() {
94  /*
95  * I see no reason why a freespeed and a capacity of zero should not be
96  * allowed! joh 9may2008
97  * The warning says that it _may_ cause problems. Not pretty if you want to get rid of warnings completely, but
98  * hopefully acceptable for the time being. kai, oct'10
99  */
100  if ((this.capacity <= 0.0) && (cpWarnCnt < maxCpWarnCnt) ) {
101  cpWarnCnt++ ;
102  log.warn("capacity=" + this.capacity + " of link id " + this.getId() + " may cause problems");
103  if ( cpWarnCnt==maxCpWarnCnt ){
104  log.warn( Gbl.FUTURE_SUPPRESSED );
105  }
106  }
107  }
108 
109  private void checkFreespeedSemantics() {
110  if ((this.freespeed <= 0.0) && (fsWarnCnt < maxFsWarnCnt) ) {
111  fsWarnCnt++ ;
112  log.warn("freespeed=" + this.freespeed + " of link id " + this.getId() +" may cause problems");
113  if ( fsWarnCnt == maxFsWarnCnt )
114  log.warn( Gbl.FUTURE_SUPPRESSED) ;
115  }
116  }
117 
118  private void checkNumberOfLanesSemantics(){
119  if ((this.nofLanes < 1) && (plWarnCnt < maxPlWarnCnt) ) {
120  plWarnCnt++ ;
121  log.warn("permlanes=" + this.nofLanes + " of link id " + this.getId() +" may cause problems");
122  if ( plWarnCnt == maxPlWarnCnt )
123  log.warn( Gbl.FUTURE_SUPPRESSED ) ;
124  }
125  }
126 
127  private void checkLengthSemantics(){
128  if ((this.getLength() <= 0.0) && (lengthWarnCnt < maxLengthWarnCnt)) {
129  lengthWarnCnt++;
130  log.warn("length=" + this.length + " of link id " + this.getId() + " may cause problems");
131  if ( lengthWarnCnt == maxLengthWarnCnt )
132  log.warn(Gbl.FUTURE_SUPPRESSED) ;
133  }
134  }
135 
136 
137 
139  // get methods
141 
142  @Override
143  public Node getFromNode() {
144  return this.from;
145  }
146 
147  @Override
148  public final boolean setFromNode(final Node node) {
149  this.from = node;
150  return true;
151  }
152 
153  @Override
154  public Node getToNode() {
155  return this.to;
156  }
157 
158  @Override
159  public final boolean setToNode(final Node node) {
160  this.to = node;
161  return true;
162  }
163 
164  // ---
165 
166  @Override
167  public void setCapacity(double capacityPerNetworkCapcityPeriod){
168  this.capacity = capacityPerNetworkCapcityPeriod;
169  this.checkCapacitySemantics();
170  }
171 
172  @Override
173  public double getCapacity() {
174  return this.capacity;
175  }
176 
177  @Override
178  public double getCapacity(final double time) { // not final since needed in TimeVariantLinkImpl
179  return this.capacity;
180  }
181 
182  public double getCapacityPeriod() {
183  // since the link has a back pointer to network, we can as well provide this here (????)
184  // TimeVariantLinkImpl needs this ... but why?
185  return network.getCapacityPeriod() ;
186  }
187 
188  // ---
189 
190  @Override
191  public double getFreespeed() {
192  return this.freespeed;
193  }
194 
201  @Override
202  public double getFreespeed(final double time) { // not final since needed in TimeVariantLinkImpl
203  return this.freespeed;
204  }
205 
206  @Override
207  public void setFreespeed(double freespeed) {
208  this.freespeed = freespeed;
209  this.checkFreespeedSemantics();
210  }
211 
212  @Override
213  public double getLength() {
214  return this.length;
215  }
216 
217  @Override
218  public final void setLength(double length) {
219  this.length = length;
220  this.checkLengthSemantics();
221  }
222 
223  @Override
224  public double getNumberOfLanes() {
225  return this.nofLanes;
226  }
227 
228  @Override
229  public double getNumberOfLanes(final double time) { // not final since needed in TimeVariantLinkImpl
230  return this.nofLanes;
231  }
232 
233  @Override
234  public void setNumberOfLanes(double lanes) {
235  this.nofLanes = lanes;
236  this.checkNumberOfLanesSemantics();
237  }
238 
239  @Override
240  public final Set<String> getAllowedModes() {
241  return this.allowedModes;
242  }
243 
244  @Override
245  public final void setAllowedModes(final Set<String> modes) {
246  this.allowedModes = HashSetCache.get(modes);
247  }
248 
249  @Override
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 ;
260  }
261 
262  @Override
263  public Id<Link> getId() {
264  return id;
265  }
266 
267  @Override
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);
272  }
273 
274  @Override
275  public Attributes getAttributes() {
276  return attributes;
277  }
278 
279  /*package*/ abstract static class HashSetCache {
280  private final static ConcurrentMap<Integer, Set<String>> cache = new ConcurrentHashMap<>();
281 
282  public static Set<String> get(final Set<String> set) {
283  if (set == null) {
284  return null;
285  }
286  return cache.computeIfAbsent(set.hashCode(), key -> ImmutableSortedSet.copyOf(set));
287  }
288  }
289 }