public <T> T evaluate(Object object, Class<T> context) {
    Point point;
    Expression param1 = parameters.get(0);

    if (param1.equals(ToDirectPositionFunction.SRS_NAME)) {

      if (parameters.size() > 5 || parameters.size() < 4) {
        throw new IllegalArgumentException(
            "Wrong number of parameters for toPoint function: "
                + parameters.toString()
                + ". Usage: toPoint('SRS_NAME'(optional), srsName(optional), point 1, point 2, gml:id(optional))");
      }
      CoordinateReferenceSystem crs = null;
      String srsName = parameters.get(1).evaluate(object, String.class);
      try {
        crs = CRS.decode((String) srsName);
      } catch (NoSuchAuthorityCodeException e) {
        throw new IllegalArgumentException(
            "Invalid or unsupported SRS name detected for toPoint function: "
                + srsName
                + ". Cause: "
                + e.getMessage());
      } catch (FactoryException e) {
        throw new RuntimeException("Unable to decode SRS name. Cause: " + e.getMessage());
      }
      GeometryFactory fac = new GeometryFactory(new PrecisionModel());
      point =
          fac.createPoint(
              new Coordinate(
                  parameters.get(2).evaluate(object, Double.class),
                  parameters.get(3).evaluate(object, Double.class)));
      // set attributes
      String gmlId = null;
      if (parameters.size() == 5) {
        gmlId = parameters.get(4).evaluate(object, String.class);
      }
      setUserData(point, crs, gmlId);
    } else {

      if (parameters.size() > 3 || parameters.size() < 2) {
        throw new IllegalArgumentException(
            "Wrong number of parameters for toPoint function: "
                + parameters.toString()
                + ". Usage: toPoint('SRS_NAME'(optional), srsName(optional), point 1, point 2, gml:id(optional))");
      }
      GeometryFactory fac = new GeometryFactory();

      point =
          fac.createPoint(
              new Coordinate(
                  param1.evaluate(object, Double.class),
                  parameters.get(1).evaluate(object, Double.class)));

      if (parameters.size() == 3) {
        String gmlId = parameters.get(2).evaluate(object, String.class);
        setUserData(point, null, gmlId);
      }
    }
    return (T) point;
  }
  private static void forceSRS(GetMapRequest getMap, String srs) {
    getMap.setSRS(srs);

    try {
      getMap.setCrs(CRS.decode(srs));
    } catch (NoSuchAuthorityCodeException e) {
      e.printStackTrace();
    } catch (FactoryException e) {
      e.printStackTrace();
    }
  }
  public void reproject(
      Coordinate coordinate, final CoordinateSystem source, final CoordinateSystem destiny) {
    try {

      Coordinate coordinateSource = new Coordinate();
      Coordinate coordinateTarget = new Coordinate();
      if (source.getName().startsWith("Geographics")) {
        coordinateSource.x = coordinate.y;
        coordinateSource.y = coordinate.x;
      } else {
        coordinateSource.x = coordinate.x;
        coordinateSource.y = coordinate.y;
      }

      CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:" + source.getEPSGCode());
      CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + destiny.getEPSGCode());

      MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);

      JTS.transform(coordinateSource, coordinateTarget, transform);

      if (destiny.getName().startsWith("Geographics")) {
        coordinate.x = coordinateTarget.y;
        coordinate.y = coordinateTarget.x;
      } else {
        coordinate.x = coordinateTarget.x;
        coordinate.y = coordinateTarget.y;
      }

    } catch (NoSuchAuthorityCodeException e) {
      e.printStackTrace();

    } catch (FactoryException e) {
      e.printStackTrace();

    } catch (VerifyError e) {
      e.printStackTrace();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 /** Creates a coordinate reference system from the specified code. */
 public CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
     throws FactoryException {
   String c = trimAuthority(code).toUpperCase();
   if (c.startsWith(PREFIX)) {
     c = c.substring(PREFIX.length());
   }
   final int i;
   try {
     i = Integer.parseInt(c);
   } catch (NumberFormatException exception) {
     // If a number can't be parsed, then this is an invalid authority code.
     NoSuchAuthorityCodeException e = noSuchAuthorityCode(CoordinateReferenceSystem.class, code);
     e.initCause(exception);
     throw e;
   }
   ensureInitialized();
   final CoordinateReferenceSystem crs = crsMap.get(i);
   if (crs != null) {
     return crs;
   }
   throw noSuchAuthorityCode(CoordinateReferenceSystem.class, code);
 }
  public void reproject(
      Coordinate coordinate, final CoordinateSystem source, final CoordinateSystem destiny) {
    try {

      // CRSAuthorityFactory crsFactory = FactoryFinder.getCRSAuthorityFactory("EPSG", null);
      CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:" + source.getEPSGCode());
      CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:" + destiny.getEPSGCode());
      MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);
      GeometryFactory h = AppContext.getApplicationContext().getGeometryFactory();
      h = new GeometryFactory(h.getPrecisionModel(), destiny.getEPSGCode());
      Coordinate coordinateFinal = coordinate;
      JTS.transform(coordinate, coordinateFinal, transform);
    } catch (NoSuchAuthorityCodeException e) {
      JOptionPane.showMessageDialog(null, e.getMessage());
    } catch (FactoryException e) {
      JOptionPane.showMessageDialog(null, e.getMessage());
    } catch (VerifyError e) {
      JOptionPane.showMessageDialog(null, e.getMessage());
    } catch (Exception e) {
      JOptionPane.showMessageDialog(null, e.getMessage());
    }
  }
  /**
   * This method tries to automatically determine SRS, bounding box and output size based on the
   * layers provided by the user and any other parameters.
   *
   * <p>If bounds are not specified by the user, they are automatically se to the union of the
   * bounds of all layers.
   *
   * <p>The size of the output image defaults to 512 pixels, the height is automatically determined
   * based on the width to height ratio of the requested layers. This is also true if either height
   * or width are specified by the user. If both height and width are specified by the user, the
   * automatically determined bounding box will be adjusted to fit inside these bounds.
   *
   * <p>General idea 1) Figure out whether SRS has been specified, fall back to EPSG:4326 2)
   * Determine whether all requested layers use the same SRS, - if so, try to do bounding box
   * calculations in native coordinates 3) Aggregate the bounding boxes (in EPSG:4326 or native) 4a)
   * If bounding box has been specified, adjust height of image to match 4b) If bounding box has not
   * been specified, but height has, adjust bounding box
   */
  public static void autoSetBoundsAndSize(GetMapRequest getMap) {
    // Get the layers
    List<MapLayerInfo> layers = getMap.getLayers();

    /** 1) Check what SRS has been requested */
    String reqSRS = getMap.getSRS();

    // if none, try to determine which SRS to use
    // and keep track of whether we can use native all the way
    boolean useNativeBounds = true;
    if (reqSRS == null) {
      reqSRS = guessCommonSRS(layers);
      forceSRS(getMap, reqSRS);
    }

    /** 2) Compare requested SRS */
    for (int i = 0; useNativeBounds && i < layers.size(); i++) {
      if (layers.get(i) != null) {
        String layerSRS = layers.get(i).getSRS();
        useNativeBounds =
            reqSRS.equalsIgnoreCase(layerSRS)
                && layers.get(i).getResource().getNativeBoundingBox() != null;
      } else {
        useNativeBounds = false;
      }
    }

    CoordinateReferenceSystem reqCRS;
    try {
      reqCRS = CRS.decode(reqSRS);
    } catch (Exception e) {
      throw new ServiceException(e);
    }

    // Ready to determine the bounds based on the layers, if not specified
    Envelope aggregateBbox = getMap.getBbox();
    boolean specifiedBbox = true;

    // If bbox is not specified by request
    if (aggregateBbox == null) {
      specifiedBbox = false;

      // Get the bounding box from the layers
      for (int i = 0; i < layers.size(); i++) {
        MapLayerInfo layerInfo = layers.get(i);
        ReferencedEnvelope curbbox;
        try {
          curbbox = layerInfo.getLatLongBoundingBox();
          if (useNativeBounds) {
            ReferencedEnvelope nativeBbox = layerInfo.getBoundingBox();
            if (nativeBbox == null) {
              try {
                CoordinateReferenceSystem nativeCrs = layerInfo.getCoordinateReferenceSystem();
                nativeBbox = curbbox.transform(nativeCrs, true);
              } catch (Exception e) {
                throw new ServiceException("Best effort native bbox computation failed", e);
              }
            }
            curbbox = nativeBbox;
          }
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
        if (aggregateBbox != null) {
          aggregateBbox.expandToInclude(curbbox);
        } else {
          aggregateBbox = curbbox;
        }
      }

      ReferencedEnvelope ref = null;
      // Reproject back to requested SRS if we have to
      if (!useNativeBounds && !reqSRS.equalsIgnoreCase(SRS)) {
        try {
          ref = new ReferencedEnvelope(aggregateBbox, CRS.decode("EPSG:4326"));
          aggregateBbox = ref.transform(reqCRS, true);
        } catch (ProjectionException pe) {
          ref.expandBy(-1 * ref.getWidth() / 50, -1 * ref.getHeight() / 50);
          try {
            aggregateBbox = ref.transform(reqCRS, true);
          } catch (FactoryException e) {
            e.printStackTrace();
          } catch (TransformException e) {
            e.printStackTrace();
          }
          // And again...
        } catch (NoSuchAuthorityCodeException e) {
          e.printStackTrace();
        } catch (TransformException e) {
          e.printStackTrace();
        } catch (FactoryException e) {
          e.printStackTrace();
        }
      }
    }

    // Just in case
    if (aggregateBbox == null) {
      forceSRS(getMap, DefaultWebMapService.SRS);
      aggregateBbox = DefaultWebMapService.BBOX;
    }

    // Start the processing of adjust either the bounding box
    // or the pixel height / width

    double bbheight = aggregateBbox.getHeight();
    double bbwidth = aggregateBbox.getWidth();
    double bbratio = bbwidth / bbheight;

    double mheight = getMap.getHeight();
    double mwidth = getMap.getWidth();

    if (mheight > 0.5 && mwidth > 0.5 && specifiedBbox) {
      // This person really doesnt want our help,
      // we'll warp it any way they like it...
    } else {
      if (mheight > 0.5 && mwidth > 0.5) {
        // Fully specified, need to adjust bbox
        double mratio = mwidth / mheight;
        // Adjust bounds to be less than ideal to meet spec
        if (bbratio > mratio) {
          // Too wide, need to increase height of bb
          double diff = ((bbwidth / mratio) - bbheight) / 2;
          aggregateBbox.expandBy(0, diff);
        } else {
          // Too tall, need to increase width of bb
          double diff = ((bbheight * mratio) - bbwidth) / 2;
          aggregateBbox.expandBy(diff, 0);
        }

        adjustBounds(reqSRS, aggregateBbox);

      } else if (mheight > 0.5) {
        mwidth = bbratio * mheight;
      } else {
        if (mwidth > 0.5) {
          mheight = (mwidth / bbratio >= 1) ? mwidth / bbratio : 1;
        } else {
          if (bbratio > 1) {
            mwidth = MAX_SIDE;
            mheight = (mwidth / bbratio >= 1) ? mwidth / bbratio : 1;
          } else {
            mheight = MAX_SIDE;
            mwidth = (mheight * bbratio >= 1) ? mheight * bbratio : 1;
          }

          // make sure OL output height is sufficient to show the OL scale bar fully
          if (mheight < MIN_OL_HEIGHT
              && ("application/openlayers".equalsIgnoreCase(getMap.getFormat())
                  || "openlayers".equalsIgnoreCase(getMap.getFormat()))) {
            mheight = MIN_OL_HEIGHT;
            mwidth = (mheight * bbratio >= 1) ? mheight * bbratio : 1;
          }
        }
      }

      // Actually set the bounding box and size of image
      getMap.setBbox(aggregateBbox);
      getMap.setWidth((int) mwidth);
      getMap.setHeight((int) mheight);
    }
  }
  private static void addSourceToRoute(Point p, boolean b) {
    // TODO Auto-generated method stub
    String[] redes = configProperties.getRedesNames();
    GeometryFactory fact = new GeometryFactory();
    try {
      if (redes != null) {

        NetworkManager networkMgr = NetworkModuleUtilWorkbench.getNetworkManager(context);

        CoordinateSystem coordSys = context.getLayerManager().getCoordinateSystem();
        if (coordSys != null) {
          p.setSRID(coordSys.getEPSGCode());
        }
        CoordinateReferenceSystem crs = CRS.decode("EPSG:" + coordSys.getEPSGCode());
        org.opengis.geometry.primitive.Point primitivePoint =
            GeographicNodeUtil.createISOPoint(p, crs);

        ExternalInfoRouteLN externalInfoRouteLN = new ExternalInfoRouteLN();
        ArrayList<VirtualNodeInfo> virtualNodesInfo = new ArrayList<VirtualNodeInfo>();
        for (int i = 0; i < redes.length; i++) {

          configuatorNetworks.put(
              redes[i], ((LocalGISNetworkManager) networkMgr).getAllNetworks().get(redes[i]));
          VirtualNodeInfo nodeInfo = null;
          try {
            nodeInfo =
                externalInfoRouteLN.getVirtualNodeInfo(
                    new GeopistaRouteConnectionFactoryImpl(),
                    primitivePoint,
                    networkMgr,
                    redes[i],
                    100);
          } catch (Exception e) {
            e.printStackTrace();
          }
          if (nodeInfo != null) {
            virtualNodesInfo.add(nodeInfo);
          }
        }
        if (virtualNodesInfo.size() == 0) return;
        Iterator<VirtualNodeInfo> it = virtualNodesInfo.iterator();
        double lastDistante = -1;
        VirtualNodeInfo selectedNodeInfo = null;
        while (it.hasNext()) {
          VirtualNodeInfo vNodeinfo = it.next();
          if (lastDistante == -1 || lastDistante > vNodeinfo.getDistance()) {
            selectedNodeInfo = vNodeinfo;
            lastDistante = vNodeinfo.getDistance();
          }
        }

        //
        //	((LocalGISNetworkManager)networkMgr).addNewVirtualNode(networkMgr.getNetwork(selectedNodeInfo.getNetworkName()).getGraph()
        //						, selectedNodeInfo.getEdge()
        //						, selectedNodeInfo.getRatio()
        //						, this);
        nodesInfo.put(selectedNodeInfo.hashCode(), selectedNodeInfo);
        //
        Coordinate coord = selectedNodeInfo.getLinestringVtoB().getCoordinateN(0);
        Point geom_nodes = fact.createPoint(coord);
        Feature feature = new BasicFeature(nodesFeatureCol.getFeatureSchema());
        feature.setGeometry(geom_nodes);
        //				feature.setAttribute("nodeId", new Integer(node.getID()));
        feature.setAttribute("nodeId", selectedNodeInfo.hashCode());
        sourcePointLayer.getFeatureCollectionWrapper().add(feature);

      } else {

      }
    } catch (NoSuchAuthorityCodeException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (FactoryException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }