ArcGIS API for JavaScript 标注错位问题解决思路

简介: 显示标注和符号的两个方案。一个FeatureLayer的,标注一直在图标的上方的固定位置,不会随距离的远近而出现错误,还有标注自动避让,实现不了换行,水利中墒情的三级标注的显示;另一个是基于GraphicsLayer的,这个的标注就是随距离拉近,符号和标注之间的距离增大,但是可以实现伪换行(多个标注),造成的问题就是距离一远,多个标注也会重叠.

项目需求:完成对点的符号化显示,并将点的某些信息显示在点符号的旁边。

设计

调研开始,展示数据前端一般用GraphicsLayer,再结合Graphic,PictureMarkerSymbol与TextSymbol就可以完成此工作。直接上代码

jidianjing_graphicsLayer: null,
jidianjing_text_featureLayer: null,
...
this.graphicsLayer = new GraphicsLayer({
    id: "graphicsLayer",
    elevationInfo: {
      mode: "relative-to-ground",
      offset: 3
    }
});
...
view.map.add(this.graphicsLayer);
...

let jidianjing_graphics = [];
                // 处理Graphics
                $.each(result, function (i, item) {
                    item.widgetModule = 'jidianjingWidgetModule_click';
                    var stcd = item.STCD;
                    var stnm = item.STNM;

                    let tempPoint = new Point({
                        type: "point",
                        x: item.LGTD,
                        y: item.LTTD
                    });
                    let normalsymbol = {
                        type: "picture-marker",
                        url: 'img/menu/081.png',
                        width: "18px",
                        height: "18px"
                    };
                    if (!StringUtil.isNull(item.WARN_NAME)) {
                        normalsymbol = {
                            type: "picture-marker",
                            url: 'img/menu/083.png',
                            width: "28px",
                            height: "28px"
                        };
                    } else if (!StringUtil.isNull(item.LL)) {
                        normalsymbol = {
                            type: "picture-marker",
                            url: 'img/menu/082.png',
                            width: "28px",
                            height: "28px"
                        };
                    }

                    let tempPop = new PopupTemplate({
                        title: '机电井:' + stnm,
                        content: _self.setjidianjingContentInfo
                    });

                    let tempGraphic = new Graphic({
                        geometry: tempPoint,
                        attributes: item,
                        symbol: normalsymbol,
                        popupTemplate: tempPop
                    });

                    let textGraphic = new Graphic({
                        geometry: tempPoint,
                        symbol: new TextSymbol({
                            color: "#FFF",
                            backgroundColor: new Color('red'),
                            borderLineColor: new Color("#fff"),
                            borderLineSize: 2,
                            haloColor: "black",
                            haloSize: "1px",
                            text: '水位:12 水温:11',
                            font: {
                                size: 8,
                                family: "sans-serif"
                            }
                        })
                    });
                _self.jidianjing_graphicsLayer.add(tempGraphic);
                _self.jidianjing_text_graphicsLayer.add(textGraphic);
...

效果

image
image

说明
gif图太大,aliyun拒绝了我的上传,所以只能用文字描述;在小比例尺下,符号标注和文字标注之间的距离较小,看着效果还可以,但是有会出现标注覆盖文字或者文字覆盖标注;随着比例尺的放大,符号和标注之间的距离会增大,如第二张图所示。但是拿给项目经理看的时候,不要这种效果,距离和标注与符号之间的距离不能变。so...改改改

新思路-构造FeatureLayer

查看了官网好多例子,发现只有FeatureLayer的标注和符号之间的距离是边的,因为我们拿到的数据是点数据,所以我们可以构造组成FeatureLayer的source,其实就对应ags里的Graphics;还有一个标注LabelClass,这个类就是用来显示标注的。so...又开干了。

jidianjing_featureLayer: null,
...
let tempGraphics = [];
// 处理Graphics
$.each(result, function (i, item) {
    item.widgetModule = 'jidianjingWidgetModule_click';
    var stcd = item.STCD;
    var stnm = item.STNM;

    let tempPoint = new Point({
        type: "point",
        x: item.LGTD,
        y: item.LTTD
    });
    let normalsymbol = {
        type: "picture-marker",
        url: 'img/menu/081.png',
        width: "18px",
        height: "18px"
    };
    if (!StringUtil.isNull(item.WARN_NAME)) {
        normalsymbol = {
            type: "picture-marker",
            url: 'img/menu/083.png',
            width: "28px",
            height: "28px"
        };
    } else if (!StringUtil.isNull(item.LL)) {
        normalsymbol = {
            type: "picture-marker",
            url: 'img/menu/082.png',
            width: "28px",
            height: "28px"
        };
    }

    let tempPop = new PopupTemplate({
        title: '机电井:' + stnm,
        content: _self.setjidianjingContentInfo
    });

    let tempGraphic = new Graphic({
        geometry: tempPoint,
        attributes: item,
        symbol: normalsymbol,
        popupTemplate: tempPop
    });

    let textGraphic = new Graphic({
        geometry: tempPoint,
        symbol: new TextSymbol({
            color: "#FFF",
            backgroundColor: new Color('red'),
            borderLineColor: new Color("#fff"),
            borderLineSize: 2,
            haloColor: "black",
            haloSize: "1px",
            text: '水位:12 水温:11',
            font: {
                size: 8,
                family: "sans-serif"
            }
        })
    });
    tempGraphics.push(tempGraphic);
...
// popup
let tempPop = new PopupTemplate({
    title: '机电井:' + '{STNM}',
    content: _self.setjidianjingContentInfo
});
// 标注
var labelClass = new LabelClass({
    minScale: 20000,
    symbol: {
        type: "label-3d",
        symbolLayers: [{
            type: "text", 
            material: {
                color: "white"
            },
            size: 10,
            halo: {
                color: [0, 0, 0, 0.8], 
                size: 0.5
            }
        }],
        verticalOffset:{
            minWorldLength: 20,
        }
    },
    labelPlacement: "above-center",
    labelExpression: "水位:[STTP], 水温:[STCD]"
    // labelExpressionInfo: {
    //   expression: "$feature.STNM"
    // }
});
// 构建feetureLayer并实现标注
this.jidianjing_text_featureLayer = new FeatureLayer({
    id: 'jidianjing_featureLayer',
    fields: [{
        name: "STCD",
        alias: "STCD",
        type: "oid"
    }, {
        name: "LGTD",
        alias: "LGTD",
        type: "string"
    }, {
        name: "LTTD",
        alias: "LTTD",
        type: "string"
    }, {
        name: "STCD",
        alias: "STCD",
        type: "string"
    }, {
        name: "STNM",
        alias: "STNM",
        type: "string"
    }, {
        name: "STTP",
        alias: "STTP",
        type: "string"
    }, {
        name: "widgetModule",
        alias: "widgetModule",
        type: "string"
    }],
    objectIdField: "STCD",
    geometryType: "point",
    spatialReference: {
        wkid: 4326
    },
    source: tempGraphics, //  an array of graphics with geometry and attributes
    // popupTemplate and symbol are not required in each graphic
    // since those are handled with the popupTemplate and
    // renderer properties of the layer
    popupTemplate: tempPop,
    // renderer: iconSymbolRenderer,
    maxScale: 0,
    minScale: 0,
    labelsVisible: true,
    labelingInfo: [labelClass]
});
view.map.add(this.jidianjing_text_featureLayer);

效果

image

image
说明

可以在上面两张图中看到,标注和符号的位置一直都是固定的,并没有随着距离的变化而变化;这时候拿给项目经理,就这个效果还算满意。

总结

符号和标注之间的距离在GraphicsLayer和FeatureLayer中的表现是不一样的,所以要根据合适的场景进行选择取舍。另外,GraphicsLayer和FeatureLayer标注换行不能实现,对GraphicsLayer可以采用加多个TextSymbol的GraphicsLayer,设置GraphicsLayer相对地面的高度就可以实现,但是距离永远是个问题,在此给一些朋友一些提醒。

目录
相关文章
|
7月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
12月前
|
JavaScript 前端开发 API
Vue.js 3:探索组合式API带来的新变革
Vue.js 3:探索组合式API带来的新变革
363 84
|
8月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
12月前
|
JSON 缓存 JavaScript
深入浅出:使用Node.js构建RESTful API
在这个数字时代,API已成为软件开发的基石之一。本文旨在引导初学者通过Node.js和Express框架快速搭建一个功能完备的RESTful API。我们将从零开始,逐步深入,不仅涉及代码编写,还包括设计原则、最佳实践及调试技巧。无论你是初探后端开发,还是希望扩展你的技术栈,这篇文章都将是你的理想指南。
|
10月前
|
JavaScript 前端开发 安全
盘点原生JS中目前最没用的几个功能API
在JavaScript的发展历程中,许多功能与API曾风光无限,但随着技术进步和语言演化,部分功能逐渐被淘汰或被更高效的替代方案取代。例如,`with`语句使代码作用域复杂、可读性差;`void`操作符功能冗余且影响可读性;`eval`函数存在严重安全风险和性能问题;`unescape`和`escape`函数已被`decodeURIComponent`和`encodeURIComponent`取代;`arguments`对象则被ES6的剩余参数语法替代。这些变化体现了JavaScript不断优化的趋势,开发者应紧跟技术步伐,学习新技能,适应新技术环境。
188 10
|
11月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
249 12
|
12月前
|
JavaScript 前端开发 API
Vue.js 3:深入探索组合式API的实践与应用
Vue.js 3:深入探索组合式API的实践与应用
|
12月前
|
JavaScript NoSQL API
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发如同一座灯塔,指引着数据的海洋。本文将带你航行在Node.js的海域,探索如何从一张白纸到完成一个功能完备的RESTful API。我们将一起学习如何搭建开发环境、设计API结构、处理数据请求与响应,以及实现数据库交互。准备好了吗?启航吧!
|
12月前
|
JSON JavaScript 前端开发
使用JavaScript和Node.js构建简单的RESTful API
使用JavaScript和Node.js构建简单的RESTful API
|
12月前
|
JavaScript 前端开发 API
Vue.js 3中的Composition API:提升你的组件开发体验
Vue.js 3中的Composition API:提升你的组件开发体验
361 1

热门文章

最新文章