Integer findMaxZoomAuto(GridSubset gridSubset, Integer minZoom, WMSMapContent map) { BoundingBox bbox = bbox(map); int zoom = minZoom; int ntiles = 0; while (ntiles < 256 && zoom < gridSubset.getGridSet().getNumLevels()) { long[] intersect = gridSubset.getCoverageIntersection(zoom, bbox); ntiles += (intersect[2] - intersect[0] + 1) * (intersect[3] - intersect[1] + 1); zoom++; } return zoom; }
int[] findMinMaxZoom(GridSubset gridSubset, WMSMapContent map) { GridSet gridSet = gridSubset.getGridSet(); Map formatOpts = map.getRequest().getFormatOptions(); Integer minZoom = null; if (formatOpts.containsKey("min_zoom")) { minZoom = Integer.parseInt(formatOpts.get("min_zoom").toString()); } if (minZoom == null) { minZoom = findClosestZoom(gridSet, map); } Integer maxZoom = null; if (formatOpts.containsKey("max_zoom")) { maxZoom = Integer.parseInt(formatOpts.get("max_zoom").toString()); } else if (formatOpts.containsKey("num_zooms")) { maxZoom = minZoom + Integer.parseInt(formatOpts.get("num_zooms").toString()); } if (maxZoom == null) { // walk down until we hit too many tiles maxZoom = findMaxZoomAuto(gridSubset, minZoom, map); } if (maxZoom < minZoom) { throw new ServiceException( format("maxZoom (%d) can not be less than minZoom (%d)", maxZoom, minZoom)); } // end index if (maxZoom > gridSet.getNumLevels()) { LOGGER.warning( format( "Max zoom (%d) can't be greater than number of zoom levels (%d)", maxZoom, gridSet.getNumLevels())); maxZoom = gridSet.getNumLevels(); } return new int[] {minZoom, maxZoom}; }
private static String generateHTML( TileLayer layer, String gridSetStr, String formatStr, boolean asPlugin) throws GeoWebCacheException { String layerName = layer.getName(); GridSubset gridSubset = layer.getGridSubset(gridSetStr); BoundingBox bbox = gridSubset.getGridSetBounds(); BoundingBox zoomBounds = gridSubset.getOriginalExtent(); String res = "resolutions: " + Arrays.toString(gridSubset.getResolutions()) + ",\n"; String units = "units: \"" + gridSubset.getGridSet().guessMapUnits() + "\",\n"; String openLayersPath; if (asPlugin) { openLayersPath = "../openlayers/OpenLayers.js"; } else { openLayersPath = "../openlayers/OpenLayers.js"; } String page = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n" + "<meta http-equiv=\"imagetoolbar\" content=\"no\">\n" + "<title>" + layerName + " " + gridSubset.getName() + " " + formatStr + "</title>\n" + "<style type=\"text/css\">\n" + "body { font-family: sans-serif; font-weight: bold; font-size: .8em; }\n" + "body { border: 0px; margin: 0px; padding: 0px; }\n" + "#map { width: 85%; height: 85%; border: 0px; padding: 0px; }\n" + "</style>\n" + "<script src=\"" + openLayersPath + "\"></script> \n" + "<script type=\"text/javascript\"> \n" + "var map, demolayer; \n" + " // sets the chosen modifiable parameter \n" + " function setParam(name, value){ \n" + " str = \"demolayer.mergeNewParams({\" + name + \": '\" + value + \"'})\" \n" + " // alert(str); \n" + " eval(str); \n" + " } \n" + "OpenLayers.DOTS_PER_INCH = " + gridSubset.getDotsPerInch() + ";\n" + "OpenLayers.Util.onImageLoadErrorColor = 'transparent';\n" + "function init(){\n" + "var mapOptions = { \n" + res + "projection: new OpenLayers.Projection('" + gridSubset.getSRS().toString() + "'),\n" + "maxExtent: new OpenLayers.Bounds(" + bbox.toString() + "),\n" + units + "controls: []\n" + "};\n" + "map = new OpenLayers.Map('map', mapOptions );\n" + "map.addControl(new OpenLayers.Control.PanZoomBar({\n" + " position: new OpenLayers.Pixel(2, 15)\n" + "}));\n" + "map.addControl(new OpenLayers.Control.Navigation());\n" + "map.addControl(new OpenLayers.Control.Scale($('scale')));\n" + "map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));\n" + "demolayer = new OpenLayers.Layer.WMS(\n" + "\"" + layerName + "\",\"../service/wms\",\n" + "{layers: '" + layerName + "', format: '" + formatStr + "' },\n" + "{ tileSize: new OpenLayers.Size(" + gridSubset.getTileWidth() + "," + gridSubset.getTileHeight() + ")"; /* * If the gridset has a top left tile origin, lets tell that to open layers. Otherwise it'll * calculate tile bounds based on the bbox bottom left corner, leading to misaligned * requests. */ GridSet gridSet = gridSubset.getGridSet(); if (gridSet.isTopLeftAligned()) { page += ",\n tileOrigin: new OpenLayers.LonLat(" + bbox.getMinX() + ", " + bbox.getMaxY() + ")"; } page += "});\n" + "map.addLayer(demolayer);\n" + "map.zoomToExtent(new OpenLayers.Bounds(" + zoomBounds.toString() + "));\n" + "// The following is just for GetFeatureInfo, which is not cached. Most people do not need this \n" + "map.events.register('click', map, function (e) {\n" + " document.getElementById('nodelist').innerHTML = \"Loading... please wait...\";\n" + " var params = {\n" + " REQUEST: \"GetFeatureInfo\",\n" + " EXCEPTIONS: \"application/vnd.ogc.se_xml\",\n" + " BBOX: map.getExtent().toBBOX(),\n" + " X: e.xy.x,\n" + " Y: e.xy.y,\n" + " INFO_FORMAT: 'text/html',\n" + " QUERY_LAYERS: map.layers[0].params.LAYERS,\n" + " FEATURE_COUNT: 50,\n" + " Layers: '" + layerName + "',\n" + " Styles: '',\n" + " Srs: '" + gridSubset.getSRS().toString() + "',\n" + " WIDTH: map.size.w,\n" + " HEIGHT: map.size.h,\n" + " format: \"" + formatStr + "\" };\n" + " OpenLayers.loadURL(\"../service/wms\", params, this, setHTML, setHTML);\n" + " OpenLayers.Event.stop(e);\n" + " });\n" + "}\n" + "function setHTML(response){\n" + " document.getElementById('nodelist').innerHTML = response.responseText;\n" + "};\n" + "</script>\n" + "</head>\n" + "<body onload=\"init()\">\n" + "<div id=\"params\">" + makeModifiableParameters(layer) + "</div>\n" + "<div id=\"map\"></div>\n" + "<div id=\"nodelist\"></div>\n" + "</body>\n" + "</html>"; return page; }
void addTileLayers(GeoPackage geopkg, List<MapLayerInfo> mapLayers, WMSMapContent map) throws IOException { if (mapLayers.isEmpty()) { return; } // figure out a name for the file entry String tileEntryName = null; Map formatOpts = map.getRequest().getFormatOptions(); if (formatOpts.containsKey("tileset_name")) { tileEntryName = (String) formatOpts.get("tileset_name"); } if (tileEntryName == null) { tileEntryName = map.getTitle(); } if (tileEntryName == null && mapLayers.size() == 1) { Iterator<MapLayerInfo> it = mapLayers.iterator(); tileEntryName = it.next().getLayerInfo().getName(); } GridSubset gridSubset = findBestGridSubset(map); int[] minmax = findMinMaxZoom(gridSubset, map); BoundingBox bbox = bbox(map); TileEntry e = new TileEntry(); e.setTableName(tileEntryName); if (mapLayers.size() == 1) { ResourceInfo r = mapLayers.get(0).getResource(); e.setIdentifier(r.getTitle()); e.setDescription(r.getAbstract()); } e.setBounds( new ReferencedEnvelope( findTileBounds(gridSubset, bbox, minmax[0]), map.getCoordinateReferenceSystem())); e.setSrid(srid(map)); GridSet gridSet = gridSubset.getGridSet(); for (int z = minmax[0]; z < minmax[1]; z++) { Grid g = gridSet.getGrid(z); TileMatrix m = new TileMatrix(); m.setZoomLevel(z); m.setMatrixWidth((int) g.getNumTilesWide()); m.setMatrixHeight((int) g.getNumTilesHigh()); m.setTileWidth(gridSubset.getTileWidth()); m.setTileHeight(gridSubset.getTileHeight()); // TODO: not sure about this m.setXPixelSize(g.getResolution()); m.setYPixelSize(g.getResolution()); // m.setXPixelSize(gridSet.getPixelSize()); // m.setYPixelSize(gridSet.getPixelSize()); e.getTileMatricies().add(m); } // figure out the actual bounds of the tiles to be renderered LOGGER.fine("Creating tile entry" + e.getTableName()); geopkg.create(e); // create a prototype getmap request GetMapRequest req = new GetMapRequest(); OwsUtils.copy(map.getRequest(), req, GetMapRequest.class); req.setLayers(mapLayers); String imageFormat = formatOpts.containsKey("format") ? parseFormatFromOpts(formatOpts) : findBestFormat(map); req.setFormat(imageFormat); req.setWidth(gridSubset.getTileWidth()); req.setHeight(gridSubset.getTileHeight()); // count tiles as we generate them int ntiles = 0; // flag determining if tile row indexes we store in database should be inverted boolean flipy = Boolean.valueOf((String) formatOpts.get("flipy")); for (int z = minmax[0]; z < minmax[1]; z++) { long[] intersect = gridSubset.getCoverageIntersection(z, bbox); for (long x = intersect[0]; x <= intersect[2]; x++) { for (long y = intersect[1]; y <= intersect[3]; y++) { BoundingBox box = gridSubset.boundsFromIndex(new long[] {x, y, z}); req.setBbox(new Envelope(box.getMinX(), box.getMaxX(), box.getMinY(), box.getMaxY())); Tile t = new Tile(); t.setZoom(z); t.setColumn((int) x); t.setRow((int) (flipy ? gridSubset.getNumTilesHigh(z) - (y + 1) : y)); WebMap result = webMapService.getMap(req); t.setData(toBytes(result)); geopkg.add(e, t); // images we encode are actually kept around, we need to clean them up if (ntiles++ == TILE_CLEANUP_INTERVAL) { cleanUpImages(); ntiles = 0; } } } } }