arcgis.js中3d场景下,显示图片,并且文字位置在图片上方

博客介绍了如何在ArcGIS.js的3D场景下显示图片和文字,包括解决图片symbol和文字symbol定位问题,以及处理不同字体显示长度的差异。通过自定义函数计算字符串的显示长度,实现文字的对齐和换行。同时,展示了如何让文字和图片随点移动,展示追踪信息。
摘要由CSDN通过智能技术生成

arcgis.js中3d场景下,显示图片,并且文字位置在图片上方

在3D地图中显示自己的图片,并且在图片上显示文字。可以跟随点移动,追踪物体的信息显示。如果有什么问题,欢迎评论和指正
先看效果:
效果图

遇到的问题:
1.arcgis.js的3D地图中图片symbol和文字symbol的xoffset,yoffset是不管用的
2.每种字体的显示长度不同,显示长度与字符串字节数不同。
字符串长度是中文字或者中文符号2个字节长度,英语的都是1个字节长度。
字体显示长度与字符串字节长度不完全一样,有些字符可能是1.5个显示长度,这就需要你具体使用的字体去做改变了。
这个显示长度就像我们编辑word文档一样,在一行的最后位置写一个中文,光标就到下一行了,也可以写二个英语,光标也会到下一行。但有时还可以写三个英文字符(iii),光标才跳到下一行。这是我自己理解的字体显示长度。
3.文字永远是以点的中心对齐,我们要做到文字右对齐或者左对齐,我们就需要使用空格来使文字对齐,文字要在点的上面就在文字后面加\n(换行符),文字要在点的下方就在文字前面加\n,加多少个这就需要具体问题具体分析了。

计算文字显示长度方法和文字左对齐,在点的上。

//得到字体的显示长度,不是字节长度
        //不同的字体(Microsoft YaHei、黑体、宋体),显示长度可能不同
        function strlen(str) {
            var len = 0;
            var numChinese = 0;
            for (var i = 0; i < str.length; i++) {
                var c = str.charCodeAt(i);
                if (c != 105 && ((c >= 48 && c <= 57) || (c >= 97 && c <= 122))) { // 数字,小写字母,i是一个长度单位 47=/
                    len += 2
                } else if (c != 73 && (c == 65306 || (c >= 65 && c <= 90) || c == 35282)) { //中文:冒号,"角"字c == 35282,大写英文字母,I是一个长度单位
                    len += 3
                } else if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f) || c == 176) {
                    //单字节加1 ,176 = °符号,也是一个长度单位
                    // if (c != 47) {
                    len++;
                    // }
                } else { //中文4个显示长度单位
                    len += 4;
                    numChinese++;
                }
            }
            if (numChinese == 3) {
                return len - numChinese + 3;
            } else if (numChinese == 4) {
                return len - numChinese + 3;
            }
            return len;
        }

        //根据自己的图片来调整换行的大小和空格的多少
        function showDataFormatting(data) {
            var dataStr = "";
            //93字节 中文是2个字节  14行
            var totalStrLength = 80;
            var totalStrRow = 17;
            for (let i = 0; i < data.length; i++) {
                let current_data = data[i];
                let currentLength = strlen(current_data);
                let diffLength = totalStrLength - currentLength;
                // let diffLength = totalStrLength - current_data.length;
                while (diffLength) {
                    current_data += " ";
                    diffLength--;
                }
                console.log("current_data:" + current_data + "|");
                dataStr += current_data + "\n";
            }
            let diffRow = totalStrRow - data.length;
            while (diffRow) {
                dataStr += "\n";
                diffRow--;
            }
            return dataStr;
        }

全部代码:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>3D 地图,图片和文字的显示</title>
    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
    </style>
    <!-- 导入arcgis -->
    <link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.22/"></script>
</head>

<body>
    <div id="viewDiv"></div>

    <script>
        console.log("此文件可以介绍在3D地图中点的上面添加图片和文字");

        //得到字体的显示长度,不是字节长度
        //不同的字体(Microsoft YaHei、黑体、宋体),显示长度可能不同
        function strlen(str) {
            var len = 0;
            var numChinese = 0;
            for (var i = 0; i < str.length; i++) {
                var c = str.charCodeAt(i);
                if (c != 105 && ((c >= 48 && c <= 57) || (c >= 97 && c <= 122))) { // 数字,小写字母,i是一个长度单位 47=/
                    len += 2
                } else if (c != 73 && (c == 65306 || (c >= 65 && c <= 90) || c == 35282)) { //中文:冒号,"角"字c == 35282,大写英文字母,I是一个长度单位
                    len += 3
                } else if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f) || c == 176) {
                    //单字节加1 ,176 = °符号,也是一个长度单位
                    // if (c != 47) {
                    len++;
                    // }
                } else { //中文4个显示长度单位
                    len += 4;
                    numChinese++;
                }
            }
            if (numChinese == 3) {
                return len - numChinese + 3;
            } else if (numChinese == 4) {
                return len - numChinese + 3;
            }
            return len;
        }

        //根据自己的图片来调整换行的大小和空格的多少
        function showDataFormatting(data) {
            var dataStr = "";
            //93字节 中文是2个字节  14行
            var totalStrLength = 80;
            var totalStrRow = 17;
            for (let i = 0; i < data.length; i++) {
                let current_data = data[i];
                let currentLength = strlen(current_data);
                let diffLength = totalStrLength - currentLength;
                // let diffLength = totalStrLength - current_data.length;
                while (diffLength) {
                    current_data += " ";
                    diffLength--;
                }
                console.log("current_data:" + current_data + "|");
                dataStr += current_data + "\n";
            }
            let diffRow = totalStrRow - data.length;
            while (diffRow) {
                dataStr += "\n";
                diffRow--;
            }
            return dataStr;
        }
        //使用arcgis.js
        require([
                "esri/Map",
                "esri/views/SceneView",
                "esri/views/MapView",
                "esri/layers/FeatureLayer",
                "esri/Graphic",
                "esri/layers/GraphicsLayer",
                "esri/symbols/TextSymbol"
            ],
            (Map, SceneView, MapView, FeatureLayer, Graphic, GraphicsLayer, TextSymbol) => {
                let textsss = new TextSymbol();
                console.log("textsss", textsss)

                let centerPoint = [116, 39]; //大概是北京的经纬度

                //底层
                const map = new Map({
                    basemap: "osm" //查看地图的模式,官方还有其他的模式
                });
                //3D容器
                const view = new SceneView({
                    container: "viewDiv", //与html元素绑定
                    map: map, //设置底层
                    zoom: 15, //初始地图距离大小
                    center: centerPoint //中心点(可以取小数) ,这里设置的北京
                });

                let graphicLayer = new GraphicsLayer({
                    maxScale: 5,
                    minScale: 1000000
                });
                map.add(graphicLayer);
                // view.layer.add(graphicLayer);

                //显示在图中的点
                let point = {
                    type: "point",
                    longitude: centerPoint[0],
                    latitude: centerPoint[1],
                    hasZ: true, //开启Z轴
                    hasM: true, //以米为单位
                    z: 200 //
                }
                let pointSymbol = {
                    type: "simple-marker",
                    style: "circle",
                    color: [255, 0, 0], //[255,255,255] or "blue"
                    size: "12px",
                    outline: { //外边框
                        color: [255, 255, 255],
                        width: 1
                    }
                }
                let pointPopupTemplate = {
                    title: "title",
                    content: "hhhhh"
                };

                let pointGraphic = new Graphic({
                    geometry: point, //点的位置
                    symbol: pointSymbol, //点的图形
                    popupTemplate: pointPopupTemplate //弹窗
                });

                graphicLayer.add(pointGraphic);



                //显示在图中的文字
                let textPoint = {
                    type: "point",
                    x: centerPoint[0],
                    y: centerPoint[1],
                    hasZ: true, //开启Z轴
                    hasM: true, //以米为单位
                    z: 200 //
                }

                let textStr = showDataFormatting(["ID:" + 1,
                    "高度:" + 999 + "m",
                    "距离:" + 999 + "m",
                    "速度:" + 999 + "m/s",
                    "经/纬度:" + 999 + "°/" + 999 + "°",
                    "方位角:" + 99 + "°",
                    "水平仪测角:" + 99 + "°"
                ]);

                //Microsoft YaHei:大小写英文 2,i I 1, 中文 3,° 1,数字2,m M N 3,. 1,/ 1,
                //黑体:
                //Microsoft YaHei: 
                //特殊 f<2 g>2  f+g=4 
                //1:i I
                //2:a 0123456789 abc e
                //3:D d A
                //4:


                let textSymbol = {
                    type: "text",
                    color: "black",
                    haloSize: "1px",
                    text: textStr,
                    // xoffset: 100,
                    // yoffset: 100,
                    font: {
                        size: 14,
                        family: "Microsoft YaHei", //Microsoft YaHei 黑体
                        // weight: "bold"
                    }
                }

                let textGraphic = new Graphic({
                    geometry: textPoint, //文字的位置
                    symbol: textSymbol //文字
                });


                let pictureSymbol2 = {
                    type: "point-3d",
                    symbolLayers: [{
                        type: "icon",
                        size: 200,
                        anchor: "bottom-right",
                        // xoffset: 100,
                        // yoffset: 100,
                        resource: {
                            href: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.51yuansu.com%2Fpic3%2Fcover%2F03%2F11%2F29%2F5b494b3dd06fe_610.jpg&refer=http%3A%2F%2Fpic.51yuansu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1643867115&t=326b45732bb38c73c16b8febc2b56029"
                        },
                        material: {
                            color: [255, 255, 255, 1]
                        }
                    }]
                };
                let pictureGraphic = new Graphic({
                    geometry: textPoint, //图片的位置
                    symbol: pictureSymbol2 //图片
                });
                console.log("pictureSymbol2", pictureSymbol2)
                console.log("textSymbol", textSymbol)


                //添加到容器
                graphicLayer.add(textGraphic);
                graphicLayer.add(pictureGraphic);

                console.log("view", view)
                console.log("view.graphics.items", view.graphics.items)
            })
    </script>
</body>

</html>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值