cesium加载geojson数据实现鼠标悬停变色高亮效果

cesium实现geojson数据鼠标悬停高亮效果

项目所需,要在cesium上加载geojson数据后实现hover效果,但没找到cesium原生实现的方法,遂用笨办法去模拟一下效果,若大神们有其他方法万望指出。

hover效果可理解为判断鼠标是否移动到目标区域内(不考虑鼠标正好在区域边的情况,目标区域可以看作多边形),若在区域内则区域变色高亮。所以模拟实现的方法可以划归为判断点是否在多边形内部,并进行相应的高亮效果。

具体实现
判断点是否在多边形内部的方法可通过射线法实现,也可利用turf.js中的booleanPointInPolygon实现。本文利用射线法的方式实现。射线法是通过点引出射线与多边形交点个数判断是否,若为奇数则在多边形内部,为偶数则在多边形外部。
点坐标的数据通过cesium viewer.screenSpaceEventHandler.setInputAction实时监听实现。
多边形高亮效果则可通过对加载的材质进行赋值实现, 例如:

entities[0].polygon.material = new
Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(’#7AFDE0’).withAlpha(0.5));

viewer.screenSpaceEventHandler.setInputAction(function(movement:any) {
                //获取鼠标移动后停留位置坐标
                let ifcartesian = viewer.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
                if (ifcartesian) {
                    let ball = Cesium.Ellipsoid.WGS84.cartesianToCartographic(ifcartesian);
                    Y_String = Cesium.Math.toDegrees(ball.latitude);
                    X_String = Cesium.Math.toDegrees(ball.longitude);
                    let high = viewer.scene.globe.getHeight(ball)
                    pointPosition = Cesium.Cartesian3.fromDegrees(X_String,Y_String,high);
                }
                let endPosition = [pointPosition.x,pointPosition.y];
                //根据是否在多边形内部,在哪个多边形内部进行材质上色
                if(isInPolygon(endPosition,polygon_point[0])){
				//高亮效果
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        });
        //检测点是否在多边形内部,返回T/F
        function isInPolygon(checkPoint:any, polygonPoints:any) {
            var counter = 0;
            var i;
            var xinters;
            var p1, p2;
            var pointCount = polygonPoints.length;
            p1 = polygonPoints[0];
            for (i = 1; i <= pointCount; i++) {
                p2 = polygonPoints[i % pointCount];
                if (
                    checkPoint[0] > Math.min(p1[0], p2[0]) &&
                    checkPoint[0] <= Math.max(p1[0], p2[0])
                ) {
                    if (checkPoint[1] <= Math.max(p1[1], p2[1])) {
                        if (p1[0] != p2[0]) {
                            xinters =
                                (checkPoint[0] - p1[0]) *
                                    (p2[1] - p1[1]) /
                                    (p2[0] - p1[0]) +
                                p1[1];
                            if (p1[1] == p2[1] || checkPoint[1] <= xinters) {
                                counter++;
                            }
                        }
                    }
                }
                p1 = p2;
            }
            if (counter % 2 == 0) {
                return false;
            } else {
                return true;
            }
        };

该方法存在的弊端是会占用较多的系统资源,并且在响应上会有一定的延迟。若有更好的方法模拟hover效果希望指正。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值