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

File:
1 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 
Note: See TracChangeset for help on using the changeset viewer.