Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.tilecache / org.gvsig.raster.tilecache.provider / src / main / java / org / gvsig / raster / tilecache / provider / FileTileCacheStructImage.java @ 8788

History | View | Annotate | Download (26 KB)

1 6340 dmartinezizquierdo
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2016 gvSIG Association
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., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.raster.tilecache.provider;
24
25
import java.io.File;
26 6509 fdiaz
import java.io.IOException;
27
import java.util.ArrayList;
28 6385 fdiaz
import java.util.HashMap;
29 6340 dmartinezizquierdo
import java.util.Iterator;
30 6509 fdiaz
import java.util.List;
31 6385 fdiaz
import java.util.Map;
32 6502 fdiaz
import java.util.Map.Entry;
33
import java.util.Set;
34 6340 dmartinezizquierdo
import java.util.TreeMap;
35
36
import javax.xml.parsers.DocumentBuilder;
37
import javax.xml.parsers.DocumentBuilderFactory;
38 6509 fdiaz
import javax.xml.parsers.ParserConfigurationException;
39
import javax.xml.transform.OutputKeys;
40
import javax.xml.transform.Transformer;
41
import javax.xml.transform.TransformerException;
42
import javax.xml.transform.TransformerFactory;
43
import javax.xml.transform.dom.DOMSource;
44
import javax.xml.transform.stream.StreamResult;
45 6340 dmartinezizquierdo
46 6518 fdiaz
import org.apache.commons.io.FileUtils;
47 6340 dmartinezizquierdo
import org.apache.commons.io.FilenameUtils;
48 6511 fdiaz
import org.apache.commons.lang3.StringUtils;
49 6340 dmartinezizquierdo
import org.cresques.cts.IProjection;
50 6385 fdiaz
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52 6509 fdiaz
import org.w3c.dom.Attr;
53 6385 fdiaz
import org.w3c.dom.Document;
54
import org.w3c.dom.Element;
55
import org.w3c.dom.NamedNodeMap;
56
import org.w3c.dom.Node;
57
import org.w3c.dom.NodeList;
58 6342 fdiaz
59 6340 dmartinezizquierdo
import org.gvsig.fmap.dal.DALFileLocator;
60 6488 fdiaz
import org.gvsig.fmap.dal.DataServerExplorer;
61
import org.gvsig.fmap.dal.DataServerExplorerParameters;
62 6509 fdiaz
import org.gvsig.fmap.dal.DataStore;
63 6340 dmartinezizquierdo
import org.gvsig.fmap.dal.DataStoreProviderFactory;
64
import org.gvsig.fmap.dal.exception.DataException;
65
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
66 6527 fdiaz
import org.gvsig.fmap.dal.raster.api.NewRasterStoreParameters;
67 6488 fdiaz
import org.gvsig.fmap.dal.raster.api.RasterQuery;
68 6505 fdiaz
import org.gvsig.fmap.dal.raster.api.RasterSet;
69 6340 dmartinezizquierdo
import org.gvsig.fmap.dal.raster.api.RasterStore;
70 6420 fdiaz
import org.gvsig.fmap.dal.raster.spi.RasterStoreProvider;
71 6340 dmartinezizquierdo
import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerManager;
72
import org.gvsig.fmap.dal.serverexplorer.filesystem.spi.FilesystemServerExplorerProviderFactory;
73
import org.gvsig.fmap.dal.spi.DALSPILocator;
74
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
75
import org.gvsig.fmap.geom.Geometry.DIMENSIONS;
76
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
77
import org.gvsig.fmap.geom.GeometryLocator;
78
import org.gvsig.fmap.geom.GeometryManager;
79 6488 fdiaz
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
80 6340 dmartinezizquierdo
import org.gvsig.fmap.geom.primitive.Envelope;
81
import org.gvsig.raster.lib.buffer.api.Band;
82 6385 fdiaz
import org.gvsig.raster.lib.buffer.api.Buffer;
83
import org.gvsig.raster.lib.buffer.api.BufferLocator;
84
import org.gvsig.raster.lib.buffer.api.BufferManager;
85 6509 fdiaz
import org.gvsig.raster.lib.buffer.api.TileStruct;
86 6385 fdiaz
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
87 6509 fdiaz
import org.gvsig.raster.lib.buffer.spi.DefaultTileStruct;
88 6498 fdiaz
import org.gvsig.tools.ToolsLocator;
89 6509 fdiaz
import org.gvsig.tools.dispose.Disposable;
90 6494 fdiaz
import org.gvsig.tools.dispose.DisposeUtils;
91 6340 dmartinezizquierdo
import org.gvsig.tools.dynobject.DynObject;
92 6498 fdiaz
import org.gvsig.tools.exception.BaseException;
93 6340 dmartinezizquierdo
import org.gvsig.tools.extensionpoint.ExtensionPoint.Extension;
94 6342 fdiaz
95 6340 dmartinezizquierdo
/**
96
 * Represents a tiled image
97 6491 fdiaz
 *
98 6340 dmartinezizquierdo
 * @author dmartinezizquierdo
99
 *
100
 */
101 6520 fdiaz
public class FileTileCacheStructImage extends AbstractTileCacheStructImage {
102 6340 dmartinezizquierdo
103 6520 fdiaz
    private static final Logger logger = LoggerFactory.getLogger(FileTileCacheStructImage.class);
104 6403 fdiaz
    private static final int MAX_RECENT_ACCEDED_TILES_NUMBER = 50;
105 6340 dmartinezizquierdo
106 6342 fdiaz
    private FilesystemServerExplorerProviderFactory factory;
107
    private String extension;
108 6340 dmartinezizquierdo
    private File tilesFolder;
109
110
    private IProjection crs;
111
112 6342 fdiaz
    /**
113
     * @param folder
114
     * @param crs
115 6488 fdiaz
     * @param innerProvider
116 6516 fdiaz
     * @param query
117 6342 fdiaz
     */
118 6520 fdiaz
    public FileTileCacheStructImage(File folder, IProjection crs, RasterStoreProvider innerProvider, RasterQuery query) {
119 6516 fdiaz
        super(innerProvider, query);
120 6488 fdiaz
        this.crs = crs;
121
        GeometryManager geoManager = GeometryLocator.getGeometryManager();
122 6511 fdiaz
        getTileStruct();
123 6385 fdiaz
124 6509 fdiaz
        // FIXME
125
        File tilePropertiesFile = new File(folder, "tileCacheStruct.xml");
126
        if (!tilePropertiesFile.exists()) {
127
            createTileCacheStructXMLFile(folder);
128
        }
129
130
        TreeMap<Integer, Double> pixelSizePerZoomLevel = new TreeMap<Integer, Double>();
131 6385 fdiaz
        recentAccededTiles = new HashMap<String, Tile>();
132 6340 dmartinezizquierdo
133 6488 fdiaz
        tilesFolder = new File(folder, "V" + File.separatorChar + "Z" + File.separatorChar + "T");
134 6491 fdiaz
        if (!tilesFolder.exists()) {
135 6488 fdiaz
            tilesFolder.mkdirs();
136
        }
137 6340 dmartinezizquierdo
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
138
        DocumentBuilder dBuilder;
139
        try {
140
            dBuilder = dbFactory.newDocumentBuilder();
141
            Document doc = dBuilder.parse(tilePropertiesFile);
142
143
            doc.getDocumentElement().normalize();
144
145
            NodeList nList = doc.getElementsByTagName("TileCacheStruct");
146
            for (int temp = 0; temp < nList.getLength(); temp++) {
147
148
                Node nNode = nList.item(temp);
149
150
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
151
                    Element eElement = (Element) nNode;
152
153
                    NamedNodeMap tileSizeAttributes = eElement.getElementsByTagName("tileSize").item(0).getAttributes();
154 6509 fdiaz
                    tileStruct.setRowsPerTile(Integer.valueOf(tileSizeAttributes.getNamedItem("rows").getNodeValue()));
155
                    tileStruct.setColumnsPerTile(Integer.valueOf(tileSizeAttributes.getNamedItem("columns").getNodeValue()));
156 6340 dmartinezizquierdo
157
                    NodeList elementsByTagName = eElement.getElementsByTagName("format");
158 6509 fdiaz
                    tileStruct.setProviderName(elementsByTagName.item(0).getTextContent());
159 6340 dmartinezizquierdo
160 6385 fdiaz
                    NodeList structExtentList = eElement.getElementsByTagName("structExtent");
161 6488 fdiaz
                    if (structExtentList.getLength() > 0) {
162
                        Element structExtentNode = (Element) structExtentList.item(0);
163
                        if (structExtentNode != null) {
164
                            Double minX =
165
                                Double.valueOf(structExtentNode.getElementsByTagName("minX").item(0).getTextContent());
166
                            Double minY =
167
                                Double.valueOf(structExtentNode.getElementsByTagName("minY").item(0).getTextContent());
168
                            Double maxX =
169
                                Double.valueOf(structExtentNode.getElementsByTagName("maxX").item(0).getTextContent());
170
                            Double maxY =
171
                                Double.valueOf(structExtentNode.getElementsByTagName("maxY").item(0).getTextContent());
172 6509 fdiaz
                            tileStruct.setEnvelope(geoManager.createEnvelope(minX, minY, maxX, maxY, SUBTYPES.GEOM2D));                        }
173 6385 fdiaz
                    }
174
175 6488 fdiaz
                    FilesystemServerExplorerManager explorerManager =
176
                        DALFileLocator.getFilesystemServerExplorerManager();
177 6342 fdiaz
                    @SuppressWarnings("unchecked")
178
                    Iterator<Extension> it = explorerManager.getRegisteredProviders();
179 6488 fdiaz
                    while (it.hasNext()) {
180 6340 dmartinezizquierdo
181 6342 fdiaz
                        Extension ext = it.next();
182 6340 dmartinezizquierdo
                        FilesystemServerExplorerProviderFactory providerFactory;
183
                        try {
184
                            providerFactory = (FilesystemServerExplorerProviderFactory) ext.create();
185 6509 fdiaz
                            if (providerFactory.getName().equalsIgnoreCase(tileStruct.getProviderName())) {
186 6340 dmartinezizquierdo
                                this.factory = providerFactory;
187
                                break;
188
                            }
189
                        } catch (Exception e) {
190
                            throw new RuntimeException(e);// FIXME !!!
191
                        }
192
                    }
193
194
                    NodeList levelsTag = eElement.getElementsByTagName("levels");
195 6488 fdiaz
                    Element levels = (Element) levelsTag.item(0);
196
                    NodeList levelList = levels.getElementsByTagName("level");
197 6340 dmartinezizquierdo
                    for (int i = 0; i < levelList.getLength(); i++) {
198 6488 fdiaz
                        Element level = (Element) levelList.item(i);
199 6385 fdiaz
200
                        NamedNodeMap levelAttributes = level.getAttributes();
201 6488 fdiaz
                        int zoomLevel = Integer.valueOf(levelAttributes.getNamedItem("index").getNodeValue());
202
                        double pixelSize = Double.valueOf(levelAttributes.getNamedItem("pixelSize").getNodeValue());
203 6385 fdiaz
204 6340 dmartinezizquierdo
                        pixelSizePerZoomLevel.put(zoomLevel, pixelSize);
205 6385 fdiaz
206 6340 dmartinezizquierdo
                    }
207 6509 fdiaz
                    this.tileStruct.setPixelSizePerZoomLevel(pixelSizePerZoomLevel);
208 6340 dmartinezizquierdo
                }
209
            }
210
        } catch (Exception e) {
211
            throw new RuntimeException();
212
        }
213
    }
214
215 6516 fdiaz
    @Override
216 6654 fdiaz
    public Band fetchTile(int bandNumber, int zoomLevel, int structRow, int structCol) {
217 6340 dmartinezizquierdo
218 6385 fdiaz
        BufferManager bufferManager = BufferLocator.getBufferManager();
219 6340 dmartinezizquierdo
220 6385 fdiaz
        String keyTile = composeKeyForRecentTiles(zoomLevel, structRow, structCol);
221
        Tile tile = recentAccededTiles.get(keyTile);
222 6340 dmartinezizquierdo
223 6385 fdiaz
        if (tile != null) {
224
            // Devolver la banda del buffer del tile
225 6506 fdiaz
            return tile.getBuffer().getBand(bandNumber);
226 6385 fdiaz
        } else {
227
            // Cargar un tile nuevo
228
            Buffer rasterSet = null;
229
            RasterStore tileStore = null;
230 6505 fdiaz
            RasterSet tileStoreRasterSet = null;
231 6385 fdiaz
            try {
232
                tileStore = createTileStore(zoomLevel, structRow, structCol);
233 6505 fdiaz
                tileStoreRasterSet = tileStore.getRasterSet();
234
                rasterSet = bufferManager.createBuffer(tileStoreRasterSet, false);
235 6342 fdiaz
236 6498 fdiaz
                if (recentAccededTiles.size() >= MAX_RECENT_ACCEDED_TILES_NUMBER) {
237 6385 fdiaz
                    removeOlderTile();
238
                }
239
                recentAccededTiles.put(keyTile, new Tile(rasterSet, keyTile));
240
241 6506 fdiaz
                Band band = rasterSet.getBand(bandNumber);
242
                ToolsLocator.getDisposableManager().bind(band);
243
                return band;
244 6654 fdiaz
            } catch (DataException | BufferException | ValidateDataParametersException | CreateEnvelopeException | CloneNotSupportedException e) {
245 6509 fdiaz
                logger.warn("Can't fetch tile: zoomLevel = " + zoomLevel + ", tileRow = " + structRow
246
                    + ", tileColumn = " + structCol + ", band = " + bandNumber + ".", e);
247 6385 fdiaz
                return null;
248
            } finally {
249 6509 fdiaz
                DisposeUtils.dispose(tileStore);
250
                tileStore = null;
251
                DisposeUtils.dispose(tileStoreRasterSet);
252
                tileStoreRasterSet = null;
253
                DisposeUtils.dispose(rasterSet);
254
                rasterSet = null;
255 6385 fdiaz
            }
256
        }
257
    }
258
259 6654 fdiaz
    private RasterStore createTileStore(int zoomLevel, int structRow, int structCol) throws ValidateDataParametersException, CreateEnvelopeException, BufferException, DataException, CloneNotSupportedException {
260 6385 fdiaz
261
        File tileFile = null;
262
        File zoomFolder = new File(tilesFolder, String.valueOf(zoomLevel));
263 6488 fdiaz
        if (!zoomFolder.exists()) {
264
            zoomFolder.mkdirs();
265
        }
266
        File firstColumnFolder = new File(zoomFolder, String.valueOf(structCol));
267
        if (!firstColumnFolder.exists()) {
268
            tileFile = requestTileFile(zoomLevel, structRow, structCol);
269
            this.extension = FilenameUtils.getExtension(tileFile.getAbsolutePath());
270
        }
271
        String rowBaseName = String.valueOf(structRow);
272
        if (this.extension == null) {
273
            File[] providerAcceptedFiles = firstColumnFolder.listFiles(factory);
274
            for (int i = 0; i < providerAcceptedFiles.length; i++) {
275
                File providerAcceptedFile = providerAcceptedFiles[i];
276
                if (FilenameUtils.getBaseName(providerAcceptedFile.getAbsolutePath()).equalsIgnoreCase(rowBaseName)) {
277
                    tileFile = providerAcceptedFile;
278
                }
279
            }
280
            if (tileFile == null || !tileFile.exists()) {
281
                tileFile = requestTileFile(zoomLevel, structRow, structCol);
282
            }
283
            this.extension = FilenameUtils.getExtension(tileFile.getAbsolutePath());
284
        } else {
285
            if (tileFile == null) {
286
                tileFile =
287
                    new File(firstColumnFolder.getAbsolutePath() + File.separatorChar + rowBaseName + "."
288
                        + this.extension);
289
            }
290
        }
291
        if (!tileFile.exists()) {
292
            tileFile = requestTileFile(zoomLevel, structRow, structCol);
293
        }
294
        RasterStore tileStore = null;
295
        DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
296 6509 fdiaz
        DataStoreProviderFactory providerFactory = manager.getStoreProviderFactory(this.tileStruct.getProviderName());
297 6385 fdiaz
298 6488 fdiaz
        DynObject params = providerFactory.createParameters();
299
        if (params.getDynClass().getDynField("file") != null) {
300
            params.setDynValue("file", tileFile);
301
        }
302
        if (params.getDynClass().getDynField("crs") != null) {
303
            params.setDynValue("crs", this.crs);
304
        }
305 6385 fdiaz
306 6509 fdiaz
        tileStore = (RasterStore) manager.openStore(this.tileStruct.getProviderName(), params);
307 6488 fdiaz
        return tileStore;
308
    }
309 6385 fdiaz
310 6509 fdiaz
    private File requestTileFile(int zoomLevel, int structRow, int structCol) throws CreateEnvelopeException,
311
        CloneNotSupportedException, BufferException, ValidateDataParametersException, DataException {
312 6385 fdiaz
313 6488 fdiaz
        RasterQuery rasterQuery = (RasterQuery) this.query.clone();
314
315 6509 fdiaz
        Double pixelSize = this.tileStruct.getPixelSizePerZoomLevel().get(zoomLevel);
316 6488 fdiaz
        rasterQuery.setPixelSize(pixelSize);
317
318
        GeometryManager geomManager = GeometryLocator.getGeometryManager();
319
320 6509 fdiaz
        Envelope structExtent = this.tileStruct.getEnvelope();
321
        int rowsPerTile = this.tileStruct.getRowsPerTile();
322
        int columnsPerTile = this.tileStruct.getColumnsPerTile();
323 6491 fdiaz
        double minX = structExtent.getMinimum(DIMENSIONS.X) + structCol * (pixelSize * columnsPerTile);
324
        double minY = structExtent.getMaximum(DIMENSIONS.Y) - ((structRow + 1) * (pixelSize * rowsPerTile));
325
        double maxX = minX + pixelSize * columnsPerTile;
326
        double maxY = minY + pixelSize * rowsPerTile;
327 6497 fdiaz
        Envelope envelope = geomManager.createEnvelope(minX, minY, maxX, maxY, SUBTYPES.GEOM2D);
328 6527 fdiaz
        rasterQuery.setClip(envelope);
329 6488 fdiaz
330 6497 fdiaz
        Buffer buffer = null;
331
        Buffer clippedBuffer = null;
332
        Buffer interpolatedBuffer = null;
333
        File destFile = null;
334 6488 fdiaz
335 6497 fdiaz
        try {
336
            buffer = innerProvider.createBuffer(rasterQuery);
337
            clippedBuffer = buffer.clip(envelope);
338
            interpolatedBuffer =
339
                clippedBuffer.createInterpolated(
340
                    (int) (Math.round(clippedBuffer.getPixelSizeY() * clippedBuffer.getRows() / pixelSize)),
341
                    (int) (Math.round(clippedBuffer.getPixelSizeX() * clippedBuffer.getColumns() / pixelSize)),
342 8788 fdiaz
                    Buffer.INTERPOLATION_Bilinear, null);
343 6488 fdiaz
344 6497 fdiaz
            String providerName = "GTiff";
345
            String extension = "tif";
346 6494 fdiaz
347 6497 fdiaz
            DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
348
            DataServerExplorerParameters eparams;
349
            eparams = manager.createServerExplorerParameters("FilesystemExplorer");
350 6488 fdiaz
351 6557 fdiaz
            destFile = FileUtils.getFile(tilesFolder,Integer.toString(zoomLevel),Integer.toString(structCol),Integer.toString(structRow)+"."+extension);
352
353 6497 fdiaz
            File parent = destFile.getParentFile();
354
            if (!parent.exists()) {
355
                parent.mkdirs();
356
            }
357 6557 fdiaz
            eparams.setDynValue("initialpath", destFile);
358
//            DataServerExplorer serverExplorer = manager.createServerExplorer(eparams);
359
            DataServerExplorer serverExplorer = manager.openServerExplorer(eparams.getExplorerName(), eparams);
360 6488 fdiaz
361 6497 fdiaz
            NewRasterStoreParameters params = (NewRasterStoreParameters) serverExplorer.getAddParameters(providerName);
362
            params.setDynValue("file", destFile);
363 6488 fdiaz
364 6497 fdiaz
            params.setDynValue("compress", "NONE");
365
            params.setDynValue("tfw", false);
366 6504 fdiaz
367 6509 fdiaz
            // FIXME: Ver de coger estos dos valores del inner provider para que
368
            // los tiles sean homog?neos con el raster original
369
            int bands = innerProvider.getBands();
370
            switch (bands) {
371
            case 3:
372
                params.setDynValue("photometric", "RGB");
373
                break;
374
            case 4:
375
                params.setDynValue("photometric", "RGB");
376
                params.setDynValue("alpha", "NON-PREMULTIPLIED");
377
                break;
378
            default:
379 6542 fdiaz
                params.setDynValue("photometric", "MINISBLACK");
380 6509 fdiaz
                break;
381
            }
382 6488 fdiaz
383 6497 fdiaz
            params.setBuffer(interpolatedBuffer);
384
            serverExplorer.add(providerName, params, true);
385
        } finally {
386 6509 fdiaz
            DisposeUtils.dispose(buffer);
387
            DisposeUtils.dispose(clippedBuffer);
388
            DisposeUtils.dispose(interpolatedBuffer);
389 6497 fdiaz
        }
390 6488 fdiaz
391
        return destFile;
392 6340 dmartinezizquierdo
    }
393
394 6502 fdiaz
    @Override
395
    protected void doDispose() throws BaseException {
396 6509 fdiaz
        if (recentAccededTiles != null) {
397 6502 fdiaz
            Set<Entry<String, Tile>> entrySet = recentAccededTiles.entrySet();
398 6516 fdiaz
            for (Iterator<Entry<String, Tile>> iterator = entrySet.iterator(); iterator.hasNext();) {
399 6502 fdiaz
                Entry<String, Tile> entry = (Entry<String, Tile>) iterator.next();
400
                DisposeUtils.dispose(entry.getValue());
401
            }
402
            recentAccededTiles.clear();
403
        }
404 6509 fdiaz
        DisposeUtils.dispose(innerProvider);
405
        innerProvider = null;
406
        DisposeUtils.dispose((Disposable) tileStruct);
407
        tileStruct = null;
408
409
        query = null;
410
        factory = null;
411
        crs = null;
412
        colorInterpretation = null;
413
        legend = null;
414
        colorTable = null;
415
    }
416
417
    private void createTileCacheStructXMLFile(File folder) {
418 6511 fdiaz
419
        TileStruct tileStructProvider = null;
420
421 6528 fdiaz
        if (innerProvider != null) {
422 6527 fdiaz
            tileStructProvider = innerProvider.getTileStruct();
423 6511 fdiaz
        }
424
425 6510 fdiaz
        int tileSizeX = TileCacheLibrary.DEFAULT_TILEWIDTH;
426 6511 fdiaz
        if(tileStructProvider!=null && tileStructProvider.getColumnsPerTile()!=0){
427
            tileSizeX = tileStructProvider.getColumnsPerTile();
428
        }
429
430 6510 fdiaz
        int tileSizeY = TileCacheLibrary.DEFAULT_TILEHEIGHT;
431 6511 fdiaz
        if(tileStructProvider!=null && tileStructProvider.getRowsPerTile()!=0){
432
            tileSizeY = tileStructProvider.getRowsPerTile();
433
        }
434 6509 fdiaz
435
        File file = new File(folder, "tileCacheStruct.xml");
436
437
        if (!file.exists()) {
438
            Buffer auxBuffer = null;
439
            try {
440
                DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
441
                DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
442
443
                // root elements
444
                Document doc = (Document) docBuilder.newDocument();
445
                Element rootElement = doc.createElement("TileCacheStruct");
446
                doc.appendChild(rootElement);
447
448
                // tileSize
449
                Element tileSize = doc.createElement("tileSize");
450
                rootElement.appendChild(tileSize);
451
452
                // tileSize Rows
453
                Attr rows = doc.createAttribute("rows");
454
                rows.setValue(String.valueOf(tileSizeY));
455
                tileSize.setAttributeNode(rows);
456
457
                // tileSize Columns
458
                Attr columns = doc.createAttribute("columns");
459
                columns.setValue(String.valueOf(tileSizeX));
460
                tileSize.setAttributeNode(columns);
461
462
                // format
463
                Element format = doc.createElement("format");
464 6511 fdiaz
                if(tileStructProvider==null || StringUtils.isEmpty(tileStructProvider.getProviderName())){
465
                    format.setTextContent("GTiff");
466
                }
467 6509 fdiaz
                rootElement.appendChild(format);
468
469
                // structExtent
470
                Element structExtent = doc.createElement("structExtent");
471
                rootElement.appendChild(structExtent);
472
473
                Envelope envelope = (Envelope) innerProvider.getDynValue(DataStore.METADATA_ENVELOPE);
474
475
                // structExtent minX
476
                Element minX = doc.createElement("minX");
477
                minX.setTextContent(String.valueOf(envelope.getMinimum(DIMENSIONS.X)));
478
                structExtent.appendChild(minX);
479
480
                // structExtent minY
481
                Element minY = doc.createElement("minY");
482
                minY.setTextContent(String.valueOf(envelope.getMinimum(DIMENSIONS.Y)));
483
                structExtent.appendChild(minY);
484
485
                // structExtent maxX
486
                Element maxX = doc.createElement("maxX");
487
                maxX.setTextContent(String.valueOf(envelope.getMaximum(DIMENSIONS.X)));
488
                structExtent.appendChild(maxX);
489
490
                // structExtent maxY
491
                Element maxY = doc.createElement("maxY");
492
                maxY.setTextContent(String.valueOf(envelope.getMaximum(DIMENSIONS.Y)));
493
                structExtent.appendChild(maxY);
494
495
                Element levels = doc.createElement("levels");
496
                rootElement.appendChild(levels);
497
498 6511 fdiaz
                List<Double> pixelSizes = new ArrayList<Double>();
499
                Map<Integer, Double> zoomLevels = new HashMap<Integer, Double>();
500 6509 fdiaz
501 6511 fdiaz
                if (tileStructProvider==null || tileStructProvider.getPixelSizePerZoomLevel() == null) {
502
                    // FIXME: ?alguna otra forma de obtener el pixelSize del store completo?
503
                    auxBuffer = innerProvider.createBuffer(null);
504
                    int completeRows = auxBuffer.getRows();
505
                    int completeColumns = auxBuffer.getColumns();
506
                    double completePixelSizeX = auxBuffer.getPixelSizeX();
507
                    double completePixelSizeY = auxBuffer.getPixelSizeY();
508 6509 fdiaz
509 6511 fdiaz
                    int maximumLength = completeColumns;
510
                    int tileMaximumLength = tileSizeX;
511
                    double maximumPixelSize = completePixelSizeX;
512 6509 fdiaz
513 6511 fdiaz
                    if (completeRows * tileSizeY > completeColumns * tileSizeX) {
514
                        maximumLength = completeRows;
515
                        tileMaximumLength = tileSizeY;
516
                        maximumPixelSize = completePixelSizeY;
517
                    }
518 6509 fdiaz
519 6511 fdiaz
                    double pixelSize = maximumPixelSize;
520
                    while (maximumLength * maximumPixelSize / pixelSize > tileMaximumLength) {
521
                        pixelSizes.add(pixelSize);
522
                        pixelSize = pixelSize * 2;
523
                    }
524 6509 fdiaz
                    pixelSizes.add(pixelSize);
525 6511 fdiaz
                    int i = 0;
526
                    for (int zoomLevel = pixelSizes.size() - 1; zoomLevel >= 0; zoomLevel--) {
527
                        zoomLevels.put(i, pixelSizes.get(zoomLevel));
528
                        appendZoomLevel(doc, levels, i, pixelSizes.get(zoomLevel));
529
                        i++;
530
                    }
531
                } else {
532
                    zoomLevels = tileStructProvider.getPixelSizePerZoomLevel();
533 6509 fdiaz
                }
534
535 6511 fdiaz
                for (Entry<Integer, Double> entry : zoomLevels.entrySet()) {
536
                    appendZoomLevel(doc, levels, entry.getKey(), entry.getValue());
537 6509 fdiaz
                }
538
539
                // write the content into xml file
540
541
                DOMSource source = new DOMSource(doc);
542
                File parent = file.getParentFile();
543
                if (!parent.exists()) {
544
                    parent.mkdirs();
545
                }
546
                file.createNewFile();
547
                StreamResult result = new StreamResult(file.toURI().getPath());
548
549
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
550
                Transformer transformer = transformerFactory.newTransformer();
551
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
552
                transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
553
                transformer.transform(source, result);
554
555
            } catch (ParserConfigurationException | TransformerException | IOException | BufferException e) {
556
                logger.warn("Can't create tileCacheStruct.xml file", e);
557
            } finally {
558
                DisposeUtils.dispose(auxBuffer);
559
                auxBuffer = null;
560
            }
561 6502 fdiaz
        }
562
    }
563
564 6509 fdiaz
    /**
565
     * @param doc
566
     * @param rootElement
567
     * @param levels
568
     * @param zoomLevel
569
     * @param pixelSize
570
     */
571
    private void appendZoomLevel(Document doc, Element levels, int zoomLevel, double pixelSize) {
572
        Element level = doc.createElement("level");
573
        levels.appendChild(level);
574
575
        // level zoomLevel
576
        Attr index = doc.createAttribute("index");
577
        index.setValue(String.valueOf(zoomLevel));
578
        level.setAttributeNode(index);
579
580
        // level pixelSize
581
        Attr pxSize = doc.createAttribute("pixelSize");
582
        pxSize.setValue(String.valueOf(pixelSize));
583
        level.setAttributeNode(pxSize);
584
    }
585
586 6516 fdiaz
    /* (non-Javadoc)
587
     * @see org.gvsig.raster.tilecache.provider.ITileStructImage#getTileStruct()
588
     */
589
    @Override
590 6509 fdiaz
    public TileStruct getTileStruct() {
591
        if(this.tileStruct==null){
592
            this.tileStruct = new DefaultTileStruct();
593
        }
594
        return this.tileStruct;
595
    }
596 6518 fdiaz
597
    public void forgetCache() {
598
        super.forgetCache();
599
        if(tilesFolder.exists() && tilesFolder.isDirectory()){
600
            File[] files = tilesFolder.listFiles();
601
            for(int i=0; i<files.length; i++){
602
                try {
603
                    FileUtils.forceDelete(files[i]);
604
                } catch (IOException e) {
605
                    logger.warn("Can't delete the file "+files[i].getAbsolutePath(), e);
606
                }
607
            }
608
        }
609
    }
610 6340 dmartinezizquierdo
}