Statistics
| Revision:

gvsig-3d / 2.1 / trunk / org.gvsig.view3d / org.gvsig.view3d.swing / org.gvsig.view3d.swing.impl / src / main / java / org / gvsig / view3d / swing / impl / data / GvSIGLayerDataRaster.java @ 531

History | View | Annotate | Download (22.5 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.LayerProperties3D;
70
import org.gvsig.view3d.swing.api.MapControl3D;
71
import org.slf4j.Logger;
72
import org.slf4j.LoggerFactory;
73

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

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

    
86
    private MapControl3D mapControl3D;
87
    private FLayer layer;
88
    
89
    private Extent canvasExtent;
90
    private Extent overlapExtent;
91

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

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

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

    
114
    public void dispose() {
115
    }
116

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

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

    
125
    public Sector getSector() {
126

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

    
129
    }
130

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

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

    
146
    private void drawRasterElevationOnTo(DataRaster canvas) {
147

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

    
152
        if (!(this.layer instanceof FLyrRaster)
153
            || !canvas.getSector().intersects(getSector())) {
154
            return;
155
        }
156
        
157
        Extent canvasExtent = getExtent(canvas.getSector());
158
        
159
        // Create query. Configure to get the zone request by canvas scaled to
160
        // tile size. 
161
        RasterQuery query = RasterLocator.getManager().createQuery();
162
        query.setSupersamplingOption(false);
163
        query.setDrawableBands(new int[] { 0 });
164
        query.setReadOnly(true);
165
        query.storeLastBuffer(true);
166
        query.setAreaOfInterest(canvasExtent, canvas.getWidth(),
167
            canvas.getHeight());
168
        
169
        Buffer adjustedBuffer = null;
170
        FLyrRaster rasterLayer = (FLyrRaster) this.layer;
171
        RasterDataStore dataStore = rasterLayer.getDataStore();
172
        
173
        try {
174
            // For best performance, checks if canvas extent is the same than
175
            // last request. If it is the same, it will get last buffer
176
            // stored. Otherwise, it will do created query. 
177
            if (canvasExtent.equals(this.canvasExtent)
178
                && dataStore.getLastBuffer() != null) {
179
                adjustedBuffer = dataStore.getLastBuffer();
180
            } else {
181
                adjustedBuffer = dataStore.query(query);
182
            }
183
        } catch (ProcessInterruptedException e) {
184
            LOG.error("Process interrupted while {} was executing a query",
185
                dataStore.getName(), e);
186
            return;
187
        } catch (QueryException e) {
188
            LOG.error("Query exception, can apply {} to {}", new Object[] {
189
                query.toString(), dataStore.getName() }, e);
190
            return;
191
        }
192

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

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

    
204
                Point2D rasterPoint =
205
                    getRasterPoint(x, y, canvas, adjustedBuffer);
206
                
207
                // If raster point is not null, get value of buffer and write it
208
                // to canvas
209
                if (rasterPoint != null) {
210
                    if (AVKey.INT8.equals(dataType)) {
211

    
212
                        byte byteValue =
213
                            adjustedBuffer.getElemByte(
214
                                (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 =
223
                            adjustedBuffer.getElemShort(
224
                                (int) rasterPoint.getY(),
225
                                (int) rasterPoint.getX(), 0);
226
                        
227
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
228
                            shortValue);
229
                        
230
                    } else if (AVKey.INT32.equals(dataType)) {
231
                        
232
                        int intValue =
233
                            adjustedBuffer.getElemInt((int) rasterPoint.getY(),
234
                                (int) rasterPoint.getX(), 0);
235
                        
236
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
237
                            intValue);
238
                        
239
                    } else if (AVKey.FLOAT32.equals(dataType)) {
240
                        
241
                        float floatValue =
242
                            adjustedBuffer.getElemFloat(
243
                                (int) rasterPoint.getY(),
244
                                (int) rasterPoint.getX(), 0);
245
                        
246
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
247
                            floatValue);
248
                        
249
                    } else if (AVKey.FLOAT64.equals(dataType)) {
250
                        
251
                        double doubleValue =
252
                            adjustedBuffer.getElemDouble(
253
                                (int) rasterPoint.getY(),
254
                                (int) rasterPoint.getX(), 0);
255
                        
256
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
257
                            doubleValue);
258
                    }
259
                } else {
260
                    // Invalid point, write NoData value
261
                    Number noData =
262
                        (Number) this.getValue(AVKey.MISSING_DATA_SIGNAL);
263
                    if (AVKey.INT8.equals(dataType)) {
264
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
265
                            noData.byteValue());
266
                    } else if (AVKey.INT16.equals(dataType)) {
267
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
268
                            noData.shortValue());
269
                    } else if (AVKey.INT32.equals(dataType)) {
270
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
271
                            noData.intValue());
272
                    } else if (AVKey.FLOAT32.equals(dataType)) {
273
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
274
                            noData.floatValue());
275
                    } else if (AVKey.FLOAT64.equals(dataType)) {
276
                        setNumberToDataRaster((ByteBufferRaster) canvas, y, x,
277
                            noData.doubleValue());
278
                    }
279
                }
280
            }
281
        }
282
    }
283

    
284
    private Point2D getRasterPoint(int x, int y, DataRaster canvas,
285
        Buffer adjustedBuffer) {
286
        
287
        // Gets coordiantes of pixel raster
288
        Point2D worldPoint =
289
            canvasExtent.rasterToWorld(new Point2D.Double(x, y),
290
                getCellSize(canvas.getSector(), canvas.getWidth()));
291

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

    
299
            if (isPointOfBuffer(rasterPoint, adjustedBuffer)) {
300
                return rasterPoint;
301
            }
302
        }
303
        return null;
304
    }
305

    
306
    private void setCanvasEnxent(Sector canvasSector) {
307
        this.canvasExtent = getExtent(canvasSector);
308
    }
309
    
310
    private void setOverlapExtent(Sector overlap) {
311
        this.overlapExtent = getExtent(overlap);
312
    }
313
    
314
    private Extent getExtent(Sector sector){
315
        Rectangle2D rectangleDegrees = sector.toRectangleDegrees();
316
        RasterManager rasterManager = RasterLocator.getManager();
317
        DataStructFactory dataStructFactory =
318
            rasterManager.getDataStructFactory();
319
        return dataStructFactory.createExtent(rectangleDegrees);
320
    }
321

    
322
    private double getCellSize(Sector sector, int width) {
323

    
324
        Rectangle2D rectangleDegrees = sector.toRectangleDegrees();
325

    
326
        return rectangleDegrees.getWidth() / width;
327
    }
328

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

    
339
    private void setNumberToDataRaster(ByteBufferRaster byteBuferRaster,
340
        int line, int col, Number value) {
341
        byteBuferRaster.setDoubleAtPosition(line, col, value.doubleValue());
342
    }
343
    
344
    private void drawVectElevationOnTo(DataRaster canvas) {
345
        // TODO Auto-generated method stub
346

    
347
    }
348

    
349
    private void drawImageOnTo(DataRaster canvas) {
350
        if (canvas == null) {
351
            throw new IllegalArgumentException();
352
        }
353

    
354
        if (!canvas.getSector().intersects(getSector())) {
355
            return;
356
        }
357

    
358
        Sector overlap = this.getSector().intersection(canvas.getSector());
359

    
360
        ViewPort viewPort =
361
            new ViewPort(mapControl3D.getMapContext().getProjection());
362

    
363
        // Set adjustable to false to avoid problems with adjusted envelope
364
        viewPort.setAdjustable(false);
365

    
366
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
367

    
368
        Envelope envelope = null;
369
        double[] degrees = overlap.asDegreesArray();
370

    
371
        try {
372

    
373
            IProjection projection =
374
                mapControl3D.getMapContext().getProjection();
375

    
376
            ICoordTrans ct = CRSFactory.getCRS("EPSG:4326").getCT(projection);
377
            Point2D p1 =
378
                convert(ct, new Point2D.Double(degrees[2], degrees[0]));
379
            Point2D p2 =
380
                convert(ct, new Point2D.Double(degrees[3], degrees[1]));
381

    
382
            envelope =
383
                geoManager.createEnvelope(Math.min(p1.getX(), p2.getX()),
384
                    Math.min(p1.getY(), p2.getY()),
385
                    Math.max(p1.getX(), p2.getX()),
386
                    Math.max(p1.getY(), p2.getY()), SUBTYPES.GEOM2D);
387

    
388
            /**
389
             * Check if request tile intersect with layer envelope to avoid
390
             * the creation of useless tiles.
391
             */
392
            if (!envelope.intersects(layer.getFullEnvelope())) {
393
                return;
394
            }
395

    
396
            viewPort.setEnvelope(envelope);
397

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

    
407
        int canvasWidth = canvas.getWidth();
408
        int canvasHeight = canvas.getHeight();
409

    
410
        java.awt.Rectangle clipRect = this.computeClipRect(overlap, this);
411
        if (null == clipRect || clipRect.width == 0 || clipRect.height == 0) {
412
            return;
413
        }
414

    
415
        // Apply the transform that correctly maps the image onto the canvas.
416
        java.awt.geom.AffineTransform affineTransform =
417
            this.computeSourceToDestTransform(clipRect.width, clipRect.height,
418
                overlap, canvasWidth, canvasHeight, canvas.getSector());
419

    
420
        // Trick to apply transform to size value
421
        Point2D srcSizePoint =
422
            new Point2D.Double(clipRect.width, clipRect.height);
423
        Point2D dstSizePoint = new Point2D.Double();
424

    
425
        affineTransform.transform(srcSizePoint, dstSizePoint);
426

    
427
        int clipWidth =
428
            (int) Math.ceil((dstSizePoint.getX() >= canvasWidth) ? canvasWidth
429
                : dstSizePoint.getX());
430
        int clipHeight =
431
            (int) Math.ceil((dstSizePoint.getY() >= canvasHeight)
432
                ? canvasHeight : dstSizePoint.getY());
433

    
434
        if (clipWidth <= 0 || clipHeight <= 0) {
435
            return;
436
        }
437

    
438
        BufferedImage image =
439
            new BufferedImage(clipWidth, clipHeight,
440
                BufferedImage.TYPE_INT_ARGB);
441

    
442
        viewPort.setImageSize(new Dimension(clipWidth, clipHeight));
443
        viewPort.refreshExtent();
444

    
445
        try {
446
            layer.draw(image, (Graphics2D) image.getGraphics(), viewPort,
447
                mapControl3D.getCancellable(), getScale(viewPort));
448

    
449
            if (layer instanceof FLyrVect && layer instanceof ILabelable) {
450

    
451
                ILabelable labelable = (ILabelable) layer;
452

    
453
                if (labelable.isLabeled()
454
                    && labelable.getLabelingStrategy() != null
455
                    && labelable.getLabelingStrategy().shouldDrawLabels(
456
                        getScale(viewPort))) {
457

    
458
                    labelable.drawLabels(image,
459
                        (Graphics2D) image.getGraphics(), viewPort,
460
                        mapControl3D.getCancellable(), getScale(viewPort),
461
                        mapControl3D.getMapContext().getViewPort().getDPI());
462
                }
463
            }
464

    
465
        } catch (ReadException e) {
466
            LOG.warn("Can't draw required zone of layer {}, can't read legend",
467
                layer.getName());
468
            return;
469
        } finally {
470
            if (mapControl3D.getCancellable().isCanceled()) {
471
                return;
472
            }
473
        }
474
        BufferedImageRaster bufferedImageRaster =
475
            new BufferedImageRaster(overlap, image);
476
        bufferedImageRaster.drawOnTo(canvas);
477

    
478
    }
479

    
480
    private Point2D convert(ICoordTrans ct, Point2D srcPoint) {
481
        if (ct == null) {
482
            return srcPoint;
483
        }
484
        return ct.convert(srcPoint, null);
485
    }
486

    
487
    private java.awt.geom.AffineTransform computeSourceToDestTransform(
488
        int sourceWidth, int sourceHeight, Sector sourceSector, int destWidth,
489
        int destHeight, Sector destSector) {
490
        // Compute the the transform from source to destination coordinates. In
491
        // this computation a pixel is assumed
492
        // to cover a finite area.
493

    
494
        double ty =
495
            destHeight
496
                * -(sourceSector.getMaxLatitude().degrees - destSector
497
                    .getMaxLatitude().degrees)
498
                / destSector.getDeltaLatDegrees();
499
        double tx =
500
            destWidth
501
                * (sourceSector.getMinLongitude().degrees - destSector
502
                    .getMinLongitude().degrees)
503
                / destSector.getDeltaLonDegrees();
504

    
505
        double sy =
506
            ((double) destHeight / (double) sourceHeight)
507
                * (sourceSector.getDeltaLatDegrees() / destSector
508
                    .getDeltaLatDegrees());
509
        double sx =
510
            ((double) destWidth / (double) sourceWidth)
511
                * (sourceSector.getDeltaLonDegrees() / destSector
512
                    .getDeltaLonDegrees());
513

    
514
        java.awt.geom.AffineTransform transform =
515
            new java.awt.geom.AffineTransform();
516
        transform.translate(tx, ty);
517
        transform.scale(sx, sy);
518
        return transform;
519
    }
520

    
521
    private double getScale(ViewPort viewPort) {
522

    
523
        double dpi = viewPort.getDPI();
524
        IProjection proj = viewPort.getProjection();
525

    
526
        if (viewPort.getImageSize() == null) {
527
            return -1;
528
        }
529

    
530
        if (viewPort.getAdjustedEnvelope() == null) {
531
            return 0;
532
        }
533
        double[] trans2Meter = MapContext.getDistanceTrans2Meter();
534
        int mUnits = viewPort.getMapUnits();
535

    
536
        if (proj == null) {
537
            double w = ((viewPort.getImageSize().width / dpi) * 0.0254);
538
            return (long) (viewPort.getAdjustedEnvelope().getLength(0) / w * trans2Meter[mUnits]);
539
        }
540

    
541
        return Math.round(proj.getScale(viewPort.getAdjustedEnvelope()
542
            .getMinimum(0) * trans2Meter[mUnits], viewPort
543
            .getAdjustedEnvelope().getMaximum(0) * trans2Meter[mUnits],
544
            viewPort.getImageSize().width, dpi));
545
    }
546

    
547
    private Rectangle computeClipRect(Sector clipSector,
548
        DataRaster clippedRaster) {
549

    
550
        AffineTransform geographicToRaster =
551
            this.computeGeographicToRasterTransform(clippedRaster.getWidth(),
552
                clippedRaster.getHeight(), clippedRaster.getSector());
553

    
554
        java.awt.geom.Point2D geoPoint = new java.awt.geom.Point2D.Double();
555
        java.awt.geom.Point2D ul = new java.awt.geom.Point2D.Double();
556
        java.awt.geom.Point2D lr = new java.awt.geom.Point2D.Double();
557

    
558
        geoPoint.setLocation(clipSector.getMinLongitude().degrees,
559
            clipSector.getMaxLatitude().degrees);
560
        geographicToRaster.transform(geoPoint, ul);
561

    
562
        geoPoint.setLocation(clipSector.getMaxLongitude().degrees,
563
            clipSector.getMinLatitude().degrees);
564
        geographicToRaster.transform(geoPoint, lr);
565

    
566
        int x = (int) Math.floor(ul.getX());
567
        int y = (int) Math.floor(ul.getY());
568
        int width = (int) Math.ceil(lr.getX() - ul.getX());
569
        int height = (int) Math.ceil(lr.getY() - ul.getY());
570

    
571
        return new Rectangle(x, y, width, height);
572
    }
573

    
574
    private java.awt.geom.AffineTransform computeGeographicToRasterTransform(
575
        int width, int height, Sector sector) {
576
        // Compute the the transform from geographic to raster coordinates. In
577
        // this computation a pixel is assumed
578
        // to cover a finite area.
579

    
580
        double ty = -sector.getMaxLatitude().degrees;
581
        double tx = -sector.getMinLongitude().degrees;
582

    
583
        double sy = -(height / sector.getDeltaLatDegrees());
584
        double sx = (width / sector.getDeltaLonDegrees());
585

    
586
        java.awt.geom.AffineTransform transform =
587
            new java.awt.geom.AffineTransform();
588
        transform.scale(sx, sy);
589
        transform.translate(tx, ty);
590
        return transform;
591
    }
592

    
593
    public DataRaster getSubRaster(AVList params) {
594
        int width = (Integer) params.getValue(AVKey.WIDTH);
595
        int height = (Integer) params.getValue(AVKey.HEIGHT);
596
        Sector sector = (Sector) params.getValue(AVKey.SECTOR);
597

    
598
        return this.getSubRaster(width, height, sector, params);
599
    }
600

    
601
    public DataRaster getSubRaster(int width, int height, Sector sector,
602
        AVList params) {
603

    
604
        params.setValue(AVKey.WIDTH, width);
605
        params.setValue(AVKey.HEIGHT, height);
606
        params.setValue(AVKey.SECTOR, sector);
607

    
608
        GvSIGLayerDataRaster subRaster =
609
            new GvSIGLayerDataRaster(mapControl3D, layer, params);
610
        return subRaster;
611
    }
612
}