Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / impl / DefaultMapContextManager.java @ 47739

History | View | Annotate | Download (43.6 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.mapcontext.impl;
24

    
25
import java.awt.Color;
26
import java.awt.Font;
27
import java.io.File;
28
import java.io.FileFilter;
29
import java.io.InputStream;
30
import java.lang.reflect.InvocationTargetException;
31
import java.lang.reflect.Method;
32
import java.net.URL;
33
import java.util.ArrayList;
34
import java.util.HashMap;
35
import java.util.Iterator;
36
import java.util.LinkedHashMap;
37
import java.util.List;
38
import java.util.Map;
39
import javax.swing.Icon;
40
import javax.swing.ImageIcon;
41
import org.apache.commons.io.IOUtils;
42
import org.apache.commons.lang3.StringUtils;
43
import org.cresques.cts.ICoordTrans;
44

    
45
import org.cresques.cts.IProjection;
46
import org.gvsig.fmap.crs.CRSFactory;
47
import org.gvsig.fmap.dal.DALLocator;
48
import org.gvsig.fmap.dal.DataFactory;
49
import org.gvsig.fmap.dal.DataManager;
50
import org.gvsig.fmap.dal.DataStore;
51
import org.gvsig.fmap.dal.DataStoreParameters;
52
import org.gvsig.fmap.dal.DataStoreProviderFactory;
53
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.feature.FeatureType;
56
import org.gvsig.fmap.dal.raster.BandDescriptor;
57
import org.gvsig.fmap.dal.raster.RasterStore;
58
import org.gvsig.fmap.geom.Geometry;
59
import org.gvsig.fmap.geom.GeometryUtils;
60
import org.gvsig.fmap.mapcontext.MapContext;
61
import org.gvsig.fmap.mapcontext.MapContextDrawer;
62
import org.gvsig.fmap.mapcontext.MapContextException;
63
import org.gvsig.fmap.mapcontext.MapContextLocator;
64
import org.gvsig.fmap.mapcontext.MapContextManager;
65
import org.gvsig.fmap.mapcontext.MapContextRuntimeException;
66
import org.gvsig.fmap.mapcontext.ViewPort;
67
import org.gvsig.fmap.mapcontext.exceptions.CantRetrieveLayerByStoreException;
68
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
69
import org.gvsig.fmap.mapcontext.layers.DefaultLayerInformationBuilder;
70
import org.gvsig.fmap.mapcontext.layers.FLayer;
71
import org.gvsig.fmap.mapcontext.layers.LayerInformationBuilder;
72
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
73
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
74
import org.gvsig.fmap.mapcontext.layers.vectorial.GraphicLayer;
75
import org.gvsig.fmap.mapcontext.layers.vectorial.impl.DefaultGraphicLayer;
76
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
77
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
78
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorialUniqueValueLegend;
79
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendReader;
80
import org.gvsig.fmap.mapcontext.rendering.legend.driver.ILegendWriter;
81
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
82
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
83
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
84
import org.gvsig.fmap.mapcontext.rendering.symbols.IWarningSymbol;
85
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolException;
86
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
87
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolPreferences;
88
import org.gvsig.raster.lib.legend.api.RasterLegend;
89
import org.gvsig.raster.lib.legend.api.RasterLegendLocator;
90
import org.gvsig.raster.lib.legend.api.RasterLegendManager;
91
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
92
import org.gvsig.tools.ToolsLocator;
93
import org.gvsig.tools.dispose.DisposeUtils;
94
import org.gvsig.tools.dynobject.DynObject;
95
import org.gvsig.tools.dynobject.exception.DynMethodException;
96
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
97
import org.gvsig.tools.folders.FoldersManager;
98
import org.gvsig.tools.observer.Notification;
99
import org.gvsig.tools.observer.ObservableHelper;
100
import org.gvsig.tools.observer.Observer;
101
import org.gvsig.tools.persistence.PersistenceManager;
102
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
103
import org.gvsig.tools.resourcesstorage.ResourcesStorage.Resource;
104
import org.gvsig.tools.swing.api.TransparencySupport;
105
import org.slf4j.Logger;
106
import org.slf4j.LoggerFactory;
107

    
108
/**
109
 * Default implementation of the {@link MapContextManager}.
110
 *
111
 */
112
@SuppressWarnings("UseSpecificCatch")
113
public class DefaultMapContextManager implements MapContextManager {
114

    
115
    private static final Logger LOGGER = LoggerFactory
116
            .getLogger(DefaultMapContextManager.class);
117

    
118
    private static final double DEFAULT_SYMBOL_TRANSPARENCY = 0.6;
119

    
120
    private Class drawerClazz = DefaultMapContextDrawer.class;
121

    
122
    private final Map<String,Class<ILegend>> legends = new HashMap();
123

    
124
    private final Map<String, Class<ILegendReader>> legendReaders = new LinkedHashMap<>();
125

    
126
    private final Map<String, Map<Class<ILegend>,Class<ILegendWriter>>> legendWriters = new LinkedHashMap<>();
127
    
128
    private final Map<Class,Class<? extends FLayer>> layerClassFromStoreClass = new HashMap<>();
129

    
130
    private final Map<String,String> iconLayers = new HashMap(); //  (Map<String storeProviderName, String iconName>)
131

    
132
    private String defaultVectorLegend;
133

    
134
    private final ObservableHelper observableHelper = new ObservableHelper();
135

    
136
    private File colorTableLibraryFolder = null;
137
    private String defaultRasterLegend;
138

    
139
    @Override
140
    public MapContext createMapContext() {
141
        MapContext mapcontext = new MapContext(new ViewPort());
142
        return (MapContext) notifyObservers(CREATE_MAPCONTEXT, mapcontext).getValue();
143
    }
144

    
145
    @Override
146
    public SymbolManager getSymbolManager() {
147
        return MapContextLocator.getSymbolManager();
148
    }
149

    
150
    private SymbolPreferences getSymbolPreferences() {
151
        return getSymbolManager().getSymbolPreferences();
152
    }
153

    
154
    @Override
155
    public String getSymbolLibraryPath() {
156
        return getSymbolPreferences().getSymbolLibraryPath();
157
    }
158

    
159
    @Override
160
    public void setSymbolLibraryPath(String symbolLibraryPath) {
161
        getSymbolPreferences().setSymbolLibraryPath(symbolLibraryPath);
162
    }
163

    
164
    @Override
165
    public void resetSymbolLibraryPath() {
166
        getSymbolPreferences().resetSymbolLibraryPath();
167
    }
168

    
169
    @Override
170
    public Color getDefaultSymbolColor() {
171
        return getSymbolPreferences().getDefaultSymbolColor();
172
    }
173

    
174
    @Override
175
    public Color getDefaultSymbolFillColor() {
176
        return getSymbolPreferences().getDefaultSymbolFillColor();
177
    }
178

    
179
    @Override
180
    public Font getDefaultSymbolFont() {
181
        return getSymbolPreferences().getDefaultSymbolFont();
182
    }
183

    
184
    public String getSymbolFileExtension() {
185
        return getSymbolPreferences().getSymbolFileExtension();
186
    }
187

    
188
    @Override
189
    public boolean isDefaultSymbolFillColorAleatory() {
190
        return getSymbolPreferences().isDefaultSymbolFillColorAleatory();
191
    }
192

    
193
    @Override
194
    public void resetDefaultSymbolColor() {
195
        getSymbolPreferences().resetDefaultSymbolColor();
196
    }
197

    
198
    @Override
199
    public void resetDefaultSymbolFillColor() {
200
        getSymbolPreferences().resetDefaultSymbolFillColor();
201
    }
202

    
203
    @Override
204
    public void resetDefaultSymbolFillColorAleatory() {
205
        getSymbolPreferences().resetDefaultSymbolFillColorAleatory();
206
    }
207

    
208
    @Override
209
    public void resetDefaultSymbolFont() {
210
        getSymbolPreferences().resetDefaultSymbolFont();
211
    }
212

    
213
    @Override
214
    public void setDefaultSymbolColor(Color defaultSymbolColor) {
215
        getSymbolPreferences().setDefaultSymbolColor(defaultSymbolColor);
216
    }
217

    
218
    @Override
219
    public void setDefaultSymbolFillColor(Color defaultSymbolFillColor) {
220
        getSymbolPreferences().setDefaultSymbolFillColor(defaultSymbolFillColor);
221
    }
222

    
223
    @Override
224
    public void setDefaultSymbolFillColorAleatory(
225
            boolean defaultSymbolFillColorAleatory) {
226
        getSymbolPreferences().setDefaultSymbolFillColorAleatory(
227
                defaultSymbolFillColorAleatory);
228
    }
229

    
230
    @Override
231
    public void setDefaultSymbolFont(Font defaultSymbolFont) {
232
        getSymbolPreferences().setDefaultSymbolFont(defaultSymbolFont);
233
    }
234

    
235
    public void setSymbolFileExtension(String extension) {
236
        getSymbolPreferences().setSymbolFileExtension(extension);
237
    }
238

    
239
    @Override
240
    public int getDefaultCartographicSupportMeasureUnit() {
241
        return getSymbolPreferences().getDefaultCartographicSupportMeasureUnit();
242
    }
243

    
244
    @Override
245
    public void setDefaultCartographicSupportMeasureUnit(
246
            int defaultCartographicSupportMeasureUnit) {
247
        getSymbolPreferences().setDefaultCartographicSupportMeasureUnit(
248
                defaultCartographicSupportMeasureUnit);
249
    }
250

    
251
    @Override
252
    public int getDefaultCartographicSupportReferenceSystem() {
253
        return getSymbolPreferences().getDefaultCartographicSupportReferenceSystem();
254
    }
255

    
256
    @Override
257
    public void setDefaultCartographicSupportReferenceSystem(
258
            int defaultCartographicSupportReferenceSystem) {
259
        getSymbolPreferences().setDefaultCartographicSupportReferenceSystem(
260
                defaultCartographicSupportReferenceSystem);
261
    }
262

    
263
    @Override
264
    public MapContextDrawer createMapContextDrawerInstance(Class drawerClazz)
265
            throws MapContextException {
266
        return createMapContextDrawerInstance(drawerClazz, "NONE");
267
    }
268

    
269
    @Override
270
    public MapContextDrawer createDefaultMapContextDrawerInstance()
271
            throws MapContextException {
272

    
273
        return createMapContextDrawerInstance(drawerClazz, "default");
274
    }
275

    
276
    private MapContextDrawer createMapContextDrawerInstance(Class drawerClazz,
277
            String name) throws RegisteredClassInstantiationException {
278
        try {
279
            MapContextDrawer drawer = (MapContextDrawer) drawerClazz.newInstance();
280
            notifyObservers(CREATE_MAPCONTEXT_DRAWER, drawer);
281
            return drawer;
282
        } catch (Exception ex) {
283
            throw new RegisteredClassInstantiationException(
284
                    MapContextDrawer.class, drawerClazz, name, ex);
285
        }
286
    }
287

    
288
    @Override
289
    public void setDefaultMapContextDrawer(Class drawerClazz)
290
            throws MapContextException {
291

    
292
        validateMapContextDrawer(drawerClazz);
293
        this.drawerClazz = drawerClazz;
294
        notifyObservers(SET_MAPCONTEXT_DRAWER, drawerClazz);
295
    }
296

    
297
    @Override
298
    public void validateMapContextDrawer(Class drawerClazz)
299
            throws MapContextException {
300
        if (!MapContextDrawer.class.isAssignableFrom(drawerClazz)) {
301
            throw new InvalidRegisteredClassException(MapContextDrawer.class,
302
                    drawerClazz, "UNKNOWN");
303
        }
304
    }
305

    
306
    @Override
307
    public GraphicLayer createGraphicsLayer(IProjection projection) {
308
        DefaultGraphicLayer layer = new DefaultGraphicLayer();
309
        try {
310
            layer.initialize(projection);
311
            layer.setLegend((IVectorLegend) createLegend(IVectorialUniqueValueLegend.LEGEND_NAME));
312
        } catch (Exception e) {
313
            LOGGER.error("Error initializing the graphics layer", e);
314
        }
315
        return (GraphicLayer) notifyObservers(CREATE_GRAPHICS_LAYER, layer).getValue();
316
    }
317

    
318
    @Override
319
    public String getDefaultVectorLegend() {
320
        return defaultVectorLegend;
321
    }
322

    
323
    @Override
324
    public void setDefaultVectorLegend(String defaultVectorLegend) {
325
        this.defaultVectorLegend = defaultVectorLegend;
326
    }
327

    
328
    @Override
329
    public String getDefaultRasterLegend() {
330
        return defaultRasterLegend;
331
    }
332

    
333
    @Override
334
    public void setDefaultRasterLegend(String defaultRasterLegend) {
335
        this.defaultRasterLegend = defaultRasterLegend;
336
    }
337
    
338
    @Override
339
    public void registerLegend(String legendName, Class legendClass)
340
            throws MapContextRuntimeException {
341

    
342
        if (legendClass == null || !ILegend.class.isAssignableFrom(legendClass)) {
343
            throw new InvalidRegisteredClassException(ILegend.class,
344
                    legendClass, legendName);
345
        }
346

    
347
        legends.put(legendName, legendClass);
348
        notifyObservers(REGISTER_LEGEND, legendName, legendClass);
349
    }
350

    
351
    @Override
352
    public ILegend createLegend(String legendName)
353
            throws MapContextRuntimeException {
354
        Class legendClass = (Class) legends.get(legendName);
355

    
356
        if (legendClass != null) {
357
            try {
358
                ILegend legend = (ILegend) legendClass.newInstance();
359
                return (ILegend) notifyObservers(CREATE_LEGEND, legend).getValue();
360
            } catch (InstantiationException | IllegalAccessException e) {
361
                throw new RegisteredClassInstantiationException(ILegend.class,
362
                        legendClass, legendName, e);
363
            }
364
        }
365
        return null;
366
    }
367

    
368
    @Override
369
    public IVectorLegend createDefaultVectorLegend(int shapeType)
370
            throws MapContextRuntimeException {
371
        try {
372
            // Create legend
373
            IVectorLegend legend
374
                    = (IVectorLegend) createLegend(getDefaultVectorLegend());
375
            if (legend == null) {
376
                return null;
377
            }
378
            // Set legend values
379
            legend.setShapeType(shapeType);
380
            ISymbol symbol = getSymbolManager().createSymbol(shapeType);
381
            if (symbol == null) {
382
                String msg = "Can't create a legend for the shape type " + shapeType + ". The type can be incorrect or there is not registered a symbol by default for that value. If this a was obtained from the store settings, review your FeatureType have correctly configured this value.";
383
                throw new RuntimeException(msg);
384
            } 
385
            if( symbol instanceof TransparencySupport && (
386
                    GeometryUtils.isSubtype(Geometry.TYPES.SURFACE,shapeType) ||
387
                    GeometryUtils.isSubtype(Geometry.TYPES.MULTISURFACE,shapeType) )
388
                ) {
389
                ((TransparencySupport)symbol).setTransparency(DEFAULT_SYMBOL_TRANSPARENCY);
390
            }
391
            legend.setDefaultSymbol(symbol);
392
            return legend;
393
        } catch (Exception e) {
394
            throw new MapContextRuntimeException(e);
395
        }
396
    }
397

    
398
    @Override
399
    public RasterLegend createDefaultRasterLegend(List<BandDescriptor> bands)
400
            throws MapContextRuntimeException {
401
        try {
402
            // Create legend
403
            RasterLegend legend = (RasterLegend) createLegend(getDefaultRasterLegend());
404
            if (legend == null) {
405
                return null;
406
            }
407
            ColorInterpretation colorInterpretation;
408
            RasterLegendManager legendManager = RasterLegendLocator.getRasterLegendManager();
409
            switch (bands.size()) {
410
                case 3:
411
                    colorInterpretation = legendManager.createColorInterpretation(ColorInterpretation.RGB);
412
                    break;
413
                case 4:
414
                    colorInterpretation = legendManager.createColorInterpretation(ColorInterpretation.ARGB);
415
                    break;
416
                default:
417
                    String[] colorBands = new String[bands.size()];
418
                    colorBands[0] = ColorInterpretation.GRAY_BAND;
419
                    for (int i = 1; i < colorBands.length; i++) {
420
                        colorBands[i] = ColorInterpretation.UNDEFINED_BAND;
421
                    }   colorInterpretation = legendManager.createColorInterpretation(colorBands);
422
                    break;
423
            }
424
            legend.setColorInterpretation(colorInterpretation);
425
            legend.addLinearStretchEnhancementOperationIfNeeded(colorInterpretation, bands, 0);
426
            return legend;
427
        } catch (Exception e) {
428
            throw new MapContextRuntimeException(e);
429
        }
430
    }
431

    
432
    // =============================================================
433
    // Legend reading/writing
434

    
435
    private Map<Class<ILegend>,Class<ILegendWriter>> getLegendWritersForFormat(String format) {
436
        synchronized(legendWriters) {
437
            return legendWriters.get(format);
438
        }
439
    }
440

    
441
    private Class<ILegendReader> getLegendReaderForFormat(String format) {
442
        synchronized(legendReaders) {
443
            return legendReaders.get(format);
444
        }
445
    }
446

    
447
    @Override
448
    public List<String> getLegendReadingFormats() {
449
        synchronized(legendReaders) {
450
            List<String> resp = new ArrayList();
451
            resp.addAll(legendReaders.keySet());
452
            return resp;
453
        }
454
    }
455

    
456
    @Override
457
    public List<String> getLegendWritingFormats() {
458
        synchronized(legendWriters) {
459
            List<String> resp = new ArrayList();
460
            resp.addAll(legendWriters.keySet());
461
            return resp;
462
        }
463
    }
464
    
465
    @Override
466
    public void registerLegendReader(String format, Class readerClass)
467
            throws MapContextRuntimeException {
468
        if (readerClass == null
469
                || !ILegendReader.class.isAssignableFrom(readerClass)) {
470
            throw new InvalidRegisteredClassException(ILegendReader.class,
471
                    readerClass, format);
472
        }
473
        synchronized (legendReaders) {
474
            legendReaders.put(format, readerClass);
475
        }
476
        notifyObservers(REGISTER_LEGEND_READER, format, readerClass);
477
    }
478

    
479
    @Override
480
    public void registerLegendWriter(Class legendClass, String format,
481
            Class writerClass) throws MapContextRuntimeException {
482
        if (writerClass == null || legendClass == null
483
                || !ILegendWriter.class.isAssignableFrom(writerClass)
484
                || !ILegend.class.isAssignableFrom(legendClass)) {
485

    
486
            throw new InvalidRegisteredClassException(ILegendWriter.class,
487
                    writerClass, format.concat("-").concat(
488
                            legendClass == null ? "Null" : legendClass.getName()));
489
        }
490

    
491
        synchronized (legendWriters) {
492
            Map<Class<ILegend>, Class<ILegendWriter>> legendWriterOfFormat = legendWriters.get(format);
493
            if (legendWriterOfFormat == null) {
494
                legendWriterOfFormat = new LinkedHashMap();
495
                legendWriters.put(format, legendWriterOfFormat);
496
            }
497
            legendWriterOfFormat.put(legendClass, writerClass);
498
        }
499
        notifyObservers(REGISTER_LEGEND_WRITER, format, writerClass);
500
    }
501

    
502
    @Override
503
    public ILegendReader createLegendReader(String format)
504
            throws MapContextRuntimeException {
505
        Class<ILegendReader> legendReaderClazz = getLegendReaderForFormat(format);
506

    
507
        if (legendReaderClazz != null) {
508
            try {
509
                ILegendReader reader = (ILegendReader) legendReaderClazz.newInstance();
510
                return (ILegendReader) notifyObservers(CREATE_LEGEND_READER, reader).getValue();
511
            } catch (InstantiationException|IllegalAccessException e) {
512
                throw new RegisteredClassInstantiationException(
513
                        ILegendReader.class, legendReaderClazz, format, e);
514
            }
515
        }
516
        return null;
517
    }
518

    
519
    @Override
520
    public ILegendWriter createLegendWriter(Class legendClass, String format)
521
            throws MapContextRuntimeException {
522

    
523
        if (legendClass == null || format == null) {
524
            return null;
525
        }
526

    
527
        Map<Class<ILegend>, Class<ILegendWriter>> legendFormatWriters = getLegendWritersForFormat(format);
528

    
529
        if (legendFormatWriters != null) {
530
            Class<ILegendWriter> legendWriterClazz = legendFormatWriters.get(legendClass);
531
            if (legendWriterClazz != null) {
532
                /*
533
                 * Found exact match
534
                 */
535
                try {
536
                    ILegendWriter writer = (ILegendWriter) legendWriterClazz.newInstance();
537
                    return (ILegendWriter) notifyObservers(CREATE_LEGEND_READER, writer).getValue();
538
                } catch (InstantiationException|IllegalAccessException e) {
539
                    throw new RegisteredClassInstantiationException(
540
                            ILegendWriter.class, 
541
                            legendWriterClazz,
542
                            format.concat("-").concat(legendClass.getName()), 
543
                            e
544
                    );
545
                }
546
            } else {
547
                /*
548
                 * Trying to find superclass/superinterface of parameter
549
                 */
550
                try {
551
                    return getSuperClassLegendWriter(legendFormatWriters, legendClass);
552
                } catch (Exception exc) {
553
                    throw new MapContextRuntimeException(exc);
554
                }
555
            }
556
        }
557
        return null;
558
    }
559

    
560
    private ILegendWriter getSuperClassLegendWriter(Map<Class<ILegend>, Class<ILegendWriter>> clsToWtr, Class<ILegend> legclass)
561
            throws Exception {
562

    
563
        Iterator kiter = clsToWtr.keySet().iterator();
564
        Object oitem;
565
        Class<ILegendWriter> citem;
566
        while (kiter.hasNext()) {
567
            oitem = kiter.next();
568
            if (oitem instanceof Class) {
569
                citem = (Class) oitem;
570
                if (citem.isAssignableFrom(legclass)) {
571
                    /*
572
                     * Found superclass/superinterface
573
                     */
574
                    citem = clsToWtr.get(oitem);
575
                    return (ILegendWriter) citem.newInstance();
576
                }
577
            }
578
        }
579
        /*
580
         * No superclass/superinterface found
581
         */
582
        return null;
583
    }
584

    
585
    // =============================================================
586

    
587
    @Override
588
    public IMultiLayerSymbol createMultiLayerSymbol(int shapeType)
589
            throws MapContextRuntimeException {
590
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(shapeType);
591
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
592
    }
593

    
594
    @Override
595
    public IMultiLayerSymbol createMultiLayerSymbol(String symbolName)
596
            throws MapContextRuntimeException {
597
        IMultiLayerSymbol symbol = getSymbolManager().createMultiLayerSymbol(symbolName);
598
        return (IMultiLayerSymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
599
    }
600

    
601
    @Override
602
    public ISymbol createSymbol(int shapeType, Color color)
603
            throws MapContextRuntimeException {
604
        ISymbol symbol = getSymbolManager().createSymbol(shapeType, color);
605
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
606
    }
607

    
608
    @Override
609
    public ISymbol createSymbol(int shapeType)
610
            throws MapContextRuntimeException {
611
        ISymbol symbol = getSymbolManager().createSymbol(shapeType);
612
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
613
    }
614

    
615
    @Override
616
    public ISymbol createSymbol(String symbolName, Color color)
617
            throws MapContextRuntimeException {
618
        ISymbol symbol = getSymbolManager().createSymbol(symbolName, color);
619
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
620
    }
621

    
622
    @Override
623
    public ISymbol createSymbol(String symbolName)
624
            throws MapContextRuntimeException {
625
        ISymbol symbol = getSymbolManager().createSymbol(symbolName);
626
        return (ISymbol) notifyObservers(CREATE_SYMBOL, symbol).getValue();
627
    }
628

    
629
    @Override
630
    public IWarningSymbol getWarningSymbol(String message, String symbolDesc,
631
            int symbolDrawExceptionType) throws MapContextRuntimeException {
632
        return getSymbolManager().getWarningSymbol(message, symbolDesc,
633
                symbolDrawExceptionType);
634
    }
635

    
636
    public ISymbol[] loadSymbols(File folder, FileFilter filter)
637
            throws SymbolException {
638
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder, filter);
639
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
640
    }
641

    
642
    public ISymbol[] loadSymbols(File folder) throws SymbolException {
643
        ISymbol[] symbols = getSymbolManager().loadSymbols(folder);
644
        return (ISymbol[]) notifyObservers(LOAD_SYMBOLS, symbols).getValue();
645
    }
646

    
647
    @Override
648
    public void registerMultiLayerSymbol(String symbolName, Class symbolClass)
649
            throws MapContextRuntimeException {
650
        getSymbolManager().registerMultiLayerSymbol(symbolName, symbolClass);
651
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass);
652
    }
653

    
654
    @Override
655
    public void registerMultiLayerSymbol(String symbolName, int[] shapeTypes,
656
            Class symbolClass) throws MapContextRuntimeException {
657
        getSymbolManager().registerMultiLayerSymbol(symbolName, shapeTypes,
658
                symbolClass);
659
        notifyObservers(REGISTER_MULTILAYER_SYMBOL, symbolName, symbolClass, shapeTypes);
660
    }
661

    
662
    @Override
663
    public void registerSymbol(String symbolName, Class symbolClass)
664
            throws MapContextRuntimeException {
665
        getSymbolManager().registerSymbol(symbolName, symbolClass);
666
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass);
667
    }
668

    
669
    @Override
670
    public void registerSymbol(String symbolName, int[] shapeTypes,
671
            Class symbolClass) throws MapContextException {
672
        getSymbolManager().registerSymbol(symbolName, shapeTypes, symbolClass);
673
        notifyObservers(REGISTER_SYMBOL, symbolName, symbolClass, shapeTypes);
674
    }
675

    
676
    public void saveSymbol(ISymbol symbol, String fileName, File folder,
677
            boolean overwrite) throws SymbolException {
678
        getSymbolManager().saveSymbol(symbol, fileName, folder, overwrite);
679
    }
680

    
681
    public void saveSymbol(ISymbol symbol, String fileName, File folder)
682
            throws SymbolException {
683
        getSymbolManager().saveSymbol(symbol, fileName, folder);
684
    }
685

    
686
    @Override
687
    public boolean registerLayer(
688
        Class theClass,
689
        Class<? extends FLayer> layerClass) 
690
    {
691
        this.layerClassFromStoreClass.put(theClass, layerClass);
692
        return true;
693
    }    
694
    
695
    private Class<? extends FLayer> getLayerClass(
696
            Class keyClass) {
697
        Class<? extends FLayer> layerClass = this.layerClassFromStoreClass.get(keyClass);
698
        if( layerClass!=null ) {
699
            return layerClass;
700
        }
701
        for (Map.Entry<Class, Class<? extends FLayer>> entry : layerClassFromStoreClass.entrySet()) {
702
            Class  currentKeyClass = entry.getKey();
703
            layerClass = entry.getValue();
704
            if( currentKeyClass.isAssignableFrom(keyClass) ) {
705
                return layerClass;
706
            }
707
        }
708
        return null;
709
    }
710
    
711
    @Override
712
    public FLayer createLayer(String layerName, DataStoreParameters dataParameters)
713
            throws LoadLayerException {
714
        try {
715
            DataManager dataManager = DALLocator.getDataManager();
716
            DataStore dataStore = dataManager.openStore(
717
                    dataParameters.getDataStoreName(), 
718
                    dataParameters
719
            );
720
            return this.createLayer(layerName, dataStore, null);
721
        } catch (Exception e) {
722
            throw new LoadLayerException(layerName, e);
723
        }
724
    }
725

    
726
    @Override
727
    public FLayer createLayer(String layerName, DataStore dataStore)
728
            throws LoadLayerException {
729
        return this.createLayer(layerName, dataStore, null);
730
    }
731

    
732

    
733
    @Override
734
    public FLayer createLayer(String layerName, CreateLayerParameters parameters) throws LoadLayerException {
735
        try {
736
            DataManager dataManager = DALLocator.getDataManager();
737
            DataStoreParameters dataParameters = parameters.getDataParameters();
738
            DataFactory sf = dataManager.getStoreFactory(dataParameters);
739
            
740
            if( sf==null 
741
                    || !StringUtils.equalsIgnoreCase(sf.getName(), "FeatureStore") 
742
                    || parameters.getCoordTrans()!=null 
743
                    || parameters.useCache() 
744
                    || parameters.isVisible()
745
                ) {
746
                DataStore dataStore = dataManager.openStore(
747
                        dataParameters.getProviderName(), 
748
                        dataParameters
749
                );
750
                return this.createLayer(layerName, dataStore, parameters);
751
            }
752
            Class<? extends FLayer> layerClass = this.getLayerClass(FeatureStore.class);
753
            if (layerClass == null) {
754
                throw new CantRetrieveLayerByStoreException(layerName, FeatureStore.class.getName());
755
            }
756
            FLayer layer;
757
            try {
758
                layer = (FLayer) layerClass.newInstance();
759
            } catch (InstantiationException | IllegalAccessException e) {
760
                throw new LoadLayerException(layerName, e);
761
            }
762

    
763
            layer.setName(layerName);
764
            layer.setVisible(false);
765
            ((FLyrVect) layer).setDataStoreParameters(dataParameters);
766
            layer.load();
767
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
768
            
769
        } catch (Exception e) {
770
            throw new LoadLayerException(layerName, e);
771
        }
772
    }    
773
    
774
    @Override
775
    public FLayer createLayer(String layerName, DataStore dataStore, CreateLayerParameters parameters) throws LoadLayerException {
776
        try {
777
            boolean useCache = false;
778
            ICoordTrans coordTrans = null;
779
            IProjection projection = (IProjection) dataStore.getDynValue(FeatureStore.METADATA_CRS);
780
            
781
            if( parameters!=null ) {
782
                if( parameters.getDataParameters()!=dataStore.getParameters() ) {
783
                    throw new IllegalArgumentException("The dataStore parameters are not the same of the store pased to create layer.");
784
                }
785
                useCache = parameters.useCache();
786
                
787
                coordTrans = parameters.getCoordTrans();
788
                // TODO: Aqui comprobacion de que si hay transformacion es adecuada
789
                // para la proyeccion del store.
790
            }
791
            
792
            if( useCache ) {
793
                DataStoreProviderFactory factory = dataStore.getProviderFactory();
794
                if( factory.isTiledSupported() != DataStoreProviderFactory.NO ) {
795
                    if( !factory.getClass().getSimpleName().equals("TileProviderFactory")) {
796
                        DataManager dataManager = DALLocator.getDataManager();
797
                        DynObject tileParameters = dataManager.createStoreParameters("TileCache");
798
                        File cacheFolder;
799
                        FoldersManager folderManager = ToolsLocator.getFoldersManager();
800
                        File applicationHome = folderManager.get("ApplicationHome");
801
                        if( applicationHome==null ) {
802
                            cacheFolder = folderManager.getTemporaryFile("gvsig_rcache");
803
                        } else {
804
                            cacheFolder = new File(applicationHome, "gvsig_rcache");
805
                        }
806
                        if (tileParameters.getDynClass().getDynField("rootFolder") != null) {
807
                            tileParameters.setDynValue("rootFolder", cacheFolder);
808
                        }
809
                        try {
810
                            dataStore.useCache("TileCache", tileParameters);
811
                        } catch (DataException e) {
812
                            LOGGER.warn("Can't cache the layer.", e);
813
                        }
814
                    }
815
                }
816
            }
817
            
818
            Class<? extends FLayer> layerClass = this.getLayerClass(dataStore.getParameters().getClass());
819
            if (layerClass == null) {
820
                layerClass = this.getLayerClass(dataStore.getProviderFactory().getClass());
821
                if (layerClass == null) {
822
                    layerClass = this.getLayerClass(dataStore.getClass());
823
                }
824
                if (layerClass == null) {
825
                    throw new CantRetrieveLayerByStoreException(layerName, dataStore.getName());
826
                }
827
            }
828
            FLayer layer;
829
            try {
830
                layer = (FLayer) layerClass.newInstance();
831
            } catch (InstantiationException | IllegalAccessException e) {
832
                throw new LoadLayerException(layerName, e);
833
            }
834

    
835
            layer.setName(layerName);
836
            ((SingleLayer) layer).setDataStore(dataStore);
837
            if (projection != null) {
838
                layer.setProjection(projection);
839
                if( coordTrans != null ) {
840
                    layer.setCoordTrans(coordTrans);
841
                }
842
            }
843
            layer.load();
844
            return (FLayer) notifyObservers(CREATE_LAYER, layer).getValue();
845
        } catch (Exception e) {
846
            throw new LoadLayerException(layerName, e);
847
        }
848
    }
849

    
850
    @Override
851
    public ILegend getLegend(DataStore dataStore) {
852
        ILegend legend = null;
853
        ResourcesStorage resourcesStorage = null;
854
        try {
855
            resourcesStorage = dataStore.getResourcesStorage();
856
            if( resourcesStorage!=null ) {
857
                Resource resource = resourcesStorage.getResource(SymbolManager.LEGEND_FILE_EXTENSION.substring(1));
858
                try {
859
                    if ((resource != null) && (resource.exists())) {
860
                        PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
861
                        InputStream is = resource.asInputStream();
862
                        legend = (ILegend) persistenceManager.getObject(is);
863
                        is.close();
864
                    }
865
                } catch (Exception e) {
866
                    LOGGER.warn("Can't loasd legend", e);
867
                } finally {
868
                    IOUtils.closeQuietly(resource);
869
                }
870
            }
871
        } finally {
872
            DisposeUtils.disposeQuietly(resourcesStorage);
873
        }
874
        //If the legend is null, next option is to check if the store has the getLegend method
875
        if (legend == null) {
876
            try {
877
                legend = (ILegend) dataStore.invokeDynMethod("getLegend", null);
878
            } catch (DynMethodNotSupportedException e) {
879
                LOGGER.debug("This store {} does not provide a legend.",
880
                        dataStore.getName());
881
            } catch (DynMethodException e) {
882
                LOGGER.warn(
883
                        "Can't load the specific legend provided for the store {}.",
884
                        dataStore.getName(), e);
885
            }
886
        }
887

    
888
        //If legend is null, last step is just try to create the legend by default
889
        if (legend == null) {
890
            if( dataStore instanceof FeatureStore ) {
891
                FeatureType featureType;
892
                try {
893
                    featureType = (((FeatureStore) dataStore).getDefaultFeatureType());
894
                    int indexGeom = featureType.getDefaultGeometryAttributeIndex();
895
                    if (indexGeom < 0) {
896
                        throw new IllegalArgumentException("The layer don't has a geometry column.");
897
                    }
898
                    int typeShape = featureType.getAttributeDescriptor(indexGeom).getGeometryType();
899
                    legend = createDefaultVectorLegend(typeShape);
900
                } catch (DataException e) {
901
                    LOGGER.warn("Error getting the default feature type", e);
902
                }
903
                
904
            } else if( dataStore instanceof RasterStore ) {
905
                RasterStore rasterStore = (RasterStore) dataStore;
906
                List<BandDescriptor> bands = rasterStore.getBandDescriptors();
907
                legend = createDefaultRasterLegend(bands);
908
            }
909
        }
910

    
911
        if( legend instanceof RasterLegend ) {
912
            RasterLegend rasterLegend = (RasterLegend) legend;
913
            RasterStore rasterStore = (RasterStore) dataStore;
914
            ColorInterpretation colorInterpretation = rasterLegend.getColorInterpretation();
915
            if (colorInterpretation.isPalette()) {
916
                rasterLegend.addColorTableOperation(colorInterpretation, 0);
917
            } else {
918
                rasterLegend.addLinearStretchEnhancementOperationIfNeeded(
919
                        colorInterpretation, 
920
                        rasterStore.getBandDescriptors(), 
921
                        0);
922
            }
923
            if (colorInterpretation.hasAnyHSLBand()) {
924
                rasterLegend.addHSLToRGBOperation(colorInterpretation);
925
            } else if (colorInterpretation.hasAnyCMYKBand()) {
926
                rasterLegend.addCMYKToRGBOperation(colorInterpretation);
927
            } else if (colorInterpretation.hasAnyYCBCRBand()) {
928
              //TODO: Not implemented yet, meanwhile do nothing
929
    //                legend.addYCBCRToRGBOperation(colorInterpretation);
930
            }        
931
        }
932
        return legend;
933
    }
934

    
935
    @Override
936
    public ILabelingStrategy getLabelingStrategy(DataStore dataStore) {
937
        ILabelingStrategy labelingStrategy = null;
938

    
939
        ResourcesStorage resourcesStorage = dataStore.getResourcesStorage();
940
        if( resourcesStorage!=null ) {
941
            Resource resource = resourcesStorage.getResource(SymbolManager.LABELINGSTRATEGY_FILE_EXTENSION.substring(1));
942
            try {
943
                if ((resource != null) && (resource.exists())) {
944
                    PersistenceManager persistenceManager = ToolsLocator.getPersistenceManager();
945
                    InputStream is = resource.asInputStream();
946
                    labelingStrategy = (ILabelingStrategy) persistenceManager.getObject(is);
947
                    is.close();
948
                }
949
            } catch (Exception e) {
950
                LOGGER.warn("Can't load Label strategy", e);
951
            } finally {
952
                IOUtils.closeQuietly(resource);
953
            }
954
        }
955

    
956
        //If the legend is null, next option is to check if the store has the getLabeling method
957
        if (labelingStrategy == null) {
958
            try {
959
                labelingStrategy
960
                        = (ILabelingStrategy) dataStore.invokeDynMethod("getLabeling",
961
                                null);
962
            } catch (DynMethodNotSupportedException e1) {
963
                labelingStrategy = null;
964
            } catch (DynMethodException e1) {
965
                LOGGER.error("Can't load the specific labeling strategy provided for the datastore {}.",
966
                        dataStore.getName(),
967
                        e1);
968
            }
969
        }
970

    
971
        return labelingStrategy;
972
    }
973

    
974
    private Object call(Object instance, String methodName, Class[] signature, Object[] params) {
975
        try {
976
            Method method = instance.getClass().getMethod(methodName, signature);
977
            if (method == null) {
978
                return null;
979
            }
980
            Object value = method.invoke(instance, params);
981
            return value;
982
        } catch (Exception ex) {
983
            return null;
984
        }
985
    }
986

    
987
    @Override
988
    public void registerIconLayer(String storeProviderName, String iconName) {
989
        if (storeProviderName == null || iconName == null) {
990
            LOGGER.info("registerIconLayer, storeProviderName or iconName are null");
991
            return;
992
        }
993
        String storeName = storeProviderName.trim().toLowerCase();
994
        if (storeName.length() == 0 || iconName.trim().length() == 0) {
995
            LOGGER.info("registerIconLayer, invalid storeProviderName or iconName");
996
            return;
997
        }
998
        iconLayers.put(storeName, iconName);
999
        notifyObservers(REGISTER_ICON_LAYER, storeName, iconName);
1000
    }
1001

    
1002
        @Override
1003
    public String getIconLayer(DataStore store) {
1004
        try {
1005
            return this.getIconLayer(store.getProviderName());
1006
        } catch (Throwable th){
1007
            return "layer-icon";
1008
        }
1009
    }
1010

    
1011
    @Override
1012
    public String getIconLayer(String providerName) {
1013
                String name = null;
1014
                try {
1015
                        name = (String) iconLayers.get(providerName.trim().toLowerCase());
1016
                } catch(Throwable th) {
1017
                        // Do nothing
1018
                }
1019
                if( StringUtils.isEmpty(name) ) {
1020
                        name = "layer-icon";
1021
                }
1022
        return name;
1023
    }
1024

    
1025
    /* (non-Javadoc)
1026
     * @see org.gvsig.fmap.mapcontext.MapContextManager#getDefaultCRS()
1027
     */
1028
    @Override
1029
    public IProjection getDefaultCRS() {
1030
        IProjection crs = CRSFactory.getCRS("EPSG:4326");
1031
        return (IProjection) notifyObservers(GET_DEFAULT_CRS, crs).getValue();
1032
    }
1033

    
1034
    public Notification notifyLoadMapContext(MapContext mapContext) {
1035
        return this.observableHelper.notifyObservers(this, LOAD_MAPCONTEXT, mapContext);
1036
    }
1037

    
1038
    public Notification notifyLoadLayer(FLayer layer) {
1039
        return this.observableHelper.notifyObservers(this, LOAD_LAYER, layer);
1040
    }
1041

    
1042
    @Override
1043
    public void addObserver(Observer o) {
1044
        this.observableHelper.addObserver(o);
1045
    }
1046

    
1047
    @Override
1048
    public void deleteObserver(Observer o) {
1049
        this.observableHelper.deleteObserver(o);
1050
    }
1051

    
1052
    @Override
1053
    public void deleteObservers() {
1054
        this.observableHelper.deleteObservers();
1055
    }
1056

    
1057
    protected Notification notifyObservers(String type, Object value) {
1058
        return this.observableHelper.notifyObservers(this, type, value);
1059
    }
1060

    
1061
    protected Notification notifyObservers(String type, Object value1, Object value2) {
1062
        return this.observableHelper.notifyObservers(this, type, value1, value2);
1063
    }
1064

    
1065
    protected Notification notifyObservers(String type, Object value1, Object value2, Object value3) {
1066
        return this.observableHelper.notifyObservers(this, type, value1, value2, value3);
1067
    }
1068

    
1069
    @Override
1070
    public File getColorTableLibraryFolder() {
1071
        if (this.colorTableLibraryFolder == null) {
1072
            // Provide a default value to the location for the color
1073
            // table library.
1074
            String colorTableLibraryPath = System.getProperty("user.home")
1075
                    + File.separator
1076
                    + "gvSIG"
1077
                    + File.separator
1078
                    + "colortable";
1079
            this.colorTableLibraryFolder = new File(colorTableLibraryPath);
1080
        }
1081
        return this.colorTableLibraryFolder;
1082
    }
1083

    
1084
    @Override
1085
    public void setColorTableLibraryFolder(File colorTableLibraryFolder) {
1086
        this.colorTableLibraryFolder = colorTableLibraryFolder;
1087
    }
1088

    
1089
    @Override
1090
    public LayerInformationBuilder createLayerInformationBuilder() {
1091
        return new DefaultLayerInformationBuilder();
1092
    }
1093

    
1094
    @Override
1095
    public Icon getIcon(int geometryType, boolean withSelection) {
1096
        try {
1097
            String name;
1098
            switch (geometryType) {
1099
                case Geometry.TYPES.LINE:
1100
                    name = "layer-type-line";
1101
                    break;
1102
                case Geometry.TYPES.POINT:
1103
                    name = "layer-type-point";
1104
                    break;
1105
                case Geometry.TYPES.POLYGON:
1106
                    name = "layer-type-polygon";
1107
                    break;
1108
                case Geometry.TYPES.MULTILINE:
1109
                    name = "layer-type-multiline";
1110
                    break;
1111
                case Geometry.TYPES.MULTIPOINT:
1112
                    name = "layer-type-multipoint";
1113
                    break;
1114
                case Geometry.TYPES.MULTIPOLYGON:
1115
                    name = "layer-type-multipolygon";
1116
                    break;
1117
                case Geometry.TYPES.GEOMETRY:
1118
                    name = "layer-type-mix";
1119
                    break;
1120
                default:
1121
                    return null;
1122
            }
1123
            if (withSelection) {
1124
                name = name + "-sel";
1125
            }
1126
            name = name + ".png";
1127
            URL url = this.getClass().getResource("/layertypes/" + name);
1128
            if (url == null) {
1129
                return null;
1130
            }
1131
            Icon icon = new ImageIcon(url);
1132
            return icon;
1133
        } catch (Exception ex) {
1134
            return null;
1135
        }
1136
    }
1137

    
1138
}