/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geogig.geoserver.gwc; import org.geoserver.gwc.layer.GeoServerTileLayer; import org.geowebcache.grid.BoundingBox; import org.geowebcache.grid.GridSubset; import org.geowebcache.storage.TileRangeMask; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; class GeometryTileRangeMask implements TileRangeMask { private Geometry geometryMask; private GridSubset gridSubset; private long[][] byLevelTileCoverage; GeometryTileRangeMask(Geometry geometryMask, GridSubset gridSubset, long[][] byLevelTileCoverage) { this.geometryMask = geometryMask; this.gridSubset = gridSubset; this.byLevelTileCoverage = byLevelTileCoverage; } @Override public long[][] getGridCoverages() { return byLevelTileCoverage.clone(); } @Override public boolean lookup(final long tileX, final long tileY, final int level) { final long[] levelCoverage = getGridCoverages()[level]; final long minxTileX = levelCoverage[0]; final long maxTileX = levelCoverage[2]; final long minTileY = levelCoverage[1]; final long maxTileY = levelCoverage[3]; if (tileX < minxTileX || tileX > maxTileX || tileY < minTileY || tileY > maxTileY) { return false; } long[] tileIndex = new long[] { tileX, tileY, level }; Envelope tileBounds = toEnvelope(gridSubset.boundsFromIndex(tileIndex)); /* * Instead of "resampling"/buffering the geometry which can be time/heap consuming, increase * the size of the tile bounds by the length of a tile on each direction */ tileBounds.expandBy(tileBounds.getWidth(), tileBounds.getHeight()); Geometry expandedTileBoundsGeom = geometryMask.getFactory().toGeometry(tileBounds); boolean intersects = geometryMask.intersects(expandedTileBoundsGeom); return intersects; } public static TileRangeMask build(GeoServerTileLayer tileLayer, GridSubset gridSubset, Geometry geomInGridsetCrs) { BoundingBox maskBounds = toBoundingBox(geomInGridsetCrs.getEnvelopeInternal()); long[][] byLevelTileCoverage = gridSubset.getCoverageIntersections(maskBounds); return new GeometryTileRangeMask(geomInGridsetCrs, gridSubset, byLevelTileCoverage); } private static BoundingBox toBoundingBox(Envelope env) { return new BoundingBox(env.getMinX(), env.getMinY(), env.getMaxX(), env.getMaxY()); } private static Envelope toEnvelope(BoundingBox bounds) { return new Envelope(bounds.getMinX(), bounds.getMaxX(), bounds.getMinY(), bounds.getMaxY()); } }