Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.arcims.feature.extension / src / main / java / org / gvsig / arcims / feature / fmap / layers / FFeatureLyrArcIMSCollection.java @ 32443

History | View | Annotate | Download (18.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *   Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *   +34 963862235
28
 *   gvsig@gva.es
29
 *   www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Prodevelop Integraci?n de Tecnolog?as SL
34
 *   Conde Salvatierra de ?lava , 34-10
35
 *   46004 Valencia
36
 *   Spain
37
 *
38
 *   +34 963 510 612
39
 *   +34 963 510 968
40
 *   gis@prodevelop.es
41
 *   http://www.prodevelop.es
42
 */
43
package org.gvsig.arcims.feature.fmap.layers;
44

    
45
import java.awt.Graphics2D;
46
import java.awt.geom.Rectangle2D;
47
import java.awt.image.BufferedImage;
48
import java.net.URL;
49
import java.util.ArrayList;
50
import java.util.Collections;
51
import java.util.ConcurrentModificationException;
52
import java.util.Iterator;
53
import java.util.List;
54
import java.util.Map;
55
import java.util.Vector;
56

    
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59
import org.cresques.cts.IProjection;
60
import org.gvsig.fmap.crs.CRSFactory;
61
import org.gvsig.fmap.mapcontext.MapContext;
62
import org.gvsig.fmap.mapcontext.ViewPort;
63
import org.gvsig.fmap.mapcontext.layers.CancelationException;
64
import org.gvsig.fmap.mapcontext.layers.FLayer;
65
import org.gvsig.fmap.mapcontext.layers.FLayers;
66
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
67
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
68
import org.gvsig.fmap.mapcontext.layers.LayerDrawEvent;
69
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
70
import org.gvsig.fmap.mapcontext.layers.SelectionEvent;
71
import org.gvsig.fmap.mapcontext.layers.SelectionListener;
72
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
73
import org.gvsig.remoteclient.arcims.ArcImsFeatureClient;
74
import org.gvsig.remoteclient.arcims.ArcImsProtocolHandler;
75
import org.gvsig.remoteclient.arcims.utils.MyCancellable;
76
import org.gvsig.remoteclient.arcims.utils.ServiceInfoTags;
77
import org.gvsig.remoteclient.arcims.utils.ServiceInformation;
78
import org.gvsig.remoteclient.arcims.utils.ServiceInformationLayer;
79
import org.gvsig.remoteclient.arcims.utils.ServiceInformationLayerFeatures;
80
import org.gvsig.utils.XMLEntity;
81
import org.gvsig.utils.XMLException;
82
import org.gvsig.utils.swing.threads.DefaultCancellableMonitorable;
83

    
84

    
85

    
86

    
87

    
88
public class FFeatureLyrArcIMSCollection extends FLayers
89
    implements SelectionListener, LayerCollectionListener {
90
    private static Logger logger = LoggerFactory.getLogger(FFeatureLyrArcIMSCollection.class.getName());
91
    private ArrayList layerlist = new ArrayList();
92
    private boolean mustBeSeparated = false;
93
    private MapContext myFMap;
94

    
95
    public FFeatureLyrArcIMSCollection(MapContext fmap, FLayers parent,
96
        boolean willbesep) {
97
        super();
98
        setParentLayer(parent);
99
        setMapContext(fmap);
100
        myFMap = fmap;
101
        mustBeSeparated = willbesep;
102
    }
103

    
104
    public FFeatureLyrArcIMSCollection() {
105
        // super(null, null);
106
            super();
107
    }
108

    
109
    /**
110
     * The extCatalogYNomenclator needs this creator.
111
     *
112
     * @param p a Map object with the following keys:
113
     *
114
     * (key, object type returned)
115
     * ---------------------------
116
     * "host", String (with or without the servlet path)
117
     * "service_name", String (remote service name)
118
     * "srs", String (coordinate system)
119
     * "layer_name", String (local layer name)
120
     *
121
     * @return a FFeatureLyrArcIMSCollection layer
122
     * @throws ConnectionException
123
     */
124
    public FFeatureLyrArcIMSCollection(Map m) throws ConnectionException {
125
        super();
126

    
127
        try {
128
            String _host = (String) m.get("host");
129
            String host = ArcImsProtocolHandler.getUrlWithServlet(new URL(_host))
130
                                               .toString();
131
            String service = (String) m.get("service_name");
132
            String _srs = (String) m.get("srs");
133
            String name = (String) m.get("layer_name");
134

    
135
            // in case layer_name is missing or equals the empty string:
136
            if ((name == null) || (name.length() == 0)) {
137
                name = service;
138
            }
139

    
140
            // --------------------------------------------
141
            IProjection srs = CRSFactory.getCRS(_srs);
142

    
143
            MyCancellable myCanc = new MyCancellable(new DefaultCancellableMonitorable());
144
            FMapFeatureArcImsDriver drv = new FMapFeatureArcImsDriver(host,
145
                    service);
146

    
147
            if (!drv.connect(myCanc)) {
148
                throw new Exception("Unable to connect to server. ");
149
            }
150

    
151
            ServiceInformation si = drv.getClient().getServiceInformation();
152
            int layercount = si.getLayers().size();
153
            String layerQuery = "";
154

    
155
            for (int i = 0; i < layercount; i++) {
156
                if (isTrueString(
157
                            ((ServiceInformationLayer) si.getLayer(i)).getVisible())) {
158
                    layerQuery = layerQuery + "," +
159
                        ((ServiceInformationLayer) si.getLayer(i)).getId();
160
                }
161
            }
162

    
163
            if (layerQuery.length() == 0) {
164
                throw new Exception("No layers are visible by default ");
165
            }
166
            else {
167
                layerQuery = layerQuery.substring(1);
168
            }
169

    
170
            String[] selectedLayerIds = layerQuery.split(",");
171
            int count = selectedLayerIds.length;
172

    
173
            FFeatureLyrArcIMS[] individualLayers = new FFeatureLyrArcIMS[count];
174

    
175
            String item;
176

    
177
            for (int i = 0; i < count; i++) {
178
                item = selectedLayerIds[i];
179

    
180
                drv = new FMapFeatureArcImsDriver(host, service, item);
181

    
182
                if (!(drv.connect(myCanc))) {
183
                    throw new Exception();
184
                }
185

    
186
                ArcImsVectorialAdapter oldadapter = new ArcImsVectorialAdapter(drv);
187
                ArcImsVectorialEditableAdapter adapter = new ArcImsVectorialEditableAdapter();
188

    
189
                /* 1 */ individualLayers[i] = new FFeatureLyrArcIMS(adapter);
190

    
191
                /* 2 */ drv.setLayer(individualLayers[i]);
192

    
193
                si = drv.getClient().getServiceInformation();
194

    
195
                ServiceInformationLayerFeatures silf = (ServiceInformationLayerFeatures) si.getLayerById(item);
196
                String lyrname = silf.getName();
197

    
198
                individualLayers[i].setProjectionInStatus(srs.getAbrev());
199
                individualLayers[i].setHostInStatus(new URL(host));
200
                individualLayers[i].setServiceInStatus(service);
201

    
202
                String units = si.getMapunits();
203
                int theDpi = si.getScreen_dpi();
204
                long scale;
205

    
206
                if (silf.getMaxscale() != -1) {
207
                    scale = LayerScaleData.getTrueScaleFromRelativeScaleAndMapUnits(silf.getMaxscale(),
208
                            units, theDpi);
209
                    individualLayers[i].setMaxScale((double) scale);
210
                }
211

    
212
                if (silf.getMinscale() != -1) {
213
                    scale = LayerScaleData.getTrueScaleFromRelativeScaleAndMapUnits(silf.getMinscale(),
214
                            units, theDpi);
215
                    individualLayers[i].setMinScale((double) scale);
216
                }
217

    
218
                individualLayers[i].setServiceInformationInStatus(si);
219

    
220
                Vector ids = new Vector();
221
                ids.add(item);
222
                individualLayers[i].setLayerIdsInStatus((Vector) ids.clone());
223
                individualLayers[i].setSubfieldsInStatus();
224

    
225
                /* 3 */
226
                // individualLayers[i].setLegend(new VectorialUniqueValueLegend());
227
                individualLayers[i].setHost(new URL(host));
228
                individualLayers[i].setService(service);
229
                individualLayers[i].setServiceType(ServiceInfoTags.vFEATURESERVICE);
230
                individualLayers[i].setTransparency(0);
231
                individualLayers[i].setLayerQuery(item);
232
                individualLayers[i].setProjection(srs);
233
                individualLayers[i].setName(lyrname);
234

    
235
                Rectangle2D fext = ((ArcImsFeatureClient) drv.getClient()).getLayerExtent(individualLayers[i].getArcimsStatus());
236
                drv.setFullExtent(fext);
237

    
238
                // individualLayers[i].setF. setFullExtent(((ArcImsProtImageHandler) drv.getClient().getHandler()).getServiceExtent(srs, individualLayers[i].getArcimsStatus()));
239

    
240
                // ------ -------------
241
                drv.setAdapter(adapter);
242

    
243
                // adapter.setRecordSet(drv.getRecordSet());
244
                adapter.setOriginalDataSource(drv.getRecordSet());
245
                adapter.setOriginalVectorialAdapter(oldadapter);
246
                drv.declareTable( individualLayers[i] );
247
                individualLayers[i].setInitialLegend();
248
                individualLayers[i].setShapeType(adapter.getShapeType());
249
                individualLayers[i].setRecordset(drv.getRecordSet());
250

    
251
                // ------ -------------
252
                if ((si.getFeaturecoordsys() == null) ||
253
                        (si.getFeaturecoordsys().equals(""))) {
254
                    si.setFeaturecoordsys(srs.getAbrev()
255
                                             .substring(ServiceInfoTags.vINI_SRS.length())
256
                                             .trim());
257
                    logger.warn("Server provides no SRS. ");
258
                }
259
            }
260

    
261
            setName(name);
262
            setProjection(srs);
263

    
264
            for (int i = 0; i < count; i++) {
265
                addLayer(individualLayers[i]);
266
            }
267
        }
268
        catch (Exception e) {
269
            throw new ConnectionException("Unable to create ArcIMS feature layer collection ",
270
                e);
271
        }
272
    }
273

    
274
    public MapContext getMapContext() {
275
        return myFMap;
276
    }
277

    
278
    public boolean mustBeSeparated() {
279
        return mustBeSeparated;
280
    }
281

    
282
    public void hasBeenSeparated() {
283
        mustBeSeparated = false;
284
    }
285

    
286
    public void setParentLayer(FLayers lyr) {
287
        super.setParentLayer(lyr);
288

    
289
        if (lyr == null) {
290
            return;
291
        }
292

    
293
        myFMap = lyr.getMapContext();
294

    
295
        if (lyr instanceof LayerCollection) {
296
            LayerCollection lyrcol = (LayerCollection) lyr;
297
            lyrcol.addLayerCollectionListener(this);
298
        }
299
    }
300

    
301
    private List myGetList() {
302
        List resp = Collections.synchronizedList(new ArrayList());
303

    
304
        int count = getLayersCount();
305

    
306
        for (int i = 0; i < count; i++) {
307
            resp.add(getLayer(i));
308
        }
309

    
310
        return resp;
311
    }
312

    
313
    // we need to rewrite this method because we dont have access to fmap
314
    // and list
315
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
316
        Cancellable cancel, double scale) throws ReadDriverException {
317
        List myList = myGetList();
318

    
319
        Iterator iter = myList.iterator();
320

    
321
        try {
322
            while (iter.hasNext()) {
323
                if (cancel.isCanceled()) {
324
                    break; // M?s que nada porque las capas raster no son interrumpibles por ahora.
325
                }
326

    
327
                FLayer lyr = (FLayer) iter.next();
328
                LayerDrawEvent beforeEvent = new LayerDrawEvent(lyr, g,
329
                        viewPort, LayerDrawEvent.LAYER_BEFORE_DRAW);
330

    
331
                myFMap.fireLayerDrawingEvent(beforeEvent);
332

    
333
                if (lyr.isVisible()) {
334
                    long t1 = System.currentTimeMillis();
335

    
336
                    try {
337
                        lyr.draw(image, g, viewPort, cancel, scale);
338
                    }
339
                    catch (ReadDriverException e) {
340
                        myFMap.addLayerError("La capa " + lyr.getName() +
341
                            " es err?nea.");
342
                        e.printStackTrace();
343
                    }
344

    
345
                    long t2 = System.currentTimeMillis();
346
                    System.out.println("Layer " + lyr.getName() + " " +
347
                        (t2 - t1) + " milisecs.");
348
                }
349

    
350
                LayerDrawEvent afterEvent = new LayerDrawEvent(lyr, g,
351
                        viewPort, LayerDrawEvent.LAYER_AFTER_DRAW);
352
                myFMap.fireLayerDrawingEvent(afterEvent);
353
            }
354

    
355
            if (getVirtualLayers() != null) {
356
                getVirtualLayers().draw(image, g, viewPort, cancel, scale);
357
            }
358
        }
359
        catch (ConcurrentModificationException e) {
360
            System.err.println(e.getMessage());
361
        }
362
    }
363

    
364
    public void addLayer(FLayer layer) throws CancelationException {
365
        if (!(layer instanceof FFeatureLyrArcIMS)) {
366
            logger.error(
367
                "Only FFeatureLyrArcIMS layers allowed in this collection. ");
368

    
369
            return;
370
        }
371

    
372
        FFeatureLyrArcIMS lyr = (FFeatureLyrArcIMS) layer;
373

    
374
        // lyr.addSelectionListener(this);
375
        super.addLayer(layer);
376
        layerlist.add(layer);
377
    }
378

    
379
    public void selectionChanged(SelectionEvent e) {
380
        // e.get
381
        getMapContext().invalidate();
382

    
383
        // System.out.println("==========> Selection changed somewhere....");
384
        // TODO Auto-generated method stub
385
    }
386

    
387
    public void setXMLEntity(XMLEntity xml) throws XMLException {
388
        setActive(xml.getBooleanProperty("active"));
389
        setName(xml.getStringProperty("name"));
390
        setMinScale(xml.getDoubleProperty("minScale"));
391
        setMaxScale(xml.getDoubleProperty("maxScale"));
392
        setVisible(xml.getBooleanProperty("visible"));
393

    
394
        if (xml.contains("proj")) {
395
            setProjection(CRSFactory.getCRS(xml.getStringProperty("proj")));
396
        }
397

    
398
        if (xml.contains("transparency")) {
399
            setTransparency(xml.getIntProperty("transparency"));
400
        }
401

    
402
        // ------------
403
        int numLayers = xml.getIntProperty("numLayers");
404
        String[] s = xml.getStringArrayProperty("LayerNames");
405

    
406
        for (int i = 0; i < numLayers; i++) {
407
            FLayer layer = null;
408

    
409
            try {
410
                String className = xml.getChild(i).getStringProperty("className");
411
                Class clase = Class.forName(className);
412
                layer = (FLayer) clase.newInstance();
413
                layer.setName(s[i]);
414
                layer.setXMLEntity(xml.getChild(i));
415
                layer.load();
416
                logger.debug("Layer: " + layer.getName() + " has been loaded.");
417
            }
418
            catch (Exception e) {
419
                logger.error("While loading layer: " + layer.getName() +
420
                    " (visible = false)", e);
421
                layer.setVisible(false);
422
            }
423

    
424
            addLayer(layer);
425
        }
426
    }
427

    
428
    public XMLEntity getXMLEntity() throws XMLException {
429
        XMLEntity xml = new XMLEntity();
430
        xml.putProperty("className", this.getClass().getName());
431
        xml.putProperty("active", isActive());
432
        xml.putProperty("name", getName());
433
        xml.putProperty("minScale", getMinScale());
434
        xml.putProperty("maxScale", getMaxScale());
435
        xml.putProperty("visible", isVisible());
436

    
437
        if (getProjection() != null) {
438
            xml.putProperty("proj", getProjection().getAbrev());
439
        }
440

    
441
        xml.putProperty("transparency", getTransparency());
442

    
443
        // --------------------
444
        xml.putProperty("numLayers", layerlist.size());
445

    
446
        String[] s = new String[layerlist.size()];
447

    
448
        for (int i = 0; i < layerlist.size(); i++) {
449
            s[i] = ((FFeatureLyrArcIMS) layerlist.get(i)).getName();
450
        }
451

    
452
        xml.putProperty("LayerNames", s);
453

    
454
        for (int i = 0; i < layerlist.size(); i++) {
455
            xml.addChild(((FFeatureLyrArcIMS) layerlist.get(i)).getXMLEntity());
456
        }
457

    
458
        return xml;
459
    }
460

    
461
    public void layerAdded(LayerCollectionEvent e) {
462
        // this layer has been added to a collection
463
        // if it has to be separated, it will be separated now:
464
        if (!mustBeSeparated) {
465
            return;
466
        }
467

    
468
        hasBeenSeparated();
469

    
470
        FLayers lyr = getParentLayer();
471

    
472
        if (lyr == null) {
473
            return;
474
        }
475

    
476
        FLayer item;
477
        int count;
478

    
479
        if (lyr instanceof LayerCollection) {
480
            LayerCollection lyrcol = (LayerCollection) lyr;
481
            count = getLayersCount();
482

    
483
            while (count > 0) {
484
                item = getLayer(count - 1);
485
                removeLayer(item);
486
                try {
487
                                        lyrcol.addLayer(item);
488
                                } catch (Exception ex) {
489
                                        logger.error("While addgin layer: " + ex.getMessage());
490
                                }
491
                count = getLayersCount();
492
            }
493

    
494
            lyrcol.removeLayer(this);
495
        }
496
    }
497

    
498
    public void layerMoved(LayerPositionEvent e) {
499
        // TODO Auto-generated method stub
500
    }
501

    
502
    public void layerRemoved(LayerCollectionEvent e) {
503
        // TODO Auto-generated method stub
504
    }
505

    
506
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
507
        // TODO Auto-generated method stub
508
    }
509

    
510
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
511
        // TODO Auto-generated method stub
512
    }
513

    
514
    public void layerRemoving(LayerCollectionEvent e)
515
        throws CancelationException {
516
        // TODO Auto-generated method stub
517
    }
518

    
519
    public void activationChanged(LayerCollectionEvent e)
520
        throws CancelationException {
521
        // TODO Auto-generated method stub
522
    }
523

    
524
    public void visibilityChanged(LayerCollectionEvent e)
525
        throws CancelationException {
526
        // TODO Auto-generated method stub
527
    }
528

    
529
    public void setXMLEntity03(XMLEntity xml) throws XMLException {
530
        // TODO
531
    }
532

    
533
    public void replaceLayer(String layerName, FLayer layer) {
534
        // TODO
535
    }
536

    
537
    private boolean isTrueString(String visible) {
538
        if (visible.compareToIgnoreCase("true") == 0) {
539
            return true;
540
        }
541

    
542
        return false;
543
    }
544
}