前言

使用openlayer实现选房平面图的需求:
	1.选用地图背景图
	2.将geojson数据(没有后台所以就写死了2个数据)生成房间图层块覆盖背景图上对应的房间块
	3.根据条件,可选区域与不可区域图形块颜色不一样
	4.点击图层能获取到对应的数据,同时选中的图层块样式发生改变

代码详解

地图背景展示

根据官方案例,只需要提供一个div,然后将Map对象挂载到div元素上

const extent = [0, 0, 50, 50];//地图范围
const projection = new Projection({//地图投影
  code: 'xkcd-image',
  units: 'pixels',
  extent,
});
this.map = new Map({
        layers: [
          new ImageLayer({
            source: new Static({ //这就是静态背景图片
              url: '/img/A-10.png',//图片路径,放在静态文件夹public(vue-cli3.0)或static(vue-cli2.0)里,根据脚手架版本来
              projection,
              imageExtent: extent,//图片位置
            }),
          }),
          vectorLayer,//多个图层,下面会讲到
        ],
        target: 'map',
        view: new View({
          projection,
          center: getCenter(extent),
          zoom: 1,//地图默认比例
          maxZoom: 4,//地图最大比例
          minZoom: 1,//地图最小
        }),
 });

这样一个带图片背景的地图就做好了
然后就要渲染上面的图层了

图层渲染

步骤大概为:GeoJSON转换json数据为feature->vectoryresource->获取样式->vectorlayer->map添加vectorlayer

根据GeoJSON获取图层

const geojsonObject = {
        type: 'FeatureCollection',
        crs: {
          type: 'name',
          properties: {
            name: 'EPSG:3857',
          },
        },
        features: [{
          type: 'Feature',
          geometry: {
            type: 'Polygon',
            coordinates: [[[14.599609375, 16.9677734375], [21.6796875, 17.08984375], [21.6796875, 4.7607421875], [14.84375, 4.7607421875]]],
          },
          id: '007ABA46-7B0C-4F90-B6D4-8F6546363E',
          properties: { modelId: '2311', id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E', type: 'room' },
        },
        {
          type: 'Feature',
          geometry: {
            type: 'Polygon',
            coordinates: [[[21.5576171875, 17.08984375], [28.6376953125, 17.08984375], [28.515625, 5.0048828125], [21.5576171875, 5.126953125]]],
          },
          id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E',
          properties: { modelId: '2310', id: '007ABA46-7B0C-4F90-B6D4-8F6565EA2B2E', type: 'room' },
        },
        ],
      };
以上是geoJSON的内容,properties是可以给图层添加的一些参数,便于处理业务需要,type即指定feature的类型,这里是指定为多边形,coordinates为多边形的坐标

(new GeoJSON()).readFeatures(geojsonObject)//将GeoJSON转换成features

获取样式

主要是边框色,填充色以及填充的文本样式

//获取样式方法
//可将feature的数据传过来进行判断返回对应的样式
 const getStyles = (param) => {
        console.log(param);
        const style = new Style({
          stroke: new Stroke({//边框
            color: '#2d9fd8',
            width: 0,
          }),
          fill: new Fill({//填充色
            color: '#2d9fd8',
 			//color:[0, 11, 214, 0.5];0.5为透明度
          }),
          text: new Text({ // 文本样式
            className: 'map-font',
            font: '14px Microsoft YaHei',
            fill: new Fill({
              color: 'black',
            }),
          }),
        });
        if (param === '2311') {//对图层里的参数进行判断
          style.getStroke().setColor('#cccccc');
          style.getFill().setColor('#cccccc');
        }
        style.getText().setText(param);//可在图层上显示文本
        return style;
      };
      const styleFunction = (feature) => getStyles(feature.values_.modelId);//传入feature的参数

map添加vectorlayer

const vectorLayer = new VectorLayer({
        source: vectorSource,
        style: styleFunction,
        title: '',
        type: 'room',
      });

可以直接将vectorlayer在初始化时就塞进map里,也可以调用map的addLayer()方法

 this.map.addLayer(vectorLayer)

map添加选中交互事件,并添加选中后的样式

 // 选中之后的样式
      const selectSingleClick = new Select({
        style: new Style({
          stroke: new Stroke({
            color: '#2d9fd8',
            width: 0,
          }),
          fill: new Fill({
            color: [0, 11, 214, 0.5],
          }),
        }),
      });
	//map添加选中事件
      this.map.addInteraction(selectSingleClick);
      // 点击图层之后的处理
      selectSingleClick.on('select', (e) => {
        const features = e.target.getFeatures().getArray();
        if (features.length > 0) {
         const feature = features[0];//获取当前图层
         //const type = feature.getGeometry().getType();
         const property = feature.getProperties();//获取当前图层里的参数
         //const coordinate = getCenter(feature.getGeometry().getExtent());
          alert(property.modelId);//弹出框展示feature里properties里的modelId
        }
      });

效果展示

(因为不能泄露地图,所以就自己随便画了个丑丑的,将就看-><-)
在这里插入图片描述
可以看到只覆盖了两个图层,数字也是覆盖上去的
下面看点击之后的效果
在这里插入图片描述
选中后的图层显示为选中设置的样式,之前覆盖的字体没了,所以如果在选中之后也要显示字体的要在Select里重新添加文本

可以进https://github.com/Daizymis/Demo/tree/master/aap/src/components/roommap参考完整源码

Logo

前往低代码交流专区

更多推荐