001/* *********************************************************************** * 002 * project: org.matsim.* 003 * LanesConsistencyChecker 004 * * 005 * *********************************************************************** * 006 * * 007 * copyright : (C) 2009 by the members listed in the COPYING, * 008 * LICENSE and WARRANTY file. * 009 * email : info at matsim dot org * 010 * * 011 * *********************************************************************** * 012 * * 013 * This program is free software; you can redistribute it and/or modify * 014 * it under the terms of the GNU General Public License as published by * 015 * the Free Software Foundation; either version 2 of the License, or * 016 * (at your option) any later version. * 017 * See also COPYING, LICENSE and WARRANTY file * 018 * * 019 * *********************************************************************** */ 020package org.matsim.lanes; 021 022import java.util.LinkedList; 023import java.util.List; 024 025import org.apache.log4j.Logger; 026import org.matsim.api.core.v01.Id; 027import org.matsim.api.core.v01.network.Link; 028import org.matsim.api.core.v01.network.Network; 029 030 031/** 032 * 033 * @author dgrether, tthunig 034 */ 035public final class LanesConsistencyChecker { 036 037 private static final Logger log = Logger.getLogger(LanesConsistencyChecker.class); 038 private Network network; 039 private Lanes lanes; 040 private boolean removeMalformed = false; 041 042 public LanesConsistencyChecker(Network net, Lanes laneDefs) { 043 this.network = net; 044 this.lanes = laneDefs; 045 } 046 047 public void checkConsistency() { 048 log.info("checking consistency..."); 049 List<Id<Link>> linksWithMalformedLanes = new LinkedList<>(); 050 for (LanesToLinkAssignment l2l : this.lanes.getLanesToLinkAssignments().values()){ 051 if (!isLaneOnLinkConsistent(l2l)){ 052 linksWithMalformedLanes.add(l2l.getLinkId()); 053 } 054 } 055 056 if (this.removeMalformed){ 057 for (Id<Link> linkId : linksWithMalformedLanes) { 058 this.lanes.getLanesToLinkAssignments().remove(linkId); 059 log.info("remove lanes on link " + linkId); 060 } 061 } 062 log.info("checked consistency. Lanes on " + linksWithMalformedLanes.size() + " links have been removed."); 063 } 064 065 private boolean isLaneOnLinkConsistent(LanesToLinkAssignment l2l) { 066 //check if link exists for each assignment of one or more lanes to a link 067 if (!this.network.getLinks().containsKey(l2l.getLinkId())) { 068 log.error("No link found for lanesToLinkAssignment on link Id(linkIdRef): " + l2l.getLinkId()); 069 return false; 070 } 071 //check length 072 else { 073 Link link = this.network.getLinks().get(l2l.getLinkId()); 074 for (Lane l : l2l.getLanes().values()){ 075 if (link.getLength() < l.getStartsAtMeterFromLinkEnd()) { 076 log.error("Link Id " + link.getId() + " is shorter than an assigned lane with id " + l.getId()); 077 return false; 078 } 079 } 080 } 081 082 //check toLinks or toLanes specified in the lanes 083 for (Lane lane : l2l.getLanes().values()) { 084 if (lane.getToLaneIds() != null) { 085 for (Id<Lane> toLaneId : lane.getToLaneIds()){ 086 if (! l2l.getLanes().containsKey(toLaneId)){ 087 log.error("Error: toLane not existing:"); 088 log.error(" Lane Id: " + lane.getId() + " on Link Id: " + l2l.getLinkId() + 089 " leads to Lane Id: " + toLaneId + " that is not existing!"); 090 return false; 091 // TODO just delete this toLane? 092 } 093 } 094 } 095 //check availability of toLink in network 096 else if (lane.getToLinkIds() != null){ 097 for (Id<Link> toLinkId : lane.getToLinkIds()) { 098 if (! this.network.getLinks().containsKey(toLinkId)){ 099 log.error("No link found in network for toLinkId " + toLinkId + " of laneId " + lane.getId() + " of link id " + l2l.getLinkId()); 100 return false; 101 // TODO just delete this toLink? 102 } else { 103 Link link = this.network.getLinks().get(l2l.getLinkId()); 104 if (! link.getToNode().getOutLinks().containsKey(toLinkId)){ 105 log.error("The given toLink " + toLinkId + " is not reachable from lane " + lane.getId() + " on link " + link.getId()); 106 return false; 107 // TODO just delete this toLink? 108 } 109 } 110 } 111 } 112 } 113 114 // comment this out, because not every out-link of a node has to be reached by every in-link. theresa, aug'17 115// //second check matching of link's outlinks and lane's toLinks 116// Link link = this.network.getLinks().get(l2l.getLinkId()); 117// log.info("Link id: " + l2l.getLinkId()); 118// Set<Id<Link>> toLinksFromLanes = new HashSet<>(); 119// for (Lane lane : l2l.getLanes().values()){ 120// if (lane.getToLinkIds() != null){ 121// toLinksFromLanes.addAll(lane.getToLinkIds()); 122// } 123// } 124// 125// for (Link nodeOutLink : link.getToNode().getOutLinks().values()){ 126// log.info("\t\thas outlink: " + nodeOutLink.getId()); 127// if (!toLinksFromLanes.contains(nodeOutLink.getId())){ 128// log.error("Error: Lane Outlink: "); 129// log.error("\t\tThe lanes of link " + link.getId() + " do not lead to all of the outlinks of the links toNode " + link.getToNode().getId() + " . The outlink " + nodeOutLink.getId() 130// + " is not reachable from the lanes of this link. "); 131// for (Lane lane : l2l.getLanes().values()){ 132// log.error("\t\tLane id: " + lane.getId()); 133// if (lane.getToLinkIds() != null){ 134// for (Id<Link> id : lane.getToLinkIds()){ 135// log.error("\t\t\t\thas toLinkId: " + id); 136// } 137// } 138// log.error("End: Lane Outlink Error Message"); 139// } 140// return false; 141// } 142// } 143 return true; 144 } 145 146 public boolean isRemoveMalformed() { 147 return removeMalformed; 148 } 149 150 public void setRemoveMalformed(boolean removeMalformed) { 151 this.removeMalformed = removeMalformed; 152 } 153 154}