跳至主要內容

框架编程思想

程序员李某某大约 6 分钟

框架编程思想

抽象框架知识

地图首先需要挂载到某个div 容器中,这是为了让用户自定义地图要素所要展示的实际尺寸大小。

其次地图通常可以设置一些基础底图,而且通常这些底图的格式都是栅格数据。

在国内我们通常使用的是天地图提供的栅格瓦片服务

另外地图可以添加一些业务图层,这些图层通常都是业务方提出,而且图层的数据类型和数据格式都是多样的,从数据类型讲可以有点线面甚至是体要素

从数据格式讲有栅格数据也有矢量数据,所以图层的种类是丰富多样的。这样看来,底图也算是一个特殊的图层了。只不过底图通常用于表示全局范围的,大面积要素下的参考地物

我们在加载这些业务图层的时候需要指定对应的数据源,在各个框架中几乎都是需要这样的操作,而且也都对数据源对象做了分类,大致分为栅格数据源和矢量数据源两大类,矢量数据源在maobox 中比较单一几乎就是指 geojson 数据源,但是在 openlayers 和 leaflet 等框架中可能还会支持kml、gml 等格式的数据源

除了地图的基础数据,对于地图的操作交互也是很重要的一部分。我们对于栅格数据的操作比较单一,基本上只能浏览,缩放,改变透明度,对比度,饱和度等属性。

对于矢量数据的操作交互通常比较丰富,一是能够灵活的修改矢量图层的样式,二是能够实时的跟矢量数据产生交互(点击查询、点击高亮等操作),因此对于矢量数据的操作是地图的主要操作部分

其次还有一些非地图本身所能承载的要素,但是需要和地图一起呈现。就比如在mapbox 的 dom 元素的使用。利用 dom 元素其实可以展示出各种丰富的地图效果

矢量样式高阶

说一个特别有意思但是容易被忽略的API——’line-blur’。这是用来模糊线条的,就是让线要素变得模糊,那正好我们可以利用这一点,既然可以模糊,是否可以考虑尝试渐变?是否以后在加载行政区图形的时候对其边界做一定的处理?能否形成阴影效果?能否形成发光效果?

const small = turf.transformScale(
  turf.polygon(huangshan.features[0].geometry.coordinates),
  0.97
);
map.addSource("huangshan-source", {
  type: "geojson",
  data: huangshan,
});
map.addSource("huangshan-small", {
  type: "geojson",
  data: small,
});
map.on("click", (e) => {
  map.addLayer({
    id: "haungshan-layer",
    type: "fill",
    source: "huangshan-source",
    paint: {
      "fill-color": "rgba(6, 248, 248, 0.2)",
    },
  });
  map.addLayer({
    id: "haungshan-line",
    type: "line",
    source: "huangshan-source",
    paint: {
      "line-color": "rgba(6, 248, 248, 1)",
      "line-width": 2,
    },
  });
  map.addLayer({
    id: "haungshan-inner",
    type: "line",
    source: "huangshan-small",
    paint: {
      "line-color": "rgba(6, 248, 248, 0.3)",
      "line-width": 18,
      "line-blur": 8,
    },
  });
});

图形运算

比如现在很多项目中要求只展示客户关心的区域的地图。比如说杭州市的项目,在页面上只需要展示杭州市的地图,其他区域不想展示,我们该如何来做?既然是只想看到本城市,其余的地方不关心,那是否可以把其余的地方抹掉?如果说我们有办法把其他的地方遮盖起来,这样也能达到相应的效果不是吗?因此我们一个非常关键且重要的图形运算技术——掩膜就诞生了。

如何遮盖成了目前最关键的问题,其实方式有很多种,我在这里给大家讲最常见的一种,那就是相交取反

世界的经纬度范围是[-180,-90,180,90],那么我们就可以把这个范围看作是一个矩形,如果我们用这个矩形和我们关心的城市图形数据做一个相交操作,再取除交集之外的部分,不就是我们需要的部分吗,我们再对这个相交取反的图形赋上一定的颜色就可以做到掩盖其余地图的功能。

实际的相交操作取反操作也有很多种办法,大家可以借助 turf.js 完成,或者直接将 geojson 数据和世界范围的[-180,-90,180,90]进行相交也可以,即将[-180,-90,180,90]直接丢进 geojson 数据的geometry 的coordinates 中即可,

实际上geojson记录多边形就是按照多边形的每个经纬度坐标来记录的,那么我们如果向数据中加入了[-180,-90,180,90]就意味着构建了一个新的多边形,多边形,以-180,90 开始,也是以-180,90 结束,那么就构成了一个凹多边形,这个多边形就是整个世界的范围,

turf.js

CDN链接

<!-- 使用unpkg -->
<script src="https://unpkg.com/@turf/turf/turf.min.js"></script>

<!-- 在BootCDN上下载指定版本 -->
<script src="https://www.bootcdn.cn/Turf.js/"></script>

指定主版本号:

<script src='https://unpkg.com/@turf/turf@6/turf.min.js'></script>
<script>
    var bbox = turf.bbox(features);
</script>

NPM下载

# 下载所有
npm install @turf/turf

# 下载知道模块
npm install @turf/collect @turf/buffer

页面引入

import * as turf from '@turf/turf'

import { lineString, along } from '@turf/turf'

参考文档

  • https://fenxianglu.cn/turfjs/category/

地图定位技巧

  1. 基于中心点和缩放层级来定位,也就是依靠center 参数和 zoom 参数来进行定位
mapboxgl.accessToken = mapboxtoken;
const map = new mapboxgl.Map({
    container: "map",
    center: [120.536363, 29.243242],
    zoom: 8,
    style: "",
});

这种定位发生在初始化地图的时候,这种定位的好处是能够高度自定义地图的缩放大小和中心位置。大家要注意地图的缩放层级不仅仅可以是整数哦,它还可以是小数,因此这种定位方式能够精准的控制地图的缩放层级和中心点。

  1. 根据数据的边界来进行定位,当你加载了矢量或者栅格图层的时候,希望定位到该图层,这时候你大概会使用一个跟 fit 相关的方法来定位,在 leaflet 和 mapbox 中都叫 fitBounds( ),而在openlayers中叫做 fit
const layer = L.geoJson(hangzhou);
layer.addTo(map);
map.fitBounds(layer.getBounds());

这种定位的好处是能够聚焦到图层,让图层主要的内容显示在浏览器上的核心区域,但是这种方式也有缺点,那就是很难调整具体的大小,虽然它能过将图层自适应在屏幕上,但是有的时候可能会过于大或者过于小,虽然简便,但是还是不推荐使用

上次编辑于:
贡献者: 李元昊