package org.iplantc.phyloviewer.viewer.server; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.iplantc.phyloviewer.client.services.TreeIntersectService; import org.iplantc.phyloviewer.shared.math.Box2D; import org.iplantc.phyloviewer.shared.math.Vector2; import org.json.JSONException; import org.json.JSONObject; import org.postgis.PGgeometry; import org.postgis.Point; import org.postgis.Polygon; import com.google.gwt.user.server.rpc.RemoteServiceServlet; public class IntersectTreeServiceImpl extends RemoteServiceServlet implements TreeIntersectService { /** * */ private static final long serialVersionUID = -3415482053977170710L; @Override public String intersectTree(int treeId, double x, double y) { DataSource pool = (DataSource) this.getServletContext().getAttribute("db.connectionPool"); Connection connection = null; try { connection = pool.getConnection(); double distance = 0.015; double xMin = x - distance; double yMin = y - distance; double xMax = x + distance; double yMax = y + distance; String boxGeometry="BOX3D(" + xMin + " " + yMin + "," + xMax + " " + yMax + ")"; PreparedStatement statement = connection.prepareStatement("select node_id, asText(point), asText(bounding_box), ST_Distance(point,?) as distance from node_layout where point && ?::box3d and ST_Distance(point,?) < ? and tree_id=? order by distance limit 1"); String geometry = "SRID=-1;POINT(" + x + " " + y + ")"; statement.setString(1, geometry); statement.setString(2,boxGeometry); statement.setString(3, geometry); statement.setDouble(4, distance); statement.setInt(5,treeId); ResultSet rs = statement.executeQuery(); if(rs.next()) { Point point = (Point) PGgeometry.geomFromString(rs.getString(2)); Polygon polygon = (Polygon) PGgeometry.geomFromString(rs.getString(3)); Vector2 min = convertPoint(polygon.getPoint(0)); Vector2 max = convertPoint(polygon.getPoint(2)); int nodeId = rs.getInt(1); Vector2 position = convertPoint(point); Box2D boundingBox = new Box2D(min,max); connection.close(); try { JSONObject hit = new JSONObject(); hit.put("nodeId", nodeId); hit.put("position",vectorToJSON(position)); hit.put("boundingBox", boundingBoxToJSON(boundingBox)); JSONObject hitResult = new JSONObject(); hitResult.put("hit", hit); return hitResult.toString(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "{\"hit\":null}"; } static JSONObject vectorToJSON(Vector2 vector) throws JSONException { JSONObject object = new JSONObject(); object.put("x",vector.getX()); object.put("y",vector.getY()); return object; } static JSONObject boundingBoxToJSON(Box2D box) throws JSONException { JSONObject object = new JSONObject(); object.put("min",vectorToJSON(box.getMin())); object.put("max",vectorToJSON(box.getMax())); return object; } private Vector2 convertPoint(Point point) { double positionX = point.getX(); double positionY = point.getY(); Vector2 p = new Vector2(positionX,positionY); return p; } }