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相对地面的高度就可以实现,但是距离永远是个问题,在此给一些朋友一些提醒。

目录
相关文章
|
29天前
|
JavaScript 前端开发 API
常用JavaScript 数组 API大全
常用JavaScript 数组 API大全
32 0
|
1月前
|
API
egg.js 24.2写第一个api接口
egg.js 24.2写第一个api接口
71 0
|
4月前
|
敏捷开发 JavaScript 前端开发
❤❤❤【Vue.js最新版】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本❤❤❤
❤❤❤【Vue.js最新版】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本❤❤❤
|
3月前
|
分布式计算 JavaScript 前端开发
JS中数组22种常用API总结,slice、splice、map、reduce、shift、filter、indexOf......
JS中数组22种常用API总结,slice、splice、map、reduce、shift、filter、indexOf......
|
2月前
|
Web App开发 JavaScript NoSQL
深入浅出:构建基于Node.js的RESTful API
在当今快速发展的互联网时代,RESTful API已成为前后端分离架构中不可或缺的一部分。本文旨在为初学者和中级开发人员提供一个清晰、简洁的指南,详细介绍如何使用Node.js构建一个高效、可维护的RESTful API。通过结合实际案例,本文将从API设计理念出发,深入讲解如何利用Express框架及MongoDB数据库实现API的增删改查功能,同时探讨如何通过JWT进行安全认证,确保数据传输的安全性。此外,文章还将简要介绍如何使用Swagger生成API文档,使得API的测试和维护更加便捷。无论你是希望提升现有项目的API设计,还是想从零开始构建一个新项目,本文都将为你提供一条清晰的道路
|
29天前
|
JavaScript 前端开发 API
JavaScript循环遍历常用的7种方法以及常用的数组 API
JavaScript循环遍历常用的7种方法以及常用的数组 API
34 0
|
1月前
|
Web App开发 JavaScript 前端开发
使用Node.js和Express构建RESTful API
使用Node.js和Express构建RESTful API
14 0
|
2月前
|
NoSQL JavaScript 前端开发
深入浅出:使用Node.js和MongoDB构建RESTful API
在当今的软件开发领域,构建高效、可扩展的Web服务已成为开发者的重要任务之一。本文将引导读者通过现代JavaScript环境——Node.js,搭配流行的NoSQL数据库MongoDB,一步步构建一个RESTful API。不同于常规的摘要,我们将采用故事化的方式,通过一个虚构的应用“BookFinder”的开发旅程,带领读者理解API设计、数据库交互及安全性考量等关键知识点。无论你是前端工程师希望深化后端知识,还是后端新手寻求实践机会,本文都将提供你所需的指南和启示。
|
3月前
|
Web App开发 Rust JavaScript
Rust 笔记:WebAssembly 的 JavaScript API
Rust 笔记:WebAssembly 的 JavaScript API
93 0
|
3月前
|
JavaScript 前端开发 程序员
Js中一些数组常用API总结
Js中一些数组常用API总结