Changeset 337
- Timestamp:
- 08/21/08 04:03:40 (3 months ago)
- Location:
- trunk/geowebcache/src
- Files:
-
- 24 modified
- 2 moved
-
main/java/org/geowebcache/GeoWebCacheDispatcher.java (modified) (2 diffs)
-
main/java/org/geowebcache/demo/Demo.java (modified) (6 diffs)
-
main/java/org/geowebcache/layer/Grid.java (modified) (6 diffs)
-
main/java/org/geowebcache/layer/GridCalculator.java (moved) (moved from trunk/geowebcache/src/main/java/org/geowebcache/util/wms/GridCalculator.java) (10 diffs)
-
main/java/org/geowebcache/layer/SRS.java (modified) (1 diff)
-
main/java/org/geowebcache/layer/TileLayer.java (modified) (15 diffs)
-
main/java/org/geowebcache/layer/wms/WMSHttpHelper.java (modified) (5 diffs)
-
main/java/org/geowebcache/layer/wms/WMSLayer.java (modified) (14 diffs)
-
main/java/org/geowebcache/layer/wms/WMSMetaTile.java (modified) (3 diffs)
-
main/java/org/geowebcache/seeder/MTSeeder.java (modified) (2 diffs)
-
main/java/org/geowebcache/seeder/SeedTask.java (modified) (2 diffs)
-
main/java/org/geowebcache/service/Parameters.java (modified) (8 diffs)
-
main/java/org/geowebcache/service/Request.java (modified) (1 diff)
-
main/java/org/geowebcache/service/kml/KMLDebugGridLayer.java (modified) (1 diff)
-
main/java/org/geowebcache/service/kml/KMLService.java (modified) (5 diffs)
-
main/java/org/geowebcache/service/kml/KMZHelper.java (modified) (1 diff)
-
main/java/org/geowebcache/service/wms/WMSParameters.java (modified) (3 diffs)
-
main/java/org/geowebcache/service/wms/WMSService.java (modified) (6 diffs)
-
main/java/org/geowebcache/util/GetCapabilitiesConfiguration.java (modified) (3 diffs)
-
main/java/org/geowebcache/util/XMLConfiguration.java (modified) (1 diff)
-
main/java/org/geowebcache/util/wms/BBOX.java (modified) (3 diffs)
-
main/webapp/WEB-INF/geowebcache-servlet.xml (modified) (2 diffs)
-
main/webapp/states_epsg4326.html (modified) (2 diffs)
-
main/webapp/states_epsg900913.html (modified) (2 diffs)
-
test/java/org/geowebcache/layer/GridCalculatorTest.java (moved) (moved from trunk/geowebcache/src/test/java/org/geowebcache/utils/wms/GridCalculatorTest.java) (13 diffs)
-
test/java/org/geowebcache/layer/wms/MetaTileTest.java (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/geowebcache/src/main/java/org/geowebcache/GeoWebCacheDispatcher.java
r323 r337 21 21 import java.io.InputStream; 22 22 import java.io.OutputStream; 23 import java.net.URL;24 23 import java.util.HashMap; 25 24 import java.util.Iterator; … … 39 38 import org.geowebcache.service.Service; 40 39 import org.geowebcache.tile.Tile; 41 import org.springframework.core.io.Resource;42 40 import org.springframework.web.context.WebApplicationContext; 43 41 import org.springframework.web.servlet.ModelAndView; -
trunk/geowebcache/src/main/java/org/geowebcache/demo/Demo.java
r335 r337 9 9 10 10 import org.geowebcache.GeoWebCacheException; 11 import org.geowebcache.layer.Grid; 11 12 import org.geowebcache.layer.SRS; 12 13 import org.geowebcache.layer.TileLayer; … … 38 39 } 39 40 41 SRS srs = null; 40 42 if (srsStr != null) { 41 if (!layer.supportsProjection(new SRS(srsStr))) { 42 throw new GeoWebCacheException("Unsupported SRS " + srsStr); 43 } 43 srs = SRS.getSRS(srsStr); 44 44 } else { 45 srs Str = SRS.getEPSG900913().toString();45 srs = SRS.getEPSG900913(); 46 46 } 47 page = generateHTML(layer, srs Str, formatStr);47 page = generateHTML(layer, srs, formatStr); 48 48 49 49 } else { … … 105 105 } 106 106 107 private static String generateHTML(TileLayer layer, S tring srsStr, String formatStr)107 private static String generateHTML(TileLayer layer, SRS srs, String formatStr) 108 108 throws GeoWebCacheException { 109 109 String layerName = layer.getName(); 110 110 String mime = layer.getDefaultMimeType().getFormat(); 111 int srsIdx = layer.getSRSIndex(newSRS(srsStr));111 //int srsIdx = layer.getSRSIndex(SRS.getSRS(srsStr)); 112 112 113 113 BBOX bbox = null; 114 114 BBOX zoomBounds = null; 115 115 String res = ""; 116 if(srsStr.equalsIgnoreCase("EPSG:900913")) { 116 Grid grid = layer.getGrid(srs); 117 118 if(srs.getNumber() == 900913) { 117 119 //res = "resolutions: [156543.03,78271.52,39135.76,19567.88,9783.94,4891.97],\n"; 118 120 res = "resolutions: " + getEPSG900913Resolutions() + ",\n"; 119 121 bbox = new BBOX(-20037508.34,-20037508.34,20037508.34,20037508.34); 120 } else if(srs Str.equalsIgnoreCase("EPSG:4326")) {122 } else if(srs.getNumber() == 4326) { 121 123 res = "resolutions: " + getEPSG4326Resolutions() + ",\n"; 122 124 bbox = new BBOX(-180.0,-90.0,180.0,90.0); … … 131 133 // zoomBounds = bbox; 132 134 //} 133 zoomBounds = layer.getBounds(srsIdx);135 zoomBounds = grid.getBounds(); 134 136 135 137 … … 137 139 "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n" 138 140 +"<meta http-equiv=\"imagetoolbar\" content=\"no\">\n" 139 +"<title>"+layerName+" "+srs Str+" "+mime+"</tile>\n"141 +"<title>"+layerName+" "+srs.toString()+" "+mime+"</tile>\n" 140 142 +"<style type=\"text/css\">\n" 141 143 +"body { font-family: sans-serif; font-weight: bold; font-size: .8em; }\n" … … 152 154 +"var mapOptions = { \n" 153 155 + res 154 +"projection: new OpenLayers.Projection('"+srs Str+"'),\n"156 +"projection: new OpenLayers.Projection('"+srs.toString()+"'),\n" 155 157 +"maxExtent: new OpenLayers.Bounds("+bbox.toString()+") \n};\n" 156 158 +"map = new OpenLayers.Map('map', mapOptions );\n" -
trunk/geowebcache/src/main/java/org/geowebcache/layer/Grid.java
r320 r337 17 17 package org.geowebcache.layer; 18 18 19 import java.util.List; 20 21 import org.geowebcache.GeoWebCacheException; 19 22 import org.geowebcache.util.wms.BBOX; 20 23 21 24 /** 22 25 * Grid Class - Each TileLayer keeps a list of Grid Objects 23 *24 *25 26 */ 26 27 27 28 public class Grid { 28 private BBOX bounds = null; 29 30 private BBOX gridbounds = null; 31 32 private SRS projection = null; 33 34 public Grid(SRS projection, BBOX bounds, BBOX gridBounds) { 35 this.projection = projection; 29 private SRS gridSRS = null; 30 31 protected BBOX bounds = null; 32 33 protected BBOX gridBounds = null; 34 35 protected double[] resolutions = null; 36 37 private volatile transient GridCalculator gridCalculator; 38 39 private volatile int zoomStart = 0; 40 41 private volatile int zoomStop = 25; 42 43 public Grid(SRS srs, BBOX bounds, BBOX gridBounds, double[] resolutions) { 44 this.gridSRS = srs; 36 45 this.bounds = bounds; 37 this.gridbounds = gridBounds; 46 this.gridBounds = gridBounds; 47 this.resolutions = resolutions; 38 48 } 39 49 … … 57 67 */ 58 68 public void setGridBounds(BBOX gridbounds) { 59 this.grid bounds = gridbounds;69 this.gridBounds = gridbounds; 60 70 } 61 71 /** … … 65 75 public void setGridBounds(String gridbounds) { 66 76 67 this.grid bounds = new BBOX(gridbounds);77 this.gridBounds = new BBOX(gridbounds); 68 78 } 69 79 /** … … 71 81 * @param projection - SRS 72 82 */ 73 public void set Projection(SRS projection) {74 this. projection = projection;83 public void setSRS(SRS srs) { 84 this.gridSRS = srs; 75 85 } 76 86 /** … … 78 88 * @return 79 89 */ 80 public SRS get Projection() {81 return this. projection;90 public SRS getSRS() { 91 return this.gridSRS; 82 92 } 83 93 /** … … 93 103 */ 94 104 public BBOX getGridBounds() { 95 return this.gridbounds; 105 return this.gridBounds; 106 } 107 108 public int getZoomStart() { 109 return this.zoomStart; 110 } 111 112 public int getZoomStop() { 113 return this.zoomStop; 114 } 115 116 public void setResolutions(double[] resolutions) { 117 this.resolutions = resolutions; 118 } 119 120 public double[] getResolutions() throws GeoWebCacheException { 121 return getGridCalculator().getResolutions(); 122 } 123 124 public GridCalculator getGridCalculator() throws GeoWebCacheException { 125 GridCalculator ret = gridCalculator; 126 if (ret == null) { 127 synchronized (this) { 128 ret = gridCalculator; 129 if (gridCalculator == null) { 130 gridCalculator = ret = initGridCalculator(); 131 } 132 } 133 } 134 return ret; 96 135 } 97 136 137 private GridCalculator initGridCalculator() throws GeoWebCacheException { 138 return new GridCalculator(this); 139 } 98 140 } -
trunk/geowebcache/src/main/java/org/geowebcache/layer/GridCalculator.java
r322 r337 15 15 * @author Arne Kepp, The Open Planning Project, Copyright 2008 16 16 */ 17 package org.geowebcache.util.wms; 18 19 import java.util.Arrays; 17 package org.geowebcache.layer; 20 18 21 19 import org.apache.commons.logging.Log; 22 20 import org.apache.commons.logging.LogFactory; 23 21 import org.geowebcache.GeoWebCacheException; 24 import org.geowebcache.layer.BadTileException; 25 import org.geowebcache.layer.OutOfBoundsException; 26 import org.geowebcache.service.ServiceException; 22 import org.geowebcache.util.wms.BBOX; 27 23 28 24 public class GridCalculator { 29 private static Log log = LogFactory 30 .getLog(org.geowebcache.util.wms.GridCalculator.class); 31 32 private BBOX gridBounds = null; 33 25 private static Log log = LogFactory.getLog(org.geowebcache.layer.GridCalculator.class); 26 27 // We may want to change this later 28 private static final int TILEPIXELS = 256; 29 30 //private BBOX gridBounds = null; 31 private Grid grid; 32 33 public final static double[] RESOLUTIONS4326 = 34 GridCalculator.getResolutionArray(180.0, TILEPIXELS, 26); 35 36 public final static double[] RESOLUTIONS900913 = 37 GridCalculator.getResolutionArray(20037508.34*2,TILEPIXELS, 26); 38 34 39 // The following are the width of the actual layer 35 40 private double gridWidth; 36 41 37 42 private double gridHeight; 38 43 44 // This is what the grid looks like at zoomlevel 0 45 private int gridX = -1; 46 47 private int gridY = -1; 48 49 private double[] resolutions; 50 39 51 // The following are for a tile, zoomed out all the way 40 private double maxTileWidth;41 42 private double maxTileHeight;52 //private double maxTileWidth; 53 54 //private double maxTileHeight; 43 55 44 56 private int zoomStart; 45 57 46 58 private int zoomStop; 47 48 //private int metaWidth;49 50 //private int metaHeight;51 52 // Used for unprojected profiles53 private int gridConstant;54 59 55 60 // Special treatment of "zoomed out tile" for EPSG 4326 56 private boolean worldBoundsCoverTwoTiles = false;61 //private boolean worldBoundsCoverTwoTiles = false; 57 62 58 63 private int[] zoomedOutGridLoc = null; … … 60 65 private int[][] boundsGridLevels = null; 61 66 62 // TODO this code does not handle coordinate systems where the base 63 // height 64 // is bigger than the width 65 // private double layerHeight; 66 67 public GridCalculator(BBOX gridBounds, BBOX layerBounds, int zoomStart, 68 int zoomStop, int metaWidth, int metaHeight, double maxTileWidth, 69 double maxTileHeight) { 70 71 this.gridBounds = gridBounds; 72 this.zoomStart = zoomStart; 73 this.zoomStop = zoomStop; 67 public GridCalculator(Grid grid) throws GeoWebCacheException { 68 69 this.grid = grid; 70 this.zoomStart = 0; 71 this.zoomStop = 25; 74 72 //this.metaWidth = metaWidth; 75 73 //this.metaHeight = metaHeight; 76 74 75 this.resolutions = grid.resolutions; 76 77 //BBOX layerBounds = grid.bounds; 78 BBOX gridBounds = grid.gridBounds; 79 77 80 // Calculate 78 81 gridWidth = gridBounds.coords[2] - gridBounds.coords[0]; 79 82 gridHeight = gridBounds.coords[3] - gridBounds.coords[1]; 80 83 81 this.maxTileWidth = maxTileWidth; 82 this.maxTileHeight = maxTileHeight; 83 this.gridConstant = (int) Math.round(gridWidth / gridHeight - 1.0); 84 85 boundsGridLevels = calculateGridBounds(layerBounds); 86 87 if( this.gridConstant > 0 88 && layerBounds.coords[0] < 0.0 89 && layerBounds.coords[2] > 0.0) { 90 worldBoundsCoverTwoTiles = true; 84 // Figure out the rest 85 determineGrid(); 86 87 boundsGridLevels = calculateGridBounds(grid.bounds); 88 } 89 90 private void determineGrid() throws GeoWebCacheException { 91 if(grid.resolutions == null) { 92 // Figure out the approriate resolutions 93 94 double ratio = gridWidth / gridHeight; 95 96 // Allow 2.5% slack 97 if(Math.abs(ratio - 1.0) < 0.025) { 98 gridX = 1; 99 gridY = 1; 100 } 101 102 // Otherwise we'll try to expand it to an integer grid, 103 // failing that we'll just increase the smaller bounds 104 // to make the box square 105 if(ratio > 1.0) { 106 // Wider than tall 107 if(Math.abs(ratio - Math.round(ratio)) < 0.025) { 108 gridY = 1; 109 gridX = (int) Math.round(ratio); 110 } else { 111 // I give up, expanding Y bounds 112 gridX = gridY = 1; 113 gridHeight = gridWidth; 114 } 115 determineResolutions(); 116 } else { 117 // Taller than wide 118 ratio = gridHeight / gridWidth; 119 if(Math.abs(ratio - Math.round(ratio)) < 0.025) { 120 gridY = (int) Math.round(ratio); 121 gridX = 1; 122 } else { 123 // I give up, expanding X bounds 124 gridX = gridY = 1; 125 gridWidth = gridHeight; 126 } 127 determineResolutions(); 128 } 129 } else { 130 double denominator = grid.resolutions[0]* GridCalculator.TILEPIXELS; 131 this.gridX = (int) Math.round(gridWidth / denominator); 132 this.gridY = (int) Math.round(gridHeight / denominator); 133 } 134 } 135 136 private void determineResolutions() throws GeoWebCacheException { 137 double baseResolution; 138 139 // We use the smaller one 140 if(gridY == 1) { 141 baseResolution = gridHeight / GridCalculator.TILEPIXELS; 142 } else if (gridX == 1) { 143 baseResolution = gridWidth / GridCalculator.TILEPIXELS; 144 } else { 145 throw new GeoWebCacheException("Unable to find height or width to calculate resolution array."); 146 } 147 148 this.resolutions = new double[this.zoomStop - this.zoomStart + 1]; 149 for(int i=this.zoomStart; i<= this.zoomStop; i++) { 150 this.resolutions[i] = baseResolution; 151 baseResolution = baseResolution / 2; 91 152 } 92 153 } 93 154 94 155 private int[][] calculateGridBounds(BBOX layerBounds) { 156 BBOX gridBounds = grid.gridBounds; 157 95 158 // We'll just waste a few bytes, for cheap lookups 96 159 int[][] gridLevels = new int[zoomStop + 1][4]; 97 160 98 double tileWidth = maxTileWidth; 99 double tileHeight = maxTileHeight; 100 101 int tileCountX = (int) Math.round(gridWidth / maxTileWidth); 102 int tileCountY = (int) Math.round(gridHeight / maxTileHeight); 161 //int tileCountX = (int) Math.round(gridWidth / resolutions[0]); 162 //int tileCountY = (int) Math.round(gridHeight / resolutions[0]); 103 163 104 164 //int metaLarger = (metaHeight > metaWidth) ? metaHeight : metaWidth; … … 111 171 for (int level = 0; level <= zoomStop; level++) { 112 172 //System.out.println("--- Level "+level+"----"); 113 173 double tileDelta = resolutions[level] * GridCalculator.TILEPIXELS; 114 174 115 175 // Min X 116 rawNumber[0] = (layerBounds.coords[0] - gridBounds.coords[0]) / tile Width;176 rawNumber[0] = (layerBounds.coords[0] - gridBounds.coords[0]) / tileDelta; 117 177 gridLevels[level][0] = (int) Math.floor(rawNumber[0]); 118 178 119 179 // Min Y 120 rawNumber[1] = (layerBounds.coords[1] - gridBounds.coords[1]) / tile Height;180 rawNumber[1] = (layerBounds.coords[1] - gridBounds.coords[1]) / tileDelta; 121 181 gridLevels[level][1] = (int) Math.floor(rawNumber[1]); 122 182 … … 125 185 126 186 // Max X 127 rawNumber[2] = (layerBounds.coords[2] - gridBounds.coords[0] - 0.000 1) / tileWidth;187 rawNumber[2] = (layerBounds.coords[2] - gridBounds.coords[0] - 0.00001) / tileDelta; 128 188 gridLevels[level][2] = (int) Math.floor(rawNumber[2]); 129 189 130 190 // Max Y 131 rawNumber[3] = (layerBounds.coords[3] - gridBounds.coords[1] - 0.000 1) / tileHeight;191 rawNumber[3] = (layerBounds.coords[3] - gridBounds.coords[1] - 0.00001) / tileDelta; 132 192 gridLevels[level][3] = (int) Math.floor(rawNumber[3]); 133 193 … … 139 199 // + metaLarger); 140 200 141 // Adjust for metatiling if appropriate 142 // if (tileCountX > metaLarger || tileCountY > metaLarger) { 143 // // Round down 144 // gridLevels[level][0] = gridLevels[level][0] 145 // - (gridLevels[level][0] % metaWidth); 146 // // Round down 147 // gridLevels[level][1] = gridLevels[level][1] 148 // - (gridLevels[level][1] % metaHeight); 149 // // Naive round up 150 // gridLevels[level][2] = gridLevels[level][2] 151 // - (gridLevels[level][2] % metaWidth) + (metaWidth - 1); 152 // // Naive round up 153 // gridLevels[level][3] = gridLevels[level][3] 154 // - (gridLevels[level][3] % metaHeight) 155 // + (metaHeight - 1); 156 // 157 // //System.out.println("postAdjust: " + 158 // // Arrays.toString(gridLevels[level])); 159 // 160 // // Fix for naive round ups, imagine applying a 3x3 metatile to a 161 // // 4x4 grid 162 // if (gridLevels[level][2] >= tileCountX) { 163 // gridLevels[level][2] = tileCountX - 1; 164 // } 165 // if (gridLevels[level][3] >= tileCountY) { 166 // gridLevels[level][3] = tileCountY - 1; 167 // } 168 // //System.out.println("postFix: " + 169 // // Arrays.toString(gridLevels[level])); 170 // } 171 172 // For the next round 173 tileWidth = tileWidth / 2; 174 tileHeight = tileHeight / 2; 175 176 tileCountX = tileCountX * 2; 177 tileCountY = tileCountY * 2; 201 //tileCountX = tileCountX * 2; 202 //tileCountY = tileCountY * 2; 178 203 } 179 204 return gridLevels; … … 210 235 double reqTileWidth = tileBounds.coords[2] - tileBounds.coords[0]; 211 236 212 double zoomLevel = Math.log(gridWidth / reqTileWidth) / Math.log(2); 213 214 long roundedZoomLevel = Math.round(zoomLevel); 215 if(Math.abs(zoomLevel - (double) roundedZoomLevel) > 0.05) { 216 throw new BadTileException("The bounds result in a zoom level of "+zoomLevel+ 217 ", expected something within 0.05 of an integer, check " + tileBounds.toString()); 218 } 237 //Arrays.binarySearch(a, key) 238 //double zoomLevel = Math.log(gridWidth / reqTileWidth) / Math.log(2); 239 240 //long roundedZoomLevel = Math.round(zoomLevel); 241 219 242 220 243 // (Z) Zoom level 221 244 // For EPSG 4326, reqTileWidth = 0.087 log(4096) / log(2) - 1; -> 11 222 retVals[2] = (int) roundedZoomLevel 223 - gridConstant; 224 225 double tileWidth = gridWidth / (Math.pow(2, retVals[2] + gridConstant)); 226 245 retVals[2] = this.binarySearchForResolution(reqTileWidth / GridCalculator.TILEPIXELS); 246 247 double tileWidth = resolutions[retVals[2]] * GridCalculator.TILEPIXELS; 248 249 // Get the bounds 250 BBOX layerBounds = grid.bounds; 251 BBOX gridBounds = grid.gridBounds; 252 227 253 // X 228 254 double xdiff = tileBounds.coords[0] - gridBounds.coords[0]; … … 290 316 */ 291 317 public BBOX bboxFromGridLocation(int[] gridLoc) { 292 double tileWidth = gridWidth / Math.pow(2, gridLoc[2] + gridConstant); 293 318 //double tileWidth = gridWidth / Math.pow(2, gridLoc[2] + gridConstant); 319 double tileWidth = resolutions[gridLoc[2]] * GridCalculator.TILEPIXELS; 320 321 BBOX gridBounds = grid.gridBounds; 322 294 323 return new BBOX(gridBounds.coords[0] + tileWidth * gridLoc[0], 295 324 gridBounds.coords[1] + tileWidth * gridLoc[1], … … 309 338 310 339 public BBOX bboxFromGridBounds(int[] gridLocBounds) { 311 double tileWidth = gridWidth 312 / Math.pow(2, gridLocBounds[4] + gridConstant); 313 340 //double tileWidth = gridWidth 341 // / Math.pow(2, gridLocBounds[4] + gridConstant); 342 343 double tileWidth = GridCalculator.TILEPIXELS * resolutions[gridLocBounds[4]]; 344 345 BBOX gridBounds = grid.gridBounds; 346 314 347 return new BBOX(gridBounds.coords[0] + tileWidth * gridLocBounds[0], 315 348 gridBounds.coords[1] + tileWidth * gridLocBounds[1], … … 388 421 return zoomedOutGridLoc; 389 422 } 390 423 424 //TODO fix negative number to return more than one top tile 425 391 426 // Exception for EPSG:4326, which can zoom out to two tiles 392 if ( worldBoundsCoverTwoTiles) {427 if (gridX == 2 && gridY == 1) { 393 428 zoomedOutGridLoc = new int[3]; 394 429 zoomedOutGridLoc[0] = -1; … … 416 451 } 417 452 418 public double[] getResolutions(int widthPixels) { 419 double[] ret = new double[zoomStop - zoomStart + 1]; 420 double tileWidth = maxTileWidth / widthPixels; 421 422 for(int i=0; i<ret.length; i++) { 423 ret[i] = tileWidth; 424 tileWidth = tileWidth / 2; 425 } 426 427 return ret; 428 } 453 public double[] getResolutions() { 454
