Statistics
| Revision:

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

History | View | Annotate | Download (12.2 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.labeling.parse.ParseException;
51
import org.gvsig.symbology.fmap.rendering.filter.operations.Expression;
52
import org.gvsig.symbology.fmap.rendering.filter.operations.ExpressionException;
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 (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
                                if (result.equals("Default")){
180
                                        return defaultSymbol;
181
                                }
182

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

    
196
                if(useDefaultSymbol)
197
                        return getDefaultSymbol();
198

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

    
219

    
220
        public void addSymbol(Object key, ISymbol symbol) {
221
                newSymbols.add(new Item((String)key.toString(),
222
                                symbol));
223
        }
224

    
225
        public void clear() {
226
                newSymbols.clear();
227
        }
228

    
229
        public void delSymbol(Object key) {
230
                ISymbol mySymbol = null;
231
                for (int i = 0; i < newSymbols.size(); i++) {
232
                        if (newSymbols.get(i).sym.equals(key))
233
                                newSymbols.remove(i);
234
                }
235
                fireClassifiedSymbolChangeEvent(new SymbolLegendEvent(mySymbol,null));
236
        }
237

    
238

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

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

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

    
249

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

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

    
257
                return descriptions;
258
        }
259

    
260
        public ISymbol[] getSymbols() {
261

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

    
272

    
273

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

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

    
286

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

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

    
308
                xml.putProperty("numKeys", newSymbols.size());
309

    
310
                if (newSymbols.size() > 0) {
311
                        xml.putProperty("tipoValueKeys", "Expressions");
312

    
313
                        String[] sk = new String[newSymbols.size()];
314

    
315
                        for (int i = 0; i < newSymbols.size(); i++) {
316
                                sk[i] = newSymbols.get(i).expression.toString();
317
                        }
318
                        xml.putProperty("keys", getValues());
319
                        int numKeys=0;
320
                        for (int i = 0; i < newSymbols.size(); i++) {
321
                                if (!newSymbols.get(i).getStringExpression().equals("Default")){
322
                                        xml.addChild(getSymbols()[i].getXMLEntity());
323
                                        numKeys++;
324
                                }
325
                        }
326
                        xml.putProperty("numKeys", numKeys);
327
                }
328

    
329

    
330
                if (getZSort()!=null) {
331
                        XMLEntity xmlZSort = getZSort().getXMLEntity();
332
                        xmlZSort.putProperty("id", "zSort");
333
                        xml.addChild(xmlZSort);
334
                }
335
                return xml;
336
        }
337

    
338
        public void setXMLEntity(XMLEntity xml) {
339
                clear();
340
                if (xml.contains("fieldName"))
341
                        setClassifyingFieldNames(new String[] {xml.getStringProperty("fieldName")});
342
                else if (xml.contains("fieldNames")){
343
                        setClassifyingFieldNames(xml.getStringArrayProperty("fieldNames"));
344
                }
345
//                if (xml.contains("fieldTypes"))
346
//                        setClassifyingFieldTypes(new int[] {xml.getIntProperty("fieldTypes")});
347

    
348
                useDefaultSymbol = xml.getBooleanProperty("useDefaultSymbol");
349
                int hasDefaultSymbol = xml.getIntProperty("useDefaultSymbol");
350
                if (hasDefaultSymbol == 1) {
351
                        setDefaultSymbol(SymbologyFactory.createSymbolFromXML(xml.getChild(0), null));
352
                } else {
353
                        setDefaultSymbol(null);
354
                }
355

    
356
                int numKeys = xml.getIntProperty("numKeys");
357
                if (numKeys > 0) {
358
                        String[] sk = xml.getStringArrayProperty("keys");
359
                        String auxExpression;
360

    
361
                        for (int i = 0; i < numKeys; i++) {
362
                                auxExpression = sk[i];
363
                                newSymbols.add(new Item(auxExpression,SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)));
364
                                System.out.println("auxExpression =" + auxExpression + "Symbol =" +
365
                                                SymbologyFactory.createSymbolFromXML(xml.getChild(i + hasDefaultSymbol), null)
366
                                                .getDescription()+"\n");
367
                        }
368
                }
369
        }
370

    
371
        public int getShapeType() {
372
                return shapeType;
373
        }
374

    
375
        public ISymbol getSymbol(int i) throws ReadDriverException {
376

    
377
                return null;
378
        }
379

    
380

    
381
        public boolean isUseDefaultSymbol() {
382
                return useDefaultSymbol;
383
        }
384

    
385
        public void setDataSource(DataSource ds) throws FieldNotFoundException,
386
        ReadDriverException {
387
//                dataSource = ds;
388
        }
389

    
390
        public void setDefaultSymbol(ISymbol s) throws IllegalArgumentException {
391
                if (s == null) throw new NullPointerException("Default symbol cannot be null");
392
                ISymbol old = defaultSymbol;
393
                defaultSymbol = s;
394
                fireDefaultSymbolChangedEvent(new SymbolLegendEvent(old, defaultSymbol));
395
        }
396

    
397
        public void setShapeType(int shapeType) {
398
                if (this.shapeType != shapeType) {
399
                        setDefaultSymbol(SymbologyFactory.
400
                                        createDefaultSymbolByShapeType(shapeType));
401
                        this.shapeType = shapeType;
402
                }
403
        }
404

    
405
        public void setXMLEntity03(XMLEntity xml) {
406
//                TODO Auto-generated method stub
407

    
408
        }
409

    
410
        public void useDefaultSymbol(boolean b) {
411
                useDefaultSymbol = b;
412
        }
413

    
414
        public Object[] getValues() {
415
                if (newSymbols != null) {
416
                        Object[] myObjects = new Object[newSymbols.size()];
417
                        for (int i = 0; i < newSymbols.size(); i++) {
418
                                myObjects[i] =newSymbols.get(i).expression;
419
                        }
420
                        return myObjects;
421
                }
422
                return null;
423
        }
424

    
425

    
426

    
427
}