Beispiel #1
0
  public void addBuildings(final String buildingShapeFileName) {

    final GeometryFactory geometryFactory = new GeometryFactory();
    final WKTReader wktReader = new WKTReader(geometryFactory);

    final ShapeFileReader shapeFileReader = new ShapeFileReader();
    shapeFileReader.readFileAndInitialize(buildingShapeFileName);
    final Collection<SimpleFeature> features = shapeFileReader.getFeatureSet();

    for (SimpleFeature ft : features) {

      try {
        final Geometry geometry = wktReader.read((ft.getAttribute("the_geom")).toString());
        final String buildingType = ft.getAttribute("ANDAMAL_1T").toString();
        final int buildingSize = Integer.valueOf(ft.getAttribute("AREA").toString());
        final Building building = new Building(geometry, buildingSize);
        building.setBuildingType(buildingType);

        for (Zone zone : this.id2zone.values()) {
          if (zone.getGeometry() != null && zone.getGeometry().intersects(geometry)) {
            zone.addBuilding(building);
            break;
          }
        }

      } catch (ParseException e) {
        throw new RuntimeException(e);
      }
    }
  }
  /** @param args */
  public static void main(String[] args) {
    // TODO Auto-generated method stub

    String networkPath = args[0];
    String newNetworkPath = args[1];
    String shapeFilePath = args[2];

    // String shapeFile = "C:/Work/Roadpricing Scenarios/SiouxFalls/Network/SiouxFalls_nodes.shp";

    Scenario scenario = ScenarioUtils.createScenario(ConfigUtils.createConfig());

    new NetworkReaderMatsimV1(scenario).parse(networkPath);
    Network network = scenario.getNetwork();
    Map<Id<Node>, ? extends Node> nodes = network.getNodes();

    Double x = 0.0;
    Double y = 0.0;

    System.out.println(shapeFilePath);
    ShapeFileReader shapeFileReader = new ShapeFileReader();
    Collection<SimpleFeature> fts = shapeFileReader.readFileAndInitialize(shapeFilePath);
    log.info("Shape file contains " + fts.size() + " features!");

    for (SimpleFeature ft : fts) {
      Geometry geo = (Geometry) ft.getDefaultGeometry();
      Coordinate[] coordinates = geo.getCoordinates();
      Collection<Property> properties = ft.getProperties("Id");

      System.out.println(
          "Feature: "
              + ft.getID()
              + ","
              + ft.getIdentifier().toString()
              + ","
              + ft.getName().toString());

      for (int i = 0; i < coordinates.length; i++) {
        System.out.print(coordinates[i].x + "," + coordinates[i].y + "   ");
        x = coordinates[i].x;
        y = coordinates[i].y;
      }

      for (Property p : properties) {
        System.out.println("Value: " + p.getValue().toString());
        Node node = nodes.get(Id.create(p.getValue().toString(), Node.class));
        node.getCoord().setXY(x, y);
        System.out.println("Name: " + p.getName().toString());
        System.out.println("Descriptor: " + p.getDescriptor().toString());
      }
      System.out.println();
      System.out.println();

      NetworkWriter writer = new NetworkWriter(network);
      writer.write(newNetworkPath);
    }
  }
Beispiel #3
0
  public Map<String, Zone> getZonesInsideBoundary(final String zonesBoundaryShapeFileName) {

    final Collection<SimpleFeature> features =
        ShapeFileReader.getAllFeatures(zonesBoundaryShapeFileName);
    if (features.size() != 1) {
      throw new RuntimeException("not exactly one feature in shape file");
    }

    final SimpleFeature feature = features.iterator().next();
    final WKTReader wktreader = new WKTReader();
    final Geometry limitingPolygon;
    try {
      limitingPolygon = wktreader.read(feature.getAttribute("the_geom").toString());
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }

    final Map<String, Zone> result = new LinkedHashMap<String, Zone>();
    for (Map.Entry<String, Zone> id2zoneEntry : this.id2zone.entrySet()) {
      if (limitingPolygon.covers(id2zoneEntry.getValue().getGeometry())) {
        result.put(id2zoneEntry.getKey(), id2zoneEntry.getValue());
      }
    }
    return result;
  }
  public SpatialAveragingUtils(
      double xMin,
      double xMax,
      double yMin,
      double yMax,
      int noOfXbins,
      int noOfYbins,
      double smoothingRadius_m,
      String visBoundaryShapeFile,
      CoordinateReferenceSystem targetCRS) {
    this.xMin = xMin;
    this.xMax = xMax;
    this.yMin = yMin;
    this.yMax = yMax;
    this.noOfXbins = noOfXbins;
    this.noOfYbins = noOfYbins;

    this.smoothinRadiusSquared_m = smoothingRadius_m * smoothingRadius_m;
    this.area_in_smoothing_circle_sqkm =
        (Math.PI * smoothingRadius_m * smoothingRadius_m) / (1000. * 1000.);
    this.cellArea_sqkm =
        ((xMax - xMin) * (yMax - yMin)) / ((noOfXbins * noOfYbins) * (1000. * 1000.));
    this.featuresInVisBoundary = ShapeFileReader.getAllFeatures(visBoundaryShapeFile);
    this.targetCRS = targetCRS;
  }
  public void createMapping(CoordinateTransformation coordinateTransformation) throws Exception {
    network = scenario.getNetwork();

    log.info("Loading Network ... done");
    log.info("Nodes: " + network.getNodes().size());
    log.info("Links: " + network.getLinks().size());

    /*
     * read zones shape file
     */
    zones = new HashSet<SimpleFeature>();

    for (SimpleFeature feature : ShapeFileReader.getAllFeatures(shapeFile)) {
      zones.add(feature);
    }

    zonesMap = new TreeMap<Integer, SimpleFeature>();
    for (SimpleFeature zone : zones) {
      //			int id = Integer.valueOf(zone.getID().replace("postcode4.", ""));	// Object Id
      //			int id = ((Long)zone.getAttribute(1)).intValue();	// Zone Id
      int id = ((Long) zone.getAttribute(3)).intValue(); // PostCode
      zonesMap.put(id, zone);
    }

    /*
     * print zones
     */
    log.info("Using " + zones.size() + " zones.");

    log.info("Adding connector nodes and links...");
    addConnectorLinks();
    log.info("done.");

    log.info("writing network ...");
    new NetworkWriter(network).write(networkOutFile);
    log.info(" ... done.");

    log.info("writing kmz network ...");
    ObjectFactory kmlObjectFactory = new ObjectFactory();
    KMZWriter kmzWriter = new KMZWriter(kmzOutFile);

    KmlType mainKml = kmlObjectFactory.createKmlType();
    DocumentType mainDoc = kmlObjectFactory.createDocumentType();
    mainKml.setAbstractFeatureGroup(kmlObjectFactory.createDocument(mainDoc));

    KmlNetworkWriter kmlNetworkWriter;
    kmlNetworkWriter =
        new KmlNetworkWriter(
            network, new GeotoolsTransformation("EPSG:28992", "WGS84"), kmzWriter, mainDoc);

    mainDoc
        .getAbstractFeatureGroup()
        .add(kmlObjectFactory.createFolder(kmlNetworkWriter.getNetworkFolder()));
    kmzWriter.writeMainKml(mainKml);
    kmzWriter.close();
    log.info("... done.");
  }
  public void readShapeFile(String shapeFileString) {
    ShapeFileReader shapeFileReader = new ShapeFileReader();
    shapeFileReader.readFileAndInitialize(shapeFileString);

    ArrayList<Geometry> geometries = new ArrayList<Geometry>();
    for (SimpleFeature ft : shapeFileReader.getFeatureSet()) {
      Geometry geo = (Geometry) ft.getDefaultGeometry();
      // System.out.println(ft.getFeatureType());
      geometries.add(geo);
    }

    Coordinate[] coords = geometries.get(0).getCoordinates();
    coords[coords.length - 1] = coords[0];

    GeometryFactory geofac = new GeometryFactory();

    LinearRing shell = geofac.createLinearRing(coords);
    areaPolygon = geofac.createPolygon(shell, null);
  }
 public SpatialAveragingWriter(SpatialAveragingInputData inputData) {
   this.targetCRS = inputData.getTargetCRS();
   this.xMin = inputData.getMinX();
   this.xMax = inputData.getMaxX();
   this.yMin = inputData.getMinY();
   this.yMax = inputData.getMaxY();
   this.noOfXbins = inputData.getNoOfXbins();
   this.noOfYbins = inputData.getNoOfYbins();
   this.useVisBoundary = inputData.isUseVisBoundary();
   if (this.useVisBoundary)
     this.featuresInVisBoundary =
         ShapeFileReader.getAllFeatures(inputData.getVisBoundaryShapeFile());
 }
 // Main
 public static void main(String[] args)
     throws SQLException, NoConnectionException, IOException, InstantiationException,
         IllegalAccessException, ClassNotFoundException {
   Map<Id<ActivityFacility>, Double> maximums = new HashMap<Id<ActivityFacility>, Double>();
   Map<Id<ActivityFacility>, Polygon> masterAreas = new HashMap<Id<ActivityFacility>, Polygon>();
   ShapeFileReader shapeFileReader = new ShapeFileReader();
   Collection<SimpleFeature> features = shapeFileReader.readFileAndInitialize(POLYGONS_FILE);
   for (SimpleFeature feature : features)
     masterAreas.put(
         Id.create((Integer) feature.getAttribute(1), ActivityFacility.class),
         (Polygon) ((MultiPolygon) feature.getDefaultGeometry()).getGeometryN(0));
   DataBaseAdmin dataBaseRealState =
       new DataBaseAdmin(new File("./data/facilities/DataBaseRealState.properties"));
   ResultSet buildingsR =
       dataBaseRealState.executeQuery("SELECT type, longitude, latitude FROM building_directory");
   CoordinateTransformation coordinateTransformation =
       TransformationFactory.getCoordinateTransformation(
           TransformationFactory.WGS84, TransformationFactory.WGS84_TM);
   GeometryFactory factory = new GeometryFactory();
   while (buildingsR.next()) {
     Coord buildingCoord =
         coordinateTransformation.transform(
             new Coord(buildingsR.getDouble(2), buildingsR.getDouble(3)));
     Point p = factory.createPoint(new Coordinate(buildingCoord.getX(), buildingCoord.getY()));
     for (Entry<Id<ActivityFacility>, Polygon> polygon : masterAreas.entrySet())
       if (p.within(polygon.getValue())) {
         Double maximum = maximums.get(polygon.getKey());
         if (maximum == null) maximum = 0.0;
         maximum += getMaximum(buildingsR.getString(1), null);
         maximums.put(polygon.getKey(), maximum);
       }
   }
   dataBaseRealState.close();
   DataBaseAdmin dataBaseAux =
       new DataBaseAdmin(new File("./data/facilities/DataBaseAuxiliar.properties"));
   for (Entry<Id<ActivityFacility>, Double> maximum : maximums.entrySet())
     dataBaseAux.executeUpdate("INSERT INTO buildings VALUES");
   dataBaseAux.close();
 }
Beispiel #9
0
 public ZonalSystem(final String zonesShapeFileName) {
   final GeometryFactory geometryFactory = new GeometryFactory();
   final WKTReader wktReader = new WKTReader(geometryFactory);
   for (SimpleFeature ft : ShapeFileReader.getAllFeatures(zonesShapeFileName)) {
     try {
       final String zoneId = ft.getAttribute("ZONE").toString();
       final Zone zone = new Zone(zoneId);
       zone.setGeometry(wktReader.read((ft.getAttribute("the_geom")).toString()));
       this.id2zone.put(zoneId, zone);
     } catch (ParseException e) {
       throw new RuntimeException(e);
     }
   }
 }
Beispiel #10
0
  public Map<String, Geometry> readShapeFile(String filename, String attrString) {

    Map<String, Geometry> shapeMap = new HashMap<String, Geometry>();

    for (SimpleFeature ft : ShapeFileReader.getAllFeatures(filename)) {

      GeometryFactory geometryFactory = new GeometryFactory();
      WKTReader wktReader = new WKTReader(geometryFactory);
      Geometry geometry;

      try {
        geometry = wktReader.read((ft.getAttribute("the_geom")).toString());
        shapeMap.put(ft.getAttribute(attrString).toString(), geometry);

      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return shapeMap;
  }
Beispiel #11
0
  public Map<String, Geometry> readShapeFile(String filename, String attrString) {
    // attrString: Für Brandenburg: Nr
    // für OSM: osm_id

    Map<String, Geometry> shapeMap = new HashMap<String, Geometry>();

    for (SimpleFeature ft : ShapeFileReader.getAllFeatures(filename)) {

      GeometryFactory geometryFactory = new GeometryFactory();
      WKTReader wktReader = new WKTReader(geometryFactory);
      Geometry geometry;

      try {
        geometry = wktReader.read((ft.getAttribute("the_geom")).toString());
        shapeMap.put(ft.getAttribute(attrString).toString(), geometry);

      } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    return shapeMap;
  }
  public static void main(String[] args) throws Exception {

    String baseDir = "../../../shared-svn/projects/cottbus/data/scenarios/cottbus_scenario/";
    String networkFile = baseDir + "network_wgs84_utm33n.xml.gz";
    boolean useLanduse = true;
    String populationOutputDirectory = baseDir + "cb_spn_gemeinde_nachfrage_landuse_ohneTagebau/";

    //		String shapesOutputDirectory = populationOutputDirectory + "shapes_all_modes/";
    String shapesOutputDirectory = populationOutputDirectory + "shapes/";

    //		String populationOutputFile = populationOutputDirectory +
    // "commuter_population_wgs84_utm33n.xml.gz";
    String populationOutputFile =
        populationOutputDirectory + "commuter_population_wgs84_utm33n_car_only.xml.gz";
    OutputDirectoryLogging.initLoggingWithOutputDirectory(populationOutputDirectory);

    File shapes = new File(shapesOutputDirectory);
    if (!shapes.exists()) {
      shapes.mkdir();
    }

    Config config1 = ConfigUtils.createConfig();
    config1.network().setInputFile(networkFile);
    Scenario sc = ScenarioUtils.loadScenario(config1);

    CommuterDataReader cdr = new CommuterDataReader();
    cdr.addFilterRange(12071000);
    cdr.addFilter("12052000"); // 12052000 == cottbus stadt
    cdr.readFile(
        "../../../shared-svn/studies/countries/de/pendler_nach_gemeinden/brandenburg_einpendler.csv");
    //		cdr.getCommuterRelations().add(new CommuterDataElement("12052000", "12052000", 1000));

    String gemeindenBrandenburgShapeFile =
        "../../../shared-svn/studies/countries/de/brandenburg_gemeinde_kreisgrenzen/gemeinden/dlm_gemeinden.shp";
    ShapeFileReader gemeindenReader = new ShapeFileReader();
    Collection<SimpleFeature> gemeindenFeatures =
        gemeindenReader.readFileAndInitialize(gemeindenBrandenburgShapeFile);

    CommuterDemandWriter cdw =
        new CommuterDemandWriter(
            gemeindenFeatures,
            gemeindenReader.getCoordinateSystem(),
            cdr.getCommuterRelations(),
            MGC.getCRS(TransformationFactory.WGS84_UTM33N));
    // landuse
    if (useLanduse) {
      DgLanduseReader landuseReader = new DgLanduseReader();
      Tuple<Collection<SimpleFeature>, CoordinateReferenceSystem> homeLanduse =
          landuseReader.readLanduseDataHome();
      Tuple<Collection<SimpleFeature>, CoordinateReferenceSystem> workLanduse =
          landuseReader.readLanduseDataWork();
      cdw.addLanduse("home", homeLanduse);
      cdw.addLanduse("work", workLanduse);
    }
    //
    //		cdw.setScalefactor(1.0); // all modes
    cdw.setScalefactor(0.55); // car mode share
    //		cdw.setScalefactor(0.1); //testing

    cdw.computeDemand(sc);
    PopulationWriter populationWriter = new PopulationWriter(sc.getPopulation(), sc.getNetwork());
    populationWriter.write(populationOutputFile);
    log.info("population written to " + populationOutputFile);

    // write some test output
    Config config = ConfigUtils.createConfig();
    config.network().setInputFile(networkFile);
    config.plans().setInputFile(populationOutputFile);
    Scenario baseScenario = ScenarioUtils.loadScenario(config);

    String shapeFilename = shapesOutputDirectory + "commuter_population_home.shp";
    new DgPopulation2ShapeWriter(
            baseScenario.getPopulation(), MGC.getCRS(TransformationFactory.WGS84_UTM33N))
        .write("home", shapeFilename, MGC.getCRS(TransformationFactory.WGS84_UTM33N));
    shapeFilename = shapesOutputDirectory + "commuter_population_work.shp";
    new DgPopulation2ShapeWriter(
            baseScenario.getPopulation(), MGC.getCRS(TransformationFactory.WGS84_UTM33N))
        .write("work", shapeFilename, MGC.getCRS(TransformationFactory.WGS84_UTM33N));

    log.info("done!");
    OutputDirectoryLogging.closeOutputDirLogging();
  }
  private void run2(final Network network) throws Exception {
    log.info("running " + this.getClass().getName() + " module...");
    NetworkExpandNode neModule =
        new NetworkExpandNode(network, expansionRadius, this.linkSeparation);

    TreeMap<String, TreeMap<Integer, Id<Link>>> mSequences = new TreeMap<>();

    try (FileInputStream fis = new FileInputStream(this.mpDbfFileName)) {
      DbaseFileReader r =
          new DbaseFileReader(fis.getChannel(), true, IOUtils.CHARSET_WINDOWS_ISO88591);
      // get header indices
      int mpIdNameIndex = -1;
      int mpSeqNrNameIndex = -1;
      int mpTrpelIDNameIndex = -1;
      for (int i = 0; i < r.getHeader().getNumFields(); i++) {
        if (r.getHeader().getFieldName(i).equals(MP_ID_NAME)) {
          mpIdNameIndex = i;
        }
        if (r.getHeader().getFieldName(i).equals(MP_SEQNR_NAME)) {
          mpSeqNrNameIndex = i;
        }
        if (r.getHeader().getFieldName(i).equals(MP_TRPELID_NAME)) {
          mpTrpelIDNameIndex = i;
        }
      }
      if (mpIdNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_ID_NAME + "' not found.");
      }
      if (mpSeqNrNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_SEQNR_NAME + "' not found.");
      }
      if (mpTrpelIDNameIndex < 0) {
        throw new NoSuchFieldException("Field name '" + MP_TRPELID_NAME + "' not found.");
      }
      log.trace("  FieldName-->Index:");
      log.trace("    " + MP_ID_NAME + "-->" + mpIdNameIndex);
      log.trace("    " + MP_SEQNR_NAME + "-->" + mpSeqNrNameIndex);
      log.trace("    " + MP_TRPELID_NAME + "-->" + mpTrpelIDNameIndex);

      // create mp data structure
      // TreeMap<mpId,TreeMap<mpSeqNr,linkId>>
      log.info("  parsing meneuver paths dbf file...");
      while (r.hasNext()) {
        Object[] entries = r.readEntry();
        String mpId = entries[mpIdNameIndex].toString();
        int mpSeqNr = Integer.parseInt(entries[mpSeqNrNameIndex].toString());
        Id<Link> linkId = Id.create(entries[mpTrpelIDNameIndex].toString(), Link.class);
        TreeMap<Integer, Id<Link>> mSequence = mSequences.get(mpId);
        if (mSequence == null) {
          mSequence = new TreeMap<>();
          mSequences.put(mpId, mSequence);
        }
        if (mSequence.put(mpSeqNr, linkId) != null) {
          fis.close();
          throw new IllegalArgumentException(
              MP_ID_NAME + "=" + mpId + ": " + MP_SEQNR_NAME + " " + mpSeqNr + " already exists.");
        }
      }
      log.info("    " + mSequences.size() + " maneuvers sequences stored.");
      log.info("  done.");
      r.close();
    }

    // store the maneuver list of the nodes
    // TreeMap<NodeId,ArrayList<Tuple<MnId,MnFeatType>>>
    log.info("  parsing meneuver shape file...");
    TreeMap<Id<Node>, ArrayList<Tuple<String, Integer>>> maneuvers = new TreeMap<>();
    SimpleFeatureSource fs = ShapeFileReader.readDataFile(this.mnShpFileName);
    SimpleFeatureIterator fIt = fs.getFeatures().features();
    while (fIt.hasNext()) {
      SimpleFeature f = fIt.next();
      int featType = Integer.parseInt(f.getAttribute(MN_FEATTYP_NAME).toString());
      if ((featType == 2103) || (featType == 2102) || (featType == 2101)) {
        // keep 'Prohibited Maneuver' (2103), 'Restricted Maneuver' (2102) and 'Calculated/Derived
        // Prohibited Maneuver' (2101)
        Id<Node> nodeId = Id.create(f.getAttribute(MN_JNCTID_NAME).toString(), Node.class);
        ArrayList<Tuple<String, Integer>> ms = maneuvers.get(nodeId);
        if (ms == null) {
          ms = new ArrayList<>();
        }
        Tuple<String, Integer> m = new Tuple<>(f.getAttribute(MN_ID_NAME).toString(), featType);
        ms.add(m);
        maneuvers.put(nodeId, ms);
      } else if ((featType == 9401) || (featType == 2104)) {
        // ignore 'Bifurcation' (9401) and 'Priority Maneuver' (2104)
      } else {
        throw new IllegalArgumentException(
            "mnId="
                + f.getAttribute(MN_ID_NAME)
                + ": "
                + MN_FEATTYP_NAME
                + "="
                + featType
                + " not known.");
      }
    }
    fIt.close();
    log.info("    " + maneuvers.size() + " nodes with maneuvers stored.");
    log.info("  done.");

    // create a maneuver matrix for each given node and
    // expand those nodes
    log.info("  expand nodes according to the given manveuvers...");
    int nodesIgnoredCnt = 0;
    int nodesAssignedCnt = 0;
    int maneuverIgnoredCnt = 0;
    int maneuverAssignedCnt = 0;
    int virtualNodesCnt = 0;
    int virtualLinksCnt = 0;
    for (Map.Entry<Id<Node>, ArrayList<Tuple<String, Integer>>> entry : maneuvers.entrySet()) {
      Id<Node> nodeId = entry.getKey();
      if (network.getNodes().get(nodeId) == null) {
        log.trace(
            "  nodeid="
                + nodeId
                + ": maneuvers exist for that node but node is missing. Ignoring and proceeding anyway...");
        nodesIgnoredCnt++;
      } else {
        // node found
        Node n = network.getNodes().get(nodeId);
        // init maneuver matrix
        // TreeMap<fromLinkId,TreeMap<toLinkId,turnAllowed>>
        TreeMap<Id<Link>, TreeMap<Id<Link>, Boolean>> mmatrix = new TreeMap<>();
        // assign maneuvers for given node to the matrix
        ArrayList<Tuple<String, Integer>> ms = entry.getValue();
        for (Tuple<String, Integer> m : ms) {
          // get maneuver path sequence for given maneuver
          TreeMap<Integer, Id<Link>> mSequence = mSequences.get(m.getFirst());
          if (mSequence == null) {
            throw new Exception(
                "nodeid=" + nodeId + "; mnId=" + m.getFirst() + ": no maneuver sequence given.");
          }
          if (mSequence.size() < 2) {
            throw new Exception(
                "nodeid="
                    + nodeId
                    + "; mnId="
                    + m.getFirst()
                    + ": mSequenceSize="
                    + mSequence.size()
                    + " not alowed!");
          }
          // get the first element of the sequence, defining the start link for the maneuver
          Id<Link> firstLinkid = mSequence.values().iterator().next();
          // go through each other element (target link of the maneuver) of the sequence by sequence
          // number
          for (Id<Link> otherLinkId : mSequence.values()) {
            // get the start link and the target link of the maneuver
            Link inLink = n.getInLinks().get(Id.create(firstLinkid + "FT", Link.class));
            if (inLink == null) {
              inLink = n.getInLinks().get(Id.create(firstLinkid + "TF", Link.class));
            }
            Link outLink = n.getOutLinks().get(Id.create(otherLinkId + "FT", Link.class));
            if (outLink == null) {
              outLink = n.getOutLinks().get(Id.create(otherLinkId + "TF", Link.class));
            }
            if ((inLink != null) && (outLink != null)) {
              // start and target link found and they are incident to the given node
              if (m.getSecond() == 2102) {
                // restricted maneuver: given start and target link path is allowed to drive
                // store it to the matrix
                TreeMap<Id<Link>, Boolean> outLinkMap = mmatrix.get(inLink.getId());
                if (outLinkMap == null) {
                  outLinkMap = new TreeMap<>();
                }
                outLinkMap.put(outLink.getId(), Boolean.TRUE);
                mmatrix.put(inLink.getId(), outLinkMap);
              } else {
                // prohibited maneuver: given start and target link path is not allowed to drive
                // store it to the matrix
                TreeMap<Id<Link>, Boolean> outLinkMap = mmatrix.get(inLink.getId());
                if (outLinkMap == null) {
                  outLinkMap = new TreeMap<>();
                }
                outLinkMap.put(outLink.getId(), Boolean.FALSE);
                mmatrix.put(inLink.getId(), outLinkMap);
              }
              maneuverAssignedCnt++;
            } else {
              maneuverIgnoredCnt++;
            }
          }
        }
        // complete the matrix
        for (TreeMap<Id<Link>, Boolean> fromLinkEntry : mmatrix.values()) {
          // detect inlinks with restricted maneuvers
          boolean hasRestrictedManeuver = false;
          for (Boolean b : fromLinkEntry.values()) {
            if (b) {
              hasRestrictedManeuver = true;
            }
          }
          // add missing toLink maneuvers
          for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
            if (!fromLinkEntry.containsKey(toLinkId)) {
              fromLinkEntry.put(toLinkId, !hasRestrictedManeuver);
            }
          }
        }
        // add allowed maneuvers for fromLinks which were not assigned yet.
        for (Id<Link> fromLinkId : n.getInLinks().keySet()) {
          if (!mmatrix.containsKey(fromLinkId)) {
            mmatrix.put(fromLinkId, new TreeMap<Id<Link>, Boolean>());
            for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
              mmatrix.get(fromLinkId).put(toLinkId, Boolean.TRUE);
            }
          }
        }
        // remove all U-turns from the matrix
        if (this.removeUTurns) {
          for (Id<Link> fromLinkId : n.getInLinks().keySet()) {
            String str1 = fromLinkId.toString().substring(0, fromLinkId.toString().length() - 2);
            for (Id<Link> toLinkId : n.getOutLinks().keySet()) {
              String str2 = toLinkId.toString().substring(0, toLinkId.toString().length() - 2);
              if (str1.equals(str2)) {
                mmatrix.get(fromLinkId).put(toLinkId, Boolean.FALSE);
              }
            }
          }
        }
        // create arraylist with turn tuples
        ArrayList<TurnInfo> turns = new ArrayList<>();
        for (Map.Entry<Id<Link>, TreeMap<Id<Link>, Boolean>> fromLinkEntry : mmatrix.entrySet()) {
          Id<Link> fromLinkId = fromLinkEntry.getKey();
          for (Map.Entry<Id<Link>, Boolean> toLinkEntry : fromLinkEntry.getValue().entrySet()) {
            if (toLinkEntry.getValue()) {
              turns.add(new TurnInfo(fromLinkId, toLinkEntry.getKey()));
            }
          }
        }
        // expand the node
        Tuple<List<Node>, List<Link>> t = neModule.expandNode(nodeId, turns);
        virtualNodesCnt += t.getFirst().size();
        virtualLinksCnt += t.getSecond().size();
        nodesAssignedCnt++;
      }
    }
    log.info("    " + nodesAssignedCnt + " nodes expanded.");
    log.info("    " + maneuverAssignedCnt + " maneuvers assigned.");
    log.info("    " + virtualNodesCnt + " new nodes created.");
    log.info("    " + virtualLinksCnt + " new links created.");
    log.info(
        "    " + nodesIgnoredCnt + " nodes with given maneuvers (2103, 2102 or 2101) ignored.");
    log.info("    " + maneuverIgnoredCnt + " maneuvers ignored (while node was found).");
    log.info("  done.");
    log.info("done.");
  }
  public static void main(String[] args) {
    try {
      if (args.length > 0) {
        String file = args[0];
        Map<String, String> parameterMap = new XMLParameterParser().parseFile(file);
        String value;

        value = parameterMap.remove("basePath");
        if (value != null) basePath = value;

        value = parameterMap.remove("networkFile");
        if (value != null) networkFile = value;

        value = parameterMap.remove("zonalAttributesFile");
        if (value != null) zonalAttributesFile = value;

        value = parameterMap.remove("separator");
        if (value != null) separator = value;

        value = parameterMap.remove("zonalSHPFile");
        if (value != null) zonalSHPFile = value;

        value = parameterMap.remove("facilitiesFile");
        if (value != null) facilitiesFile = value;

        value = parameterMap.remove("facilitiesAttributesFile");
        if (value != null) facilitiesAttributesFile = value;

        value = parameterMap.remove("f2lFile");
        if (value != null) f2lFile = value;

        value = parameterMap.remove("facilitiesPerZone");
        if (value != null) facilitiesPerZone = Integer.parseInt(value);

        value = parameterMap.remove("validLinkTypes");
        if (value != null) validLinkTypes = CollectionUtils.stringToSet(value);

        for (String key : parameterMap.keySet())
          log.warn("Found parameter " + key + " which is not handled!");
      } else {
        log.error("No input config file was given. Therefore cannot proceed. Aborting!");
        return;
      }

      log.info("loading network ...");
      Config config = ConfigUtils.createConfig();
      config.network().setInputFile(basePath + networkFile);
      Scenario scenario = ScenarioUtils.loadScenario(config);
      log.info("done.\n");

      log.info("loading zonal attributes ...");
      boolean skipHeader = true;
      Map<Integer, Emme2Zone> zonalAttributes =
          new Emme2ZonesFileParser(basePath + zonalAttributesFile, separator).readFile(skipHeader);
      log.info("done.\n");

      log.info("loading zonal shp file ...");
      // use a TreeMap to be deterministic
      Map<Integer, SimpleFeature> zonalShapes = new TreeMap<Integer, SimpleFeature>();
      for (SimpleFeature feature : ShapeFileReader.getAllFeatures(basePath + zonalSHPFile)) {
        zonalShapes.put((Integer) feature.getAttribute(3), feature);
      }
      log.info("done.\n");

      log.info("identify nodes outside the model area ...");
      Set<Id<Node>> externalNodes = getExternalNodes(scenario, zonalShapes);
      log.info("\tfound " + externalNodes.size() + " nodes outside the mapped area");
      log.info("done.\n");

      /*
       * We have to create tta activities BEFORE filtering the network. They might also start
       * and end at highways. We do not know their real start and end positions. The coordinate
       * we know might only be the place where the agents enter the modeled area, which will
       * probably be by using a highway.
       */
      log.info("creating external facilities for tta activities ...");
      createExternalFacilities(scenario, externalNodes);
      log.info("done.\n");

      /*
       * Before creating the internal facilities, we can perform the links filtering.
       */
      log.info("removing links from network where no facilities should be attached to ...");
      List<Id<Link>> linksToRemove = new ArrayList<Id<Link>>();
      for (Link link : scenario.getNetwork().getLinks().values()) {
        String type = ((LinkImpl) link).getType();
        if (!validLinkTypes.contains(type)) linksToRemove.add(link.getId());
      }
      log.info("\tfound " + linksToRemove.size() + " links which do not match the criteria");
      for (Id<Link> linkId : linksToRemove)
        ((NetworkImpl) scenario.getNetwork()).removeLink(linkId);
      log.info(
          "\tprocessed network contains "
              + scenario.getNetwork().getLinks().size()
              + " valid links");
      log.info("done.\n");

      log.info("creating internal facilities ...");
      createInternalFacilities(scenario, zonalAttributes, zonalShapes);
      log.info("done.\n");

      log.info("writing facilities to links mapping to a file ...");
      createAndWriteF2LMapping(scenario);
      log.info("done.\n");

      log.info(
          "writing "
              + scenario.getActivityFacilities().getFacilities().size()
              + " facilities to a file ...");
      FacilitiesWriter facilitiesWriter = new FacilitiesWriter(scenario.getActivityFacilities());
      facilitiesWriter.write(basePath + facilitiesFile);
      new ObjectAttributesXmlWriter(scenario.getActivityFacilities().getFacilityAttributes())
          .writeFile(basePath + facilitiesAttributesFile);
      log.info("done.\n");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }