/webportal/src/main/java/org/ala/spatial/analysis/web/AreaAddressRadiusSelection.java

http://alageospatialportal.googlecode.com/ · Java · 204 lines · 166 code · 33 blank · 5 comment · 10 complexity · 6646ac3f43bfdd42617eca41bc068069 MD5 · raw file

  1. package org.ala.spatial.analysis.web;
  2. import au.org.emii.portal.composer.MapComposer;
  3. import au.org.emii.portal.menu.MapLayer;
  4. import au.org.emii.portal.menu.MapLayerMetadata;
  5. import com.vividsolutions.jts.geom.Coordinate;
  6. import com.vividsolutions.jts.geom.GeometryFactory;
  7. import com.vividsolutions.jts.geom.LinearRing;
  8. import com.vividsolutions.jts.geom.Polygon;
  9. import com.vividsolutions.jts.geom.Point;
  10. import com.vividsolutions.jts.io.WKTWriter;
  11. import java.net.URL;
  12. import java.net.URLEncoder;
  13. import java.util.List;
  14. import javax.measure.converter.UnitConverter;
  15. import javax.measure.unit.Unit;
  16. import org.ala.spatial.util.LayersUtil;
  17. import org.ala.spatial.util.Util;
  18. import org.codehaus.jackson.JsonNode;
  19. import org.codehaus.jackson.map.ObjectMapper;
  20. import org.geotools.factory.Hints;
  21. import org.geotools.geometry.jts.JTSFactoryFinder;
  22. import org.geotools.referencing.GeodeticCalculator;
  23. import org.geotools.referencing.crs.DefaultGeographicCRS;
  24. import org.zkoss.zk.ui.event.Event;
  25. import org.zkoss.zul.Button;
  26. import org.zkoss.zul.Doublebox;
  27. import org.zkoss.zul.Label;
  28. import org.zkoss.zul.Textbox;
  29. /**
  30. *
  31. * @author Adam
  32. */
  33. public class AreaAddressRadiusSelection extends AreaToolComposer {
  34. private Textbox addressBox;
  35. Doublebox dRadius;
  36. Label addressLabel;
  37. private Textbox displayGeom;
  38. //String layerName;
  39. Textbox txtLayerName;
  40. Button btnOk;
  41. Button btnClear;
  42. private double longitude;
  43. private double latitude;
  44. @Override
  45. public void afterCompose() {
  46. super.afterCompose();
  47. dRadius.setDisabled(true);
  48. btnOk.setDisabled(true);
  49. txtLayerName.setValue(getMapComposer().getNextAreaLayerName("My Area"));
  50. }
  51. public void onClick$btnOk(Event event) {
  52. if (!validate()) {
  53. return;
  54. }
  55. createRadiusFromAddress();
  56. ok = true;
  57. this.detach();
  58. }
  59. public void onClick$btnCreate(Event event) {
  60. createRadiusFromAddress();
  61. }
  62. public void onClick$btnCancel(Event event) {
  63. MapComposer mc = getMapComposer();
  64. this.detach();
  65. }
  66. public void createRadiusFromAddress() {
  67. String wkt = radiusFromAddress(addressBox.getText());
  68. if (wkt.contentEquals("none")) {
  69. return;
  70. } else {
  71. try {
  72. MapComposer mc = getMapComposer();
  73. layerName = (mc.getMapLayer(txtLayerName.getValue()) == null) ? txtLayerName.getValue() : mc.getNextAreaLayerName(txtLayerName.getValue());
  74. MapLayer mapLayer = mc.addWKTLayer(wkt, layerName, txtLayerName.getValue());
  75. MapLayerMetadata md = mapLayer.getMapLayerMetadata();
  76. if (md == null) {
  77. md = new MapLayerMetadata();
  78. mapLayer.setMapLayerMetadata(md);
  79. }
  80. md.setMoreInfo(LayersUtil.getMetadata(dRadius.getText() + "km radius around " + addressLabel.getValue() + " (" + longitude + ", " + latitude + ")"));
  81. displayGeom.setText(wkt);
  82. } catch (Exception e) {
  83. logger.error("Error adding WKT layer");
  84. }
  85. }
  86. }
  87. public String findAddressLine(String text) throws Exception {
  88. String url = "http://maps.google.com/maps/api/geocode/json?components=locality&sensor=false&address=" + URLEncoder.encode(text, "UTF-8");
  89. ObjectMapper mapper = new ObjectMapper();
  90. JsonNode node = mapper.readTree(new URL(url));
  91. return node.get("results").get(0).get("formatted_address").getTextValue();
  92. }
  93. public double[] findAddressLatLng(String text) throws Exception {
  94. String url = "http://maps.google.com/maps/api/geocode/json?components=locality&sensor=false&address=" + URLEncoder.encode(text, "UTF-8");
  95. ObjectMapper mapper = new ObjectMapper();
  96. JsonNode node = mapper.readTree(new URL(url));
  97. JsonNode latLngNode = node.get("results").get(0).get("geometry").get("location");
  98. return new double[]{
  99. latLngNode.get("lat").getDoubleValue(),
  100. latLngNode.get("lng").getDoubleValue()
  101. };
  102. }
  103. public void onClick$btnFindAddress(Event event) {
  104. try {
  105. String address = findAddressLine(addressBox.getText());
  106. addressLabel.setValue(address);
  107. dRadius.setDisabled(false);
  108. btnOk.setDisabled(false);
  109. } catch (Exception ge) {
  110. ge.printStackTrace();
  111. }
  112. }
  113. private String radiusFromAddress(String address) {
  114. try {
  115. double[] latlng = findAddressLatLng(address);
  116. double radius = dRadius.getValue() * 1000.0;
  117. return Util.createCircleJs(latlng[1], latlng[0], radius);
  118. } catch (Exception ge) {
  119. return "none";
  120. }
  121. }
  122. private String createCircle(double x, double y, final double RADIUS) {
  123. return createCircle(x, y, RADIUS, 50);
  124. }
  125. private String createCircle(double x, double y, final double RADIUS, int sides) {
  126. try {
  127. Hints hints = new Hints(Hints.CRS, DefaultGeographicCRS.WGS84);
  128. GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(hints);
  129. Point point = geometryFactory.createPoint(new Coordinate(x, y));
  130. Polygon polygon = bufferInKm(point, RADIUS / 1000);
  131. WKTWriter writer = new WKTWriter();
  132. String wkt = writer.write(polygon);
  133. return wkt.replaceAll("POLYGON ", "POLYGON").replaceAll(", ", ",");
  134. } catch (Exception e) {
  135. System.out.println("Circle fail!");
  136. e.printStackTrace();
  137. return "none";
  138. }
  139. }
  140. public Polygon bufferInKm(Point p, Double radiusKm) {
  141. Hints hints = new Hints(Hints.CRS, DefaultGeographicCRS.WGS84);
  142. GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(hints);
  143. GeodeticCalculator c = new GeodeticCalculator();
  144. c.setStartingGeographicPoint(p.getX(), p.getY());
  145. Unit u = c.getEllipsoid().getAxisUnit();
  146. Unit km = Unit.valueOf("km");
  147. Coordinate coords[] = new Coordinate[361];
  148. for (int i = 0; i < 360; i++) {
  149. UnitConverter converter = km.getConverterTo(u);
  150. double converted = converter.convert(radiusKm);
  151. c.setDirection(i - 180, converted);
  152. java.awt.geom.Point2D boundaryPoint = c.getDestinationGeographicPoint();
  153. coords[i] = new Coordinate(boundaryPoint.getX(), boundaryPoint.getY());
  154. }
  155. coords[360] = coords[0];
  156. LinearRing ring = geometryFactory.createLinearRing(coords);
  157. Polygon polygon = geometryFactory.createPolygon(ring, null);
  158. return polygon;
  159. }
  160. private boolean validate() {
  161. StringBuilder sb = new StringBuilder();
  162. double radius = dRadius.getValue();
  163. if (radius <= 0) {
  164. sb.append("\nRadius must be greater than 0.");
  165. }
  166. if (sb.length() > 0) {
  167. getMapComposer().showMessage(sb.toString());
  168. }
  169. return sb.length() == 0;
  170. }
  171. }