Statistics
| Revision:

gvsig-3d / 2.1 / branches / org.gvsig.view3d_vector_and_extrusion_2.3 / org.gvsig.view3d / org.gvsig.view3d / org.gvsig.view3d.swing / org.gvsig.view3d.swing.impl / src / main / java / org / gvsig / view3d / swing / impl / data / GvSIGLayerDataRaster.java @ 708

History | View | Annotate | Download (22 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright � 2007-2015 gvSIG Association
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.view3d.swing.impl.data;
26

    
27
import gov.nasa.worldwind.WWObjectImpl;
28
import gov.nasa.worldwind.avlist.AVKey;
29
import gov.nasa.worldwind.avlist.AVList;
30
import gov.nasa.worldwind.data.BufferedImageRaster;
31
import gov.nasa.worldwind.data.ByteBufferRaster;
32
import gov.nasa.worldwind.data.DataRaster;
33
import gov.nasa.worldwind.geom.Sector;
34

    
35
import java.awt.Dimension;
36
import java.awt.Graphics2D;
37
import java.awt.Rectangle;
38
import java.awt.geom.AffineTransform;
39
import java.awt.geom.Point2D;
40
import java.awt.geom.Rectangle2D;
41
import java.awt.image.BufferedImage;
42

    
43
import org.cresques.cts.ICoordTrans;
44
import org.cresques.cts.IProjection;
45
import org.gvsig.fmap.crs.CRSFactory;
46
import org.gvsig.fmap.dal.coverage.RasterLocator;
47
import org.gvsig.fmap.dal.coverage.RasterManager;
48
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
49
import org.gvsig.fmap.dal.coverage.datastruct.DataStructFactory;
50
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
51
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
52
import org.gvsig.fmap.dal.coverage.exception.QueryException;
53
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
54
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
55
import org.gvsig.fmap.dal.exception.ReadException;
56
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
57
import org.gvsig.fmap.geom.GeometryLocator;
58
import org.gvsig.fmap.geom.GeometryManager;
59
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
60
import org.gvsig.fmap.geom.primitive.Envelope;
61
import org.gvsig.fmap.mapcontext.MapContext;
62
import org.gvsig.fmap.mapcontext.ViewPort;
63
import org.gvsig.fmap.mapcontext.layers.FLayer;
64
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
65
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
66
import org.gvsig.raster.fmap.layers.FLyrRaster;
67
import org.gvsig.view3d.lib.api.View3DLocator;
68
import org.gvsig.view3d.lib.api.View3DManager;
69
import org.gvsig.view3d.lib.api.properties.ElevationLayerProperties3D;
70
import org.gvsig.view3d.lib.api.properties.LayerProperties3D;
71
import org.gvsig.view3d.swing.api.MapControl3D;
72
import org.slf4j.Logger;
73
import org.slf4j.LoggerFactory;
74

    
75
/**
76
 * Default implementation of {@link DataRaster}.
77
 * 
78
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
79
 *
80
 */
81
@SuppressWarnings("deprecation")
82
public class GvSIGLayerDataRaster extends WWObjectImpl implements DataRaster {
83

    
84
    private static final Logger LOG =
85
        LoggerFactory.getLogger(GvSIGLayerDataRaster.class);
86

    
87
    private MapControl3D mapControl3D;
88
    private FLayer layer;
89

    
90
    private Extent canvasExtent;
91
    private Extent overlapExtent;
92

    
93
    /**
94
     * Default constructor of <code>GvSIGLayerDataRaster</code>
95
     * 
96
     * @param mapControl3D
97
     *            context where {@link FLayer} is loaded.
98
     * @param theLayer
99
     *            source to get raster information
100
     * @param params
101
     *            parameters of <code>GvSIGLayerDataRaster</code>
102
     */
103
    public GvSIGLayerDataRaster(MapControl3D mapControl3D, FLayer theLayer,
104
        AVList params) {
105

    
106
        if (params == null || mapControl3D == null || theLayer == null) {
107
            throw new IllegalArgumentException();
108
        }
109

    
110
        this.layer = theLayer;
111
        this.mapControl3D = mapControl3D;
112
        this.setValues(params.copy());
113
    }
114

    
115
    public void dispose() {
116
    }
117

    
118
    public int getWidth() {
119
        return (Integer) this.getValue(AVKey.WIDTH);
120
    }
121

    
122
    public int getHeight() {
123
        return (Integer) this.getValue(AVKey.HEIGHT);
124
    }
125

    
126
    public Sector getSector() {
127

    
128
        return (Sector) this.getValue(AVKey.SECTOR);
129

    
130
    }
131

    
132
    public void drawOnTo(DataRaster canvas) {
133
        View3DManager manager = View3DLocator.getManager();
134
        LayerProperties3D properties = manager.getLayerProperties(layer, null);
135

    
136
        if (properties instanceof ElevationLayerProperties3D) {
137
            if (this.layer instanceof FLyrRaster) {
138
                this.drawRasterElevationOnTo(canvas);
139
            } else if (this.layer instanceof FLyrVect) {
140
                this.drawVectElevationOnTo(canvas);
141
            }
142
        } else {
143
            this.drawImageOnTo(canvas);
144
        }
145
    }
146

    
147
    private void drawRasterElevationOnTo(DataRaster canvas) {
148

    
149
        if (canvas == null) {
150
            throw new IllegalArgumentException();
151
        }
152

    
153
        if (!(this.layer instanceof FLyrRaster)
154
            || !canvas.getSector().intersects(getSector())) {
155
            return;
156
        }
157

    
158
        Extent canvasExtent = getExtent(canvas.getSector());
159

    
160
        // Create query. Configure to get the zone request by canvas scaled to
161
        // tile size.
162
        RasterQuery query = RasterLocator.getManager().createQuery();
163
        query.setSupersamplingOption(false);
164
        query.setDrawableBands(new int[] { 0 });
165
        query.setReadOnly(true);
166
        query.storeLastBuffer(true);
167
        query.setAreaOfInterest(canvasExtent, canvas.getWidth(),
168
            canvas.getHeight());
169

    
170
        Buffer adjustedBuffer = null;
171
        FLyrRaster rasterLayer = (FLyrRaster) this.layer;
172
        RasterDataStore dataStore = rasterLayer.getDataStore();
173

    
174
        try {
175
            // For best performance, checks if canvas extent is the same than
176
            // last request. If it is the same, it will get last buffer
177
            // stored. Otherwise, it will do created query.
178
            if (canvasExtent.equals(this.canvasExtent)
179
                && dataStore.getLastBuffer() != null) {
180
                adjustedBuffer = dataStore.getLastBuffer();
181
            } else {
182
                adjustedBuffer = dataStore.query(query);
183
            }
184
        } catch (ProcessInterruptedException e) {
185
            LOG.error("Process interrupted while {} was executing a query",
186
                dataStore.getName(), e);
187
            return;
188
        } catch (QueryException e) {
189
            LOG.error("Query exception, can apply {} to {}",
190
                new Object[] { query.toString(), dataStore.getName() }, e);
191
            return;
192
        }
193

    
194
        // For performance reasons, stores canvas extent to avoid calculate it
195
        // in each iteration
196
        setCanvasEnxent(canvas.getSector());
197
        Sector overlap = this.getSector().intersection(canvas.getSector());
198
        setOverlapExtent(overlap);
199

    
200
        String dataType = this.getStringValue(AVKey.DATA_TYPE);
201

    
202
        for (int y = 0; y < canvas.getHeight(); y++) {
203
            for (int x = 0; x < canvas.getWidth(); x++) {
204

    
205
                Point2D rasterPoint =
206
                    getRasterPoint(x, y, canvas, adjustedBuffer);
207

    
208
                // If raster point is not null, get value of buffer and write it
209
                // to canvas
210
                if (rasterPoint != null) {
211
                    if (AVKey.INT8.equals(dataType)) {
212

    
213
                        byte byteValue =
214
                            adjustedBuffer.getElemByte((int) rasterPoint.getY(),
215
                                (int) rasterPoint.getX(), 0);
216

    
217
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
218
                            byteValue);
219

    
220
                    } else if (AVKey.INT16.equals(dataType)) {
221

    
222
                        short shortValue = adjustedBuffer.getElemShort(
223
                            (int) rasterPoint.getY(), (int) rasterPoint.getX(),
224
                            0);
225

    
226
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
227
                            shortValue);
228

    
229
                    } else if (AVKey.INT32.equals(dataType)) {
230

    
231
                        int intValue =
232
                            adjustedBuffer.getElemInt((int) rasterPoint.getY(),
233
                                (int) rasterPoint.getX(), 0);
234

    
235
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
236
                            intValue);
237

    
238
                    } else if (AVKey.FLOAT32.equals(dataType)) {
239

    
240
                        float floatValue = adjustedBuffer.getElemFloat(
241
                            (int) rasterPoint.getY(), (int) rasterPoint.getX(),
242
                            0);
243

    
244
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
245
                            floatValue);
246

    
247
                    } else if (AVKey.FLOAT64.equals(dataType)) {
248

    
249
                        double doubleValue = adjustedBuffer.getElemDouble(
250
                            (int) rasterPoint.getY(), (int) rasterPoint.getX(),
251
                            0);
252

    
253
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
254
                            doubleValue);
255
                    }
256
                } else {
257
                    // Invalid point, write NoData value
258
                    Number noData =
259
                        (Number) this.getValue(AVKey.MISSING_DATA_SIGNAL);
260
                    if (AVKey.INT8.equals(dataType)) {
261
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
262
                            noData.byteValue());
263
                    } else if (AVKey.INT16.equals(dataType)) {
264
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
265
                            noData.shortValue());
266
                    } else if (AVKey.INT32.equals(dataType)) {
267
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
268
                            noData.intValue());
269
                    } else if (AVKey.FLOAT32.equals(dataType)) {
270
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
271
                            noData.floatValue());
272
                    } else if (AVKey.FLOAT64.equals(dataType)) {
273
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
274
                            noData.doubleValue());
275
                    }
276
                }
277
            }
278
        }
279
    }
280

    
281
    private Point2D getRasterPoint(int x, int y, DataRaster canvas,
282
        Buffer adjustedBuffer) {
283

    
284
        // Gets coordiantes of pixel raster
285
        Point2D worldPoint =
286
            canvasExtent.rasterToWorld(new Point2D.Double(x, y),
287
                getCellSize(canvas.getSector(), canvas.getWidth()));
288

    
289
        if (layer instanceof FLyrRaster) {
290
            // Gets pixel of adjusted buffer
291
            Sector overlap = this.getSector().intersection(canvas.getSector());
292
            Point2D rasterPoint = overlapExtent.worldToRaster(worldPoint,
293
                getCellSize(overlap, adjustedBuffer.getWidth()));
294

    
295
            if (isPointOfBuffer(rasterPoint, adjustedBuffer)) {
296
                return rasterPoint;
297
            }
298
        }
299
        return null;
300
    }
301

    
302
    private void setCanvasEnxent(Sector canvasSector) {
303
        this.canvasExtent = getExtent(canvasSector);
304
    }
305

    
306
    private void setOverlapExtent(Sector overlap) {
307
        this.overlapExtent = getExtent(overlap);
308
    }
309

    
310
    private Extent getExtent(Sector sector) {
311
        Rectangle2D rectangleDegrees = sector.toRectangleDegrees();
312
        RasterManager rasterManager = RasterLocator.getManager();
313
        DataStructFactory dataStructFactory =
314
            rasterManager.getDataStructFactory();
315
        return dataStructFactory.createExtent(rectangleDegrees);
316
    }
317

    
318
    private double getCellSize(Sector sector, int width) {
319

    
320
        Rectangle2D rectangleDegrees = sector.toRectangleDegrees();
321

    
322
        return rectangleDegrees.getWidth() / width;
323
    }
324

    
325
    private boolean isPointOfBuffer(Point2D rasterPoint, Buffer buffer) {
326
        if (layer instanceof FLyrRaster) {
327
            double x = rasterPoint.getX();
328
            double y = rasterPoint.getY();
329
            return x > -1 && y > -1 && x < buffer.getWidth()
330
                && y < buffer.getHeight() ? true : false;
331
        }
332
        return false;
333
    }
334

    
335
    private void setNumberToDataRaster(ByteBufferRaster byteBuferRaster,
336
        int line, int col, Number value) {
337
        byteBuferRaster.setDoubleAtPosition(line, col, value.doubleValue());
338
    }
339

    
340
    private void drawVectElevationOnTo(DataRaster canvas) {
341
        // TODO Auto-generated method stub
342

    
343
    }
344

    
345
    private void drawImageOnTo(DataRaster canvas) {
346
        if (canvas == null) {
347
            throw new IllegalArgumentException();
348
        }
349

    
350
        if (!canvas.getSector().intersects(getSector())) {
351
            return;
352
        }
353

    
354
        Sector overlap = this.getSector().intersection(canvas.getSector());
355

    
356
        ViewPort viewPort =
357
            new ViewPort(mapControl3D.getMapContext().getProjection());
358

    
359
        // Set adjustable to false to avoid problems with adjusted envelope
360
        viewPort.setAdjustable(false);
361

    
362
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
363

    
364
        Envelope envelope = null;
365
        double[] degrees = overlap.asDegreesArray();
366

    
367
        try {
368

    
369
            IProjection projection =
370
                mapControl3D.getMapContext().getProjection();
371

    
372
            ICoordTrans ct = CRSFactory.getCRS("EPSG:4326").getCT(projection);
373
            Point2D p1 =
374
                convert(ct, new Point2D.Double(degrees[2], degrees[0]));
375
            Point2D p2 =
376
                convert(ct, new Point2D.Double(degrees[3], degrees[1]));
377

    
378
            envelope = geoManager.createEnvelope(Math.min(p1.getX(), p2.getX()),
379
                Math.min(p1.getY(), p2.getY()), Math.max(p1.getX(), p2.getX()),
380
                Math.max(p1.getY(), p2.getY()), SUBTYPES.GEOM2D);
381

    
382
            /**
383
             * Check if request tile intersect with layer envelope to avoid
384
             * the creation of useless tiles.
385
             */
386
            if (!envelope.intersects(layer.getFullEnvelope())) {
387
                return;
388
            }
389

    
390
            viewPort.setEnvelope(envelope);
391

    
392
        } catch (CreateEnvelopeException e) {
393
            LOG.error(
394
                "Can't create envelope from sector tile:  minLat {} maxLat {} minLon {} maxLon {}",
395
                new Object[] { degrees[0], degrees[1], degrees[2],
396
                    degrees[3] });
397
            return;
398
        } catch (ReadException e) {
399
            LOG.warn("Can't get full envelope of {}", layer.getName());
400
        }
401

    
402
        int canvasWidth = canvas.getWidth();
403
        int canvasHeight = canvas.getHeight();
404

    
405
        java.awt.Rectangle clipRect = this.computeClipRect(overlap, this);
406
        if (null == clipRect || clipRect.width == 0 || clipRect.height == 0) {
407
            return;
408
        }
409

    
410
        // Apply the transform that correctly maps the image onto the canvas.
411
        java.awt.geom.AffineTransform affineTransform =
412
            this.computeSourceToDestTransform(clipRect.width, clipRect.height,
413
                overlap, canvasWidth, canvasHeight, canvas.getSector());
414

    
415
        // Trick to apply transform to size value
416
        Point2D srcSizePoint =
417
            new Point2D.Double(clipRect.width, clipRect.height);
418
        Point2D dstSizePoint = new Point2D.Double();
419

    
420
        affineTransform.transform(srcSizePoint, dstSizePoint);
421

    
422
        int clipWidth = (int) Math.ceil((dstSizePoint.getX() >= canvasWidth)
423
            ? canvasWidth : dstSizePoint.getX());
424
        int clipHeight = (int) Math.ceil((dstSizePoint.getY() >= canvasHeight)
425
            ? canvasHeight : dstSizePoint.getY());
426

    
427
        if (clipWidth <= 0 || clipHeight <= 0) {
428
            return;
429
        }
430

    
431
        BufferedImage image = new BufferedImage(clipWidth, clipHeight,
432
            BufferedImage.TYPE_INT_ARGB);
433

    
434
        viewPort.setImageSize(new Dimension(clipWidth, clipHeight));
435
        viewPort.refreshExtent();
436

    
437
        try {
438
            layer.draw(image, (Graphics2D) image.getGraphics(), viewPort,
439
                mapControl3D.getCancellable(), getScale(viewPort));
440

    
441
            if (layer instanceof FLyrVect && layer instanceof ILabelable) {
442

    
443
                ILabelable labelable = (ILabelable) layer;
444

    
445
                if (labelable.isLabeled()
446
                    && labelable.getLabelingStrategy() != null
447
                    && labelable.getLabelingStrategy()
448
                        .shouldDrawLabels(getScale(viewPort))) {
449

    
450
                    labelable.drawLabels(image,
451
                        (Graphics2D) image.getGraphics(), viewPort,
452
                        mapControl3D.getCancellable(), getScale(viewPort),
453
                        mapControl3D.getMapContext().getViewPort().getDPI());
454
                }
455
            }
456

    
457
        } catch (ReadException e) {
458
            LOG.warn("Can't draw required zone of layer {}, can't read legend",
459
                layer.getName());
460
            return;
461
        } finally {
462
            if (mapControl3D.getCancellable().isCanceled()) {
463
                return;
464
            }
465
        }
466
        BufferedImageRaster bufferedImageRaster =
467
            new BufferedImageRaster(overlap, image);
468
        bufferedImageRaster.drawOnTo(canvas);
469

    
470
    }
471

    
472
    private Point2D convert(ICoordTrans ct, Point2D srcPoint) {
473
        if (ct == null) {
474
            return srcPoint;
475
        }
476
        return ct.convert(srcPoint, null);
477
    }
478

    
479
    private java.awt.geom.AffineTransform computeSourceToDestTransform(
480
        int sourceWidth, int sourceHeight, Sector sourceSector, int destWidth,
481
        int destHeight, Sector destSector) {
482
        // Compute the the transform from source to destination coordinates. In
483
        // this computation a pixel is assumed
484
        // to cover a finite area.
485

    
486
        double ty = destHeight
487
            * -(sourceSector.getMaxLatitude().degrees
488
                - destSector.getMaxLatitude().degrees)
489
            / destSector.getDeltaLatDegrees();
490
        double tx = destWidth
491
            * (sourceSector.getMinLongitude().degrees
492
                - destSector.getMinLongitude().degrees)
493
            / destSector.getDeltaLonDegrees();
494

    
495
        double sy = ((double) destHeight / (double) sourceHeight)
496
            * (sourceSector.getDeltaLatDegrees()
497
                / destSector.getDeltaLatDegrees());
498
        double sx = ((double) destWidth / (double) sourceWidth)
499
            * (sourceSector.getDeltaLonDegrees()
500
                / destSector.getDeltaLonDegrees());
501

    
502
        java.awt.geom.AffineTransform transform =
503
            new java.awt.geom.AffineTransform();
504
        transform.translate(tx, ty);
505
        transform.scale(sx, sy);
506
        return transform;
507
    }
508

    
509
    private double getScale(ViewPort viewPort) {
510

    
511
        double dpi = viewPort.getDPI();
512
        IProjection proj = viewPort.getProjection();
513

    
514
        if (viewPort.getImageSize() == null) {
515
            return -1;
516
        }
517

    
518
        if (viewPort.getAdjustedEnvelope() == null) {
519
            return 0;
520
        }
521
        double[] trans2Meter = MapContext.getDistanceTrans2Meter();
522
        int mUnits = viewPort.getMapUnits();
523

    
524
        if (proj == null) {
525
            double w = ((viewPort.getImageSize().width / dpi) * 0.0254);
526
            return (long) (viewPort.getAdjustedEnvelope().getLength(0) / w
527
                * trans2Meter[mUnits]);
528
        }
529

    
530
        return Math.round(proj.getScale(
531
            viewPort.getAdjustedEnvelope().getMinimum(0) * trans2Meter[mUnits],
532
            viewPort.getAdjustedEnvelope().getMaximum(0) * trans2Meter[mUnits],
533
            viewPort.getImageSize().width, dpi));
534
    }
535

    
536
    private Rectangle computeClipRect(Sector clipSector,
537
        DataRaster clippedRaster) {
538

    
539
        AffineTransform geographicToRaster =
540
            this.computeGeographicToRasterTransform(clippedRaster.getWidth(),
541
                clippedRaster.getHeight(), clippedRaster.getSector());
542

    
543
        java.awt.geom.Point2D geoPoint = new java.awt.geom.Point2D.Double();
544
        java.awt.geom.Point2D ul = new java.awt.geom.Point2D.Double();
545
        java.awt.geom.Point2D lr = new java.awt.geom.Point2D.Double();
546

    
547
        geoPoint.setLocation(clipSector.getMinLongitude().degrees,
548
            clipSector.getMaxLatitude().degrees);
549
        geographicToRaster.transform(geoPoint, ul);
550

    
551
        geoPoint.setLocation(clipSector.getMaxLongitude().degrees,
552
            clipSector.getMinLatitude().degrees);
553
        geographicToRaster.transform(geoPoint, lr);
554

    
555
        int x = (int) Math.floor(ul.getX());
556
        int y = (int) Math.floor(ul.getY());
557
        int width = (int) Math.ceil(lr.getX() - ul.getX());
558
        int height = (int) Math.ceil(lr.getY() - ul.getY());
559

    
560
        return new Rectangle(x, y, width, height);
561
    }
562

    
563
    private java.awt.geom.AffineTransform computeGeographicToRasterTransform(
564
        int width, int height, Sector sector) {
565
        // Compute the the transform from geographic to raster coordinates. In
566
        // this computation a pixel is assumed
567
        // to cover a finite area.
568

    
569
        double ty = -sector.getMaxLatitude().degrees;
570
        double tx = -sector.getMinLongitude().degrees;
571

    
572
        double sy = -(height / sector.getDeltaLatDegrees());
573
        double sx = (width / sector.getDeltaLonDegrees());
574

    
575
        java.awt.geom.AffineTransform transform =
576
            new java.awt.geom.AffineTransform();
577
        transform.scale(sx, sy);
578
        transform.translate(tx, ty);
579
        return transform;
580
    }
581

    
582
    public DataRaster getSubRaster(AVList params) {
583
        int width = (Integer) params.getValue(AVKey.WIDTH);
584
        int height = (Integer) params.getValue(AVKey.HEIGHT);
585
        Sector sector = (Sector) params.getValue(AVKey.SECTOR);
586

    
587
        return this.getSubRaster(width, height, sector, params);
588
    }
589

    
590
    public DataRaster getSubRaster(int width, int height, Sector sector,
591
        AVList params) {
592

    
593
        params.setValue(AVKey.WIDTH, width);
594
        params.setValue(AVKey.HEIGHT, height);
595
        params.setValue(AVKey.SECTOR, sector);
596

    
597
        GvSIGLayerDataRaster subRaster =
598
            new GvSIGLayerDataRaster(mapControl3D, layer, params);
599
        return subRaster;
600
    }
601
}