/** * * geo-platform * Rich webgis framework * http://geo-platform.org * ==================================================================== * * Copyright (C) 2008-2017 geoSDI Group (CNR IMAA - Potenza - ITALY). * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. 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 General Public License * for more details. You should have received a copy of the GNU General * Public License along with this program. If not, see http://www.gnu.org/licenses/ * * ==================================================================== * * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you permission * to link this library with independent modules to produce an executable, regardless * of the license terms of these independent modules, and to copy and distribute * the resulting executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the license of * that module. An independent module is a module which is not derived from or * based on this library. If you modify this library, you may extend this exception * to your version of the library, but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. */ package org.geosdi.geoplatform.services; import com.google.common.collect.Lists; import org.geosdi.geoplatform.core.dao.GPServerDAO; import org.geosdi.geoplatform.core.model.GPBBox; import org.geosdi.geoplatform.core.model.GPLayerInfo; import org.geosdi.geoplatform.core.model.GeoPlatformServer; import org.geosdi.geoplatform.exception.ResourceNotFoundFault; import org.geosdi.geoplatform.request.RequestByID; import org.geosdi.geoplatform.response.RasterLayerDTO; import org.geosdi.geoplatform.response.ServerDTO; import org.geotools.data.ows.CRSEnvelope; import org.geotools.data.ows.Layer; import org.geotools.data.ows.StyleImpl; import org.geotools.data.ows.WMSCapabilities; import org.geotools.data.wms.WebMapServer; import org.geotools.ows.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; public class GPWMSServiceImpl implements GPWMSService { private final static String EPSG_4326 = "EPSG:4326"; private final static String EPSG_3857 = "EPSG:3857"; private final static String EPSG_GOOGLE = "EPSG:900913"; private Logger logger = LoggerFactory.getLogger( GPWMSServiceImpl.class); // DAO private GPServerDAO serverDao; private static final String GEB = "earthbuilder.google.com"; public GPWMSServiceImpl() { } @Override public ServerDTO getCapabilities(String serverUrl, RequestByID request, String token, String authkey) throws ResourceNotFoundFault { ServerDTO serverDTO; if (request.getId() != null) { GeoPlatformServer server = serverDao.find(request.getId()); if (server == null) { throw new ResourceNotFoundFault("Server has been deleted", request.getId()); } serverDTO = new ServerDTO(server); } else { serverDTO = new ServerDTO(); serverDTO.setServerUrl(serverUrl); } WMSCapabilities wmsCapabilities = this.getWMSCapabilities( serverUrl, token, authkey); List<RasterLayerDTO> layers = this.convertToLayerList( wmsCapabilities.getLayer(), serverUrl); serverDTO.setLayerList(layers); return serverDTO; } @Override public ServerDTO getShortServer(String serverUrl) throws ResourceNotFoundFault { GeoPlatformServer server = serverDao.findByServerUrl(serverUrl); if (server == null) { throw new ResourceNotFoundFault("Server not found " + serverUrl); } return new ServerDTO(server); } private boolean isURLServerAlreadyExists(String serverUrl) { return serverDao.findByServerUrl(serverUrl) == null ? false : true; } private WMSCapabilities getWMSCapabilities(String serverUrl, String token, String authkey) throws ResourceNotFoundFault { URL serverURL; WebMapServer wms; WMSCapabilities cap = null; String urlServerEdited = this.editServerUrl(serverUrl, token, authkey); logger.debug("####################URL Server edited: {}\n", urlServerEdited); try { serverURL = new URL(urlServerEdited); wms = new WebMapServer(serverURL); cap = wms.getCapabilities(); } catch (MalformedURLException e) { logger.error("MalformedURLException: " + e); throw new ResourceNotFoundFault("Malformed URL"); } catch (ServiceException e) { logger.error("ServiceException: " + e); throw new ResourceNotFoundFault("Invalid URL"); } catch (IOException e) { logger.error("IOException: " + e); throw new ResourceNotFoundFault("Inaccessible URL"); } catch (Exception e) { logger.error("Exception: " + e); throw new ResourceNotFoundFault("Incorrect URL"); } return cap; } private String editServerUrl(String urlServer, String token, String authkey) { StringBuilder stringBuilder = new StringBuilder(urlServer); if (!urlServer.contains("?")) { stringBuilder.append("?request=GetCapabilities"); } if (urlServer.contains(GEB)) { stringBuilder.append("&access_token=").append(token); } if (authkey != null) { stringBuilder.append("&authkey=").append(authkey); } return stringBuilder.toString(); } private List<RasterLayerDTO> convertToLayerList(Layer layer, String urlServer) { List<RasterLayerDTO> shortLayers = Lists.<RasterLayerDTO>newArrayList(); RasterLayerDTO raster = this.getRasterAndSubRaster(layer, layer, urlServer); shortLayers.add(raster); return shortLayers; } private RasterLayerDTO getRasterAndSubRaster(Layer ancestorLayer, Layer layer, String urlServer) { RasterLayerDTO raster = this.convertLayerToRaster(ancestorLayer, layer, urlServer); List<Layer> subLayerList = layer.getLayerChildren(); List<RasterLayerDTO> subRasterList = Lists.<RasterLayerDTO>newArrayListWithExpectedSize( subLayerList.size()); raster.setSubLayerList(subRasterList); // ADD subRaster for (Layer layerIth : subLayerList) { RasterLayerDTO rasterIth = this.getRasterAndSubRaster(ancestorLayer, layerIth, urlServer); subRasterList.add(rasterIth); } return raster; } private RasterLayerDTO convertLayerToRaster(Layer ancestorLayer, Layer layer, String urlServer) { RasterLayerDTO raster = new RasterLayerDTO(); raster.setUrlServer(this.getUrlServer(urlServer)); raster.setName(layer.getName()); raster.setAbstractText(layer.get_abstract()); if (layer.getTitle() == null || layer.getTitle().trim().equals("")) { raster.setTitle(layer.getName()); } else { raster.setTitle(layer.getTitle()); } Map<String, CRSEnvelope> additionalBounds = layer.getBoundingBoxes(); logger.debug("ADDITIONAL BOUNDS ###############################" + additionalBounds.toString()); if (!additionalBounds.isEmpty()) { if (additionalBounds.containsKey(EPSG_GOOGLE) || additionalBounds.containsKey(EPSG_3857)) { CRSEnvelope env = additionalBounds .get(EPSG_GOOGLE); if (env == null) { env = additionalBounds.get(EPSG_3857); } raster.setBbox(this.createBbox(env)); raster.setSrs(env.getEPSGCode()); } else { raster.setBbox(this.createBbox(layer.getLatLonBoundingBox())); raster.setSrs(EPSG_4326); } } else { additionalBounds = ancestorLayer.getBoundingBoxes(); if (additionalBounds.containsKey(EPSG_GOOGLE) || additionalBounds.containsKey(EPSG_3857)) { CRSEnvelope env = additionalBounds .get(EPSG_GOOGLE); if (env == null) { env = additionalBounds.get(EPSG_3857); } raster.setBbox(this.createBbox(env)); raster.setSrs(env.getEPSGCode()); logger.info("GOOGLE"); } else { raster.setBbox(this.createBbox(ancestorLayer.getLatLonBoundingBox())); raster.setSrs(EPSG_4326); logger.info("4326"); } } logger.debug("Raster Name: " + raster.getName()); logger.debug("Raster BBOX: " + raster.getBbox()); logger.debug("Raster SRS: " + raster.getSrs()); if (urlServer.contains(GEB)) { if (layer.getLatLonBoundingBox() != null) { raster.setBbox(this.createBbox(layer.getLatLonBoundingBox())); } raster.setSrs(EPSG_4326); } // Set LayerInfo of Raster Ith GPLayerInfo layerInfo = new GPLayerInfo(); layerInfo.setQueryable(layer.isQueryable()); if (layer.getKeywords() != null) { List<String> keywordList = Arrays.asList(layer.getKeywords()); if (keywordList.size() > 0) { layerInfo.setKeywords(keywordList); } } raster.setLayerInfo(layerInfo); // Set Styles of Raster Ith List<StyleImpl> stylesImpl = layer.getStyles(); logger.debug( "\n*** Layer \"{}\" has {} SubLayers and {} StyleImpl ***", layer.getTitle(), layer.getLayerChildren().size(), stylesImpl.size()); raster.setStyleList(this.createStyleList(stylesImpl)); return raster; } private List<ServerDTO> convertToServerList( List<GeoPlatformServer> serverList) { List<ServerDTO> shortServers = new ArrayList<ServerDTO>( serverList.size()); ServerDTO serverDTOIth = null; for (GeoPlatformServer server : serverList) { serverDTOIth = new ServerDTO(server); shortServers.add(serverDTOIth); } return shortServers; } private List<String> createStyleList(List<StyleImpl> stylesImpl) { List<String> styleList = new ArrayList<String>(stylesImpl.size()); for (StyleImpl style : stylesImpl) { styleList.add(style.getName()); } return styleList; } private GPBBox createBbox(CRSEnvelope env) { return ((env != null) ? new GPBBox(env.getMinX(), env.getMinY(), env.getMaxX(), env.getMaxY()) : new GPBBox(-179, -89, 179, 89)); } private String getUrlServer(String urlServer) { int index = -1; if (urlServer.contains(".map")) { index = urlServer.indexOf(".map") + 4; } else if (urlServer.contains("mapserv.exe") || urlServer.contains("mapserver") || urlServer.contains("mapserv") || urlServer.contains("usertoken") || urlServer.contains("map")) { index = urlServer.indexOf("&"); } else { index = urlServer.indexOf("?"); // index += 1; } if (index != -1) { String newUrl = urlServer.substring(0, index); return newUrl; } return urlServer; } private double longToSphericalMercatorX(double x) { return (x / 180.0) * 20037508.34; } private double latToSphericalMercatorY(double y) { if (y > 85.05112) { y = 85.05112; } if (y < -85.05112) { y = -85.05112; } y = (Math.PI / 180.0) * y; double tmp = Math.PI / 4.0 + y / 2.0; return 20037508.34 * Math.log(Math.tan(tmp)) / Math.PI; } public void setServerDao(GPServerDAO serverDao) { this.serverDao = serverDao; } }