OpenLayers学习笔记中级篇(四、地图图标操作)

openlayers3加图标定位 首先想说的是我也是刚刚接触openlayers,因为公司的需求所以开始学习openlayers,刚开始想学openlayers2,但是试过几次发现openlayers2的浏览效果不好,还存在一些浏览卡顿不流畅等问题,于是我转向openlayers3,发现openlayers3确实在效果上好了很多,但是openlayers3在很多语法方面做了较大调整。由于我也是刚刚接触ol3,所以做出的功能也许不多 阅读详情

图标是GIS应用中必不可少的要素,比如在地图上标注饭店,学校,加油站等,就需要添加图标,点击图标,可能需要提示更为详细的信息,比如地址,评价,或者更为复杂的业务信息。本节将从基本的应用入手讲解,直到比较高级一些的自定义特色图标和信息展示。

在OpenLayer3中添加图标有两种方式,一种是我们这一小节马上就要介绍的,比较传统的overlay,另一种是下一小节马上就要介绍的Feature + Style的方式。 overlay之所以传统,是因为它就是传统的html方式显示图片。 下面就是用这种方式加载一个五角星的示例:

1、overlay方式添加图标

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<!--下面就是传统的显示一个图片图标的方式,用img-->
<div id="anchor"><img src="img/star.png" alt="示例五角星"/></div>
<script type="text/javascript">
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      })
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 12
    })
  });

  // 下面把上面的图标附加到地图上,需要一个ol.Overlay
  var anchor = new ol.Overlay({
    element: document.getElementById('anchor')
  });
  // 关键的一点,需要设置附加到地图上的位置
  anchor.setPosition([116.403598,39.917553]);
  // 然后添加到map上
  map.addOverlay(anchor);
</script>
</body>

</html>

还是先运行看一下效果如下:

这样我们就把一个五角星加载地图上北京的位置上!来看一下具体的流程:

首先我们定义了一个div用来放置五角星图片,然后我们定义了一个Overlay,在Overlay的元素位置上放上五角星的div  id,然后非常重要的一步是给五角星图片设置一个位置,最后把Overlay图层加入到地图上即可!

功能已经完成了,下面我们来分析一下这种方式加载图标的优点和缺点:

缺点:

当图标比较多的情况下,如果采用这种方式,那么我们会加入非常多的HTML元素,从而造成效率降低。 关于效率的测试,大家可以自行测试。 为什么会这样呢? 因为界面上元素的遍历在数量比较多的情况下,会变慢,基于此基础上的渲染,鼠标事件都会变慢。

优点:

这种使用传统的方式显示图标可以应用传统的HTML技术,比如鼠标移动到图标上,鼠标图标变成手势。 我们可以用css来处理就可以了,比如在head里面添加下面的代码:

<style type="text/css">
    #anchor {
        cursor:pointer;
    }
</style>

就可以看到鼠标放到锚点上去的时候,鼠标图标从箭头,变成手了。 类似的其他技术都可以应用上去,比如css动画。 鉴于动画在前端的重要性,下面单独用实例来讲解。

2、给图标添加动画效果,话不多说,直接上代码:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
	<meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
    <!--定义动画,图标先放大,再缩小-->
    <style type="text/css">
      @keyframes zoom
      {
        from {top: 0; left: 0; width: 32px; height: 32px;}
        50% {top: -16px; left: -16px; width: 64px; height: 64px;}
        to {top: 0; left: 0; width: 32px; height: 32px;}
      }
/* Firefox */
      @-moz-keyframes zoom 
      {
        from {top: 0; left: 0; width: 32px; height: 32px;}
        50% {top: -16px; left: -16px; width: 64px; height: 64px;}
        to {top: 0; left: 0; width: 32px; height: 32px;}
      }
/* Safari 和 Chrome */
      @-webkit-keyframes zoom 
      {
        from {top: 0; left: 0; width: 32px; height: 32px;}
        50% {top: -16px; left: -16px; width: 64px; height: 64px;}
        to {top: 0; left: 0; width: 32px; height: 32px;}
      }
/* Opera */
      @-o-keyframes zoom 
      {
        from {top: 0; left: 0; width: 32px; height: 32px;}
        50% {top: -16px; left: -16px; width: 64px; height: 64px;}
        to {top: 0; left: 0; width: 32px; height: 32px;}
      }

      /* 应用css动画到图标元素上 */
      #anchorImg
      {
        display: block;
        position: absolute;
        animation: zoom 5s;
        animation-iteration-count: infinite; /* 一直重复动画 */
        -moz-animation: zoom 5s; /* Firefox */
        -moz-animation-iteration-count: infinite; /* 一直重复动画 */
        -webkit-animation: zoom 5s;  /* Safari 和 Chrome */
        -webkit-animation-iteration-count: infinite; /* 一直重复动画 */
        -o-animation: zoom 5s; /* Opera */
        -o-animation-iteration-count: infinite; /* 一直重复动画 */
      }
    </style>
</head>
<body>
<div id="map" style="width: 100%"></div>
<div id="anchor" style="width: 64px;height: 64px;" ><img id='anchorImg' src="img/star.png" alt="示例五角星"/></div>
<script type="text/javascript">
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      })
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
     center: [116.403598,39.917553],
      zoom: 10
    })
  });

  var anchor = new ol.Overlay({
    element: document.getElementById('anchor')
  });
  anchor.setPosition([116.403598,39.917553]);
  map.addOverlay(anchor);
</script>
</body>

</html>

这是一个动态的动画效果,大家可以自己测试一下看看效果,还是很不错的。这里我们也只是比demo1多做了一些css样式的改变,这也是overlayer加载图标的优点,我们可以使用css来处理图标的加载样式。除了这种css实现动画之外,我们还可以直接加载gif动画,这是非常简单的,在此不再赘述!

下面我们来介绍第二种加载图标的方法:Feture+Style的方式加载图标。其实这种方式之前我们已经使用过了,就是在地图加载章节那儿的矢量地图的加载方式那儿,下面我们根据具体的代码来看一下:

3、feature+style加载图标

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
    <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  // 我们需要一个vector的layer来放置图标
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })

  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [104, 30],
      zoom: 10
    })
  });

  // 创建一个Feature,并设置好在地图上的位置
  var anchor = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
  });
  // 设置样式,在样式中就可以设置图标
  anchor.setStyle(new ol.style.Style({
    image: new ol.style.Icon({
      src: 'img/star.png'
    })
  }));
  // 添加到之前的创建的layer中去
  layer.getSource().addFeature(anchor);
</script>
</body>

</html>

还是先运行代码看一下:

图标加载成功,下面我们进行代码的讲解,看一下我们这种方法具体的加载顺序:

首先我们需要一个vector的layer来放置图标,然后我们创建一个Feature,并设置好在地图上的位置,然后我们设置样式Feature,在样式中就可以设置图标,最后将feature添加到之前的创建的layer中去,就可以加载出来图标了!下面我们来对比一下overlayer和feature方式加载的异同点:

效果是一样的,但从代码上来看,是不一样的:

  • 首先overlay需要HTML元素img,但这种方式不需要
  • overlay是添加在map上的,但是这种方式需要一个Vector的layer,并添加在其上
  • 我们没有办法像overlay那样使用一些HTML技术

虽然不能用css直接修改图标显示,但并不是说使用这种方式没有自定义的余地,大家可以先在官网API上看一下ol.style.Icon的构造参数,会看到可以设置位置,透明度,放大缩小,旋转等,基本能满足大多数的应用,由于和CSS不同,很多同学在应用时遇到一些问题,所以下面给出了一些具体的使用示例。

 4、大家看上面的效果图时会发现,我们的图标是不能随着层级的放大缩小而改变自己的大小的,这样有时候图标的显示是非常丑陋的,我们下面做一个根据层级放大缩小图标的功能!这个功能很简单,在ol.style.Icon中是可以设置scale的,这样就为 我们提供了方便。 通过设置它,就可以做到。话不多说,直接上代码如下:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
    <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  // 我们需要一个vector的layer来放置图标
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })

  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 10
    })
  });

  // 创建一个Feature,并设置好在地图上的位置
  var anchor = new ol.Feature({
    geometry: new ol.geom.Point([116.403598,39.917553])
  });
  // 设置样式,在样式中就可以设置图标
  anchor.setStyle(new ol.style.Style({
    image: new ol.style.Icon({
      src: 'img/star.png'
    })
  }));
  // 添加到之前的创建的layer中去
  layer.getSource().addFeature(anchor);
  
   // 监听地图层级变化
  map.getView().on('change:resolution', function(){
      var style = anchor.getStyle();
      // 重新设置图标的缩放率,基于层级20来做缩放
      style.getImage().setScale(this.getZoom() / 20);
      anchor.setStyle(style);
  })
</script>
</body>

</html>

大家可以自行测试一下效果!

5、下面我们再来设置一下如何直接通过绘制的形式直接加载图标,OpenLayers 3提供了一个规则几何体的样式类ol.style.RegularShape,使用它可以轻松绘制正方形,三角形等,也支持星形规则几何图形,直接上代码如下:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 10
    })
  });

  // 添加一个三角形
  var shape = new ol.Feature({
    geometry: new ol.geom.Point([116.203598,39.927553])
  });
  shape.setStyle(new ol.style.Style({
    image: new ol.style.RegularShape({
      points: 3,    // 顶点数
      radius: 20,    // 图形大小,单位为像素
      stroke: new ol.style.Stroke({ // 设置边的样式
          color: 'red',
          size: 5
      }),
      fill: new ol.style.Fill({ // 设置五星填充样式
          color: 'blue'
      })
    })
  }));

  layer.getSource().addFeature(shape);

  // 添加一个五星
    var star = new ol.Feature({
    geometry: new ol.geom.Point([116.403598,39.917553])
  });
  star.setStyle(new ol.style.Style({
    image: new ol.style.RegularShape({
      points: 5,    // 顶点个数
      radius1: 20, // 外圈大小
      radius2: 10, // 内圈大小
      stroke: new ol.style.Stroke({ // 设置边的样式
          color: 'red',
          size: 2
      }),
      fill: new ol.style.Fill({ // 设置五星填充样式
          color: 'blue'
      })
    })
  }));

  layer.getSource().addFeature(star);

</script>
</body>

</html>

看一下效果:

我们绘制的三角形和五角星都加载到了地图上,其实加载的方式和feature加载图标的方法是一样的,只不过我们把要加的图标换成了我们使用ol.style.Style自己绘制的图形,另外由代码我们也可以得到,我们可以通过这种方法加载各种规则的多边形!除了基本的设置之外,还支持图形旋转,以及跟随地图旋转而旋转,这些设置在其他的应用中也多有涉及,此处不再用实例来介绍,可自行验证。

6、有了加载规则的绘制图标,那么一些不规则的图标如何绘制并加入到地图种呢?别着急,马上来实现它!我们可以用canvas自己来绘制不规则的图标,好了,直接上代码如下:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 10
    })
  });

  // 使用canvas绘制一个不规则几何图形
    var canvas =document.createElement('canvas');
    	canvas.width = 40;
  		canvas.height = 40;
    var context = canvas.getContext("2d");
    	context.strokeStyle = "red";  
	  	context.lineWidth = 3;  
	  	context.beginPath();   
	  	context.moveTo(0, 0);
	  	context.lineTo(20, 10);
	  	context.lineTo(0, 20);
	  	context.lineTo(10, 10);
	  	context.lineTo(0, 0);  
	  	context.stroke();
	
  // 把绘制了的canvas设置到style里面
    var style = new ol.style.Style({
        image: new ol.style.Icon({
          img: canvas,
          imgSize: [canvas.width, canvas.height],
          rotation: 90 * Math.PI / 180
        })
    });

    // 创建一个Feature
	  var shape = new ol.Feature({
	    geometry: new ol.geom.Point([116.403598,39.917553])
	  });

  // 应用具有不规则几何图形的样式到Feature
  	shape.setStyle(style);
  	layer.getSource().addFeature(shape);
</script>
</body>

</html>

看一下效果图:

我们成功绘制了不规则图标并把它加入到了地图中!我们使用了ol.style.Icon样式的img属性来设置,需要注意的是,必须设置imgSize属性,因为仅仅通过img设置的图像对象,没有办法自动获取宽高。 同时,官网也提供了一个类似的例子earthquake-custom-symbol,只是使用OpenLayers3 内部提供的封装库来绘制图像到canvas上,原理一样。有了这种方式之后,相信做任何图标都不会遇到难题了。

7、现在我们加载各种样式的图标都不是问题了,但是我们目前加载的图标都是静态的,实际项目中我们可能需要对图标做点击时间然后进行各种操作,在实际业务应用中,需要根据环境条件,动态的修改图标样式,以反馈数据变化。 比如像下面这样,点击五星,五星图标会用红色填充,话不多受,直接上代码:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>地图图标加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 10
    })
  });

  // 添加一个空心的五星
    var star = new ol.Feature({
    geometry: new ol.geom.Point([116.403598,39.917553])
  });
  star.setStyle(new ol.style.Style({
    image: new ol.style.RegularShape({
      points: 5,
      radius1: 20,
      radius2: 10,
      stroke: new ol.style.Stroke({
          color: 'red',
          size: 2
      })
    })
  }));

  layer.getSource().addFeature(star);

  // 监听地图点击事件
  map.on('click', function(event){
      var feature = map.forEachFeatureAtPixel(event.pixel, function(feature){
          return feature;
      });
      if (feature) {
      	alert("我要红了")
          // 将空心五星为红色实心五星
          var style = feature.getStyle().getImage();
          feature.setStyle(new ol.style.Style({
            image: new ol.style.RegularShape({
              points: 5,
                  radius1: 20,
                  radius2: 10,
                  stroke: style.getStroke(),
                  fill: new ol.style.Fill({
                      color: 'red'
                  })
            })
          }));
      }
  });

</script>
</body>

</html>

看一下效果:

点击前:

点击后:

这里我输出了一句“我要红了”,其实在正式项目中,我们可以在这一句话的位置进行数据的反馈等操作!

8、前面我们加载的都是图标,下面我们来做一个加载文字的demo,话不多说,直接上代码:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>文字标注加载</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [116.403598,39.917553],
      zoom: 12
    })
  });

  var anchor = new ol.Feature({
    geometry: new ol.geom.Point([116.403598,39.917553])
  });
  // 设置文字style
  anchor.setStyle(new ol.style.Style({
    text: new ol.style.Text({
      font: '15px sans-serif',  //默认这个字体,可以修改成其他的,格式和css的字体设置一样
      text: '北京天安门',
      fill: new ol.style.Fill({
          color: 'red'
      })
    })
  }));
  layer.getSource().addFeature(anchor);
</script>
</body>

</html>

看一下效果:

加载成功!关于文字标注,还有很多属性可以设置,比如缩放,旋转,以及位移等等,非常简单,可自行设置调试。

9、styleFunction的应用

很多时候,我们会忽略styleFunction的存在,但很明显的,它可以让我们的图标或者标签应用更加灵活,比如根据层级放大缩小图标也可以用styleFunction来实现,直接上代码:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>styleFunction应用</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map" style="width: 100%"></div>
<script type="text/javascript">
  var layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  })
  var map = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer
    ],
    target: 'map',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [104, 30],
      zoom: 10
    })
  });

  var anchor = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
  });
  // 应用style function,动态的获取样式
  anchor.setStyle(function(resolution){
      return [new ol.style.Style({
          image: new ol.style.Icon({
            src: 'img/star.png',
            scale: map.getView().getZoom() / 20
          })
        })];
  });

  layer.getSource().addFeature(anchor);
</script>
</body>

</html>

大家可以自己运行代码看一下效果,这里解释一下代码:对比一下前面同样功能的代码,你会发现这样更加的简单, 同时在此基础上扩展开来的应用也会更加的多。 比如动态替换图标,或者让图标不显示等等,可自行来实现这两个需求,以掌握此方式的使用。

在上面这个例子中,我们是在feature上应用了styleFunction,通过官网API文档可以看到,其类型为ol.FeatureStyleFunction,函数仅带有一个参数resolution,在上面的代码中看到了,在函数体内this指的是当前的feature,根据文档说明,这个函数要范围一个style数组。 这一点需要注意,虽然实际使用中,即使没有返回数组也不会出错,但还是希望大家能遵守官网API的说明来使用该接口。

我们知道,除了feature可以设置样式之外,layer也是可以设置样式的,同样地也支持styleFunction,但是需要注意的是,其定义和feature的不一样,类型为ol.style.StyleFunction,该函数具有两个参数,第一个参数为feature,第二个参数为resolution,同样地,该函数需要返回style数组。styleFunction在feature上具有很好的灵活性,那么应用在layer上,同样威力无穷,比如像下面这个,直接上代码:

<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>                  
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta content=always name=referrer>
    <title>styleFunction应用</title>
    <link href="css/ol.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>

<body>
   <div id="map2" style="width: 100%"></div>
<script type="text/javascript">

  // 创建layer使用的style function,根据feature的自定义type,返回不同的样式
  var layerStyleFunction = function(feature, resolution) {
    var type = feature.get('type');
    var style = null;
    // 点
    if (type === 'point') {
      style = new ol.style.Style({
        image: new ol.style.Circle({
          radius: 5,
          fill: new ol.style.Fill({
            color: 'red'
          })
        })
      });
    } else if ( type === 'circle') { // 圆形
      style = new ol.style.Style({
        image: new ol.style.Circle({
          radius: 20,
          stroke: new ol.style.Stroke({
            color: 'red',
            size: 3
          })
        })
      });
    } else { // 其他形状
      style = new ol.style.Style({
        image: new ol.style.RegularShape({
          points: 5,
          radius: 20,
          fill: new ol.style.Fill({
            color: 'blue'
          })
        })
      });
    }

    // 返回 style 数组
    return [style];
  };

  var layer2 = new ol.layer.Vector({
    source: new ol.source.Vector(),
    style: layerStyleFunction // 应用上面创建的 style function
  });

  var map2 = new ol.Map({
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM()
      }), 
      layer2
    ],
    target: 'map2',
    view: new ol.View({
      projection: 'EPSG:4326',
      center: [104, 30],
      zoom: 10
    })
  });

  // 添加三个feature,并设置自定义属性 type
  var rect = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
  });
  layer2.getSource().addFeature(rect);

  var circle = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
  });
  circle.set('type', 'circle');
  layer2.getSource().addFeature(circle);

  var point = new ol.Feature({
    geometry: new ol.geom.Point([104, 30])
  });
  point.set('type', 'point');
  layer2.getSource().addFeature(point);

</script>
</body>

</html>

看一下效果:

在地图上可以看到中心位置有一个圆,一个点,一个五边形,但这次都没有直接在这些feature上设置样式,而是创建layer使用的style function,根据feature定义的type,返回不同的样式。这就是一个典型的根据feature的属性进行不同渲染的例子,可以在业务上无限扩展,比如feature的属性可以是速度,可以是大小,可以是时间,可以是权重等等。 由此可见,只要掌握了这个方法,前端按照条件渲染就不再困难。

好了,关于地图标注的加载和相关操作就进行到这儿了,上门我们写过的demo可以满足绝大多数项目的需要了,希望大家多多动手练习!下一节我们将根据openlayers官网的demo来做地图开发时的各种事件,大家加油!

 

 

Openlayers之地图标注 1、标注的简介 标注简单点说就是通过图标、文字等方式将我们想展示的内容显示在地图上,着重突出人们所关注的专题内容,从而为用户提供个性化的地图服务; 2、标注方式 在Openlayers3里面,有两种对地理位置点进行标注的方法,一种是通过创建矢量图层然后设置其样式的方法,还有一种就是创建Overlay覆盖层的方法;对于第一种方式,本质上创建的还是一个矢量对象,只是将其表现形式更换了一下,用St 阅读详情

相关推荐

【openlayers框架学习】十六:通过鼠标点击在地图上添加图标标记以及图标聚合

本文介绍了电子地图开发中常用的OpenLayers框架,重点讲解了OpenLayers在地图开发中的高级应用,通过鼠标点击实现在地图上添加图标标记以及缩放地图实现图标的聚合。。文章提供了完整的代码示例,适合初学者快速入门WebGIS开发。

weixin_41637679的博客 945

【openlayers-3】加载图标

openlayers添加图标

WXG1011的博客 1310

openlayers6【十六】vue overlay类实现gif动态图标效果详解

前提: openlayer 里面支持 gif 图标上图的只有 overlay类 可以实现。 openlayers 不支持 svga 动画图 文章目录1. 效果图2. 【核心】创建overlay类,循环点位根据坐标创建div点位3. css设置gif图标4. 完整代码 1. 效果图 2. 【核心】创建overlay类,循环点位根据坐标创建div点位 // 使用Overlay添加GIF动态图标点位信息 addGif() { let _that = this; let mainBox =.

@必意玲 5822

openlayers点击图标弹出自定义属性

效果图 Html代码 <div id="map"></div> Css代码 #map { width: 100%; height: 100%; } .ole-js-popup { padding: 0; border-radius: 3px; border: none; box-sizing: border-box; box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.15); pointer-events:

好巧~我看到你了 1829

宝马项目化流程标准(BMW ABC flyer requirement)

宝马项目化流程标准(BMW ABC flyer requirement)

于大博 7254

推荐系统:NDCG评价指标及其Python实现方法

除了推荐任务,在二分类任务中,也可以计算该指标,代码如下: # ndcg def get_dcg(y_pred, y_true, k): #注意y_pred与y_true必须是一一对应的,并且y_pred越大越接近label=1(用相关性的说法就是,与label=1越相关) df = pd.DataFrame({"y_pred":y_pred, "y_true":y_true}) ...

lanyuelvyun的博客 8242

OpenLayers 3地图添加图标

OpenLayers 3地图添加图标 一、overlay方式在地图添加图标 1、项目结构 2、map.html <!Doctype html> <html xmlns='http://www.w3.org/1999/xhtml'> <head> <meta http-equiv='Content-Type' content='text/html;charset=utf-8'> <meta http-equiv='X-UA-Compat

大树 3880

从HAL库SPI状态机机制剖析:为什么你的DMA发送会卡在BUSY状态?

本文深入剖析了STM32 HAL库中SPI状态机机制导致DMA发送卡在BUSY状态的常见问题。通过分析状态机设计原理,揭示了混合使用阻塞方式和DMA方式时状态切换冲突的根源,并提供了三种实战解决方案:正确配置SPI中断、使用HAL_SPI_Abort()函数以及手动管理状态机,帮助开发者实现稳定流畅的SPI DMA通信。

bush的博客 268

利用Openlayers2给地图添加Icon标注

实现效果代码

qq_37385726的博客 2512

【GPT】Coze使用开放平台接口-【7】Dify 比较篇

coze 用于社交,dify 用来内部构建。抛开工作流,机器人,工具,coze 最大的区别在于可以直接发布到社交媒体上。所以,coze 对操作体验上也花了不少功夫,而 dify 就专注在帮助使用者打磨工作流。coze 各个大模块之前可以联动的机制也比较多,所以侧重点各不相同。

非晓为骁的博客 7614

别再凭感觉选电容了!手把手教你计算电机控制器里的母线电容(附Excel计算工具)

本文详细解析了电机控制器中母线电容的选型方法,从理论计算到工程实践,帮助工程师避免常见误区。通过精确计算纹波电压、电容容量等关键参数,并结合薄膜电容与电解电容的性能对比,提供实用的选型建议。附带的Excel计算工具可快速完成参数计算,适用于工业伺服驱动和电动车电机控制器设计。

weixin_28720573的博客 522

openlayers 地图上加图标_OpenLayers学习笔记中级篇(四、地图图标操作)

图标是GIS应用中必不可少的要素,比如在地图上标注饭店,学校,加油站等,就需要添加图标,点击图标,可能需要提示更为详细的信息,比如地址,评价,或者更为复杂的业务信息。本节将从基本的应用入手讲解,直到比较高级一些的自定义特色图标和信息展示。在OpenLayer3中添加图标有两种方式,一种是我们这一小节马上就要介绍的,比较传统的overlay,另一种是下一小节马上就要介绍的Feature+Styl...

weixin_39630909的博客 1096

基于51单片机的电子记分牌的设计

基于51单片机的电子记分牌的设计 电子记分牌基于51单片机的电子记分牌的设计摘要1 引言2 总体设计方案2.1 设计思路(1)设计要求(2)设计思路(3)设计方案2.3综合设计方框图(1)硬件设计框图(2)软件设计3 设计原理分析3.1 电源、复位、下载电路的设计(见图1、2、3)3.2 时钟电路的设计3.3 矩阵键盘电路的设计3.4 数码管显示电路设计4程序代码 摘要 本设计为电子记分牌设计,是以STC89C52芯片为核心,辅以必要电路设计进行的。用4位LED七段数码管显示比赛两方的分数(每方分数用2位

行走的皮卡丘 2037

转载:OpenLayers学习笔记中级篇(四、地图图标操作)

1、overlay方式添加图标 首先我们定义了一个div用来放置五角星图片,然后我们定义了一个Overlay,在Overlay的元素位置上放上五角星的divid,然后非常重要的一步是给五角星图片设置一个位置,最后把Overlay图层加入到地图上即可! 功能已经完成了,下面我们来分析一下这种方式加载图标的优点和缺点: 缺点: 当图标比较多的情况下,如果采用这种方式,那么我们会加入非常多的...

Handsome2013的博客 1183

C++ 小游戏程序 (共七款)

C++编程小游戏_闪耀的天狼星的博客-优快云博客_游戏c++C++跑酷小游戏_闪耀的天狼星的博客-优快云博客。好玩的c++编程小游戏,共六款。代码】C++跑酷小游戏。

小天狼星_布莱克 的博客 3万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

vue+openlayers在地图添加图标

参考帖子:https://blog.youkuaiyun.com/feiteyizu/article/details/81133845 有两种方式,介绍第二种,第一种太简单,,而且不能动态增加dom元素从而添加图标,也就是说,如果使用上述帖子的第一种方式,你需要加几个图标,就需要提前预定好多少个图标对应的dom元素,而且未被使用的图标会显示在地图下面,地图会被撑变形,需求如果只是添加一两个图标,且是固定的,可...

简的博客 8613

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

openlayers 地图上加图标_Openlayers 定位,添加自定义图标,点击图标弹框

之前已经把地图展示出来,现在可以在地图上做相关操作。首先定义一个位置图层,这样可以动态操作importFeaturefrom'ol/Feature'import{VectorasVectorLayer}from'ol/layer'importGeoJSONfrom'ol/format/GeoJSON'importVectorSourcefrom'ol/source/Ve...

weixin_36437537的博客 2643

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

openlayers 地图上加图标_openlayers添加地图标记

html,body {width: 100%;height: 100%;margin: 0;}.map {width: 100%;height: 100%;background: #f6f6f4;}var map;$(function () {InitMap();AddPoint();})var layer;//地图初始化function InitMap() {//初始化地图layer = new...

weixin_39593523的博客 539

openlayers 地图上加图标_openlayers地图添加标志物

openlayers是最好的开源地图引擎,我们开发主要在地图上标记兴趣点,画区域,任意图形,运动轨迹等等。在ol地图上画东西其实非常简单,只需要按以下步骤执行Pointpoint是一个ol坐标点,例如根据经纬度来转为ol对应的坐标var lonLat = [114.158648, 22.284701];var transPoint = ol.proj.fromLonLat(lonLat);Feat...

weixin_29658015的博客 1369

openlayers 地图上加图标_OpenLayers添加地图标记

添加地图标记functioninit(){varmap= newOpenLayers.Map("ch3_markers");varlayer= newOpenLayers.Layer.OSM("OpenStreetMap");map.addLayer(layer);map.addControl(newOpenLayers.Control.LayerSwitcher());map.setCenter...

weixin_39553805的博客 590

openlayers地图显示中心图标

openlayers地图显示中心点openlayers地图显示中心位置,类似微信发送位置误区使用Overlay拖动地图,中心图标随地图移动而移动总结 openlayers地图显示中心位置,类似微信发送位置 地图使用中,显示中心位置很常见,有时候我们需要拖动地图调整地图中心位置怎么做呢? 误区 说到中心位置,第一时间想到创建点,地图拖动时移除原来的点,根据拖动后的中心位置添加新的点,心里感觉有点不符合常理,但不跳一下怎么知道是不是坑呢? 直接上代码 var currentMarker,currentFeatu

weixin_43727458的博客 1923

openlayers6【十五】地图样式 Style类详解

文章目录1. 写在前面2. ol.style 属性及子类3. ol.style使用栗子 1. 写在前面 地图样式是由 style 类控制的,其包含了地图样式的方方面面,例如,填充色、图标样式、图片样式、规则图形样式、边界样式、文字样式等,样式一般针对矢量要素图层。 了解更多矢量图层可以参考:openlayers6【十三】地图矢量图层 Vector 详解 2. ol.style 属性及子类 1.1 可以配置的选项 /* * @typedef {{ * geometry: (undefined|

@必意玲 1万+

openlayers 地图上加图标_openlayers在底图上添加静态icon

越学习openlayer你会发现openlayer是真的很强大,今天记录一下学习的成果,需求是做那种室内的CAD的场景然后里面展示人员icon并且实时展示人员的位置信息,以及点击弹出对应人员的一些位置信息,姓名,电话等等,这个在工业互联网中是很常见的,接下来就开始操作了由于我是在vue+ts中写的,所以下面的代码片段可能是基于vue来写的第一步,我们需要建立一个底图,这个底图可以是谷歌地图也可以是...

weixin_39945445的博客 1462

OpenLayers-基于OpenLayers的地图应用中图标汉化

在OpenLayers中图标默认是英文的,但是作为中国人,且做出来的地图产品主要是面向中国人,英文的图标对我们来说自然是不可接受的,因此需要对其进行汉化。这个功能做起来也很简单。只需要添加如下几个语句即可: [javascript] view plain copy OpenLayers.INCHES_PER_UNIT["千米"]=OpenLayers.INCH...

a18826265589的博客 363
上一篇: OpenLayers学习笔记中级篇(三、地图的分辨率设置)
下一篇: OpenLayers学习笔记中级篇(五、地图事件)
MagicMHD
博客等级 码龄9年 503粉丝 78原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值