MATSIM
NetworkReaderTeleatlas.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * NetworkReaderTeleatlas.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2008 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.io;
22 
23 import java.io.IOException;
24 
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
27 import org.geotools.api.data.SimpleFeatureSource;
28 import org.geotools.api.feature.simple.SimpleFeature;
29 import org.geotools.api.geometry.BoundingBox;
30 import org.geotools.data.simple.SimpleFeatureIterator;
31 import org.matsim.api.core.v01.Coord;
32 import org.matsim.api.core.v01.Id;
39 
53 public final class NetworkReaderTeleatlas implements MatsimSomeReader {
54 
55  // ////////////////////////////////////////////////////////////////////
56  // member variables
57  // ////////////////////////////////////////////////////////////////////
58 
59  private final static Logger log = LogManager.getLogger(NetworkReaderTeleatlas.class);
60 
61  private final Network network;
62 
66  private final String jcShpFileName; // teleatlas junction shape file name
67 
71  private final String nwShpFileName; // teleatlas network shape file name
72 
82  public boolean ignoreFrcType8 = false;
83 
93  public boolean ignoreFrcType7onewayN = false;
94 
106 
116  public int minSpeedForNormalCapacity = 40; // km/h
117 
118  private static final String NODE_ID_NAME = "ID";
119  private static final String NODE_FEATTYP_NAME = "FEATTYP";
120  private static final String NODE_JNCTTYP_NAME = "JNCTTYP";
121 
122  private static final String LINK_ID_NAME = "ID";
123  private static final String LINK_FEATTYP_NAME = "FEATTYP";
124  private static final String LINK_FERRYTYP_NAME = "FT";
125  private static final String LINK_FJNCTID_NAME = "F_JNCTID";
126  private static final String LINK_TJNCTID_NAME = "T_JNCTID";
127  private static final String LINK_LENGTH_NAME = "METERS";
128  private static final String LINK_FRCTYP_NAME = "FRC";
129  private static final String LINK_ONEWAY_NAME = "ONEWAY";
130  private static final String LINK_SPEED_NAME = "KPH";
131  private static final String LINK_LANES_NAME = "LANES";
132 
133  // TODO balmermi: probably we also need to consider the following attributes
134  // but for the ch-teleatlas-net version 2008 it was not necessary
135  // PRIVATERD Private Road
136  // 0: No Special Restriction (default)
137  // 2: Not Publicly Accessible
138  // CONSTATUS Construction Status
139  // Blank: Not Under Construction (default)
140  // FT: Under Construction in Positive Direction
141  // N: Under Construction in Both Directions
142  // TF: Under Construction in Negative Direction
143  // F_BP From (Start) Blocked Passage
144  // 0: No Blocked Passage at Start Junction (default)
145  // 1: Blocked Passage at Start Junction
146  // T_BP To (End) Blocked Passage
147  // 0: No Blocked Passage at End Junction (default)
148  // 2: Blocked Passage at End Junction
149 
150  // ////////////////////////////////////////////////////////////////////
151  // constructors
152  // ////////////////////////////////////////////////////////////////////
153 
165  public NetworkReaderTeleatlas(final Network network, final String jcShpFileName, final String nwShpFileName) {
166  this.network = network;
167  this.jcShpFileName = jcShpFileName;
168  this.nwShpFileName = nwShpFileName;
169  }
170 
171  // ////////////////////////////////////////////////////////////////////
172  // read methods
173  // ////////////////////////////////////////////////////////////////////
174 
175  public void read() throws IOException {
176  log.info("reading nodes from Junction Shape file '" + this.jcShpFileName + "'...");
177  this.readNodesFromJCshp();
178  log.info("done.");
179  log.info("reading links from Network Shape file '" + this.nwShpFileName + "'...");
180  this.readLinksFromNWshp();
181  log.info("done.");
182  // TODO balmermi: adding date and check if you get more info from the input
183  // files to include into the name
184  network.setName("teleatlas");
185  }
186 
187  // ////////////////////////////////////////////////////////////////////
188 
221  private void readNodesFromJCshp() throws IOException {
222  int nCnt = network.getNodes().size();
223  SimpleFeatureSource fs = GeoFileReader.readDataFile(jcShpFileName);
224  SimpleFeatureIterator fIt = fs.getFeatures().features();
225  while (fIt.hasNext()) {
226  SimpleFeature f = fIt.next();
227  // get node attributes
228  // Coordinate c = f.getBounds().centre();
229  BoundingBox bb = f.getBounds();
230  Coord c = new Coord((bb.getMinX() + bb.getMaxX()) / 2.0, (bb.getMinY() + bb.getMaxY()) / 2.0);
231 
232  Object id = f.getAttribute(NODE_ID_NAME);
233  int feattyp = Integer.parseInt(f.getAttribute(NODE_FEATTYP_NAME).toString());
234  if ((feattyp != 4120) && (feattyp != 4220)) {
235  throw new IllegalArgumentException(NODE_ID_NAME + "=" + id + ": " + NODE_FEATTYP_NAME + "=" + feattyp + " not allowed.");
236  }
237  int jncttyp = Integer.parseInt(f.getAttribute(NODE_JNCTTYP_NAME).toString());
238  if ((jncttyp < 0) || (jncttyp == 1) || (jncttyp > 6)) {
239  throw new IllegalArgumentException(NODE_ID_NAME + "=" + id + ": " + NODE_JNCTTYP_NAME + "=" + jncttyp + " not allowed.");
240  }
241  if (id == null) {
242  throw new IllegalArgumentException("In " + jcShpFileName + ": There is at least one feature that does not have an ID set.");
243  }
244  String type = feattyp + "-" + jncttyp;
245  Node n = network.getFactory().createNode(Id.create(id.toString(), Node.class), c);
246  final String type1 = type;
247  Node r = n;
248  NetworkUtils.setType(r,type1);
249  network.addNode(n);
250  }
251  fIt.close();
252  nCnt = network.getNodes().size() - nCnt;
253  log.info(" " + nCnt + " nodes added to the network.");
254  }
255 
256  // ////////////////////////////////////////////////////////////////////
257 
344  private void readLinksFromNWshp() throws IOException {
345  int lCnt = network.getLinks().size();
346  int ignoreCnt = 0;
347  SimpleFeatureSource fs = GeoFileReader.readDataFile(this.nwShpFileName);
348  SimpleFeatureIterator fIt = fs.getFeatures().features();
349  while (fIt.hasNext()) {
350  SimpleFeature f = fIt.next();
351  boolean ignore = false;
352  // get link attributes
353  Object id = f.getAttribute(LINK_ID_NAME);
354  int featTyp = Integer.parseInt(f.getAttribute(LINK_FEATTYP_NAME).toString());
355  if ((featTyp != 4110) && (featTyp != 4130) && (featTyp != 4165)) {
356  throw new IllegalArgumentException(LINK_ID_NAME + "=" + id + ": " + LINK_FEATTYP_NAME + "=" + featTyp + " not allowed.");
357  }
358  int ferryType = Integer.parseInt(f.getAttribute(LINK_FERRYTYP_NAME).toString());
359  if ((ferryType < 0) || (ferryType > 2)) {
360  throw new IllegalArgumentException(LINK_ID_NAME + "=" + id + ": " + LINK_FERRYTYP_NAME + "=" + ferryType + " not allowed.");
361  }
362  Id<Node> fromJunctionId = Id.create(f.getAttribute(LINK_FJNCTID_NAME).toString(), Node.class);
363  Id<Node> toJunctionId = Id.create(f.getAttribute(LINK_TJNCTID_NAME).toString(), Node.class);
364  double length = Double.parseDouble(f.getAttribute(LINK_LENGTH_NAME).toString());
365  int linksType = Integer.parseInt(f.getAttribute(LINK_FRCTYP_NAME).toString());
366  if ((linksType < -1) || (linksType > 8)) {
367  throw new IllegalArgumentException(LINK_ID_NAME + "=" + id + ": " + LINK_FRCTYP_NAME + "=" + linksType + " not allowed.");
368  }
369  String oneway = f.getAttribute(LINK_ONEWAY_NAME).toString();
370  if (!oneway.equals(" ") && !oneway.equals("FT") && !oneway.equals("TF") && !oneway.equals("N")) {
371  throw new IllegalArgumentException(LINK_ID_NAME + "=" + id + ": " + LINK_ONEWAY_NAME + "=" + oneway + " not allowed.");
372  }
373  double speed = Double.parseDouble(f.getAttribute(LINK_SPEED_NAME).toString());
374  double lanes = Double.parseDouble(f.getAttribute(LINK_LANES_NAME).toString());
375  // ignore link where from node or to node is missing
376  Node fNode = network.getNodes().get(fromJunctionId);
377  Node tNode = network.getNodes().get(toJunctionId);
378  if ((fNode == null) || (tNode == null)) {
379  log.warn(" linkId=" + id.toString()
380  + ": at least one of the two junctions do not exist. Ignoring and proceeding anyway...");
381  ignore = true;
382  }
383  // ignore link that is not a 'Road Element' (4110) or a 'Ferry Connection Element' (4130)
384  // There are 'Address Area Boundary Element' (4165) links that will be ignored
385  if ((featTyp != 4110) && (featTyp != 4130)) {
386  log.trace(" linkId=" + id.toString() + ": ignoring " + LINK_FEATTYP_NAME + "=" + featTyp + ".");
387  ignore = true;
388  }
389  // ignore links FRC types = -1 [Not Applicable (for FeatTyp 4165)]
390  if (linksType < 0) {
391  log.trace(" linkId=" + id.toString() + ": ignoring " + LINK_FRCTYP_NAME + "=" + linksType + ".");
392  ignore = true;
393  }
394  // option flag: ignore links FRC type = 8 [Other Road]
395  if (this.ignoreFrcType8 && (7 < linksType)) {
396  log.trace(" linkId=" + id.toString() + ": ignoring " + LINK_FRCTYP_NAME + "=" + linksType + ".");
397  ignore = true;
398  }
399  // ignore links FRC types = 7 [Local Road of Minor Importance] that are ONEWAY = N [Closed in Both Directions]
400  // links with type < 7 also contains ONEWAY = N but should be open anyway....
401  if (this.ignoreFrcType7onewayN && ((linksType == 7) && oneway.equals("N"))) {
402  log.trace(" linkId=" + id.toString() + ": ignoring " + LINK_FRCTYP_NAME + "=" + linksType + " with " + LINK_ONEWAY_NAME
403  + "=" + oneway);
404  ignore = true;
405  }
406 
407  // simple rule for number of lanes (a lot of them are = 0, so we need to define something)
408  if (lanes < 1) {
409  if (linksType <= this.maxFrcTypeForDoubleLaneLink) {
410  lanes = 2;
411  } else {
412  lanes = 1;
413  }
414  }
415  // simple rule for setting capacities
416  double cap;
417  if (speed < minSpeedForNormalCapacity) {
418  cap = lanes * 1000;
419  } else {
420  cap = lanes * 2000;
421  }
422 
423  if (ignore) {
424  ignoreCnt++;
425  } else {
426  if (oneway.equals(" ") || oneway.equals("N")) {
427  Link l = network.getFactory().createLink(Id.create(id.toString() + "FT", Link.class), fNode, tNode);
428  l.setLength(length);
429  l.setFreespeed(speed / 3.6);
430  l.setCapacity(cap);
431  l.setNumberOfLanes(lanes);
432  NetworkUtils.setOrigId(l, id.toString() ) ;
433  NetworkUtils.setType(l, linksType + "-" + featTyp + "-" + ferryType);
434  l = network.getFactory().createLink(Id.create(id.toString() + "TF", Link.class), tNode, fNode);
435  l.setLength(length);
436  l.setFreespeed(speed / 3.6);
437  l.setCapacity(cap);
438  l.setNumberOfLanes(lanes);
439  NetworkUtils.setOrigId(l, id.toString() ) ;
440  NetworkUtils.setType(l, linksType + "-" + featTyp + "-" + ferryType);
441  } else if (oneway.equals("FT")) {
442  Link l = network.getFactory().createLink(Id.create(id.toString() + oneway, Link.class), fNode, tNode);
443  l.setLength(length);
444  l.setFreespeed(speed / 3.6);
445  l.setCapacity(cap);
446  l.setNumberOfLanes(lanes);
447  NetworkUtils.setOrigId(l, id.toString() ) ;
448  NetworkUtils.setType(l, linksType + "-" + featTyp + "-" + ferryType);
449  } else if (oneway.equals("TF")) {
450  Link l = network.getFactory().createLink(Id.create(id.toString() + oneway, Link.class), tNode, fNode);
451  l.setLength(length);
452  l.setFreespeed(speed / 3.6);
453  l.setCapacity(cap);
454  l.setNumberOfLanes(lanes);
455  NetworkUtils.setOrigId(l, id.toString() ) ;
456  NetworkUtils.setType(l, linksType + "-" + featTyp + "-" + ferryType);
457  } else {
458  throw new IllegalArgumentException("linkId=" + id.toString() + ": " + LINK_ONEWAY_NAME + "=" + oneway + " not known!");
459  }
460  }
461  }
462  fIt.close();
463 
464  network.setCapacityPeriod(3600.0);
465 
466  lCnt = network.getLinks().size() - lCnt;
467  log.info(" " + lCnt + " links added to the network layer.");
468  log.info(" " + ignoreCnt + " links ignored from the input shape file.");
469  }
470 
471  // ////////////////////////////////////////////////////////////////////
472  // print methods
473  // ////////////////////////////////////////////////////////////////////
474 
481  public final void printInfo(final String prefix) {
482  System.out.println(prefix + "configuration of " + this.getClass().getName() + ":");
483  System.out.println(prefix + " MATSim network:");
484  System.out.println(prefix + " ignoreFrcType8: " + ignoreFrcType8);
485  System.out.println(prefix + " ignoreFrcType7onewayN: " + ignoreFrcType7onewayN);
486  System.out.println(prefix + " maxFrcTypeForDoubleLaneLink: " + maxFrcTypeForDoubleLaneLink);
487  System.out.println(prefix + " minSpeedForNormalCapacity: " + minSpeedForNormalCapacity);
488  System.out.println(prefix + " junction shape:");
489  System.out.println(prefix + " jcShpFileName: " + jcShpFileName);
490  System.out.println(prefix + " NODE_ID_NAME: " + NODE_ID_NAME);
491  System.out.println(prefix + " NODE_FEATTYP_NAME: " + NODE_FEATTYP_NAME);
492  System.out.println(prefix + " NODE_JNCTTYP_NAME: " + NODE_JNCTTYP_NAME);
493  System.out.println(prefix + " network shape:");
494  System.out.println(prefix + " nwShpFileName: " + nwShpFileName);
495  System.out.println(prefix + " LINK_ID_NAME: " + LINK_ID_NAME);
496  System.out.println(prefix + " LINK_FEATTYP_NAME: " + LINK_FEATTYP_NAME);
497  System.out.println(prefix + " LINK_FERRYTYP_NAME: " + LINK_FERRYTYP_NAME);
498  System.out.println(prefix + " LINK_FJNCTID_NAME: " + LINK_FJNCTID_NAME);
499  System.out.println(prefix + " LINK_TJNCTID_NAME: " + LINK_TJNCTID_NAME);
500  System.out.println(prefix + " LINK_LENGTH_NAME: " + LINK_LENGTH_NAME);
501  System.out.println(prefix + " LINK_FRCTYP_NAME: " + LINK_FRCTYP_NAME);
502  System.out.println(prefix + " LINK_ONEWAY_NAME: " + LINK_ONEWAY_NAME);
503  System.out.println(prefix + " LINK_SPEED_NAME: " + LINK_SPEED_NAME);
504  System.out.println(prefix + " LINK_LANES_NAME: " + LINK_LANES_NAME);
505  System.out.println(prefix + "done.");
506  }
507 }
NetworkReaderTeleatlas(final Network network, final String jcShpFileName, final String nwShpFileName)
static void setOrigId(final Node node, final String id)
Map< Id< Node >, ? extends Node > getNodes()
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
Link createLink(final Id< Link > id, final Node fromNode, final Node toNode)
static SimpleFeatureSource readDataFile(final String filename)
void setCapacityPeriod(double capPeriod)
Map< Id< Link >, ? extends Link > getLinks()
Node createNode(final Id< Node > id, final Coord coord)
static void setType(Node node, final String type)