Changeset 10612 in josm


Ignore:
Timestamp:
2016-07-23T18:50:10+02:00 (8 years ago)
Author:
Don-vip
Message:

see #11390, fix #12910 - Clean WMS Imagery (patch by michael2402) - gsoc-core - requires java 8

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java

    r10520 r10612  
    1111import java.util.Collections;
    1212import java.util.HashSet;
     13import java.util.Iterator;
    1314import java.util.List;
    1415import java.util.Locale;
     16import java.util.NoSuchElementException;
    1517import java.util.Set;
    1618import java.util.regex.Pattern;
     19import java.util.stream.Collectors;
     20import java.util.stream.Stream;
     21import java.util.stream.StreamSupport;
    1722
    1823import javax.imageio.ImageIO;
     
    2530import org.openstreetmap.josm.data.projection.Projections;
    2631import org.openstreetmap.josm.tools.HttpClient;
    27 import org.openstreetmap.josm.tools.Predicate;
    2832import org.openstreetmap.josm.tools.Utils;
    2933import org.w3c.dom.Document;
     
    3539import org.xml.sax.SAXException;
    3640
     41/**
     42 * This class represents the capabilites of a WMS imagery server.
     43 */
    3744public class WMSImagery {
    3845
     46    private static final class ChildIterator implements Iterator<Element> {
     47        private Element child;
     48
     49        ChildIterator(Element parent) {
     50            child = advanceToElement(parent.getFirstChild());
     51        }
     52
     53        private static Element advanceToElement(Node firstChild) {
     54            Node node = firstChild;
     55            while (node != null && !(node instanceof Element)) {
     56                node = node.getNextSibling();
     57            }
     58            return (Element) node;
     59        }
     60
     61        @Override
     62        public boolean hasNext() {
     63            return child != null;
     64        }
     65
     66        @Override
     67        public Element next() {
     68            if (!hasNext()) {
     69                throw new NoSuchElementException("No next sibling.");
     70            }
     71            Element next = child;
     72            child = advanceToElement(child.getNextSibling());
     73            return next;
     74        }
     75    }
     76
     77    /**
     78     * An exception that is thrown if there was an error while getting the capabilities of the WMS server.
     79     */
    3980    public static class WMSGetCapabilitiesException extends Exception {
    4081        private final String incomingData;
     
    62103
    63104        /**
    64          * Returns the answer from WMS server.
    65          * @return the answer from WMS server
     105         * The data that caused this exception.
     106         * @return The server response to the capabilites request.
    66107         */
    67108        public String getIncomingData() {
     
    79120     */
    80121    public List<LayerDetails> getLayers() {
    81         return layers;
     122        return Collections.unmodifiableList(layers);
    82123    }
    83124
     
    98139    }
    99140
     141    /**
     142     * Gets the preffered format for this imagery layer.
     143     * @return The preffered format as mime type.
     144     */
    100145    public String getPreferredFormats() {
    101         return formats.contains("image/jpeg") ? "image/jpeg"
    102                 : formats.contains("image/png") ? "image/png"
    103                 : formats.isEmpty() ? null
    104                 : formats.get(0);
     146        if (formats.contains("image/jpeg")) {
     147            return "image/jpeg";
     148        } else if (formats.contains("image/png")) {
     149            return "image/png";
     150        } else if (formats.isEmpty()) {
     151            return null;
     152        } else {
     153            return formats.get(0);
     154        }
    105155    }
    106156
     
    129179
    130180    public String buildGetMapUrl(Collection<LayerDetails> selectedLayers, String format) {
    131         return buildRootUrl()
    132                 + "FORMAT=" + format + (imageFormatHasTransparency(format) ? "&TRANSPARENT=TRUE" : "")
     181        return buildRootUrl() + "FORMAT=" + format + (imageFormatHasTransparency(format) ? "&TRANSPARENT=TRUE" : "")
    133182                + "&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&LAYERS="
    134                 + Utils.join(",", Utils.transform(selectedLayers, new Utils.Function<LayerDetails, String>() {
    135             @Override
    136             public String apply(LayerDetails x) {
    137                 return x.ident;
    138             }
    139         }))
     183                + Utils.join(",", Utils.transform(selectedLayers, x -> x.ident))
    140184                + "&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}";
    141185    }
    142186
    143     public void attemptGetCapabilities(String serviceUrlStr) throws MalformedURLException, IOException, WMSGetCapabilitiesException {
     187    public void attemptGetCapabilities(String serviceUrlStr) throws IOException, WMSGetCapabilitiesException {
    144188        URL getCapabilitiesUrl = null;
    145189        try {
     
    162206            serviceUrl = new URL(serviceUrlStr);
    163207        } catch (HeadlessException e) {
     208            Main.warn(e);
    164209            return;
    165210        }
     
    192237            child = getChild(child, "GetMap");
    193238
    194             formats = new ArrayList<>(Utils.filter(Utils.transform(getChildren(child, "Format"),
    195                     new Utils.Function<Element, String>() {
    196                         @Override
    197                         public String apply(Element x) {
    198                             return x.getTextContent();
    199                         }
    200                     }),
    201                     new Predicate<String>() {
    202                         @Override
    203                         public boolean evaluate(String format) {
    204                             boolean isFormatSupported = isImageFormatSupported(format);
    205                             if (!isFormatSupported) {
    206                                 Main.info("Skipping unsupported image format {0}", format);
    207                             }
    208                             return isFormatSupported;
    209                         }
    210                     }
    211             ));
     239            formats = getChildrenStream(child, "Format")
     240                    .map(x -> x.getTextContent())
     241                    .filter(WMSImagery::isImageFormatSupportedWarn)
     242                    .collect(Collectors.toList());
    212243
    213244            child = getChild(child, "DCPType");
     
    231262    }
    232263
     264    private static boolean isImageFormatSupportedWarn(String format) {
     265        boolean isFormatSupported = isImageFormatSupported(format);
     266        if (!isFormatSupported) {
     267            Main.info("Skipping unsupported image format {0}", format);
     268        }
     269        return isFormatSupported;
     270    }
     271
    233272    static boolean isImageFormatSupported(final String format) {
    234273        return ImageIO.getImageReadersByMIMEType(format).hasNext()
    235274                // handles image/tiff image/tiff8 image/geotiff image/geotiff8
    236                 || (format.startsWith("image/tiff") || format.startsWith("image/geotiff")) && ImageIO.getImageReadersBySuffix("tiff").hasNext()
     275                || (format.startsWith("image/tiff") || format.startsWith("image/geotiff"))
     276                        && ImageIO.getImageReadersBySuffix("tiff").hasNext()
    237277                || format.startsWith("image/png") && ImageIO.getImageReadersBySuffix("png").hasNext()
    238278                || format.startsWith("image/svg") && ImageIO.getImageReadersBySuffix("svg").hasNext()
     
    276316        // Parse the CRS/SRS pulled out of this layer's XML element
    277317        // I think CRS and SRS are the same at this point
    278         List<Element> crsChildren = getChildren(element, "CRS");
    279         crsChildren.addAll(getChildren(element, "SRS"));
    280         for (Element child : crsChildren) {
    281             String crs = (String) getContent(child);
    282             if (!crs.isEmpty()) {
    283                 String upperCase = crs.trim().toUpperCase(Locale.ENGLISH);
    284                 crsList.add(upperCase);
    285             }
    286         }
     318        getChildrenStream(element)
     319            .filter(child -> "CRS".equals(child.getNodeName()) || "SRS".equals(child.getNodeName()))
     320            .map(child -> (String) getContent(child))
     321            .filter(crs -> !crs.isEmpty())
     322            .map(crs -> crs.trim().toUpperCase(Locale.ENGLISH))
     323            .forEach(crsList::add);
    287324
    288325        // Check to see if any of the specified projections are supported by JOSM
     
    351388    }
    352389
     390    private static Stream<Element> getChildrenStream(Element parent) {
     391        if (parent == null) {
     392            // ignore missing elements
     393            return Stream.empty();
     394        } else {
     395            Iterable<Element> it = () -> new ChildIterator(parent);
     396            return StreamSupport.stream(it.spliterator(), false);
     397        }
     398    }
     399
     400    private static Stream<Element> getChildrenStream(Element parent, String name) {
     401        return getChildrenStream(parent).filter(child -> name.equals(child.getNodeName()));
     402    }
     403
    353404    private static List<Element> getChildren(Element parent, String name) {
    354         List<Element> retVal = new ArrayList<>();
    355         if (parent != null) {
    356             for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
    357                 if (child instanceof Element && name.equals(child.getNodeName())) {
    358                     retVal.add((Element) child);
    359                 }
    360             }
    361         }
    362         return retVal;
     405        return getChildrenStream(parent, name).collect(Collectors.toList());
    363406    }
    364407
    365408    private static Element getChild(Element parent, String name) {
    366         if (parent == null)
    367             return null;
    368         for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
    369             if (child instanceof Element && name.equals(child.getNodeName()))
    370                 return (Element) child;
    371         }
    372         return null;
    373     }
    374 
     409        return getChildrenStream(parent, name).findFirst().orElse(null);
     410    }
     411
     412    /**
     413     * The details of a layer of this wms server.
     414     */
    375415    public static class LayerDetails {
    376416
     417        /**
     418         * The layer name
     419         */
    377420        public final String name;
    378421        public final String ident;
     422        /**
     423         * The child layers of this layer
     424         */
    379425        public final List<LayerDetails> children;
     426        /**
     427         * The bounds this layer can be used for
     428         */
    380429        public final Bounds bounds;
    381430        public final Set<String> crsList;
    382431        public final boolean supported;
    383432
    384         public LayerDetails(String name, String ident, Set<String> crsList,
    385                             boolean supportedLayer, Bounds bounds,
    386                             List<LayerDetails> childLayers) {
     433        public LayerDetails(String name, String ident, Set<String> crsList, boolean supportedLayer, Bounds bounds,
     434                List<LayerDetails> childLayers) {
    387435            this.name = name;
    388436            this.ident = ident;
Note: See TracChangeset for help on using the changeset viewer.