Skip to content

渐变折线

使用 leaflet 、leaflet-hotline、vue 绘制渐变折线。

示例

安装依赖

shell
pnpm install leaflet-hotline

项目引入

js
import leafletHotline from 'leaflet-hotline';

// 注册插件
leafletHotline(L);

代码实现

vue
<script setup>
import { defineAsyncComponent, onMounted } from 'vue';
import leafletHotline from 'leaflet-hotline';
import geoJson from '../../public/geojson/gulou.json';

const InitMap = defineAsyncComponent(() =>
  import('../../components/InitMapTianditu.vue')
);

onMounted(() => {
  // 注册插件 todo 项目使用无需在 onMounted 中调用,这里是为了 vitePress 打包。
  leafletHotline(L);
});

function generateRandomNumber(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 创建渐变折线
const createGradientPolyline = async (map) => {
  const list = geoJson.features[0].geometry.coordinates[0][0];

  // 处理数据
  const listData = list.map((item) => [
    item[1],
    item[0],
    generateRandomNumber(100, 160)
  ]);

  // 配置项
  const options = {
    min: 100,
    max: 160,
    palette: {
      0.0: '#008800',
      0.5: '#ffff00',
      1.0: '#ff0000'
    },
    weight: 5,
    outlineColor: '#000000',
    outlineWidth: 1,
    smoothFactor: 1
  };

  // 加载到地图
  L.hotline([listData], options).addTo(map);
};

const mapLoad = (map) => {
  createGradientPolyline(map);
};
</script>

<template>
  <init-map @map-load="mapLoad"></init-map>
</template>

<style scoped></style>
vue
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
// todo 项目使用请放开 leaflet 引入
// import L from 'leaflet';

const props = defineProps({
  center: {
    type: Array,
    default: [32.0237855, 118.8075675]
  }
})

const emit = defineEmits(['mapLoad']);

const mapRef = ref();

const initMap = () => {
  const map = L.map(mapRef.value, {
    center: props.center,
    zoom: 11,
    minZoom: 6,
    maxZoom: 20
  });

  const mapType = 'vec';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      attribution:
        '&copy; <a href="http://lbs.tianditu.gov.cn/home.html">天地图 GS(2022)3124号 - 甲测资字1100471</a>'
    }
  ).addTo(map);

  const mapLabelType = 'cva';
  L.tileLayer(
    'https://t{s}.tianditu.gov.cn/' +
      mapLabelType +
      '_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
      mapLabelType +
      '&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
    {
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
    }
  ).addTo(map);

  // 地图初始化完成发送事件
  emit('mapLoad', map);

  return map;
};

const mapObj = ref();

// 在 onMounted 中初始化地图
onMounted(() => {
  mapObj.value = initMap();
});

const removeMap = () => {
  if (mapObj.value) {
    mapObj.value.remove();
  }
};

// 在组件卸载时删除地图
onUnmounted(() => {
  removeMap();
});
</script>

<template>
  <div ref="mapRef" class="map"></div>
</template>

<style scoped>
.map {
  height: 40vh;
  z-index: 0;
}
</style>
json
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"adcode":320106,"name":"鼓楼区","center":[118.769739,32.066966],"centroid":[118.760828,32.082331],"childrenNum":0,"level":"district","acroutes":[100000,320000,320100],"parent":{"adcode":320100}},"geometry":{"type":"MultiPolygon","coordinates":[[[[118.765692,32.132457],[118.760899,32.125978],[118.744907,32.115539],[118.74058,32.110198],[118.736654,32.105328],[118.726652,32.092952],[118.728885,32.090858],[118.730136,32.087028],[118.729215,32.081566],[118.728136,32.075364],[118.727648,32.068579],[118.727796,32.06464],[118.727048,32.060787],[118.723337,32.051232],[118.718702,32.042624],[118.724908,32.040642],[118.727418,32.039705],[118.724972,32.038741],[118.724274,32.038342],[118.723664,32.037784],[118.723208,32.037184],[118.722661,32.03634],[118.720217,32.032325],[118.720414,32.032302],[118.723428,32.031136],[118.725185,32.03053],[118.728518,32.029824],[118.731024,32.029412],[118.733622,32.029106],[118.73377,32.03179],[118.734328,32.03964],[118.73821,32.039629],[118.741522,32.039583],[118.742219,32.039503],[118.743252,32.039287],[118.744077,32.039174],[118.746118,32.038754],[118.746759,32.038738],[118.748984,32.038784],[118.750198,32.038639],[118.753747,32.037897],[118.755359,32.037675],[118.757234,32.037484],[118.757782,32.037498],[118.759622,32.038649],[118.762638,32.040596],[118.763632,32.04115],[118.763613,32.041246],[118.764736,32.04174],[118.766108,32.042491],[118.766845,32.042819],[118.767236,32.042895],[118.768034,32.042879],[118.769821,32.042715],[118.771712,32.042631],[118.776264,32.042326],[118.777517,32.042221],[118.784102,32.041767],[118.784118,32.043979],[118.784105,32.05555],[118.784116,32.058213],[118.784091,32.066431],[118.784079,32.073789],[118.784091,32.077642],[118.784065,32.078843],[118.784073,32.081248],[118.784065,32.088778],[118.78404,32.090089],[118.783824,32.091458],[118.784093,32.092269],[118.786244,32.091469],[118.789027,32.090514],[118.793473,32.088407],[118.793854,32.088348],[118.795371,32.08836],[118.796861,32.088448],[118.797217,32.088558],[118.797789,32.089117],[118.796733,32.090724],[118.796688,32.091372],[118.796827,32.091833],[118.798568,32.09269],[118.799036,32.092971],[118.799115,32.09324],[118.7989,32.094718],[118.798933,32.094887],[118.799774,32.095137],[118.799358,32.095989],[118.800641,32.096664],[118.80409,32.099279],[118.804022,32.099519],[118.802995,32.100114],[118.801932,32.100486],[118.800918,32.10105],[118.800762,32.104926],[118.799012,32.104776],[118.7987,32.104718],[118.798735,32.106055],[118.798908,32.106788],[118.799125,32.10742],[118.799525,32.10786],[118.79981,32.108318],[118.800243,32.109297],[118.801422,32.108928],[118.801561,32.109215],[118.802316,32.112953],[118.80261,32.113172],[118.803555,32.113318],[118.803944,32.11363],[118.804455,32.114637],[118.806136,32.119119],[118.806397,32.120064],[118.806336,32.120713],[118.805877,32.121429],[118.805946,32.12218],[118.80547,32.122667],[118.804821,32.122805],[118.804153,32.123354],[118.803312,32.124352],[118.803216,32.125113],[118.803287,32.125925],[118.803599,32.126646],[118.803573,32.126807],[118.802948,32.127294],[118.802403,32.127319],[118.801857,32.127121],[118.801033,32.126564],[118.800012,32.125405],[118.799551,32.125019],[118.798849,32.123319],[118.798329,32.122792],[118.797879,32.122509],[118.795755,32.121752],[118.793857,32.121913],[118.792981,32.122431],[118.792331,32.12412],[118.792097,32.125062],[118.791326,32.125948],[118.790434,32.126119],[118.789377,32.125476],[118.787078,32.121727],[118.785777,32.120934],[118.78439,32.120683],[118.781754,32.122886],[118.783029,32.123634],[118.783393,32.123596],[118.783784,32.123738],[118.784425,32.124107],[118.785713,32.124999],[118.787157,32.125745],[118.788194,32.126451],[118.786871,32.128133],[118.784334,32.127425],[118.783231,32.127639],[118.776482,32.129511],[118.765692,32.132457]]]]}}]}

options

options描述类型
min数据数组中预期的最小 z 值。这将映射到停止值 0。任何小于此值的 z 值在选择要使用的颜色时将被视为最小值。Number
max数据数组中预期的最大 z 值。这将映射到停止值 1。任何大于此值的 z 值在选择要使用的颜色时将被视为最大值。Number
palette渐变调色板的配置,格式为 { <stop>: '<color>' }。默认为 { 0.0: 'green', 0.5: 'yellow', 1.0: 'red' }。值应在 0 和 1 之间。Object
weight默认为 5,表示线条的宽度Number
outlineColor边界线的颜色。默认为 'black',不支持rgb、rgbaString
outlineWidth边界线的宽度,以像素为单位。可以为 0。默认为 1Number
smoothFactor线的平滑度Number

贡献者

Released under the MIT License.