openlayers 一些样式

近期工作需要设计交通图,故需要设计一些类似铁路,桥梁,隧道等样式,在此记录下样式的一些效果。可能有更好的实现方式,在这里 就当抛转引玉了。

参考文章:
https://www.jianshu.com/p/e68e8e1b7474

1.铁路

需要设计以下两种样式,一种再建的,一种已完工的
在这里插入图片描述
样式代码:

//铁路已完工
[
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#000000",
                    width:6,
                    lineCap:"butt"
                }),
                zIndex:20
            }),
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#ffffff",
                    width:6,
                    lineDash:[15,15],
                    lineCap:"butt"
                }),
                zIndex:21
            })
        ]
//铁路再建
[
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#000000",
                    width:6,
                    lineDash:[15,45],
                    lineCap:"butt"
                }),
                zIndex:20
            }),
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#ffffff",
                    width:6,
                    lineDash:[15,45],
                    lineDashOffset:30,
                    lineCap:"butt"
                }),
                zIndex:21
            })
        ]

效果:
在这里插入图片描述
在这里插入图片描述

2.街道

街道大致就是白色的底加上黑色的边
在这里插入图片描述
样式代码

[
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#000000",
                    width:10,
                    lineCap:"butt"
                }),
                zIndex:20
            }),
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color:"#ffffff",
                    width:6,
                    lineCap:"butt"
                }),
                zIndex:21
            })
        ]

效果
在这里插入图片描述

3.隧道和桥梁

大致的想法是,利用街道的样式稍微做下调整,然后取线段的最后一个点和第一个点,加上分叉的样式,分叉点准备采用图片来弄,图个便利。
在这里插入图片描述
在这里插入图片描述
图片
在这里插入图片描述
在这里插入图片描述

样式代码

//桥梁样式
//因为绘制的时候用的是MultiLineString,如果用的是LineString,请自行调整代码
function drawsty(feature){
        var myStyle = [];
        myStyle.push(new ol.style.Style({
            stroke: new ol.style.Stroke({
                color:"#000000",
                width:10,
                lineCap:"butt"
            }),
            zIndex:20
        }));
        myStyle.push(new ol.style.Style({
            stroke: new ol.style.Stroke({
                color:"#FFFFFF",
                width:6,
                lineCap:"butt"
            }),
            zIndex:21
        }));
        var linearr = feature.getGeometry().getLineStrings();
        $.each(linearr,function(i,j){
            var firstcoord = j.getFirstCoordinate().join(",");
            var lastcoord =j.getLastCoordinate().join(",");
            //因为要给图片设置角度,所以需要遍历线的每一段,然后计算出图片需要旋转的角度
            j.forEachSegment(function(start, end) {
                if(firstcoord == start.join(",")){
                    var dx = end[0]- start[0];
                    var dy = end[1] - start[1];
                    var rotation = Math.atan2(dy, dx);
                    myStyle.push(new ol.style.Style({
                        geometry: new ol.geom.Point(start),
                        image: new ol.style.Icon({
                            src: "image/bridge.png",
                            scale:0.8,
                            rotation: -rotation-Math.PI/2//图片旋转角度,请自行调整
                        })
                    }));
                }
                if(lastcoord == end.join(",")){
                    var dx = end[0]- start[0];
                    var dy = end[1] - start[1];
                    var rotation = Math.atan2(dy, dx);
                    myStyle.push(new ol.style.Style({
                        geometry: new ol.geom.Point(end),
                        image: new ol.style.Icon({
                            src: "image/bridge.png",
                            scale:0.8,
                            rotation: -rotation+Math.PI/2
                        })
                    }));
                }
            });
        })
        return myStyle;
    }
    //隧道样式,隧道和桥梁的不同点是,隧道的黑色边框是虚线
    function drawsty(feature){
        var myStyle = [];
        myStyle.push(new ol.style.Style({
            stroke: new ol.style.Stroke({
                color:"#000000",
                width:10,
                lineDash:[15,1],
                lineCap:"butt"
            }),
            zIndex:20
        }));
        myStyle.push(new ol.style.Style({
            stroke: new ol.style.Stroke({
                color:"#FFFFFF",
                width:6,
                lineCap:"butt"
            }),
            zIndex:21
        }));
        var linearr = feature.getGeometry().getLineStrings();
        $.each(linearr,function(i,j){
            var firstcoord = j.getFirstCoordinate().join(",");
            var lastcoord =j.getLastCoordinate().join(",");
            j.forEachSegment(function(start, end) {
                if(firstcoord == start.join(",")){
                    var dx = end[0]- start[0];
                    var dy = end[1] - start[1];
                    var rotation = Math.atan2(dy, dx);
                    myStyle.push(new ol.style.Style({
                        geometry: new ol.geom.Point(start),
                        image: new ol.style.Icon({
                            src: "image/tunnel.png",
                            scale:0.8,
                            rotation: -rotation+Math.PI/2
                        })
                    }));
                }
                if(lastcoord == end.join(",")){
                    var dx = end[0]- start[0];
                    var dy = end[1] - start[1];
                    var rotation = Math.atan2(dy, dx);
                    myStyle.push(new ol.style.Style({
                        geometry: new ol.geom.Point(end),
                        image: new ol.style.Icon({
                            src: "image/tunnel.png",
                            scale:0.8,
                            rotation: -rotation-Math.PI/2
                        })
                    }));
                }
            });
        })
        return myStyle;
    }

效果:
在这里插入图片描述
在这里插入图片描述

4.高德地图导航样式

采用rbush实现该功能
箭头图片
在这里插入图片描述

样式代码

function styleFunction(feature,res){
        //轨迹线图形  此处我自己用的是MultiLineString
        var trackLine= feature.getGeometry().getLineStrings()[0];
        var styles = [
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: '#2E8B57',
                    width: 10
                }),
                zIndex:3
            }),
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: '#000000',
                    width: 12
                }),
                zIndex:1
            })
        ];
        //对segments建立btree索引
        let tree= rbush();//路段数
        trackLine.forEachSegment(function(start, end) {
            var dx = end[0] - start[0];
            var dy = end[1] - start[1];
            //计算每个segment的方向,即箭头旋转方向
            let rotation = Math.atan2(dy, dx);
            let geom=new ol.geom.LineString([start,end]);
            let extent=geom.getExtent();
            var item = {
                minX: extent[0],
                minY: extent[1],
                maxX: extent[2],
                maxY: extent[3],
                geom: geom,
                rotation:rotation
            };
            tree.insert(item);
        });
        //轨迹地理长度
        let length=trackLine.getLength();
        console.log(length);
        //像素间隔步长
        let stpes=40;//像素步长间隔
        //将像素步长转实际地理距离步长
        let geo_steps=stpes*res;
        //箭头总数
        let arrowsNum=parseInt(length/geo_steps);
        for(let i=1;i<arrowsNum;i++){
            let arraw_coor=trackLine.getCoordinateAt(i*1.0/arrowsNum);
            let tol=10;//查询设置的点的容差,测试地图单位是米。如果是4326坐标系单位为度的话,改成0.0001.
            let arraw_coor_buffer=[arraw_coor[0]-tol,arraw_coor[1]-tol,arraw_coor[0]+tol,arraw_coor[1]+tol];
            //进行btree查询
            var treeSearch = tree.search({
                minX: arraw_coor_buffer[0],
                minY: arraw_coor_buffer[1],
                maxX: arraw_coor_buffer[2],
                maxY: arraw_coor_buffer[3]
            });
            let arrow_rotation;
            //只查询一个,那么肯定是它了,直接返回
            if(treeSearch.length==1)
                arrow_rotation=treeSearch[0].rotation;
            else if(treeSearch.length>1){
                let results=treeSearch.filter(function(item){
                    //箭头点与segment相交,返回结果。该方法实测不是很准,可能是计算中间结果
                    //保存到小数精度导致查询有点问题
                    // if(item.geom.intersectsCoordinate(arraw_coor))
                    //   return true;

                    //换一种方案,设置一个稍小的容差,消除精度问题
                    let _tol=1;//消除精度误差的容差
                    if(item.geom.intersectsExtent([arraw_coor[0]-_tol,arraw_coor[1]-_tol,arraw_coor[0]+_tol,arraw_coor[1]+_tol]))
                        return true;
                })
                if(results.length>0)
                    arrow_rotation=results[0].rotation;
            }
            styles.push(new ol.style.Style({
                geometry: new ol.geom.Point(arraw_coor),
                image: new ol.style.Icon({
                    src: 'image/arrow.png',
                    scale:0.4,
                    rotation: -arrow_rotation+Math.PI/2
                }),
                zIndex:3
            }));
        }
        return styles;
    }

效果
在这里插入图片描述

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值