Ignore:
Timestamp:
2017-04-09T11:08:10+02:00 (7 years ago)
Author:
bastiK
Message:

fixed #7427 - Support reprojection (warping) of imagery layer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java

    r11848 r11858  
    77import java.util.ArrayList;
    88import java.util.Arrays;
     9import java.util.Collection;
    910import java.util.List;
    10 import java.util.Set;
    11 import java.util.TreeSet;
     11import java.util.Objects;
    1212
    1313import javax.swing.AbstractAction;
     
    2828import org.openstreetmap.josm.data.preferences.IntegerProperty;
    2929import org.openstreetmap.josm.data.projection.Projection;
     30import org.openstreetmap.josm.data.projection.Projections;
    3031import org.openstreetmap.josm.gui.ExtendedDialog;
    3132import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
     
    5556    private static final String CACHE_REGION_NAME = "WMS";
    5657
    57     private final Set<String> supportedProjections;
     58    private final List<String> serverProjections;
    5859
    5960    /**
     
    6667        CheckParameterUtil.ensureParameterNotNull(info.getUrl(), "info.url");
    6768        TemplatedWMSTileSource.checkUrl(info.getUrl());
    68         this.supportedProjections = new TreeSet<>(info.getServerProjections());
     69        this.serverProjections = new ArrayList<>(info.getServerProjections());
    6970    }
    7071
     
    8788    @Override
    8889    protected AbstractWMSTileSource getTileSource() {
    89         AbstractWMSTileSource tileSource = new TemplatedWMSTileSource(info);
     90        AbstractWMSTileSource tileSource = new TemplatedWMSTileSource(
     91                info, chooseProjection(Main.getProjection()));
    9092        info.setAttribution(tileSource);
    9193        return tileSource;
     
    112114
    113115    @Override
    114     public boolean isProjectionSupported(Projection proj) {
    115         return supportedProjections == null || supportedProjections.isEmpty() || supportedProjections.contains(proj.toCode()) ||
    116                 (info.isEpsg4326To3857Supported() && supportedProjections.contains("EPSG:4326")
    117                         && "EPSG:3857".equals(Main.getProjection().toCode()));
    118     }
    119 
    120     @Override
    121     public String nameSupportedProjections() {
    122         StringBuilder ret = new StringBuilder();
    123         for (String e: supportedProjections) {
    124             ret.append(e).append(", ");
    125         }
    126         String appendix = "";
    127 
    128         if (isReprojectionPossible()) {
    129             appendix = ". <p>" + tr("JOSM will use EPSG:4326 to query the server, but results may vary "
    130                     + "depending on the WMS server") + "</p>";
    131         }
    132         return ret.substring(0, ret.length()-2) + appendix;
     116    public Collection<String> getNativeProjections() {
     117        return serverProjections;
    133118    }
    134119
    135120    @Override
    136121    public void projectionChanged(Projection oldValue, Projection newValue) {
    137         // do not call super - we need custom warning dialog
     122        Projection tileProjection = chooseProjection(newValue);
     123        if (!Objects.equals(tileSource.getTileProjection(), tileProjection)) {
     124            tileSource.setTileProjection(tileProjection);
     125        }
     126    }
    138127
    139         if (!isProjectionSupported(newValue)) {
    140             String message =
    141                     "<html><body><p>" + tr("The layer {0} does not support the new projection {1}.",
    142                             Utils.escapeReservedCharactersHTML(getName()), newValue.toCode()) +
    143                     "<p style='width: 450px; position: absolute; margin: 0px;'>" +
    144                             tr("Supported projections are: {0}", nameSupportedProjections()) + "</p>" +
    145                     "<p>" + tr("Change the projection again or remove the layer.");
    146 
    147             ExtendedDialog warningDialog = new ExtendedDialog(Main.parent, tr("Warning"), new String[]{tr("OK")}).
    148                     setContent(message).
    149                     setIcon(JOptionPane.WARNING_MESSAGE);
    150 
    151             if (isReprojectionPossible()) {
    152                 warningDialog.toggleEnable("imagery.wms.projectionSupportWarnings." + tileSource.getBaseUrl());
     128    private Projection chooseProjection(Projection requested) {
     129        if (serverProjections.contains(requested.toCode())) {
     130            return requested;
     131        } else {
     132            for (String code : serverProjections) {
     133                Projection proj = Projections.getProjectionByCode(code);
     134                if (proj != null) {
     135                    Main.info(tr("Reprojecting layer {0} from {1} to {2}. For best image quality and performance,"
     136                            + " switch to one of the supported projections: {3}",
     137                            getName(), proj.toCode(), Main.getProjection().toCode(), Utils.join(", ", getNativeProjections())));
     138                    return proj;
     139                }
    153140            }
    154             warningDialog.showDialog();
    155         }
    156 
    157         if (!newValue.equals(oldValue)) {
    158             tileSource.initProjection(newValue);
     141            Main.warn(tr("Unable to find supported projection for layer {0}. Using {1}.", getName(), requested.toCode()));
     142            return requested;
    159143        }
    160144    }
     
    176160        return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME);
    177161    }
    178 
    179     private boolean isReprojectionPossible() {
    180         return supportedProjections.contains("EPSG:4326") && "EPSG:3857".equals(Main.getProjection().toCode());
    181     }
    182162}
Note: See TracChangeset for help on using the changeset viewer.