/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt.client.map.layer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.geomajas.geometry.Coordinate; import org.geomajas.gwt.client.map.MapModel; import org.geomajas.gwt.client.map.MapView; import org.geomajas.gwt.client.spatial.Bbox; import org.geomajas.gwt.client.util.Log; import org.geomajas.gwt2.client.animation.NavigationAnimation; import org.geomajas.gwt2.client.map.View; import org.geomajas.gwt2.client.map.ViewPort; import org.geomajas.gwt2.client.map.ViewPortTransformationService; import org.geomajas.gwt2.client.map.ZoomOption; import org.geomajas.gwt2.client.map.layer.tile.TileConfiguration; import org.geomajas.gwt2.plugin.wms.client.capabilities.WmsLayerInfo; import org.geomajas.gwt2.plugin.wms.client.layer.WmsLayerConfiguration; import org.geomajas.gwt2.plugin.wms.client.layer.WmsLayerImpl; /** * SmartGWT implementation of the client WMS layer. This is an extension of the GWT2 wms layer adding support for the * SmartGWT map. * * @author Oliver May */ public class ClientWmsLayer extends WmsLayerImpl { /** * Create a new Client WMS layer. * * @param title the title * @param wmsConfig the wms configuration * @param tileConfig the tile configuration */ public ClientWmsLayer(String title, String crs, WmsLayerConfiguration wmsConfig, TileConfiguration tileConfig) { this(title, crs, wmsConfig, tileConfig, null); } /** * Create a new Client WMS layer. * * @param title the title * @param wmsConfig the wms configuration * @param tileConfig the tile configuration * @param layerCapabilities the layer capabilities or null */ public ClientWmsLayer(String title, String crs, WmsLayerConfiguration wmsConfig, TileConfiguration tileConfig, WmsLayerInfo layerCapabilities) { // we may need a SmartGwt MapConfiguration here ! super(title, crs, wmsConfig, tileConfig, layerCapabilities); } /** * Set the map model on this layer. * * @param mapModel the mapModel. */ public void setMapModel(MapModel mapModel) { setViewPort(new SmartGwtViewport(mapModel)); } @Override public String toString() { return "ClientWmsLayer{" + "id=" + getId() + ", " + "title=" + getTitle() + ", " + "capabilities=" + getCapabilities() + ", " + "config=" + getConfiguration() + ", " + "legendImageUrl=" + getLegendImageUrl() + ", " + "opacity=" + getOpacity() + '}'; } /** * SmartGwt implementation of the GWT2 viewport. This is intended for internal use in the client WMS layer, as it * does not implement all ViewPort methods. It can however be extended to fully support everything. */ private class SmartGwtViewport implements ViewPort { private final MapModel mapModel; private final List<Double> fixedResolutions = new ArrayList<Double>(); public SmartGwtViewport(MapModel mapModel) { this.mapModel = mapModel; //Calculate fixed scales based on the resolutions. //FIXME: what to do when no fixed resolutions exist. if (mapModel.getMapView().getResolutions() == null || mapModel.getMapView().getResolutions().size() < 1) { RuntimeException e = new RuntimeException("Error while adding Client WMS layer, " + "the map should define a list of resolutions."); Log.logError("Error while adding Client WMS layer.", e); throw e; } for (Double resolution : mapModel.getMapView().getResolutions()) { fixedResolutions.add(resolution); } Collections.sort(fixedResolutions); } @Override public org.geomajas.geometry.Bbox getMaximumBounds() { return mapModel.getMapView().getMaxBounds().toDtoBbox(); } @Override public double getMaximumResolution() { if (fixedResolutions.size() == 0) { return Double.MAX_VALUE; } return fixedResolutions.get(fixedResolutions.size() - 1); } @Override public double getMinimumResolution() { if (fixedResolutions.size() == 0) { return 0; } return fixedResolutions.get(0); } @Override public int getResolutionCount() { return fixedResolutions.size(); } @Override public double getResolution(int index) { if (index < 0) { throw new IllegalArgumentException("Resolution index cannot be found."); } if (index >= fixedResolutions.size()) { throw new IllegalArgumentException("Resolution index cannot be found."); } return fixedResolutions.get(index); } @Override public int getResolutionIndex(double resolution) { double maximumResolution = getMaximumResolution(); if (resolution >= maximumResolution) { return fixedResolutions.size() - 1; } double minimumResolution = getMinimumResolution(); if (resolution <= minimumResolution) { return 0; } for (int i = 0; i < fixedResolutions.size(); i++) { double lower = fixedResolutions.get(i); double upper = fixedResolutions.get(i + 1); if (resolution <= upper && resolution > lower) { if (Math.abs(upper - resolution) >= Math.abs(lower - resolution)) { return i; } else { return i + 1; } } } return 0; } @Override public int getMapWidth() { return mapModel.getMapView().getWidth(); } @Override public int getMapHeight() { return mapModel.getMapView().getWidth(); } @Override public String getCrs() { return mapModel.getCrs(); } @Override public Coordinate getPosition() { return mapModel.getMapView().getPanOrigin(); } @Override public double getResolution() { return 1 / mapModel.getMapView().getCurrentScale(); } @Override public View getView() { return new View(getPosition(), getResolution()); } @Override public org.geomajas.geometry.Bbox getBounds() { return mapModel.getMapView().getBounds().toDtoBbox(); } @Override public void registerAnimation(NavigationAnimation navigationAnimation) { throw new UnsupportedOperationException(); } @Override public void applyPosition(Coordinate coordinate) { mapModel.getMapView().setCenterPosition(coordinate); } @Override public void applyResolution(double r) { applyResolution(r, ZoomOption.FREE); } private MapView.ZoomOption convertZoomOption(ZoomOption zoomOption) { switch (zoomOption) { case FREE: return MapView.ZoomOption.EXACT; case LEVEL_FIT: return MapView.ZoomOption.LEVEL_FIT; case LEVEL_CLOSEST: default: return MapView.ZoomOption.LEVEL_CLOSEST; } } @Override public void applyResolution(double r, ZoomOption zoomOption) { mapModel.getMapView().setCurrentScale(1 / r, convertZoomOption(zoomOption)); } @Override public void applyBounds(org.geomajas.geometry.Bbox bbox) { applyBounds(bbox, ZoomOption.FREE); } @Override public void applyBounds(org.geomajas.geometry.Bbox bbox, ZoomOption zoomOption) { mapModel.getMapView().applyBounds(new Bbox(bbox), convertZoomOption(zoomOption)); } @Override public void applyView(View view) { throw new UnsupportedOperationException(); } @Override public void applyView(View view, ZoomOption zoomOption) { throw new UnsupportedOperationException(); } @Override public ViewPortTransformationService getTransformationService() { throw new UnsupportedOperationException(); } @Override public double toResolution(double r) { throw new UnsupportedOperationException(); } @Override public org.geomajas.geometry.Bbox asBounds(View view) { throw new UnsupportedOperationException(); } @Override public View asView(org.geomajas.geometry.Bbox bbox, ZoomOption zoomOption) { throw new UnsupportedOperationException(); } @Override public void stopInteraction() { } } }