grid.js
来自「用来在地图上做操作GIS,在地图上做标记」· JavaScript 代码 · 共 710 行 · 第 1/2 页
JS
710 行
var tileBounds = new OpenLayers.Bounds(tileoffsetlon, tileoffsetlat, tileoffsetlon + tilelon, tileoffsetlat + tilelat); var x = tileoffsetx; x -= parseInt(this.map.layerContainerDiv.style.left); var y = tileoffsety; y -= parseInt(this.map.layerContainerDiv.style.top); var px = new OpenLayers.Pixel(x, y); var tile = row[colidx++]; if (!tile) { tile = this.addTile(tileBounds, px); this.addTileMonitoringHooks(tile); row.push(tile); } else { tile.moveTo(tileBounds, px, false); } tileoffsetlon += tilelon; tileoffsetx += this.tileSize.w; } while ((tileoffsetlon <= bounds.right + tilelon * this.buffer) || colidx < minCols) tileoffsetlat -= tilelat; tileoffsety += this.tileSize.h; } while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer) || rowidx < minRows) //shave off exceess rows and colums this.removeExcessTiles(rowidx, colidx); //now actually draw the tiles this.spiralTileLoad(); }, /** * Method: spiralTileLoad * Starts at the top right corner of the grid and proceeds in a spiral * towards the center, adding tiles one at a time to the beginning of a * queue. * * Once all the grid's tiles have been added to the queue, we go back * and iterate through the queue (thus reversing the spiral order from * outside-in to inside-out), calling draw() on each tile. */ spiralTileLoad: function() { var tileQueue = []; var directions = ["right", "down", "left", "up"]; var iRow = 0; var iCell = -1; var direction = OpenLayers.Util.indexOf(directions, "right"); var directionsTried = 0; while( directionsTried < directions.length) { var testRow = iRow; var testCell = iCell; switch (directions[direction]) { case "right": testCell++; break; case "down": testRow++; break; case "left": testCell--; break; case "up": testRow--; break; } // if the test grid coordinates are within the bounds of the // grid, get a reference to the tile. var tile = null; if ((testRow < this.grid.length) && (testRow >= 0) && (testCell < this.grid[0].length) && (testCell >= 0)) { tile = this.grid[testRow][testCell]; } if ((tile != null) && (!tile.queued)) { //add tile to beginning of queue, mark it as queued. tileQueue.unshift(tile); tile.queued = true; //restart the directions counter and take on the new coords directionsTried = 0; iRow = testRow; iCell = testCell; } else { //need to try to load a tile in a different direction direction = (direction + 1) % 4; directionsTried++; } } // now we go through and draw the tiles in forward order for(var i=0; i < tileQueue.length; i++) { var tile = tileQueue[i] tile.draw(); //mark tile as unqueued for the next time (since tiles are reused) tile.queued = false; } }, /** * APIMethod: addTile * Gives subclasses of Grid the opportunity to create an * OpenLayer.Tile of their choosing. The implementer should initialize * the new tile and take whatever steps necessary to display it. * * Parameters * bounds - {<OpenLayers.Bounds>} * * Returns: * {<OpenLayers.Tile>} The added OpenLayers.Tile */ addTile:function(bounds, position) { // Should be implemented by subclasses }, /** * Method: addTileMonitoringHooks * This function takes a tile as input and adds the appropriate hooks to * the tile so that the layer can keep track of the loading tiles. * * Parameters: * tile - {<OpenLayers.Tile>} */ addTileMonitoringHooks: function(tile) { tile.onLoadStart = function() { //if that was first tile then trigger a 'loadstart' on the layer if (this.numLoadingTiles == 0) { this.events.triggerEvent("loadstart"); } this.numLoadingTiles++; }; tile.events.register("loadstart", this, tile.onLoadStart); tile.onLoadEnd = function() { this.numLoadingTiles--; this.events.triggerEvent("tileloaded"); //if that was the last tile, then trigger a 'loadend' on the layer if (this.numLoadingTiles == 0) { this.events.triggerEvent("loadend"); } }; tile.events.register("loadend", this, tile.onLoadEnd); }, /** * Method: removeTileMonitoringHooks * This function takes a tile as input and removes the tile hooks * that were added in addTileMonitoringHooks() * * Parameters: * tile - {<OpenLayers.Tile>} */ removeTileMonitoringHooks: function(tile) { tile.events.unregister("loadstart", this, tile.onLoadStart); tile.events.unregister("loadend", this, tile.onLoadEnd); }, /** * Method: moveGriddedTiles * * Parameters: * bounds - {<OpenLayers.Bounds>} */ moveGriddedTiles: function(bounds) { var buffer = this.buffer || 1; while (true) { var tlLayer = this.grid[0][0].position; var tlViewPort = this.map.getViewPortPxFromLayerPx(tlLayer); if (tlViewPort.x > -this.tileSize.w * (buffer - 1)) { this.shiftColumn(true); } else if (tlViewPort.x < -this.tileSize.w * buffer) { this.shiftColumn(false); } else if (tlViewPort.y > -this.tileSize.h * (buffer - 1)) { this.shiftRow(true); } else if (tlViewPort.y < -this.tileSize.h * buffer) { this.shiftRow(false); } else { break; } }; if (this.buffer == 0) { for (var r=0, rl=this.grid.length; r<rl; r++) { var row = this.grid[r]; for (var c=0, cl=row.length; c<cl; c++) { var tile = row[c]; if (!tile.drawn && tile.bounds.intersectsBounds(bounds, false)) { tile.draw(); } } } } }, /** * Method: shiftRow * Shifty grid work * * Parameters: * prepend - {Boolean} if true, prepend to beginning. * if false, then append to end */ shiftRow:function(prepend) { var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1); var modelRow = this.grid[modelRowIndex]; var resolution = this.map.getResolution(); var deltaY = (prepend) ? -this.tileSize.h : this.tileSize.h; var deltaLat = resolution * -deltaY; var row = (prepend) ? this.grid.pop() : this.grid.shift(); for (var i=0; i < modelRow.length; i++) { var modelTile = modelRow[i]; var bounds = modelTile.bounds.clone(); var position = modelTile.position.clone(); bounds.bottom = bounds.bottom + deltaLat; bounds.top = bounds.top + deltaLat; position.y = position.y + deltaY; row[i].moveTo(bounds, position); } if (prepend) { this.grid.unshift(row); } else { this.grid.push(row); } }, /** * Method: shiftColumn * Shift grid work in the other dimension * * Parameters: * prepend - {Boolean} if true, prepend to beginning. * if false, then append to end */ shiftColumn: function(prepend) { var deltaX = (prepend) ? -this.tileSize.w : this.tileSize.w; var resolution = this.map.getResolution(); var deltaLon = resolution * deltaX; for (var i=0; i<this.grid.length; i++) { var row = this.grid[i]; var modelTileIndex = (prepend) ? 0 : (row.length - 1); var modelTile = row[modelTileIndex]; var bounds = modelTile.bounds.clone(); var position = modelTile.position.clone(); bounds.left = bounds.left + deltaLon; bounds.right = bounds.right + deltaLon; position.x = position.x + deltaX; var tile = prepend ? this.grid[i].pop() : this.grid[i].shift() tile.moveTo(bounds, position); if (prepend) { this.grid[i].unshift(tile); } else { this.grid[i].push(tile); } } }, /** * Method: removeExcessTiles * When the size of the map or the buffer changes, we may need to * remove some excess rows and columns. * * Parameters: * rows - {Integer} Maximum number of rows we want our grid to have. * colums - {Integer} Maximum number of columns we want our grid to have. */ removeExcessTiles: function(rows, columns) { // remove extra rows while (this.grid.length > rows) { var row = this.grid.pop(); for (var i=0, l=row.length; i<l; i++) { var tile = row[i]; this.removeTileMonitoringHooks(tile) tile.destroy(); } } // remove extra columns while (this.grid[0].length > columns) { for (var i=0, l=this.grid.length; i<l; i++) { var row = this.grid[i]; var tile = row.pop(); this.removeTileMonitoringHooks(tile); tile.destroy(); } } }, /** * Method: onMapResize * For singleTile layers, this will replace the tile with the * a new one with updated tileSize and extent. */ onMapResize: function() { if (this.singleTile) { this.clearGrid(); this.setTileSize(); this.initSingleTile(this.map.getExtent()); } }, /** * APIMethod: getTileBounds * Returns The tile bounds for a layer given a pixel location. * * Parameters: * viewPortPx - {<OpenLayers.Pixel>} The location in the viewport. * * Returns: * {<OpenLayers.Bounds>} Bounds of the tile at the given pixel location. */ getTileBounds: function(viewPortPx) { var maxExtent = this.map.getMaxExtent(); var resolution = this.getResolution(); var tileMapWidth = resolution * this.tileSize.w; var tileMapHeight = resolution * this.tileSize.h; var mapPoint = this.getLonLatFromViewPortPx(viewPortPx); var tileLeft = maxExtent.left + (tileMapWidth * Math.floor((mapPoint.lon - maxExtent.left) / tileMapWidth)); var tileBottom = maxExtent.bottom + (tileMapHeight * Math.floor((mapPoint.lat - maxExtent.bottom) / tileMapHeight)); return new OpenLayers.Bounds(tileLeft, tileBottom, tileLeft + tileMapWidth, tileBottom + tileMapHeight); }, CLASS_NAME: "OpenLayers.Layer.Grid"});
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?