如何在openlayers中使用iconfont或font Awesome字体图标

前言

  本文我们主要讲下如何在 openlayers 中使用 iconfont 字体,看明白了 iconfont ,那么Font Awesome 也就能明白了。虽然网上也能搜到一些讲这个的帖子,但是都讲得不清不楚的,比如牛老师的,我看完以后就是丈二和尚摸不着头脑,所以本文中,我会以 iconfont 为例,从最基础的讲起,力求初学者也能看的懂。另外遇到了哪些坑,我们也来讲一讲。

1.准备工作

  说到准备工作,那自然是我们要先去 iconfont 官网去下载自己的字体了,看一下我下载好的字体
在这里插入图片描述
在这里插入图片描述
  接下来就是在我们的测试页面中引入 iconfontcss,然后使用具体的图标了。
在这里插入图片描述

注意,iconfont 提供了 3 种在页面中显示的方式,分别是UnicodeFont classSymbol ,如果普通的页面元素上使用字体图标,这几种都支持,并且Font class是大家用的最多的方式,,因为既直观又简单。但是在openlayers中,经过我的测试,不支持Font class方式,这一点可以说相当可惜。

在这里插入图片描述
  注意看,左上角已经显示了 iconfont 的图标了,说明我们的配置没问题。

2.新建一个最简单的helloworld页面

  因为我要实现的是对矢量切片进行样式的配置,所以就新建一个矢量切片的图层。我们的示例图层也使用 GeoServer 中自带的示例图层来进行展示。
在这里插入图片描述

   var projection = new ol.proj.Projection({
       code: 'EPSG:4326',
       units: 'degrees',
       axisOrientation: 'neu',
       global: true
   });
   var layerName="sf:bugsites";
   var pbfLayer4326=new ol.layer.VectorTile({
       source: new ol.source.VectorTile({
           url: "http://localhost:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER="+layerName+"&STYLE=&TILEMATRIX=EPSG:4326:{z}&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL={x}&TILEROW={y}",
           format: new ol.format.MVT({}),
           projection: projection,
           tileGrid: new ol.tilegrid.WMTS({
               tileSize: [256,256],
               origin: [-180.0, 90.0],
               resolutions: [0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125, 0.0054931640625, 0.00274658203125, 0.001373291015625, 6.866455078125E-4, 3.4332275390625E-4, 1.71661376953125E-4, 8.58306884765625E-5, 4.291534423828125E-5, 2.1457672119140625E-5, 1.0728836059570312E-5, 5.364418029785156E-6, 2.682209014892578E-6, 1.341104507446289E-6, 6.705522537231445E-7, 3.3527612686157227E-7],
               matrixIds: ['EPSG:4326:0', 'EPSG:4326:1', 'EPSG:4326:2', 'EPSG:4326:3', 'EPSG:4326:4', 'EPSG:4326:5', 'EPSG:4326:6', 'EPSG:4326:7', 'EPSG:4326:8', 'EPSG:4326:9', 'EPSG:4326:10', 'EPSG:4326:11', 'EPSG:4326:12', 'EPSG:4326:13', 'EPSG:4326:14', 'EPSG:4326:15', 'EPSG:4326:16', 'EPSG:4326:17', 'EPSG:4326:18', 'EPSG:4326:19', 'EPSG:4326:20', 'EPSG:4326:21']
           }),
           wrapX: true
       }),
       style:function(feature,resolutions){
           // console.log(feature.getType(),feature.get("layer"),resolutions);
           if(feature.getType()=="Point"){
               return new ol.style.Style({
                       text: new ol.style.Text({
		                       font: 'normal 12px "iconfont"' ,
		                       text: "\ue61b",
		                       fill: new ol.style.Fill({ color: '#00f' }),
		                       textBaseline: 'bottom'
		                   })
		               });
           }else if(feature.getType()=="Polygon" || feature.getType()=="MulitiPolygon"){
              //...
           }else if(feature.getType()=="LineString" || feature.getType()=="MulitiLineString"){
               //...
           }
       }
   });
   var map = new ol.Map({
       layers: [pbfLayer4326],
       target: 'map',
       view: new ol.View({
           zoom:13,
           center:[-103.78,44.40],
           projection: projection
       })

   });

3.看看效果

在这里插入图片描述

4.注意点1-需使用Unicode写法

  请注意这段关键代码中 fonttext 的属性的写法,font 属性中的 iconfont 用双引号包了起来,而 text 属性则使用的是 Unicode

   if(feature.getType()=="Point"){
       return new ol.style.Style({
               text: new ol.style.Text({
               font: 'normal 12px "iconfont"' ,
               text: "\ue61b",
               fill: new ol.style.Fill({ color: '#00f' }),
               textBaseline: 'bottom'
           })
       });
   }

  那么 “\ue61b” 对应的是哪个 Unicode 图标,这还得回到我们下载 iconfont 字体里去看一下
在这里插入图片描述
  可以看出,对应的公园的图标,但是这里显示的是 “&#xe61b”,为什么在 openlayers 里要改成 “\ue61b” 呢?因为 “&#x” 是十六进制写法,“\u” 则是对应的 Unicode 写法。
  那么如果我们将 openlayers 里的写法换成是 Font class写法,会发生什么事呢?我们来尝试一下,修改一下代码

if(feature.getType()=="Point"){
    return new ol.style.Style({
            text: new ol.style.Text({
            font: 'normal 12px "iconfont"' ,
            text: "icon-gongyuan",
            fill: new ol.style.Fill({ color: '#00f' }),
            textBaseline: 'bottom'
        })
    });
}

在这里插入图片描述
  可以发现,字体图标并没有起作用,本文中用到的 openlayers 版本为4.6.5,并没有使用更高的版本进行测试,不排除是版本问题,也可能后续版本进行了修复,但是3.x和4.x中想使用字体图标,那就必须是本文中的写法,才能起作用。

4.注意点2-需注意iconfott.woff2的请求顺序

  我还曾遇到过一个很奇怪的问题,地图首次加载时字体图标死活出不来,显示的是一个方框,后来刷新一下页面就出来了。我不知道为什么会存在延迟加载的问题,目前我的解决方式是,先在页面给个普通元素 span 加载一下相应的图标,之后才在 openlayers 里去使用这个字体图标,这样就不会存在使用上的延迟问题。
  经过调试,我发现造成这一现象的主要原因是,iconfott.woff2 的请求顺序决定的。
在这里插入图片描述
  可以看到 iconfott.woff2 是由 iconfont.css 请求的,如果 iconfott.woff2 是在矢量切片之前被请求到,则显示就是正确的,反之显示的就是一个方框。
  那么有没有更好的解决方式呢?答案是:有,link 标签可以预加载

 <link rel="preload" as="font" href="./iconfont/iconfont.woff2?t=1665994611202" type="font/ttf" crossorigin="anonymous">

href 中需要传递一个 t 值,我们可以在 iconfont.css 中的找到它
在这里插入图片描述

5.特殊图标的制作

  那么如果我们想使用一个特殊的图标,应该如何制作呢?比如高德中的这种:
在这里插入图片描述
  首先这个图标是由两层构成的,下面的一层是圆圈,上面的一层才是图标,那么怎么在 openlayers 中画下面的这个圆呢?答案是使用 ol.style.RegularShape 这个类,这个类是用来画五角星的,参数里可以给定点的数量,如果只给五个,就是五角星,那要是给360个呢?那么不就是圆了么?
但是360个太多了,影响性能,36个就能满足我们的需求。

  var tubiao="\u0119";
  var color="#ff5b4d";
  var offsetX=-0.5;
  var scale=1;
  return [
	    new ol.style.Style({
	        text:new ol.style.Text({
	            font: 'normal 15px "iconfont"' ,
	            text: tubiao,
	            fill: new ol.style.Fill({ color: "#fff"}),
	            textBaseline: 'bottom',
	            scale:scale,
	            offsetY:6,//正值向下,负值向上
	            offsetX:offsetX,//正值向右,负值向左
	        }),
	        image:new ol.style.RegularShape({
	            points:36,
	            radius:8,
	            fill:new ol.style.Fill({ color: color }),
	        })
	    }),
	    new ol.style.Style({
	        text:new ol.style.Text({
	            font: 'bold 12px arial' ,
	            text: "故宫博物院",
	            overflow:true,
	            stroke: new ol.style.Stroke({
	                color: '#fff',
	                width: 1
	            }),
	            fill: new ol.style.Fill({ color: color }),
	            textBaseline: 'bottom',
	            offsetY:24,
	            scale:1,
	            
	        }),
	    }),
	];

在这里插入图片描述
大功告成!

6.总结

  本文以 iconfont 为例,讲解了如何在 openlayers 中使用字体图标,并讲解了其中遇到的问题,以及对应的解决方案。值得注意的是,本文中是以 wmts 的方式加载的矢量切片,网上搜到的资料,大部分人使用的 tms 方式来加载矢量切片,因 tms 并不是 ogc 的标准,所以本文并未采用。当然,不论以何种形式来加载矢量切片,并不会对样式有影响,还是这样去设置的。
  所以在一定程度上可以说,本文是一石二鸟,在一个示例里,既讲了矢量切片的 wmts 加载,又讲了 openlayers 中字体图标的使用,一举两得。好了,本文就讲到这里了,回见~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AIGIS.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值