美文网首页
openlayers +GeoJSON 给不同的行政区显示不同的

openlayers +GeoJSON 给不同的行政区显示不同的

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

    1、效果

    普通效果


    image.png

    选中效果


    image.png

    2,初始化地图

      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
          })
    

    3、添加GeoJSON数据并给不同的行政区域添加颜色

    ···
    createStyle(feature,{
    textAlign="center",
    justify="center",
    areaFillColor='rgba(47, 209, 117, 0.3)',
    areaStrokeColor='#2FD175',
    textFillCOlor='#2FD175',
    textStrokeColor='#fff'}) {

        return new Style({
          fill:new Fill({
            color:feature.get('name')==='中原区'?'rgba(255,0,0,0.3)':areaFillColor
          }),
          stroke:new Stroke({
            color:feature.get('name')==='中原区'?'red':areaStrokeColor,
            width:2
          }),
          text: new Text({
            font: '16px  PingFang SC',
            textAlign,
            justify,
            text:feature.get('name'),
            fill: new Fill({
              color: feature.get('name')==='中原区'?'red':textFillCOlor,
            }),
            stroke:new Stroke({
              color:textStrokeColor,
              width:2
            }),
          }),
        });
      },
    

    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)
    

    ···

    5、给行政区域添加点击事件

    ···
    handlePolygon(){
    const polygonClick = new Select({
    style: this.setSelectStyle,
    });
    this.map.addInteraction(polygonClick);
    polygonClick.on('select',(e)=>{
    // console.log('点击',e.selected,e,e.target)
    this.$emit('click',e.selected,e)
    })
    },
    setSelectStyle(feature,{
    areaFillColor='rgba(47, 209, 117, 0.7)',
    areaStrokeColor='#2FD175',
    textAlign="center",
    justify="center",
    textFillCOlor='#2FD175',
    textStrokeColor='#fff'}) {
    let selected = new Style({
    fill: new Fill({
    color: areaFillColor,
    }),
    stroke: new Stroke({
    color: areaStrokeColor,
    width: 2,
    }),
    text: new Text({
    font: '16px PingFang SC',
    textAlign,
    justify,
    text:feature.get('name'),
    fill: new Fill({
    color: feature.get('name')==='中原区'?'red':textFillCOlor,
    }),
    stroke:new Stroke({
    color:textStrokeColor,
    width:2
    }),
    }),
    });
    return selected;
    },
    ···

    完整代码

    <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 {Projection} from 'ol/proj'
    // import TileLayer from 'ol/layer/Tile'
    // import OSM from 'ol/source/OSM'
    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 TopoJSON from 'ol/format/TopoJSON'
    
    import {
       Circle as CircleStyle,
      Fill,
      Stroke,
      Style,
      Text
    } from 'ol/style';
    export default {
      props:{
       
        defaultConfig:{
          type:Object,
          default:()=>{
            return{
              name:'',
              lat:null,
              lng:null,
              
            }
          }
        },
        styleConfig:{ // 地块颜色,文字设置
          type:Object,
          default:()=>{}
        },
        selectStyleConfig:{ // 选中地块颜色,文字样式设置
          type:Object,
          default:()=>{}
        }
      },
      data () {
        return {
          colors:['red','green','blue'],
          map: null,
          view: null,
          options: {
            zoom: 10,
            center: [113.570594, 34.829485]
          },
          point:[],
          geoJSonData: null, // 要绘制的区域
          iconFeature:null, // marks
          iconVectorLayer:null,//marks vectorLayer
          
          // styleSelectedDefaultConfig:{}, // 选中样式默认设置
        }
      },
      created(){
        if(this.defaultConfig?.lag&&this.defaultConfig?.lng){
          this.options.center = [this.defaultConfig?.lng,this.defaultConfig?.lag]
        }
    
      },
      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 = {}) {
          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
          })
          this.addGeoJson()
        
          // this.addTopoJson()
        },
        /**
         * 使用TopoJson
         */
        addTopoJson () {
          if (this.dynamicBboundary) {
            this.map.removeLayer(this.dynamicBboundary)
          }
          const features = new TopoJSON({
            featureProjection: 'EPSG:4326'
          }).readFeatures(this.geoJSonData)
          const source = new VectorSource({
            features
            // url: 'https://geo.datav.aliyun.com/areas_v3/bound/410000_full.json',
            // format: new GeoJSON()
          })
    
          this.dynamicBboundary = new VectorLayer({
            source: source,
            className: 'boundary',
            style: {
              'fill-color': 'rgba(255, 255, 255, 0.01)',
              'stroke-width': 5,
              'stroke-color': '#1469e9',
              'circle-radius': 5,
              'circle-fill-color': 'rgba(255, 255, 255, 0.6)',
              'circle-stroke-width': 1,
              'circle-stroke-color': '#319FD3'
            }
    
          })
          this.map.addLayer(this.dynamicBboundary)
          const feature = source.getFeatures()[0]
          const polygon = feature.getGeometry()
          console.log('polygon', polygon)
          this.view.fit(polygon, { padding: [170, 50, 30, 150] })
        },
        /**
         * 设置样式
         */
        createStyle(feature) {
          let styleConfig={
            textAlign:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.textAlign:this.styleDefaultConfig.textAlign,
            justify:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.justify:this.styleDefaultConfig.justify,
            areaFillColor:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.areaFillColor:this.styleDefaultConfig.areaFillColor,
            areaStrokeColor:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.areaStrokeColor:this.styleDefaultConfig.areaStrokeColor,
            textFillColor:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.textFillColor:this.styleDefaultConfig.textFillColor,
            textStrokeColor:feature.get('name')===this.selectStyleConfig.name?this.styleSelectedDefaultConfig.textStrokeColor:this.styleDefaultConfig.textStrokeColor
          }
            
        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 () {
          // const features = new GeoJSON({
          //   featureProjection: 'EPSG:4326'
          // }).readFeatures(this.henan)
          // const source = new VectorSource({
          //   features
          //   // url: 'https://geo.datav.aliyun.com/areas_v3/bound/410000_full.json',
          //   // 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)
          if(this.selectStyleConfig?.name){
            this.setLocationMark()
          }
          this.handlePolygon()
        },
        handlePolygon(){
          const polygonClick = new Select({
            style:  this.setSelectStyle,
          });
          this.map.addInteraction(polygonClick);
          polygonClick.on('select',(e)=>{
            this.point=e.selected[0].get('center')
            // console.log('point',this.point)
            this.setLocationMark()
            this.$emit('click',e.selected,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;
     
    }
    </style>
    
    

    相关文章

      网友评论

          本文标题:openlayers +GeoJSON 给不同的行政区显示不同的

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