MATSIM
NetworkUtils.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * NetworkUtils.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.*;
24 import java.util.function.Function;
25 
26 import javax.annotation.Nullable;
27 
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.logging.log4j.LogManager;
30 import org.apache.logging.log4j.Logger;
31 import org.matsim.api.core.v01.Coord;
32 import org.matsim.api.core.v01.Id;
38 import org.matsim.core.config.Config;
41 import org.matsim.core.gbl.Gbl;
50 
56 public final class NetworkUtils {
57 
58  private static final Logger log = LogManager.getLogger(NetworkUtils.class);
59 
60  private NetworkUtils() {
61  throw new IllegalStateException("Utility class");
62  }
63 
69  public static Network createNetwork() {
71  }
72 
76  public static Network createNetwork(Config config) {
77  return createNetwork(config.network());
78  }
79 
87  public static Network createNetwork(NetworkConfigGroup networkConfigGroup) {
88  LinkFactory linkFactory = new LinkFactoryImpl();
89 
90  if (networkConfigGroup.isTimeVariantNetwork()) {
91  linkFactory = new VariableIntervalTimeVariantLinkFactory();
92  }
93 
94  return new NetworkImpl(linkFactory);
95  }
96 
100  public static double[] getBoundingBox(final Collection<? extends Node> nodes) {
101  double[] bBox = new double[4];
102  bBox[0] = Double.POSITIVE_INFINITY;
103  bBox[1] = Double.POSITIVE_INFINITY;
104  bBox[2] = Double.NEGATIVE_INFINITY;
105  bBox[3] = Double.NEGATIVE_INFINITY;
106 
107  for (Node n : nodes) {
108  if (n.getCoord().getX() < bBox[0]) {
109  bBox[0] = n.getCoord().getX();
110  }
111  if (n.getCoord().getX() > bBox[2]) {
112  bBox[2] = n.getCoord().getX();
113  }
114  if (n.getCoord().getY() > bBox[3]) {
115  bBox[3] = n.getCoord().getY();
116  }
117  if (n.getCoord().getY() < bBox[1]) {
118  bBox[1] = n.getCoord().getY();
119  }
120  }
121  return bBox;
122  }
123 
127  public static Node[] getSortedNodes(final Network network) {
128  Node[] nodes = network.getNodes().values().toArray(Node[]::new);
129  Arrays.sort(nodes, Comparator.comparing(Identifiable::getId));
130  return nodes;
131  }
132 
138  public static List<Node> getNodes(final Network network, final String nodes) {
139  if (nodes == null) {
140  return new ArrayList<>(0);
141  }
142  String trimmed = nodes.trim();
143  if (trimmed.length() == 0) {
144  return new ArrayList<>(0);
145  }
146  String[] parts = trimmed.split("[ \t\n]+");
147  final List<Node> nodesList = new ArrayList<>(parts.length);
148 
149  for (String id : parts) {
150  Node node = network.getNodes().get(Id.create(id, Node.class));
151  if (node == null) {
152  throw new IllegalArgumentException("no node with id " + id);
153  }
154  nodesList.add(node);
155  }
156  return nodesList;
157  }
158 
162  public static Link[] getSortedLinks(final Network network) {
163  Link[] links = network.getLinks().values().toArray(Link[]::new);
164  Arrays.sort(links, Comparator.comparing(Identifiable::getId));
165  return links;
166  }
167 
173  public static List<Link> getLinks(final Network network, final String links) {
174  if (links == null) {
175  return new ArrayList<>(0);
176  }
177  String trimmed = links.trim();
178  if (trimmed.length() == 0) {
179  return new ArrayList<>(0);
180  }
181  String[] parts = trimmed.split("[ \t\n]+");
182  final List<Link> linksList = new ArrayList<>(parts.length);
183 
184  for (String id : parts) {
185  Link link = network.getLinks().get(Id.create(id, Link.class));
186  if (link == null) {
187  throw new IllegalArgumentException("no link with id " + id);
188  }
189  linksList.add(link);
190  }
191  return linksList;
192  }
193 
198  public static List<Id<Link>> getLinkIds(final String links) {
199  if (links == null) {
200  return new ArrayList<>(0);
201  }
202  String trimmed = links.trim();
203  if (trimmed.length() == 0) {
204  return new ArrayList<>(0);
205  }
206  String[] parts = trimmed.split("[ \t\n]+");
207  final List<Id<Link>> linkIdsList = new ArrayList<>(parts.length);
208 
209  for (String id : parts) {
210  linkIdsList.add(Id.create(id, Link.class));
211  }
212  return linkIdsList;
213  }
214 
215  public static List<Link> getLinks(final Network network, final List<Id<Link>> linkIds) {
216  List<Link> links = new ArrayList<>();
217  for (Id<Link> linkId : linkIds) {
218  Link link = network.getLinks().get(linkId);
219  if (link == null) {
220  throw new IllegalArgumentException("no link with id " + linkId);
221  }
222  links.add(link);
223  }
224  return links;
225  }
226 
227  public static List<Id<Link>> getLinkIds(final List<Link> links) {
228  List<Id<Link>> linkIds = new ArrayList<>();
229  if (links != null) {
230  for (Link link : links) {
231  linkIds.add(link.getId());
232  }
233  }
234  return linkIds;
235  }
236 
243  public static int getNumberOfLanesAsInt(final double time, final Link link) {
244  int numberOfLanes = (int) link.getNumberOfLanes(time);
245  return Math.max(1, numberOfLanes);
246  }
247 
248  public static int getNumberOfLanesAsInt(final Link link) {
249  int numberOfLanes = (int) link.getNumberOfLanes();
250  return Math.max(1, numberOfLanes);
251  }
252 
253 
254  public static boolean isMultimodal(final Network network) {
255  String mode = null;
256  boolean hasEmptyModes = false;
257  for (Link link : network.getLinks().values()) {
258  Set<String> modes = link.getAllowedModes();
259  if (modes.size() > 1) {
260  return true; // it must be multimodal with more than 1 mode
261  } else if (modes.size() == 1) {
262  String m2 = modes.iterator().next();
263  if (mode == null) {
264  if (hasEmptyModes) {
265  // i.e. we have a mode restriction on the current link but not mode restriction on some other link. => multi-modal
266  return true;
267  }
268  mode = m2;
269  // (memorize that we have seen a link with a mode restriction)
270  } else {
271  if (!m2.equals(mode)) {
272  // i.e. we have a mode restriction on the current link, and some other mode restriction on some other link. => multi-modal
273  return true;
274  }
275  // position here can be reached with "mode!=null" and "hasEmptyModes==true". Should return "true" here but does not.
276  // Works anyways, since (it seems to me) that that state (mode!=null, hasEmptyModes==true) can never be reached.
277  // ??? kai, feb'15
278  }
279  } else {
280  if (mode != null) {
281  // i.e. we have no mode restriction on the current link, but a mode restriction on some other link. => multi-modal:
282  return true;
283  }
284  hasEmptyModes = true;
285  // (memorize that we have seen a link without mode restrictions)
286  }
287  }
288  return false;
289 
290  }
291 
292  public static Link getConnectingLink(final Node fromNode, final Node toNode) {
293  for (Link link : fromNode.getOutLinks().values()) {
294  if (link.getToNode() == toNode) {
295  return link;
296  }
297  }
298  return null;
299  }
300 
306  public static Node getCloserNodeOnLink(Coord coord, Link link) {
307  // yyyy I don't think there is a test for this anywhere. kai, mar'14
308 
309  Node toNode = link.getToNode();
310  Node fromNode= link.getFromNode();
311 
312  double distanceToNode = getEuclideanDistance(coord, toNode.getCoord());
313  double distanceFromNode= getEuclideanDistance(coord, fromNode.getCoord());
314 
315  if(distanceToNode < distanceFromNode)
316  return toNode;
317  return fromNode;
318  }
319 
324  public static double getEuclideanDistance(Coord origin, Coord destination){
325  return CoordUtils.calcEuclideanDistance(origin, destination);
326  }
327 
331  public static double getEuclideanDistance(double x1, double y1, double x2, double y2){
332  return getEuclideanDistance(new Coord(x1,y1), new Coord(x2, y2));
333  }
334 
382  // TODO [balmermi] there should be only one 'getNearestLink' method
383  // which returns either the nearest 'left' or 'right' entry link, based on a global
384  // config param.
385  public static Link getNearestRightEntryLink(Network network, final Coord coord) {
386  Link nearestRightLink = null;
387  Link nearestOverallLink = null;
388  Node nearestNode = NetworkUtils.getNearestNode((network),coord);
389 
390  double[] coordVector = new double[2];
391  coordVector[0] = nearestNode.getCoord().getX() - coord.getX();
392  coordVector[1] = nearestNode.getCoord().getY() - coord.getY();
393 
394  // now find nearest link from the nearest node
395  double shortestRightDistance = Double.MAX_VALUE; // reset the value
396  double shortestOverallDistance = Double.MAX_VALUE; // reset the value
397  List<Link> incidentLinks = new ArrayList<>(nearestNode.getInLinks().values());
398  incidentLinks.addAll(nearestNode.getOutLinks().values());
399  for (Link link : incidentLinks) {
400  double dist = CoordUtils.distancePointLinesegment(link.getFromNode().getCoord(), link.getToNode().getCoord(), coord);
401  if (dist <= shortestRightDistance) {
402  // Generate a vector representing the link
403  double[] linkVector = new double[2];
404  linkVector[0] = link.getToNode().getCoord().getX()
405  - link.getFromNode().getCoord().getX();
406  linkVector[1] = link.getToNode().getCoord().getY()
407  - link.getFromNode().getCoord().getY();
408 
409  // Calculate the z component of cross product of coordVector and the link
410  double crossProductZ = coordVector[0]*linkVector[1] - coordVector[1]*linkVector[0];
411  // If coord lies to the right of the directed link, i.e. if the z component
412  // of the cross product is negative, set it as new nearest link
413  if (crossProductZ < 0) {
414  if (dist < shortestRightDistance) {
415  shortestRightDistance = dist;
416  nearestRightLink = link;
417  }
418  else { // dist == shortestRightDistance
419  if (link.getId().compareTo(nearestRightLink.getId()) < 0) {
420  shortestRightDistance = dist;
421  nearestRightLink = link;
422  }
423  }
424  }
425  }
426  if (dist < shortestOverallDistance) {
427  shortestOverallDistance = dist;
428  nearestOverallLink = link;
429  }
430  else if (dist == shortestOverallDistance) {
431  if (link.getId().compareTo(nearestOverallLink.getId()) < 0) {
432  shortestOverallDistance = dist;
433  nearestOverallLink = link;
434  }
435  }
436  }
437 
438  // Return the nearest overall link if there is no nearest link
439  // such that the given coord is on the right side of it
440  if (nearestRightLink == null) {
441  return nearestOverallLink;
442  }
443  return nearestRightLink;
444  }
445 
457  public static Link getNearestLink(Network network, final Coord coord) {
458  Link nearestLink = null;
459  Node nearestNode = NetworkUtils.getNearestNode((network),coord);
460  if ( nearestNode == null ) {
461  log.warn("nearestNode not found. Will probably crash eventually. Maybe network for requested mode does not exist (i.e. links not annotated accordingly)? Maybe run NetworkCleaner? " +
462  network) ;
463  return null ;
464  }
465 
466  if ( nearestNode.getInLinks().isEmpty() && nearestNode.getOutLinks().isEmpty() ) {
467  log.warn(network + "[found nearest node that has no incident links. Will probably crash eventually ... Maybe run NetworkCleaner?][node = " + nearestNode.getId() + "]" ) ;
468  }
469 
470  // now find nearest link from the nearest node
471  // [balmermi] it checks now ALL incident links, not only the outgoing ones.
472  // TODO [balmermi] Now it finds the first of the typically two nearest links (same nodes, other direction)
473  // It would be nicer to find the nearest link on the "right" side of the coordinate.
474  // (For Great Britain it would be the "left" side. Could be a global config param...)
475  double shortestDistance = Double.MAX_VALUE;
476  for (Link link : getIncidentLinks(nearestNode).values()) {
477  double dist = CoordUtils.distancePointLinesegment(link.getFromNode().getCoord(), link.getToNode().getCoord(), coord);
478  if (dist < shortestDistance) {
479  shortestDistance = dist;
480  nearestLink = link;
481  }
482  }
483  if ( nearestLink == null ) {
484  log.warn(network + "[nearestLink not found. Will probably crash eventually ... Maybe run NetworkCleaner?]" ) ;
485  }
486  return nearestLink;
487  }
488 
497  public static Link getLeftmostTurnExcludingU(Link inLink){
498 
499  TreeMap<Double, Link> result = getOutLinksSortedClockwiseByAngle(inLink);
500 
501  if (result.size() == 0){
502  return null;
503  }
504  return result.get(result.firstKey());
505  }
506 
525  public static TreeMap<Double, Link> getOutLinksSortedClockwiseByAngle(Link inLink){
526  Coord coordInLink = getVector(inLink);
527  double thetaInLink = Math.atan2(coordInLink.getY(), coordInLink.getX());
528  TreeMap<Double, Link> outLinksByOrientation = new TreeMap<>();
529 
530  for (Link outLink : inLink.getToNode().getOutLinks().values()) {
531  if (!(outLink.getToNode().equals(inLink.getFromNode()))) {
532  Coord coordOutLink = getVector(outLink);
533  double thetaOutLink = Math.atan2(coordOutLink.getY(), coordOutLink.getX());
534  double thetaDiff = thetaOutLink - thetaInLink;
535  if (thetaDiff < -Math.PI) {
536  thetaDiff += 2 * Math.PI;
537  } else if (thetaDiff > Math.PI) {
538  thetaDiff -= 2 * Math.PI;
539  }
540  outLinksByOrientation.put(-thetaDiff, outLink);
541  }
542  }
543  return outLinksByOrientation;
544  }
545 
546  private static Coord getVector(Link link){
547  double x = link.getToNode().getCoord().getX() - link.getFromNode().getCoord().getX();
548  double y = link.getToNode().getCoord().getY() - link.getFromNode().getCoord().getY();
549  return new Coord(x, y);
550  }
551 
552 
553  public static Map<Id<Node>, ? extends Node> getOutNodes(Node node) {
554  Map<Id<Node>, Node> nodes = new TreeMap<>();
555  for (Link link : node.getOutLinks().values()) {
556  Node outNode = link.getToNode();
557  nodes.put(outNode.getId(), outNode);
558  }
559  return nodes;
560  }
561 
562 
563  public static Map<Id<Link>, ? extends Link> getIncidentLinks(Node node) {
564  Map<Id<Link>, Link> links = new TreeMap<>(node.getInLinks());
565  links.putAll(node.getOutLinks());
566  return links;
567  }
568 
569 
570  public static Map<Id<Node>, ? extends Node> getInNodes(Node node) {
571  Map<Id<Node>, Node> nodes = new TreeMap<>();
572  for (Link link : node.getInLinks().values()) {
573  Node inNode = link.getFromNode();
574  nodes.put(inNode.getId(), inNode);
575  }
576  return nodes;
577  }
578 
579 
580  public static Map<Id<Node>, ? extends Node> getIncidentNodes(Node node) {
581  Map<Id<Node>, Node> nodes = new TreeMap<>(getInNodes(node));
582  nodes.putAll(getOutNodes(node));
583  return nodes;
584  }
585 
586 
587  public static Node createNode(Id<Node> id) {
588  return new NodeImpl(id);
589  }
590 
591 
592  public static Node createNode(Id<Node> id, Coord coord, String type) {
593  return new NodeImpl(id, coord, type);
594  }
595 
596 
597  public static Node createNode(Id<Node> id, Coord coord) {
598  return new NodeImpl(id, coord);
599  }
600 
601 
602  @Deprecated // use link.getAttributes()... directly. kai, dec'16
603  public static void setOrigId( final Node node, final String id ) {
604  if ( node instanceof NodeImpl ) {
605  ((NodeImpl)node).setOrigId( id ) ;
606  } else {
607  throw new RuntimeException("wrong implementation of interface Node to do this") ;
608  }
609  }
610 
611 
612  @Deprecated // use link.getAttributes()... directly. kai, dec'16
613  public static void setType(Node node, final String type) {
614  if ( node instanceof NodeImpl ) {
615  ((NodeImpl)node).setType( type ) ;
616  } else {
617  throw new RuntimeException("wrong implementation of interface Node to do this") ;
618  }
619  }
620 
621  @Deprecated // use link.getAttributes()... directly. kai, dec'16
622  public static String getOrigId( Node node ) {
623  if ( node instanceof NodeImpl ) {
624  return ((NodeImpl) node).getOrigId() ;
625  } else {
626  throw new RuntimeException("wrong implementation of interface Node to do this") ;
627  }
628  }
629 
630 
631  @Deprecated // use link.getAttributes()... directly. kai, dec'16
632  public static String getType( Node node ) {
633  if ( node instanceof NodeImpl ) {
634  return ((NodeImpl) node).getType() ;
635  } else {
636  throw new RuntimeException("wrong implementation of interface Node to do this") ;
637  }
638  }
639 
640 
645  public static double getFreespeedTravelTime( Link link ) {
646  return link.getLength() / link.getFreespeed() ;
647  }
652  public static double getFreespeedTravelTime( Link link, double time ) {
653  return link.getLength() / link.getFreespeed(time) ;
654  }
655 
656  public static final String ALLOWED_SPEED = "allowed_speed";
657  public static final String TYPE="type" ;
658  public static void setType( Link link , String type ) {
659 // if ( link instanceof LinkImpl ) {
660 // ((LinkImpl)link).setType2( type ) ;
661 // } else {
662 // throw new RuntimeException("wrong implementation of interface Link to do this") ;
663 // }
664  if ( type != null ) {
665  link.getAttributes().putAttribute(TYPE, type) ;
666  }
667  }
668  public static String getType(Link link) {
669 // if ( link instanceof LinkImpl ) {
670 // return ((LinkImpl)link).getType2() ;
671 // } else {
672 // throw new RuntimeException( "getType not possible for this implementation of interface Link" ) ;
673 // }
674  return (String) link.getAttributes().getAttribute(TYPE);
675  }
676 
681  public static String getHighwayType(Link link) {
682 
683  String type = (String) link.getAttributes().getAttribute(TYPE);
684 
685  if (type != null)
686  type = type.replaceFirst("^highway\\.", "");
687 
688  if (type == null || type.isBlank())
689  type = "unclassified";
690 
691  return type;
692  }
693 
697  public static double getAllowedSpeed(Link link) {
698 
699  Object speed = link.getAttributes().getAttribute(ALLOWED_SPEED);
700  if (speed == null)
701  return link.getFreespeed();
702 
703  if (speed instanceof Double s)
704  return s;
705  return Double.parseDouble(speed.toString());
706  }
707 
708  public static String getOrigId( Link link ) {
709 // if ( link instanceof LinkImpl ) {
710 // return ((LinkImpl)link).getOrigId2() ;
711 // } else {
712 // throw new RuntimeException("wrong implementation of Link interface do getOrigId" ) ;
713 // }
714  Object o = link.getAttributes().getAttribute(ORIGID);
715  return o == null ? null : o.toString();
716  }
717 
718  public static void setOrigId( Link link, String id ) {
719 // if ( link instanceof LinkImpl ) {
720 // ((LinkImpl) link).setOrigId2(id);
721 // } else {
722 // throw new RuntimeException("wrong implementation of interface Link to do setOrigId") ;
723 // }
724  if ( id != null ) {
725  link.getAttributes().putAttribute(ORIGID, id) ;
726  }
727  }
728 
729 
730  public static Link createLink(Id<Link> id, Node from, Node to, Network network, double length, double freespeed,
731  double capacity, double lanes) {
732  return new LinkImpl(id, from, to, network, length, freespeed, capacity, lanes);
733  }
734 
735  public static Link createAndAddLink(Network network, final Id<Link> id, final Node fromNode, final Node toNode, final double length, final double freespeed,
736  final double capacity, final double numLanes) {
737  return createAndAddLink(network, id, fromNode, toNode, length, freespeed, capacity, numLanes, null, null ) ;
738  }
739 
740  public static Link createAndAddLink(Network network, final Id<Link> id, final Node fromNode, final Node toNode, final double length, final double freespeed,
741  final double capacity, final double numLanes, final String origId, final String type) {
742  if (network.getNodes().get(fromNode.getId()) == null) {
743  throw new IllegalArgumentException(network+"[from="+fromNode+" does not exist]");
744  }
745 
746  if (network.getNodes().get(toNode.getId()) == null) {
747  throw new IllegalArgumentException(network+"[to="+toNode+" does not exist]");
748  }
749 
750  Link link = network.getFactory().createLink(id, fromNode, toNode) ;
751  link.setLength(length);
752  link.setFreespeed(freespeed);
753  link.setCapacity(capacity);
754  link.setNumberOfLanes(numLanes);
755  setType( link, type);
756  setOrigId( link, origId ) ;
757 
758  network.addLink( link ) ;
759 
760  return link;
761  }
762 
763 
764  public static void setNetworkChangeEvents(Network network, List<NetworkChangeEvent> events) {
765  if ( network instanceof TimeDependentNetwork ) {
766  ((TimeDependentNetwork)network).setNetworkChangeEvents(events);
767  } else {
768  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + "Network, TimeDependentNetwork" ) ;
769  }
770  }
771 
772 
773  public static Node createAndAddNode(Network network, final Id<Node> id, final Coord coord) {
774  if (network.getNodes().containsKey(id)) {
775  throw new IllegalArgumentException(network + "[id=" + id + " already exists]");
776  }
777  Node n = network.getFactory().createNode(id, coord);
778  network.addNode(n) ;
779  return n;
780  }
781 
782 
783  public static void addNetworkChangeEvent( Network network, NetworkChangeEvent event ) {
784  if ( network instanceof TimeDependentNetwork ) {
785  ((TimeDependentNetwork) network).addNetworkChangeEvent(event);
786  } else {
787  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + " Network, TimeDependentNetwork " ) ;
788  }
789  }
790 
791 
792  public static Queue<NetworkChangeEvent> getNetworkChangeEvents(Network network ) {
793  if ( network instanceof TimeDependentNetwork ) {
794  return ((TimeDependentNetwork) network).getNetworkChangeEvents() ;
795  } else {
796  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + " Network, TimeDependentNetwork " ) ;
797  }
798  }
799 
800 
801  public static Link getNearestLinkExactly(Network network, Coord coord) {
802  if ( network instanceof SearchableNetwork ) {
803  return ((SearchableNetwork) network).getNearestLinkExactly(coord) ;
804  } else {
805  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + " Network, SearchableNetwork " ) ;
806  }
807  }
808 
809 
810  public static Node getNearestNode(Network network, final Coord coord) {
811  if ( network instanceof SearchableNetwork ) {
812  return ((SearchableNetwork)network).getNearestNode(coord);
813  } else {
814  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + " Network, SearchableNetwork " ) ;
815  }
816  }
817 
818 
819  public static Collection<Node> getNearestNodes(Network network, final Coord coord, final double distance) {
820  if ( network instanceof SearchableNetwork ) {
821  return ((SearchableNetwork)network).getNearestNodes(coord, distance);
822  } else {
823  throw new RuntimeException( Gbl.WRONG_IMPLEMENTATION + " Network, SearchableNetwork" ) ;
824  }
825  }
826 
827  public static final String ORIGID = "origid";
828 
829  public static void runNetworkCleaner( Network network ) {
831  }
832  public static void runNetworkSimplifier( Network network ) {
833  new NetworkSimplifier().run(network) ;
834  }
835  public static void writeNetwork(Network network, String string) {
836  new NetworkWriter(network).write(string) ;
837  }
838 
839  public static Link findLinkInOppositeDirection(Link link) {
840  for (Link candidateLink : link.getToNode().getOutLinks().values()) {
841  if (candidateLink.getToNode().equals(link.getFromNode())) {
842  return candidateLink;
843  }
844  }
845  return null;
846  }
847 
848  private static final String ACCESSTIMELINKATTRIBUTEPREFIX = "accesstime_";
849  private static final String EGRESSTIMELINKATTRIBUTEPREFIX = "egresstime_";
850 
851  public static OptionalTime getLinkAccessTime(Link link, String routingMode){
852  String attribute = ACCESSTIMELINKATTRIBUTEPREFIX+routingMode;
853  Object o = link.getAttributes().getAttribute(attribute);
854  if (o!=null){
855  return OptionalTime.defined((double) o);
856  }
857  else return OptionalTime.undefined();
858  }
859 
860  public static void setLinkAccessTime(Link link, String routingMode, double accessTime){
861  String attribute = ACCESSTIMELINKATTRIBUTEPREFIX+routingMode;
862  link.getAttributes().putAttribute(attribute,accessTime);
863  }
864 
865  public static OptionalTime getLinkEgressTime(Link link, String routingMode) {
866  String attribute = EGRESSTIMELINKATTRIBUTEPREFIX + routingMode;
867  Object o = link.getAttributes().getAttribute(attribute);
868  if (o != null) {
869  return OptionalTime.defined((double) o);
870  } else return OptionalTime.undefined();
871  }
872 
873  public static void setLinkEgressTime(Link link, String routingMode, double egressTime) {
874  String attribute = EGRESSTIMELINKATTRIBUTEPREFIX + routingMode;
875  link.getAttributes().putAttribute(attribute, egressTime);
876  }
877 
878  public static Network readNetwork(String filename) {
879  return readNetwork(filename, ConfigUtils.createConfig());
880  }
881 
882  public static Network readNetwork(String filename, Config config) {
883  return readNetwork(filename, config.network());
884  }
885 
886  public static Network readNetwork(String filename, NetworkConfigGroup networkConfigGroup) {
887  Network network = createNetwork(networkConfigGroup);
888  new MatsimNetworkReader(network).readFile(filename);
889  return network;
890  }
891 
898  public static Network readNetwork(String filename, NetworkConfigGroup networkConfigGroup, CoordinateTransformation transformation) {
899  var network = readNetwork(filename, networkConfigGroup);
900  network.getNodes().values().parallelStream()
901  .forEach(node -> {
902  var transformedCoord = transformation.transform(node.getCoord());
903  node.setCoord(transformedCoord);
904  });
905  return network;
906  }
907 
908  public static void readNetwork(Network network, String string) {
909  new MatsimNetworkReader(network).readFile(string);
910  }
911 
921  public static boolean compare(Network expected, Network actual) {
922 
923  // check that all element from expected result are in tested network
924  for (Link link : expected.getLinks().values()) {
925  Link testLink = actual.getLinks().get(link.getId());
926  if (testLink == null) return false;
927  if (!testLinksAreEqual(link, testLink)) return false;
928  }
929 
930  for (Node node : expected.getNodes().values()) {
931  Node testNode = actual.getNodes().get(node.getId());
932  if (testNode == null) return false;
933  if (!testNodesAreEqual(node, testNode)) return false;
934  }
935 
936  // also check the other way around, to make sure there are no extra elements in the network
937  for (Link link : actual.getLinks().values()) {
938  Link expectedLink = expected.getLinks().get(link.getId());
939  if (expectedLink == null) return false;
940  }
941 
942  for (Node node : actual.getNodes().values()) {
943  Node expectedNode = expected.getNodes().get(node.getId());
944  if (expectedNode == null) return false;
945  }
946  return true;
947  }
948 
949  public static NetworkCollector getCollector() {
950  NetworkConfigGroup networkConfigGroup = new NetworkConfigGroup();
951  networkConfigGroup.setTimeVariantNetwork(false);
952  return getCollector(networkConfigGroup);
953  }
954 
955  public static NetworkCollector getCollector(Config config) {
956  return getCollector(config.network());
957  }
958 
959  public static NetworkCollector getCollector(NetworkConfigGroup networkConfigGroup) {
960  return new NetworkCollector(networkConfigGroup);
961  }
962 
963  private static boolean testLinksAreEqual(Link expected, Link actual) {
964 
965  DisallowedNextLinks actualDnl = getDisallowedNextLinks(actual);
966  DisallowedNextLinks expectedDnl = getDisallowedNextLinks(expected);
967 
968  return actual.getAllowedModes().containsAll(expected.getAllowedModes())
969  && expected.getCapacity() == actual.getCapacity()
970  && expected.getCapacityPeriod() == actual.getCapacityPeriod()
971  && expected.getFreespeed() == actual.getFreespeed()
972  && expected.getLength() == actual.getLength()
973  && expected.getNumberOfLanes() == actual.getNumberOfLanes()
974  && Objects.equals(expectedDnl, actualDnl);
975  }
976 
977  private static boolean testNodesAreEqual(Node expected, Node actual) {
978  return expected.getCoord().equals(actual.getCoord());
979  }
980 
987  public static Coord findNearestPointOnLink(Coord coord, Link link) {
989  }
990 
991  public static final String ORIG_GEOM = "origgeom";
992  public static List<Node> getOriginalGeometry(Link link) {
993 
994  // use a list since order is important
995  List<Node> result = new ArrayList<>();
996  result.add(link.getFromNode());
997  var attr = (String)link.getAttributes().getAttribute(ORIG_GEOM);
998 
999  if (!StringUtils.isBlank(attr)) {
1000  var data = attr.split(" ");
1001  for (String date : data) {
1002  var values = date.split(",");
1003  if (values.length != 3) throw new RuntimeException("expected three values per node but found: " + date);
1004  var coord = new Coord(Double.parseDouble(values[1]), Double.parseDouble(values[2]));
1005  var node = new NodeImpl(Id.createNodeId(values[0]), coord);
1006  result.add(node);
1007  }
1008  }
1009 
1010  result.add(link.getToNode());
1011  return result;
1012  }
1013 
1014  private static final String DISALLOWED_NEXT_LINKS_ATTRIBUTE = "disallowedNextLinks";
1015 
1016  @Nullable
1018  return (DisallowedNextLinks) link.getAttributes().getAttribute(DISALLOWED_NEXT_LINKS_ATTRIBUTE);
1019  }
1020 
1022  DisallowedNextLinks disallowedNextLinks = getDisallowedNextLinks(link);
1023  if (disallowedNextLinks == null) {
1024  disallowedNextLinks = new DisallowedNextLinks();
1025  setDisallowedNextLinks(link, disallowedNextLinks);
1026  }
1027  return disallowedNextLinks;
1028  }
1029 
1030  public static void setDisallowedNextLinks(Link link, DisallowedNextLinks disallowedNextLinks) {
1031  link.getAttributes().putAttribute(DISALLOWED_NEXT_LINKS_ATTRIBUTE, disallowedNextLinks);
1032  }
1033 
1034  public static boolean addDisallowedNextLinks(Link link, String mode, List<Id<Link>> linkIds) {
1035  DisallowedNextLinks disallowedNextLinks = getOrCreateDisallowedNextLinks(link);
1036  return disallowedNextLinks.addDisallowedLinkSequence(mode, linkIds);
1037  }
1038 
1039  public static void removeDisallowedNextLinks(Link link) {
1040  link.getAttributes().removeAttribute(DISALLOWED_NEXT_LINKS_ATTRIBUTE);
1041  }
1042 
1043  public static void copyAttributesExceptDisallowedNextLinks(Link from, Link to) {
1044  AttributesUtils.copyAttributesFromToExcept(from, to, DISALLOWED_NEXT_LINKS_ATTRIBUTE);
1045  }
1046 
1047  public static void addAllowedMode(Link link, String mode) {
1048  Set<String> modes = new HashSet<>(link.getAllowedModes());
1049  modes.add(mode);
1050  link.setAllowedModes(modes);
1051  }
1052 
1053  public static void removeAllowedMode(Link link, String mode) {
1054  Set<String> modes = new HashSet<>(link.getAllowedModes());
1055  modes.remove(mode);
1056  link.setAllowedModes(modes);
1057  }
1058 
1065  public static void restrictModesAndCleanNetwork(Network network, Function<Id<Link>, Set<String>> modesToRemoveByLinkId) {
1066  new NetworkModeRestriction(modesToRemoveByLinkId).run(network);
1067  }
1068 }
static Node [] getSortedNodes(final Network network)
static void setOrigId(final Node node, final String id)
static int getNumberOfLanesAsInt(final double time, final Link link)
static final String DISALLOWED_NEXT_LINKS_ATTRIBUTE
static double getAllowedSpeed(Link link)
static Link getConnectingLink(final Node fromNode, final Node toNode)
static Network readNetwork(String filename, NetworkConfigGroup networkConfigGroup)
static DisallowedNextLinks getOrCreateDisallowedNextLinks(Link link)
static void setLinkEgressTime(Link link, String routingMode, double egressTime)
Map< Id< Node >, ? extends Node > getNodes()
static boolean addDisallowedNextLinks(Link link, String mode, List< Id< Link >> linkIds)
static final String ACCESSTIMELINKATTRIBUTEPREFIX
static Link getNearestRightEntryLink(Network network, final Coord coord)
void setTimeVariantNetwork(final boolean timeVariantNetwork)
static double calcEuclideanDistance(Coord coord, Coord other)
static Node getCloserNodeOnLink(Coord coord, Link link)
static List< Link > getLinks(final Network network, final String links)
final NetworkConfigGroup network()
Definition: Config.java:411
static String getHighwayType(Link link)
static double [] getBoundingBox(final Collection<? extends Node > nodes)
static final String EGRESSTIMELINKATTRIBUTEPREFIX
static boolean isMultimodal(final Network network)
static Node createNode(Id< Node > id, Coord coord, String type)
Map< Id< Link >, ? extends Link > getInLinks()
static String getOrigId(Link link)
static Node createAndAddNode(Network network, final Id< Node > id, final Coord coord)
static Link createLink(Id< Link > id, Node from, Node to, Network network, double length, double freespeed, double capacity, double lanes)
static boolean compare(Network expected, Network actual)
static void setLinkAccessTime(Link link, String routingMode, double accessTime)
static String getOrigId(Node node)
static NetworkCollector getCollector(NetworkConfigGroup networkConfigGroup)
static void removeDisallowedNextLinks(Link link)
static Map< Id< Link >, ? extends Link > getIncidentLinks(Node node)
static Network readNetwork(String filename, Config config)
static OptionalTime getLinkEgressTime(Link link, String routingMode)
static Coord orthogonalProjectionOnLineSegment(final Coord lineFrom, final Coord lineTo, final Coord point)
static Link findLinkInOppositeDirection(Link link)
static Map< Id< Node >, ? extends Node > getIncidentNodes(Node node)
static Link getLeftmostTurnExcludingU(Link inLink)
static List< Node > getOriginalGeometry(Link link)
static Queue< NetworkChangeEvent > getNetworkChangeEvents(Network network)
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
static double getFreespeedTravelTime(Link link, double time)
static void runNetworkCleaner(Network network)
static Link getNearestLinkExactly(Network network, Coord coord)
static double distancePointLinesegment(final Coord lineFrom, final Coord lineTo, final Coord point)
static Collection< Node > getNearestNodes(Network network, final Coord coord, final double distance)
static Network createNetwork(NetworkConfigGroup networkConfigGroup)
static String getType(Node node)
static DisallowedNextLinks getDisallowedNextLinks(Link link)
static TreeMap< Double, Link > getOutLinksSortedClockwiseByAngle(Link inLink)
static Coord findNearestPointOnLink(Coord coord, Link link)
static NetworkCollector getCollector()
Link createLink(final Id< Link > id, final Node fromNode, final Node toNode)
static Link [] getSortedLinks(final Network network)
static String getType(Link link)
static Link getNearestLink(Network network, final Coord coord)
static void removeAllowedMode(Link link, String mode)
static List< Id< Link > > getLinkIds(final List< Link > links)
static< T extends Attributable > void copyAttributesFromToExcept(T from, T to, String exceptAttribute)
static NetworkCollector getCollector(Config config)
static void readNetwork(Network network, String string)
static void writeNetwork(Network network, String string)
Object putAttribute(final String attribute, final Object value)
static OptionalTime defined(double seconds)
boolean equals(final Object other)
Definition: Coord.java:107
static List< Id< Link > > getLinkIds(final String links)
static void restrictModesAndCleanNetwork(Network network, Function< Id< Link >, Set< String >> modesToRemoveByLinkId)
static void runNetworkSimplifier(Network network)
static double getEuclideanDistance(Coord origin, Coord destination)
Map< Id< Link >, ? extends Link > getLinks()
static void copyAttributesExceptDisallowedNextLinks(Link from, Link to)
Node createNode(final Id< Node > id, final Coord coord)
static Link createAndAddLink(Network network, final Id< Link > id, final Node fromNode, final Node toNode, final double length, final double freespeed, final double capacity, final double numLanes, final String origId, final String type)
static double getFreespeedTravelTime(Link link)
static Node createNode(Id< Node > id, Coord coord)
static boolean testLinksAreEqual(Link expected, Link actual)
static Link createAndAddLink(Network network, final Id< Link > id, final Node fromNode, final Node toNode, final double length, final double freespeed, final double capacity, final double numLanes)
static final String WRONG_IMPLEMENTATION
Definition: Gbl.java:250
final void readFile(final String filename)
static void setType(Node node, final String type)
static int getNumberOfLanesAsInt(final Link link)
static void setNetworkChangeEvents(Network network, List< NetworkChangeEvent > events)
static Map< Id< Node >, ? extends Node > getOutNodes(Node node)
static OptionalTime getLinkAccessTime(Link link, String routingMode)
static void setDisallowedNextLinks(Link link, DisallowedNextLinks disallowedNextLinks)
static List< Link > getLinks(final Network network, final List< Id< Link >> linkIds)
static Network createNetwork(Config config)
static Coord getVector(Link link)
Map< Id< Link >, ? extends Link > getOutLinks()
static Network readNetwork(String filename)
static boolean testNodesAreEqual(Node expected, Node actual)
static Network readNetwork(String filename, NetworkConfigGroup networkConfigGroup, CoordinateTransformation transformation)
static Node createNode(Id< Node > id)
static void addNetworkChangeEvent(Network network, NetworkChangeEvent event)
static List< Node > getNodes(final Network network, final String nodes)
static void setType(Link link, String type)
static void addAllowedMode(Link link, String mode)
static Id< Node > createNodeId(final long key)
Definition: Id.java:211
static Node getNearestNode(Network network, final Coord coord)
static void setOrigId(Link link, String id)
static double getEuclideanDistance(double x1, double y1, double x2, double y2)
static Config createConfig(final String context)
static Map< Id< Node >, ? extends Node > getInNodes(Node node)