[Git][debian-gis-team/jmapviewer][upstream] New upstream version 2.13+dfsg

Bas Couwenberg gitlab at salsa.debian.org
Sat Feb 15 16:16:28 GMT 2020



Bas Couwenberg pushed to branch upstream at Debian GIS Project / jmapviewer


Commits:
b2d2fae3 by Bas Couwenberg at 2020-02-15T17:07:42+01:00
New upstream version 2.13+dfsg
- - - - -


4 changed files:

- Readme.txt
- src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java
- src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
- src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java


Changes:

=====================================
Readme.txt
=====================================
@@ -10,7 +10,7 @@ JMapViewer
 (c) 2010-2011, Michael Vigovsky
 (c) 2011-2017, Paul Hartmann
 (c) 2011-2016, Gleb Smirnoff
-(c) 2011-2019, Vincent Privat
+(c) 2011-2020, Vincent Privat
 (c) 2011, Jason Huntley
 (c) 2012-2016, Simon Legner
 (c) 2012, Teemu Koskinen


=====================================
src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java
=====================================
@@ -21,6 +21,7 @@ import javax.imageio.ImageIO;
  */
 public final class FeatureAdapter {
 
+    private static ApiKeyAdapter apiKeyAdapter = new DefaultApiKeyAdapter();
     private static BrowserAdapter browserAdapter = new DefaultBrowserAdapter();
     private static ImageAdapter imageAdapter = new DefaultImageAdapter();
     private static TranslationAdapter translationAdapter = new DefaultTranslationAdapter();
@@ -31,20 +32,87 @@ public final class FeatureAdapter {
         // private constructor for utility classes
     }
 
+    /**
+     * Provider of confidential API keys.
+     */
+    @FunctionalInterface
+    public interface ApiKeyAdapter {
+        /**
+         * Retrieves the API key for the given imagery id.
+         * @param imageryId imagery id
+         * @return the API key for the given imagery id
+         * @throws IOException in case of I/O error
+         */
+        String retrieveApiKey(String imageryId) throws IOException;
+    }
+
+    /**
+     * Link browser.
+     */
+    @FunctionalInterface
     public interface BrowserAdapter {
+        /**
+         * Browses to a given link.
+         * @param url link
+         */
         void openLink(String url);
     }
 
+    /**
+     * Translation support.
+     */
     public interface TranslationAdapter {
+        /**
+         * Translates some text for the current locale.
+         * <br>
+         * For example, <code>tr("JMapViewer''s default value is ''{0}''.", val)</code>.
+         * <br>
+         * @param text the text to translate.
+         * Must be a string literal. (No constants or local vars.)
+         * Can be broken over multiple lines.
+         * An apostrophe ' must be quoted by another apostrophe.
+         * @param objects the parameters for the string.
+         * Mark occurrences in {@code text} with <code>{0}</code>, <code>{1}</code>, ...
+         * @return the translated string.
+         */
         String tr(String text, Object... objects);
         // TODO: more i18n functions
     }
 
+    /**
+     * Logging support.
+     */
+    @FunctionalInterface
     public interface LoggingAdapter {
+        /**
+         * Retrieves a logger for the given name.
+         * @param name logger name
+         * @return logger for the given name
+         */
         Logger getLogger(String name);
     }
 
+    /**
+     * Image provider.
+     */
+    @FunctionalInterface
     public interface ImageAdapter {
+        /**
+         * Returns a <code>BufferedImage</code> as the result of decoding a supplied <code>URL</code>.
+         *
+         * @param input a <code>URL</code> to read from.
+         * @param readMetadata if {@code true}, makes sure to read image metadata to detect transparency color for non translucent images,
+         * if any.
+         * Always considered {@code true} if {@code enforceTransparency} is also {@code true}
+         * @param enforceTransparency if {@code true}, makes sure to read image metadata and, if the image does not
+         * provide an alpha channel but defines a {@code TransparentColor} metadata node, that the resulting image
+         * has a transparency set to {@code TRANSLUCENT} and uses the correct transparent color.
+         *
+         * @return a <code>BufferedImage</code> containing the decoded contents of the input, or <code>null</code>.
+         *
+         * @throws IllegalArgumentException if <code>input</code> is <code>null</code>.
+         * @throws IOException if an error occurs during reading.
+         */
         BufferedImage read(URL input, boolean readMetadata, boolean enforceTransparency) throws IOException;
     }
 
@@ -70,18 +138,42 @@ public final class FeatureAdapter {
         boolean put(String key, String value);
     }
 
+    /**
+     * Registers API key adapter.
+     * @param apiKeyAdapter API key adapter
+     */
+    public static void registerApiKeyAdapter(ApiKeyAdapter apiKeyAdapter) {
+        FeatureAdapter.apiKeyAdapter = Objects.requireNonNull(apiKeyAdapter);
+    }
+
+    /**
+     * Registers browser adapter.
+     * @param browserAdapter browser adapter
+     */
     public static void registerBrowserAdapter(BrowserAdapter browserAdapter) {
         FeatureAdapter.browserAdapter = Objects.requireNonNull(browserAdapter);
     }
 
+    /**
+     * Registers image adapter.
+     * @param imageAdapter image adapter
+     */
     public static void registerImageAdapter(ImageAdapter imageAdapter) {
         FeatureAdapter.imageAdapter = Objects.requireNonNull(imageAdapter);
     }
 
+    /**
+     * Registers translation adapter.
+     * @param translationAdapter translation adapter
+     */
     public static void registerTranslationAdapter(TranslationAdapter translationAdapter) {
         FeatureAdapter.translationAdapter = Objects.requireNonNull(translationAdapter);
     }
 
+    /**
+     * Registers logging adapter.
+     * @param loggingAdapter logging adapter
+     */
     public static void registerLoggingAdapter(LoggingAdapter loggingAdapter) {
         FeatureAdapter.loggingAdapter = Objects.requireNonNull(loggingAdapter);
     }
@@ -95,22 +187,62 @@ public final class FeatureAdapter {
         FeatureAdapter.settingsAdapter = Objects.requireNonNull(settingsAdapter);
     }
 
+    /**
+     * Retrieves the API key for the given imagery id using the current {@link ApiKeyAdapter}.
+     * @param imageryId imagery id
+     * @return the API key for the given imagery id
+     * @throws IOException in case of I/O error
+     */
+    public static String retrieveApiKey(String imageryId) throws IOException {
+        return apiKeyAdapter.retrieveApiKey(imageryId);
+    }
+
+    /**
+     * Opens a link using the current {@link BrowserAdapter}.
+     * @param url link to open
+     */
     public static void openLink(String url) {
         browserAdapter.openLink(url);
     }
 
+    /**
+     * Reads an image using the current {@link ImageAdapter}.
+     * @param url image URL to read
+     * @return a <code>BufferedImage</code> containing the decoded contents of the input, or <code>null</code>.
+     * @throws IOException if an error occurs during reading.
+     */
     public static BufferedImage readImage(URL url) throws IOException {
         return imageAdapter.read(url, false, false);
     }
 
+    /**
+     * Translates a text using the current {@link TranslationAdapter}.
+     * @param text the text to translate.
+     * Must be a string literal. (No constants or local vars.)
+     * Can be broken over multiple lines.
+     * An apostrophe ' must be quoted by another apostrophe.
+     * @param objects the parameters for the string.
+     * Mark occurrences in {@code text} with <code>{0}</code>, <code>{1}</code>, ...
+     * @return the translated string.
+     */
     public static String tr(String text, Object... objects) {
         return translationAdapter.tr(text, objects);
     }
 
+    /**
+     * Returns a logger for the given name using the current {@link LoggingAdapter}.
+     * @param name logger name
+     * @return logger for the given name
+     */
     public static Logger getLogger(String name) {
         return loggingAdapter.getLogger(name);
     }
 
+    /**
+     * Returns a logger for the given class using the current {@link LoggingAdapter}.
+     * @param klass logger class
+     * @return logger for the given class
+     */
     public static Logger getLogger(Class<?> klass) {
         return loggingAdapter.getLogger(klass.getSimpleName());
     }
@@ -147,6 +279,19 @@ public final class FeatureAdapter {
         return settingsAdapter.put(key, value);
     }
 
+    /**
+     * Default API key support that relies on system property named {@code <imageryId>.api-key}.
+     */
+    public static class DefaultApiKeyAdapter implements ApiKeyAdapter {
+        @Override
+        public String retrieveApiKey(String imageryId) {
+            return System.getProperty(imageryId + ".api-key");
+        }
+    }
+
+    /**
+     * Default browser support that relies on Java Desktop API.
+     */
     public static class DefaultBrowserAdapter implements BrowserAdapter {
         @Override
         public void openLink(String url) {
@@ -164,6 +309,9 @@ public final class FeatureAdapter {
         }
     }
 
+    /**
+     * Default image support that relies on Java Image IO API.
+     */
     public static class DefaultImageAdapter implements ImageAdapter {
         @Override
         public BufferedImage read(URL input, boolean readMetadata, boolean enforceTransparency) throws IOException {
@@ -171,6 +319,9 @@ public final class FeatureAdapter {
         }
     }
 
+    /**
+     * Default "translation" support that do not really translates strings, but only takes care of formatting arguments.
+     */
     public static class DefaultTranslationAdapter implements TranslationAdapter {
         @Override
         public String tr(String text, Object... objects) {
@@ -178,6 +329,9 @@ public final class FeatureAdapter {
         }
     }
 
+    /**
+     * Default logging support that relies on Java Logging API.
+     */
     public static class DefaultLoggingAdapter implements LoggingAdapter {
         @Override
         public Logger getLogger(String name) {


=====================================
src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
=====================================
@@ -297,7 +297,14 @@ public class JMapViewer extends JPanel implements TileLoaderListener {
         int yMin = Integer.MAX_VALUE;
         int xMax = Integer.MIN_VALUE;
         int yMax = Integer.MIN_VALUE;
-        int mapZoomMax = tileController.getTileSource().getMaxZoom();
+        /*
+         *  Cap mapZoomMax at highest level that prevents overflowing int in X and Y coordinates. As int is from -2^31..2^31.
+         *  Log_2(TileSize) is how many bits are used due to tile size. Math.log(TileSize) / Math.log(2) gives Log_2(TileSize)
+         *  So 31 - tileSizeBits gives maximum zoom that can be handled without overflowing.
+         *  It means 23 for 256 tile size or 22 for 512 tile size
+         */
+        int tileSizeBits = (int) (Math.log(tileController.getTileSource().getDefaultTileSize()) / Math.log(2));
+        int mapZoomMax = Math.min(31 - tileSizeBits, tileController.getTileSource().getMaxZoom());
 
         if (markers && mapMarkerList != null) {
             synchronized (this) {


=====================================
src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java
=====================================
@@ -1,12 +1,15 @@
 // License: GPL. For details, see Readme.txt file.
 package org.openstreetmap.gui.jmapviewer.tilesources;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
+import java.util.function.BiConsumer;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
 import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
 
 /**
@@ -24,6 +27,7 @@ import org.openstreetmap.gui.jmapviewer.interfaces.TemplatedTileSource;
  * {y} - substituted with Y tile number
  * {!y} - substituted with Yahoo Y tile number
  * {-y} - substituted with reversed Y tile number
+ * {apiKey} - substituted with API key retrieved for the imagery id
  * {switch:VAL_A,VAL_B,VAL_C,...} - substituted with one of VAL_A, VAL_B, VAL_C. Usually
  *                                  used to specify many tile servers
  * {header:(HEADER_NAME,HEADER_VALUE)} - sets the headers to be sent to tile server
@@ -45,11 +49,19 @@ public class TemplatedTMSTileSource extends TMSTileSource implements TemplatedTi
     private static final Pattern PATTERN_NEG_Y   = Pattern.compile("\\{-y\\}");
     private static final Pattern PATTERN_SWITCH  = Pattern.compile("\\{switch:([^}]+)\\}");
     private static final Pattern PATTERN_HEADER  = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)\\}");
+    private static final Pattern PATTERN_API_KEY = Pattern.compile("\\{apiKey\\}");
     private static final Pattern PATTERN_PARAM  = Pattern.compile("\\{((?:\\d+-)?z(?:oom)?(:?[+-]\\d+)?|x|y|!y|-y|switch:([^}]+))\\}");
+
+    /**
+     * Pattern used only for compatibility with older JOSM clients. To remove end of 2020, with an update of JOSM wiki
+     * @deprecated to remove end of 2020
+     */
+    @Deprecated
+    private static final Pattern PATTERN_API_KEY_COMPATIBILITY = Pattern.compile("_apiKey_");
     // CHECKSTYLE.ON: SingleSpaceSeparator
 
     private static final Pattern[] ALL_PATTERNS = {
-        PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH
+        PATTERN_HEADER, PATTERN_ZOOM, PATTERN_X, PATTERN_Y, PATTERN_Y_YAHOO, PATTERN_NEG_Y, PATTERN_SWITCH, PATTERN_API_KEY
     };
 
     /**
@@ -62,25 +74,45 @@ public class TemplatedTMSTileSource extends TMSTileSource implements TemplatedTi
         if (cookies != null && !cookies.isEmpty()) {
             headers.put(COOKIE_HEADER, cookies);
         }
-        handleTemplate();
+        handleTemplate(info.getId());
+    }
+
+    private void replacePattern(BiConsumer<Matcher, StringBuffer> replaceAction, Pattern... patterns) {
+        for (Pattern p : patterns) {
+            StringBuffer output = new StringBuffer();
+            Matcher m = p.matcher(baseUrl);
+            while (m.find()) {
+                replaceAction.accept(m, output);
+            }
+            m.appendTail(output);
+            baseUrl = output.toString();
+        }
     }
 
-    private void handleTemplate() {
+    private void handleTemplate(String imageryId) {
         // Capturing group pattern on switch values
         Matcher m = PATTERN_SWITCH.matcher(baseUrl);
         if (m.find()) {
             rand = new Random();
             randomParts = m.group(1).split(",");
         }
-        StringBuffer output = new StringBuffer();
-        Matcher matcher = PATTERN_HEADER.matcher(baseUrl);
-        while (matcher.find()) {
+        // Capturing group pattern on header values
+        replacePattern((matcher, output) -> {
             headers.put(matcher.group(1), matcher.group(2));
             matcher.appendReplacement(output, "");
+        }, PATTERN_HEADER);
+        // Capturing group pattern on API key values
+        if (imageryId != null) {
+            replacePattern((matcher, output) -> {
+                try {
+                    matcher.appendReplacement(output, FeatureAdapter.retrieveApiKey(imageryId));
+                } catch (IOException e) {
+                    throw new IllegalArgumentException(e);
+                }
+            }, PATTERN_API_KEY, PATTERN_API_KEY_COMPATIBILITY);
         }
-        matcher.appendTail(output);
-        baseUrl = output.toString();
-        m = PATTERN_ZOOM.matcher(this.baseUrl);
+        // Capturing group pattern on zoom values
+        m = PATTERN_ZOOM.matcher(baseUrl);
         if (m.find()) {
             if (m.group(1) != null) {
                 inverse_zoom = true;
@@ -93,7 +125,6 @@ public class TemplatedTMSTileSource extends TMSTileSource implements TemplatedTi
                 zoom_offset += Integer.parseInt(ofs);
             }
         }
-
     }
 
     @Override



View it on GitLab: https://salsa.debian.org/debian-gis-team/jmapviewer/commit/b2d2fae3f934228bdab6574de4b4005288f97101

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/jmapviewer/commit/b2d2fae3f934228bdab6574de4b4005288f97101
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20200215/e9403240/attachment-0001.html>


More information about the Pkg-grass-devel mailing list