zoukankan      html  css  js  c++  java
  • openlayers在底图上添加静态icon

    越学习openlayer你会发现openlayer是真的很强大,今天记录一下学习的成果,需求是做那种室内的CAD的场景然后里面展示人员icon并且实时展示人员的位置信息,以及点击弹出对应人员的一些位置信息,姓名,电话等等,这个在工业互联网中是很常见的,接下来就开始操作了

    由于我是在vue+ts中写的,所以下面的代码片段可能是基于vue来写的

    第一步,我们需要建立一个底图,这个底图可以是谷歌地图也可以是我们拿到的cad渲染出来的静态底图

    let extent = [pointer.x, pointer.y, pointer2.x, pointer2.y]; // 图片图层四至
    // pointer pointer2分别是静态图片左下角和右上角的基于基站的坐标
            console.log(extent)
            let projection = new olprojProjection({
                code: "xkcd-image",
                units: "pixels",
                extent: extent
            });
    this.map = new olMap({
                target: DOM接点的ID,
                layers: [
                    new ollayerImage({
                        source: new olsourceImageStatic({
                            url: 静态图片的地址, // 静态地图,如果是本地的,在vuecli3中将图片放在public里
                            projection: projection,
                            imageExtent: extent // 映射到地图的范围
                        })
                    })
                ],
                view: new olView({
                    center: getCenter(extent),
                    projection: projection,
                    zoom: 2.2,
                    minZoom: 1,
                    maxZoom: 12
                }),
                // 加载控件到地图容器中
                // 加载鼠标位置控件
                controls: defaults().extend([mousePositionControl])
            });

    第二步,底图建立好之后,接下来绘制人员图标,我这边和后台的数据对接方式是ws,就是后台实时推送人员的位置信息,前端渲染,这个时候很刚入学者会每个icon建立一个layer,其实不是这样的,你可以先建立一个定位图层layer,一个layer一个source就可以了,

    新建定位图层

     // 创建定位图层
            this.positionLayer = new ollayerVector({
                source: new olsourceVector(),
                style: new olstyleStyle()
            })
            this.map.addLayer(this.positionLayer)

    然后拿到数据之后,我这边获取的数据接口是一个list,也就是一个数组,需要for循环来添加icon

    list.forEach((value: any, index: number) => {
                let time = new Date().getTime()
                if (!that.personListCache.has(value.id)) {
                    // 绘制人员定位信息
                    let personS = that.createPerson(value)
                    console.log(value)
                    console.log(personS)
                    that.personListCache.set(value.id, { spriteObj: personS, lastModified: time })
                } else {
                    let personIn = that.personListCache.get(value.id)
                    // console.log(personIn.spriteObj.getGeometry().getCoordinates())
                    // var geometry = new olgeomPoint([value.x, value.y])
                    // personIn.spriteObj.setGeometry(geometry)
                    personIn.lastModified = time
                    if (personIn) {
                        personIn.oldObj = {
                            x: personIn.spriteObj.getGeometry().getCoordinates()[0],
                            y: personIn.spriteObj.getGeometry().getCoordinates()[1]
                        }
                        personIn.newObj = {
                            x: value.x,
                            y: value.y
                        }
                        if (personIn.oldObj.x === personIn.newObj.x && personIn.oldObj.y === personIn.newObj.y) {
                            // that.updataPersonPos(personIn)
                        } else {
                            that.updataPersonPos(personIn)
                        }
                    }
                }
            })

    建立一个map的原因是,后台不确定是否会新增重复的人员给我,故建立一个map对象判断是否以及绘制在底图上,如果绘制在底图上了,那么只用改变他的位置也就是xy或者说是经纬度,如果没有就去调用createPerson方法去绘制icon

    createPerson(value: any) {
            var startMarker = new olFeature({
                type: 'person',
                msg: value,
                geometry: new olgeomPoint([value.x, value.y])
            })
            let srcImg = value.type === 'type1' ? './images/type1.png' : value.type === 'type2' ? './images/type2.png' : './images/type3.png'
            var startStyle = new olstyleStyle({
                image: new olstyleIcon({
                    anchor: [0.5, 0.5],
                    scale: 0.3,
                    src: srcImg,
                    imgSize: [117, 158]
                }),
                text: new Text({
                    text: value.name,
                    // font: '14px font-size',
                    padding: [4, 7, 4, 7],
                    fill: new Fill({ color: '#fff' }),
                    backgroundFill: new Fill({ color: '#3737379e' }),
                    offsetY: -34
                })
            })
            startMarker.setStyle(startStyle)
            this.positionLayer.getSource().addFeature(startMarker)
            return startMarker
        }

    注意红色部分,很关键,第一次的我是直接把startStyle放到了positionLayer上,导致绘制出来的所有的icon的信息都是一样的,至于上面的三目运算大家应该知道,icon的类型不一样绘制出来的图标也是需要不一样的

    好了,自定义底图上添加静态icon就完成了,

    接下啦看看效果图吧,底图我随便换了一个静态图片,icon也是

    索嘎,完工

  • 相关阅读:
    hadoop中namenode发生故障的处理方法
    开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil
    Hbase的安装与部署(集群版)
    分别用反射、编程接口的方式创建DataFrame
    用Mapreduce求共同好友
    SparkSteaming中直连与receiver两种方式的区别
    privot函数使用
    Ajax无刷新显示
    使用ScriptManager服务器控件前后台数据交互
    数据库知识
  • 原文地址:https://www.cnblogs.com/ldlx-mars/p/11906877.html
Copyright © 2011-2022 走看看