react项目使用@antv/l7实现展示地图可视化

官网文档:https://l7.antv.antgroup.com/tutorial/quickstart

安装依赖

// 安装L7 依赖
npm install --save @antv/l7
// 安装第三方底图依赖
npm install --save @antv/l7-maps

初步实现

src\pages\Map\china.tsx

import { Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import { useEffect } from 'react';
export default function IndexPage() {

  useEffect(() => {
    const scene = new Scene({
      id: 'map',
      map: new GaodeMap({
        style: 'dark',
        pitch: 35.210526315789465,
        zoom: 4.4
      }),
    });
  }, [])

  return (
    <div className="map-china" style={{ margin: 20 }}>
      <div
        id='map'
        style={{ height: 500, width: 800, position: 'relative', justifyContent: 'center' }}
      >
      </div>
    </div>
  );
}

在这里插入图片描述

显示模型

地图数据

https://gw.alipayobjects.com/os/bmw-prod/d6da7ac1-8b4f-4a55-93ea-e81aa08f0cf3.json

在这里插入图片描述

import { PolygonLayer, Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import { useEffect } from 'react';
import data from '../../mock/geo.json';

export default function IndexPage() {
  useEffect(() => {
    const scene = new Scene({
      id: 'map',
      map: new GaodeMap({
        style: 'dark',
        pitch: 35.210526315789465,
        zoom: 4.4
      }),
    });

    // 使用面图层来绘制行政区划数据
    const chinaPolygonLayer = new PolygonLayer({
      autoFit: true
    })
      .source(data)
      .color('name', [
        'rgb(239,243,255)',
        'rgb(189,215,231)',
        'rgb(107,174,214)',
        'rgb(49,130,189)',
        'rgb(8,81,156)'
      ]).shape("fill").style({
        opacity: 1
      })
  //将其添加到 Scene 中进行显示
    scene.addLayer(chinaPolygonLayer)

  }, [])

  return (
    <div className="map-china" style={{ margin: 20 }}>
      <div
        id='map'
        style={{ height: 500, width: 800, position: 'relative', justifyContent: 'center' }}
      >
      </div>
    </div>
  );
}

在这里插入图片描述

使用 LineLayer 和 PointLayer 增加行政区划描边和行政区划文字标注

数据地址

https://gw.alipayobjects.com/os/bmw-prod/c4a6aa9d-8923-4193-a695-455fd8f6638c.json

在这里插入图片描述

标签文本香港和澳门的位置有点出入,json数据可下载下拉修改一下

  { "name": "香港", "center": [114.173355, 22.328951] },
  { "name": "澳门", "center": [113.54909, 22.198951] }

import { LineLayer, PointLayer, PolygonLayer, Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import { useEffect } from 'react';
import data from '../../mock/geo.json';
import dataPoint from '../../mock/point.json';

export default function IndexPage() {

  useEffect(() => {
    const scene = new Scene({
      id: 'map',
      map: new GaodeMap({
        style: 'dark',
        pitch: 35.210526315789465,
        zoom: 4.4
      }),
    });

    const chinaPolygonLayer = new PolygonLayer({
      autoFit: true
    })
      .source(data)
      .color('name', [
        'rgb(239,243,255)',
        'rgb(189,215,231)',
        'rgb(107,174,214)',
        'rgb(49,130,189)',
        'rgb(8,81,156)'
      ]).shape("fill").style({
        opacity: 1
      })

    //  图层边界
    const layer2 = new LineLayer({
      zIndex: 2
    })
      .source(data)
      .color("rgb(93,112,146)")
      .size(0.6)
      .style({
        opacity: 1
      });
    scene.addLayer(chinaPolygonLayer)
    scene.addLayer(layer2);

    const labelLayer = new PointLayer({
      zIndex: 5
    })
      .source(dataPoint, {
        parser: {
          type: "json",
          coordinates: "center"
        }
      })
      .color("#fff")
      .shape("name", "text")
      .size(12)
      .style({
        opacity: 1,
        stroke: "#fff",
        strokeWidth: 0,
        padding: [5, 5],
        textAllowOverlap: false
      });

    scene.addLayer(labelLayer);

  }, [])

  return (
    <div className="map-china" style={{ margin: 20 }}>
      <div
        id='map'
        style={{ height: 500, width: 800, position: 'relative', justifyContent: 'center' }}
      >
      </div>
    </div>
  );
}

在这里插入图片描述

PolygonLayer关于绘制图形的类型

  • shape 为 fill 几何图层用于绘制平面的几何图形。
  • shape 为extrude几何图层用于绘制 3D 的几何体。

fill类型

const chinaPolygonLayer = new PolygonLayer({
  autoFit: false, //layer 初始化完成之后,地图是否自动缩放到图层范围, 默认false
})
  .source(data)//几何体图层数据推荐使用 GeoJSON 格式的数据
  .color('name', [
    'rgb(239,243,255)',
    'rgb(189,215,231)',
    'rgb(107,174,214)',
    'rgb(49,130,189)',
    'rgb(8,81,156)'
  ])
  .shape("fill")
  .style({
    opacity: 1
  })

在这里插入图片描述

extrude类型

const chinaPolygonLayer = new PolygonLayer({
  autoFit: false, //layer 初始化完成之后,地图是否自动缩放到图层范围, 默认false
})
  .source(data)//几何体图层数据推荐使用 GeoJSON 格式的数据
  .color('name', [
    'rgb(239,243,255)',
    'rgb(189,215,231)',
    'rgb(107,174,214)',
    'rgb(49,130,189)',
    'rgb(8,81,156)'
  ])
  .shape("extrude")
  .style({
    opacity: 1
  })

在这里插入图片描述

Scene

export interface ISceneConfig extends IRenderConfig {
    id: string | HTMLDivElement;//需传入 dom 容器或者容器 id。
    canvas?: HTMLCanvasElement;
    gl?: any;
    hasBaseMap?: boolean;
    map: IMapWrapper;
    logoPosition?: PositionName;//提供的 Logo 可以配置显示位置,默认在左下角。
    logoVisible?: boolean;//logo 是否可见
    isMini?: boolean;
    animate?: boolean;
    fitBoundsOptions?: unknown;
    pickBufferScale?: number;
    stencil?: boolean;
    debug?: boolean;
}
const scene = new Scene({
  id: 'map',
  map: new GaodeMap({
    style: 'dark',//地图样式,可选dark,light, normal, blank无底图
    pitch: 35.210526315789465,//地图倾角
    // center: [], //地图中心
    zoom: 3.3, //地图缩放
  }),
});

在这里插入图片描述

const scene = new Scene({
  id: 'map',
  map: new GaodeMap({
    style: 'blank',//地图样式,可选dark,light, normal, blank无底图
    pitch: 35.210526315789465,//地图倾角
    // center: [], //地图中心
    zoom: 3.3, //地图缩放
  }),
});

在这里插入图片描述

const scene = new Scene({
  id: 'map',
  map: new GaodeMap({
    style: 'light',//地图样式,可选dark,light, normal, blank无底图
    pitch: 35.210526315789465,//地图倾角
    // center: [], //地图中心
    zoom: 3.3, //地图缩放
  }),
});

在这里插入图片描述

const scene = new Scene({
  id: 'map',
  map: new GaodeMap({
    style: 'normal',//地图样式,可选dark,light, normal, blank无底图
    pitch: 35.210526315789465,//地图倾角
    // center: [], //地图中心
    zoom: 3.3, //地图缩放
  }),
});

在这里插入图片描述

设置左边下logo不可见

const scene = new Scene({
  id: 'map',
  map: new GaodeMap({
    style: 'dark',//地图样式,可选dark,light, normal, blank无底图
    pitch: 35.210526315789465,//地图倾角
    // center: [], //地图中心
    zoom: 3.3, //地图缩放
    
  }),
  logoVisible: false
});

在这里插入图片描述

鼠标移动区域高亮效果

active(option: IActiveOption | boolean): ILayer;

export interface IActiveOption {
    color: string | number[];
    mix?: number;
}

默认状态高亮

chinaPolygonLayer.active(true) //  开启默认高亮效果

自定义

chinaPolygonLayer.active({
  color: '#888'
})

在这里插入图片描述

chinaPolygonLayer.active({
  color: '#888',
  mix: 0.5
})

在这里插入图片描述

点击地图区域高亮设置

const hightLayer = new LineLayer({
  zIndex: 4, // 设置显示层级
  name: 'hightlight'
}) .source({
    type: 'FeatureCollection',
    features: [ ]
  })
  .shape('line')
  .size(6)
  .color('red');
scene.addLayer(hightLayer);
chinaPolygonLayer.on('click', feature => {
  hightLayer.setData({
    type: 'FeatureCollection',
    features: [ feature.feature ]
  });
});

在这里插入图片描述

鼠标悬浮监听弹窗显示信息

export interface IPopupOption {
    /**
     * 是否展示关闭按钮
     */
    closeButton: boolean;
    /**
     * 关闭按钮距离右上角的偏移
     */
    closeButtonOffsets?: [number, number];
    /**
     * 点击地图区域是否关闭弹框
     */
    closeOnClick: boolean;
    /**
     * 按 Esc 键是否关闭弹框
     */
    closeOnEsc: boolean;
    /**
     * 气泡体的最大宽度
     */
    maxWidth: string;
    /**
     * 气泡
     */
    anchor: anchorType[any];
    /**
     * 气泡相对偏移
     */
    offsets: [number, number];
    /**
     * 气泡上的所有鼠标事件是否关闭事件冒泡
     */
    stopPropagation: boolean;
    /**
     * popup 位置发生变化时地图是否自动平移至气泡位置
     */
    autoPan: boolean;
    /**
     * 展示其他气泡时,当前气泡是否自动关闭
     */
    autoClose: boolean;
    /**
     * 当前气泡是否自动跟随光标
     */
    followCursor: boolean;
    /**
     * 自定义气泡容器的 class
     */
    className?: string;
    /**
     * 自定义气泡容器的 style
     */
    style?: string;
    /**
     * Popup 气泡的内置文本
     */
    text?: string;
    /**
     * Popup 气泡的内置HTML
     */
    html?: DOM.ElementType;
    /**
     * Popup 气泡的标题
     */
    title?: DOM.ElementType;
    /**
     * 初始的经纬度位置
     */
    lngLat?: ILngLat;
}
export interface IPopup extends EventEmitter {
    addTo(scene: Container): this;
    remove(): void;
    setLnglat(lngLat: ILngLat): this;
    getLnglat(): ILngLat;
    setHTML(html: DOM.ElementType): this;
    setText(text: string): this;
    setMaxWidth(maxWidth: string): this;
    isOpen(): boolean;
    open(): this;
    close(): this;
    getOptions(): IPopupOption;
    setOptions(option: Partial<IPopupOption>): this;
}
chinaPolygonLayer.on('mousemove', e => {
  const popup = new Popup({
    offsets: [ 0, 0 ],
    closeButton: false
  })
  .setLnglat(e.lngLat)
  .setHTML(`<span>地区: ${e.feature.properties.name}</span><br><span>编码: ${e.feature.properties.adcode}</span>`);
  scene.addPopup(popup);
  });

在这里插入图片描述

添加图例,目前图例颜色与地图并不一致

const legend = new Control({
  position: "bottomright"
});

const color: string[] = ['#fbfbee', '#f4f8d1', '#dbedcc', '#b1d8ce', '#87cad0', '#75b0ce', '#6d90bd']

legend.onAdd = function () {
  var el = document.createElement("div");
  el.className = "infolegend legend";
  var grades = [0, 10, 20, 50, 100, 200, 500];
  for (var i = 0; i < grades.length; i++) {
    el.innerHTML +=
      '<div class="item"><i style="background:' + color[i] + '"></i> <span class="text">' + grades[i] +
      (grades[i + 1] ? "–" + grades[i + 1] + "</span></div>" : "+");
  }
  return el;
};

scene.addControl(legend)
.infolegend {
  background-color: aliceblue;
  padding-right: 20px;
  border-radius: 6px;

  .item {
    height: 20px;
    line-height: 20px;
    margin-top: 2px;
    margin-bottom: 6px;

    i {
      width: 20px;
      height: 20px;
      display: inline-block;
      margin-left: 10px;
    }

    .text {
      display: inline-block;
      position: relative;
      top: -4px;
      margin-left: 6px;
    }
  }

}

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值