Changeset 2350 in josm for trunk/src/org


Ignore:
Timestamp:
2009-10-29T20:10:13+01:00 (14 years ago)
Author:
Gubaer
Message:

applied #3781: patch by hansendc: Selecting a way that is part outer ring of multipolygon is broken

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java

    r2321 r2350  
    391391    }
    392392
    393     public Collection<Way> joinWays(Collection<Way> join, OsmPrimitive errs)
     393    public Collection<PolyData> joinWays(Collection<Way> join, OsmPrimitive errs)
    394394    {
    395         Collection<Way> res = new LinkedList<Way>();
     395        Collection<PolyData> res = new LinkedList<PolyData>();
    396396        Object[] joinArray = join.toArray();
    397397        int left = join.size();
     
    480480                w = new Way(w);
    481481                w.setNodes(n);
    482                 if (selected) {
    483                     data.addSelected(Collections.singleton(w),false /* don't notify listeners */);
    484                 } else {
    485                     data.clearSelection(w);
    486                 }
     482                // Do not mess with the DataSet's contents here.
    487483            }
    488484            if(!w.isClosed())
     
    494490                }
    495491            }
    496             res.add(w);
     492            PolyData pd = new PolyData(w);
     493            pd.selected = selected;
     494            res.add(new PolyData(w));
    497495        } /* while(left != 0) */
    498496
     
    845843    }
    846844
     845    class PolyData {
     846        public Polygon poly = new Polygon();
     847        public Way way;
     848        public boolean selected = false;
     849        private Point p = null;
     850        private Collection<Polygon> inner = null;
     851        PolyData(Way w)
     852        {
     853            way = w;
     854            for (Node n : w.getNodes())
     855            {
     856                p = nc.getPoint(n);
     857                poly.addPoint(p.x,p.y);
     858            }
     859        }
     860        public int contains(Polygon p)
     861        {
     862            int contains = p.npoints;
     863            for(int i = 0; i < p.npoints; ++i)
     864            {
     865                if(poly.contains(p.xpoints[i],p.ypoints[i])) {
     866                    --contains;
     867                }
     868            }
     869            if(contains == 0) return 1;
     870            if(contains == p.npoints) return 0;
     871            return 2;
     872        }
     873        public void addInner(Polygon p)
     874        {
     875            if(inner == null) {
     876                inner = new ArrayList<Polygon>();
     877            }
     878            inner.add(p);
     879        }
     880        public boolean isClosed()
     881        {
     882            return (poly.npoints >= 3
     883                    && poly.xpoints[0] == poly.xpoints[poly.npoints-1]
     884                                                       && poly.ypoints[0] == poly.ypoints[poly.npoints-1]);
     885        }
     886        public Polygon get()
     887        {
     888            if(inner != null)
     889            {
     890                for (Polygon pp : inner)
     891                {
     892                    for(int i = 0; i < pp.npoints; ++i) {
     893                        poly.addPoint(pp.xpoints[i],pp.ypoints[i]);
     894                    }
     895                    poly.addPoint(p.x,p.y);
     896                }
     897                inner = null;
     898            }
     899            return poly;
     900        }
     901    }
     902    void addInnerToOuters(Relation r, boolean incomplete, PolyData pdInner, LinkedList<PolyData> outerPolygons)
     903    {
     904        Way wInner = pdInner.way;
     905        if(wInner != null && !wInner.isClosed())
     906        {
     907            Point pInner = nc.getPoint(wInner.getNode(0));
     908            pdInner.poly.addPoint(pInner.x,pInner.y);
     909        }
     910        PolyData o = null;
     911        for (PolyData pdOuter : outerPolygons)
     912        {
     913            Integer c = pdOuter.contains(pdInner.poly);
     914            if(c >= 1)
     915            {
     916                if(c > 1 && pdOuter.way != null && pdOuter.way.isClosed())
     917                {
     918                    r.putError(tr("Intersection between ways ''{0}'' and ''{1}''.",
     919                            pdOuter.way.getDisplayName(DefaultNameFormatter.getInstance()), wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
     920                }
     921                if(o == null || o.contains(pdOuter.poly) > 0) {
     922                    o = pdOuter;
     923                }
     924            }
     925        }
     926        if(o == null)
     927        {
     928            if(!incomplete)
     929            {
     930                r.putError(tr("Inner way ''{0}'' is outside.",
     931                        wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
     932            }
     933            o = outerPolygons.get(0);
     934        }
     935        o.addInner(pdInner.poly);
     936    }
     937
    847938    public Boolean drawMultipolygon(Relation r) {
    848939        Collection<Way> inner = new LinkedList<Way>();
     
    9121003            Boolean zoomok = isZoomOk(wayStyle);
    9131004            Boolean visible = false;
    914             Collection<Way> join = new LinkedList<Way>();
     1005            Collection<Way> outerjoin = new LinkedList<Way>();
     1006            Collection<Way> innerjoin = new LinkedList<Way>();
    9151007
    9161008            drawn = true;
     
    9201012                    outerclosed.add(w);
    9211013                } else {
    922                     join.add(w);
    923                 }
    924             }
    925             if(join.size() != 0)
    926             {
    927                 for(Way w : joinWays(join, incomplete ? null : r)) {
    928                     outerclosed.add(w);
    929                 }
    930             }
    931 
    932             join.clear();
     1014                    outerjoin.add(w);
     1015                }
     1016            }
    9331017            for (Way w : inner)
    9341018            {
     
    9361020                    innerclosed.add(w);
    9371021                } else {
    938                     join.add(w);
    939                 }
    940             }
    941             if(join.size() != 0)
    942             {
    943                 for(Way w : joinWays(join, incomplete ? null : r)) {
    944                     innerclosed.add(w);
    945                 }
    946             }
    947 
    948             if(outerclosed.size() == 0)
     1022                    innerjoin.add(w);
     1023                }
     1024            }
     1025            if(outerclosed.size() == 0 && outerjoin.size() == 0)
    9491026            {
    9501027                r.putError(tr("No outer way for multipolygon ''{0}''.",
     
    9541031            else if(zoomok)
    9551032            {
    956                 class PolyData {
    957                     public Polygon poly = new Polygon();
    958                     public Way way;
    959                     private Point p = null;
    960                     private Collection<Polygon> inner = null;
    961                     PolyData(Way w)
    962                     {
    963                         way = w;
    964                         for (Node n : w.getNodes())
    965                         {
    966                             p = nc.getPoint(n);
    967                             poly.addPoint(p.x,p.y);
    968                         }
    969                     }
    970                     public int contains(Polygon p)
    971                     {
    972                         int contains = p.npoints;
    973                         for(int i = 0; i < p.npoints; ++i)
    974                         {
    975                             if(poly.contains(p.xpoints[i],p.ypoints[i])) {
    976                                 --contains;
    977                             }
    978                         }
    979                         if(contains == 0) return 1;
    980                         if(contains == p.npoints) return 0;
    981                         return 2;
    982                     }
    983                     public void addInner(Polygon p)
    984                     {
    985                         if(inner == null) {
    986                             inner = new ArrayList<Polygon>();
    987                         }
    988                         inner.add(p);
    989                     }
    990                     public boolean isClosed()
    991                     {
    992                         return (poly.npoints >= 3
    993                                 && poly.xpoints[0] == poly.xpoints[poly.npoints-1]
    994                                                                    && poly.ypoints[0] == poly.ypoints[poly.npoints-1]);
    995                     }
    996                     public Polygon get()
    997                     {
    998                         if(inner != null)
    999                         {
    1000                             for (Polygon pp : inner)
    1001                             {
    1002                                 for(int i = 0; i < pp.npoints; ++i) {
    1003                                     poly.addPoint(pp.xpoints[i],pp.ypoints[i]);
    1004                                 }
    1005                                 poly.addPoint(p.x,p.y);
    1006                             }
    1007                             inner = null;
    1008                         }
    1009                         return poly;
    1010                     }
    1011                 }
    10121033                LinkedList<PolyData> poly = new LinkedList<PolyData>();
    1013                 for (Way w : outerclosed)
    1014                 {
     1034                for (Way w : outerclosed) {
    10151035                    poly.add(new PolyData(w));
    10161036                }
     1037                poly.addAll(joinWays(outerjoin, incomplete ? null : r));
    10171038                for (Way wInner : innerclosed)
    10181039                {
    1019                     Polygon polygon = new Polygon();
    1020 
    1021                     for (Node n : wInner.getNodes())
    1022                     {
    1023                         Point pInner = nc.getPoint(n);
    1024                         polygon.addPoint(pInner.x,pInner.y);
    1025                     }
    1026                     if(!wInner.isClosed())
    1027                     {
    1028                         Point pInner = nc.getPoint(wInner.getNode(0));
    1029                         polygon.addPoint(pInner.x,pInner.y);
    1030                     }
    1031                     PolyData o = null;
    1032                     for (PolyData pd : poly)
    1033                     {
    1034                         Integer c = pd.contains(polygon);
    1035                         if(c >= 1)
    1036                         {
    1037                             if(c > 1 && pd.way.isClosed())
    1038                             {
    1039                                 r.putError(tr("Intersection between ways ''{0}'' and ''{1}''.",
    1040                                         pd.way.getDisplayName(DefaultNameFormatter.getInstance()), wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
    1041                             }
    1042                             if(o == null || o.contains(pd.poly) > 0) {
    1043                                 o = pd;
    1044                             }
    1045                         }
    1046                     }
    1047                     if(o == null)
    1048                     {
    1049                         if(!incomplete)
    1050                         {
    1051                             r.putError(tr("Inner way ''{0}'' is outside.",
    1052                                     wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
    1053                         }
    1054                         o = poly.get(0);
    1055                     }
    1056                     o.addInner(polygon);
     1040                    PolyData pdInner = new PolyData(wInner);
     1041                    // incomplete is probably redundant
     1042                    addInnerToOuters(r, incomplete, pdInner, poly);
     1043                }
     1044                for (PolyData pdInner : joinWays(innerjoin, incomplete ? null : r)) {
     1045                    addInnerToOuters(r, incomplete, pdInner, poly);
    10571046                }
    10581047                AreaElemStyle areaStyle = (AreaElemStyle)wayStyle;
     
    10621051                    if(isPolygonVisible(p))
    10631052                    {
    1064                         drawAreaPolygon(p, (data.isSelected(pd.way) || data.isSelected(r)) ? selectedColor
    1065                                 : areaStyle.color);
     1053                        boolean selected = (data.isSelected(pd.way) || data.isSelected(r));
     1054                        drawAreaPolygon(p, selected ? selectedColor : areaStyle.color);
    10661055                        visible = true;
    10671056                    }
Note: See TracChangeset for help on using the changeset viewer.