|
12 | 12 | import gov.nasa.worldwind.geopkg.Tile;
|
13 | 13 | import gov.nasa.worldwind.geopkg.TileEntry;
|
14 | 14 | import gov.nasa.worldwind.geopkg.TileMatrix;
|
15 |
| - |
16 | 15 | import gov.nasa.worldwind.gs.wms.map.MapResponseOutputStreamAdaptor;
|
17 |
| -import java.io.ByteArrayOutputStream; |
18 | 16 |
|
| 17 | +import static java.lang.String.format; |
| 18 | + |
| 19 | +import java.io.ByteArrayOutputStream; |
19 | 20 | import java.io.File;
|
20 | 21 | import java.io.IOException;
|
21 | 22 | import java.util.Iterator;
|
|
44 | 45 | import org.geoserver.wms.map.RawMap;
|
45 | 46 | import org.geoserver.wms.map.RenderedImageMap;
|
46 | 47 | import org.geoserver.wms.map.RenderedImageMapResponse;
|
| 48 | +import org.geotools.coverage.grid.io.GridCoverage2DReader; |
47 | 49 |
|
48 | 50 | import org.geotools.geometry.jts.ReferencedEnvelope;
|
49 | 51 | import org.geotools.referencing.CRS;
|
| 52 | +import org.geotools.renderer.lite.RendererUtilities; |
50 | 53 | import org.geotools.util.logging.Logging;
|
51 | 54 |
|
52 | 55 | import org.geowebcache.grid.Grid;
|
53 | 56 | import org.geowebcache.grid.GridSet;
|
54 | 57 | import org.geowebcache.grid.GridSubset;
|
55 | 58 |
|
| 59 | +import org.opengis.coverage.grid.GridEnvelope; |
56 | 60 | import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
57 | 61 |
|
58 | 62 | /**
|
@@ -245,6 +249,67 @@ public WebMap produceMap(WMSMapContent mapContent) throws ServiceException, IOEx
|
245 | 249 | return super.produceMap(mapContent);
|
246 | 250 | }
|
247 | 251 |
|
| 252 | + /** |
| 253 | + * Returns the zoom level, plus one, closest to the highest resolution |
| 254 | + * coverage used in the map request. This is the ending value used in loops |
| 255 | + * that process the levels, it is not the max zoom level in the GeoPackage. |
| 256 | + * |
| 257 | + * Overrides the base class behavior which returned a "zoom level + 1" where |
| 258 | + * the zoom level contained at least 256 tiles. |
| 259 | + * |
| 260 | + * @param gridSubset the grid for the GeoPackage |
| 261 | + * @param minZoom the starting zoom level |
| 262 | + * @param request the map request containing the layer coverages |
| 263 | + * @return the selected maximum zoom level + 1 |
| 264 | + */ |
| 265 | + @Override |
| 266 | + protected Integer findMaxZoomAuto(GridSubset gridSubset, Integer minZoom, GetMapRequest request) { |
| 267 | + |
| 268 | + // Get the maximum scale for the highest resolution layer: |
| 269 | + // loop through the layer coverages associated with the request |
| 270 | + // and compute the scale for each. |
| 271 | + List<MapLayerInfo> layers = request.getLayers(); |
| 272 | + double reqScaleDenominator = Double.MAX_VALUE; |
| 273 | + for (MapLayerInfo layer : layers) { |
| 274 | + try { |
| 275 | + if (layer.getType() == MapLayerInfo.TYPE_RASTER) { |
| 276 | + // Get the width of the underlying coverage |
| 277 | + GridCoverage2DReader coverageReader = (GridCoverage2DReader) layer.getCoverageReader(); |
| 278 | + GridEnvelope originalGridRange = coverageReader.getOriginalGridRange(); |
| 279 | + int imageWidth = originalGridRange.getSpan(0); // 0=cols, 1=rows |
| 280 | + // Compute the scale demonimator |
| 281 | + ReferencedEnvelope bounds = this.bounds(request); |
| 282 | + double scale = RendererUtilities.calculateOGCScale(bounds, imageWidth, null); |
| 283 | + // Select the largest scale (the smallest denominator) |
| 284 | + reqScaleDenominator = Math.min(scale, reqScaleDenominator); |
| 285 | + } |
| 286 | + } catch (Exception e) { |
| 287 | + LOGGER.warning( |
| 288 | + format("Exception caught computing the scale for layer %s: %s", |
| 289 | + layer.getName(), e.toString())); |
| 290 | + } |
| 291 | + } |
| 292 | + if (reqScaleDenominator < Double.MAX_VALUE) { |
| 293 | + // Find the level with the closest scale denominator to the required scale |
| 294 | + GridSet gridSet = gridSubset.getGridSet(); |
| 295 | + int i = minZoom; |
| 296 | + double error = Math.abs(gridSet.getGrid(i).getScaleDenominator() - reqScaleDenominator); |
| 297 | + while (i < gridSet.getNumLevels() - 1) { |
| 298 | + Grid g = gridSet.getGrid(i + 1); |
| 299 | + double e = Math.abs(g.getScaleDenominator() - reqScaleDenominator); |
| 300 | + if (e > error) { |
| 301 | + break; |
| 302 | + } |
| 303 | + error = e; |
| 304 | + i++; |
| 305 | + } |
| 306 | + // Return the selected zoom level + 1; this is the ending index |
| 307 | + // used in loops, not the max zoom level in the GeoPackage |
| 308 | + return Math.max(i + 1, 0); |
| 309 | + } |
| 310 | + return super.findMaxZoomAuto(gridSubset, minZoom, request); |
| 311 | + } |
| 312 | + |
248 | 313 | /**
|
249 | 314 | * Gets a tile set name in the form of a valid SQLite table name from the
|
250 | 315 | * map layers.
|
|
0 commit comments