Ticket #13361: 13361_v6.patch

File 13361_v6.patch, 26.2 KB (added by GerdP, 7 years ago)

based on r11227, no further changes

  • src/org/openstreetmap/josm/data/osm/BBox.java

     
    99import org.openstreetmap.josm.data.coor.QuadTiling;
    1010import org.openstreetmap.josm.tools.Utils;
    1111
     12/**
     13 * A bounding box with latitude  / longitude coordinates
     14 */
    1215public class BBox {
    13 
    1416    private double xmin = Double.POSITIVE_INFINITY;
    1517    private double xmax = Double.NEGATIVE_INFINITY;
    1618    private double ymin = Double.POSITIVE_INFINITY;
     
    1719    private double ymax = Double.NEGATIVE_INFINITY;
    1820
    1921    /**
     22     * Constructs a new (invalid) BBox
     23     */
     24    public BBox() { }
     25
     26    /**
    2027     * Constructs a new {@code BBox} defined by a single point.
    2128     *
    2229     * @param x X coordinate
     
    2431     * @since 6203
    2532     */
    2633    public BBox(final double x, final double y) {
    27         xmax = xmin = x;
    28         ymax = ymin = y;
    29         sanity();
     34        if (!Double.isNaN(x) && !Double.isNaN(y)) {
     35            xmin = x;
     36            ymin = y;
     37            xmax = x;
     38            ymax = y;
     39        }
    3040    }
    3141
    3242    /**
    3343     * Constructs a new {@code BBox} defined by points <code>a</code> and <code>b</code>.
    34      * Result is minimal BBox containing both points.
     44     * Result is minimal BBox containing both points if they are both valid, else undefined
    3545     *
    3646     * @param a first point
    3747     * @param b second point
     
    5262        this.ymax = copy.ymax;
    5363    }
    5464
     65    /**
     66     * Create minimal  BBox so that {@code this.bounds(ax,ay)} and {@code this.bounds(bx,by)} will both return true
     67     * @param ax left or right X value (-180 .. 180)
     68     * @param ay top or bottom Y value (-90 .. 90)
     69     * @param bx left or right X value (-180 .. 180)
     70     * @param by top or bottom Y value (-90 .. 90)
     71     */
    5572    public BBox(double ax, double ay, double bx, double by) {
     73        if (Double.isNaN(ax) || Double.isNaN(ay) || Double.isNaN(bx) || Double.isNaN(by)) {
     74            return; // use default which is an invalid BBox
     75        }
    5676
    5777        if (ax > bx) {
    5878            xmax = ax;
     
    6989            ymax = by;
    7090            ymin = ay;
    7191        }
    72 
    73         sanity();
    7492    }
    7593
     94    /**
     95     * Create BBox for all nodes of the way with known coordinates.
     96     * If no node has a known coordinate, an invalid BBox is returned.
     97     * @param w the way
     98     */
    7699    public BBox(Way w) {
    77         for (Node n : w.getNodes()) {
    78             LatLon coor = n.getCoor();
    79             if (coor == null) {
    80                 continue;
    81             }
    82             add(coor);
    83         }
     100        w.getNodes().forEach((n) -> add(n.getCoor()));
    84101    }
    85102
     103    /**
     104     * Create BBox for a node. An invalid BBox is returned if the coordinates are not known.
     105     * @param n the node
     106     */
    86107    public BBox(Node n) {
    87         LatLon coor = n.getCoor();
    88         if (coor == null) {
    89             xmin = xmax = ymin = ymax = 0;
    90         } else {
    91             xmin = xmax = coor.lon();
    92             ymin = ymax = coor.lat();
    93         }
     108        if (n.isLatLonKnown())
     109            add(n.getCoor());
    94110    }
    95111
    96     private void sanity() {
    97         if (xmin < -180.0) {
    98             xmin = -180.0;
    99         }
    100         if (xmax > 180.0) {
    101             xmax = 180.0;
    102         }
    103         if (ymin < -90.0) {
    104             ymin = -90.0;
    105         }
    106         if (ymax > 90.0) {
    107             ymax = 90.0;
    108         }
    109     }
    110 
     112    /**
     113     * Add a point to an existing BBox. Extends this bbox if necessary so that this.bounds(c) will return true
     114     * if c is a valid LatLon instance.
     115     * @param c a LatLon point
     116     */
    111117    public final void add(LatLon c) {
    112         add(c.lon(), c.lat());
     118        if (c != null && c.isValid())
     119            add(c.lon(), c.lat());
    113120    }
    114121
    115122    /**
     
    118125     * @param y Y coordinate
    119126     */
    120127    public final void add(double x, double y) {
     128        if (Double.isNaN(x) || Double.isNaN(y))
     129            return;
    121130        xmin = Math.min(xmin, x);
    122131        xmax = Math.max(xmax, x);
    123132        ymin = Math.min(ymin, y);
    124133        ymax = Math.max(ymax, y);
    125         sanity();
    126134    }
    127135
    128     public final void add(BBox box) {
    129         xmin = Math.min(xmin, box.xmin);
    130         xmax = Math.max(xmax, box.xmax);
    131         ymin = Math.min(ymin, box.ymin);
    132         ymax = Math.max(ymax, box.ymax);
    133         sanity();
     136    /**
     137     * Extends this bbox to include the bbox other. Does nothing if other is not valid.
     138     * @param other a bbox
     139     */
     140    public final void add(BBox other) {
     141        if (other.isValid()) {
     142            xmin = Math.min(xmin, other.xmin);
     143            xmax = Math.max(xmax, other.xmax);
     144            ymin = Math.min(ymin, other.ymin);
     145            ymax = Math.max(ymax, other.ymax);
     146        }
    134147    }
    135148
     149    /**
     150     * Extends this bbox to include the bbox of the primitive extended by extraSpace.
     151     * @param primitive an OSM primitive
     152     * @param extraSpace the value to extend the primitives bbox. Unit is in LatLon degrees.
     153     */
    136154    public void addPrimitive(OsmPrimitive primitive, double extraSpace) {
    137155        BBox primBbox = primitive.getBBox();
    138156        add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace);
     
    278296            && Double.compare(b.xmin, xmin) == 0 && Double.compare(b.ymin, ymin) == 0;
    279297    }
    280298
     299    /**
     300     * @return true if the bbox covers a part of the planets surface
     301     * Height and width must be non-negative, but may (both) be 0.
     302     */
     303    public boolean isValid() {
     304        return (xmin <= xmax && ymin <= ymax);
     305    }
     306
     307    /**
     308     * @return true if the bbox covers a part of the planets surface
     309     */
     310    public boolean isInWorld() {
     311        return !(xmin < -180.0 || xmax > 180.0 || ymin < -90.0 || ymax > 90.0);
     312    }
     313
    281314    @Override
    282315    public String toString() {
    283316        return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]";
  • src/org/openstreetmap/josm/data/osm/DataSet.java

     
    503503                throw new DataIntegrityProblemException(
    504504                        tr("Unable to add primitive {0} to the dataset because it is already included", primitive.toString()));
    505505
    506             primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reinexRelation to work properly)
     506            allPrimitives.add(primitive);
     507            primitive.setDataset(this);
     508            primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reindexRelation to work properly)
    507509            boolean success = false;
    508510            if (primitive instanceof Node) {
    509511                success = nodes.add((Node) primitive);
     
    514516            }
    515517            if (!success)
    516518                throw new RuntimeException("failed to add primitive: "+primitive);
    517             allPrimitives.add(primitive);
    518             primitive.setDataset(this);
    519519            firePrimitivesAdded(Collections.singletonList(primitive), false);
    520520        } finally {
    521521            endUpdate();
  • src/org/openstreetmap/josm/data/osm/Node.java

     
    329329
    330330    @Override
    331331    public BBox getBBox() {
    332         return new BBox(this);
     332        return new BBox(lon, lat);
    333333    }
    334334
    335335    @Override
     336    protected void addToBBox(BBox box, Set<PrimitiveId> visited) {
     337        box.add(lon, lat);
     338    }
     339
     340    @Override
    336341    public void updatePosition() {
    337342        // Do nothing
    338343    }
  • src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    14161416    public boolean isMultipolygon() {
    14171417        return false;
    14181418    }
     1419
     1420    /**
     1421     * If necessary, extend the bbox to contain this primitive
     1422     * @param box a bbox instance
     1423     * @param visited a set of visited members  or null
     1424     */
     1425    protected abstract void addToBBox(BBox box, Set<PrimitiveId> visited);
    14191426}
  • src/org/openstreetmap/josm/data/osm/QuadBuckets.java

     
    55import java.util.Arrays;
    66import java.util.Collection;
    77import java.util.Iterator;
     8import java.util.LinkedHashSet;
    89import java.util.List;
    910import java.util.NoSuchElementException;
    1011
     
    3132        throw new AssertionError(s);
    3233    }
    3334
    34     public static final int MAX_OBJECTS_PER_LEVEL = 16;
     35    private static final int MAX_OBJECTS_PER_LEVEL = 16;
    3536
    3637    static class QBLevel<T extends OsmPrimitive> {
    3738        private final int level;
     
    181182        }
    182183
    183184        boolean matches(final T o, final BBox searchBbox) {
    184             if (o instanceof Node) {
    185                 final LatLon latLon = ((Node) o).getCoor();
    186                 // node without coords -> bbox[0,0,0,0]
    187                 return searchBbox.bounds(latLon != null ? latLon : LatLon.ZERO);
    188             }
    189185            return o.getBBox().intersects(searchBbox);
    190186        }
    191187
     
    393389    private QBLevel<T> root;
    394390    private QBLevel<T> searchCache;
    395391    private int size;
     392    private Collection<T> invalidBBoxPrimitives;
    396393
    397394    /**
    398395     * Constructs a new {@code QuadBuckets}.
     
    404401    @Override
    405402    public final void clear() {
    406403        root = new QBLevel<>(this);
     404        invalidBBoxPrimitives = new LinkedHashSet<>();
    407405        searchCache = null;
    408406        size = 0;
    409407    }
     
    410408
    411409    @Override
    412410    public boolean add(T n) {
    413         root.add(n);
     411        if (n.getBBox().isValid())
     412            root.add(n);
     413        else
     414            invalidBBoxPrimitives.add(n);
    414415        size++;
    415416        return true;
    416417    }
     
    460461        T t = (T) o;
    461462        searchCache = null; // Search cache might point to one of removed buckets
    462463        QBLevel<T> bucket = root.findBucket(t.getBBox());
    463         if (bucket.removeContent(t)) {
     464        boolean removed = bucket.removeContent(t);
     465        if (!removed)
     466            removed = invalidBBoxPrimitives.remove(o);
     467        if (removed)
    464468            size--;
    465             return true;
    466         } else
    467             return false;
     469        return removed;
    468470    }
    469471
    470472    @Override
     
    471473    public boolean contains(Object o) {
    472474        @SuppressWarnings("unchecked")
    473475        T t = (T) o;
     476        if (!t.getBBox().isValid())
     477            return invalidBBoxPrimitives.contains(o);
    474478        QBLevel<T> bucket = root.findBucket(t.getBBox());
    475479        return bucket != null && bucket.content != null && bucket.content.contains(t);
    476480    }
     
    500504    class QuadBucketIterator implements Iterator<T> {
    501505        private QBLevel<T> currentNode;
    502506        private int contentIndex;
     507        private Iterator<T> invalidBBoxIterator = invalidBBoxPrimitives.iterator();
     508        boolean fromInvalidBBoxPrimitives;
    503509        QuadBuckets<T> qb;
    504510
    505511        final QBLevel<T> nextContentNode(QBLevel<T> q) {
     
    525531
    526532        @Override
    527533        public boolean hasNext() {
    528             if (this.peek() == null)
    529                 return false;
     534            if (this.peek() == null) {
     535                fromInvalidBBoxPrimitives = true;
     536                return invalidBBoxIterator.hasNext();
     537            }
    530538            return true;
    531539        }
    532540
     
    547555
    548556        @Override
    549557        public T next() {
     558            if (fromInvalidBBoxPrimitives)
     559                return invalidBBoxIterator.next();
    550560            T ret = peek();
    551561            if (ret == null)
    552562                throw new NoSuchElementException();
     
    556566
    557567        @Override
    558568        public void remove() {
    559             // two uses
    560             // 1. Back up to the thing we just returned
    561             // 2. move the index back since we removed
    562             //    an element
    563             contentIndex--;
    564             T object = peek();
    565             if (currentNode.removeContent(object))
     569            if (fromInvalidBBoxPrimitives) {
     570                invalidBBoxIterator.remove();
    566571                qb.size--;
     572            } else {
     573                // two uses
     574                // 1. Back up to the thing we just returned
     575                // 2. move the index back since we removed
     576                //    an element
     577                contentIndex--;
     578                T object = peek();
     579                if (currentNode.removeContent(object))
     580                    qb.size--;
     581
     582            }
    567583        }
    568584    }
    569585
     
    582598        return size == 0;
    583599    }
    584600
     601    /**
     602     * Search for elements in the given bbox.
     603     * @param searchBbox the bbox
     604     * @return a list of elements, maybe empty but never null
     605     */
    585606    public List<T> search(BBox searchBbox) {
    586607        List<T> ret = new ArrayList<>();
     608        if (!searchBbox.isValid()) {
     609            return ret;
     610        }
    587611        // Doing this cuts down search cost on a real-life data set by about 25%
    588612        if (searchCache == null) {
    589613            searchCache = root;
  • src/org/openstreetmap/josm/data/osm/Relation.java

     
    446446
    447447    @Override
    448448    public BBox getBBox() {
    449         RelationMember[] members = this.members;
     449        if (getDataSet() != null && bbox != null)
     450            return new BBox(bbox); // use cached value
    450451
    451         if (members.length == 0)
    452             return new BBox(0, 0, 0, 0);
    453         if (getDataSet() == null)
    454             return calculateBBox(new HashSet<PrimitiveId>());
    455         else {
    456             if (bbox == null) {
    457                 bbox = calculateBBox(new HashSet<PrimitiveId>());
    458             }
    459             if (bbox == null)
    460                 return new BBox(0, 0, 0, 0); // No real members
    461             else
    462                 return new BBox(bbox);
    463         }
     452        BBox box = new BBox();
     453        addToBBox(box, new HashSet<PrimitiveId>());
     454        if (getDataSet() != null)
     455            bbox = box; // set cache
     456        return new BBox(box);
    464457    }
    465458
    466     private BBox calculateBBox(Set<PrimitiveId> visitedRelations) {
    467         if (visitedRelations.contains(this))
    468             return null;
    469         visitedRelations.add(this);
    470 
    471         RelationMember[] members = this.members;
    472         if (members.length == 0)
    473             return null;
    474         else {
    475             BBox result = null;
    476             for (RelationMember rm:members) {
    477                 BBox box = rm.isRelation() ? rm.getRelation().calculateBBox(visitedRelations) : rm.getMember().getBBox();
    478                 if (box != null) {
    479                     if (result == null) {
    480                         result = box;
    481                     } else {
    482                         result.add(box);
    483                     }
    484                 }
    485             }
    486             return result;
     459    @Override
     460    protected void addToBBox(BBox box, Set<PrimitiveId> visited) {
     461        for (RelationMember rm : members) {
     462            if (visited.add(rm.getMember()))
     463                rm.getMember().addToBBox(box, visited);
    487464        }
    488465    }
    489466
    490467    @Override
    491468    public void updatePosition() {
    492         bbox = calculateBBox(new HashSet<PrimitiveId>());
     469        bbox = null; // make sure that it is recalculated
     470        bbox = getBBox();
    493471    }
    494472
    495473    @Override
  • src/org/openstreetmap/josm/data/osm/Way.java

     
    633633    }
    634634
    635635    @Override
     636    protected void addToBBox(BBox box, Set<PrimitiveId> visited) {
     637        box.add(getBBox());
     638    }
     639
     640    @Override
    636641    public void updatePosition() {
    637642        bbox = new BBox(this);
    638643    }
  • test/unit/org/openstreetmap/josm/data/osm/BBoxTest.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.osm;
    33
     4import static org.junit.Assert.assertFalse;
     5import static org.junit.Assert.assertTrue;
     6
    47import org.junit.Rule;
    58import org.junit.Test;
     9import org.openstreetmap.josm.data.coor.LatLon;
    610import org.openstreetmap.josm.testutils.JOSMTestRules;
    711
    812import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    3034            .suppress(Warning.NONFINAL_FIELDS)
    3135            .verify();
    3236    }
     37
     38    /**
     39     * Test LatLon constructor which might result in invalid bbox
     40     */
     41    @Test
     42    public void testLatLonConstructor() {
     43        LatLon latLon1 = new LatLon(10, 20);
     44        LatLon latLon2 = new LatLon(20, 10);
     45        BBox b1 = new BBox(latLon1, latLon2);
     46        BBox b2 = new BBox(latLon2, latLon1);
     47        assertTrue(b1.bounds(latLon1));
     48        assertTrue(b2.bounds(latLon1));
     49        assertTrue(b1.bounds(latLon2));
     50        assertTrue(b2.bounds(latLon2));
     51        assertTrue(b2.bounds(b1));
     52        assertTrue(b1.bounds(b2));
     53
     54        // invalid latlon values
     55        LatLon invalid1 = new LatLon(-190, 340);
     56        BBox b3 = new BBox(invalid1, latLon1);
     57        BBox b4 = new BBox(latLon1, invalid1);
     58        BBox b5 = new BBox(invalid1, invalid1);
     59        // what should be the result?
     60        assertTrue(b3.isValid());
     61        assertTrue(b4.isValid());
     62        assertTrue(b3.bounds(latLon1));
     63        assertTrue(b4.bounds(latLon1));
     64        assertTrue(b5.isValid());
     65        assertFalse(b5.isInWorld());
     66    }
     67
    3368}
  • test/unit/org/openstreetmap/josm/data/osm/NodeTest.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.osm;
    33
     4import static org.junit.Assert.assertEquals;
    45import static org.junit.Assert.assertFalse;
    56import static org.junit.Assert.assertNotNull;
    67import static org.junit.Assert.assertNull;
     8import static org.junit.Assert.assertTrue;
    79
    810import org.junit.Rule;
    911import org.junit.Test;
     
    4244        assertNull(n.getCoor());
    4345        assertFalse(n.isOutsideDownloadArea());
    4446    }
     47
     48    /**
     49     * Test BBox calculation with Node
     50     */
     51    @Test
     52    public void testBBox() {
     53        DataSet ds = new DataSet();
     54        Node n1 = new Node(1);
     55        Node n2 = new Node(2);
     56        Node n3 = new Node(3);
     57        Node n4 = new Node(4);
     58        n1.setIncomplete(true);
     59        n2.setCoor(new LatLon(10, 10));
     60        n3.setCoor(new LatLon(20, 20));
     61        n4.setCoor(new LatLon(90, 180));
     62        ds.addPrimitive(n1);
     63        ds.addPrimitive(n2);
     64        ds.addPrimitive(n3);
     65        ds.addPrimitive(n4);
     66
     67        assertFalse(n1.getBBox().isValid());
     68        assertTrue(n2.getBBox().isValid());
     69        assertTrue(n3.getBBox().isValid());
     70        assertTrue(n4.getBBox().isValid());
     71        BBox box1 = n1.getBBox();
     72        box1.add(n2.getCoor());
     73        assertTrue(box1.isValid());
     74        BBox box2 = n2.getBBox();
     75        box2.add(n1.getCoor());
     76        assertTrue(box2.isValid());
     77        assertEquals(box1, box2);
     78        box1.add(n3.getCoor());
     79        assertTrue(box1.isValid());
     80        assertEquals(box1.getCenter(), new LatLon(15, 15));
     81    }
    4582}
  • test/unit/org/openstreetmap/josm/data/osm/QuadBucketsTest.java

     
    88import java.util.Collection;
    99import java.util.Iterator;
    1010import java.util.List;
     11import java.util.Random;
    1112
    1213import org.fest.reflect.core.Reflection;
    1314import org.fest.reflect.reference.TypeRef;
     
    174175            Assert.assertEquals(count, qbWays.size());
    175176        }
    176177        Assert.assertEquals(0, qbWays.size());
     178
    177179    }
     180
     181    /**
     182     *  Add more data so that quad buckets tree has a few leaves
     183     */
     184    @Test
     185    public void testSplitsWithIncompleteData() {
     186        DataSet ds = new DataSet();
     187        long nodeId = 1;
     188        long wayId = 1;
     189        final int NUM_COMPLETE_WAYS = 300;
     190        final int NUM_INCOMPLETE_WAYS = 10;
     191        final int NUM_NODES_PER_WAY = 20;
     192        final int NUM_INCOMPLETE_NODES = 10;
     193
     194        // force splits in quad buckets
     195        Random random = new Random(31);
     196        for (int i = 0; i < NUM_COMPLETE_WAYS; i++) {
     197            Way w = new Way(wayId++);
     198            List<Node> nodes = new ArrayList<>();
     199            double center = random.nextDouble() * 10;
     200            for (int j = 0; j < NUM_NODES_PER_WAY; j++) {
     201                Node n = new Node(nodeId++);
     202                double lat = random.nextDouble() * 0.001;
     203                double lon = random.nextDouble() * 0.001;
     204                n.setCoor(new LatLon(center + lat, center + lon));
     205                nodes.add(n);
     206                ds.addPrimitive(n);
     207            }
     208            w.setNodes(nodes);
     209            ds.addPrimitive(w);
     210        }
     211        Assert.assertEquals(NUM_COMPLETE_WAYS, ds.getWays().size());
     212        Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY, ds.getNodes().size());
     213
     214        // add some incomplete nodes
     215        List<Node> incompleteNodes = new ArrayList<>();
     216        for (int i = 0; i < NUM_INCOMPLETE_NODES; i++) {
     217            Node n = new Node(nodeId++);
     218            incompleteNodes.add(n);
     219            n.setIncomplete(true);
     220            ds.addPrimitive(n);
     221        }
     222        Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY + NUM_INCOMPLETE_NODES, ds.getNodes().size());
     223        // add some incomplete ways
     224        List<Way> incompleteWays = new ArrayList<>();
     225        for (int i = 0; i < NUM_INCOMPLETE_WAYS; i++) {
     226            Way w = new Way(wayId++);
     227            incompleteWays.add(w);
     228            w.setIncomplete(true);
     229            ds.addPrimitive(w);
     230        }
     231        Assert.assertEquals(NUM_COMPLETE_WAYS + NUM_INCOMPLETE_WAYS, ds.getWays().size());
     232
     233        BBox planet = new BBox(-180, -90, 180, 90);
     234        // incomplete ways should not be found with search
     235        Assert.assertEquals(NUM_COMPLETE_WAYS, ds.searchWays(planet).size());
     236        // incomplete ways are only retrieved via iterator or object reference
     237        for (Way w : incompleteWays) {
     238            Assert.assertTrue(ds.getWays().contains(w));
     239        }
     240
     241        QuadBuckets<Way> qb = new QuadBuckets<>();
     242        qb.addAll(ds.getWays());
     243        int count = qb.size();
     244        Assert.assertEquals(count, ds.getWays().size());
     245        Iterator<Way> iter = qb.iterator();
     246        while (iter.hasNext()) {
     247            iter.next();
     248            iter.remove();
     249            count--;
     250            Assert.assertEquals(count, qb.size());
     251        }
     252        Assert.assertEquals(0, qb.size());
     253    }
    178254}
  • test/unit/org/openstreetmap/josm/data/osm/RelationTest.java

     
    7575        w1.addNode(n3);
    7676        Assert.assertEquals(w1.getBBox(), r1.getBBox());
    7777        Assert.assertEquals(w1.getBBox(), r2.getBBox());
     78
     79        // create incomplete node and add it to the relation, this must not change the bbox
     80        BBox oldBBox = r2.getBBox();
     81        Node n4 = new Node();
     82        n4.setIncomplete(true);
     83        ds.addPrimitive(n4);
     84        r2.addMember(new RelationMember("", n4));
     85
     86        Assert.assertEquals(oldBBox, r2.getBBox());
    7887    }
    7988
    8089    @Test
  • test/unit/org/openstreetmap/josm/data/osm/WayTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.osm;
     3
     4import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertFalse;
     6import static org.junit.Assert.assertTrue;
     7
     8import java.util.Arrays;
     9
     10import org.junit.BeforeClass;
     11import org.junit.Test;
     12import org.openstreetmap.josm.JOSMFixture;
     13import org.openstreetmap.josm.data.coor.LatLon;
     14
     15/**
     16 * Unit tests of the {@code Node} class.
     17 */
     18public class WayTest {
     19
     20    /**
     21     * Setup test.
     22     */
     23    @BeforeClass
     24    public static void setUpBeforeClass() {
     25        JOSMFixture.createUnitTestFixture().init();
     26    }
     27
     28    /**
     29     * Test BBox calculation with Way
     30     */
     31    @Test
     32    public void testBBox() {
     33        DataSet ds = new DataSet();
     34        Node n1 = new Node(1);
     35        Node n2 = new Node(2);
     36        Node n3 = new Node(3);
     37        Node n4 = new Node(4);
     38        n1.setIncomplete(true);
     39        n2.setCoor(new LatLon(10, 10));
     40        n3.setCoor(new LatLon(20, 20));
     41        n4.setCoor(new LatLon(90, 180));
     42        ds.addPrimitive(n1);
     43        ds.addPrimitive(n2);
     44        ds.addPrimitive(n3);
     45        ds.addPrimitive(n4);
     46        Way way = new Way(1);
     47        assertFalse(way.getBBox().isValid());
     48        way.setNodes(Arrays.asList(n1));
     49        assertFalse(way.getBBox().isValid());
     50        way.setNodes(Arrays.asList(n2));
     51        assertTrue(way.getBBox().isValid());
     52        way.setNodes(Arrays.asList(n1, n2));
     53        assertTrue(way.getBBox().isValid());
     54        assertEquals(way.getBBox(), new BBox(10, 10));
     55    }
     56}