日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

html5页面热力图几十万数据,基于百度地图的数据可视化,包括大量数据的标绘以及热力图的插入...

發布時間:2023/12/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 html5页面热力图几十万数据,基于百度地图的数据可视化,包括大量数据的标绘以及热力图的插入... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(function(global, factory) {

typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :

typeof define === 'function' && define.amd ? define(factory) :

(global.PointLine = factory());

}(this, (function() {

'use strict';

/**

* @author https://github.com/chengquan223

* @Date 2017-02-27

* */

function CanvasLayer(options) {

this.options = options || {};

this.paneName = this.options.paneName || 'labelPane';

this.zIndex = this.options.zIndex || 0;

this._map = options.map;

this._lastDrawTime = null;

this.show();

}

CanvasLayer.prototype = new BMap.Overlay();

CanvasLayer.prototype.initialize = function(map) {

this._map = map;

var canvas = this.canvas = document.createElement('canvas');

var ctx = this.ctx = this.canvas.getContext('2d');

canvas.style.cssText = 'position:absolute;' + 'left:0;' + 'top:0;' + 'z-index:' + this.zIndex + ';';

this.adjustSize();

this.adjustRatio(ctx);

map.getPanes()[this.paneName].appendChild(canvas);

var that = this;

map.addEventListener('resize', function() {

that.adjustSize();

that._draw();

});

return this.canvas;

};

CanvasLayer.prototype.adjustSize = function() {

var size = this._map.getSize();

var canvas = this.canvas;

canvas.width = size.width;

canvas.height = size.height;

canvas.style.width = canvas.width + 'px';

canvas.style.height = canvas.height + 'px';

};

CanvasLayer.prototype.adjustRatio = function(ctx) {

var backingStore = ctx.backingStorePixelRatio || ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio ||

ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;

var pixelRatio = (window.devicePixelRatio || 1) / backingStore;

var canvasWidth = ctx.canvas.width;

var canvasHeight = ctx.canvas.height;

ctx.canvas.width = canvasWidth * pixelRatio;

ctx.canvas.height = canvasHeight * pixelRatio;

ctx.canvas.style.width = canvasWidth + 'px';

ctx.canvas.style.height = canvasHeight + 'px';

// console.log(ctx.canvas.height, canvasHeight);

ctx.scale(pixelRatio, pixelRatio);

};

CanvasLayer.prototype.draw = function() {

var self = this;

var args = arguments;

clearTimeout(self.timeoutID);

self.timeoutID = setTimeout(function() {

self._draw();

}, 15);

};

CanvasLayer.prototype._draw = function() {

var map = this._map;

var size = map.getSize();

var center = map.getCenter();

if (center) {

var pixel = map.pointToOverlayPixel(center);

this.canvas.style.left = pixel.x - size.width / 2 + 'px';

this.canvas.style.top = pixel.y - size.height / 2 + 'px';

this.dispatchEvent('draw');

this.options.update && this.options.update.call(this);

}

};

CanvasLayer.prototype.getContainer = function() {

return this.canvas;

};

CanvasLayer.prototype.show = function() {

if (!this.canvas) {

this._map.addOverlay(this);

}

this.canvas.style.display = 'block';

};

CanvasLayer.prototype.hide = function() {

this.canvas.style.display = 'none';

//this._map.removeOverlay(this);

};

CanvasLayer.prototype.setZIndex = function(zIndex) {

this.canvas.style.zIndex = zIndex;

};

CanvasLayer.prototype.getZIndex = function() {

return this.zIndex;

};

var tool = {

merge: function merge(settings, defaults) {

Object.keys(settings).forEach(function(key) {

defaults[key] = settings[key];

});

},

//計算兩點間距離

getDistance: function getDistance(p1, p2) {

return Math.sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]));

},

//判斷點是否在線段上

containStroke: function containStroke(x0, y0, x1, y1, lineWidth, x, y) {

if (lineWidth === 0) {

return false;

}

var _l = lineWidth;

var _a = 0;

var _b = x0;

// Quick reject

if (y > y0 + _l && y > y1 + _l || y < y0 - _l && y < y1 - _l || x > x0 + _l && x > x1 + _l || x < x0 - _l && x <

x1 - _l) {

return false;

}

if (x0 !== x1) {

_a = (y0 - y1) / (x0 - x1);

_b = (x0 * y1 - x1 * y0) / (x0 - x1);

} else {

return Math.abs(x - x0) <= _l / 2;

}

var tmp = _a * x - y + _b;

var _s = tmp * tmp / (_a * _a + 1);

return _s <= _l / 2 * _l / 2;

},

// 判斷點擊圖片的位置

containStrokeImage: function(clickPoint, markerPoint) {

var markerWidth = 32,

markerHeight = 32,

self = this;

var marker = self.isimageContent(markerPoint);

var arr = [];

if (marker.leftTopX <= clickPoint.x && clickPoint.x <= marker.rightBottomX && clickPoint.y < marker.rightBottomY &&

marker.leftTopY < clickPoint.y) {

return true;

} else {

return false;

}

// ctx.clearRech(0,0,ctx.width,ctx.height);

/**

* 1.點擊的位置

* 2.計算出四個邊角的位置

* 3. 篩選出是否在四邊之內

*

*

*

*

* **/

},

isimageContent: function(markerPoint) {

return {

leftTopX: markerPoint.x,

leftTopY: markerPoint.y,

rightBottomX: markerPoint.x + 32,

rightBottomY: markerPoint.y + 32

}

},

//點擊的區域重合的時候

selectZjFunc: function(markerarr, e) {

var thatSelectjl = 0;

var thatIndex = 0

var self = this;

markerarr.forEach((item, index) => {

var markerpix = item.marker.pixel;

var thisjl = self.selectjsFunc(markerpix, e)

if (thisjl > thatSelectjl) {

thatSelectjl = thisjl

thatIndex = index

}

})

return thatIndex;

},

// 計算點擊的位置距離部署點位的距離

selectjsFunc: function(marker, e) {

return Math.sqrt((marker.x - e.x) * (marker.x - e.x) + (e.y - marker.y) * (e.y - marker.y))

},

//點聚合算法的實現1. 實現拆分屏幕

//2. 數據判斷

//3. 實現繪制(僅限熱力圖,如果有后續需要做出標繪的點聚合,也可以)

cfpmFunc: function(width, height, cfWidth) {

var self = this;

//橫向

var widthLength = parseInt(width / cfWidth) + 1;

var widthOver = width % cfWidth

var widthHeight = parseInt(height / cfWidth) + 1;

var heightOver = height % cfWidth

var pointarr = [];

for (var i = 1; i <= widthLength; i++) {

for (var j = 1; j <= widthHeight; j++) {

var obj = {}

obj.leftTopX = (i - 1) * cfWidth;

obj.leftTopY = (j - 1) * cfWidth;

obj.rightBottomX = (i - 1) * cfWidth;

obj.rightBottomY = (j - 1) * cfWidth;

if (i == widthLength) {

if (j == widthHeight) {

obj.rightBottomX = (i - 1) * cfWidth + widthOver;

obj.rightBottomY = (j - 1) * cfWidth + heightOver;

} else {

obj.rightBottomX = (i - 1) * cfWidth + widthOver;

obj.rightBottomY = j * cfWidth;

}

} else {

obj.rightBottomX = i * cfWidth;

obj.rightBottomY = (j - 1) * cfWidth + heightOver;

}

pointarr.push(obj)

}

}

return pointarr;

},

// 當前方框內是否存在數據

jhFunc: function(clickPoint, marker, width, height) {

var self = this;

if (marker.leftTopX <= clickPoint.x && clickPoint.x <= marker.rightBottomX && clickPoint.y < marker.rightBottomY &&

marker.leftTopY < clickPoint.y) {

return true;

} else {

return false;

}

},

};

//所有圖片存儲的位置

var base64Image = {

tzred:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozMmMyNjgwOS1mOTMwLTQyYTEtYjBjZi1kNjYyNjY3MjFhYzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDREODQ2QTAxMTgyMTFFNDk0QTg5MjZDRjBEOTA3RDkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDREODQ2OUYxMTgyMTFFNDk0QTg5MjZDRjBEOTA3RDkiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NjY2N2Q2MDAtM2RkMS00ZWZhLTgyNTktZTA0MWUyYTkwOTZjIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjMyYzI2ODA5LWY5MzAtNDJhMS1iMGNmLWQ2NjI2NjcyMWFjMSIvPiA8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"

}

var PointLine = function PointLine(map, userOptions) {

var self = this;

self.map = map;

self.lines = [];

self.pixelList = [];

//默認參數

//需要的數據

/**

* 經度,緯度,標題頭 添加的點擊事件

*

* **/

var options = {

};

//全局變量

var baseLayer = null,

//獲取當前所需要的canvas的寬高

width = map.getSize().width,

height = map.getSize().height;

function Line(opts) {

// this.message = opts.message;//裝備信息

// this.path = opts.path;//裝備的位置

this.tzArr = opts.tzArr;

}

//繪制軍標

Line.prototype.draw = function() {

var self = this;

var ctx = self.ctx;

var img = new Image();

//等待處理

// img.setAttribute("crossOrigin","")

img.onload = function() {

for (let i = 0; i < self.pixelList.length; i++) {

const item = self.pixelList[i]

ctx.drawImage(img, item.pixel.x, item.pixel.y, 32, 32);

}

// 存儲到這個的全局變量

}

img.src = base64Image.tzred;

}

//熱力圖繪制

Line.prototype.drawHot = function() {

var self = this;

var ctx = self.ctx;

var radius = 50;

for (let i = 0; i < self.jhArr.length; i++) {

const item = self.jhArr[i]

if(!item){

continue

}

ctx.beginPath()

ctx.arc(item.pixel.x, item.pixel.y, radius, 0, 2 * Math.PI);

ctx.closePath()

let radialGradient = ctx.createRadialGradient(item.pixel.x, item.pixel.y, 0, item.pixel.x, item.pixel.y,

radius);

radialGradient.addColorStop(0.0, "rgba(0,0,0,1)")

radialGradient.addColorStop(1.0, "rgba(0,0,0,0)")

ctx.fillStyle = radialGradient;

//權重對比算法,替換算法

// let globalAlpha = (value - min) / (max - min);

// ctx.globalAlpha = Math.max(Math.min(globalAlpha, 1), 0)

ctx.fill()

}

//自定義調色板

var paientCanvas = document.createElement('canvas')

var paientctx = paientCanvas.getContext('2d');

let gradentConfig = {

'0.2': 'rgba(0,0,255,0.2)',

'0.3': 'rgba(43,111,231,0.3)',

'0.4': 'rgba(2,192,241,0.4)',

'0.6': 'rgba(44,222,148,0.6)',

'0.8': 'rgba(254,237,83,0.8)',

'0.9': 'rgba(255,118,55,0.9)',

'1.0': 'rgba(255,64,28,1)',

}

paientCanvas.width = 256;

paientCanvas.height = 1;

var gradient = paientctx.createLinearGradient(0, 0, 256, 1)

for (var key in gradentConfig) {

gradient.addColorStop(key, gradentConfig[key])

}

paientctx.fillStyle = gradient;

paientctx.fillRect(0, 0, 256, 1)

//獲取到需要映射的imagedata

var imgdata = paientctx.getImageData(0, 0, 256, 1).data;

var img = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height)

var ctxImagedata = img.data

for (var i = 3; i < ctxImagedata.length; i += 4) {

var alpha = ctxImagedata[i]

var offset = alpha * 4;

if (!offset) {

continue

}

ctxImagedata[i - 3] = imgdata[offset]

ctxImagedata[i - 2] = imgdata[offset + 1]

ctxImagedata[i - 1] = imgdata[offset + 2]

}

//卡頓,需要點聚合的算法進行相應處理

ctx.putImageData(img, 0, 0, 0, 0, ctx.canvas.width, ctx.canvas.height)

}

//底層canvas添加

var brush = function brush() {

// 創建一個新的canvas

var baseCtx = baseLayer.canvas.getContext('2d');

if (!baseCtx) {

return;

}

//添加軍標

addLine();

baseCtx.clearRect(0, 0, width, height);

//獲取當前地圖層級

var zoom = map.getZoom();

self.lines.pixelList = [];

self.lines.tzArr.forEach((item) => {

self.lines.pixelList.push({

message: item.message,

pixel: map.pointToPixel(item.H)

})

})

self.lines.ctx = baseCtx

if (zoom > 12) {

self.lines.draw();

} else {

//將屏幕分為50*50的網格,并且確定左上角和右下角的點的位置

var pmWg = tool.cfpmFunc(baseCtx.canvas.width, baseCtx.canvas.height, 50)

//將網格內存在的點做進一步的篩選

// console.log(pmWg)

var jhArr = []

self.lines.tzArr.forEach((item) => {

var thisPixel = map.pointToPixel(item.H);

//篩選掉超出屏幕邊界的點

if (thisPixel.x < 0 || thisPixel.y < 0 || thisPixel.x > baseCtx.canvas.width || thisPixel.y > baseCtx.canvas

.height) {

return

}

//進一步篩選點

for (let k in pmWg) {

var itemWg = pmWg[k]

if (tool.jhFunc(thisPixel, itemWg, 50, 50)) {

if (jhArr[k]) {

continue;

} else {

jhArr[k] = {

message: item.message,

pixel: thisPixel

}

}

}

}

})

self.lines.jhArr = jhArr;

self.lines.drawHot();

}

};

var addLine = function addLine() {

// if (self.lines!=""&&!self.lines) return;

var dataset = options.data;

dataset.forEach((item, index) => {

item.H = new BMap.Point(item.lng, item.lat)

})

var line = new Line({

tzArr: dataset

})

self.lines = line;

};

self.init(userOptions, options);

baseLayer = new CanvasLayer({

map: map,

update: brush

});

this.clickEvent = this.clickEvent.bind(this);

this.bindEvent();

};

PointLine.prototype.init = function(settings, defaults) {

//合并參數

tool.merge(settings, defaults);

this.options = defaults;

};

PointLine.prototype.bindEvent = function(e) {

var map = this.map;

if (this.options.methods) {

if (this.options.methods.click) {

map.setDefaultCursor("default");

map.addEventListener('click', this.clickEvent);

}

if (this.options.methods.mousemove) {

map.setDefaultCursor("default");

map.addEventListener('mousemove', this.moveEvent);

}

}

};

PointLine.prototype.clickEvent = function(e) {

var self = this,

lines = self.lines.pixelList;

var curPt = e.pixel;

var arr = []

if (lines.length > 0) {

lines.forEach(function(marker, i) {

var markerPixel = marker.pixel;

var isOnMarker = tool.containStrokeImage(curPt, markerPixel)

if (isOnMarker) {

arr.push({

index: i,

marker: marker

})

}

});

}

if (arr.length > 1) {

var lastGod = tool.selectZjFunc(arr, curPt)

self.options.methods.click(e, arr[lastGod].marker.message);

return;

} else if (arr.length == 1) {

var lastGod = arr[0].marker.message

self.options.methods.click(e, arr[0].marker.message);

return;

} else {

return;

}

};

return PointLine;

})));

總結

以上是生活随笔為你收集整理的html5页面热力图几十万数据,基于百度地图的数据可视化,包括大量数据的标绘以及热力图的插入...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。