Statistics
| Revision:

root / trunk / extensions / extSymbology / src / org / gvsig / symbology / fmap / rendering / VectorialFilterExpressionLegend.java @ 20768

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.rendering.filter.operations.Expression;
50
import org.gvsig.symbology.fmap.rendering.filter.operations.ExpressionException;
51
import org.gvsig.symbology.fmap.rendering.filter.parser.ExpressionParser;
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 VectorialFilterExpressionLegend 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
        private ExpressionParser parser = new ExpressionParser(new StringReader("true"));
91

    
92
        private ArrayList<Item> newSymbols = new ArrayList<Item>() {
93
                private static final long serialVersionUID = 1L;
94
                
95
                public int indexOf(String expr) {
96
                        return super.indexOf(new Item(expr, null));
97
                }
98
        };
99

    
100

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

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

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

    
116
                }
117
                private Expression createExpressionParser(String expressionString) throws ParseException {
118
                        parser = new ExpressionParser(new java.io.StringReader(expressionString));
119
                        parser.Expression();
120
                        Expression expression = parser.getExpression();
121
                        return expression;
122
                }
123
                @Override
124
                public boolean equals(Object obj) {
125
                        if (obj == null) return false;
126
                        if (!obj.getClass().equals(Item.class)) return false;
127
                        return this.expression.equals(((Item) obj).expression);
128
                }
129
                public ISymbol getSym() {
130
                        return sym;
131
                }
132
                public String getStringExpression() {
133
                        return expression;
134
                }
135
                public Expression getExpressionForParser() {
136
                        return expParser;
137
                }
138
        }
139

    
140
        /**
141
         * Constructor method
142
         * 
143
         * @param type shapetype of the layer
144
         * @param fieldNames classifying field names used in the legend
145
         */
146
        public VectorialFilterExpressionLegend(int type,String[] fieldNames) {
147
                setShapeType(type);
148
                this.setClassifyingFieldNames(fieldNames);
149
                this.fNames = fieldNames;
150
        }
151
        
152
        /**
153
         * Constructor method
154
         *
155
         */
156
        public VectorialFilterExpressionLegend() { }
157

    
158

    
159
        public ISymbol getSymbolByFeature(IFeature feat) {
160

    
161
                ISymbol returnSymbol = null;
162
                Object result = null;
163
                fNames =  getClassifyingFieldNames();
164

    
165
                for (int i = 0; i < newSymbols.size(); i++) {
166

    
167
                        Expression expression = newSymbols.get(i).expParser;
168
                        try {
169

    
170
                                result = expression.evaluate(getSymbolsTable(feat, fNames));
171

    
172
                        } catch (ExpressionException e) {
173
                                e.printStackTrace();
174
                        } catch (LegendDriverException e) {
175
                                Logger.getLogger(getClass()).error(Messages.getString("invalid_url"));
176
                        }
177

    
178
                        if(result != null && (Boolean)result==true) {
179
                                returnSymbol = newSymbols.get(i).sym;
180
                                if (returnSymbol != null) {
181
                                        return returnSymbol;
182
                                }
183
                        }
184
                }
185
                if(useDefaultSymbol)
186
                        return getDefaultSymbol();
187

    
188
                return null;
189
        }
190
        /**
191
         * Returns a HashTable containing the name of the field of an specific feature
192
         * and its values
193
         * 
194
         * @param feat specific feature
195
         * @param fNames field names
196
         * @return HashTable
197
         * @throws LegendDriverException
198
         */
199
        private Hashtable<String, Value> getSymbolsTable(IFeature feat, String[] fNames) throws LegendDriverException {
200
                for (int j = 0; j < fNames.length; j++) {
201
                        if(feat.getAttribute(j) != null)
202
                                parser_symbol_table.put(fNames[j], feat.getAttribute(j));
203
                        else throw new LegendDriverException(LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND);
204
                }
205
                return parser_symbol_table;
206
        }
207

    
208

    
209
        public void addSymbol(Object key, ISymbol symbol) {
210
                newSymbols.add(new Item((String)key.toString(),
211
                                symbol));
212
        }
213

    
214
        public void clear() {
215
                newSymbols.clear();
216
        }
217

    
218
        public void delSymbol(Object key) {
219
                newSymbols.remove(key);
220
                ISymbol mySymbol = null;
221
                for (int i = 0; i < newSymbols.size(); i++) {
222
                        if (newSymbols.get(i).equals(key))
223
                                mySymbol = newSymbols.get(i).sym;
224
                }
225

    
226
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(mySymbol,null));
227
        }
228

    
229

    
230
        public void replace(ISymbol oldSymbol, ISymbol newSymbol) {
231

    
232
                for (int i = 0; i < newSymbols.size(); i++) {
233
                        if (newSymbols.get(i).sym.equals(oldSymbol))
234
                                newSymbols.get(i).sym = newSymbol;
235
                }
236

    
237
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(oldSymbol,newSymbol));
238
        }
239

    
240

    
241
        public String[] getDescriptions() {
242
                String[] descriptions = new String[newSymbols.size()];
243
                ISymbol[] auxSym = getSymbols();
244

    
245
                for (int i = 0; i < descriptions.length; i++)
246
                        descriptions[i] = auxSym[i].getDescription();
247

    
248
                return descriptions;
249
        }
250

    
251
        public ISymbol[] getSymbols() {
252

    
253
                if (newSymbols != null) {
254
                        ISymbol[] mySymbols = new ISymbol[newSymbols.size()];
255
                        for (int i = 0; i < newSymbols.size(); i++) {
256
                                mySymbols[i] = newSymbols.get(i).sym;
257
                        }
258
                        return mySymbols;
259
                } 
260
                return null;
261
        }
262

    
263

    
264

    
265
        public ILegend cloneLegend() throws XMLException {
266
                return LegendFactory.createFromXML(getXMLEntity());
267
        }
268

    
269
        public ISymbol getDefaultSymbol() {
270
                if(defaultSymbol==null) {
271
                        defaultSymbol = SymbologyFactory.createDefaultSymbolByShapeType(shapeType);
272
                        fireDefaultSymbolChangedEvent(new SymbolLegendEvent(null, defaultSymbol));
273
                }
274
                return defaultSymbol;
275
        }
276

    
277

    
278
        public String getClassName() {
279
                return getClass().getName();
280
        }
281

    
282
        public XMLEntity getXMLEntity() {
283
                XMLEntity xml = new XMLEntity();
284
                xml.putProperty("className", this.getClass().getName());
285
                xml.putProperty("fieldNames", getClassifyingFieldNames());
286
                xml.putProperty("fieldTypes", getClassifyingFieldTypes());
287
                xml.putProperty("labelfield", labelFieldName);
288
                xml.putProperty("labelFieldHeight", labelFieldHeight);
289
                xml.putProperty("labelFieldRotation", labelFieldRotation);
290
                if (getDefaultSymbol() == null) {
291
                        xml.putProperty("useDefaultSymbol", 0);
292
                } else {
293
                        xml.putProperty("useDefaultSymbol", 1);
294
                        xml.addChild(getDefaultSymbol().getXMLEntity());
295
                }
296

    
297
                xml.putProperty("numKeys", newSymbols.size());
298

    
299
                if (newSymbols.size() > 0) {
300
                        xml.putProperty("tipoValueKeys", "Expressions");
301

    
302
                        String[] sk = new String[newSymbols.size()];
303

    
304
                        for (int i = 0; i < newSymbols.size(); i++) {
305
                                sk[i] = newSymbols.get(i).expression.toString();
306
                        }
307
                        xml.putProperty("keys", getValues());
308

    
309
                        for (int i = 0; i < newSymbols.size(); i++) {
310
                                xml.addChild(getSymbols()[i].getXMLEntity());
311
                        }
312
                }
313

    
314

    
315
                if (getZSort()!=null) {
316
                        XMLEntity xmlZSort = getZSort().getXMLEntity();
317
                        xmlZSort.putProperty("id", "zSort");
318
                        xml.addChild(xmlZSort);
319
                }
320
                return xml;
321
        }
322

    
323
        public void setXMLEntity(XMLEntity xml) {
324
                clear();
325
                if (xml.contains("fieldName"))
326
                        setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
327
                else {
328
                        setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
329
                }
330
                if (xml.contains("fieldTypes"))
331
                        setClassifyingFieldTypes(new int[] {xml.getIntProperty("fieldTypes")});
332

    
333
                useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
334
                int hasDefaultSymbol = xml.getIntProperty("useDefaultSymbol");
335
                if (hasDefaultSymbol == 1) {
336
                        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
337
                } else {
338
                        setDefaultSymbol(null);
339
                }
340

    
341
                int numKeys = xml.getIntProperty("numKeys");
342
                if (numKeys > 0) {
343
                        String[] sk = xml.getStringArrayProperty("keys");
344
                        String auxExpression;
345

    
346
                        for (int i = 0; i < numKeys; i++) {
347
                                auxExpression = sk[i];
348
                                newSymbols.add(new Item(auxExpression,SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)));
349
                                System.out.println("auxExpression =" + auxExpression + "Symbol =" +
350
                                                SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)
351
                                                .getDescription()+"\n");
352
                        }
353
                }
354
        }
355

    
356
        public int getShapeType() {
357
                return shapeType;
358
        }
359

    
360
        public ISymbol getSymbol(int i) throws ReadDriverException {
361

    
362
                return null;
363
        }
364
        
365

    
366
        public boolean isUseDefaultSymbol() {
367
                return useDefaultSymbol;
368
        }
369

    
370
        public void setDataSource(DataSource ds) throws FieldNotFoundException,
371
        ReadDriverException {
372
//                dataSource = ds;
373
        }
374

    
375
        public void setDefaultSymbol(ISymbol s) throws IllegalArgumentException {
376
                if (s == null) throw new NullPointerException("Default symbol cannot be null");
377
                ISymbol old = defaultSymbol;
378
                defaultSymbol = s;
379
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
380
        }
381

    
382
        public void setShapeType(int shapeType) {
383
                if (this.shapeType != shapeType) {
384
                        setDefaultSymbol(SymbologyFactory.
385
                                        createDefaultSymbolByShapeType(shapeType));
386
                        this.shapeType = shapeType;
387
                }
388
        }
389

    
390
        public void setXMLEntity03(XMLEntity xml) {
391
//                TODO Auto-generated method stub
392

    
393
        }
394

    
395
        public void useDefaultSymbol(boolean b) {
396
                useDefaultSymbol = b;
397
        }
398

    
399
        public Object[] getValues() {
400
                if (newSymbols != null) {
401
                        Object[] myObjects = new Object[newSymbols.size()];
402
                        for (int i = 0; i < newSymbols.size(); i++) {
403
                                myObjects[i] =newSymbols.get(i).expression;
404
                        }
405
                        return myObjects;
406
                } 
407
                return null;
408
        }
409

    
410

    
411

    
412
}