Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / symboltables / ProjectSymbolTable.java @ 44338

History | View | Annotate | Download (28.4 KB)

1 44129 jjdelcerro
package org.gvsig.app.project.symboltables;
2 43987 jjdelcerro
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.util.HashMap;
6 43997 jjdelcerro
import java.util.Iterator;
7 44203 jjdelcerro
import java.util.List;
8 43987 jjdelcerro
import java.util.Map;
9
import java.util.Properties;
10
import org.apache.commons.io.IOUtils;
11
import org.apache.commons.lang3.Range;
12 44243 jjdelcerro
import org.apache.commons.lang3.StringUtils;
13 43997 jjdelcerro
import org.cresques.cts.IProjection;
14 44025 jjdelcerro
import org.gvsig.app.ApplicationLocator;
15
import org.gvsig.app.ApplicationManager;
16 44129 jjdelcerro
import org.gvsig.app.project.Project;
17
import org.gvsig.app.project.ProjectManager;
18 43997 jjdelcerro
import org.gvsig.app.project.documents.Document;
19 43987 jjdelcerro
import org.gvsig.app.project.documents.view.ViewDocument;
20
import org.gvsig.app.project.documents.view.ViewManager;
21 44153 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
22
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
23
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
24 44189 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
25 43987 jjdelcerro
import org.gvsig.expressionevaluator.Interpreter;
26
import org.gvsig.expressionevaluator.spi.AbstractFunction;
27
import org.gvsig.expressionevaluator.spi.AbstractSymbolTable;
28 43997 jjdelcerro
import org.gvsig.fmap.crs.CRSFactory;
29 44153 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
30
import org.gvsig.fmap.dal.DataManager;
31 44189 jjdelcerro
import org.gvsig.fmap.dal.HasDataStore;
32 44153 jjdelcerro
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
33 43987 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
34
import org.gvsig.fmap.dal.feature.FeatureQuery;
35
import org.gvsig.fmap.dal.feature.FeatureSet;
36
import org.gvsig.fmap.dal.feature.FeatureStore;
37 43997 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
38 44035 jjdelcerro
import org.gvsig.fmap.geom.primitive.Point;
39 43997 jjdelcerro
import org.gvsig.fmap.mapcontext.MapContext;
40 43987 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.FLayer;
41
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
42 43997 jjdelcerro
import org.gvsig.fmap.mapcontrol.AreaAndPerimeterCalculator;
43 44035 jjdelcerro
import org.gvsig.temporarystorage.TemporaryStorageGroup;
44
import org.gvsig.temporarystorage.TemporaryStorageLocator;
45
import org.gvsig.temporarystorage.TemporaryStorageManager;
46 44203 jjdelcerro
import org.gvsig.tools.util.UnmodifiableBasicList;
47 43987 jjdelcerro
48
/**
49
 *
50
 * @author jjdelcerro
51
 */
52
@SuppressWarnings("UseSpecificCatch")
53
public class ProjectSymbolTable extends AbstractSymbolTable {
54 44338 jjdelcerro
    public static final String PROJECT_GROUP = "Project";
55 43987 jjdelcerro
56 44129 jjdelcerro
    public static final String AREA_NAME = "AREA";
57
    public static final String PERIMETER_NAME = "PERIMETER";
58 44153 jjdelcerro
    public static final String STORE_NAME = "STORE";
59
    public static final String FETCH_FIRST_NAME = "FETCH_FIRST";
60
    public static final String FETCH_FIRST_SELECTED_NAME = "FETCH_FIRST_SELECTED";
61 44203 jjdelcerro
    public static final String FETCH_NAME = "FETCH";
62 44338 jjdelcerro
    public static final String APPLICATION_NAME = "APPLICATION";
63 44129 jjdelcerro
64
    static final String NAME = "Project";
65
66 44189 jjdelcerro
    private static final String TABLE_DOCUMENT_TYPENAME = "project.document.table";
67
68 43987 jjdelcerro
    private abstract class CachedValue<T> {
69
70
        T value = null;
71
        long lastAccess = 0;
72
73
        protected abstract void reload();
74
75
        public boolean isExpired() {
76
            long now = System.currentTimeMillis();
77
            return now - lastAccess > 3000;
78
        }
79
80
        public T get() {
81
            if (isExpired()) {
82
                reload();
83
            }
84
            lastAccess = System.currentTimeMillis();
85
            return value;
86
        }
87
    }
88
89
    private class ProjectValue extends CachedValue<Project> {
90
91
        @Override
92
        protected void reload() {
93
            value = ProjectManager.getInstance().getCurrentProject();
94
        }
95
96
    }
97
98 44025 jjdelcerro
    private class CurrentViewValue extends CachedValue<ViewDocument> {
99
100
        @Override
101
        protected void reload() {
102
            ApplicationManager application = ApplicationLocator.getManager();
103
            ViewDocument viewdoc = (ViewDocument) application.getActiveDocument(ViewManager.TYPENAME);
104
            value = viewdoc;
105
        }
106
107
    }
108
109
    private class CurrentViewEnvelopeValue extends CachedValue<Geometry> {
110
111
        @Override
112
        protected void reload() {
113
            ApplicationManager application = ApplicationLocator.getManager();
114
            ViewDocument viewdoc = (ViewDocument) application.getActiveDocument(ViewManager.TYPENAME);
115
            if( viewdoc == null ) {
116
                value = null;
117
                return;
118
            }
119
            value = viewdoc.getMapContext().getViewPort().getEnvelope().getGeometry();
120
        }
121
122
    }
123
124 43987 jjdelcerro
    private class PropertiesValue extends CachedValue<Map<File, Properties>> {
125
126
        @Override
127
        protected void reload() {
128
            value = new HashMap<>();
129
        }
130
    }
131
132
    private class CurrentProjectFunction extends AbstractFunction {
133
134
        public CurrentProjectFunction() {
135
            super(
136 44338 jjdelcerro
                    PROJECT_GROUP,
137 43987 jjdelcerro
                    "project",
138
                    Range.is(0),
139
                    "Access to the current project loaded in gvSIG desktop.\n",
140
                    "project()",
141
                    null,
142
                    "Project"
143
            );
144
        }
145
146
        @Override
147
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
148
            return currentProject.get();
149
        }
150
151
    }
152
153 44338 jjdelcerro
    private class ApplicationFunction extends AbstractFunction {
154
155
        public ApplicationFunction() {
156
            super(
157
                    PROJECT_GROUP,
158
                    APPLICATION_NAME,
159
                    Range.is(0),
160
                    "Access to the Application object.\n",
161
                    APPLICATION_NAME+"()",
162
                    null,
163
                    "ApplicationManager"
164
            );
165
        }
166
167
        @Override
168
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
169
            return ApplicationLocator.getApplicationManager();
170
        }
171
172
    }
173
174 44153 jjdelcerro
    private class StoreFunction extends AbstractFunction {
175 44189 jjdelcerro
176 44153 jjdelcerro
        public StoreFunction() {
177
            super(
178 44338 jjdelcerro
                    PROJECT_GROUP,
179 44153 jjdelcerro
                    STORE_NAME,
180
                    Range.is(2), // Range.between(1, 2),
181
                    "Return the data store associated with a layer.", // or a table.\n" +
182
//                       "If receive a single parameter, it will correspond to " +
183
//                       "the name of a table-type document, and it will return " +
184
//                       "your data store. If you receive two parameters, you expect " +
185
//                       "to be the name of a view and a layer of it, returning the " +
186
//                       "data store of the layer.",
187
                    STORE_NAME+"({{view}}, layer)",
188
                    new String[]{
189 44243 jjdelcerro
                        "view - String value with the name of a view, if view is null use current View.",
190 44153 jjdelcerro
                        "layer - String value with the name of a layer in the indicated view"
191
//                        "table - String value with the name of document table"
192
                    },
193
                    "DataStore"
194
            );
195
        }
196 43987 jjdelcerro
197 44153 jjdelcerro
        @Override
198
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
199
            Project project = currentProject.get();
200
            switch (args.length) {
201 44189 jjdelcerro
                case 1:
202
                    String tableName = getStr(args, 0);
203
                    Document document = project.getDocument(tableName, TABLE_DOCUMENT_TYPENAME);
204
                    if (document == null) {
205 44243 jjdelcerro
                        throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't locate table document '"+tableName+"'.");
206
//                        return null;
207 44189 jjdelcerro
                    }
208
                    if( document instanceof HasDataStore ) {
209
                        return ((HasDataStore) document).getDataStore();
210
                    }
211 44243 jjdelcerro
                    throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't get store from table document '"+tableName+"'.");
212
//                    return null;
213 44189 jjdelcerro
214 44153 jjdelcerro
                case 2:
215 44243 jjdelcerro
                    ViewDocument view;
216 44153 jjdelcerro
                    String viewName = getStr(args, 0);
217 44243 jjdelcerro
                    if( StringUtils.isBlank(viewName) ) {
218
                        view = (ViewDocument) project.getActiveDocument(ViewManager.TYPENAME);
219
                        if (view == null) {
220
                            throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't locate active View.");
221
//                            return null;
222
                        }
223
                    } else {
224
                        view = (ViewDocument) project.getDocument(viewName, ViewManager.TYPENAME);
225
                        if (view == null) {
226
                            throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't locate View '"+viewName+"'.");
227
//                            return null;
228
                        }
229
                    }
230 44153 jjdelcerro
                    String layerName = getStr(args, 1);
231 44243 jjdelcerro
                    FLayer layer = view.getLayer(layerName);
232
                    if( layer == null ) {
233
                        throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't locate layer '"+layerName+"' in View '"+viewName+"'.");
234 44153 jjdelcerro
                    }
235 44189 jjdelcerro
                    if( layer instanceof HasDataStore ) {
236
                        return ((HasDataStore)layer).getDataStore();
237 44153 jjdelcerro
                    }
238 44243 jjdelcerro
                    throw new ExpressionRuntimeException("Problems calling '"+STORE_NAME+"' function, can't get the store from layer '"+layerName+"' in View '"+viewName+"'.");
239
//                    return null;
240 44153 jjdelcerro
            }
241
            return null;
242
        }
243
244
    }
245
246 44203 jjdelcerro
    private class FetchFunction extends AbstractFunction {
247
248
        public FetchFunction() {
249
            super(
250 44338 jjdelcerro
                    PROJECT_GROUP,
251 44203 jjdelcerro
                    FETCH_NAME,
252
                    Range.between(2, 4),
253
                    "Access to the features of a table and retuen a list with the values.",
254
                    FETCH_NAME+"({{value}}, store, where, order)",
255
                    new String[]{
256
                        "value - value to retrieve from the store, usually an expression in the columns of this are involved.",
257
                        "store - data store from which values will be collected",
258
                        "where - Optional. String value with a filter expression",
259
                        "order - Optional. String value with the order. must be a string with the names of separate fields with commas"
260
                    },
261
                    "Object"
262
            );
263
        }
264
265
        @Override
266
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
267
            Object value;
268
            String where = null;
269
            String order = null;
270
            String expression_s = getStr(args, 0);
271
            FeatureStore store = (FeatureStore) getObject(args, 1);
272
            switch (args.length) {
273
                case 3:
274
                    where = getStr(args, 2);
275
                    break;
276
                case 4:
277
                    where = getStr(args, 2);
278
                    order = getStr(args, 3);
279
                    break;
280
            }
281
            try {
282
                List<Feature> features;
283
                if (where == null && order == null) {
284
                    features = store.getFeatures();
285
                } else {
286
                    FeatureQuery query = store.createFeatureQuery();
287
                    if (where != null) {
288
                        query.addFilter(where);
289
                    }
290
                    if (order != null) {
291
                        query.getOrder().add(order);
292
                    }
293
                    query.retrievesAllAttributes();
294
                    features = store.getFeatures(query);
295
                }
296
                UnmodifiableBasicList<Object> list = new ListOfFeaturesWrapper(
297
                        features,
298
                        interpreter.getSymbolTable(),
299
                        expression_s
300
                );
301
                return list;
302
            } catch (Exception ex) {
303
                throw new ExpressionRuntimeException("Problems calling '"+FETCH_NAME+"' function", ex);
304
            }
305
        }
306
    }
307
308 44153 jjdelcerro
    private class FetchFirstFunction extends AbstractFunction {
309
310
        public FetchFirstFunction() {
311 43987 jjdelcerro
            super(
312 44338 jjdelcerro
                    PROJECT_GROUP,
313 44153 jjdelcerro
                    FETCH_FIRST_NAME,
314
                    Range.between(2, 4),
315 43987 jjdelcerro
                    "Access to the first feature of the layer, and "
316
                    + "return the value of the attribute.",
317 44153 jjdelcerro
                    FETCH_FIRST_NAME+"({{value}}, store, where, order)",
318 43987 jjdelcerro
                    new String[]{
319 44153 jjdelcerro
                        "value - value to retrieve from the store, usually an expression in the columns of this are involved.",
320
                        "store - data store from which values will be collected",
321
                        "where - Optional. String value with a filter expression",
322
                        "order - Optional. String value with the order. must be a string with the names of separate fields with commas"
323 43987 jjdelcerro
                    },
324
                    "Object"
325
            );
326
        }
327
328
        @Override
329
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
330 44189 jjdelcerro
            Object value;
331 44153 jjdelcerro
            String where = null;
332 43987 jjdelcerro
            String order = null;
333 44153 jjdelcerro
            String expression_s = getStr(args, 0);
334
            FeatureStore store = (FeatureStore) getObject(args, 1);
335 44243 jjdelcerro
            if( store == null ) {
336
                throw new ExpressionRuntimeException("Problems calling '"+FETCH_FIRST_NAME+"' function, the store is null.");
337
            }
338 43997 jjdelcerro
            switch (args.length) {
339 44189 jjdelcerro
                case 3:
340 44153 jjdelcerro
                    where = getStr(args, 2);
341
                    break;
342 43987 jjdelcerro
                case 4:
343 44153 jjdelcerro
                    where = getStr(args, 2);
344
                    order = getStr(args, 3);
345 43987 jjdelcerro
                    break;
346
            }
347
            try {
348
                FeatureSet set;
349 44153 jjdelcerro
                if (where == null && order == null) {
350 43987 jjdelcerro
                    set = store.getFeatureSet();
351
                } else {
352
                    FeatureQuery query = store.createFeatureQuery();
353 44153 jjdelcerro
                    if (where != null) {
354
                        query.addFilter(where);
355 43987 jjdelcerro
                    }
356 43997 jjdelcerro
                    if (order != null) {
357 43987 jjdelcerro
                        query.getOrder().add(order);
358
                    }
359 44129 jjdelcerro
                    query.retrievesAllAttributes();
360 43987 jjdelcerro
                    set = store.getFeatureSet(query);
361
                }
362
                Feature feature = set.first();
363
                if (feature == null) {
364 44153 jjdelcerro
                    return null;
365 43987 jjdelcerro
                }
366 44153 jjdelcerro
                DataManager dataManager = DALLocator.getDataManager();
367
                FeatureSymbolTable symbolTable = dataManager.createFeatureSymbolTable();
368
                symbolTable.setFeature(feature);
369
370
                ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getManager();
371
                Expression expression = expManager.createExpression();
372
                expression.setPhrase(expression_s);
373
                value = expression.execute(symbolTable.createParent());
374
375
                return value;
376 43987 jjdelcerro
            } catch (Exception ex) {
377 44189 jjdelcerro
                throw new ExpressionRuntimeException("Problems calling '"+FETCH_FIRST_NAME+"' function", ex);
378 43987 jjdelcerro
            }
379
        }
380 44153 jjdelcerro
    }
381 43987 jjdelcerro
382 44153 jjdelcerro
    private class FetchFirstSelectedFunction extends AbstractFunction {
383
384
        public FetchFirstSelectedFunction() {
385 44338 jjdelcerro
            super(
386
                    PROJECT_GROUP,
387 44153 jjdelcerro
                    FETCH_FIRST_SELECTED_NAME,
388
                    Range.is(2),
389
                    "Access to the first feature of the selection.",
390
                    FETCH_FIRST_SELECTED_NAME+"({{value}}, store)",
391
                    new String[]{
392
                        "value - value to retrieve from the store, usually an expression in the columns of this are involved.",
393
                        "store - data store from which values will be collected"
394
                    },
395
                    "Object"
396
            );
397
        }
398
399
        @Override
400
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
401
            String expression_s = getStr(args, 0);
402
            FeatureStore store = (FeatureStore) getObject(args, 1);
403
            try {
404
                FeatureSet set = store.getFeatureSelection();
405
                Feature feature = set.first();
406
                if (feature == null) {
407
                    return null;
408
                }
409
                DataManager dataManager = DALLocator.getDataManager();
410
                FeatureSymbolTable symbolTable = dataManager.createFeatureSymbolTable();
411
                symbolTable.setFeature(feature);
412
413
                ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getManager();
414
                Expression expression = expManager.createExpression();
415
                expression.setPhrase(expression_s);
416
                Object value = expression.execute(symbolTable.createParent());
417
418
                return value;
419
            } catch (Exception ex) {
420 44189 jjdelcerro
                throw new ExpressionRuntimeException("Problems calling '"+FETCH_FIRST_SELECTED_NAME+"' function", ex);
421 44153 jjdelcerro
            }
422
        }
423 43987 jjdelcerro
    }
424
425
    private class ViewFunction extends AbstractFunction {
426
427
        public ViewFunction() {
428
            super(
429 44338 jjdelcerro
                    PROJECT_GROUP,
430 43987 jjdelcerro
                    "view",
431
                    Range.is(1),
432
                    "Access to the indicated view",
433
                    "view({{viewName}})",
434
                    new String[]{
435
                        "view - String value with the name of a view"
436
                    },
437
                    "DocumentView"
438
            );
439
        }
440
441
        @Override
442
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
443
            String viewName = getStr(args, 0);
444
            Project project = currentProject.get();
445
            ViewDocument view = (ViewDocument) project.getDocument(viewName, ViewManager.TYPENAME);
446
            return view;
447
        }
448
449
    }
450
451 44025 jjdelcerro
    private class ViewBBoxFunction extends AbstractFunction {
452
453
        public ViewBBoxFunction() {
454
            super(
455 44338 jjdelcerro
                    PROJECT_GROUP,
456 44025 jjdelcerro
                    "viewbbox",
457
                    Range.is(0),
458
                    "Return the BBox of the active view.",
459
                    "viewbbox()",
460
                    null,
461
                    "Geometry"
462
            );
463
        }
464
465
        @Override
466
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
467
            return currentViewEnvelope.get();
468
        }
469
470
    }
471
472 44035 jjdelcerro
473
    private class SavedPointFunction extends AbstractFunction {
474
475
        public SavedPointFunction() {
476
            super(
477 44338 jjdelcerro
                    PROJECT_GROUP,
478 44035 jjdelcerro
                    "savedpoint",
479
                    Range.is(1),
480
                    "Return the value of the saved point with the name indicated.\n"
481
                            + "If the named point do not exists return null.",
482
                    "savedpoint({{name}})",
483
                    new String[]{
484
                        "name - String value with the name of the point"
485
                    },
486
                    "Geometry"
487
            );
488
        }
489
490
        @Override
491
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
492
            TemporaryStorageManager manager = TemporaryStorageLocator.getTemporaryStorageManager();
493
            TemporaryStorageGroup storage = manager.create("Points",Point.class);
494
            Geometry value = (Geometry) storage.get(getStr(args, 0));
495
            return value;
496
        }
497
498
    }
499
500 44129 jjdelcerro
    private  class AreaFunction extends AbstractFunction {
501
502 43997 jjdelcerro
        public AreaFunction() {
503
            super(
504 44338 jjdelcerro
                    PROJECT_GROUP,
505 44129 jjdelcerro
                    AREA_NAME,
506 43999 jjdelcerro
                    Range.between(2,3),
507 43997 jjdelcerro
                    "Calculate the area of the geometry in the indicated units",
508 44129 jjdelcerro
                    AREA_NAME+"({{geometry}}, 'm?')",
509 43997 jjdelcerro
                    new String[]{
510
                        "geometry - Geometry",
511 43999 jjdelcerro
                        "Projection - Optional. Projection of the geometry or a string with the projection name",
512 43997 jjdelcerro
                        "units - String value with the name the units to use"
513
                    },
514
                    "Double"
515
            );
516
        }
517
518
        @Override
519
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
520 43999 jjdelcerro
            int units = 0;
521
            IProjection proj = null;
522 43997 jjdelcerro
            Geometry geom = getGeom(args, 0);
523 43999 jjdelcerro
            switch( args.length ) {
524
                case 2:
525 44207 jjdelcerro
                    units = getUnitsArea(args, 1);
526 43999 jjdelcerro
                    break;
527
                case 3:
528
                    proj = getProjection(args, 1);
529 44207 jjdelcerro
                    units = getUnitsArea(args, 2);
530 43999 jjdelcerro
                    break;
531
            }
532 43997 jjdelcerro
            if (proj == null) {
533
                proj = geom.getProjection();
534
            }
535
            AreaAndPerimeterCalculator calculator = new AreaAndPerimeterCalculator();
536
            double area = calculator.area(geom, proj, units);
537
            return area;
538
        }
539
    }
540
541
    private class PerimeterFunction extends AbstractFunction {
542
543
        public PerimeterFunction() {
544
            super(
545 44338 jjdelcerro
                    PROJECT_GROUP,
546 44129 jjdelcerro
                    PERIMETER_NAME,
547 43999 jjdelcerro
                    Range.between(2,3),
548 43997 jjdelcerro
                    "Calculate the perimeter of the geometry in the indicated units",
549 44129 jjdelcerro
                    PERIMETER_NAME+"({{geometry}}, 'm')",
550 43997 jjdelcerro
                    new String[]{
551
                        "geometry - Geometry",
552 43999 jjdelcerro
                        "Projection - Optional. Projection of the geometry or a string with the projection name",
553 43997 jjdelcerro
                        "units - String value with the name the units to use"
554
                    },
555
                    "Double"
556
            );
557
        }
558
559
        @Override
560
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
561 43999 jjdelcerro
            int units = 0;
562
            IProjection proj = null;
563 43997 jjdelcerro
            Geometry geom = getGeom(args, 0);
564 43999 jjdelcerro
            switch( args.length ) {
565
                case 2:
566 44207 jjdelcerro
                    units = getUnitsArea(args, 1);
567 43999 jjdelcerro
                    break;
568
                case 3:
569
                    proj = getProjection(args, 1);
570 44207 jjdelcerro
                    units = getUnitsArea(args, 2);
571 43999 jjdelcerro
                    break;
572
            }
573 43997 jjdelcerro
            if (proj == null) {
574
                proj = geom.getProjection();
575
            }
576
            AreaAndPerimeterCalculator calculator = new AreaAndPerimeterCalculator();
577
            double area = calculator.perimeter(geom, proj, units);
578
            return area;
579
        }
580
    }
581
582 43987 jjdelcerro
    private class PropertyFunction extends AbstractFunction {
583
584
        public PropertyFunction() {
585
            super(
586 44338 jjdelcerro
                    PROJECT_GROUP,
587 43987 jjdelcerro
                    "property",
588
                    Range.between(2, 3),
589
                    "Access to a property value in a properties file. If the"
590
                    + "indicated filename is not absolute, access it relative"
591
                    + "to the project.",
592
                    "property({{filename}}, name, defaultValue)",
593
                    new String[]{
594
                        "filename - String value with the name of the properties file",
595
                        "name - String value with the name of the property to retrieve from the file",
596
                        "defaultValue - Optional. Default value if can't access the file or the property",},
597
                    "String"
598
            );
599
        }
600
601
        @Override
602
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
603
            String filename = getStr(args, 0);
604
            String name = getStr(args, 1);
605
            String defaultValue = null;
606
            if (args.length == 3) {
607
                defaultValue = getStr(args, 2);
608
            }
609
610
            File file = new File(filename);
611
            if (!file.isAbsolute()) {
612
                Project project = currentProject.get();
613
                if (project.getFile() == null) {
614
                    return defaultValue;
615
                }
616
                file = new File(project.getFile().getParent(), filename);
617
            }
618
            Map<File, Properties> x = propertiesFiles.get();
619
            Properties properties = x.get(file);
620
            if (properties == null) {
621
                properties = new Properties();
622
                FileInputStream in = null;
623
                try {
624
                    in = new FileInputStream(file);
625
                    properties.load(in);
626
                } catch (Exception ex) {
627
                    return defaultValue;
628
                } finally {
629
                    IOUtils.closeQuietly(in);
630
                }
631
                x.put(file, properties);
632
            }
633
            String value = properties.getProperty(name, defaultValue);
634
            return value;
635
        }
636
637
    }
638
639
    ProjectValue currentProject = new ProjectValue();
640 44025 jjdelcerro
    CurrentViewValue currentView = new CurrentViewValue();
641
    CurrentViewEnvelopeValue currentViewEnvelope = new CurrentViewEnvelopeValue();
642 43987 jjdelcerro
    PropertiesValue propertiesFiles = new PropertiesValue();
643
644
    @SuppressWarnings("OverridableMethodCallInConstructor")
645
    public ProjectSymbolTable() {
646 44129 jjdelcerro
        super(NAME);
647 43987 jjdelcerro
        this.addFunction(new CurrentProjectFunction());
648 44153 jjdelcerro
        this.addFunction(new StoreFunction());
649 44203 jjdelcerro
        this.addFunction(new FetchFunction());
650 44153 jjdelcerro
        this.addFunction(new FetchFirstFunction());
651
        this.addFunction(new FetchFirstSelectedFunction());
652 43987 jjdelcerro
        this.addFunction(new ViewFunction());
653 44025 jjdelcerro
        this.addFunction(new ViewBBoxFunction());
654 43987 jjdelcerro
        this.addFunction(new PropertyFunction());
655 43997 jjdelcerro
        this.addFunction(new AreaFunction());
656
        this.addFunction(new PerimeterFunction());
657 44035 jjdelcerro
        this.addFunction(new SavedPointFunction());
658 44338 jjdelcerro
        this.addFunction(new ApplicationFunction());
659 43987 jjdelcerro
    }
660
661 43997 jjdelcerro
    private MapContext getMapContext(Feature feature) {
662
        FeatureStore store = feature.getStore();
663
        Project project = ProjectManager.getInstance().getCurrentProject();
664
        project.getDocuments(ViewManager.TYPENAME);
665
        for (Document document : project.getDocuments(ViewManager.TYPENAME)) {
666
            ViewDocument view = (ViewDocument) document;
667
            MapContext mapContext = view.getMapContext();
668
            FLayer layer = getLayer(mapContext, store);
669
            if (layer != null) {
670
                return mapContext;
671
            }
672
        }
673
        return null;
674
    }
675
676
    private FLayer getLayer(MapContext mapContext, FeatureStore store) {
677
        Iterator<FLayer> it = mapContext.deepiterator();
678
        while (it.hasNext()) {
679
            FLayer layer = it.next();
680
            if (layer instanceof FLyrVect) {
681
                FeatureStore layer_store = ((FLyrVect) layer).getFeatureStore();
682
                if (layer_store == store) {
683
                    return layer;
684
                }
685
            }
686
        }
687
        return null;
688
    }
689
690
    private IProjection getProjection(Object[] args, int i) {
691
        Object value = args[i];
692
        if (value == null) {
693
            return null;
694
        }
695
        if (value instanceof IProjection) {
696
            return (IProjection) value;
697
        }
698
        String code = value.toString();
699
        return CRSFactory.getCRS(code);
700
    }
701
702 44207 jjdelcerro
    private int getUnitsArea(Object[] args, int i) {
703 43997 jjdelcerro
        Object value = args[i];
704
        if (value == null) {
705
            throw new IllegalArgumentException("Illegal unit value 'null'");
706
        }
707
        if (value instanceof Number) {
708
            return ((Number) value).intValue();
709
        }
710
        String name = value.toString();
711
        String[] names = MapContext.getAreaAbbr();
712
        for (int j = 0; j < names.length; j++) {
713
            if (name.equalsIgnoreCase(names[j])) {
714
                return j;
715
            }
716
        }
717
        names = MapContext.getAreaNames();
718
        for (int j = 0; j < names.length; j++) {
719
            if (name.equalsIgnoreCase(names[j])) {
720
                return j;
721
            }
722
        }
723
        throw new IllegalArgumentException("Illegal unit name '" + name + "'");
724
    }
725
726 44207 jjdelcerro
    private int getUnitsDistance(Object[] args, int i) {
727
        Object value = args[i];
728
        if (value == null) {
729
            throw new IllegalArgumentException("Illegal unit value 'null'");
730
        }
731
        if (value instanceof Number) {
732
            return ((Number) value).intValue();
733
        }
734
        String name = value.toString();
735
        String[] names = MapContext.getDistanceAbbr();
736
        for (int j = 0; j < names.length; j++) {
737
            if (name.equalsIgnoreCase(names[j])) {
738
                return j;
739
            }
740
        }
741
        names = MapContext.getDistanceNames();
742
        for (int j = 0; j < names.length; j++) {
743
            if (name.equalsIgnoreCase(names[j])) {
744
                return j;
745
            }
746
        }
747
        throw new IllegalArgumentException("Illegal unit name '" + name + "'");
748
    }
749
750 43987 jjdelcerro
}