Statistics
| Revision:

gvsig-osm / org.gvsig.raster.osm / trunk / org.gvsig.raster.osm / org.gvsig.raster.osm.app.osmclient / src / main / java / org / gvsig / raster / osm / app / osmclient / layer / FLyrOSM.java @ 85

History | View | Annotate | Download (18.3 KB)

1
/* OSM layers for gvSIG. 
2
 * Geographic Information System of the Valencian Government
3
*
4
* Copyright (C) 2012 Nacho Brodin
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
 
23
package org.gvsig.raster.osm.app.osmclient.layer;
24

    
25
import java.awt.Dimension;
26
import java.awt.Graphics2D;
27
import java.awt.Image;
28
import java.awt.Point;
29
import java.awt.geom.Point2D;
30
import java.awt.image.BufferedImage;
31
import java.lang.ref.WeakReference;
32
import java.util.ArrayList;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.List;
36

    
37
import javax.print.attribute.PrintRequestAttributeSet;
38

    
39
import org.cresques.cts.ICoordTrans;
40
import org.gvsig.andami.PluginServices;
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataParameters;
43
import org.gvsig.fmap.dal.DataStore;
44
import org.gvsig.fmap.dal.DataStoreParameters;
45
import org.gvsig.fmap.dal.coverage.RasterLocator;
46
import org.gvsig.fmap.dal.coverage.RasterManager;
47
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
48
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
49
import org.gvsig.fmap.dal.coverage.datastruct.ViewPortData;
50
import org.gvsig.fmap.dal.coverage.exception.FilePaletteException;
51
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
52
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
53
import org.gvsig.fmap.dal.coverage.exception.QueryException;
54
import org.gvsig.fmap.dal.coverage.grid.RasterFilter;
55
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
56
import org.gvsig.fmap.dal.coverage.store.parameter.RasterDataParameters;
57
import org.gvsig.fmap.dal.coverage.store.parameter.TileDataParameters;
58
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
59
import org.gvsig.fmap.dal.exception.DataException;
60
import org.gvsig.fmap.dal.exception.InitializeException;
61
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
62
import org.gvsig.fmap.dal.exception.ReadException;
63
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
64
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
65
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
66
import org.gvsig.fmap.geom.GeometryLocator;
67
import org.gvsig.fmap.geom.GeometryManager;
68
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
69
import org.gvsig.fmap.geom.primitive.Envelope;
70
import org.gvsig.fmap.mapcontext.ViewPort;
71
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
72
import org.gvsig.fmap.mapcontext.layers.FLayer;
73
import org.gvsig.fmap.mapcontext.layers.operations.IHasImageLegend;
74
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
75
import org.gvsig.raster.fmap.layers.DefaultFLyrRaster;
76
import org.gvsig.raster.fmap.layers.IRasterLayerActions;
77
import org.gvsig.raster.fmap.layers.NotAvailableStateException;
78
import org.gvsig.raster.osm.io.OSMDataParameters;
79
import org.gvsig.raster.swing.RasterSwingLibrary;
80
import org.gvsig.raster.util.CancelTaskImpl;
81
import org.gvsig.tools.ToolsLocator;
82
import org.gvsig.tools.dynobject.DynObjectSet;
83
import org.gvsig.tools.dynobject.DynStruct;
84
import org.gvsig.tools.persistence.PersistenceManager;
85
import org.gvsig.tools.task.SimpleTaskStatus;
86
import org.gvsig.tools.task.TaskStatusManager;
87
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
89

    
90

    
91
/**
92
 * Open Street Map layer class.
93
 * @author Nacho Brodin (nachobrodin@gmail.com)
94
 */
95
public class FLyrOSM extends DefaultFLyrRaster implements IHasImageLegend {
96
        private static final GeometryManager geomManager               = GeometryLocator.getGeometryManager();
97
        private static final Logger          logger                    = LoggerFactory.getLogger(FLyrOSM.class);
98
        private List<WeakReference<Thread>>         disableUpdateDrawVersion;
99
        private boolean                                                 firstLoad                 = false;
100
        private RasterManager                rManager                  = RasterLocator.getManager();
101
        private boolean                      deleteCache               = false;
102
        
103
        public static void registerPersistent() {
104
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
105
                DynStruct definition = manager.getDefinition("FLyrOSM_Persistent");
106
                if( definition == null ) {
107
                        if (manager.getDefinition(DefaultFLyrRaster.class) == null) {
108
                                DefaultFLyrRaster.registerPersistent();
109
                        }
110

    
111
                        definition = manager.addDefinition(
112
                                        FLyrOSM.class,
113
                                        "FLyrOSM_Persistent",
114
                                        "FLyrOSM Persistent Definition",
115
                                        null, 
116
                                        null
117
                        );
118
                        
119
                        definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE, DefaultFLyrRaster.PERSISTENT_NAME);
120
                }
121
        }
122

    
123
        public FLyrOSM() {
124
                super();
125
                this.updateDrawVersion();
126
                try {
127
                        enableAwake();
128
                } catch (NotAvailableStateException e) {
129
                        logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
130
                }
131
        }
132
        
133
        public static DataStore createDataStore(String host) throws InitializeException {
134
                DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
135
                RasterDataParameters params = null;
136
                try {
137
                        params = (RasterDataParameters)dataman.createStoreParameters("OSM Raster");
138
                } catch (InitializeException e) {
139
                        RasterSwingLibrary.messageBoxInfo("error_creating_parameters", PluginServices.getMDIManager().getActiveWindow(), e);
140
                } catch (ProviderNotRegisteredException e) {
141
                        RasterSwingLibrary.messageBoxInfo("error_creating_parameters", PluginServices.getMDIManager().getActiveWindow(), e);
142
                }
143
                params.setURI(host);
144
                
145
                try {
146
                        return dataman.openStore(params.getDataStoreName(), params);
147
                } catch (ValidateDataParametersException e) {
148
                        throw new InitializeException(e);
149
                } catch (ProviderNotRegisteredException e) {
150
                        throw new InitializeException(e);
151
                }
152
        }
153

    
154
        public void setDataStore(DataStore dataStore) throws LoadLayerException {
155
                this.dataStore = (RasterDataStore) dataStore;
156
                try {
157
                        enableOpen();
158
                } catch (NotAvailableStateException e) {
159
                        logger.error("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
160
                }
161
                setProjection(this.dataStore.getProjection());
162
                //setFullExtent(this.dataStore.getExtent().toRectangle2D());
163
        }
164
        
165
        @SuppressWarnings("deprecation")
166
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
167
                         org.gvsig.tools.task.Cancellable cancel, double scale) throws ReadException {
168
                TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
169
                SimpleTaskStatus taskStatus = new RasterTaskStatus("Drawing " + getName() + "...", cancel);
170
                manager.add(taskStatus);
171
                taskStatus.setAutoremove(true);
172

    
173
                //Solo el zoom normal recalcula el nivel dependiendo de la escala. El zoom por niveles asigna
174
                //?l el nivel de zoom por lo que no habr? que recalcularlo.
175
                if(recalcLevel) {
176
                        double pixelSize = viewPort.getExtent().getWidth() / (double)viewPort.getImageWidth();
177
                        zoomLevel = dataStore.getNearestLevel(pixelSize);
178
                }
179
                recalcLevel = true;
180
                
181
                if(!firstLoad) {
182
                        try {
183
                                initFilters();
184
                                try {
185
                                        if(!isOpen())
186
                                                enableOpen();
187
                                } catch (NotAvailableStateException e) {
188
                                        throw new ReadException("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), e);
189
                                }
190
                        } catch (FilePaletteException e) {
191
                                throw new ReadException(e.getMessage(), e);
192
                        }
193
                        firstLoad = true;
194
                }
195
                
196
                enableStopped();
197

    
198
                if (isWithinScale(scale)) {
199
                        if (!viewPort.getAdjustedExtent().intersects(getFullEnvelope()))
200
                                return;
201
                        Envelope adjustedExtent = viewPort.getAdjustedEnvelope();
202
                        Extent ext = rManager.getDataStructFactory().createExtent(
203
                                        adjustedExtent.getLowerCorner().getX(),
204
                                        adjustedExtent.getUpperCorner().getY(), 
205
                                        adjustedExtent.getUpperCorner().getX(),
206
                                        adjustedExtent.getLowerCorner().getY());
207
                        Dimension imgSz = viewPort.getImageSize();
208
                        ViewPortData vp2 = rManager.getDataStructFactory().createViewPortData(viewPort.getProjection(), ext, imgSz );
209
                        vp2.setMat(viewPort.getAffineTransform());
210
                        
211
                        try {
212
                                OSMDataParameters par = getOSMParameters(getDataStore().getParameters());
213
                                par.setWidth((int)viewPort.getImageSize().getWidth());
214
                                par.setHeight((int)viewPort.getImageSize().getHeight());
215
                                
216
                                getRender().drawTiledService(g, vp2, viewPort.getImageSize(), taskStatus);
217
                        } catch (ProcessInterruptedException e) {
218
                                throw new ReadException("Problems drawing this layer: " + e.getMessage(), e);
219
                        } catch (QueryException e) {
220
                                throw new ReadException("Problems drawing this layer: " + e.getMessage(), e);
221
                        } finally {
222
                                taskStatus.terminate();
223
                        }
224
                }
225
                disableStopped();
226
        }
227
        
228

    
229
        /**
230
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
231
         *                 com.iver.cit.gvsig.fmap.ViewPort,
232
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
233
         */
234
        @SuppressWarnings("deprecation")
235
        public void print(Graphics2D g, ViewPort viewPort,  org.gvsig.tools.task.Cancellable cancel, 
236
                        double scale, PrintRequestAttributeSet properties) throws ReadException {
237
                
238
        }
239

    
240
        @SuppressWarnings("deprecation")
241
        public void _print(Graphics2D g, ViewPort viewPort,  org.gvsig.tools.task.Cancellable cancel,
242
                        double scale) throws ReadException {
243
                draw(null, g, viewPort, cancel,scale);
244
        }
245

    
246
        public HashMap<String, Object> getProperties() {
247
                HashMap<String, Object> info = new HashMap<String, Object>();
248
                OSMDataParameters par = getOSMParameters(getDataStore().getParameters());
249
                String layerName = getName();
250
                try {
251
                        info.put("selectedLayer", layerName);
252
                        info.put("host", par.getURI());
253
                        info.put("srs", dataStore.getProjection().getAbrev());
254
                        return info;
255
                } catch (Exception e) {
256
                        e.printStackTrace();
257
                }
258
                return null;
259
        }
260

    
261

    
262
        public String getTocImageIcon() {
263
                return "icon-layer-osm";
264
        }
265

    
266
        public boolean isActionEnabled(int action) {
267
                switch (action) {
268
                case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
269
                case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
270
                case IRasterLayerActions.BANDS_FILE_LIST:
271
                case IRasterLayerActions.GEOLOCATION:
272
                case IRasterLayerActions.PANSHARPENING:
273
                case IRasterLayerActions.SAVE_COLORINTERP:
274
                case IRasterLayerActions.SAVEAS:
275
                case IRasterLayerActions.BANDS_RGB:
276
                case IRasterLayerActions.CLIPPING:
277
                case IRasterLayerActions.ENHANCED:
278
                case IRasterLayerActions.STATS:
279
                case IRasterLayerActions.NODATA:
280
                case IRasterLayerActions.HISTOGRAM:
281
                        return false;
282
                case IRasterLayerActions.COLOR_TABLE:
283
                case IRasterLayerActions.REMOTE_ACTIONS:
284
                        return true;
285
                }
286

    
287
                return super.isActionEnabled(action);
288
        }
289

    
290
        public ILegend getLegend() {
291
                return null;
292
        }
293
        
294
        public boolean isRemote() {
295
                return true;
296
        }
297

    
298
        public boolean overviewsSupport() {
299
                return false;
300
        }
301

    
302
        protected void updateDrawVersion() {
303
                if (this.disableUpdateDrawVersion != null){
304

    
305
                        Thread curThread = Thread.currentThread();
306

    
307
                        Thread aThread;
308

    
309
                        Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
310
                        while (iter.hasNext()){
311
                                aThread = (Thread) ((WeakReference<?>)iter.next()).get();
312
                                if (aThread == null){
313
                                        iter.remove();
314
                                } else if(aThread.equals(curThread)){
315
                                        return;
316
                                }
317
                        }
318
                }
319
                super.updateDrawVersion();
320
        }
321

    
322
        protected void disableUpdateDrawVersion() {
323
                if (this.disableUpdateDrawVersion == null) {
324
                        this.disableUpdateDrawVersion = new ArrayList<WeakReference<Thread>>();
325
                }
326
                this.disableUpdateDrawVersion.add(new WeakReference<Thread>(Thread.currentThread()));
327
        }
328

    
329
        protected void enableUpdateDrawVersion() {
330
                if (this.disableUpdateDrawVersion == null) {
331
                        return;
332
                }
333
                Thread curThread = Thread.currentThread();
334
                Thread aThread;
335

    
336
                Iterator<WeakReference<Thread>> iter = this.disableUpdateDrawVersion.iterator();
337
                while (iter.hasNext()) {
338
                        aThread = (Thread) ((WeakReference<?>)iter.next()).get();
339
                        if (aThread == null) {
340
                                iter.remove();
341
                        } else if(aThread.equals(curThread)) {
342
                                iter.remove();
343
                                break;
344
                        }
345
                }
346

    
347
        }
348

    
349
        /*private Rectangle2D.Double getRectable2DFromEnvelope(Envelope env) {
350
                return new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env
351
                                .getLength(0), env.getLength(1));
352
        }
353

354
        private Envelope getEnvelopeFromRectable2D(Rectangle2D rect) {
355
                try {
356
                        return geomManager.createEnvelope(rect.getMinX(), rect.getMinY(),
357
                                        rect.getMaxX(), rect.getMaxY(),
358
                                        SUBTYPES.GEOM2D);
359
                } catch (CreateEnvelopeException e) {
360
                        logger.error("Error creating the envelope", e);
361
                }
362
                return null;
363
        }*/
364
        
365
        @Override
366
        public String getFileFormat() {
367
                return "OSM";
368
        }
369
        
370

    
371
        /**
372
         * Devuelve el envelope en la proyeccion de la vista
373
         */
374
        public Envelope getFullEnvelope() {
375
                Extent e1 = getDataStore().getExtent();
376
                Envelope rAux = null;
377
                try {
378
                        rAux = geomManager.createEnvelope(e1.getMin().getX(), e1.getMin().getY(), e1.getMax().getX(), e1.getMax().getY(), SUBTYPES.GEOM2D);
379
                } catch (CreateEnvelopeException exc) {
380
                        logger.error("Error creating the envelope", exc);
381
                }
382

    
383
                // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
384
                // y alto 0.
385
                if (rAux == null || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
386
                                && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
387
                        try {
388
                                rAux = geomManager.createEnvelope(0, 0, 100, 100, SUBTYPES.GEOM2D);
389
                        } catch (CreateEnvelopeException e) {
390
                                logger.error("Error creating the envelope", e);
391
                        }
392
                }
393
                // Si existe reproyecci?n, reproyectar el extent
394
                ICoordTrans ct = getCoordTrans();
395
                if (ct != null) {
396
                        Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux
397
                                        .getMinimum(1));
398
                        Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux
399
                                        .getMaximum(1));
400
                        pt1 = ct.convert(pt1, null);
401
                        pt2 = ct.convert(pt2, null);
402
                        try {
403
                                rAux = geomManager.createEnvelope(pt1.getX(), pt1.getY(), pt2
404
                                                .getX(), pt2.getY(), SUBTYPES.GEOM2D);
405
                        } catch (CreateEnvelopeException e) {
406
                                logger.error("Error creating the envelope", e);
407
                        }// new
408
                        // Rectangle2D.Double();
409
                }
410
                return rAux;
411

    
412
        }
413
        
414
        public Extent getFullRasterExtent() {
415
                Envelope env = getFullEnvelope();
416
                double minx = env.getMinimum(0);
417
                double miny = env.getMinimum(1);
418
                double maxx = env.getMaximum(0);
419
                double maxy = env.getMaximum(1);
420
                Point2D ul = new Point2D.Double(minx, maxy);
421
                Point2D ur = new Point2D.Double(maxx, maxy);
422
                Point2D ll = new Point2D.Double(minx, miny);
423
                Point2D lr = new Point2D.Double(maxx, miny);
424
                return rManager.getDataStructFactory().createExtent(ul, lr, ur, ll);
425
        }
426

    
427
    @SuppressWarnings("deprecation")
428
        public DynObjectSet getInfo(Point p, double tolerance, org.gvsig.tools.task.Cancellable cancel)
429
                throws LoadLayerException, DataException {
430
                
431
                return null;
432
        }
433
    
434
    @SuppressWarnings("deprecation")
435
        public DynObjectSet getInfo(Point p, double tolerance, org.gvsig.tools.task.Cancellable cancel, boolean fast)
436
    throws LoadLayerException, DataException {
437

    
438
            Point2D pReal = getMapContext().getViewPort().toMapPoint(p);
439
            @SuppressWarnings("unused")
440
                String fInfo = null;
441
            try {
442
                    fInfo = getDataStore().getInfoByPoint(pReal.getX(), pReal.getY(), new CancelTaskImpl(cancel));
443
            } catch (InfoByPointException e) {
444
                    throw new LoadLayerException("Error in getInfoByPoint", e);
445
            }
446
            return null;
447
            //return new DynObjectSetWMTSInfo(fInfo, type);
448
    }
449
    
450
    /**
451
     * Sets the data store parameters
452
     * @param params
453
     * @throws InitializeException
454
     */
455
    public void setParameters(DataStoreParameters params) throws InitializeException {
456
                if(params instanceof TileDataParameters) {
457
                        ((TileDataParameters)params).deleteCache(deleteCache);
458
                }
459
                
460
            DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
461
                try {
462
                        DataStore dStore = dataman.openStore(params.getDataStoreName(), params);
463
                        this.setDataStore(dStore);
464
                        
465
                        if(params instanceof OSMDataParameters) {
466
                                this.setName(((OSMDataParameters) params).getURI());
467
                        }
468
                        
469
                        if(params instanceof TileDataParameters) {
470
                                DataParameters p = ((TileDataParameters) params).getDataParameters();
471
                                if(p instanceof OSMDataParameters) {
472
                                        this.setName(((OSMDataParameters) p).getURI());
473
                                }
474
                        }
475
                        
476
                } catch (ValidateDataParametersException e) {
477
                        throw new InitializeException(e);
478
                } catch (ProviderNotRegisteredException e) {
479
                        throw new InitializeException(e);
480
                } catch (InitializeException e) {
481
                        throw new InitializeException(e);
482
                } catch (LoadLayerException e) {
483
                        throw new InitializeException(e);
484
                }
485
    }
486
    
487
    /**
488
     * Gets <code>WMTSDataParameters</code>
489
     * @param parameters
490
     * @return
491
     */
492
    private OSMDataParameters getOSMParameters(DataStoreParameters parameters) {
493
            OSMDataParameters params = null;
494
            if(parameters instanceof OSMDataParameters) {
495
                        params = (OSMDataParameters) parameters;
496
                }
497
                
498
                if(parameters instanceof TileDataParameters) {
499
                        DataParameters p = ((TileDataParameters) parameters).getDataParameters();
500
                        if(p instanceof OSMDataParameters) {
501
                                params = (OSMDataParameters) p;
502
                        }
503
                }
504
                return params;
505
    }
506

    
507
        public Image getImageLegend() {
508
                return null;
509
        }
510

    
511
        public String getPathImage() {
512
                return null;
513
        }
514
        
515
        public FLayer cloneLayer() throws Exception {
516
                RasterDataStore  ds = dataStore.cloneDataStore();
517
                FLyrOSM newLayer = new FLyrOSM();
518
                newLayer.setName(getName());
519
                newLayer.setOpenRasterStore(ds);
520
                newLayer.firstLoad = firstLoad;
521
                
522
                List<RasterFilter> filters = getRender().getFilterList().getStatusCloned();
523

    
524
                //Hacemos una copia de las bandas a renderizar
525
                ColorInterpretation ci = getRender().getRenderColorInterpretation();
526
                if(ci != null) {
527
                        newLayer.getRender().setRenderColorInterpretation(ci.cloneColorInterpretation());
528
                }
529

    
530
                //Asignamos el entorno
531
                if(newLayer.getRender().getFilterList() == null)
532
                        newLayer.getRender().setFilterList(RasterLocator.getManager().createEmptyFilterList(getRender().getFilterList().getInitDataType()));
533
                newLayer.getRender().getFilterList().setEnv(getRender().getFilterList().getEnv());
534
                newLayer.getRender().getFilterList().setStatus(filters);
535

    
536
                // Asignamos los valores noData del original
537
                NoData nd = (NoData)getNoDataValue().clone();
538
                newLayer.setNoDataValue(nd);
539
                newLayer.enableOpen();
540
                
541
                return newLayer;
542
        }
543

    
544
        /**
545
         * Assigns the flag to delete this layer from the cache
546
         * @param selected
547
         */
548
        public void deleteCache(boolean deleteCache) {
549
                this.deleteCache = deleteCache;
550
        }
551
}