From 62d4b19b5650eaaf6674c3c70fb50980ca138b07 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 2 Nov 2011 08:39:46 +0100 Subject: [PATCH] Fix crash preferences/implement depends rendering style --- .../osmand/render/RenderingRuleProperty.java | 4 +- .../render/RenderingRuleSearchRequest.java | 13 +- .../RenderingRuleStorageProperties.java | 34 ++-- .../osmand/render/RenderingRulesStorage.java | 162 ++++++++++++------ ..._default.render.xml => default.render.xml} | 0 .../net/osmand/render/test_depends.render.xml | 8 + .../plus/activities/SettingsActivity.java | 11 +- .../osmand/plus/render/RendererRegistry.java | 33 ++-- 8 files changed, 167 insertions(+), 98 deletions(-) rename DataExtractionOSM/src/net/osmand/render/{new_default.render.xml => default.render.xml} (100%) create mode 100644 DataExtractionOSM/src/net/osmand/render/test_depends.render.xml diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java b/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java index 66be67c037..f90abed754 100644 --- a/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRuleProperty.java @@ -247,11 +247,11 @@ public class RenderingRuleProperty { // Set the alpha value color |= 0x00000000ff000000; } else if (colorString.length() != 9) { - throw new IllegalArgumentException("Unknown color" + colorString); //$NON-NLS-1$ + throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$ } return (int)color; } - throw new IllegalArgumentException("Unknown color" + colorString); //$NON-NLS-1$ + throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$ } public static String colorToString(int color) { diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRuleSearchRequest.java b/DataExtractionOSM/src/net/osmand/render/RenderingRuleSearchRequest.java index 3c3c2628cd..dccd446b84 100644 --- a/DataExtractionOSM/src/net/osmand/render/RenderingRuleSearchRequest.java +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRuleSearchRequest.java @@ -4,7 +4,6 @@ package net.osmand.render; public class RenderingRuleSearchRequest { private final RenderingRulesStorage storage; - private final RenderingRuleSearchRequest dependsRequest; RenderingRuleProperty[] props; int[] values; float[] fvalues; @@ -20,11 +19,6 @@ public class RenderingRuleSearchRequest { public RenderingRuleSearchRequest(RenderingRulesStorage storage) { this.storage = storage; this.ALL = storage.PROPS; - if(storage.getDependsStorage() != null){ - dependsRequest = new RenderingRuleSearchRequest(storage.getDependsStorage()); - } else { - dependsRequest = null; - } props = storage.PROPS.getPoperties(); values = new int[props.length]; for (int i = 0; i < props.length; i++) { @@ -114,12 +108,7 @@ public class RenderingRuleSearchRequest { searchResult = true; return true; } - - if(dependsRequest != null){ - // TODO search depends ? - // and copy results to local array - // dependsRequest.search(state); - } + return false; } diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRuleStorageProperties.java b/DataExtractionOSM/src/net/osmand/render/RenderingRuleStorageProperties.java index 33bcbfe2c4..2422e89982 100644 --- a/DataExtractionOSM/src/net/osmand/render/RenderingRuleStorageProperties.java +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRuleStorageProperties.java @@ -83,12 +83,22 @@ public class RenderingRuleStorageProperties { public RenderingRuleProperty R_TEXT_HALO_RADIUS; public RenderingRuleProperty R_TEXT_WRAP_WIDTH; - final Map properties = new LinkedHashMap(); + final Map properties; // C++ - final List rules = new ArrayList(); - final List customRules = new ArrayList(); + final List rules ; + final List customRules ; public RenderingRuleStorageProperties() { + properties = new LinkedHashMap(); + rules = new ArrayList(); + customRules = new ArrayList(); + createDefaultRenderingRuleProperties(); + } + + public RenderingRuleStorageProperties(RenderingRuleStorageProperties toClone) { + properties = new LinkedHashMap(toClone.properties); + rules = new ArrayList(toClone.rules); + customRules = new ArrayList(toClone.customRules); createDefaultRenderingRuleProperties(); } @@ -158,15 +168,19 @@ public class RenderingRuleStorageProperties { } private RenderingRuleProperty registerRuleInternal(RenderingRuleProperty p) { - properties.put(p.getAttrName(), p); - p.setId(rules.size()); - rules.add(p); - return p; + if(get(p.getAttrName()) == null) { + properties.put(p.getAttrName(), p); + p.setId(rules.size()); + rules.add(p); + } + return get(p.getAttrName()); } public RenderingRuleProperty registerRule(RenderingRuleProperty p) { - registerRuleInternal(p); - customRules.add(p); - return p; + RenderingRuleProperty ps = registerRuleInternal(p); + if(!customRules.contains(ps)) { + customRules.add(p); + } + return ps; } } diff --git a/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java b/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java index 878e5fc81c..3e5bd4d153 100644 --- a/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java +++ b/DataExtractionOSM/src/net/osmand/render/RenderingRulesStorage.java @@ -4,10 +4,8 @@ import gnu.trove.map.hash.TIntObjectHashMap; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -43,7 +41,7 @@ public class RenderingRulesStorage { List dictionary = new ArrayList(); Map dictionaryMap = new LinkedHashMap(); - public final RenderingRuleStorageProperties PROPS = new RenderingRuleStorageProperties(); + public RenderingRuleStorageProperties PROPS = new RenderingRuleStorageProperties(); @SuppressWarnings("unchecked") protected TIntObjectHashMap[] tagValueGlobalRules = new TIntObjectHashMap[LENGTH_RULES]; @@ -51,15 +49,20 @@ public class RenderingRulesStorage { private int bgColor = 0; private int bgNightColor = 0; private String renderingName; - private String depends; - private RenderingRulesStorage dependsStorage; + public static interface RenderingRulesStorageResolver { + + RenderingRulesStorage resolve(String name, RenderingRulesStorageResolver ref) throws SAXException; + } + public RenderingRulesStorage(){ // register empty string as 0 getDictionaryValue(""); } + + public int getDictionaryValue(String val) { if(dictionaryMap.containsKey(val)){ return dictionaryMap.get(val); @@ -92,23 +95,41 @@ public class RenderingRulesStorage { return nightMode ? bgNightColor : bgColor; } - public String getDepends() { - return depends; - } - public RenderingRulesStorage getDependsStorage() { - return dependsStorage; - } - - public void setDependsStorage(RenderingRulesStorage dependsStorage) { - this.dependsStorage = dependsStorage; - } - - - public void parseRulesFromXmlInputStream(InputStream is) throws SAXException, IOException { + public void parseRulesFromXmlInputStream(InputStream is, RenderingRulesStorageResolver resolver) throws SAXException, IOException { try { final SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); - saxParser.parse(is, new RenderingRulesHandler(saxParser)); + RenderingRulesHandler handler = new RenderingRulesHandler(saxParser, resolver); + saxParser.parse(is, handler); + RenderingRulesStorage depends = handler.getDependsStorage(); + if (depends != null) { + // merge results + // dictionary,bgNightColor and props are already merged + + for(int i=0; i attrsMap) throws SAXException { int tag = rr.getIntPropertyValue(RenderingRuleStorageProperties.TAG); if(tag == -1){ @@ -137,19 +157,26 @@ public class RenderingRulesStorage { RenderingRule previous = tagValueGlobalRules[state].get(key); if(previous != null){ // all root rules should have at least tag/value - if(previous.getProperties().length > 2){ - Map m = new HashMap(); - m.put("tag", dictionary.get(tag)); - m.put("value", dictionary.get(value)); - toInsert = new RenderingRule(m, RenderingRulesStorage.this); - toInsert.addIfElseChildren(previous); - } else { - toInsert = previous; - } + toInsert = createRootWrapperRule(key, previous); toInsert.addIfElseChildren(rr); } tagValueGlobalRules[state].put(key, toInsert); } + + + + private RenderingRule createRootWrapperRule(int tagValueKey, RenderingRule previous) { + if (previous.getProperties().length > 2) { + Map m = new HashMap(); + m.put("tag", getTagString(tagValueKey)); + m.put("value", getValueString(tagValueKey)); + RenderingRule toInsert = new RenderingRule(m, RenderingRulesStorage.this); + toInsert.addIfElseChildren(previous); + return toInsert; + } else { + return previous; + } + } private class GroupRules { Map groupAttributes = new LinkedHashMap(); @@ -183,10 +210,17 @@ public class RenderingRulesStorage { Stack stack = new Stack(); Map attrsMap = new LinkedHashMap(); + private final RenderingRulesStorageResolver resolver; + private RenderingRulesStorage dependsStorage; - public RenderingRulesHandler(SAXParser parser){ + public RenderingRulesHandler(SAXParser parser, RenderingRulesStorageResolver resolver){ this.parser = parser; + this.resolver = resolver; + } + + public RenderingRulesStorage getDependsStorage() { + return dependsStorage; } @Override @@ -267,6 +301,19 @@ public class RenderingRulesStorage { } PROPS.registerRule(prop); } else if("renderingStyle".equals(name)){ //$NON-NLS-1$ + String depends = attributes.getValue("depends"); + if(depends != null && depends.length()> 0){ + this.dependsStorage = resolver.resolve(depends, resolver); + } + if(dependsStorage != null){ + bgColor = dependsStorage.bgColor; + bgNightColor = dependsStorage.bgNightColor; + // copy dictionary + dictionary = new ArrayList(dependsStorage.dictionary); + dictionaryMap = new LinkedHashMap(dependsStorage.dictionaryMap); + PROPS = new RenderingRuleStorageProperties(dependsStorage.PROPS); + + } String dc = attributes.getValue("defaultColor"); int defaultColor = 0; if(dc != null && dc.length() > 0){ @@ -278,7 +325,7 @@ public class RenderingRulesStorage { bgNightColor = RenderingRuleProperty.parseColor(dnc); } renderingName = attributes.getValue("name"); - depends = attributes.getValue("depends"); + } else if("renderer".equals(name)){ //$NON-NLS-1$ throw new SAXException("Rendering style is deprecated and no longer supported."); } else { @@ -372,38 +419,47 @@ public class RenderingRulesStorage { for(RenderingRule rc : rr.getIfElseChildren()){ printRenderingRule(indent, rc, out); } - } public static void main(String[] args) throws SAXException, IOException { RenderingRulesStorage storage = new RenderingRulesStorage(); - storage.parseRulesFromXmlInputStream(RenderingRulesStorage.class.getResourceAsStream("new_default.render.xml")); -// storage.printDebug(LINE_RULES, System.out); - long tm = System.nanoTime(); - int count = 100000; - for (int i = 0; i < count; i++) { + final RenderingRulesStorageResolver resolver = new RenderingRulesStorageResolver() { + @Override + public RenderingRulesStorage resolve(String name, RenderingRulesStorageResolver ref) throws SAXException { + RenderingRulesStorage depends = new RenderingRulesStorage(); + try { + depends.parseRulesFromXmlInputStream(RenderingRulesStorage.class.getResourceAsStream(name+".render.xml"), + ref); + } catch (IOException e) { + throw new SAXException(e); + } + return depends; + } + }; + storage.parseRulesFromXmlInputStream(RenderingRulesStorage.class.getResourceAsStream("test_depends.render.xml"), + resolver); +// storage.printDebug(ORDER_RULES, System.out); +// long tm = System.nanoTime(); +// int count = 100000; +// for (int i = 0; i < count; i++) { RenderingRuleSearchRequest searchRequest = new RenderingRuleSearchRequest(storage); searchRequest.setStringFilter(storage.PROPS.R_TAG, "highway"); searchRequest.setStringFilter(storage.PROPS.R_VALUE, "motorway"); - // searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1); - searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 14); - searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 14); - // searchRequest.setStringFilter(storage.PROPS.R_ORDER_TYPE, "line"); - // searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true); + searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1); + searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 15); + searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 15); + searchRequest.setIntFilter(storage.PROPS.R_ORDER_TYPE, 2); + // searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true); // searchRequest.setBooleanFilter(storage.PROPS.get("hmRendered"), true); - - searchRequest.search(ORDER_RULES); - printResult(searchRequest, new PrintStream(new OutputStream() { - @Override - public void write(int b) throws IOException { - - } - })); - } - System.out.println((System.nanoTime()- tm)/ (1e6f * count) ); + + boolean res = searchRequest.search(LINE_RULES); + System.out.println("Result " + res); + printResult(searchRequest, System.out); +// } +// System.out.println((System.nanoTime()- tm)/ (1e6f * count) ); } - + private static void printResult(RenderingRuleSearchRequest searchRequest, PrintStream out) { if(searchRequest.isFound()){ out.print(" Found : "); diff --git a/DataExtractionOSM/src/net/osmand/render/new_default.render.xml b/DataExtractionOSM/src/net/osmand/render/default.render.xml similarity index 100% rename from DataExtractionOSM/src/net/osmand/render/new_default.render.xml rename to DataExtractionOSM/src/net/osmand/render/default.render.xml diff --git a/DataExtractionOSM/src/net/osmand/render/test_depends.render.xml b/DataExtractionOSM/src/net/osmand/render/test_depends.render.xml new file mode 100644 index 0000000000..6dedb6ab0d --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/render/test_depends.render.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java index 287eb4f238..c3e61782d0 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java @@ -23,7 +23,6 @@ import net.osmand.plus.ProgressDialogImplementation; import net.osmand.plus.R; import net.osmand.plus.ResourceManager; import net.osmand.plus.render.MapRenderRepositories; -import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.views.SeekBarPreference; import net.osmand.render.RenderingRuleProperty; @@ -289,7 +288,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference entries = (String[]) rendererNames.toArray(new String[rendererNames.size()]); registerListPreference(osmandSettings.RENDERER, screen, entries, entries); - createCustomRenderingProperties(); + createCustomRenderingProperties(false); tileSourcePreference = (ListPreference) screen.findPreference(osmandSettings.MAP_TILE_SOURCES.getId()); tileSourcePreference.setOnPreferenceChangeListener(this); @@ -342,7 +341,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } } - private void createCustomRenderingProperties() { + private void createCustomRenderingProperties(boolean update) { RenderingRulesStorage renderer = getMyApplication().getRendererRegistry().getCurrentSelectedRenderer(); PreferenceCategory cat = (PreferenceCategory) findPreference("custom_vector_rendering"); cat.removeAll(); @@ -356,7 +355,6 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference lp.setSummary(p.getDescription()); cat.addPreference(lp); - LinkedHashMap vals = new LinkedHashMap(); screenPreferences.put(custom.getId(), lp); listPreferences.put(custom.getId(), custom); @@ -367,6 +365,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } } + if(update) { + updateAllSettings(); + } } } @@ -553,7 +554,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } else { Toast.makeText(this, R.string.renderer_load_exception, Toast.LENGTH_SHORT).show(); } - createCustomRenderingProperties(); + createCustomRenderingProperties(true); } } else if(preference == applicationDir){ warnAboutChangingStorage((String) newValue); diff --git a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java index 859e1994bb..07d24ee3fa 100644 --- a/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java +++ b/OsmAnd/src/net/osmand/plus/render/RendererRegistry.java @@ -10,9 +10,9 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; -import net.osmand.Algoritms; import net.osmand.LogUtil; import net.osmand.render.RenderingRulesStorage; +import net.osmand.render.RenderingRulesStorage.RenderingRulesStorageResolver; import org.apache.commons.logging.Log; import org.xml.sax.SAXException; @@ -33,7 +33,7 @@ public class RendererRegistry { private Map renderers = new LinkedHashMap(); public RendererRegistry(){ - internalRenderers.put(DEFAULT_RENDER, "new_default.render.xml"); + internalRenderers.put(DEFAULT_RENDER, "default.render.xml"); } public RenderingRulesStorage defaultRender() { @@ -59,7 +59,7 @@ public class RendererRegistry { private RenderingRulesStorage getRenderer(String name, Set loadedRenderers) { try { - return loadRenderer(name); + return loadRenderer(name, loadedRenderers); } catch (IOException e) { log.error("Error loading renderer", e); //$NON-NLS-1$ } catch (SAXException e) { @@ -68,11 +68,7 @@ public class RendererRegistry { return null; } - public RenderingRulesStorage loadRenderer(String name) throws IOException, SAXException { - return loadRenderer(name, new LinkedHashSet()); - } - - private RenderingRulesStorage loadRenderer(String name, Set loadedRenderers) throws IOException, SAXException { + private RenderingRulesStorage loadRenderer(String name, final Set loadedRenderers) throws IOException, SAXException { InputStream is = null; if(externalRenderers.containsKey(name)){ is = new FileInputStream(externalRenderers.get(name)); @@ -82,19 +78,24 @@ public class RendererRegistry { throw new IllegalArgumentException("Not found " + name); //$NON-NLS-1$ } RenderingRulesStorage main = new RenderingRulesStorage(); - main.parseRulesFromXmlInputStream(is); loadedRenderers.add(name); - if(!Algoritms.isEmpty(main.getDepends())){ - if (loadedRenderers.contains(main.getDepends())) { - log.warn("Circular dependencies found " + name); //$NON-NLS-1$ - } else { - RenderingRulesStorage dep = getRenderer(main.getDepends(), loadedRenderers); + main.parseRulesFromXmlInputStream(is, new RenderingRulesStorageResolver() { + + @Override + public RenderingRulesStorage resolve(String name, RenderingRulesStorageResolver ref) throws SAXException { + if(renderers.containsKey(name)){ + return renderers.get(name); + } + if (loadedRenderers.contains(name)) { + log.warn("Circular dependencies found " + name); //$NON-NLS-1$ + } + RenderingRulesStorage dep = getRenderer(name, loadedRenderers); if (dep == null) { log.warn("Dependent renderer not found : " + name); //$NON-NLS-1$ } - main.setDependsStorage(dep); + return null; } - } + }); renderers.put(name, main); return main; }