cesium实现给三维建筑物贴图

 代码太多直接贴上来看吧……就是cesium.js并没有直接给三维建筑模型贴图的方法,但是有把图片变成三维模型的方法,利用这个方法,给图片设置长宽高,定义经纬度和图片旋转角度,做出一个图片贴在模型上的假效果,其实这并不是贴图,而是一个图片图层,我这里是利用cesium的滚轮事件来触发贴图的,但是现在由于建筑物特别多,显示所有贴图会超级卡、电脑会崩溃。正在解决中……以下是代码,效果图以后帖

Cesium.Ion.defaultAccessToken = "官网申请的token"

var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        // url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=42dca576db031641be0524ee977ddd04'
        url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
    }),
    animation: false,
    timeline: false,  //时间线
    fullscreenButton: true,  //全屏模式
    infoBox: false,  //要素信息框
    homeButton: false, //显示主页
    geocoder: false, //搜索位置
    sceneModePicker: true,//模式切换
    selectionIndicator: true, //展示三维的指示器
    navigationHelpButton: false, //帮助按钮
    navigationInstructionsInitiallyVisible: false
});
viewer.extend(Cesium.viewerCesiumNavigationMixin, {});  //添加指南针控件
//经度、纬度、建筑物视角高度
var initialPosition = new Cesium.Cartesian3.fromDegrees(117.146985,39.1039, 500);
// var initialPosition = new Cesium.Cartesian3.fromDegrees(117.122208999746, 39.1504710002357, 20);

var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949050, 0.025883251314950971306);
var homeCameraView = {
    destination: initialPosition,
    orientation: {
        heading: initialOrientation.heading,//围绕负z轴的旋转
        pitch: initialOrientation.pitch,//围绕负y轴的旋转
        roll: initialOrientation.roll//围绕正x轴的旋转
    }
};
viewer.scene.camera.setView(homeCameraView);  //将相机设定在特定的位置和方向

var layer= new Cesium.WebMapTileServiceImageryProvider({
    url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=42dca576db031641be0524ee977ddd04',
    layer:'img',
    style:'default',
    tileMatrixSetID:'w',
    format:'tiles',
    maximumLevel: 18

});
viewer.imageryLayers.addImageryProvider(layer);

var layer1 = new Cesium.WebMapTileServiceImageryProvider({
    url: 'http://t0.tianditu.gov.cn/cia_w/wmts?tk=42dca576db031641be0524ee977ddd04',
    layer: 'cia',
    style: 'default',
    tileMatrixSetID: 'w',
    format: 'tiles',
    maximumLevel: 18
});
viewer.imageryLayers.addImageryProvider(layer1);



//根据建筑物数值加载不同颜色
function setColor(leq) {
    if (leq < 30) {
        return Cesium.Color.fromCssColorString('#267300');
    } else if (leq >= 30 && leq < 35) {
        return Cesium.Color.fromCssColorString('#5E8C00');
    }
    else if (leq >= 35 && leq < 40) {
        return Cesium.Color.fromCssColorString('#A8A800');
    } else if (leq >= 40 && leq < 45) {
        return Cesium.Color.fromCssColorString('#C48300');
    } else if (leq >= 45 && leq < 50) {
        return Cesium.Color.fromCssColorString('#E04B00');
    } else if (leq >= 50 && leq < 55) {
        return Cesium.Color.fromCssColorString('#FF0000');
    } else if (leq >= 55 && leq < 60) {
        return Cesium.Color.fromCssColorString('#D41923');
    } else if (leq >= 60 && leq < 65) {
        return Cesium.Color.fromCssColorString('#A82236');
    } else if (leq >= 65 && leq < 70) {
        return Cesium.Color.fromCssColorString('#7D250A');
    } else if (leq >= 70 && leq <= 75) {
        return Cesium.Color.fromCssColorString('#4F275E');
    }
    else {
        return Cesium.Color.fromCssColorString('#002673');
    }
}
/*//视角高度?
function getLevel(height) {
    if (height > 48000000) {
        return 0;
    } else if (height > 24000000) {
        return 1;
    } else if (height > 12000000) {
        return 2;
    } else if (height > 6000000) {
        return 3;
    } else if (height > 3000000) {
        return 4;
    } else if (height > 1500000) {
        return 5;
    } else if (height > 750000) {
        return 6;
    } else if (height > 375000) {
        return 7;
    } else if (height > 187500) {
        return 8;
    } else if (height > 93750) {
        return 9;
    } else if (height > 46875) {
        return 10;
    } else if (height > 23437.5) {
        return 11;
    } else if (height > 11718.75) {
        return 12;
    } else if (height > 5859.38) {
        return 13;
    } else if (height > 2929.69) {
        return 14;
    } else if (height > 1464.84) {
        return 15;
    } else if (height > 732.42) {
        return 16;
    } else if (height > 366.21) {
        return 17;
    } else {
        return 18;
    }
}*/
/* 获取camera高度  */
function getHeight() {
    if (viewer) {
        var scene = viewer.scene;
        var ellipsoid = scene.globe.ellipsoid;
        var height = ellipsoid.cartesianToCartographic(viewer.camera.position).height;
        return height;
    }
}

/* 获取camera中心点坐标 */
function getCenterPosition() {
    var result = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas
            .clientHeight / 2));
    var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
    var lon = curPosition.longitude * 180 / Math.PI;
    var lat = curPosition.latitude * 180 / Math.PI;
    var height = getHeight();
    return {
        lon: lon,
        lat: lat,
        height: height
    };
}

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);
    }

    // 当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.height = Math.ceil(viewer.camera.positionCartographic.height);
    return extent;
}

$.ajax({
     url: "http://192.168.9.123:8090/BulidLayer",
    type: "post",
    async: true,
    dataType: "json",
    contentType: "application/x-www-form-urlencoded; charset=utf-8",
    success: function (data) {

        $("#loadimg").css("display", "none");
        var features = data.features;
        for (var i = 0; i < features.length; i++) {
            var positionArr = [];
            for (var m = 0; m < features[i].geometry.coordinates[0][0].length; m++) {
                positionArr.push(features[i].geometry.coordinates[0][0][m][0]);
                positionArr.push(features[i].geometry.coordinates[0][0][m][1]);
            }
            //加载建筑物模型
            viewer.entities.add({
                name: 'polygon with holes',
                polygon: {
                    hierarchy: {
                        positions: Cesium.Cartesian3.fromDegreesArray(positionArr)
                    },
                    //根据ld_leq值给楼层上色
                    material: setColor(features[i].properties.leqd),
                    //geojson中建筑物的高度   挤压高度?
                    extrudedHeight: features[i].properties.height,
                    outline: false
                }
            });
          /*  $.ajax({
                url: "http://192.168.9.123:8090/Bulidpng?the_geom=" + aa,
                type: "post",
                async: true,
                dataType: "json",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                success: function (data) {
                    $("#loadimg").css("display", "none");
                    for (var i = 0; i < data.length; i++) {
                        var lon = data[i].location.split(" ")
                        //加载图片实现贴图效果
                        viewer.entities.add({
                            name: 'vertical noisemap',
                            //设置图片的中心点和距离地面的高度,此处设置为建筑物的一半高度即可
                            position: Cesium.Cartesian3.fromDegrees(lon[0], lon[1], data[i].height / 2),
                            box: {
                                //图片的xyz值,分别对应长宽高
                                dimensions: new Cesium.Cartesian3(data[i].leng, 0.05, data[i].height),
                                material: "data:image/png;base64," + data[i].photo
                                // material: "./images/大楼.jpg"
                            },
                            orientation: Cesium.Transforms.headingPitchRollQuaternion(
                                Cesium.Cartesian3.fromDegrees(lon[0], lon[1], 0),
                                new Cesium.HeadingPitchRoll(
                                    //旋转角度
                                    Cesium.Math.toRadians(data[i].angle),
                                    Cesium.Math.toRadians(0),
                                    Cesium.Math.toRadians(0)
                                )
                            )
                        });
                    }

                },
                error: function (data) {
                    console.log(data);
                }
            });*/

        }
        /*$.ajax({
            url: "http://192.168.9.123:9096/geoserver/png/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=png%3Acons_png3&maxFeatures=50&outputFormat=application%2Fjson",
            type: "post",
            async: true,
            dataType: "json",
            contentType: "application/x-www-form-urlencoded; charset=utf-8",
            success: function (data) {
                // console.log(data)
                for (var s = 0; s < data.features.length; s++) {
                    var lon = data.features[s].properties.location.split(" ")
                    //加载图片实现贴图效果
                    viewer.entities.add({
                        name: 'vertical noisemap',
                        //设置图片的中心点和距离地面的高度,此处设置为建筑物的一半高度即可
                        position: Cesium.Cartesian3.fromDegrees(lon[0], lon[1], data.features[s].properties.height / 2),
                        box: {
                            //图片的xyz值,分别对应长宽高
                            dimensions: new Cesium.Cartesian3(data.features[s].properties.leng, 0.05, data.features[s].properties.height),
                            material: "data:image/png;base64,"+data.features[s].properties.photo
                            // material: "./images/大楼.jpg"
                        },
                        orientation: Cesium.Transforms.headingPitchRollQuaternion(
                            Cesium.Cartesian3.fromDegrees(lon[0], lon[1], 0),
                            new Cesium.HeadingPitchRoll(
                                //旋转角度
                                Cesium.Math.toRadians(data.features[s].properties.angle),
                                Cesium.Math.toRadians(0),
                                Cesium.Math.toRadians(0)
                            )
                        )
                    });
                }
            },
            error: function (data) {
                console.log(data)
            }
        })*/
       /* var providerPoint = new Cesium.WebMapServiceImageryProvider({
            url: 'http://192.168.9.123:9096/geoserver/png/wms',
            layers: 'png:cons_png',
            parameters: {
                service : 'WMS',
                format: 'image/png',
                transparent: true
            }
        });
        viewer.imageryLayers.addImageryProvider(providerPoint);*/
        //鼠标事件
        var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        handler.setInputAction(function(wheelment){
           /* var pt1 = new Cesium.Cartesian2(0,0);
            var pt2= new Cesium.Cartesian2(1000,1000);

            var pick1= viewer.scene.globe.pick(viewer.camera.getPickRay(pt1), viewer.scene);
            var pick2= viewer.scene.globe.pick(viewer.camera.getPickRay(pt2), viewer.scene);

//将三维坐标转成地理坐标
            var geoPt1= viewer.scene.globe.ellipsoid.cartesianToCartographic(pick1);
            var geoPt2= viewer.scene.globe.ellipsoid.cartesianToCartographic(pick2);

//地理坐标转换为经纬度坐标
            var point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180];
            var point2=[geoPt2.longitude / Math.PI * 180,geoPt2.latitude / Math.PI * 180];
            // console.log(point1)//屏幕左上角
            // console.log(point2)//屏幕右下角
            var aa = point1[0]+","+point1[1]+","+point2[0]+","+point2[1]
            //加载三维地图时没有缩放层级,只有视角高度,这里的高度从你自己设置的高度开始
            var height=viewer.scene.camera.positionCartographic.height;*/

            getCenterPosition();
            getCurrentExtent();
            // 打印中心点坐标、高度、当前范围坐标
            console.log(getCenterPosition());
            console.log("bounds",getCurrentExtent());
            var aa = getCenterPosition().lon+","+getCenterPosition().lat
            $.ajax({
                url: "http://192.168.9.123:8090/Bulidpng?the_geom=" + aa,
                type: "post",
                async: true,
                dataType: "json",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                success: function (data) {
                    $("#loadimg").css("display", "none");
                    for (var i = 0; i < data.length; i++) {
                        var lon = data[i].location.split(" ")
                        //加载图片实现贴图效果
                        viewer.entities.add({
                            name: 'vertical noisemap',
                            //设置图片的中心点和距离地面的高度,此处设置为建筑物的一半高度即可
                            position: Cesium.Cartesian3.fromDegrees(lon[0], lon[1], data[i].height / 2),
                            box: {
                                //图片的xyz值,分别对应长宽高
                                dimensions: new Cesium.Cartesian3(data[i].leng, 0.05, data[i].height),
                                // material: "data:image/png;base64," + data[i].photo
                                material: "./images/大楼.jpg"
                            },
                            orientation: Cesium.Transforms.headingPitchRollQuaternion(
                                Cesium.Cartesian3.fromDegrees(lon[0], lon[1], 0),
                                new Cesium.HeadingPitchRoll(
                                    //旋转角度
                                    Cesium.Math.toRadians(data[i].angle),
                                    Cesium.Math.toRadians(0),
                                    Cesium.Math.toRadians(0)
                                )
                            )
                        });
                    }

                },
                error: function (data) {
                    console.log(data);
                }
            });



        },Cesium.ScreenSpaceEventType.WHEEL);
    },
    error: function (data) {
        console.log(data);
    }
});



 

你可能感兴趣的:(cesium)