/******************************************************************************* * Copyright (c) 2010 Stefan A. Tzeggai. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Stefan A. Tzeggai - initial API and implementation ******************************************************************************/ package org.geopublishing.atlasStyler.rulesLists; import java.awt.Color; import java.awt.Component; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; import org.apache.log4j.Logger; import org.geopublishing.atlasStyler.ASUtil; import org.geopublishing.atlasStyler.AtlasStyler; import org.geopublishing.atlasStyler.AtlasStyler.LANGUAGE_MODE; import org.geopublishing.atlasStyler.AtlasStylerVector; import org.geopublishing.atlasStyler.RuleChangedEvent; import org.geotools.filter.AndImpl; import org.geotools.filter.BinaryComparisonAbstract; import org.geotools.styling.FeatureTypeStyle; import org.geotools.styling.Font; import org.geotools.styling.LabelPlacement; import org.geotools.styling.PointPlacement; import org.geotools.styling.Rule; import org.geotools.styling.TextSymbolizer; import org.geotools.styling.visitor.DuplicatingStyleVisitor; import org.opengis.filter.Filter; import org.opengis.filter.PropertyIsEqualTo; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Function; import org.opengis.filter.expression.PropertyName; import de.schmitzm.geotools.FilterUtil; import de.schmitzm.geotools.GTUtil; import de.schmitzm.geotools.feature.FeatureUtil; import de.schmitzm.geotools.feature.FeatureUtil.GeometryForm; import de.schmitzm.geotools.gui.XMapPane; import de.schmitzm.geotools.styling.StyledFeaturesInterface; import de.schmitzm.geotools.styling.StylingUtil; import de.schmitzm.i18n.Translation; public class TextRuleList extends AbstractRulesList { /** All default text rule names start with this **/ public static final String DEFAULT_CLASS_RULENAME = "DEFAULT"; public static final Filter DEFAULT_FILTER_ALL_OTHERS = FilterUtil.ALLWAYS_TRUE_FILTER; final static protected Logger LOGGER = Logger.getLogger(TextRuleList.class); /** * A Filter to mark that not ALL classes have been disabled by the * {@link TextRuleList}{@link #setEnabled(boolean)} method. This filter is * not used anymore and only for backward compatibility. Will be removed in * 2.0 **/ public static final PropertyIsEqualTo oldClassesDisabledFilter = RulesListInterface.oldAllClassesDisabledFilter; /** * A Filter to mark that not ALL classes have been disabled by the * {@link TextRuleList}{@link #setEnabled(boolean)} method. This filter is * not used anymore and only for backward compatibility. Will be removed in * 2.0 **/ public static final PropertyIsEqualTo oldClassesEnabledFilter = RulesListInterface.OldAllClassesEnabledFilter; /** * A piece of {@link Filter} that is only true, if the rendering language is * set to the given language. @see XMapPane#setRenderLanguage * * @param lang * if <code>null</code>, the rule will be true when no specific * rendering language has been set. */ public static Filter classLanguageFilter(String lang) { if (lang == null) lang = XMapPane.ENV_LANG_DEFAULT; // set argument to set a default return value of 0 Expression exEnv = ff.function("env", ff.literal(XMapPane.ENV_LANG), ff.literal(XMapPane.ENV_LANG_DEFAULT)); Filter filter = ff.equals(ff.literal(lang), exEnv); return filter; } /** Stores whether the class specific {@link TextSymbolizer}s are enabled **/ private final List<Boolean> classesEnabled = new ArrayList<Boolean>(); /** Stores all {@link Filter}s for all classes **/ private final List<Filter> classesFilters = new ArrayList<Filter>(); /** * Stores whether the class is only valid for a special language. If * <code>null</code>, a class is not language-specific **/ private final List<String> classesLanguages = new ArrayList<String>(); /** Stores all maxScale parameters for the classes **/ List<Double> classesMaxScales = new ArrayList<Double>(); /** Stores all minScale parameters for all classes **/ List<Double> classesMinScales = new ArrayList<Double>(); private List<String> classesRuleNames = new ArrayList<String>(); /** Stores all {@link TextSymbolizer}s for all classes **/ List<TextSymbolizer> classesSymbolizers = new ArrayList<TextSymbolizer>(); /** * @deprecated move the selIdx out of this class */ @Deprecated private int selIdx = 0; final private StyledFeaturesInterface<?> styledFeatures; public TextRuleList(StyledFeaturesInterface<?> styledFeatures, boolean withDefaults) { super(RulesListType.TEXT_LABEL, GeometryForm.ANY); this.styledFeatures = styledFeatures; if (withDefaults) addDefaultClass(); } public TextRuleList(StyledFeaturesInterface<?> styledFeatures, GeometryForm geometryForm, boolean withDefaults) { super(RulesListType.TEXT_LABEL, geometryForm); this.styledFeatures = styledFeatures; } /** * * @param ts * @param ruleName * @param filter * @param enabled * @param lang * @param minScale * <code>null</code> allowed will fall-back to 0. * @param maxScale * <code>null</code> allowed will fall-back to Double.MAX_VALUE * @return the index of the newly added class */ public int addClass(TextSymbolizer ts, String ruleName, Filter filter, boolean enabled, String lang, Double minScale, Double maxScale) { int index = classesSymbolizers.size(); pushQuite(); try { setClassSymbolizer(index, ts); setClassRuleName(index, ruleName); setClassFilter(index, filter); setClassEnabled(index, enabled); setClassLang(index, lang); setClassMinMaxScales(index, minScale, maxScale); setSelIdx(index); return index; } finally { popQuite(new RuleChangedEvent("Added a new class with position " + index + " and ruleName " + ruleName, this)); } } /** * Adds filters that indicate whether this class or all classes are * disabled. Is added as the last filters so they are easily identified. * * @param idx * the index of the label class (0=default) * * @return modified filter * * @see #parseAndRemoveEnabledDisabledFilters(Filter, int) */ protected Filter addClassEnabledDisabledFilters(Filter filter, int idx) { filter = addLanguageFilter(filter, idx); // Is this class enabled? if (isClassEnabled(idx)) { filter = ff.and(StylingUtil.LABEL_CLASS_ENABLED_FILTER, filter); } else { filter = ff.and(StylingUtil.LABEL_CLASS_DISABLED_FILTER, filter); } return filter; } /** * @return the index of the newly added class */ public int addDefaultClass() { return addDefaultClass(null); } /** * @return the index of the newly added class */ public int addDefaultClass(String lang) { TextSymbolizer defaultTextSymbolizer = createDefaultTextSymbolizer(); pushQuite(); try { if (existsClass(DEFAULT_FILTER_ALL_OTHERS, lang)) { LOGGER.debug("Not adding a default class for " + lang + " because an equal class already exits!"); return -1; } String ruleName = DEFAULT_CLASS_RULENAME; if (lang != null) ruleName += "_" + lang; return addClass(defaultTextSymbolizer, ruleName, DEFAULT_FILTER_ALL_OTHERS, true, lang, null, null); } finally { popQuite(new RuleChangedEvent("Added a default TextSymbolizer", this)); } } private Filter addLanguageFilter(Filter filter, int idx) { // Is this class language specific? if (getClassLang(idx) != null) { filter = ff.and(classLanguageFilter(classesLanguages.get(idx)), filter); } else { } return filter; } /** * @return the number of text classes defined. */ public int countClasses() { return classesFilters.size(); } private TextSymbolizer createDefaultTextSymbolizer() { // If we already have a default symbolizer, we will return a duplication // of it. if (getSymbolizers().size() > 0) { DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor( StylingUtil.STYLE_FACTORY); duplicatingStyleVisitor.visit(getClassSymbolizer(0)); return (TextSymbolizer) duplicatingStyleVisitor.getCopy(); } // final String[] fonts = g.getAvailableFontFamilyNames(); // TODO Use the default classes font if available?? // TODO better default font!! with multiple families Font sldFont = ASUtil.SB .createFont("Times New Roman", false, false, 11); List<String> valueFieldNamesPrefereStrings = FeatureUtil .getValueFieldNamesPrefereStrings(getStyledFeatures() .getSchema(), false); TextSymbolizer ts = ASUtil.SB.createTextSymbolizer(); if (valueFieldNamesPrefereStrings.size() != 0) { ts.setLabel(FeatureUtil.FILTER_FACTORY2 .property(valueFieldNamesPrefereStrings.get(0))); } ts.setFill(StylingUtil.STYLE_BUILDER.createFill(Color.black)); // TODO better default font!! with multiple families ts.setFont(sldFont); // For Polygons we set the PointPlacement option X to 50% // by default if (FeatureUtil.getGeometryForm(getStyledFeatures().getSchema()) == GeometryForm.POLYGON) { LabelPlacement labelPlacement = ts.getLabelPlacement(); if (labelPlacement instanceof PointPlacement) { PointPlacement pointPlacement = (PointPlacement) labelPlacement; pointPlacement.getAnchorPoint().setAnchorPointX( FeatureUtil.FILTER_FACTORY2.literal(".5")); } } return ts; } /** * @return <code>true</code> if another class with the same filter and name * already exists. */ public boolean existsClass(Filter filter, String lang) { for (int i = 0; i < countClasses(); i++) { if (getClassLang(i) == null && lang != null) continue; if (getClassLang(i) != null && !getClassLang(i).equals(lang)) continue; if (filter != null && getClassFilter(i).toString().equals(filter.toString())) return true; } return false; } private List<Filter> getClassesFilters() { return classesFilters; } public Filter getClassFilter(int index) { if (index > classesFilters.size() - 1) return null; return classesFilters.get(index); } public String getClassLang(int index) { if (index > classesLanguages.size() - 1) return null; return classesLanguages.get(index); } public TextSymbolizer getClassSymbolizer(int index) { if (index > classesSymbolizers.size() - 1) return null; return classesSymbolizers.get(index); } /** * A list of languages that a default class has already been defined for * * @return */ public ArrayList<String> getDefaultLanguages() { ArrayList<String> usedLangs = new ArrayList<String>(); if (AtlasStyler.getLanguageMode() == LANGUAGE_MODE.OGC_SINGLELANGUAGE) return usedLangs; for (String lang : AtlasStyler.getLanguages()) { if (existsClass(DEFAULT_FILTER_ALL_OTHERS, lang)) { usedLangs.add(lang); } } return usedLangs; } /** * @deprecated move the selIdx out of this class */ @Deprecated public String getRuleName() { return classesRuleNames.get(selIdx); } public String getRuleName(int index) { if (index > classesRuleNames.size() - 1) return null; return classesRuleNames.get(index); } public List<String> getRuleNames() { return classesRuleNames; } @Override public List<Rule> getRules() { // LOGGER.debug("Enabled Textrule = " + isEnabled()); ArrayList<Rule> rules = new ArrayList<Rule>(); for (int i = 0; i < classesSymbolizers.size(); i++) { TextSymbolizer tSymbolizer = classesSymbolizers.get(i); // The filter stored for this class. This filer already contains the // exclusion of NODATA values. Filter filter = classesFilters.get(i); // if (i == 0 || filter.equals(FILTER_DEFAULT_ALL_OTHERS_ID)) { if (getRuleName(i).startsWith(DEFAULT_CLASS_RULENAME)) { // The default symbolizer get's a special filter= not (2ndFilter // OR 3rdFilter OR 4thFilter) if other rules are defined. if (getRuleNames().size() > 1) { List<Filter> ors = new ArrayList<Filter>(); for (int j = 0; j < getRuleNames().size(); j++) { // Default Filter otherFilter = getClassFilter(j); if (j == i || j == 0) continue; ors.add(addLanguageFilter(otherFilter, j)); } if (ors.size() > 0) { filter = ASUtil.ff2.not(FilterUtil .correctOrForValidation(ASUtil.ff2.or(ors))); } } else { // The default filter includes all, IF no other rules have // been defined. filter = DEFAULT_FILTER_ALL_OTHERS; } } Rule rule = ASUtil.SB.createRule(tSymbolizer); rule.setName(getRuleNames().get(i)); rule.setMinScaleDenominator(classesMinScales.get(i)); rule.setMaxScaleDenominator(classesMaxScales.get(i)); // If there is a second label attribute, make a second Rule that // only displays the first label in case that the second is null final PropertyName firstPropertyName = StylingUtil .getFirstPropertyName(styledFeatures.getSchema(), tSymbolizer); final PropertyName secondPropertyName = StylingUtil .getSecondPropertyName(styledFeatures.getSchema(), tSymbolizer); if (secondPropertyName != null) { // Attention: This structure is also in AtlasStyler.import Filter secondLabelNodataFilter = ff.isNull(secondPropertyName); for (Object nodata : getStyledFeatures() .getAttributeMetaDataMap() .get(secondPropertyName.getPropertyName()) .getNodataValues()) { secondLabelNodataFilter = ff.or( ff.equals(secondPropertyName, ff.literal(nodata)), secondLabelNodataFilter); } Filter secondNotEmpty = ASUtil.ff2.not(secondLabelNodataFilter); filter = ASUtil.ff.and(secondNotEmpty, filter); filter = addClassEnabledDisabledFilters(filter, i); filter = addAbstractRlSettings(filter); rule.setFilter(filter); rules.add(rule); // Not the fallbackrule in case that the second attribute IS // empty. DuplicatingStyleVisitor duplicatingRuleVisitor = new DuplicatingStyleVisitor(); duplicatingRuleVisitor.visit(rule); Rule fallbackRule = (Rule) duplicatingRuleVisitor.getCopy(); fallbackRule.setName(RULENAME_DONTIMPORT); filter = ASUtil.ff.and(secondLabelNodataFilter, filter); filter = addClassEnabledDisabledFilters(filter, i); filter = addAbstractRlSettings(filter); fallbackRule.setFilter(filter); final TextSymbolizer ts2 = (TextSymbolizer) fallbackRule .symbolizers().get(0); StylingUtil.setDoublePropertyName(ts2, firstPropertyName, null); rules.add(fallbackRule); } else { // No second labeling property set filter = addClassEnabledDisabledFilters(filter, i); filter = addAbstractRlSettings(filter); rule.setFilter(filter); rules.add(rule); } } return rules; } /** * @deprecated move the selIdx out of this class */ @Deprecated public int getSelIdx() { return selIdx; } public StyledFeaturesInterface<?> getStyledFeatures() { return styledFeatures; } /** * @return the {@link TextSymbolizer} selected in the combo box * @see #getSelIdx() * @deprecated move the selIdx out of this class */ @Deprecated public TextSymbolizer getSymbolizer() { return getClassSymbolizer(selIdx); } public List<TextSymbolizer> getSymbolizers() { return classesSymbolizers; } // /** // * Are all {@link TextSymbolizer} classes disabled/enabled. // */ // public boolean isEnabled() { // return enabled; // } /** * @return <code>true</code> is at least one DEFAULT rule exists. */ public boolean hasDefault() { for (String s : getRuleNames()) { if (s != null && s.startsWith(DEFAULT_CLASS_RULENAME)) return true; } return false; } public void importClassesFromStyle(RulesListInterface symbRL, Component owner) { pushQuite(); try { if (symbRL instanceof UniqueValuesRuleList) { UniqueValuesRuleList uniqueRL = (UniqueValuesRuleList) symbRL; if (uniqueRL.getNumClasses() <= (uniqueRL.isWithDefaultSymbol() ? 1 : 0)) { if (owner != null) { JOptionPane .showMessageDialog( owner, AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.Error.NoClasses")); } return; } if (getRuleNames().size() > 1) { if (owner != null) { int res = JOptionPane .showConfirmDialog( owner, AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.AskOverwrite", getRuleNames().size() - 1, (uniqueRL.getValues() .size() - (uniqueRL .isWithDefaultSymbol() ? 1 : 0))), AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.AskOverwrite.Title"), JOptionPane.YES_NO_OPTION); if (res != JOptionPane.YES_OPTION) return; } removeAllClassesButFirst(); } for (int i = (uniqueRL.isWithDefaultSymbol() ? 1 : 0); i < uniqueRL .getValues().size(); i++) { Object val = uniqueRL.getValues().get(i); // Copy the first rules's settings to the new class: TextSymbolizer defaultTextSymbolizer = createDefaultTextSymbolizer(); getSymbolizers().add(defaultTextSymbolizer); PropertyIsEqualTo filter = ASUtil.ff2.equals(ASUtil.ff2 .property(uniqueRL.getPropertyFieldName()), ASUtil.ff2.literal(val)); getClassesFilters().add(filter); classesLanguages.add(null); setClassEnabled(1 + i - (uniqueRL.isWithDefaultSymbol() ? 1 : 0), true); getRuleNames().add(uniqueRL.getLabels().get(i)); classesMaxScales.add(uniqueRL.getSymbols().get(i) .getMaxScaleDenominator()); classesMinScales.add(uniqueRL.getSymbols().get(i) .getMinScaleDenominator()); } } /*********************************************************************** * Importing Rules form GraduatedColorRuleList is a bit different */ else if (symbRL instanceof GraduatedColorRuleList) { GraduatedColorRuleList gradRL = (GraduatedColorRuleList) symbRL; if (gradRL.getNumClasses() <= 0) { if (owner != null) { JOptionPane .showMessageDialog( owner, AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.Error.NoClasses")); } return; } if (getRuleNames().size() > 1) { if (owner != null) { int res = JOptionPane .showConfirmDialog( owner, AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.AskOverwrite", getRuleNames().size() - 1, gradRL.getRules() .size()), AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.AskOverwrite.Title"), JOptionPane.YES_NO_OPTION); if (res != JOptionPane.YES_OPTION) return; } removeAllClassesButFirst(); } int idx = 1; // the default rule is left untouched for (Rule r : gradRL.getRules()) { idx++; setClassEnabled(idx, true); // Copy the first rules's settings to the new class: TextSymbolizer defaultTextSymbolizer = createDefaultTextSymbolizer(); StylingUtil.copyAllValues(defaultTextSymbolizer, getClassSymbolizer(0)); getSymbolizers().add(defaultTextSymbolizer); Filter filter = r.getFilter(); getClassesFilters().add(filter); classesMinScales.add(gradRL.getTemplate() .getMinScaleDenominator()); classesMaxScales.add(gradRL.getTemplate() .getMaxScaleDenominator()); // The title could be a Translation.. but we only want a // string! Translation t = new Translation(); t.fromOneLine(GTUtil.descriptionTitle(r.getDescription())); getRuleNames().add(t.toString()); } JOptionPane .showMessageDialog( owner, AtlasStylerVector .R("TextRulesList.Labelclass.Action.LoadClassesFromSymbols.SuccesMsg", getRuleNames().size() - 1)); } } finally { popQuite(); } } /** * Parses a list of {@link Rule}s and configures this {@link TextRuleList} * with it. */ @Override public void importRules(List<Rule> rules) { pushQuite(); try { int idx = 0; for (Rule rule : rules) { Filter filter = rule.getFilter(); try { filter = parseAndRemoveEnabledDisabledFilters(filter, idx); // When using two label properties, we have two rules for // one // label class. So we drop it. String ruleName = rule.getName(); if (ruleName != null && ruleName.equals(RULENAME_DONTIMPORT)) continue; if ( (ruleName != null && ruleName.startsWith(DEFAULT_CLASS_RULENAME)) || (filter != null && filter.equals(oldClassesEnabledFilter)) || (filter != null && filter.equals(oldClassesDisabledFilter)) || idx == 0) { // Do not store the filter imported for default rules. getClassesFilters().add(DEFAULT_FILTER_ALL_OTHERS); // If this has been an old default rule, update the // ruleName to the new ruleName = DEFAULT_CLASS_RULENAME; if (getClassLang(idx) != null) ruleName += "_" + getClassLang(idx); } else { getClassesFilters().add(filter); } // getClassLang(idx); final TextSymbolizer textSymb = (TextSymbolizer) rule .getSymbolizers()[0]; getSymbolizers().add(textSymb); getRuleNames().add(ruleName); classesMaxScales.add(rule.getMaxScaleDenominator()); classesMinScales.add(rule.getMinScaleDenominator()); idx++; } catch (Exception e) { e.printStackTrace(); LOGGER.error("Error parsing textSymbolizerClassfilter ' " + filter + " '", e); } } /** * @deprecated move the selIdx out of this class */ setSelIdx(0); } finally { popQuite(); } } public Boolean isClassEnabled(int index) { if (index > classesEnabled.size() - 1) return null; return classesEnabled.get(index); } /** * Interprets the filters added by * {@link #addClassEnabledDisabledFilters(Filter, int)} * * @param idx * the index of the label class (0=default) * * @return The simpler filter that was inside all the mess. */ protected Filter parseAndRemoveEnabledDisabledFilters(Filter filter, int idx) { final Filter fullFilter = filter; filter = parseAbstractRlSettings(filter); /** * Interpreting whether the class is disable/enables */ try { if (filter.equals(Filter.EXCLUDE)) { setClassEnabled(idx, false); } else if (filter.equals(Filter.INCLUDE)) { setClassEnabled(idx, true); } else if (filter.equals(oldClassesEnabledFilter)) { setClassEnabled(idx, true); } else if (filter.equals(oldClassesDisabledFilter)) { setClassEnabled(idx, false); } else { List<?> andChildren = ((AndImpl) filter).getChildren(); if (andChildren.get(0).equals( StylingUtil.LABEL_CLASS_DISABLED_FILTER)) { setClassEnabled(idx, false); } else if (andChildren.get(0).equals( StylingUtil.LABEL_CLASS_ENABLED_FILTER)) { setClassEnabled(idx, true); } else { throw new RuntimeException(andChildren.get(0).toString() + "\n" + fullFilter.toString()); } filter = (Filter) andChildren.get(1); } } catch (Exception e) { setClassEnabled(idx, true); LOGGER.warn( "Couldn't interpret whether this TextRulesList CLASS is disabled or enabled. Assuming it is enabled.", e); } filter = parseAndRemoveLanguageFilter(filter, idx); return filter; } private Filter parseAndRemoveLanguageFilter(Filter filter, int idx) { /** * Interpreting whether this class is language specific */ LOGGER.debug("filter: " + filter); if (!(filter instanceof AndImpl)) { setClassLang(idx, null); return filter; } try { AndImpl andFilter = (AndImpl) filter; List<?> andChildren = andFilter.getChildren(); // System.out.println(filter); Filter envEqualsLang = (Filter) andChildren.get(0); Function envFunction = (Function) ((BinaryComparisonAbstract) envEqualsLang) .getExpression2(); Expression langExp = ((BinaryComparisonAbstract) envEqualsLang) .getExpression1(); if (!envFunction.getName().equals("env")) throw new RuntimeException(); setClassLang(idx, langExp.toString()); filter = (Filter) andChildren.get(1); } catch (Exception e) { setClassLang(idx, null); } return filter; } @Override public void parseMetaInfoString(String metaInfoString, FeatureTypeStyle fts) { // Does nothing } private void removeAllClassesButFirst() { TextSymbolizer backupS = getClassSymbolizer(0); getSymbolizers().clear(); getSymbolizers().add(backupS); String backupRN = getRuleNames().get(0); getRuleNames().clear(); getRuleNames().add(backupRN); Filter backupFR = getClassFilter(0); getClassesFilters().clear(); getClassesFilters().add(backupFR); Double backupMin = classesMinScales.get(0); classesMinScales.clear(); classesMinScales.add(backupMin); Double backupMax = classesMaxScales.get(0); classesMaxScales.clear(); classesMaxScales.add(backupMax); Boolean backupEnabled = classesEnabled.get(0); classesEnabled.clear(); classesEnabled.add(backupEnabled); } /** * Remove a text symbolizer class. */ public void removeClass(int idx) { getSymbolizers().remove(idx); getClassesFilters().remove(idx); getRuleNames().remove(idx); removeClassMinScale(idx); removeClassMaxScale(idx); removeClassEnabled(idx); } /** * @param classIdx * Label class idx, 0 = default/all others */ public void removeClassEnabled(int classIdx) { classesEnabled.remove(classIdx); } /** * @param classIdx * Label class idx, 0 = default/all others */ public void removeClassMaxScale(int classIdx) { classesMaxScales.remove(classIdx); } /** * @param classIdx * Label class idx, 0 = default/all others */ public void removeClassMinScale(int classIdx) { classesMinScales.remove(classIdx); } public void setClassEnabled(int index, boolean b) { while (classesEnabled.size() - 1 < index) { classesEnabled.add(true); } classesEnabled.set(index, b); fireEvents(new RuleChangedEvent( "a text symbolizer class enablement has been set to " + b, this)); } public void setClassFilter(int index, Filter filter) { while (classesFilters.size() - 1 < index) { classesFilters.add(Filter.EXCLUDE); } classesFilters.set(index, filter); fireEvents(new RuleChangedEvent( "a text symbolizer class FILTER has been set to " + filter, this)); } /** * @param lang * may be <code>null</code> */ void setClassLang(int index, String lang) { while (classesLanguages.size() - 1 < index) { classesLanguages.add(null); } if (XMapPane.ENV_LANG_DEFAULT.equals(lang)) { lang = null; } if (index == 0 && lang != null) throw new RuntimeException( "The default class may not be language specific"); classesLanguages.set(index, lang); fireEvents(new RuleChangedEvent( "a text symbolizer CLASS language has been set to " + lang, this)); } public void setClassMaxScale(int index, Double maxValue) { while (classesMaxScales.size() - 1 < index) { classesMaxScales.add(0.); } if (maxValue == null) maxValue = Double.MAX_VALUE; classesMaxScales.set(index, maxValue); fireEvents(new RuleChangedEvent( "a text CLASS MaxScale has been set to " + maxValue, this)); } public void setClassMinMaxScales(int index, Double minValue, Double maxValue) { setClassMinScale(index, minValue); setClassMaxScale(index, maxValue); } public void setClassMinScale(int index, Double minValue) { while (classesMinScales.size() - 1 < index) { classesMinScales.add(0.); } if (minValue == null) minValue = 0.; classesMinScales.set(index, minValue); fireEvents(new RuleChangedEvent( "a text CLASS MinScale has been set to " + minValue, this)); } private void setClassRuleName(int index, String ruleName) { while (classesRuleNames.size() - 1 < index) { classesRuleNames.add(""); } classesRuleNames.set(index, ruleName); fireEvents(new RuleChangedEvent( "a text CLASS rulename has been set to " + ruleName, this)); } private void setClassSymbolizer(int index, TextSymbolizer ts) { while (classesSymbolizers.size() - 1 < index) { classesSymbolizers.add(ts); } classesSymbolizers.set(index, ts); fireEvents(new RuleChangedEvent( "a text CLASS symbolizer has been set to " + ts, this)); } public void setRuleNames(List<String> ruleNames) { this.classesRuleNames = ruleNames; // No Event needs to be fired! Its just a name... } /** * @deprecated move the selIdx out of this class */ @Deprecated public void setSelIdx(int selIdx) { this.selIdx = selIdx; } public void setSymbolizers(List<TextSymbolizer> symbolizers) { this.classesSymbolizers = symbolizers; fireEvents(new RuleChangedEvent("setSymbolizers", this)); } }