Ignore:
Timestamp:
06.11.2011 15:00:56 (7 months ago)
Author:
Don-vip
Message:

see #2212 - Allow JOSM to download data crossing the 180th meridian

Location:
trunk/src/org/openstreetmap/josm/data
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/Bounds.java

    r4573 r4580  
    141141            throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0.0 exptected, got {1}", "lonExtent", lonExtent)); 
    142142 
    143         this.minLat = LatLon.roundToOsmPrecision(center.lat() - latExtent / 2); 
    144         this.minLon = LatLon.roundToOsmPrecision(center.lon() - lonExtent / 2); 
    145         this.maxLat = LatLon.roundToOsmPrecision(center.lat() + latExtent / 2); 
    146         this.maxLon = LatLon.roundToOsmPrecision(center.lon() + lonExtent / 2); 
     143        this.minLat = LatLon.roundToOsmPrecision(LatLon.toIntervalLat(center.lat() - latExtent / 2)); 
     144        this.minLon = LatLon.roundToOsmPrecision(LatLon.toIntervalLon(center.lon() - lonExtent / 2)); 
     145        this.maxLat = LatLon.roundToOsmPrecision(LatLon.toIntervalLat(center.lat() + latExtent / 2)); 
     146        this.maxLon = LatLon.roundToOsmPrecision(LatLon.toIntervalLon(center.lon() + lonExtent / 2)); 
    147147    } 
    148148 
     
    164164    public LatLon getCenter() 
    165165    { 
    166         return getMin().getCenter(getMax()); 
     166        if (crosses180thMeridian()) { 
     167            LatLon result = new LatLon(minLat, minLon-360.0).getCenter(getMax()); 
     168            if (result.lon() < -180.0) { 
     169                result.setLocation(result.lon()+360.0, result.lat()); 
     170            } 
     171            return result; 
     172        } else { 
     173            return getMin().getCenter(getMax()); 
     174        } 
    167175    } 
    168176 
     
    174182            minLat = LatLon.roundToOsmPrecision(ll.lat()); 
    175183        } 
    176         if (ll.lon() < minLon) { 
    177             minLon = LatLon.roundToOsmPrecision(ll.lon()); 
    178         } 
    179184        if (ll.lat() > maxLat) { 
    180185            maxLat = LatLon.roundToOsmPrecision(ll.lat()); 
    181186        } 
    182         if (ll.lon() > maxLon) { 
    183             maxLon = LatLon.roundToOsmPrecision(ll.lon()); 
     187        if (crosses180thMeridian()) { 
     188            if (ll.lon() > maxLon && ll.lon() < minLon) { 
     189                if (Math.abs(ll.lon() - minLon) <= Math.abs(ll.lon() - maxLon)) { 
     190                    minLon = LatLon.roundToOsmPrecision(ll.lon()); 
     191                } else { 
     192                    maxLon = LatLon.roundToOsmPrecision(ll.lon()); 
     193                } 
     194            } 
     195        } else { 
     196            if (ll.lon() < minLon) { 
     197                minLon = LatLon.roundToOsmPrecision(ll.lon()); 
     198            } 
     199            if (ll.lon() > maxLon) { 
     200                maxLon = LatLon.roundToOsmPrecision(ll.lon()); 
     201            } 
    184202        } 
    185203    } 
     
    189207        extend(b.getMax()); 
    190208    } 
     209     
    191210    /** 
    192211     * Is the given point within this bounds? 
    193212     */ 
    194213    public boolean contains(LatLon ll) { 
    195         if (ll.lat() < minLat || ll.lon() < minLon) 
    196             return false; 
    197         if (ll.lat() > maxLat || ll.lon() > maxLon) 
    198             return false; 
     214        if (ll.lat() < minLat || ll.lat() > maxLat) 
     215            return false; 
     216        if (crosses180thMeridian()) { 
     217            if (ll.lon() > maxLon && ll.lon() < minLon) 
     218                return false; 
     219        } else { 
     220            if (ll.lon() < minLon || ll.lon() > maxLon) 
     221                return false; 
     222        } 
    199223        return true; 
    200224    } 
    201225 
     226    private static boolean intersectsLonCrossing(Bounds crossing, Bounds notCrossing) { 
     227        return notCrossing.minLon <= crossing.maxLon || notCrossing.maxLon >= crossing.minLon; 
     228    } 
     229     
    202230    /** 
    203231     * The two bounds intersect? Compared to java Shape.intersects, if does not use 
     
    205233     */ 
    206234    public boolean intersects(Bounds b) { 
    207         return b.maxLat >= minLat && 
    208         b.maxLon >= minLon && 
    209         b.minLat <= maxLat && 
    210         b.minLon <= maxLon; 
    211     } 
    212  
    213  
     235        if (b.maxLat < minLat || b.minLat > maxLat) 
     236            return false; 
     237         
     238        if (crosses180thMeridian() && !b.crosses180thMeridian()) { 
     239            return intersectsLonCrossing(this, b); 
     240        } else if (!crosses180thMeridian() && b.crosses180thMeridian()) { 
     241            return intersectsLonCrossing(b, this); 
     242        } else if (crosses180thMeridian() && b.crosses180thMeridian()) { 
     243            return true; 
     244        } else { 
     245            return b.maxLon >= minLon && b.minLon <= maxLon; 
     246        } 
     247    } 
     248 
     249    /** 
     250     * Determines if this Bounds object crosses the 180th Meridian. 
     251     * See http://wiki.openstreetmap.org/wiki/180th_meridian 
     252     * @return true if this Bounds object crosses the 180th Meridian. 
     253     */ 
     254    public boolean crosses180thMeridian() { 
     255        return this.minLon > this.maxLon; 
     256    } 
     257     
    214258    /** 
    215259     * Converts the lat/lon bounding box to an object of type Rectangle2D.Double 
     
    217261     */ 
    218262    public Rectangle2D.Double asRect() { 
    219         return new Rectangle2D.Double(minLon, minLat, maxLon-minLon, maxLat-minLat); 
     263        double w = maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0); 
     264        return new Rectangle2D.Double(minLon, minLat, w, maxLat-minLat); 
    220265    } 
    221266 
    222267    public double getArea() { 
    223         return (maxLon - minLon) * (maxLat - minLat); 
     268        double w = maxLon-minLon + (crosses180thMeridian() ? 360.0 : 0.0); 
     269        return w * (maxLat - minLat); 
    224270    } 
    225271 
     
    250296    } 
    251297 
    252     private double toIntervalLat(double value, double min, double max) { 
    253         if (value < min) 
    254             return min; 
    255         if (value > max) 
    256             return max; 
    257         return value; 
    258     } 
    259  
    260     private double toIntervalLon(double value) { 
    261         if (value < -180 || value > 180) { 
    262             value = (value + 180) % 360; 
    263             if (value < 0) { 
    264                 value += 360; 
    265             } 
    266             return value - 180; 
    267         } else 
    268             return value; 
    269     } 
    270  
    271298    public void normalize() { 
    272         minLat = toIntervalLat(minLat, -90, 90); 
    273         maxLat = toIntervalLat(maxLat, -90, 90); 
    274         minLon = toIntervalLon(minLon); 
    275         maxLon = toIntervalLon(maxLon); 
     299        minLat = LatLon.toIntervalLat(minLat); 
     300        maxLat = LatLon.toIntervalLat(maxLat); 
     301        minLon = LatLon.toIntervalLon(minLon); 
     302        maxLon = LatLon.toIntervalLon(maxLon); 
    276303    } 
    277304 
  • trunk/src/org/openstreetmap/josm/data/coor/LatLon.java

    r4574 r4580  
    7777                return isValidLat(lat()) && isValidLon(lon()); 
    7878        } 
     79         
     80    public static double toIntervalLat(double value) { 
     81        if (value < -90) 
     82            return -90; 
     83        if (value > 90) 
     84            return 90; 
     85        return value; 
     86    } 
     87 
     88    /** 
     89     * Returns a valid OSM longitude [-180,+180] for the given extended longitude value. 
     90     * For example, a value of -181 will return +179, a value of +181 will return -179.  
     91     * @param lon A longitude value not restricted to the [-180,+180] range. 
     92     */ 
     93    public static double toIntervalLon(double value) { 
     94        if (isValidLon(value)) { 
     95            return value; 
     96        } else { 
     97            int n = (int) (value + Math.signum(value)*180.0) / 360; 
     98            return value - n*360.0; 
     99        } 
     100    } 
    79101         
    80102    /** 
     
    165187     */ 
    166188    public boolean isWithin(Bounds b) { 
    167         return lat() >= b.getMin().lat() && lat() <= b.getMax().lat() && lon() > b.getMin().lon() && lon() < b.getMax().lon(); 
     189        return b.contains(this); 
    168190    } 
    169191 
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r4414 r4580  
    11751175        return ret; 
    11761176    } 
     1177     
     1178    /** 
     1179     * Moves all primitives and datasources from DataSet "from" to this DataSet 
     1180     * @param from The source DataSet 
     1181     */ 
     1182    public void mergeFrom(DataSet from) { 
     1183        if (from != null) { 
     1184            for (Node n : from.getNodes()) { 
     1185                from.removePrimitive(n); 
     1186                addPrimitive(n); 
     1187            } 
     1188            for (Way w : from.getWays()) { 
     1189                from.removePrimitive(w); 
     1190                addPrimitive(w); 
     1191            } 
     1192            for (Relation r : from.getRelations()) { 
     1193                from.removePrimitive(r); 
     1194                addPrimitive(r); 
     1195            } 
     1196            dataSources.addAll(from.dataSources); 
     1197            from.dataSources.clear(); 
     1198        } 
     1199    } 
    11771200 
    11781201    /* --------------------------------------------------------------------------------- */ 
Note: See TracChangeset for help on using the changeset viewer.