Leaflet使用SVG创建动态Legend

接前一篇文章,前一篇文章我们使用 SVG 创建了带有动态文字的图标,今天再看看怎样在地图上根据动态图标生成相关的legend,当然这里也还是使用了 SVG 来生成相关颜色的 legend。

看下面的代码,生成了一个 svg 节点,其中包含了一个带有颜色的圆形图标和一个文字说明。

private generateLegend(name: string, color: string): string {
  return `<svg
            version="1.2"
            baseProfile="tiny"
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            viewBox="0 0 30 30"
        >
            <circle cx="20" cy="20" r="10" fill="${color}" />
        </svg><span style="margin-left: 4px;">${name}</span>`;
}

完整的 map.component.ts 文件如下,其它代码参考前一篇文章。

import { Component, OnInit, AfterViewInit } from "@angular/core";
import * as leaflet from "leaflet";

@Component({
  selector: "app-map",
  templateUrl: "./map.component.html",
  styleUrls: ["./map.component.css"],
})
export class MapComponent implements OnInit, AfterViewInit {
  map!: leaflet.Map;
  constructor() {}

  ngOnInit(): void {}

  ngAfterViewInit(): void {
    this.initMap();
  }

  private initMap(): void {
    this.map = leaflet.map("map").setView([51.5, -0.09], 13);

    const tiles = leaflet.tileLayer(
      "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
      {
        maxZoom: 19,
        attribution:
          '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
      },
    );
    tiles.addTo(this.map);

    const clients = [
      { name: "Client A", lat: 51.5, lng: -0.09, value: 7, color: "red" },
      { name: "Client B", lat: 51.5, lng: -0.07, value: 7, color: "blue" },
      { name: "Client C", lat: 51.5, lng: -0.11, value: 7, color: "green" },
    ];

    clients.forEach((client) => {
      this.generateMarker(client.lat, client.lng, client.value, client.color);
    });

    const generateLegend = this.generateLegend;
    const legend = leaflet.control.scale({ position: "bottomleft" });
    legend.onAdd = function () {
      const div = leaflet.DomUtil.create("div", "info");
      let html = `<div style="width: 80px; height: 80px; background-color: lightgray;">`;
      html += `<strong>Categories</strong><br/>`;
      clients.forEach((client) => {
        html += generateLegend(client.name, client.color) + "<br/>";
      });
      html += `</div>`;
      div.innerHTML = html;
      return div;
    };
    legend.addTo(this.map);
  }

  private generateMarker(
    lat: number,
    lng: number,
    value: number,
    color: string,
  ) {
    const circleSVGHtml = `<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" width="250" height="250">
                    <circle cx="125" cy="125" r="100" fill="${color}"/>
                    <text x="50%" y="50%" text-anchor="middle" fill="white" font-size="100px" font-family="Arial" dy=".2em">
                    ${value}
                    </text>
                </svg>`;
    const iconURL = "data:image/svg+xml," + encodeURIComponent(circleSVGHtml);
    const circleIcon = leaflet.icon({
      iconUrl: iconURL,
      iconSize: [30, 30],
    });
    const marker = leaflet
      .marker([lat, lng], { icon: circleIcon })
      .addTo(this.map);
    return marker;
  }

  private generateLegend(name: string, color: string): string {
    return `<svg
            version="1.2"
            baseProfile="tiny"
            xmlns="http://www.w3.org/2000/svg"
            width="16"
            height="16"
            viewBox="0 0 30 30"
        >
            <circle cx="20" cy="20" r="10" fill="${color}" />
        </svg><span style="margin-left: 4px;">${name}</span>`;
  }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容