21 package org.matsim.core.network.io;
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
40 import org.xml.sax.Attributes;
42 import java.util.HashSet;
45 import java.util.Stack;
55 final class NetworkReaderMatsimV2
extends MatsimXmlParser {
57 private final static String NETWORK =
"network";
58 private final static String LINKS =
"links";
59 private final static String NODE =
"node";
60 private final static String LINK =
"link";
61 private final Network network;
63 private final AttributesXmlReaderDelegate attributesDelegate =
new AttributesXmlReaderDelegate();
66 private final String externalInputCRS;
67 private final String targetCRS;
68 private CoordinateTransformation coordinateTransformation =
new IdentityTransformation();
70 private final static Logger log = LogManager.getLogger(NetworkReaderMatsimV2.class);
72 NetworkReaderMatsimV2(
73 final String inputCRS,
74 final String targetCRS,
75 final Network network) {
76 super(ValidationType.DTD_ONLY);
77 this.externalInputCRS = inputCRS;
78 this.targetCRS = targetCRS;
79 if (externalInputCRS != null && targetCRS != null) {
80 this.coordinateTransformation = TransformationFactory.getCoordinateTransformation(externalInputCRS, targetCRS);
81 ProjectionUtils.putCRS(network, targetCRS);
83 this.network = network;
87 public void startTag(
final String name,
final Attributes atts,
final Stack<String> context) {
89 case NODE -> startNode( atts );
90 case LINK -> startLink( atts );
91 case NETWORK -> startNetwork( atts );
92 case LINKS -> startLinks( atts );
93 case TAG_ATTRIBUTES, TAG_ATTRIBUTE -> attributesDelegate.startTag( name, atts, context, currentAttributes );
100 public void endTag(
final String name,
final String content,
final Stack<String> context) {
103 if (context.peek().equals(NETWORK)) {
104 String inputCRS = (String) network.getAttributes().getAttribute(ProjectionUtils.INPUT_CRS_ATT);
105 if (inputCRS != null && targetCRS != null) {
106 if (externalInputCRS != null) {
108 log.warn(
"coordinate transformation defined both in config and in input file: setting from input file will be used");
110 coordinateTransformation = TransformationFactory.getCoordinateTransformation(inputCRS, targetCRS);
111 ProjectionUtils.putCRS(network, targetCRS);
116 attributesDelegate.endTag(name, content, context);
121 private void startNetwork(
final Attributes atts) {
122 if (atts.getValue(
"type") != null) {
123 log.info(
"Attribute 'type' is deprecated. There's always only ONE network, where the links and nodes define, which " +
124 "transportation mode is allowed to use it (for the future)");
126 this.network.setName(atts.getValue(
"name"));
127 if (atts.getValue(
"capDivider") != null) {
128 log.warn(
"capDivider defined. it will be used but should be gone eventually. " +
129 "-- This is a weird comment, since the matsim public api tells to put this into the network rather than" +
130 " into the ``links''. kai, jun'11");
131 String capperiod = atts.getValue(
"capDivider") +
":00:00";
132 this.network.setCapacityPeriod(Time.parseTime(capperiod));
135 currentAttributes = network.getAttributes();
138 private void startLinks(
final Attributes atts) {
139 double capacityPeriod = 3600.0;
140 String capperiod = atts.getValue(
"capperiod");
141 if (capperiod != null) {
142 capacityPeriod = Time.parseTime(capperiod);
145 log.warn(
"capperiod was not defined. Using default value of " + Time.writeTime(capacityPeriod) +
".");
147 this.network.setCapacityPeriod(capacityPeriod);
149 String effectivecellsize = atts.getValue(
"effectivecellsize");
150 if (effectivecellsize == null){
151 this.network.setEffectiveCellSize(7.5);
153 this.network.setEffectiveCellSize(Double.parseDouble(effectivecellsize));
156 String effectivelanewidth = atts.getValue(
"effectivelanewidth");
157 if (effectivelanewidth == null) {
158 this.network.setEffectiveLaneWidth(3.75);
160 this.network.setEffectiveLaneWidth(Double.parseDouble(effectivelanewidth));
163 if ((atts.getValue(
"capPeriod") != null) || (atts.getValue(
"capDivider") != null) || (atts.getValue(
"capdivider") != null)) {
164 log.warn(
"Found capPeriod, capDivider and/or capdivider in the links element. They will be ignored, since they " +
165 "should be set in the network element. -- This is a weird warning, since setting them in the " +
166 "network element also produces a warning.");
167 log.warn(
"At this point, it seems that, in network.xml, one sets capperiod in the `links' section, but in the " +
168 "matsim api, the corresponding entry belongs into the `network' object. kai, jun'11") ;
172 private void startNode(
final Attributes atts) {
174 this.network.getFactory().createNode(
175 Id.create(atts.getValue(
"id"), Node.class),
177 this.network.addNode(node);
179 NetworkUtils.setType(node,atts.getValue(
"type"));
182 if (atts.getValue(NetworkUtils.ORIGID) != null) {
183 NetworkUtils.setOrigId( node, atts.getValue(NetworkUtils.ORIGID) ) ;
186 currentAttributes = node.getAttributes();
189 private Coord parseCoord(Attributes atts) {
190 final Coord c = atts.getValue(
"z" ) == null ?
192 Double.parseDouble(atts.getValue(
"x")),
193 Double.parseDouble(atts.getValue(
"y"))) :
198 return coordinateTransformation.transform( c );
201 private void startLink(
final Attributes atts) {
202 final String fromNodeStr = atts.getValue(
"from");
203 Node fromNode = this.network.getNodes().get(Id.create(fromNodeStr, Node.class));
204 if ( fromNode==null ) {
205 throw new RuntimeException(
"node id given by link cannot be dereferenced; node label=" + fromNodeStr ) ;
207 final String toNodeStr = atts.getValue(
"to");
208 Node toNode = this.network.getNodes().get(Id.create(toNodeStr, Node.class));
209 if ( toNode==null ) {
210 throw new RuntimeException(
"node id given by link cannot be dereferenced; node label=" + toNodeStr ) ;
212 Link l = this.network.getFactory().createLink(Id.create(atts.getValue(
"id"), Link.class), fromNode, toNode);
213 l.setLength(Double.parseDouble(atts.getValue(
"length")));
214 l.setFreespeed(Double.parseDouble(atts.getValue(
"freespeed")));
215 l.setCapacity(Double.parseDouble(atts.getValue(
"capacity")));
216 l.setNumberOfLanes(Double.parseDouble(atts.getValue(
"permlanes")));
217 this.network.addLink(l);
219 String value = atts.getValue(NetworkUtils.ORIGID);
220 if ( value != null ) {
221 NetworkUtils.setOrigId( (l), value ) ;
225 final String value = atts.getValue(NetworkUtils.TYPE);
226 if ( value != null ) {
227 NetworkUtils.setType( (l), value);
231 if (atts.getValue(
"modes") != null) {
232 String[] strModes = StringUtils.explode(atts.getValue(
"modes"),
',');
233 if ((strModes.length == 1) && strModes[0].isEmpty()) {
234 l.setAllowedModes(
new HashSet<String>());
236 Set<String> modes =
new HashSet<>();
237 for (String strMode : strModes) {
238 modes.add(strMode.trim().intern());
240 l.setAllowedModes(modes);
244 currentAttributes = l.getAttributes();
247 public void putAttributeConverters(Map<Class<?>, AttributeConverter<?>> converters) {
248 this.attributesDelegate.putAttributeConverters( converters );
static final String TAG_ATTRIBUTE
static final String TAG_ATTRIBUTES
static double parseDouble(String value)