Changeset 2540 in josm


Ignore:
Timestamp:
2009-11-28T22:40:34+01:00 (12 years ago)
Author:
stoecker
Message:

applied #2892 - patch by plaicy - added osmgo shortlink support to url decoder

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java

    r2512 r2540  
    33
    44import java.util.HashMap;
     5import java.util.Map;
    56
    67import org.openstreetmap.josm.data.Bounds;
     
    89
    910public class OsmUrlToBounds {
     11    private static final String SHORTLINK_PREFIX = "http://osm.org/go/";
    1012
    1113    public static Bounds parse(String url) {
     14        Bounds b = parseShortLink(url);
     15        if (b != null)
     16            return b;
    1217        int i = url.indexOf('?');
    1318        if (i == -1)
     
    2227        }
    2328
    24         Bounds b = null;
    2529        try {
    2630            if (map.containsKey("bbox")) {
     
    4044                b = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
    4145            } else {
    42                 double size = 180.0 / Math.pow(2, Integer.parseInt(map.get("zoom")));
    43                 b = new Bounds(
    44                     new LatLon(parseDouble(map, "lat") - size/2, parseDouble(map, "lon") - size),
    45                     new LatLon(parseDouble(map, "lat") + size/2, parseDouble(map, "lon") + size));
     46                b = positionToBounds(parseDouble(map, "lat"),
     47                                     parseDouble(map, "lon"),
     48                                     Integer.parseInt(map.get("zoom")));
    4649            }
    4750        } catch (NumberFormatException x) {
     
    5558            return Double.parseDouble(map.get(key));
    5659        return Double.parseDouble(map.get("m"+key));
     60    }
     61
     62    private static final char[] SHORTLINK_CHARS = {
     63        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
     64        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
     65        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
     66        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
     67        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
     68        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
     69        'w', 'x', 'y', 'z', '0', '1', '2', '3',
     70        '4', '5', '6', '7', '8', '9', '_', '@'
     71    };
     72
     73    /**
     74     * p
     75     *
     76     * @param url string for parsing
     77     *
     78     * @return Bounds if shortlink, null otherwise
     79     *
     80     * @see http://trac.openstreetmap.org/browser/sites/rails_port/lib/short_link.rb
     81     */
     82    private static Bounds parseShortLink(final String url) {
     83        if (!url.startsWith(SHORTLINK_PREFIX)) {
     84            return null;
     85        }
     86        final String shortLink = url.substring(SHORTLINK_PREFIX.length());
     87
     88        final Map<Character, Integer> array = new HashMap<Character, Integer>();
     89
     90        for (int i=0; i<SHORTLINK_CHARS.length; ++i) {
     91            array.put(SHORTLINK_CHARS[i], i);
     92        }
     93
     94        // long is necessary (need 32 bit positive value is needed)
     95        long x = 0;
     96        long y = 0;
     97        int zoom = 0;
     98        int zoomOffset = 0;
     99
     100        for (final char ch : shortLink.toCharArray()) {
     101            if (array.containsKey(ch)) {
     102                int val = array.get(ch);
     103                for (int i=0; i<3; ++i) {
     104                    x <<= 1;
     105                    if ((val & 32) != 0) {
     106                        x |= 1;
     107                    }
     108                    val <<= 1;
     109
     110                    y <<= 1;
     111                    if ((val & 32) != 0) {
     112                        y |= 1;
     113                    }
     114                    val <<= 1;
     115                }
     116                zoom += 3;
     117            } else {
     118                zoomOffset--;
     119            }
     120        }
     121
     122        x <<= 32 - zoom;
     123        y <<= 32 - zoom;
     124
     125        // 2**32 == 4294967296
     126        return positionToBounds(y * 180.0 / 4294967296.0 - 90.0,
     127                                x * 360.0 / 4294967296.0 - 180.0,
     128                                // TODO: -2 was not in ruby code
     129                                zoom - 8 - (zoomOffset % 3) - 2);
     130    }
     131
     132    private static Bounds positionToBounds(final double lat, final double lon, final int zoom) {
     133        final double size = 180.0 / Math.pow(2, zoom);
     134        return new Bounds(
     135                          new LatLon(lat - size/2, lon - size),
     136                          new LatLon(lat + size/2, lon + size));
    57137    }
    58138
Note: See TracChangeset for help on using the changeset viewer.