Changeset 2788 in josm for trunk/src


Ignore:
Timestamp:
2010-01-09T14:43:03+01:00 (14 years ago)
Author:
jttt
Message:

Move most of multipolygon handling from MapPaintVisitor to the new Multipolygon class, move checks to validator plugin

Location:
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint
Files:
2 added
1 edited

Legend:

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

    r2762 r2788  
    1717import java.util.Comparator;
    1818import java.util.LinkedList;
    19 import java.util.List;
    2019
    2120import org.openstreetmap.josm.Main;
     
    3231import org.openstreetmap.josm.data.osm.Way;
    3332import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
     33import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
     34import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData;
    3435import org.openstreetmap.josm.gui.DefaultNameFormatter;
    3536import org.openstreetmap.josm.gui.NavigatableComponent;
     
    190191            areaStyle.getLineStyle().paintPrimitive(w, paintSettings, painter, data.isSelected(w));
    191192        }
    192     }
    193 
    194     public Collection<PolyData> joinWays(Collection<Way> join, OsmPrimitive errs)
    195     {
    196         Collection<PolyData> res = new LinkedList<PolyData>();
    197         Way[] joinArray = join.toArray(new Way[join.size()]);
    198         int left = join.size();
    199         while(left != 0)
    200         {
    201             Way w = null;
    202             boolean selected = false;
    203             List<Node> n = null;
    204             boolean joined = true;
    205             while(joined && left != 0)
    206             {
    207                 joined = false;
    208                 for(int i = 0; i < joinArray.length && left != 0; ++i)
    209                 {
    210                     if(joinArray[i] != null)
    211                     {
    212                         Way c = joinArray[i];
    213                         if(w == null)
    214                         { w = c; selected = data.isSelected(w); joinArray[i] = null; --left; }
    215                         else
    216                         {
    217                             int mode = 0;
    218                             int cl = c.getNodesCount()-1;
    219                             int nl;
    220                             if(n == null)
    221                             {
    222                                 nl = w.getNodesCount()-1;
    223                                 if(w.getNode(nl) == c.getNode(0)) {
    224                                     mode = 21;
    225                                 } else if(w.getNode(nl) == c.getNode(cl)) {
    226                                     mode = 22;
    227                                 } else if(w.getNode(0) == c.getNode(0)) {
    228                                     mode = 11;
    229                                 } else if(w.getNode(0) == c.getNode(cl)) {
    230                                     mode = 12;
    231                                 }
    232                             }
    233                             else
    234                             {
    235                                 nl = n.size()-1;
    236                                 if(n.get(nl) == c.getNode(0)) {
    237                                     mode = 21;
    238                                 } else if(n.get(0) == c.getNode(cl)) {
    239                                     mode = 12;
    240                                 } else if(n.get(0) == c.getNode(0)) {
    241                                     mode = 11;
    242                                 } else if(n.get(nl) == c.getNode(cl)) {
    243                                     mode = 22;
    244                                 }
    245                             }
    246                             if(mode != 0)
    247                             {
    248                                 joinArray[i] = null;
    249                                 joined = true;
    250                                 if(data.isSelected(c)) {
    251                                     selected = true;
    252                                 }
    253                                 --left;
    254                                 if(n == null) {
    255                                     n = w.getNodes();
    256                                 }
    257                                 n.remove((mode == 21 || mode == 22) ? nl : 0);
    258                                 if(mode == 21) {
    259                                     n.addAll(c.getNodes());
    260                                 } else if(mode == 12) {
    261                                     n.addAll(0, c.getNodes());
    262                                 } else if(mode == 22)
    263                                 {
    264                                     for(Node node : c.getNodes()) {
    265                                         n.add(nl, node);
    266                                     }
    267                                 }
    268                                 else /* mode == 11 */
    269                                 {
    270                                     for(Node node : c.getNodes()) {
    271                                         n.add(0, node);
    272                                     }
    273                                 }
    274                             }
    275                         }
    276                     }
    277                 } /* for(i = ... */
    278             } /* while(joined) */
    279             if(n != null)
    280             {
    281                 w = new Way(w);
    282                 w.setNodes(n);
    283             }
    284             if(!w.isClosed())
    285             {
    286                 if(errs != null)
    287                 {
    288                     putError(errs, tr("multipolygon way ''{0}'' is not closed.",
    289                             w.getDisplayName(DefaultNameFormatter.getInstance())), true);
    290                 }
    291             }
    292             PolyData pd = new PolyData(w);
    293             pd.selected = selected;
    294             res.add(pd);
    295         } /* while(left != 0) */
    296 
    297         return res;
    298193    }
    299194
     
    564459    }
    565460
    566     class PolyData {
    567         public Polygon poly = new Polygon();
    568         public Way way;
    569         public boolean selected = false;
    570         private Point p = null;
    571         private Collection<Polygon> inner = null;
    572         PolyData(Way w)
    573         {
    574             way = w;
    575             for (Node n : w.getNodes())
    576             {
    577                 p = nc.getPoint(n);
    578                 poly.addPoint(p.x,p.y);
    579             }
    580         }
    581         public int contains(Polygon p)
    582         {
    583             int contains = p.npoints;
    584             for(int i = 0; i < p.npoints; ++i)
    585             {
    586                 if(poly.contains(p.xpoints[i],p.ypoints[i])) {
    587                     --contains;
    588                 }
    589             }
    590             if(contains == 0) return 1;
    591             if(contains == p.npoints) return 0;
    592             return 2;
    593         }
    594         public void addInner(Polygon p)
    595         {
    596             if(inner == null) {
    597                 inner = new ArrayList<Polygon>();
    598             }
    599             inner.add(p);
    600         }
    601         public boolean isClosed()
    602         {
    603             return (poly.npoints >= 3
    604                     && poly.xpoints[0] == poly.xpoints[poly.npoints-1]
    605                                                        && poly.ypoints[0] == poly.ypoints[poly.npoints-1]);
    606         }
    607         public Polygon get()
    608         {
    609             if(inner != null)
    610             {
    611                 for (Polygon pp : inner)
    612                 {
    613                     for(int i = 0; i < pp.npoints; ++i) {
    614                         poly.addPoint(pp.xpoints[i],pp.ypoints[i]);
    615                     }
    616                     poly.addPoint(p.x,p.y);
    617                 }
    618                 inner = null;
    619             }
    620             return poly;
    621         }
    622     }
    623     void addInnerToOuters(Relation r, boolean incomplete, PolyData pdInner, LinkedList<PolyData> outerPolygons)
    624     {
    625         Way wInner = pdInner.way;
    626         if(wInner != null && !wInner.isClosed())
    627         {
    628             Point pInner = nc.getPoint(wInner.getNode(0));
    629             pdInner.poly.addPoint(pInner.x,pInner.y);
    630         }
    631         PolyData o = null;
    632         for (PolyData pdOuter : outerPolygons)
    633         {
    634             int c = pdOuter.contains(pdInner.poly);
    635             if(c >= 1)
    636             {
    637                 if(c > 1 && pdOuter.way != null && pdOuter.way.isClosed())
    638                 {
    639                     putError(r, tr("Intersection between ways ''{0}'' and ''{1}''.",
    640                             pdOuter.way.getDisplayName(DefaultNameFormatter.getInstance()), wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
    641                 }
    642                 if(o == null || o.contains(pdOuter.poly) > 0) {
    643                     o = pdOuter;
    644                 }
    645             }
    646         }
    647         if(o == null)
    648         {
    649             if(!incomplete)
    650             {
    651                 putError(r, tr("Inner way ''{0}'' is outside.",
    652                         wInner.getDisplayName(DefaultNameFormatter.getInstance())), true);
    653             }
    654             o = outerPolygons.get(0);
    655         }
    656         o.addInner(pdInner.poly);
    657     }
    658 
    659461    public boolean drawMultipolygon(Relation r) {
    660         Collection<Way> inner = new LinkedList<Way>();
    661         Collection<Way> outer = new LinkedList<Way>();
    662         Collection<Way> innerclosed = new LinkedList<Way>();
    663         Collection<Way> outerclosed = new LinkedList<Way>();
    664         boolean incomplete = false;
    665462        boolean drawn = false;
    666463
    667         // Fill inner and outer list with valid ways
    668         for (RelationMember m : r.getMembers()) {
    669             if (m.getMember().isIncomplete()) {
    670                 incomplete = true;
    671             } else if(m.getMember().isDrawable()) {
    672                 if(m.isWay()) {
    673                     Way w = m.getWay();
    674                     if(w.getNodesCount() < 2) {
    675                         continue;
    676                     }
    677 
    678                     if("inner".equals(m.getRole())) {
    679                         inner.add(w);
    680                     } else if("outer".equals(m.getRole())) {
    681                         outer.add(w);
    682                     } else {
    683                         putError(r, tr("No useful role ''{0}'' for Way ''{1}''.",
    684                                 m.getRole(), w.getDisplayName(DefaultNameFormatter.getInstance())), true);
    685                         if(!m.hasRole()) {
    686                             outer.add(w);
    687                         } else if(data.isSelected(r)) {
    688                             // TODO Is this necessary?
    689                             drawSelectedMember(m.getMember(), styles != null
    690                                     ? getPrimitiveStyle(m.getMember()) : null, true, true);
    691                         }
    692                     }
    693                 }
    694                 else
    695                 {
    696                     putError(r, tr("Non-Way ''{0}'' in multipolygon.",
    697                             m.getMember().getDisplayName(DefaultNameFormatter.getInstance())), true);
    698                 }
    699             }
    700         }
     464        Multipolygon multipolygon = new Multipolygon(nc);
     465        multipolygon.load(r);
    701466
    702467        ElemStyle wayStyle = getPrimitiveStyle(r);
     
    704469        // If area style was not found for relation then use style of ways
    705470        if(styles != null && !(wayStyle instanceof AreaElemStyle)) {
    706             for (Way w : outer) {
     471            for (Way w : multipolygon.getOuterWays()) {
    707472                wayStyle = styles.getArea(w);
    708473                if(wayStyle != null) {
     
    716481            boolean zoomok = isZoomOk(wayStyle);
    717482            boolean visible = false;
    718             Collection<Way> outerjoin = new LinkedList<Way>();
    719             Collection<Way> innerjoin = new LinkedList<Way>();
    720483
    721484            drawn = true;
    722             for (Way w : outer)
    723             {
    724                 if(w.isClosed()) {
    725                     outerclosed.add(w);
    726                 } else {
    727                     outerjoin.add(w);
    728                 }
    729             }
    730             for (Way w : inner)
    731             {
    732                 if(w.isClosed()) {
    733                     innerclosed.add(w);
    734                 } else {
    735                     innerjoin.add(w);
    736                 }
    737             }
    738 
    739 
    740             if(outerclosed.size() == 0 && outerjoin.size() == 0)
    741             {
    742                 putError(r, tr("No outer way for multipolygon ''{0}''.",
    743                         r.getDisplayName(DefaultNameFormatter.getInstance())), true);
    744                 visible = true; /* prevent killing remaining ways */
    745             }
    746             else if(zoomok)
    747             {
    748                 LinkedList<PolyData> outerPoly = new LinkedList<PolyData>();
    749                 for (Way w : outerclosed) {
    750                     outerPoly.add(new PolyData(w));
    751                 }
    752                 outerPoly.addAll(joinWays(outerjoin, incomplete ? null : r));
    753                 for (Way wInner : innerclosed)
    754                 {
    755                     PolyData pdInner = new PolyData(wInner);
    756                     // incomplete is probably redundant
    757                     addInnerToOuters(r, incomplete, pdInner, outerPoly);
    758                 }
    759                 for (PolyData pdInner : joinWays(innerjoin, incomplete ? null : r)) {
    760                     addInnerToOuters(r, incomplete, pdInner, outerPoly);
    761                 }
     485
     486            if(zoomok && !multipolygon.getOuterWays().isEmpty()) {
    762487                AreaElemStyle areaStyle = (AreaElemStyle)wayStyle;
    763                 for (PolyData pd : outerPoly) {
     488                for (PolyData pd : multipolygon.getCombinedPolygons()) {
    764489                    Polygon p = pd.get();
    765490                    if(!isPolygonVisible(p)) {
     
    767492                    }
    768493
    769                     boolean selected = pd.selected || data.isSelected(pd.way) || data.isSelected(r);
     494                    boolean selected = pd.selected || data.isSelected(r);
    770495                    painter.drawArea(p, selected ? paintSettings.getSelectedColor() : areaStyle.color, null);
    771496                    visible = true;
     
    775500            if(!visible)
    776501                return drawn;
    777             for (Way wInner : inner)
     502            for (Way wInner : multipolygon.getInnerWays())
    778503            {
    779504                ElemStyle innerStyle = getPrimitiveStyle(wInner);
     
    783508                        continue;
    784509                    }
    785                     if(zoomok && (wInner.mappaintDrawnCode != paintid
    786                             || outer.size() == 0))
    787                     {
     510                    if(zoomok && (wInner.mappaintDrawnCode != paintid || multipolygon.getOuterWays().isEmpty())) {
    788511                        ((AreaElemStyle)wayStyle).getLineStyle().paintPrimitive(wInner, paintSettings, painter, (data.isSelected(wInner)
    789512                                || data.isSelected(r)));
     
    808531                }
    809532            }
    810             for (Way wOuter : outer)
     533            for (Way wOuter : multipolygon.getOuterWays())
    811534            {
    812535                ElemStyle outerStyle = getPrimitiveStyle(wOuter);
Note: See TracChangeset for help on using the changeset viewer.