引入supercluster.js脚本
<script id="cesium_sandcastle_script">
function startup(Cesium) {
'use strict';
//Sandcastle_Begin
//设置主视角,默认进入时视角范围
SetHoumeViewerjd(118.25669445145353, 21.58050898317632, 123.91666536429605, 25.77861604625837);
//创建cesium地球
var viewer = new Cesium.Viewer("cesiumContainer", {
selectionIndicator: true,
infoBox: true,
//需要进行可视化的数据源的集合
animation: true, //是否显示动画控件
shouldAnimate: true,
homeButton: true, //是否显示Home按钮
fullscreenButton: true, //是否显示全屏按钮
baseLayerPicker: true, //是否显示图层选择控件
geocoder: false, //是否显示地名查找控件
timeline: true, //是否显示时间线控件
sceneModePicker: true, //是否显示投影方式控件
navigationHelpButton: true, //是否显示帮助信息控件
requestRenderMode: true, //启用请求渲染模式
scene3DOnly: false, //每个几何实例将只能以3D渲染以节省GPU内存
sceneMode: 3, //初始场景模式 1 2D模式 2 2D循环模式 3 3D模式 Cesium.SceneMode
//加载天地图影像地图,WebMapTileServiceImageryProvider该接口是加载WMTS服务的接口
//tileset添加地形,本地地址
imageryProvider: new Cesium.TileMapServiceImageryProvider({
url: 'http://192.168.2.27:8080' + '/TMS/',
fileExtension: 'jpg',
layer: 'img',
style: 'default',
tileMatrixSetID: 'w',
format: 'tiles',
maximumLevel: 20,
name: "main"
}),
});
//去掉版权信息
viewer._cesiumWidget._creditContainer.style.display = "none";
//光照
viewer.scene.globe.enableLighting = false;
//地形深度
viewer.scene.globe.depthTestAgainstTerrain = false;
var level;//当前地图级别
//设置相机主视角
function SetHoumeViewerjd(west, south, east, north) {
//参数为经纬度
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = new Cesium.Rectangle.fromDegrees(west, south, east, north);
if (Cesium.defined(viewer)) {
var hw1 = viewer.camera.computeViewRectangle();
console.log("设置后相机视角", hw1);
}
}
//加载poi数据
function LoadJsonData() {
getJSON('../Apps/SampleData/geojson/cadshp/上海市-矢量地图_百度POI (V1.0)1.json', (geojson) => {
console.log("加载数据:", geojson.features);
//相机移动事件,获取当前地图级别,相机视角范围
viewer.camera.moveEnd.addEventListener(GetLevel);
//设置地图当前级别,当前相机视角
function GetLevel() {
var tileRender = viewer.scene.globe._surface._tilesToRender;
if (tileRender && tileRender.length > 0) {
level = tileRender[0]._level;
var v3d = GetViewerExtent();
console.log("当前相机视角:", v3d);
viewer.entities.removeAll();//清除全部entity
JuHe(geojson, level, v3d);//聚合算法,技术poi聚合数据
}
}
});
}
//聚合算法,json,当前地图级别
function JuHe(geojson, level, v3d) {
//聚合初始化
var supercluster = new Supercluster({
log: true,
radius: 50,
extent: 256,
minZoom: 0,
maxZoom: 18
});
//加载数据
supercluster.load(geojson.features);
// var clusters = supercluster.getClusters([
// viewer.camera.getExtent()
// ], viewer.camera.getMagnitude());
// var clusters = supercluster.getClusters([
// -180, -90, 180, 90
// ], level);
//获取聚合数据
var clusters = supercluster.getClusters([
v3d.xmin, v3d.ymin, v3d.xmax, v3d.ymax
], level);
console.log("所有需要聚合的数据:", clusters);
//循环生成聚合数据点
for (var i = 0; i < clusters.length; i++) {
var cluster = clusters[i];
if (cluster.properties.cluster) {
// 聚合点点位
var clusterEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(cluster.geometry.coordinates[0], cluster.geometry.coordinates[1]),
billboard: {
image: '../Apps/public/poi/SH_text_daxinggouwuguangchang.png',
width: 20,
height: 26,
//scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1)
},
label: {
text: String(cluster.properties.point_count),
font: '14px sans-serif',
//scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1),
pixelOffset: new Cesium.Cartesian2(0, -30)
}
});
} else {
//根据点位类型,渲染不同的图标
var imageurl;
// 单个点位
if (cluster.properties.stdtag == "旅游景点;其他") {
imageurl = '../Apps/public/poi/SH_text_lvyou.png'
} else if (cluster.properties.stdtag == "酒店;其他") {
imageurl = '../Apps/public/poi/SH_text_zhusu.png'
} else if (cluster.properties.stdtag == "购物;其他") {
imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'
}
else if (cluster.properties.stdtag == "生活服务;其他") {
imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'
} else if (cluster.properties.stdtag == "房地产;其他") {
imageurl = '../Apps/public/poi/SH_text_daxinggouwuguangchang.png'
} else if (cluster.properties.stdtag == "文化传媒;其他") {
imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'
} else if (cluster.properties.stdtag == "休闲娱乐;其他") {
imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'
} else if (cluster.properties.stdtag == "旅游景点;博物馆") {
imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'
} else if (cluster.properties.stdtag == "旅游景点;博物馆") {
imageurl = '../Apps/public/poi/SH_text_juyuangongyuandaxueyizhi.png'
} else {
imageurl = '../Apps/public/poi/point.png'
}
var markerEntity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(cluster.geometry.coordinates[0], cluster.geometry.coordinates[1]),
billboard: {
image: imageurl,
width: 20,
height: 26
},
label: {
text: String(cluster.properties.Name),
font: '14px sans-serif',
//scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 1.5e6, 0.1),
pixelOffset: new Cesium.Cartesian2(0, -30)
}
});
}
}
}
// 获取当前三维范围
function getCurrentExtent() {
// 范围对象
var extent = {};
// 得到当前三维场景
var scene = viewer.scene;
// 得到当前三维场景的椭球体
var ellipsoid = scene.globe.ellipsoid;
var canvas = scene.canvas;
// canvas左上角
var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);
// canvas右下角
var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);
// 当canvas左上角和右下角全部在椭球体上
if (car3_lt && car3_rb) {
var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
// extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
// extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
// extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
// extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
extent.xmin = carto_lt.longitude;
extent.ymax = carto_lt.latitude;
extent.xmax = carto_rb.longitude;
extent.ymin = carto_rb.latitude;
}
// 当canvas左上角不在但右下角在椭球体上
else if (!car3_lt && car3_rb) {
var car3_lt2 = null;
var yIndex = 0;
do {
// 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率
yIndex <= canvas.height ? yIndex += 10 : canvas.height;
car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);
} while (!car3_lt2);
var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
// extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
// extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
// extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
// extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
extent.xmin = carto_lt.longitude;
extent.ymax = carto_lt.latitude;
extent.xmax = carto_rb.longitude;
extent.ymin = carto_rb.latitude;
}
// 获取高度
extent.height = Math.ceil(viewer.camera.positionCartographic.height);
return extent;
}
//获取相机当前视角
function GetViewerExtent() {
// 范围对象
var extent = {};
var hw = viewer.camera.computeViewRectangle();
console.log("当前相机视角", hw);
var maxx = Cesium.Math.toDegrees(hw.east);
var maxy = Cesium.Math.toDegrees(hw.north);
var minx = Cesium.Math.toDegrees(hw.west);
var miny = Cesium.Math.toDegrees(hw.south);
console.log("相机经纬度---", maxx, "---", maxy, "---", minx, "---", miny);
extent.xmin = minx;
extent.ymax = maxy;
extent.xmax = maxx;
extent.ymin = miny;
return extent;
}
$("#load").click(function () {
console.log("加载");
LoadJsonData();
});
//加载json
function LoadJson() {
let index;
getJSON('../Apps/superclusterdemo/places.json', (geojson) => {
console.log(`loaded ${geojson.features.length} points JSON `);
index = new Supercluster({
log: true,
radius: 60,
extent: 256,
maxZoom: 20
}).load(geojson.features);
index.getTile(0, 0, 0);
console.log("源数据:", index);
console.log(index.getTile(0, 0, 0));
});
}
//读取json数据POI
function getJSON(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300 && xhr.response) {
callback(xhr.response);
}
};
xhr.send();
}
//Sandcastle_End
Sandcastle.finishedLoading();
}
if (typeof Cesium !== 'undefined') {
window.startupCalled = true;
startup(Cesium);
}
</script>
cesium 使用supercluster.js插件实现聚合功能
于 2024-01-19 15:48:41 首次发布