前言
最近有个需求,在地图上手动选择一些点,每次点一个点都会在这个点上做一个标记,标记的图标和文字自定义,文字需要在图标上方,先上效果,图上的紫色图标是在网上找的图片,文字手动传入,文字样式自定义
具体实现
1.接入三维webscene地图
js
scene = new WebScene({
portalItem: {
id: "c4ea6b80419a40d5b8e890b6af37a9c1",
portal: "https://portal.ehjedu.cn/arcgis"
}
});
ags.scene = scene;
view = new SceneView({
container: "viewDiv",
map: scene,
});
view.ui.remove("attribution"); //移除地图下面的esri字符
view.ui.empty("top-left");
2.通过地图的点击事件获取点坐标,在相应的位置上创建point点,每个创建的点需要增加属性,此处取名place属性名,后续用来在地图上展示该文字
js
view.on('click', function (event) {
AddPointText(event.mapPoint.x, event.mapPoint.y, event.mapPoint.z, '测试')
})
// 根据坐标生成点
function AddPointText(x, y, z, type) {
const point = {
type: "point",
hasZ: true,
hasM: false,
x: x,
y: y,
z: z + 12, // 标签整体上移12米,隧道模型顶部距离中心线12米
spatialReference: {
wkid: 3857
}
};
// 创建点,并增加属性palce
const pointGraphic = new Graphic({
geometry: point,
attributes: {
// 这里传入的type值就是后续会在地图上展示的文字
place: type,
}
});
createFeatureText(pointGraphic, '超前钻探')
}
3.创建featureLayer,把新加的点以及图标文字等都加入此featureLayer中,如果要隐藏这些点,直接吧featureLayer图层的visible设置为false即可
js
async function createFeatureText(pointGraphic, id) {
const [LabelClass, FeatureLayer] = await jsapi.load([
"esri/layers/support/LabelClass",
"esri/layers/FeatureLayer"
]);
// 标签图片枚举
const resourceType = {
TSP: tspImage,
顺变电磁: shunbianImage,
超前钻探: chaoqianImage,
取芯钻探: quxinImage,
地质雷达: leidaImage,
里程段: textImg,
加深炮孔: textImg,
设计输入: textImg,
}
// 标签图片symbol自定义
const fwSym = {
type: 'picture-marker',
url: resourceType && resourceType[id],
height: '50px',
width: '50px',
}
// 后面featurelayer图层渲染的Renderer
const fwRenderer = {
type: "unique-value",
field: 'place',
defaultSymbol: fwSym,
uniqueValueInfos: [{
value: 'gaoyan',
symbol: fwSym,
}]
}
// featureLayer图层中文字label的样式设置
const labelClass = new LabelClass({
symbol: {
type: "label-3d",
symbolLayers: [
{
type: "text",
material: {
color: "white"
},
size: 15
}
]
},
labelPlacement: "above-center",
labelExpressionInfo: {
// 文字展示的是我们加入的place属性的内容,如果这个属性没有值,就展示no data
// 所以你想展示什么文字,在创建点的时候给属性palce赋予对应的值即可
expression: 'DefaultValue($feature.place, "no data")'
}
});
const featureLayer = new FeatureLayer({
source: [pointGraphic], //pointGraphic 一系列的点数组,一定得传入数组
renderer: fwRenderer,
id: id,
outFields: ["place"],
maxScale: 0,
minScale: 0,
fields: [{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
}, {
name: "place",
alias: "Place",
type: "string"
}],
objectIdField: "ObjectID",
geometryType: "point",
labelingInfo: [labelClass]
});
scene && scene.add(featureLayer);
}
上面的resourceType是一个图标枚举,如果你想根据不同的类型展示不同的图标及文字,可以扩展resourceType,循环调用createFeatureText,根据传入id展示不同的图片
扩展一下
如果想要在特定的时候展示特定的图层,隐藏其他图层,可以通过控制新增的featureLayer的visible来控制,例如
js
// 控制不同的图层显隐藏
function showVisble(type) {
const arr = ['顺变电磁', '超前钻探', '设计输入', '取芯钻探', '地质雷达', '加深炮孔']
scene && scene.layers && scene.layers.items.forEach(item => {
if (arr.includes(item.id)) {
item.visible = false;
}
if (item.id === type) {
item.visible = true
}
})
}