arcgis实现在地图上自定义图标和3d文字展示

前言

最近有个需求,在地图上手动选择一些点,每次点一个点都会在这个点上做一个标记,标记的图标和文字自定义,文字需要在图标上方,先上效果,图上的紫色图标是在网上找的图片,文字手动传入,文字样式自定义

具体实现

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
        }
    })
}
相关推荐
neter.asia3 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫4 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
光影少年23 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_24 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891126 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾28 分钟前
前端基础-html-注册界面
前端·算法·html
Dragon Wu30 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym35 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫36 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫40 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js