public void addOSMEdgeToSpatialIndex(OSMEdge osmEdge) {
    // System.out.println("added edge with ID " + osmEdge.getId());
    // counter__edge.put(osmEdge.getId(), osmEdge.getGeometry());	// store edges in the hash map

    Geometry env = osmEdge.getGeometry().getBoundary();
    //  (minx, miny), (maxx, miny), (maxx, maxy), (minx, maxy), (minx, miny).

    if (env.getNumGeometries() > 0) {
      Point p1 = (Point) env.getGeometryN(0);
      Point p2 = (Point) env.getGeometryN(1);

      si.add(
          new Rectangle((float) p1.getX(), (float) p1.getY(), (float) p2.getX(), (float) p2.getY()),
          osmEdge.getId());
    }
  }
  public void dumpBuffer(List<OSMEdge> edges, String filename) throws SchemaException, IOException {

    final SimpleFeatureType TYPE =
        DataUtilities.createType(
            "route",
            "location:LineString:srid=4326,"
                + // <- the geometry attribute: Polyline type
                "name:String,"
                + // <- a String attribute
                "number:Integer" // a number attribute
            );

    // 1. build a feature
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    ArrayList<SimpleFeature> features = new ArrayList<SimpleFeature>();

    Iterator<OSMEdge> iter = edges.iterator();
    while (iter.hasNext()) {
      OSMEdge o = iter.next();
      SimpleFeature feature = featureBuilder.buildFeature(null);
      feature.setDefaultGeometry(o.getGeometry());
      features.add(feature);
    }
    SimpleFeatureCollection collection =
        new ListFeatureCollection(TYPE, features); // FeatureCollections.newCollection();

    logger.info("Writing to shapefile " + filename);
    File newFile = new File(filename);
    // File newFile = getNewShapeFile(file);

    ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

    Map<String, Serializable> params = new HashMap<String, Serializable>();
    params.put("url", newFile.toURI().toURL());
    params.put("create spatial index", Boolean.TRUE);

    ShapefileDataStore newDataStore =
        (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    newDataStore.createSchema(TYPE);

    // You can comment out this line if you are using the createFeatureType method (at end of
    // class file) rather than DataUtilities.createType
    newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84);

    Transaction transaction = new DefaultTransaction("create");

    String typeName = newDataStore.getTypeNames()[0];
    SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);

    if (featureSource instanceof SimpleFeatureStore) {
      SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;

      featureStore.setTransaction(transaction);
      try {
        featureStore.addFeatures(collection);
        transaction.commit();
      } catch (Exception problem) {
        problem.printStackTrace();
        transaction.rollback();
      } finally {
        transaction.close();
      }
      // System.exit(0); // success!
    } else {
      logger.error(typeName + " does not support read/write access");
      // System.exit(1);	// exit program with status 1 (error)
    }
  }
  /**
   * Create a new graph, with linestrings read from the database (optionally using only a buffer
   * around a given track for the network)
   *
   * @param track GPS track consisting of a list of data points
   * @param bufferSize size of the buffer to select around the track
   * @param dumpFile if not empty, the path of a shapefile to dump the network into.
   */
  public void addLineStringsFromDatabase(
      ArrayList<Point> track, float bufferSize, String dumpFile) {
    setLineMergeGraphH4cked(new LineMergeGraphH4cked());
    distancesCalculated = false;

    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();

    // Query gpsResults = session.createQuery("from" );

    if (track == null) {
      Query result = session.createQuery("from OSMEdge");

      @SuppressWarnings("unchecked")
      Iterator<OSMEdge> iter = result.iterate();
      while (iter.hasNext()) {
        OSMEdge o = iter.next();
        LineString g = o.getGeometry();
        addLineString(g, o.getId(), o.getEnvtype(), o.getCyktype(), o.getGroenm());
        // let us add this thing to the spatial index
        addOSMEdgeToSpatialIndex(o);
      }
    } else {
      // let us join the nodes of the track to a linestring ....

      Iterator<Point> trackIter = track.iterator();
      Coordinate[] coords = new Coordinate[track.size()];
      int i = 0;
      while (trackIter.hasNext()) {
        Point p = trackIter.next();
        coords[i] = p.getCoordinate();
        i++;
      }
      if (i > 1) {
        LineString l = fact.createLineString(coords);

        Criteria testCriteria = session.createCriteria(OSMEdge.class);
        if (bufferSize > 0.) { // ... build a buffer ...
          Geometry buffer = l.buffer(bufferSize);
          //				testCriteria.add(SpatialRestrictions.within("geometry", buffer));
          testCriteria.add(SpatialRestrictions.intersects("geometry", buffer));
        }
        @SuppressWarnings("unchecked")
        List<OSMEdge> result = testCriteria.list();

        logger.info("Spatial query selected " + result.size() + " edges");

        Iterator<OSMEdge> iter = result.iterator();
        i = 0;
        while (iter.hasNext()) {
          i++;
          OSMEdge o = iter.next();
          LineString g = o.getGeometry();
          addLineString(g, o.getId(), o.getEnvtype(), o.getCyktype(), o.getGroenm());
          // let us add this thing to the spatial index
          addOSMEdgeToSpatialIndex(o);
        }

        // if required, dump the graph to a shapefile:
        if (dumpFile != "") {
          try {
            this.dumpBuffer(result, dumpFile);
            logger.info("buffer dumped");
          } catch (Exception e) {
            logger.error("error dumping buffer: " + e);
          }
        }
      } else {
        logger.error("error: track has <2 coordinates");
      }
    }

    session.disconnect();
  }