Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / rendering / VectorFilterExpressionLegend.java @ 23265

History | View | Annotate | Download (11.9 KB)

1
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib��ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.symbology.fmap.rendering;
42

    
43

    
44
import java.io.StringReader;
45
import java.util.ArrayList;
46
import java.util.Hashtable;
47

    
48
import org.apache.log4j.Logger;
49
import org.gvsig.symbology.fmap.labeling.parse.LabelExpressionParser;
50
import org.gvsig.symbology.fmap.rendering.filter.operations.Expression;
51
import org.gvsig.symbology.fmap.rendering.filter.operations.ExpressionException;
52
import org.gvsig.symbology.fmap.rendering.filter.parser.ParseException;
53

    
54
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
55
import com.hardcode.gdbms.engine.data.DataSource;
56
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
57
import com.hardcode.gdbms.engine.values.Value;
58
import com.iver.cit.gvsig.fmap.Messages;
59
import com.iver.cit.gvsig.fmap.core.IFeature;
60
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
61
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
62
import com.iver.cit.gvsig.fmap.drivers.legend.LegendDriverException;
63
import com.iver.cit.gvsig.fmap.layers.XMLException;
64
import com.iver.cit.gvsig.fmap.rendering.AbstractClassifiedVectorLegend;
65
import com.iver.cit.gvsig.fmap.rendering.ILegend;
66
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
67
import com.iver.cit.gvsig.fmap.rendering.SymbolLegendEvent;
68
import com.iver.utiles.XMLEntity;
69

    
70

    
71
/**
72
 *
73
 * Implements a vectorial legend which represents the elements of a layer
74
 * depending on the value of an expression. That is, if the expression is
75
 * evaluated to true, then the symbol associated to the expression is painted.
76
 * In other case it is not showed.
77
 *
78
 * @author Pepe Vidal Salvador - jose.vidal.salvador@iver.es
79
 */
80
public class VectorFilterExpressionLegend extends AbstractClassifiedVectorLegend  {
81

    
82
        private int shapeType;
83
        private ISymbol defaultSymbol;
84
        private String labelFieldName;
85
        private String labelFieldHeight;
86
        private String labelFieldRotation;
87
        private boolean useDefaultSymbol = false;
88
        private String[] fNames;
89
        private Hashtable<String, Value> parser_symbol_table = new Hashtable<String, Value>();
90

    
91
        private ArrayList<Item> newSymbols = new ArrayList<Item>() {
92
                private static final long serialVersionUID = 1L;
93

    
94
                public int indexOf(String expr) {
95
                        return super.indexOf(new Item(expr, null));
96
                }
97
        };
98

    
99

    
100
        private class Item {
101
                private ISymbol sym;
102
                private String expression;
103
                private Expression expParser;
104

    
105
                public Item(String expression, ISymbol sym) {
106
                        this.expression = expression;
107
                        this.sym = sym;
108

    
109
                        try {
110
                                this.expParser =  createExpressionParser(this.expression);
111
                        } catch (ParseException e) {
112
                                e.printStackTrace();
113
                                Logger.getLogger(getClass()).error(Messages.getString("invalid_filter_expression"));
114
                        }
115

    
116
                }
117

    
118
                private Expression createExpressionParser(String expressionString) throws ParseException {
119
                        LabelExpressionParser parser = new LabelExpressionParser(new StringReader(expressionString), parser_symbol_table);
120
                        try {
121
                                parser.LabelExpression();
122
                        } catch (org.gvsig.symbology.fmap.labeling.parse.ParseException e) {
123
                                e.printStackTrace();
124
                        }
125
                        Expression expression = (Expression) parser.getStack().pop();
126
                        return expression;
127
                }
128

    
129
                @Override
130
                public boolean equals(Object obj) {
131
                        if (obj == null) return false;
132
                        if (!obj.getClass().equals(Item.class)) return false;
133
                        return this.expression.equals(((Item) obj).expression);
134
                }
135

    
136
                public ISymbol getSym() {
137
                        return sym;
138
                }
139

    
140
                public String getStringExpression() {
141
                        return expression;
142
                }
143

    
144
                public Expression getExpressionForParser() {
145
                        return expParser;
146
                }
147
        }
148

    
149
        /**
150
         * Constructor method
151
         *
152
         * @param type shapetype of the layer
153
         * @param fieldNames classifying field names used in the legend
154
         */
155
        public VectorFilterExpressionLegend(int type,String[] fieldNames) {
156
                setShapeType(type);
157
                this.setClassifyingFieldNames(fieldNames);
158
                this.fNames = fieldNames;
159
        }
160

    
161
        /**
162
         * Constructor method
163
         *
164
         */
165
        public VectorFilterExpressionLegend() { }
166

    
167

    
168
        public ISymbol getSymbolByFeature(IFeature feat) {
169
                ISymbol returnSymbol = null;
170
                Object result = null;
171
                fNames =  getClassifyingFieldNames();
172
                try {
173
                        updateSymbolsTable(feat, fNames);
174

    
175
                        for (int i = 0; i < newSymbols.size(); i++) {
176
                                Expression expression = newSymbols.get(i).expParser;
177

    
178
                                result = expression.evaluate();
179

    
180

    
181
                                if(result != null && (Boolean)result==true) {
182
                                        returnSymbol = newSymbols.get(i).sym;
183
                                        if (returnSymbol != null) {
184
                                                return returnSymbol;
185
                                        }
186
                                }
187
                        }
188
                } catch (ExpressionException e) {
189
                        e.printStackTrace();
190
                } catch (LegendDriverException e) {
191
                        Logger.getLogger(getClass()).error(Messages.getString("invalid_url"));
192
                }
193

    
194
                if(useDefaultSymbol)
195
                        return getDefaultSymbol();
196

    
197
                return null;
198
        }
199
        /**
200
         * Returns a HashTable containing the name of the field of an specific feature
201
         * and its values
202
         *
203
         * @param feat specific feature
204
         * @param fNames field names
205
         * @return HashTable
206
         * @throws LegendDriverException
207
         */
208
        private void updateSymbolsTable(IFeature feat, String[] fNames) throws LegendDriverException {
209
                for (int j = 0; j < fNames.length; j++) {
210
                        if(feat.getAttribute(j) != null)
211
                                parser_symbol_table.put(fNames[j], feat.getAttribute(j));
212
                        else throw new LegendDriverException(LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND);
213
                }
214
        }
215

    
216

    
217
        public void addSymbol(Object key, ISymbol symbol) {
218
                newSymbols.add(new Item((String)key.toString(),
219
                                symbol));
220
        }
221

    
222
        public void clear() {
223
                newSymbols.clear();
224
        }
225

    
226
        public void delSymbol(Object key) {
227
                newSymbols.remove(key);
228
                ISymbol mySymbol = null;
229
                for (int i = 0; i < newSymbols.size(); i++) {
230
                        if (newSymbols.get(i).equals(key))
231
                                mySymbol = newSymbols.get(i).sym;
232
                }
233

    
234
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(mySymbol,null));
235
        }
236

    
237

    
238
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
239

    
240
                for (int i = 0; i < newSymbols.size(); i++) {
241
                        if (newSymbols.get(i).sym.equals(oldSymbol))
242
                                newSymbols.get(i).sym = newSymbol;
243
                }
244

    
245
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(oldSymbol,newSymbol));
246
        }
247

    
248

    
249
        public String[] getDescriptions() {
250
                String[] descriptions = new String[newSymbols.size()];
251
                ISymbol[] auxSym = getSymbols();
252

    
253
                for (int i = 0; i < descriptions.length; i++)
254
                        descriptions[i] = auxSym[i].getDescription();
255

    
256
                return descriptions;
257
        }
258

    
259
        public ISymbol[] getSymbols() {
260

    
261
                if (newSymbols != null) {
262
                        ISymbol[] mySymbols = new ISymbol[newSymbols.size()];
263
                        for (int i = 0; i < newSymbols.size(); i++) {
264
                                mySymbols[i] = newSymbols.get(i).sym;
265
                        }
266
                        return mySymbols;
267
                }
268
                return null;
269
        }
270

    
271

    
272

    
273
        public ILegend cloneLegend() throws XMLException {
274
                return LegendFactory.createFromXML(getXMLEntity());
275
        }
276

    
277
        public ISymbol getDefaultSymbol() {
278
                if(defaultSymbol==null) {
279
                        defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
280
                        fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
281
                }
282
                return defaultSymbol;
283
        }
284

    
285

    
286
        public String getClassName() {
287
                return getClass().getName();
288
        }
289

    
290
        public XMLEntity getXMLEntity() {
291
                XMLEntity xml = new XMLEntity();
292
                xml.putProperty("className", this.getClass().getName());
293
                xml.putProperty("fieldNames", getClassifyingFieldNames());
294
                xml.putProperty("fieldTypes", getClassifyingFieldTypes());
295
                xml.putProperty("labelfield", labelFieldName);
296
                xml.putProperty("labelFieldHeight", labelFieldHeight);
297
                xml.putProperty("labelFieldRotation", labelFieldRotation);
298
                if (getDefaultSymbol() == null) {
299
                        xml.putProperty("useDefaultSymbol", 0);
300
                } else {
301
                        xml.putProperty("useDefaultSymbol", 1);
302
                        xml.addChild(getDefaultSymbol().getXMLEntity());
303
                }
304

    
305
                xml.putProperty("numKeys", newSymbols.size());
306

    
307
                if (newSymbols.size() > 0) {
308
                        xml.putProperty("tipoValueKeys", "Expressions");
309

    
310
                        String[] sk = new String[newSymbols.size()];
311

    
312
                        for (int i = 0; i < newSymbols.size(); i++) {
313
                                sk[i] = newSymbols.get(i).expression.toString();
314
                        }
315
                        xml.putProperty("keys", getValues());
316

    
317
                        for (int i = 0; i < newSymbols.size(); i++) {
318
                                xml.addChild(getSymbols()[i].getXMLEntity());
319
                        }
320
                }
321

    
322

    
323
                if (getZSort()!=null) {
324
                        XMLEntity xmlZSort = getZSort().getXMLEntity();
325
                        xmlZSort.putProperty("id", "zSort");
326
                        xml.addChild(xmlZSort);
327
                }
328
                return xml;
329
        }
330

    
331
        public void setXMLEntity(XMLEntity xml) {
332
                clear();
333
                if (xml.contains("fieldName"))
334
                        setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
335
                else {
336
                        setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
337
                }
338
                if (xml.contains("fieldTypes"))
339
                        setClassifyingFieldTypes(new int[] {xml.getIntProperty("fieldTypes")});
340

    
341
                useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
342
                int hasDefaultSymbol = xml.getIntProperty("useDefaultSymbol");
343
                if (hasDefaultSymbol == 1) {
344
                        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
345
                } else {
346
                        setDefaultSymbol(null);
347
                }
348

    
349
                int numKeys = xml.getIntProperty("numKeys");
350
                if (numKeys > 0) {
351
                        String[] sk = xml.getStringArrayProperty("keys");
352
                        String auxExpression;
353

    
354
                        for (int i = 0; i < numKeys; i++) {
355
                                auxExpression = sk[i];
356
                                newSymbols.add(new Item(auxExpression,SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)));
357
                                System.out.println("auxExpression =" + auxExpression + "Symbol =" +
358
                                                SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)
359
                                                .getDescription()+"\n");
360
                        }
361
                }
362
        }
363

    
364
        public int getShapeType() {
365
                return shapeType;
366
        }
367

    
368
        public ISymbol getSymbol(int i) throws ReadDriverException {
369

    
370
                return null;
371
        }
372

    
373

    
374
        public boolean isUseDefaultSymbol() {
375
                return useDefaultSymbol;
376
        }
377

    
378
        public void setDataSource(DataSource ds) throws FieldNotFoundException,
379
        ReadDriverException {
380
//                dataSource = ds;
381
        }
382

    
383
        public void setDefaultSymbol(ISymbol s) throws IllegalArgumentException {
384
                if (s == null) throw new NullPointerException("Default symbol cannot be null");
385
                ISymbol old = defaultSymbol;
386
                defaultSymbol = s;
387
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
388
        }
389

    
390
        public void setShapeType(int shapeType) {
391
                if (this.shapeType != shapeType) {
392
                        setDefaultSymbol(SymbologyFactory.
393
                                        createDefaultSymbolByShapeType(shapeType));
394
                        this.shapeType = shapeType;
395
                }
396
        }
397

    
398
        public void setXMLEntity03(XMLEntity xml) {
399
//                TODO Auto-generated method stub
400

    
401
        }
402

    
403
        public void useDefaultSymbol(boolean b) {
404
                useDefaultSymbol = b;
405
        }
406

    
407
        public Object[] getValues() {
408
                if (newSymbols != null) {
409
                        Object[] myObjects = new Object[newSymbols.size()];
410
                        for (int i = 0; i < newSymbols.size(); i++) {
411
                                myObjects[i] =newSymbols.get(i).expression;
412
                        }
413
                        return myObjects;
414
                }
415
                return null;
416
        }
417

    
418

    
419

    
420
}