在学习cesium中,有这么一个需求,就是手动圈中一个面【多边形】,然后在地图上标注一些标注点,并判断这些点哪些在面内加以区分。
首先需要创建一个面,代码如下:
const polygon = new Cesium.Entity({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
105.0, 32.0, 131.0, 32.0, 131.0, 50.0, 105.0, 50.0, 102.0, 40.0, 105.0,
32.0,
]),
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// 将多边形添加到Viewer中
cesiumGather.cesiumViewer.entities.add(polygon);
};
然后创建点,【之前的文章有提过,可以自行翻阅】。
让后通过Turf.js来进行判断,这个js文件库,主要用于地图坐标判断、转化等等,可自行查看Turf官网
完整代码如下:
<template>
<div id="cesiumContainer" />
</template>
<script setup>
import * as turf from "@turf/turf";
import * as Cesium from "cesium";
import { reactive, onMounted } from "vue";
const cesiumGather = reactive({
popVisible: false,
overlayChartObj: {},
cesiumViewer: null,
popClickVisble: false,
});
onMounted(() => {
// 添加图层
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false, //搜索框
homeButton: false, //home键
animation: false, //动画控件
fullscreenButton: false, //全屏按钮
sceneModePicker: false, //场景模式选择器
timeline: false, //时间轴
navigationHelpButton: false, //导航提示
baseLayerPicker: false, //地图选择器
// infoBox: false, //是否显示信息框
scene3DOnly: false, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
selectionIndicator: false, //是否显示选取指示器组件
baselLayerPicker: false, // 将图层选择的控件关掉,才能添加其他影像数据
});
viewer._cesiumWidget._creditContainer.style.display = "none";
cesiumGather.cesiumViewer = viewer;
mapCesiumData();
drawPolygon();
searchPointList();
});
// 获取聚合数据
const mapCesiumData = () => {
let queryData = [
[
{ lng: 104.023442, lat: 23.44311, label: "标点AA1" },
{ lng: 134.023442, lat: 27.44331, label: "标点AA2" },
{ lng: 105.023442, lat: 32.44311, label: "标点AA3" },
{ lng: 104.023442, lat: 23.44231, label: "标点AA4" },
{ lng: 105.023442, lat: 13.44311, label: "标点AA5" },
{ lng: 114.023442, lat: 33.44331, label: "标点AA6" },
{ lng: 124.023442, lat: 43.42311, label: "标点AA7" },
{ lng: 134.023442, lat: 33.42331, label: "标点AA8" },
{ lng: 144.023442, lat: 53.14311, label: "标点AA9" },
{ lng: 101.023442, lat: 23.44341, label: "标点AA10" },
{ lng: 104.023442, lat: 23.44321, label: "标点一" },
{ lng: 134.023442, lat: 27.44321, label: "标点二" },
{ lng: 105.023442, lat: 32.44321, label: "标点三" },
{ lng: 134.023442, lat: 23.44221, label: "标点四" },
{ lng: 125.023442, lat: 13.44321, label: "标点五" },
{ lng: 114.023442, lat: 33.44321, label: "标点六" },
{ lng: 124.023442, lat: 43.42321, label: "标点七" },
{ lng: 114.023442, lat: 33.42321, label: "标点八" },
{ lng: 124.023442, lat: 53.14321, label: "标点九" },
{ lng: 101.023442, lat: 23.44321, label: "标点十" },
{ lng: 104.023442, lat: 23.44322, label: "标点CC1" },
{ lng: 114.023442, lat: 27.44323, label: "标点CC2" },
{ lng: 125.023442, lat: 32.44322, label: "标点CC3" },
{ lng: 134.023442, lat: 23.44221, label: "标点CC4" },
{ lng: 115.023442, lat: 13.44323, label: "标点CC5" },
{ lng: 134.023442, lat: 33.44324, label: "标点CC6" },
{ lng: 104.023442, lat: 43.42322, label: "标点CC7" },
{ lng: 114.023442, lat: 33.42324, label: "标点CC8" },
{ lng: 124.023442, lat: 53.14322, label: "标点CC9" },
{ lng: 131.023442, lat: 23.44323, label: "标点CC10" },
],
];
queryData.forEach((item, index) => {
// setTimeout(() => {
renderCesiumPoint(cesiumGather.cesiumViewer, item);
// }, 20000 * index);
});
};
// 加载点位
const renderCesiumPoint = (cesiumViewer, projectList) => {
cesiumGather.popVisible = false;
cesiumGather.overlayChartObj = {};
cesiumViewer.entities.removeAll();
for (let i = 0; i < projectList.length; i++) {
const pro = projectList[i];
cesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(pro.lng, pro.lat, 1000),
name: pro.label,
property: pro, //自己加的相关属性,弹窗里需要用到
billboard: {
//图标
image: "./static/images/markers/4.png",
scale: 1, //图标比例
width: 36,
height: 36,
// 垂直方向
verticalOrigin: Cesium.VerticalOrigin.BASELINE,
//水平方向
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
label: {
// 文字标签
text: pro.label,
scale: 1,
font: "16px monospace",
fillColor: Cesium.Color.WHITE,
showBackground: true, //设置背景颜色
pixelOffset: new Cesium.Cartesian2(0, -44), //设置左右、上下移动
// 垂直方向
verticalOrigin: Cesium.VerticalOrigin.BASELINE,
//水平方向
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
description: `<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter">
<tbody>
<tr>
<th>标注名称</th>
<td>${pro.label}</td>
</tr>
<tr>
<th>Longitude</th>
<td>${pro.lng.toFixed(5)}</td>
</tr>
<tr>
<th>Latitude</th>
<td>${pro.lat.toFixed(5)}</td>
</tr>
</tbody>
</table>
<button onclick="handleClick()">点我</button>`,
});
}
};
const drawPolygon = () => {
// 创建多边形对象
const polygon = new Cesium.Entity({
polygon: {
hierarchy: Cesium.Cartesian3.fromDegreesArray([
105.0, 32.0, 131.0, 32.0, 131.0, 50.0, 105.0, 50.0, 102.0, 40.0, 105.0,
32.0,
]),
material: Cesium.Color.BLUE.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// 将多边形添加到Viewer中
cesiumGather.cesiumViewer.entities.add(polygon);
};
const searchPointList = () => {
let queryData = [
[
{ lng: 104.023442, lat: 23.44311, label: "标点AA1" },
{ lng: 134.023442, lat: 27.44331, label: "标点AA2" },
{ lng: 105.023442, lat: 32.44311, label: "标点AA3" }, //
{ lng: 104.023442, lat: 23.44231, label: "标点AA4" },
{ lng: 105.023442, lat: 13.44311, label: "标点AA5" },
{ lng: 114.023442, lat: 33.44331, label: "标点AA6" }, //
{ lng: 124.023442, lat: 43.42311, label: "标点AA7" }, //
{ lng: 134.023442, lat: 33.42331, label: "标点AA8" },
{ lng: 144.023442, lat: 53.14311, label: "标点AA9" },
{ lng: 101.023442, lat: 23.44341, label: "标点AA10" },
{ lng: 104.023442, lat: 23.44321, label: "标点一" },
{ lng: 134.023442, lat: 27.44321, label: "标点二" },
{ lng: 105.023442, lat: 32.44321, label: "标点三" }, //
{ lng: 134.023442, lat: 23.44221, label: "标点四" },
{ lng: 125.023442, lat: 13.44321, label: "标点五" },
{ lng: 114.023442, lat: 33.44321, label: "标点六" }, //
{ lng: 124.023442, lat: 43.42321, label: "标点七" }, //
{ lng: 114.023442, lat: 33.42321, label: "标点八" }, //
{ lng: 124.023442, lat: 53.14321, label: "标点九" },
{ lng: 101.023442, lat: 23.44321, label: "标点十" },
{ lng: 104.023442, lat: 23.44322, label: "标点CC1" },
{ lng: 114.023442, lat: 27.44323, label: "标点CC2" },
{ lng: 125.023442, lat: 32.44322, label: "标点CC3" }, //
{ lng: 134.023442, lat: 23.44221, label: "标点CC4" },
{ lng: 115.023442, lat: 13.44323, label: "标点CC5" },
{ lng: 134.023442, lat: 33.44324, label: "标点CC6" },
{ lng: 104.023442, lat: 43.42322, label: "标点CC7" }, //
{ lng: 114.023442, lat: 33.42324, label: "标点CC8" }, //
{ lng: 124.023442, lat: 53.14322, label: "标点CC9" },
{ lng: 131.023442, lat: 23.44323, label: "标点CC10" },
],
];
let pointList = [];
queryData.forEach((item) => {
item.forEach((tag) => {
pointList.push([tag.lng, tag.lat]);
});
});
let polygonList = [
[105.0, 32.0],
[131.0, 32.0],
[131.0, 50.0],
[105.0, 50.0],
[102.0, 40.0],
[105.0, 32.0],
];
// TODO 返回在多边形内的点【存在缺陷,标点CC3】
/* var ptsWithin = turf.pointsWithinPolygon(
turf.points(pointList),
turf.polygon([polygonList])
);
console.log(ptsWithin,'====ptsWithin===='); */
// TODO 判断点是否在多边形内
pointList.forEach((item) => {
if (
turf.booleanPointInPolygon(turf.point(item), turf.polygon([polygonList]))
) {
console.log(item, "-----");
}
});
};
</script>
<style scoped></style>