cesium控件:使用天地图替换掉cesium自带的geocode,并实现聚合

 

 

需要了解的两个案例:

geocode沙盒案例:Cesium Sandcastle

cluster沙盒案例:Cesium Sandcastle

1.使用天地图替换掉cesium自带的geocode,并实现聚合

天地图API

申请天地图浏览器端key

 

2.关键词搜索

关键词搜索的响应(resultType)有五种类型,目前只碰到三种

resultType=1

resultType=2

resultType=3

代码:

function TDTGeocoder(){}
TDTGeocoder.prototype.geocode=function(input){
    // 地理编码
    // let endpoint='https://api.tianditu.gov.cn/geocoder'
    // let resource = new Cesium.Resource({
    //  url: endpoint,
    //  queryParameters: {
    //      "format": "json",
    //      "ds":JSON.stringify({"keyWord":input}),//[object object]转字符串
    //      "tk":"6c981203185b9bc35cbbd42b74e7727d"
    //  },
    // })
    // return resource.fetchJson().then(function (results) {
    //  console.log(results)
    //  let location=results.location//获取经纬度
    //  let lon=location.lon
    //  let lat=location.lat
    //  return {
    //      displayName: input,
    //      // 没有考虑半球情况
    //      destination: Cesium.Rectangle.fromDegrees(
    //          lon+0.05,//west
    //          lat-0.05,//south
    //          lon+0.05,//east
    //          lat+0.05//north
    //      ),
    //  };
    // });


    // 关键词搜索
    let Cesium=window.Cesium
    let endpoint2='https://api.tianditu.gov.cn/search'
    let postStr={
        keyWord:input,
        level:10,
        mapBound:"-180,-90,180,90",//左下,右上
        queryType:1,
        count:50,
        start:0
    }
    let resource2 = new Cesium.Resource({
        url: endpoint2,
        queryParameters: {
            "format": "json",
            "postStr":JSON.stringify(postStr),//[object object]转字符串
            "tk":"6c981203185b9bc35cbbd42b74e7727d"
        },
    })
    return resource2.fetchJson().then(function (results) {
        console.log(results)
        // 天地图地名搜索有5种返回类型
        let resultType=results.resultType
        if(resultType==1){
            let pois=results.pois
            if(!pois){
                return
            }
            return pois.map((poi)=>{
                let lonlat=poi.lonlat
                let lon=Number(lonlat.split(" ")[0])
                let lat=Number(lonlat.split(" ")[1])
                return{
                    displayName:poi.name,
                    destination:Cesium.Rectangle.fromDegrees(
                        lon+0.05,//west
                        lat-0.05,//south
                        lon+0.05,//east
                        lat+0.05//north
                    )
                }
            })
        }else if(resultType==2){//统计
            let statistics=results.statistics
            let priorityCitys=statistics.priorityCitys
            if(!priorityCitys){
                return
            }
            return priorityCitys.map((city)=>{
                let lon=Number(city.lon)
                let lat=Number(city.lat)
                return{
                    displayName:input+","+city.name,
                    destination:Cesium.Rectangle.fromDegrees(
                        lon+0.05,//west
                        lat-0.05,//south
                        lon+0.05,//east
                        lat+0.05//north
                    )
                }
            })
        }else if(resultType==3){//行政区
            let area=results.area
            if(!area){
                return
            }
            let bound=area.bound
            return{
                displayName:area.name,
                destination:Cesium.Rectangle.fromDegrees(
                    bound.split(",")[0],
                    bound.split(",")[1],
                    bound.split(",")[2],
                    bound.split(",")[3],
                )
            }
        }else{//4和5没有测试到
            return
        }
        
    })
}

3.POI点+聚合的实现

关键步骤:

将坐标信息转换为DataSource

查阅文档,可以法线CustomDataSource类可以加载一组entities作为数据源

代码:

 let dataSource = new Cesium.CustomDataSource()
    // console.log(collection)
    collection.map((item)=>{
        dataSource.entities.add({
            position:Cesium.Cartesian3.fromDegrees(item.lon,item.lat),
            // billboard:{
            //     image:'image/location.png',
            // },
            point:{
                color:new Cesium.Color(93/255,200/255,205/255,1.0),
                outlineWidth:3,
                outlineColor:Cesium.Color.WHITE,
                pixelSize:10,
                // heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND
                heightReference:Cesium.CLAMP_TO_GROUND,
                disableDepthTestDistance:15000000
            },
            label:{
                text:item.name,
                font:'12px',
                fillColor:new Cesium.Color(255/255,118/255,0/255,1.0),
                outlineWidth:2,
                outlineColor:new Cesium.Color(255/255,180/255,115/255,1.0),
                showBackground:true,
                backgroundColor:new Cesium.Color(0.2,0.2,0.2,0.8),
                backgroundPadding:new Cesium.Cartesian2(5,10),
                verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
                horizontalOrigin :Cesium.HorizontalOrigin.CENTER
            }
        })
    })
    viewer.dataSources.add(dataSource)

4.完整代码

新建一个js文件

function TDTGeocoder(){}
TDTGeocoder.prototype.geocode=function(input){
    // 地理编码
    // let endpoint='https://api.tianditu.gov.cn/geocoder'
    // let resource = new Cesium.Resource({
    // 	url: endpoint,
    // 	queryParameters: {
    // 		"format": "json",
    // 		"ds":JSON.stringify({"keyWord":input}),//[object object]转字符串
    // 		"tk":"6c981203185b9bc35cbbd42b74e7727d"
    // 	},
    // })
    // return resource.fetchJson().then(function (results) {
    // 	console.log(results)
    // 	let location=results.location//获取经纬度
    // 	let lon=location.lon
    // 	let lat=location.lat
    // 	return {
    // 		displayName: input,
    // 		// 没有考虑半球情况
    // 		destination: Cesium.Rectangle.fromDegrees(
    // 			lon+0.05,//west
    // 			lat-0.05,//south
    // 			lon+0.05,//east
    // 			lat+0.05//north
    // 		),
    // 	};
    // });

    // 关键词搜索
    let Cesium=window.Cesium
    let endpoint2='https://api.tianditu.gov.cn/search'
    let postStr={
        keyWord:input,
        level:11,
        mapBound:"-180,-90,180,90",//左下,右上
        queryType:1,
        count:50,
        start:0
    }
    let resource2 = new Cesium.Resource({
        url: endpoint2,
        queryParameters: {
            "format": "json",
            "postStr":JSON.stringify(postStr),//[object object]转字符串
            "tk":"6c981203185b9bc35cbbd42b74e7727d"
        },
    })
    return resource2.fetchJson().then(function (results) {
        console.log(results)
        // 天地图地名搜索有5种返回类型
        let resultType=results.resultType
        if(resultType==1){
            let pois=results.pois
            if(!pois){
                return
            }
            let collection=[]
            pois.map((poi)=>{
                let lonlat=poi.lonlat
                let lon=Number(lonlat.split(" ")[0])
                let lat=Number(lonlat.split(" ")[1])
                collection.push({lon:lon,lat:lat,name:poi.name})
            })
            setPoint(collection)
            return pois.map((poi)=>{
                let lonlat=poi.lonlat
                let lon=Number(lonlat.split(" ")[0])
                let lat=Number(lonlat.split(" ")[1])
                return{
                    displayName:poi.name,
                    destination:Cesium.Rectangle.fromDegrees(
                        lon+0.05,//west
                        lat-0.05,//south
                        lon+0.05,//east
                        lat+0.05//north
                    )
                }
            })
        }else if(resultType==2){//统计
            let statistics=results.statistics
            let priorityCitys=statistics.priorityCitys
            if(!priorityCitys){
                return
            }
            let collection=[]
            priorityCitys.map((city)=>{
                let lon=Number(city.lon)
                let lat=Number(city.lat)
                collection.push({lon:lon,lat:lat,name:input+","+city.name})
            })
            setPoint(collection)
            return priorityCitys.map((city)=>{
                let lon=Number(city.lon)
                let lat=Number(city.lat)
                return{
                    displayName:input+","+city.name,
                    destination:Cesium.Rectangle.fromDegrees(
                        lon+0.05,//west
                        lat-0.05,//south
                        lon+0.05,//east
                        lat+0.05//north
                    )
                }
            })
        }else if(resultType==3){//行政区
            let area=results.area
            if(!area){
                return
            }
            let bound=area.bound
            let lonlat=area.lonlat
            let lon=Number(lonlat.split(",")[0])
            let lat=Number(lonlat.split(",")[1])
            let collection=[]
            collection.push({lon:lon,lat:lat,name:area.name})
            setPoint(collection)
            return{
                displayName:area.name,
                destination:Cesium.Rectangle.fromDegrees(
                    bound.split(",")[0],
                    bound.split(",")[1],
                    bound.split(",")[2],
                    bound.split(",")[3],
                )
            }
        }else{//4和5没有测试到
            return
        }
        
    })
}
let lastDataSource
function setPoint(collection){
    let Cesium=window.Cesium
    let viewer=window.viewer
    if(lastDataSource){
        viewer.dataSources.removeAll()
        lastDataSource=undefined
    }
    //CustomDataDource可用于手动管理一组实体的 DataSource 实现。
    let dataSource = new Cesium.CustomDataSource()
    // console.log(collection)
    collection.map((item)=>{
        dataSource.entities.add({
            position:Cesium.Cartesian3.fromDegrees(item.lon,item.lat),
            // billboard:{
            //     image:'image/location.png',
            // },
            point:{
                color:new Cesium.Color(93/255,200/255,205/255,1.0),
                outlineWidth:3,
                outlineColor:Cesium.Color.WHITE,
                pixelSize:10,
                // heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND
                heightReference:Cesium.CLAMP_TO_GROUND,
                disableDepthTestDistance:15000000
            },
            label:{
                text:item.name,
                font:'12px',
                fillColor:new Cesium.Color(255/255,118/255,0/255,1.0),
                outlineWidth:2,
                outlineColor:new Cesium.Color(255/255,180/255,115/255,1.0),
                showBackground:true,
                backgroundColor:new Cesium.Color(0.2,0.2,0.2,0.8),
                backgroundPadding:new Cesium.Cartesian2(5,10),
                verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
                horizontalOrigin :Cesium.HorizontalOrigin.CENTER
            }
        })
    })
    viewer.dataSources.add(dataSource)
    dataSource.clustering.enabled=true//开启聚合
    dataSource.clustering.pixelRange=10
    dataSource.clustering.minimumClusterSize=2
    lastDataSource=dataSource
    let pinBuilder=new Cesium.PinBuilder()//自定义聚合图标
    // fromText(text,color,size)
    let pin50 = pinBuilder.fromText("50+", new Cesium.Color(93/255,200/255,205/255,1.0), 48).toDataURL()
    let pin40=pinBuilder.fromText("40+",new Cesium.Color(93/255,200/255,205/255,1.0), 48).toDataURL()
    let pin30 = pinBuilder.fromText("30+", new Cesium.Color(93/255,200/255,205/255,1.0), 48).toDataURL();
    let pin20 = pinBuilder.fromText("20+", new Cesium.Color(93/255,200/255,205/255,1.0), 48).toDataURL();
    let pin10 = pinBuilder.fromText("10+", new Cesium.Color(93/255,200/255,205/255,1.0), 48).toDataURL();
    // 聚合个数小于10的pin
    let singleDigitPins = new Array(8);
    for (let i = 0; i < singleDigitPins.length; ++i) {
        singleDigitPins[i] = pinBuilder
        .fromText(`${i + 2}`, new Cesium.Color(93/255,200/255,205/255,1.0), 48)
        .toDataURL();
    }
    dataSource.clustering.clusterEvent.addEventListener((clusteredEntities,cluster)=>{
        // clusteredEntities聚合点处的entity数组
        // cluster 包含了该聚合点的billboard,label和point样式
        cluster.label.show = false;
        cluster.billboard.show = true;
        cluster.billboard.id = cluster.label.id;
        cluster.billboard.verticalOrigin =Cesium.VerticalOrigin.BOTTOM;
        if (clusteredEntities.length >= 50) {
            cluster.billboard.image = pin50;
        } else if (clusteredEntities.length >= 40) {
            cluster.billboard.image = pin40;
        } else if (clusteredEntities.length >= 30) {
            cluster.billboard.image = pin30;
        } else if (clusteredEntities.length >= 20) {
            cluster.billboard.image = pin20;
        } else if (clusteredEntities.length >= 10) {
            cluster.billboard.image = pin10;
        } else {
            cluster.billboard.image =singleDigitPins[clusteredEntities.length - 2];
        }
    })
}
export default TDTGeocoder

new TDTGeocoder()替换掉viewer的默认geocode

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值