/* * Copyright (c) 2012 Brown Bag Consulting. * This file is part of the ExpressUI project. * Author: Juan Osuna * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License Version 3 * as published by the Free Software Foundation with the addition of the * following permission added to Section 15 as permitted in Section 7(a): * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY * Brown Bag Consulting, Brown Bag Consulting DISCLAIMS THE WARRANTY OF * NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License. * * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the ExpressUI software without * disclosing the source code of your own applications. These activities * include: offering paid services to customers as an ASP, providing * services from a web application, shipping ExpressUI with a closed * source product. * * For more information, please contact Brown Bag Consulting at this * address: juan@brownbagconsulting.com. */ package com.expressui.domain.geocode; import com.expressui.domain.RestClientService; import com.vaadin.event.MouseEvents; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Service; import org.vaadin.vol.*; import javax.annotation.Resource; import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; /** * Service for creating maps using Open Layers and Google */ @Configuration @Service public class MapService extends RestClientService { @Resource private GeocodeClient geocodeClient; /** * Create a map * * @param address address to center the map on * @param name name of the map * @param zoomLevel zoom level * @return map component */ public OpenLayersMap createMap(String address, final String name, Integer zoomLevel) { final OpenLayersMap map = new OpenLayersMap(); GoogleStreetMapLayer googleStreets = new GoogleStreetMapLayer(); map.addLayer(googleStreets); double[] coordinates = getCoordinates(address); if (coordinates == null) { return null; } map.setCenter(coordinates[0], coordinates[1]); map.setZoom(zoomLevel); MarkerLayer markerLayer = new MarkerLayer(); final Marker marker = new Marker(coordinates[0], coordinates[1]); markerLayer.addMarker(marker); map.addLayer(markerLayer); marker.addClickListener(new MouseEvents.ClickListener() { public void click(MouseEvents.ClickEvent event) { final Popup popup = new Popup(marker.getLon(), marker.getLat(), name); popup.setAnchor(marker); popup.setPopupStyle(Popup.PopupStyle.FRAMED_CLOUD); popup.addListener(new Popup.CloseListener() { public void onClose(Popup.CloseEvent event) { map.removeComponent(popup); } }); map.addPopup(popup); } }); map.removeControl(Control.LayerSwitcher); return map; } /** * Get longitude and latitude coordinates for given address. * * @param address address to query for * @return first item is longitude, second is latitude */ public double[] getCoordinates(String address) { GeocodeResponse geocodeResponse = geocodeClient.getGeocode(address, false); if (geocodeResponse.status.equals("ZERO_RESULTS")) { return null; } else { double[] coordinates = new double[2]; coordinates[0] = geocodeResponse.result.geometry.location.lng; coordinates[1] = geocodeResponse.result.geometry.location.lat; return coordinates; } } @Bean public GeocodeClient getGeocodeClient(@Value("${geoCodeService.url:}") String url) throws Exception { return create(url, GeocodeClient.class); } public static interface GeocodeClient { @GET @Produces("application/xml") GeocodeResponse getGeocode(@QueryParam("address") String address, @QueryParam("sensor") boolean hasSensor); } @XmlRootElement(namespace = "", name = "GeocodeResponse") @XmlAccessorType(XmlAccessType.FIELD) public static class GeocodeResponse { public String status; public Result result; } @XmlAccessorType(XmlAccessType.FIELD) public static class Result { public Geometry geometry; } @XmlAccessorType(XmlAccessType.FIELD) public static class Geometry { public Location location; } @XmlAccessorType(XmlAccessType.FIELD) public static class Location { public double lat; public double lng; } }