需要了解的两个案例:
geocode沙盒案例:Cesium Sandcastle
cluster沙盒案例:Cesium Sandcastle
1.使用天地图替换掉cesium自带的geocode,并实现聚合
申请天地图浏览器端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