Leaflat迷你小地球仪

本文介绍如何使用leaflet-globeminimap库在地图中添加一个迷你地球仪,并展示了代码示例,包括初始化、地图投影和交互控制。通过自定义选项,可以调整迷你地图的样式和行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、效果展示

在这里插入图片描述

二、代码


// L, d3, topojson
import * as L from "leaflet";
import * as d3 from "d3";
import * as topojson from "topojson";
import { wordJson } from "./world";

L.Control.GlobeMiniMap = L.Control.extend({
  options: {
    position: "bottomleft",
    width: 82,
    height: 82,
    land: "#bbb",
    water: "rgba(0, 0, 0, 0.3)",
    marker: "#CC0000",
    topojsonSrc: wordJson,
  },

  //layer is the map layer to be shown in the minimap
  initialize: function (options) {
    L.Util.setOptions(this, options);
  },

  onAdd: function (map) {
    this._mainMap = map;

    //Creating the container and stopping events from spilling through to the main map.
    this._container = L.DomUtil.create("div", "leaflet-control-minimap");
    this._container.style.width = this.options.width + "px";
    this._container.style.height = this.options.height + "px";

    L.DomEvent.disableClickPropagation(this._container);
    L.DomEvent.on(this._container, "mousewheel", L.DomEvent.stopPropagation);

    //Keep a record of this to prevent auto toggling when the user explicitly doesn't want it.
    this._userToggledDisplay = false;
    this._minimized = false;

    this._mainMap.on("moveend", this._onMainMapMoved, this);

    return this._container;
  },

  addTo: function (map) {
    L.Control.prototype.addTo.call(this, map);
    this.initCanvas();

    return this;
  },

  initCanvas: function () {
    //marker icon
    //https://upload.wikimedia.org/wikipedia/commons/9/93/Map_marker_font_awesome.svg

    d3.select(".leaflet-control-minimap")
      .append("svg")
      .attr("width", 82)
      .attr("height", 82)
      .attr("style", "position: absolute; left: 0; top: 0;")
      .append("path")
      .attr(
        "d",
        "m 768,896 q 0,106 -75,181 -75,75 -181,75 -106,0 -181,-75 -75,-75 -75,-181 0,-106 75,-181 75,-75 181,-75 106,0 181,75 75,75 75,181 z m 256,0 q 0,-109 -33,-179 L 627,-57 q -16,-33 -47.5,-52 -31.5,-19 -67.5,-19 -36,0 -67.5,19 Q 413,-90 398,-57 L 33,717 Q 0,787 0,896 q 0,212 150,362 150,150 362,150 212,0 362,-150 150,-150 150,-362 z"
      )
      .attr("transform", "scale(.01,-.01),translate(3600,-3900)")
      .attr("style", "fill:" + this.options.marker);

    this.projection = d3.geo
      .orthographic()
      .scale(40)
      .translate([41, 41])
      .rotate([0, 0])
      .clipAngle(90);

    var canvas = d3
      .select(".leaflet-control-minimap")
      .append("canvas")
      .attr("width", 400)
      .attr("height", 400);

    this.c = canvas.node().getContext("2d");

    this.path = d3.geo.path().projection(this.projection).context(this.c);

    var that = this;
    d3.json(this.options.topojsonSrc, function () {
      const world = wordJson;
      that.globe = { type: "Sphere" };
      that.land = topojson.feature(world, world.objects.land);
    });

    //set to current view
    this.transitionMap(this._mainMap.getCenter());
  },

  transitionMap: function (p) {
    var that = this;
    var c = that.c;
    var path = that.path;
    d3.transition()
      .duration(1250)
      .each("start", function () {})
      .tween("rotate", function () {
        var r = d3.interpolate(that.projection.rotate(), [-p.lng, -p.lat]);
        return function (t) {
          that.projection.rotate(r(t));
          c.clearRect(0, 0, that.options.width, that.options.height);
          c.fillStyle = that.options.water;
          c.beginPath();
          path(that.globe);
          c.fill();
          c.fillStyle = that.options.land;
          c.beginPath();
          path(that.land);
          c.fill();
        };
      });
  },

  onRemove: function (map) {
    this._mainMap.off("moveend", this._onMainMapMoved, this);
    this._mainMap.off("move", this._onMainMapMoving, this);
  },

  _onMainMapMoved: function (e) {
    if (!this._miniMapMoving) {
      this._mainMapMoving = true;

      this.transitionMap(this._mainMap.getCenter());
    } else {
      this._miniMapMoving = false;
    }
  },
});

L.control.globeminimap = function (layer, options) {
  return new L.Control.GlobeMiniMap(layer, options);
};

L.Map.mergeOptions({
  miniMapControl: false,
});

export default L;


  • 地图引用
import L from "./leaflet-globeminimap";

// 构建地图
const map = L.map(ID, {
  zoomControl: false,
  maxBounds: bounds,
  // 西安坐标
  center: [34, 108],
  maxZoom: 21,
  minZoom: 4,
  zoom: 4,
});

// 添加了一个迷你地球仪
new L.Control.GlobeMiniMap({
  land: "#94cf6a",
  water: "#3972f7",
  marker: "#e44131",
}).addTo(map);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值