Ignore:
Timestamp:
2014-05-03T01:07:19+02:00 (10 years ago)
Author:
bastiK
Message:

mapcss: major performance improvement for style creation, "rendering phase 1" (see #9691)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java

    r7033 r7054  
    1919import org.openstreetmap.josm.data.osm.Node;
    2020import org.openstreetmap.josm.data.osm.OsmPrimitive;
     21import org.openstreetmap.josm.data.osm.Relation;
     22import org.openstreetmap.josm.data.osm.Way;
    2123import org.openstreetmap.josm.gui.mappaint.Cascade;
    2224import org.openstreetmap.josm.gui.mappaint.Environment;
     
    2426import org.openstreetmap.josm.gui.mappaint.Range;
    2527import org.openstreetmap.josm.gui.mappaint.StyleSource;
     28import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector;
    2629import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector;
     30import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.OptimizedGeneralSelector;
    2731import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
    2832import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
     
    4246    public static final String MAPCSS_STYLE_MIME_TYPES = "text/x-mapcss, text/mapcss, text/css; q=0.9, text/plain; q=0.8, application/zip, application/octet-stream; q=0.5";
    4347
    44     public final List<MapCSSRule> rules;
     48    // all rules
     49    public final List<MapCSSRule> rules = new ArrayList<>();
     50    // rules filtered by primitive type
     51    public final List<MapCSSRule> nodeRules = new ArrayList<>();
     52    public final List<MapCSSRule> wayRules = new ArrayList<>();
     53    public final List<MapCSSRule> relationRules = new ArrayList<>();
     54    public final List<MapCSSRule> multipolygonRules = new ArrayList<>();
     55   
    4556    private Color backgroundColorOverride;
    4657    private String css = null;
     
    4960    public MapCSSStyleSource(String url, String name, String shortdescription) {
    5061        super(url, name, shortdescription);
    51         rules = new ArrayList<>();
    5262    }
    5363
    5464    public MapCSSStyleSource(SourceEntry entry) {
    5565        super(entry);
    56         rules = new ArrayList<>();
    5766    }
    5867
     
    6877        CheckParameterUtil.ensureParameterNotNull(css);
    6978        this.css = css;
    70         rules = new ArrayList<>();
    7179    }
    7280
     
    7583        init();
    7684        rules.clear();
     85        nodeRules.clear();
     86        wayRules.clear();
     87        relationRules.clear();
     88        multipolygonRules.clear();
    7789        try (InputStream in = getSourceInputStream()) {
    7890            try {
     
    104116            logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
    105117        }
    106     }
    107 
     118        // optimization: filter rules for different primitive types
     119        for (MapCSSRule r: rules) {
     120            List<Selector> nodeSel = new ArrayList<>();
     121            List<Selector> waySel = new ArrayList<>();
     122            List<Selector> relationSel = new ArrayList<>();
     123            List<Selector> multipolygonSel = new ArrayList<>();
     124            for (Selector sel : r.selectors) {
     125                // find the rightmost selector, this must be a GeneralSelector
     126                Selector selRightmost = sel;
     127                while (selRightmost instanceof ChildOrParentSelector) {
     128                    selRightmost = ((ChildOrParentSelector) selRightmost).right;
     129                }
     130                Selector optimizedSel = sel.optimizedBaseCheck();
     131                switch (((GeneralSelector) selRightmost).getBase()) {
     132                    case "node":
     133                        nodeSel.add(optimizedSel);
     134                        break;
     135                    case "way":
     136                        waySel.add(optimizedSel);
     137                        break;
     138                    case "area":
     139                        waySel.add(optimizedSel);
     140                        multipolygonSel.add(optimizedSel);
     141                        break;
     142                    case "relation":
     143                        relationSel.add(optimizedSel);
     144                        multipolygonSel.add(optimizedSel);
     145                        break;
     146                    case "*":
     147                        nodeSel.add(optimizedSel);
     148                        waySel.add(optimizedSel);
     149                        relationSel.add(optimizedSel);
     150                        multipolygonSel.add(optimizedSel);
     151                        break;
     152                }
     153            }
     154            nodeRules.add(new MapCSSRule(nodeSel, r.declaration));
     155            wayRules.add(new MapCSSRule(waySel, r.declaration));
     156            relationRules.add(new MapCSSRule(relationSel, r.declaration));
     157            multipolygonRules.add(new MapCSSRule(multipolygonSel, r.declaration));
     158        }
     159        rules.clear();
     160    }
     161   
    108162    @Override
    109163    public InputStream getSourceInputStream() throws IOException {
     
    188242    public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
    189243        Environment env = new Environment(osm, mc, null, this);
    190         RULE: for (MapCSSRule r : rules) {
     244        List<MapCSSRule> matchingRules;
     245        if (osm instanceof Node) {
     246            matchingRules = nodeRules;
     247        } else if (osm instanceof Way) {
     248            matchingRules = wayRules;
     249        } else {
     250            if (((Relation) osm).isMultipolygon()) {
     251                matchingRules = multipolygonRules;
     252            } else {
     253                matchingRules = relationRules;
     254            }
     255        }
     256        RULE: for (MapCSSRule r : matchingRules) {
    191257            for (Selector s : r.selectors) {
    192258                env.clearSelectorMatchingInformation();
Note: See TracChangeset for help on using the changeset viewer.