private static Point[] anglesToFeature(
     String spatialcontext, String viewpoint, Angle[] angles, Database db)
     throws ClientException, SQLException, Exception {
   ResultSet result = db.getViewpoint(spatialcontext, viewpoint);
   if (!result.next()) {
     throw new ClientException(
         "viewpoint " + viewpoint + " in spatialcontext " + spatialcontext + " does not exist",
         404);
   }
   String filename = Config.getProperty("pointcloudpath") + result.getString("filename");
   Transformation ptrans = new Transformation(result.getString("pointcloud_trans"));
   Transformation vtrans = new Transformation(result.getString("viewpoint_trans"));
   if (result.next()) {
     Config.warn(
         "more than one viewpoint in spatialcontext "
             + spatialcontext
             + " with name "
             + viewpoint
             + " in the database");
   }
   Point[] points = null;
   try (Pointcloud pc = new Pointcloud(filename, ptrans)) {
     points = pc.getPoints(angles);
     pc.close();
   } catch (Exception e) {
     throw e;
   }
   for (Point point : points) {
     point.transform(vtrans);
   }
   return points;
 }
 public static Response editFeature(
     int fid,
     String spatialcontext,
     String viewpoint,
     InputXML input,
     String img,
     int width,
     int height) {
   try (Database db = new Database()) {
     Point[] points = anglesToFeature(spatialcontext, viewpoint, input.getAngles(), db);
     GeoFeature feature =
         Util.pointsToFeature(points, input.getAngles(), input.getType(), false, 0);
     db.setFeature(fid, spatialcontext, feature.toWkt(), "wkt", 0);
     db.addMeasurement(fid, spatialcontext, viewpoint, input);
     /*HashMap<String, Double> visibility = checkVisibility(spatialcontext, feature, db);
     for (String vp : visibility.keySet()) {
     db.setVisibility(spatialcontext, fid, vp, visibility.get(vp) > VISIBILITY_TOLERANCE);
     }*/
     db.setVisibility(spatialcontext, fid, viewpoint, true);
     db.close();
     // insertImage(img, fid, width, height);
     return FeatureXML.getFeature(spatialcontext, fid);
   } catch (ClientException e) {
     return Config.getResult(e);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }
  public static Response importFeatures(
      String spatialcontext,
      String data,
      String format,
      String srid,
      String creator,
      String license) {
    try (Database db = new Database()) {
      String[] split = data.split("\\r?\\n");
      for (String content : split) {
        int fid = db.addFeature(spatialcontext, content, format, Integer.parseInt(srid));
        db.addImport(fid, creator, license);

        // TODO: Visibility Analysis
        GeoFeature feature = db.getFeature(spatialcontext, fid);
        HashMap<String, Double> visibility = checkVisibility(spatialcontext, feature, db, null);
        for (String vp : visibility.keySet()) {
          db.setVisibility(spatialcontext, fid, vp, visibility.get(vp) > VISIBILITY_TOLERANCE);
        }
      }
      db.close();
      return Config.getResult();
      // return
      // Response.seeOther(URI.create(Config.getProperty("gv_viewer"))).header("Access-Control-Allow-Origin", "*").build();
    } catch (ClientException e) {
      return Config.getResult(e);
    } catch (Exception e) {
      return Config.getResult(e);
    }
  }
  private static double getPrismPoint(
      String spatialcontext, String viewpoint, Database db, InputXML input, Point[] points)
      throws SQLException, ClientException, Exception {
    double prismPoint;
    if (input.getType().equals("PRISM")) {
      ResultSet result = db.getViewpoint(spatialcontext, viewpoint);
      if (!result.next()) {
        throw new ClientException(
            "viewpoint " + viewpoint + " in spatialcontext " + spatialcontext + " does not exist",
            404);
      }
      String filename = Config.getProperty("pointcloudpath") + result.getString("filename");
      Transformation trans = new Transformation(result.getString("pointcloud_trans"));
      trans.transform(new Transformation(result.getString("viewpoint_trans")));
      Transformation inv = trans.inverse();
      if (result.next()) {
        Config.warn(
            "more than one viewpoint in spatialcontext "
                + spatialcontext
                + " with name "
                + viewpoint
                + " in the database");
      }
      PlanarPolygon tmp = new PlanarPolygon(input.getAngles(), points);
      tmp.transform(inv);

      prismPoint = PTGInteraction.getPrismaPoint(tmp, filename);
      tmp.transform(trans);
    } else {
      prismPoint = 0;
    }
    return prismPoint;
  }
 public static Response deleteFeature(String spatialcontext, int fid) {
   try (Database db = new Database()) {
     db.removeFeature(fid, spatialcontext);
     File file = new File(Config.getProperty("screenshotpath") + fid + ".png");
     file.delete();
     return Config.getResult();
   } catch (ClientException e) {
     return Config.getResult(e);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }
 public static Response getFeature(String spatialcontext, InputXML input) {
   try (Database db = new Database()) {
     Point[] points = anglesToFeature(spatialcontext, input.getViewpoint(), input.getAngles(), db);
     GeoFeature feature =
         Util.pointsToFeature(points, input.getAngles(), input.getType(), false, 0);
     String message = Config.xml + "<feature>";
     message += "<geom>" + feature.toWkt() + "</geom>";
     return Config.getResult(message + "</feature>");
   } catch (ClientException e) {
     return Config.getResult(e);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }
 public static void insertImage(String img, int fid, int width, int height)
     throws FileNotFoundException, IOException {
   if (img != null && !img.isEmpty()) {
     img = img.replace(' ', '+');
     String encodingPrefix = "base64,";
     int contentStartIndex = img.indexOf(encodingPrefix) + encodingPrefix.length();
     byte[] imgData = Base64.decodeBase64(img.substring(contentStartIndex).getBytes());
     BufferedImage image = ImageIO.read(new ByteArrayInputStream(imgData));
     if (width == 0 || height == 0) {
       ImageIO.write(image, "png", new File(Config.getProperty("screenshotpath") + fid + ".png"));
     } else {
       BufferedImage resizedImage = resizeclip(image, width, height);
       ImageIO.write(
           resizedImage, "png", new File(Config.getProperty("screenshotpath") + fid + ".png"));
     }
   }
 }
 public static Response setScreenshot(
     String spatialcontext, int fid, String img, int width, int height) {
   try {
     insertImage(img, fid, width, height);
     return FeatureXML.getFeature(spatialcontext, fid);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }
 public static Response setVisibility(
     String spatialcontext, String viewpoint, int fid, boolean visible) {
   try (Database db = new Database()) {
     db.setVisibility(spatialcontext, fid, viewpoint, visible);
     db.close();
     return FeatureXML.getFeature(spatialcontext, fid);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }
  private static HashMap<String, Double> checkVisibility(
      String spatialcontext, GeoFeature feature, Database db, String viewpoint)
      throws SQLException, ClassNotFoundException, IOException {
    double tolerance;
    if (viewpoint == null || viewpoint.isEmpty()) {
      tolerance = POINTCLOUD_TOLERANCE;
    } else {
      ResultSet startViewpoint = db.getViewpoint(spatialcontext, viewpoint);
      if (startViewpoint.next()) {
        String filename =
            Config.getProperty("pointcloudpath") + startViewpoint.getString("filename");
        Transformation t = new Transformation(startViewpoint.getString("pointcloud_trans"));
        t.transform(new Transformation(startViewpoint.getString("viewpoint_trans")));
        feature.transform(t.inverse());
        tolerance = feature.getPointTol(filename);
        feature.transform(t);
        if (tolerance < POINTCLOUD_TOLERANCE) {
          tolerance = POINTCLOUD_TOLERANCE;
        }
      } else {
        tolerance = POINTCLOUD_TOLERANCE;
      }
    }
    // result.last();
    // int size = result.getRow();
    // result.beforeFirst();
    ResultSet result = db.getViewpoints(spatialcontext);
    HashMap<String, Double> visibility = new HashMap<>();
    while (result.next()) {
      // user.setStatus(result.getRow() * 90 / size);
      String filename = Config.getProperty("pointcloudpath") + result.getString("filename");
      Transformation t = new Transformation(result.getString("pointcloud_trans"));
      t.transform(new Transformation(result.getString("viewpoint_trans")));
      feature.transform(t.inverse());
      visibility.put(result.getString("name"), feature.visible(tolerance, filename));
      feature.transform(t);
    }

    return visibility;
  }
 public static Response setVisibility(String spatialcontext, int fid, String viewpoint) {
   try (Database db = new Database()) {
     GeoFeature feature = db.getFeature(spatialcontext, fid);
     HashMap<String, Double> visibility = checkVisibility(spatialcontext, feature, db, viewpoint);
     for (String vp : visibility.keySet()) {
       db.setVisibility(spatialcontext, fid, vp, visibility.get(vp) > VISIBILITY_TOLERANCE);
     }
     db.close();
     return FeatureXML.getFeature(spatialcontext, fid);
   } catch (Exception e) {
     return Config.getResult(e);
   }
 }