react-leaflet的github地址:https://github.com/PaulLeCam/react-leaflet

react-leaflet-markercluster点聚合github地址  :https://github.com/YUzhva/react-leaflet-markercluster

本篇案例github地址:https://github.com/GugaLiz/ant-design-react-ProDemo

一、react-leaflet显示多个marker点并显示多行popup

1.注意点:安装leaflet。  命令:npm install leaflet

2.装好环境以后这里有两个难点,①marker图标重新引入。②popup多行显示。

因为之前有踩过vue结合leaflet的坑、所以第一个问题这次跟vue里面重新引用图标一样解决了。第二个问题其实也不难、就是要灵活一点去试吧。因为官方文档没有写这种情况,只是很简单的示例。我先着重贴一下解决方案的代码、后面有整体代码结合理解。最后有我自己整理的github链接可以方便在实际开发中参考。

效果:

①。解决marker图标重新引入,第一import Leaflet,第二把leaflet模块中的markers文件夹复制到src路径下的asset静态资源文件夹中,第三重新引入图标。

import L from 'leaflet';   //引入leaflet
import { Map, TileLayer,Marker,Popup } from 'react-leaflet';
import "leaflet/dist/leaflet.css";
//把图标重新引入
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.imagePath = ''
L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('../../assets/markers/marker-icon-2x.png'),
  iconUrl: require('../../assets/markers/marker-icon.png'),
  shadowUrl: require('../../assets/markers/marker-shadow.png')
})

②。解决第二问题,第一把每一个marker需要多行显示的popup的每一行都做成一个obj,这样在第二步进行处理的时候就可以分开与样式融合到一起。第二步处理popup

//处理popup的内容

let popupContent = [{key:city,string:`城市:${city}`},
{key:name,string:`基站名称:${name}`},
{key:lng,string:`经度:${lng}`},
{key:lat,string:`纬度:${lat}`},
{key:district,string:`地区:${district}`},
{key:address,string:`地址:${address}`},
{key:maintainer,string:`维护人员:${maintainer}`},
]
//处理popup的显示
const PopupMarker = ({ children,position }) => {
const items = children.map((item) => (<span key={item.key}>{item.string}<br /></span>))   //把每一行要显示的数据与样式融合为一个item方便调用显示
return <Marker position={position}>
<Popup><div>
{items}
</div></Popup>
</Marker>
}

整体代码参上:

import React, { PureComponent, Fragment } from 'react';
import { render } from 'react-dom';import { connect } from 'dva';
import { Row, Col, Card, Tooltip, Menu, Dropdown, Icon, Button,Layout } from 'antd';import styles from './MapTest.less';import L from 'leaflet';
import { Map, TileLayer,Marker,Popup } from 'react-leaflet';import "leaflet/dist/leaflet.css";const {Content} = Layout;//把图标重新引入
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.imagePath = ''
L.Icon.Default.mergeOptions({iconRetinaUrl: require('../../assets/markers/marker-icon-2x.png'),iconUrl: require('../../assets/markers/marker-icon.png'),shadowUrl: require('../../assets/markers/marker-shadow.png')
})//处理每一个marker的显示
const PopupMarker = ({ children,position }) => {
const items = children.map((item) => (<span key={item.key}>{item.string}<br /></span>))return  <Marker position={position}><Popup><div>{items}</div></Popup>
</Marker>

}
//处理markerlist
const MarkersList = ({markers}) => {const items = markers.map(({ key,...props}) => (<PopupMarker key={key} {...props} />
  ))return <div>{items}</div>
}export default class SiteMap extends PureComponent {render() {const position = [22.7047, 113.302];  //中心点//模拟数据const dataList = [];for (let i = 0; i < 46; i += 1) {dataList.push({id: i,Province: '',Name: `site ${i}`,Lat: 22.7047 + `${i}`,Lng: 113.302 - `${i}`,currentValue: Math.floor(Math.random() * 1000),status: Math.floor(Math.random() * 10) % 2,purchaseDate: new Date(`2017-07-${Math.floor(i / 2) + 1}`),create_time: new Date(`2017-07-${Math.floor(i / 2) + 1}`),progress: Math.ceil(Math.random() * 100),Province: Math.floor(Math.random() * 10) % 2 ? '省份1' : '省份2',City: Math.floor(Math.random() * 10) % 2 ? '城市1' : '城市2',});}let cellPoints = [];dataList.map(item => {let lng = Number.parseFloat(item.Lng);let lat = Number.parseFloat(item.Lat);let name = item.Name;     let city = item.City || '';let district = item.District || '';let address = item.Address || '';let maintainer = item.Maintainer || '';let popupContent = [{key:city,string:`城市:${city}`},{key:name,string:`基站名称:${name}`},{key:lng,string:`经度:${lng}`},{key:lat,string:`纬度:${lat}`},{key:district,string:`地区:${district}`},{key:address,string:`地址:${address}`},{key:maintainer,string:`维护人员:${maintainer}`},]cellPoints.push({key:name,position:[lat, lng],children:popupContent});});const style= { width: '100%',height: '600px',}return (<Content><div className="ant-card-bordered" style={style}>          <Map center={position} zoom={13} style={{width: '100%', height: '100%'}}><TileLayerurl="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/><MarkersList markers={cellPoints} /></Map></div></Content>
    );}
}

LeafletMarker.js

二、使用react-leaflet-markercluster点聚合显示坐标点。

1.注意点:按照github上使用方法安装好。 命令:

npm install react-leaflet-markercluster
npm install leaflet.markercluster leaflet react-leaflet prop-types

2.确保两个都安装上就可以使用了、文档还蛮全的也是案例型、容易使用。我这里也只是简单引用点聚合。我这里的方式是先定义marker样式,然后引用,注意这里要在less文件里写好聚合点样式噢。

//定义聚合点样式
const createClusterCustomIcon = function (cluster) {
return L.divIcon({
html: `<span>${cluster.getChildCount()}</span>`,
className: styles.markercustom,
iconSize: L.point(40, 40, true)
});
};
//引用
<MarkerClusterGroup
spiderfyDistanceMultiplier={2}
iconCreateFunction={createClusterCustomIcon}
markers={cellPoints}
/>
//样式
/* Customising the Clustered Markers */
.markercustom {
background: #9370db;
border: 3px solid #ededed;
border-radius: 50%;
color: #ededed;
height: 40px;
line-height: 37px;
text-align: center;
width: 40px;
}

效果:
整体代码:(注释掉部分是实际项目中模拟数据的流通,可去github看~)

import React, { PureComponent, Fragment } from 'react';
import { render } from 'react-dom';import { connect } from 'dva';
import { Row, Col, Card, Tooltip, Menu, Dropdown, Icon, Button,Layout } from 'antd';import styles from './MapTest.less';import L from 'leaflet';
import { Map, TileLayer } from 'react-leaflet';
import MarkerClusterGroup from 'react-leaflet-markercluster';import "leaflet/dist/leaflet.css";const {Content} = Layout;//把图标重新引入
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.imagePath = ''
L.Icon.Default.mergeOptions({iconRetinaUrl: require('../../assets/markers/marker-icon-2x.png'),iconUrl: require('../../assets/markers/marker-icon.png'),shadowUrl: require('../../assets/markers/marker-shadow.png')
})// @connect(({ site, loading }) => ({//   site,
//   loading: loading.models.site,
// }))
export default class SiteMap extends PureComponent {// componentDidMount() {//   const { dispatch } = this.props;//   dispatch({//     type: 'site/fetch',//   });// }
  render() {//  const { site:{data}, loading } = this.props;
    const position = [22.7047, 113.302];//const dataList = { data }.data.list;const dataList = [];for (let i = 0; i < 46; i += 1) {dataList.push({id: i,Province: '',Name: `site ${i}`,Lat: 22.7047 + `${i}`,Lng: 113.302 - `${i}`,currentValue: Math.floor(Math.random() * 1000),status: Math.floor(Math.random() * 10) % 2,purchaseDate: new Date(`2017-07-${Math.floor(i / 2) + 1}`),create_time: new Date(`2017-07-${Math.floor(i / 2) + 1}`),progress: Math.ceil(Math.random() * 100),Province: Math.floor(Math.random() * 10) % 2 ? '省份1' : '省份2',City: Math.floor(Math.random() * 10) % 2 ? '城市1' : '城市2',});}let cellPoints = [];const sytlep = {width:'100%',}dataList.map(item => {let lng = Number.parseFloat(item.Lng);let lat = Number.parseFloat(item.Lat);let name = item.Name;     let city = item.City || '';let district = item.District || '';let Address = item.Address || '';let maintainer = item.Maintainer || '';let popupDiv = `<div style={stylep}><span>城市:${city}</span><br /><span>基站名称:${name}</span><br /><span>经度:${lng}</span><br /><span>纬度:${lat}</span><br /><span>地区:${district}</span><br /><span>地址:${Address}</span><br /><span>维护人员:${maintainer}</span><br /></div>`
      cellPoints.push({position:[lat, lng],popup:popupDiv});});const style= { width: '100%',height: '600px',} //定义聚合点样式const createClusterCustomIcon = function (cluster) {return L.divIcon({html: `<span>${cluster.getChildCount()}</span>`,
        className: styles.markercustom,iconSize: L.point(40, 40, true)});};return (<Content><div className="ant-card-bordered" style={style}><Map className={styles.markercluster} center={position} zoom={13} style={{width: '100%', height: '100%'}}><TileLayerurl="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/><MarkerClusterGroup spiderfyDistanceMultiplier={2}iconCreateFunction={createClusterCustomIcon}markers={cellPoints}   /></Map></div></Content>
    );}
}

markercluster

总结:

这里要注意记得把marker的图片文件夹放入src/assets里面,不然会跑不起来的。

两种用法文档都有比较详细的代码可以参考。如果出不来效果多研究研究。

具体项目中的使用可以参考我的github的demo,会持续更新丰富。

转载于:https://www.cnblogs.com/GuliGugaLiz/p/9149956.html

React-leaflet在ant-design pro中的基本使用相关推荐

  1. 关于ant design pro中2个下拉列表,下列列表a的数据需要依据列表b选择的值来进行变化,无法及时获取

    <ProFormTreeSelectname="permission"label="列表的label"placeholder="选择" ...

  2. Ant Design Pro 中 ProTable受控菜单 class类 与 构造函数

    // class 类 state = {// 列表受控模式columnsStateMap: {btId: { show: false }, // 需要受控的字段名(btId)},};// 在组件中 & ...

  3. React Ant design pro 访问服务器接口,获取数据显示

    React Ant design pro 访问服务器接口 一.前两天更新了Ant design pro环境搭建,需要了解的小伙伴可以看一下之前的内容,还有react基础教程噢. 二.框架搭建完后,一般 ...

  4. ant design pro (八)构建和发布

    一.概述 原文地址:https://pro.ant.design/docs/deploy-cn 二.详细 2.1.构建 当项目开发完毕,只需要运行一行命令就可以打包你的应用: npm run buil ...

  5. Ant Design Pro引入Echarts 报错Unexpected token

    想要在ant design pro中引入echart,发现在网上找了很多示例直接运行不通过,可能需要更改下部分格式,比如直接引用下面链接中的代码就会报错:Unexpected token, https ...

  6. ant design pro(二)布局

    一.概述 参看地址:https://pro.ant.design/docs/layout-cn 其实在上述地址ant-design上已经有详细介绍,本文知识简述概要. 页面整体布局是一个产品最外层的框 ...

  7. Ant Design Pro -- 02项目结构@20210331

    一.项目的目录结构 ├── config # umi 配置,包含路由,构建等配置 ├── docker # 部署 ├── functions # ├── mock # 本地模拟数据 ├── publi ...

  8. 前端UI框架Ant Design Pro

    一直忙于工作,也没时间总结.现在有点零散时间把之前做的笔记整理一下. 目前项目使用的技术栈是,前端UI框架Ant Design Pro,数据交互使用react,后端使用的是springcloud,离线 ...

  9. 【前端】Ant Design Pro和Arco Design Pro非技术对比

    最近公司要从Ant Design Pro和Arco Design Pro中选择一个作为中后台前端,非技术简单对比一下 stars数量 图片地址 中后台前端效果 Ant Design Pro Arco ...

  10. ant design pro模板_Ant Design Pro 学习笔记

    学习笔记 摘要介绍 Ant Design Pro 是一个基于Ant Design搭建起来的模板项目.它提供了两个主要布局:BasicLayout.UserLayout,在布局基础上制作了20多个基础页 ...

最新文章

  1. 单目摄像头检测6D姿态
  2. Java 反射:框架设计的灵魂
  3. 计算价格, java中浮点数精度丢失的解决方案
  4. 如何才能写出一手高质量优美的代码
  5. Visual Stdio的解决方案资源管理器位置调整
  6. Bzoj3628: [JLOI2014]天天酷跑
  7. 看脸 高效学英语 下
  8. B. MIN-MEX Cut
  9. Bootstrap创建按钮工具栏
  10. 干货:不同场景容器内获取客户端源IP的方法
  11. 谷歌推Tacotron 2,搞定绕口令,效果优于WaveNet
  12. python3.6安装步骤-手动安装python3.6的操作过程详解
  13. react navigation传值给上一页面
  14. 命令提示符操作及Java的特点
  15. 2021-04-25
  16. 硬盘容量和计算机容量的换算,t和g的换算(硬盘容量G跟T的换算)
  17. python空气质量等级判断_空气质量等级的判定
  18. 第13天 缓冲、转换、对象(序列化)和打印流
  19. ESP8266-Arduino编程实例-LIS3MDL磁场传感器驱动
  20. Ray----Tune(5):Tune包中的类和函数参考

热门文章

  1. 设计模式 ( 一 ) 单例模式
  2. String、StringBuilder、StringBuffer、StringConcatFactory
  3. Redis实现分布式session功能的共享
  4. MyBatis中association,collection多表查询(resultMap高级映射)笔录
  5. poj 2157 Maze(bfs)
  6. Jquery操作select选项集合,判断集合中是否存在option
  7. Linux学习之十一、环境变量的功能
  8. utf-8和gbk的区别
  9. flex学习笔记 数据验证
  10. svn在linux下的使用(svn命令行)删除 新增 添加 提交 状态查询 恢...