最近在项目中遇到一个需求
判断地球上的坐标点在不在区域面的范围内,在的话把点高亮显示,不在范围内的话就变暗显示
- 首先引用cesium 和 turf 库
import * as Cesium from "cesium"
import * as turf from "@turf/turf"
2.在封装一个方法,方法的参数 polygons 是面的经纬度集合,points 是坐标点位的实体对象,也可以直接传经纬度信息,这样就省去了转换,我这里是多做了一步转换处理
/**
* 用来判断这些点在不在这个面里,并且把在面范围里的点高亮显示,不在范围的变暗显示,
* @param polygons 面的数据,格式:([{lon,lat,hei},{lon,lat,hei},{lon,lat,hei},{lon,lat,hei}])
* @param points 点的数据,点的实体对象
* @returns
*/
function cartograhicToDegrees(cartograhic: any) {
return [Cesium.Math.toDegrees(cartograhic.longitude), Cesium.Math.toDegrees(cartograhic.latitude)]
}
export function getJudgeInSide(polygons: any, points: Array<any>) {
let brightEntities: Array<any> = []
//转换经纬度的格式
let degreesArray = pointsToDegreesArray(polygons)
let polygon = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(degreesArray))
let cartographicPolygon = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(polygon.positions)
//把面转成turf格式的面
let geoJsonPolygon = turf.polygon([cartographicPolygon.map(cartograhicToDegrees)])
points.forEach(item => {
//获取实体点的经纬度信息
let res = getEntitiesPointLnoLat(item)
//根据点的经纬度,通过turf转成turf格式的点
let pointTurf = turf.point(res.position)
//通过 turf 的 booleanPointInPolygon 方法判断点是不是在面里
let isInside = turf.booleanPointInPolygon(pointTurf, geoJsonPolygon)
if (isInside) {
//把在范围内的坐标点位实体存到 brightEntities 中
brightEntities.push(item)
//高亮显示范围内的坐标点位
item.billboard.color = Cesium.Color.fromAlpha(Cesium.Color.WHITE, 1)
} else {
//不在范围内的坐标点位变暗处理
item.billboard.color = Cesium.Color.fromAlpha(Cesium.Color.WHITE, 0.2)
}
})
return brightEntities
}
用于获取坐标点位实体点的经纬度信息
/**
* 获取实体点的经纬度信息
* @param point 实体点位
*/
function getEntitiesPointLnoLat(entitiesPoint: any) {
let position = entitiesPoint.position.getValue(Cesium.JulianDate.now())
let longitude = Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(position).longitude)
let latitude = Cesium.Math.toDegrees(Cesium.Cartographic.fromCartesian(position).latitude)
return { position: [longitude, latitude], entities: entitiesPoint }
}
用于面的经纬度格式转换
// 坐标点格式转换
function pointsToDegreesArray(points: any): any {
const degreesArray: any[] = []
points.map((item: any) => {
degreesArray.push(item[0])
degreesArray.push(item[1])
})
return degreesArray
}
3.调用
// brightEntities 是在面范围内的坐标点位实体,可用作其他的处理
let brightEntities = getJudgeInSide(polygons,points)
或
getJudgeInSide(polygons,points)