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框架与MapReduce模式中谈海量数据处理
    Hadoop
    Clone Graph
    Gas Station
    ZigZag Conversion
    String to Integer (atoi)
    Palindrome Number
    Container With Most Water
    Longest Common Prefix
    求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
  • 原文地址:https://www.cnblogs.com/ldlx-mars/p/11906877.html
Copyright © 2011-2022 走看看