美文网首页
Openlayers 绘制返回的多边形点位

Openlayers 绘制返回的多边形点位

作者: 冰落寞成 | 来源:发表于2022-12-09 14:49 被阅读0次

页面显示效果

1670654364117.png

后端返回的数据格式如下

data:[{
      id:1,
      name:'土豆',
      geom:{
            type:"MultiPolygon",
              coordinates:[[[[113.2639026,35.002306639999986],[114.5236994172,35.002306639999986],[114.5236994172,34.151525541999995],[113.2639026,34.151525541999995],[113.2639026,35.002306639999986]]]]
          }
       },{
          id:2,
          name:'玉米',
          geom:{
            type:"MultiPolygon",
              coordinates:[[[[113.2639026,35.002306639999986],[114.5236994172,35.002306639999986],[114.5236994172,34.151525541999995],[113.2639026,34.151525541999995],[113.2639026,35.002306639999986]]]]
          }
    }]

整理数据成GeoJson 形式

let featureArr=[]
for(let i=0;i<data.length;i++){
    let json ={
        'type':"Feature",
         'properties':{
            name:data[i].name,
            id:data[i].id
          },
         'geometry':data[i]geom
        }
      featureArr.push(json)
}
 let FeatureCollection={ // Geojson 
        "type":"FeatureCollection",
        "features":featureArr
      }

添加GeoJSON,并绘制到地图上

    const features = new GeoJSON({
        featureProjection: 'EPSG:4326'
      }).readFeatures(FeatureCollection)
   const source = new VectorSource({
        features,
        format: new GeoJSON()
      })
   const vectorLayer = new VectorLayer({
        source: source,
        style:this.createStyle
      })
 this.map.addLayer(vectorLayer)

获取多边形的中线点

   let extent=boundingExtent(features.getGeometry().getCoordinates()[0][0])
  let centerPoint = getCenter(extent)

多边形添加点击事件

const polygonClick = new Select({
      style:  this.setSelectStyle, // 设置点击后的样式
      });
      this.map.addInteraction(polygonClick);
      polygonClick.on('select',(e)=>{
          console.log('pointe',e.selected[0])
          let features=e.selected[0]
          let extent=boundingExtent(features.getGeometry().getCoordinates()[0][0])
          let centerPoint = getCenter(extent)
        this.point=centerPoint;
      // console.log('point',point,center)
        this.setLocationMark() //  设置mark
        // this.$emit('click',e.selected,e)
      })

完整封装好的地图组件

<template>
<div class="page-container">
  
  <div class="map-container" ref="map"></div>
  </div>
</template>
<script>

import 'ol/ol.css'
import { Map, View, Feature } from 'ol'
import {boundingExtent,getCenter} from 'ol/extent';
import Point from 'ol/geom/Point'

import Select from 'ol/interaction/Select';
import {  Vector as VectorSource, } from 'ol/source'
import { Tile as TileLayer, Vector as VectorLayer, } from 'ol/layer'
import XYZ from 'ol/source/XYZ'
import GeoJSON from 'ol/format/GeoJSON'

import {
   Circle as CircleStyle,
  Fill,
  Stroke,
  Style,
  Text
} from 'ol/style';
export default {
  props:{
   
    defaultConfig:{
      type:Object,
      default:()=>{
        return{
          lat:null,
          lng:null,
          geomArr:[]
        }
      }
    },
    styleConfig:{ // 地块颜色,文字设置
      type:Object,
      default:()=>{}
    },
    selectStyleConfig:{ // 选中地块颜色,文字样式设置
      type:Object,
      default:()=>{}
    }
  },
  data () {
    return {
      colors:['red','green','blue'],
      map: null,
      view: null,
      options: {
        zoom: 6,
        center: [113.625351, 34.746303]
      },
      point:[],
      config:{
        center:[113.625351, 34.746303],
        zoom:14,
        geomArr:[]
      }, // 设置项
      iconFeature:null, // marks
      iconVectorLayer:null,//marks vectorLayer
      
      // styleSelectedDefaultConfig:{}, // 选中样式默认设置
    }
  },
  created(){
    if(this.defaultConfig?.lat&&this.defaultConfig?.lng){
      this.options.center = [parseFloat(this.defaultConfig?.lng),parseFloat(this.defaultConfig?.lat)]
    }
  },
  computed:{
    styleDefaultConfig:{ // 地块样式默认设置
      get(){
        return{
          textAlign:this.styleConfig?.textAlign||"center",
          justify:this.styleConfig?.justify||"center",
          areaFillColor:this.styleConfig?.areaFillColor||'rgba(47, 209, 117, 0.3)',
          areaStrokeColor:this.styleConfig?.areaStrokeColor||'#2FD175',
          textFillColor:this.styleConfig?.textFillColor||'#2FD175',
          textStrokeColor:this.styleConfig?.textStrokeColor||'#fff'
        }
      },
      set(){}
    },
    styleSelectedDefaultConfig:{
      get(){
        return{
          textAlign:this.selectStyleConfig?.textAlign||"center",
          justify:this.selectStyleConfig?.justify||"center",
          areaFillColor:this.selectStyleConfig?.areaFillColor||'rgba(47, 209, 117, 0.7)',
          areaStrokeColor:this.selectStyleConfig?.areaStrokeColor||'#2FD175',
          textFillColor:this.selectStyleConfig?.textFillColor||'#2FD175',
          textStrokeColor:this.selectStyleConfig?.textStrokeColor||'#fff',
        }
      },
      set(){

      }
    }
  },
  mounted () {
    this.point =this.options.center || [113.625351, 34.746303]
    this.initMap(this.options)
    
  },
  methods: {
    /**
     * 初始化地图
     */
    initMap (options = {}) {
      // console.log('ss',options.center )
      this.view = new View({
        projection: 'EPSG:4326',
        center: options.center || [113.625351, 34.746303], // 郑州
        zoom: options.zoom || 12
      })
      
      this.map = new Map({
        target: this.$refs.map,
        layers: [
          new TileLayer({
            title: '网格',
            source: new XYZ({
              visible: true,
              wrapX: true,
              url: 地图地库路径
            })
          })

        ],
        view: this.view
      })
    },
    /**
     * 设置config
     */
      setConfigDatas(config){
        // console.log('setConfigDatas')
        if(config.lng&&config.lat){
          this.config.center=[config.lng,config.lat]
        }
        this.config.zoom=config.zoom||this.options.zoom
        this.config.geomArr = config.geomArr||[]
        // console.log('this.config.geomArr',this.config.geomArr)
        if(this.config.geomArr.length>0){
          this.addGeoJson()
        }
      },
    /**
     * 设置样式
     */
    createStyle(feature) {
      let styleConfig={
        textAlign:feature.get('active')?this.styleSelectedDefaultConfig.textAlign:this.styleDefaultConfig.textAlign,
        justify:feature.get('active')?this.styleSelectedDefaultConfig.justify:this.styleDefaultConfig.justify,
        areaFillColor:feature.get('active')?this.styleSelectedDefaultConfig.areaFillColor:this.styleDefaultConfig.areaFillColor,
        areaStrokeColor:feature.get('active')?this.styleSelectedDefaultConfig.areaStrokeColor:this.styleDefaultConfig.areaStrokeColor,
        textFillColor:feature.get('active')?this.styleSelectedDefaultConfig.textFillColor:this.styleDefaultConfig.textFillColor,
        textStrokeColor:feature.get('active')?this.styleSelectedDefaultConfig.textStrokeColor:this.styleDefaultConfig.textStrokeColor
      }
        // console.log(styleConfig)
      return new Style({
        fill:new Fill({
          color:styleConfig.areaFillColor
        }),
        stroke:new Stroke({
          color:styleConfig.areaStrokeColor,
          width:2
        }),
        text: new Text({
          font: '16px  PingFang SC',
          textAlign:styleConfig.textAlign,
          justify:styleConfig.justify,
          text:feature.get('name'),
          fill: new Fill({
            color: styleConfig.textFillCOlor,
          }),
          stroke:new Stroke({
            color:styleConfig.textStrokeColor,
            width:2
          }),
        }),
      });
  },

    /**
     *设置选中的样式
    */
    setSelectStyle(feature) {
       return new Style({
      fill:new Fill({
        color:this.styleSelectedDefaultConfig.areaFillColor
      }),
      stroke:new Stroke({
        color:this.styleSelectedDefaultConfig.areaStrokeColor,
        width:2
      }),
      text: new Text({
        font: '16px  PingFang SC',
        textAlign:this.styleSelectedDefaultConfig.textAlign,
        justify:this.styleSelectedDefaultConfig.justify,
        text:feature.get('name'),
        fill: new Fill({
          color: this.styleSelectedDefaultConfig.textFillCOlor,
        }),
        stroke:new Stroke({
          color:this.styleSelectedDefaultConfig.textStrokeColor,
          width:2
        }),
      }),
    });
    },
    /**
     * 添加geoGson 数据
     */
    addGeoJson () {
      console.log('addGeoJson',this.config)
      let arr = this.config.geomArr
      let featureArr=[]
      console.log('arr',arr,arr.length)
      for(let i=0;i<arr.length;i++){
        let json ={
          'type':"Feature",
          'properties':{
            name:arr[i]?.properties?.name,
            active:arr[i]?.properties?.active
          },
          'geometry':JSON.parse(arr[i]?.geom)
        }
        featureArr.push(json)
        if(arr[i].active){
          this.point=this.config.center
        }
      }
     
      let FeatureCollection={
        "type":"FeatureCollection",
        "features":featureArr
      }
      const features = new GeoJSON({
        featureProjection: 'EPSG:4326'
      }).readFeatures(FeatureCollection)
      
      const source = new VectorSource({
        features,
        
        format: new GeoJSON()
      })
       
      // const source = new VectorSource({
      //   url:'https://geo.datav.aliyun.com/areas_v3/bound/410100_full.json',
        
      //   format: new GeoJSON()
      // })

      const vectorLayer = new VectorLayer({
        source: source,
        style:this.createStyle
      })
      this.map.addLayer(vectorLayer)
      this.setLocationMark()
      this.handlePolygon()
    },
    handlePolygon(){
      const polygonClick = new Select({
        style:  this.setSelectStyle,
      });
      this.map.addInteraction(polygonClick);
      polygonClick.on('select',(e)=>{
          console.log('pointe',e.selected[0])
          let features=e.selected[0]
          let extent=boundingExtent(features.getGeometry().getCoordinates()[0][0])
          let centerPoint = getCenter(extent)
        this.point=centerPoint;
      // console.log('point',point,center)
        this.setLocationMark()
        // this.$emit('click',features.getProperties(),e)
      })
    },
  
    setLocationMark(){
    
      if(this.iconVectorLayer){
        
        this.map.removeLayer(this.iconVectorLayer)
        this.iconVectorLayer=null
        // return false
      }
      this.iconFeature = new Feature({
        geometry: new Point(this.point),
        // name: 'Null Island',
        // population: 4000,
        // rainfall: 500,
        
      });
      const iconStyle1 = new Style({

        image: new CircleStyle({
          radius: 8,
          fill: new Fill({color: '#2FD175'}),
          stroke: new Stroke({color: '#fff', width: 3}),
          size:[16,16]
        }),


      });
      
      this.iconFeature.setStyle(iconStyle1);
      const vectorSource = new VectorSource({
        features: [this.iconFeature],
      });

      this.iconVectorLayer = new VectorLayer({
        source: vectorSource,
      });
      this.map.addLayer(this.iconVectorLayer)
    }
  }
}
</script>
<style lang="scss" scoped>
.map-container {
  width: 100%;
  height: 800px;
  .mark{
    width: 100px;
    height: 100px;
    background: red;
  }
}
</style>

相关文章

网友评论

      本文标题:Openlayers 绘制返回的多边形点位

      本文链接:https://www.haomeiwen.com/subject/jjvzfdtx.html