- window.WMTSLayer = (function(){
-
- function clamp(value,min,max){
- return value < min ? min : value > max ? max: value
- }
-
- var caches = {
- data:{},
- get:function(key){
- return this.data[key];
- },
- put:function(key,value){
- this.data[key] = value;
- },
- clear:function(){
- this.data = {};
- }
- };
-
- var lib = LKMap;
-
- var transparentPngUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=';
-
- var transparentImage = (function(){
- var canvas = document.createElement("canvas");
- canvas.width = 256;
- canvas.height = 256;
- var context = canvas.getContext("2d");
- context.fillStyle = "rgba(0,0,0,0)";
- context.fillRect(0,0,256,256);
- return canvas;
- })();
-
- var vetexShaderSource = `
- uniform mat4 u_Matrix;
- uniform vec4 u_Translate;
- attribute vec3 a_Position;
- attribute vec2 a_UV;
- varying vec2 v_UV;
- void main(){
- v_UV = a_UV;
- gl_Position = u_Matrix * vec4( (a_Position.xy + u_Translate.xy), 0.0 ,1.0 );
- }
- `;
-
- var fragmentShaderSource = `
- #ifdef GL_ES
- precision mediump float;
- #endif
- varying vec2 v_UV;
- uniform sampler2D texture;
- void main(){
- vec4 textureColor = texture2D(texture,v_UV);
- gl_FragColor = textureColor;
- }
- `;
-
- //坐标转换
- var pi = 3.1415926535897932384626;
- var a = 6378245.0;
- var ee = 0.00669342162296594323;
- var x_pi = pi * 3000.0 / 180.0;
-
- function transformLat(x, y) {
- var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
- ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
- ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
- ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
- return ret;
- }
-
- function transform(lng, lat) {
- var dLat = transformLat(lng - 105.0, lat - 35.0);
- var dLng = transformLng(lng - 105.0, lat - 35.0);
- var radLat = lat / 180.0 * pi;
- var magic = Math.sin(radLat);
- magic = 1 - ee * magic * magic;
- var sqrtMagic = Math.sqrt(magic);
- dLat = dLat * 180.0 / (a * (1 - ee) / (magic * sqrtMagic) * pi);
- dLng = dLng * 180.0 / (a / sqrtMagic * Math.cos(radLat) * pi);
- var mgLat = lat + dLat;
- var mgLng = lng + dLng;
- var newCoord = {
- lng: mgLng,
- lat: mgLat
- };
- return newCoord;
- }
-
- function transformLng(x, y) {
- var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
- ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
- ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
- ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
- return ret;
- }
-
- function gcj02_To_gps84(lng, lat) {
- if (Array.isArray(lng)) {
- var _lng = lng[0];
- lat = lng[1];
- lng = _lng;
- }
- if (lng instanceof Object) {
- var _lng = lng.lng;
- lat = lng.lat;
- lng = _lng;
- }
-
- var coord = transform(lng, lat);
- var lontitude = lng * 2 - coord.lng;
- var latitude = lat * 2 - coord.lat;
- var newCoord = {
- lng: lontitude,
- lat: latitude
- };
- return [lontitude,latitude];
- }
-
- function gps84_To_gcj02(lng, lat) {
- if (Array.isArray(lng)) {
- var _lng = lng[0];
- lat = lng[1];
- lng = _lng;
- }
- if (lng instanceof Object) {
- var _lng = lng.lng;
- lat = lng.lat;
- lng = _lng;
- }
-
- var dLat = transformLat(lng - 105.0, lat - 35.0);
- var dLng = transformLng(lng - 105.0, lat - 35.0);
- var radLat = lat / 180.0 * pi;
- var magic = Math.sin(radLat);
- magic = 1 - ee * magic * magic;
- var sqrtMagic = Math.sqrt(magic);
- dLat = dLat * 180.0 / (a * (1 - ee) / (magic * sqrtMagic) * pi);
- dLng = dLng * 180.0 / (a / sqrtMagic * Math.cos(radLat) * pi);
- var mgLat = lat + dLat;
- var mgLng = lng + dLng;
- var newCoord = {
- lng: mgLng,
- lat: mgLat
- };
- return [mgLng,mgLat];
- }
-
-
- function TileXYZLayerFor4326(options){
-
- this._options = Object.assign({
- minzoom:1,
- maxzoom:22,
- tileSize:256
- },options);
-
- this._extent = this._options.extent || [-180,-90,180,90];
-
- this._map = null;
- this._transform = null;
- this._program = null;
- this._gl = null;
-
- //当前可视区域的切片
- this._tiles = {};
-
- }
-
- TileXYZLayerFor4326.prototype = {
-
- constructor:TileXYZLayerFor4326,
-
- addTo:function(map){
-
- this._map = map;
- this._transform = map.transform;
- this._layerId = "vectorTileLayer_"+Date.now();
-
- map.addLayer({
- id:this._layerId,
- type: 'custom',
- onAdd: (function(_this){
- return function(map,gl){
- return _this._onAdd(map,gl,this);
- }
- })(this),
- render: (function(_this){
- return function(gl, matrix){
- return _this._render(gl, matrix, this);
- }
- })(this)
- });
-
- map.on("remove",function(){
- caches.clear();
- });
- },
-
- _onAdd: function(map,gl){
- var _this = this;
-
- this._gl = gl;
-
- this.transparentTexture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, this.transparentTexture);
- gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, transparentImage);
- gl.bindTexture(gl.TEXTURE_2D,null);
-
- var vetexShader = gl.createShader(gl.VERTEX_SHADER)
- gl.shaderSource(vetexShader,vetexShaderSource);
- gl.compileShader(vetexShader);
-
- if (!gl.getShaderParameter(vetexShader,gl.COMPILE_STATUS)) {
- throw "Shader Compile Error: " + (gl.getShaderInfoLog(vetexShader));
- }
-
- var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader,fragmentShaderSource);
- gl.compileShader(fragmentShader);
-
- if (!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)) {
- throw "Shader Compile Error: " + (gl.getShaderInfoLog(fragmentShader));
- }
-
- var program = this._program = gl.createProgram();
- gl.attachShader(program, vetexShader);
- gl.attachShader(program, fragmentShader);
- gl.linkProgram(program);
- /**
- * 属性
- */
- var attributes = this._attributes = {
- aPosition:{
- name:"a_Position",
- location:gl.getAttribLocation(this._program,"a_Position"),
- },
- aUV:{
- name:"a_UV",
- location:gl.getAttribLocation(this._program,"a_UV"),
- }
- };
-
- /**
- * 缓冲区
- */
- this._buffers = {
- aPositionBuffer:{
- buffer:gl.createBuffer(),
- size:3,
- attribute: attributes["aPosition"],
- points: new Float32Array(3 * 6),
- update:function(extent){
- },
- update1:function(extent){
- gl.bindBuffer(gl.ARRAY_BUFFER,this.buffer);
- var centerMecatorExtent = extent;
- var minx = centerMecatorExtent[0],
- miny = centerMecatorExtent[1],
- maxx = centerMecatorExtent[2],
- maxy = centerMecatorExtent[3];
- var points = this.points;
- points[0] = minx ,points[1] = maxy, points[2] = 0.0 ,
- points[3] = maxx ,points[4] = maxy, points[5] = 0.0,
- points[6] = minx ,points[7] = miny, points[8] = 0.0 ,
- points[9] = maxx ,points[10] = maxy, points[11] = 0.0 ,
- points[12] = minx,points[13] = miny, points[14] = 0.0,
- points[15] = maxx,points[16] = miny, points[17] = 0.0 ;
- gl.bufferData(gl.ARRAY_BUFFER,points, gl.STATIC_DRAW);
- gl.enableVertexAttribArray(this.attribute.location);
- gl.vertexAttribPointer(this.attribute.location,this.size,gl.FLOAT,false,0,0);
- }
- },
- aUVBuffer:{
- buffer:gl.createBuffer(),
- size:2,
- attribute:attributes["aUV"],
- points:new Float32Array( [0,0,1,0,0,1,1,0,0,1,1,1] ),
- hasBufferData:false,
- update:function(){
- gl.bindBuffer(gl.ARRAY_BUFFER,this.buffer);
- if(!this.hasBufferData){
- gl.bufferData(gl.ARRAY_BUFFER, this.points, gl.STATIC_DRAW);
- this.hasBufferData = true;
- }
- gl.enableVertexAttribArray(this.attribute.location);
- gl.vertexAttribPointer(this.attribute.location,this.size,gl.FLOAT,false,0,0);
- }
- }
- }
- /**
- * 变量
- */
- this._uniforms = {
- uMatrix:{
- value:null,
- location:gl.getUniformLocation(this._program,"u_Matrix"),
- update:function(matrix){
- if(this.value !== matrix){
- gl.uniformMatrix4fv(this.location,false,matrix);
- }
- }
- },
- uTranslate:{
- value:[0,0],
- location:gl.getUniformLocation(this._program,"u_Translate"),
- update:function(){}
- },
- uTexture:{
- value:null,
- location:gl.getUniformLocation(this._program, 'texture'),
- update:function(){}
- }
- };
- },
- /**
- * 渲染
- * @param {*} gl
- * @param {*} matrix
- */
- _render:function(gl, matrix){
- if(this._program){
- var transform = this._transform;
- var options = this._options;
- var tileSize = options.tileSize ||256;
-
- var z = transform.coveringZoomLevel({
- tileSize:tileSize,
- roundZoom:true
- });
-
- this.realz = z;
-
- z = z < 5 ? 5 : z;
-
- this.z = z;
-
- if (options.minzoom !== undefined && z < options.minzoom) { z = 0; }
-
- if (options.maxzoom !== undefined && z > options.maxzoom) { z = options.maxzoom; }
-
- var resolution = this.resolution = this.getResolutionFromZ(z);
-
- var center = transform.center;
- /*
- var lngLat = gps84_To_gcj02(center.lng,center.lat);
-
- center.lng = lngLat[0];
- center.lat = lngLat[1];*/
-
- //var centerCoord = lib.MercatorCoordinate.fromLngLat(transform.center);
- var maxx = clamp (center.lng + resolution * tileSize, -180, 180);
- var miny = clamp (center.lat - resolution * tileSize, -90, 90);
- var minx = clamp (center.lng, -180, 180) ,maxy = clamp(center.lat, -90,90) ;
- var leftBottom = lib.MercatorCoordinate.fromLngLat([minx,miny]);
- var topRight = lib.MercatorCoordinate.fromLngLat([maxx,maxy]);
-
- this.centerMecatorExtent = [leftBottom.x,leftBottom.y,topRight.x,topRight.y];
-
- gl.useProgram(this._program);
-
- gl.enable(gl.BLEND);
-
- gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
-
- for(let key in this._uniforms){
- this._uniforms[key].update(matrix);
- }
-
- for(let key in this._buffers){
- this._buffers[key].update();
- }
-
- this.calcTilesInView();
-
- this.renderTiles();
-
- }
- },
- renderTiles(){
- var gl = this._gl;
- var tiles = this._tiles;
- var tile;
-
- for(var key in tiles){
-
- tile = tiles[key];
-
- tile.calcExtent();
-
- this._buffers.aPositionBuffer.update1(tile.extent);
-
- gl.uniform4fv(this._uniforms.uTranslate.location,tile.translate);
- gl.activeTexture(gl.TEXTURE0);
- if(tile.texture){
- gl.bindTexture(gl.TEXTURE_2D, tile.texture);
- }else{
- gl.bindTexture(gl.TEXTURE_2D, this.transparentTexture);
- }
- gl.uniform1i(this._uniforms.uTexture.location, 0);
- gl.drawArrays(gl.TRIANGLES, 0, 6);
- }
-
- },
- /**
- * 计算当前可视范围内的切片
- */
- calcTilesInView:function(){
- var z = this.z;
- var options = this._options;
- var tileSize = options.tileSize ||256;
-
- var resolution = this.resolution;
-
- var extent = this._extent;
- var tileRes = resolution * tileSize;
- var viewExtent = this.getViewExtent();
-
-
- var startX = Math.floor((viewExtent[0] - extent[0]) / tileRes);
- var startY = Math.floor((extent[3] - viewExtent[3]) / tileRes);
- var endX = Math.ceil((viewExtent[2] - extent[0]) / tileRes);
- var endY = Math.ceil((extent[3] - viewExtent[1]) / tileRes);
-
- // startX = startX < 20 ? 20 : startX;
- startY = startY < 1 ? 1 : startY;
- // endX = endX < 31 ? 31 : endX;
- //endY = endY < 20 ? 20 : endY;
- /* if(this.realz < 5){
- endY = endY > 10 ? 10 : endY
- }*/
-
- var i,j,key,tile;
-
- var tiles = this._tiles;
-
- var newTiles = {}
-
- for(i = startX ; i < endX; i ++){
- for(j = startY; j < endY ; j ++){
- key = this._key(z,i,j);
- if(!tiles[key]){
- caches.get(key);
- if(caches.get(key)){
- newTiles[key] = caches.get(key);
- }else{
- tile = new Tile(z,i,j,resolution,this);
- newTiles[key] = tile;
- }
- }else{
- newTiles[key] = tiles[key];
- delete tiles[key];
- }
- }
- };
-
- for(var key in tiles){
- if(tiles[key].request){
- tiles[key].request.cancel();
- }
- }
-
- this._tiles = newTiles;
-
- },
- _key:function(z,x,y){
- return z+'/'+x+"/"+y;
- },
- /**
- * 计算分辨率
- */
- getResolutionFromZ:function(z){
- return [
- 1.25764139776733, 0.628820698883665, 0.251528279553466,
- 0.125764139776733, 0.0628820698883665, 0.0251528279553466,
- 0.0125764139776733, 0.00628820698883665, 0.00251528279553466,
- 0.00125764139776733, 0.000628820698883665, 0.000251528279553466,
- 0.000125764139776733, 0.0000628820698883665, 0.0000251528279553466,
- 0.0000125764139776733, 0.00000628820698883665, 0.00000251528279553466,
- 0.00000125764139776733, 0.000000628820698883665,
- 0.000000251528279553466,
- /* 0.7031250000000002, 0.3515625000000001, 0.17578125000000006,
- 0.043945312500000014, 0.021972656250000007, 0.010986328125000003,
- 0.005493164062500002, 0.002746582031250001, 0.0013732910156250004,
- 6.866455078125002E-4, 3.433227539062501E-4, 1.7166137695312505E-4,
- 8.583068847656253E-5, 4.2915344238281264E-5, 2.1457672119140632E-5,
- 1.0728836059570316E-5, 5.364418029785158E-6, 2.682209014892579E-6,
- 1.3411045074462895E-6*/
- ][z];
- // return 1.4062500000000002 / Math.pow(2,z);
- },
- /**
- * 计算extent
- */
- getViewExtent:function(){
- var transform = this._transform;
- var bounds = [
- transform.pointLocation(new lib.Point(0, 0)),
- transform.pointLocation(new lib.Point(transform.width, 0)),
- transform.pointLocation(new lib.Point(transform.width, transform.height)),
- transform.pointLocation(new lib.Point(0, transform.height))
- ];
-
- var minx , miny , maxx, maxy;
-
- for(var i = 0,point = null ; i < bounds.length ; i ++ ){
- point = bounds[i];
- if(i == 0 ){
- minx = point.lng;
- miny = point.lat;
- maxx = point.lng;i
- maxy = point.lat;
- }else {
- if(minx > point.lng) minx = point.lng;
- if(miny > point.lat) miny = point.lat;
- if(maxx < point.lng) maxx = point.lng;
- if(maxy < point.lat) maxy = point.lat;
- }
- }
-
- // [minx,miny,maxx,maxy] = [gcj02_To_gps84(minx,miny),gcj02_To_gps84(maxx,maxy)].flat();
-
- return [
- clamp(minx,-180,180),
- clamp(miny,-90,90),
- clamp(maxx,-180,180),
- clamp(maxy,-90,90)
- ]
- },
- /**
- * 重绘
- */
- repaint:function(){
- this._map.triggerRepaint();
- }
-
- }
-
- /**
- * 请求
- * @param {*} url
- * @param {*} callback
- * @param {*} async
- */
- var getImage = (function(){
-
- var MAX_REQUEST_NUM = 16000;
-
- var requestNum = 0;
- var requestQuenes = [];
-
- function getImage(url,callback){
- if(requestNum > MAX_REQUEST_NUM){
- var quene = {
- url:url,
- callback:callback,
- canceled:false,
- cancel:function(){
- this.canceled = true;
- }
- }
- requestQuenes.push(quene);
- return quene;
- }
-
- var advanced = false;
- var advanceImageRequestQueue = function () {
- if (advanced) { return; }
- advanced = true;
- requestNum--;
- while (requestQuenes.length && requestNum < MAX_REQUEST_NUM) { // eslint-disable-line
- var request = requestQuenes.shift();
- var url = request.url;
- var callback = request.callback;
- var canceled = request.canceled;
- if (!canceled) {
- request.cancel = getImage(url, callback).cancel;
- }
- }
- };
-
- requestNum ++ ;
- var req = get(url,function(error,data){
- advanceImageRequestQueue();
- if(!error){
- var URL = window.URL || window.webkitURL;
- var blob = new Blob([data],{type:"image/png"});
- var blobUrl = URL.createObjectURL(blob)
- var image = new Image();
- image.src = blobUrl;
- image.onload = function(){
- callback(image);
- URL.revokeObjectURL(image.src);
- };
- image.src = data.byteLength ? URL.createObjectURL(blob) : transparentPngUrl;
- }
-
- });
-
- return {
- cancel:function(){
- req.abort();
- }
- }
- }
-
- function get(url, callback, async) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, async === false ? false : true);
- xhr.responseType = "arraybuffer";
- xhr.onabort = function (event) {
- callback(true, null);
- };
- xhr.onload = function (event) {
- if (!xhr.status || xhr.status >= 200 && xhr.status < 300) {
- var source;
- source = xhr.response;
- if (source) {
- try {
- source = eval("(" + source + ")");
- } catch (e) {
- }
- }
- if (source) {
- callback(false, source);
- } else {
- callback(false, null);
- }
- }
- };
- xhr.onerror = function (e) {
- callback(true, null);
- };
- xhr.send(null);
- return xhr;
- }
-
- return getImage;
- })()
-
-
-
- function Tile(z,x,y,resolution,layer){
- this._resolution = resolution;
- this._layer = layer;
- this._coord = [z,x,y];
- this._gl = layer._gl;
- this._url = layer._options.url;
- this.texture = null;
- this.loaded = false;
- this.tileSize = layer._options.tileSize;
- this.worldExtent = layer._extent;
- this.extent = [0,0,0,0];
- this.translate = [0,0,0,0];
- this._load();
- }
-
- Tile.prototype = {
- constructor:Tile,
-
- calcExtent:function(){
-
- var gl = this._gl;
- var worldExtent = this.worldExtent;
- var tileSize = this.tileSize;
- var resolution = this._resolution;
- var coord = this._coord;
- var x = coord[1],y = coord[2];
-
- var maxTileNum = Math.ceil((worldExtent[3] - worldExtent[1]) / resolution / tileSize);
-
- var minx = clamp(x * tileSize * resolution - worldExtent[2],-180,180);
- var maxx = clamp(minx + tileSize * resolution, -180,180);
- var maxy = clamp(worldExtent[3] - y * tileSize * resolution, -90 , 90 );
- var miny = clamp(maxy - tileSize * resolution, -90,90);
-
- var y1 = y + 1;
- y1 = y1 > maxTileNum ? maxTileNum : y1;
- maxy1 = worldExtent[3] - y1 * tileSize * resolution;
-
- var bl = lib.MercatorCoordinate.fromLngLat(gps84_To_gcj02(minx,miny));
- var tr = lib.MercatorCoordinate.fromLngLat(gps84_To_gcj02(maxx,maxy));
-
- this.extent[0] = bl.x;
- this.extent[1] = bl.y;
- this.extent[2] = tr.x;
- this.extent[3] = tr.y;
-
- //var centerMecatorExtent = this._layer.centerMecatorExtent;
-
- // if(!this.translate){
- // this.translate = [0,0,0,0];
- // }
-
- // this.translate[0] = bl.x - centerMecatorExtent[0];
- // this.translate[1] = bl.y - centerMecatorExtent[1];
- // this.translate[2] = tr.x - centerMecatorExtent[2];
- // this.translate[3] = tr.y - centerMecatorExtent[3];
-
- },
- _load: function(){
- var gl = this._gl
- var _this = this;
- var z = this._coord[0];
- var x = this._coord[1];
- var y = this._coord[2];
- var url = this._url.replace("{x}",x).replace("{y}",y).replace("{z}",z);
- this.request = getImage(url,function(img){
- delete _this .request;
- if(_this._gl){
- var texture = _this.texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
- gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
- gl.bindTexture(gl.TEXTURE_2D, null);
- caches.put(z+"/"+x+"/"+y,_this);
- _this.loaded = true;
- _this._layer.repaint();
- }
- });
- }
- }
-
-
- return TileXYZLayerFor4326
-
- })()