PageRenderTime 70ms CodeModel.GetById 33ms app.highlight 19ms RepoModel.GetById 3ms app.codeStats 0ms

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