A010:vue+openlayers中根据地图上的矢量地块定位


前言

提示:如果对操作流程还不熟悉的话,可以参考之前的文章 ,这些内容会帮助你更好地了解 OpenLayers 的功能点。我们会持续更新相关内容,如果你感兴趣或有这方面的需求,欢迎关注并收藏。


一、加载矢量的地块

mounted里面加载一个底图到地图上

const view = new View({
      projection: "EPSG:4326",
      center: [116.389, 39.903],
      zoom: 7,
    });
this.map = new Map({
      layers: [
      new TileLayer({
        source: new XYZ({
        url: "http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",
       }),
      })],
      target: "map",
      view: view,
 });

打开这个网址DataV.GeoAtlas地理小工具系列,可以获取各大地区的geojson文件。它提供了几种访问方式,可以通过网址在线获取,也可以直接把文件下下来放到项目里引用。
在这里插入图片描述
咱们点到北京市,直接复制在线地址。methods里面写一个方法addRegionLayer,定义一个矢量的source,把url写成我们刚刚复制的地址。110000表示的就是北京市,如果选择别的城市会发现编码不一样,其他都一样。

format属性是一个实例化的 GeoJSON 类。它告诉 OpenLayers 如何解析加载的数据。在这里,通过 new GeoJSON() 创建了一个 GeoJSON 格式解析器,这样 OpenLayers 就知道加载的数据是以 GeoJSON 格式编码的。(简单理解:固定写法,source里只要写了url,format就得写。加载geojson数据类型的矢量数据源时format就是 new GeoJSON())

addRegionLayer() {
     const source = new VectorSource({
        url: "https://geo.datav.aliyun.com/areas_v3/bound/110000_full.json",
        format: new GeoJSON(),
     });
     
 },

然后再把矢量的source放到矢量图层上,style里面是样式,stroke表示描边,fill表示填充。官网里写了一些circle圆形的样式,但是我们的地块都是多边形,所以不要circle相关的。style其实还有别的写法,这个咱们后面再说。

this.vectorLayer = new VectorLayer({
        source: source,
        style: {
          "fill-color": "rgba(255, 255, 255, 0.6)",
          "stroke-width": 2,
          "stroke-color": "#319FD9",
        },
      });

把图层加到地图上,看效果

this.map.addLayer(this.vectorLayer)

在这里插入图片描述

二、矢量地块定位

1.写三个按钮,定义一个fitTo方法分别传想要定位的区域名称

<div class="fitBox">
      <el-button type="primary" @click="fitTo('密云区')"
        >定位至密云区</el-button
      >
      <el-button type="primary" @click="fitTo('门头沟区')"
        >定位至门头沟区</el-button
      >
      <el-button type="primary" @click="fitTo('通州区')"
        >定位至通州区</el-button
      >
    </div>

2.methods里面定义一个fitTo方法,不知道的先来打印一下获取的features到底是个什么

fitTo(type) {
      const features = this.vectorLayer.getSource().getFeatures();
      console.log("features", features);
     
    },

可以看到一个数组里装了16个Feature类,数数北京市下面的地区刚好也是16个,由此可知,一个feature类就是一个地区多边形。
在这里插入图片描述
点开其中一个,可以看见很多属性,Feature其实就是一个描述地块属性的类,里面有很多属性代表不同的东西,可以理解为一个很大的对象。在values里可以看到geometry,geometry表示是一个几何对象,描述了要素的几何形状,它的属性值一般有点的坐标、线的路径、面的边界等。在 OpenLayers 中,几何对象可以是 Point点、LineString线、Polygon多边形、MultiPolygon多个多边形 等类型。
在这里插入图片描述
有一个name属性是区域名称,我们的思路就是循环遍历所有features找到我们想要定位到的地区的feature。getGeometry()就是获取了feature的几何形状,再使用fit方法进行定位。padding 参数是一个长度为 4 的数组,用于指定在适合指定几何对象时,地图视图周围的填充量。数组的四个值分别表示上、右、下、左四个方向的填充量(以像素为单位)。

features.forEach((v) => {
        if (v.get("name") == type) {
          const polygon = v.getGeometry();
          this.map.getView().fit(polygon, { padding: [170, 50, 30, 150] });
        }
      });

三、示例效果

在这里插入图片描述

四、完整代码

<template>
  <div class="box">
    <h1>Advanced Mapbox Vector Tiles</h1>
    <div id="map"></div>
    <div class="fitBox">
      <el-button type="primary" @click="fitTo('密云区')"
        >定位至密云区</el-button
      >
      <el-button type="primary" @click="fitTo('门头沟区')"
        >定位至门头沟区</el-button
      >
      <el-button type="primary" @click="fitTo('通州区')"
        >定位至通州区</el-button
      >
    </div>
  </div>
</template>
 
<script>
import GeoJSON from "ol/format/GeoJSON.js";
import Map from "ol/Map.js";
import View from "ol/View.js";
import { OSM, Vector as VectorSource, XYZ } from "ol/source.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
export default {
  name: "",
  components: {},
  data() {
    return {
      vectorLayer: null,
      map: null,
    };
  },
  computed: {},
  created() {},
  methods: {
    fitTo(type) {
      const features = this.vectorLayer.getSource().getFeatures();
      console.log("features", features);
      features.forEach((v) => {
        if (v.get("name") == type) {
          const polygon = v.getGeometry();
          this.map.getView().fit(polygon, { padding: [170, 50, 30, 150] });
        }
      });
    },
    addRegionLayer() {
      const source = new VectorSource({
        url: "https://geo.datav.aliyun.com/areas_v3/bound/110000_full.json",
        format: new GeoJSON(),
      });
      this.vectorLayer = new VectorLayer({
        source: source,
        style: {
          "fill-color": "rgba(255, 255, 255, 0.6)",
          "stroke-width": 2,
          "stroke-color": "#319FD9",
        },
      });
      this.map.addLayer(this.vectorLayer)
    },
  },
  mounted() {
    const view = new View({
      projection: "EPSG:4326",
      center: [116.389, 39.903],
      zoom: 7,
    });
    this.map = new Map({
      layers: [
        new TileLayer({
          source: new XYZ({
            url: "http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png",
          }),
        }),
      ],
      target: "map",
      view: view,
    });
    this.addRegionLayer()
  },
};
</script>
 
<style lang="scss" scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}
</style>
  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值