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%'}}>
<TileLayer
url="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%'}}>
<TileLayer
url="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,会持续更新丰富。

React-leaflet在ant-design pro中的基本使用的更多相关文章

  1. Ant Design Pro中Transfer穿梭框的实际用法(与后端交互)

    Ant Design Pro中Transfer穿梭框的实际用法(与后端交互) 该控件的属性以及属性的作用在ADP的官方文档中都有介绍,但没有讲如何与后端交互,本文旨在讲解该控件与后端的交互. Ant ...

  2. 实战 ant design pro 中的坑

    1.替换mock数据: 1.将:.roadhogrc.mock.js 中的代理模式替换 当不使用代理的时候就会将所有 /api/的链接换成 http://localhost:8080/ export ...

  3. 把antd的组件源码搬到Ant Design Pro中使用

    把组件源码搬过来后,样式死活不生效,经过1天的努力,有说less-loader的,有说webpack配置,还有说babel配置的,最后,我自己找到了方法 就是在global.less中使用@impor ...

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

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

  5. ant design pro (七)和服务端进行交互

    一.概述 原文地址:https://pro.ant.design/docs/server-cn Ant Design Pro 是一套基于 React 技术栈的单页面应用,我们提供的是前端代码和本地模拟 ...

  6. ant design pro(二)布局

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

  7. Ant Design Pro快速入门

    在上一篇文章中,我们介绍了如何构建一个Ant Design Pro的环境. 同时讲解了如何启动服务并查看前端页面功能. 在本文中,我们将简单讲解如何在Ant Design Pro框架下实现自己的业务功 ...

  8. Ant Design Pro 学习笔记:数据流向

    在讲这个问题之前,有一个问题应当讲一下: Ant Design Pro / umi / dva 是什么关系? 首先是 umi / dva 的关系. umi 是一个基于路由的 react 开发框架. d ...

  9. ant design pro (十五)advanced 使用 API 文档工具

    一.概述 原文地址:https://pro.ant.design/docs/api-doc-cn 在日常开发中,往往是前后端分离的,这个时候约定好一套接口标准,前后端各自独立开发,就不会被对方的技术难 ...

  10. ant design pro (十一)advanced Mock 和联调

    一.概述 原文地址:https://pro.ant.design/docs/mock-api-cn Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路.通过预先跟服务器端约定好的 ...

随机推荐

  1. mysql 显示表名和表数量

    SELECT count(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname'; SELECT * FROM informatio ...

  2. .NET Core 单元测试

    应用程序测试的类型很多,包括集成测试,Web 测试,负载测试等.在最底层的是单元测试,此测试可以测试单个软件组件或方法.单元测试一般只测试开发人员的代码,不应该测试基础结构普.问题,如数据库,文件系统 ...

  3. redux 源码阅读

    目录 [目录结构] [utils] actionTypes.js isPlainObject.js warning.js [逻辑代码] index.js createStore.js compose. ...

  4. 随笔编号-04 AngularJS 相关小问题解决方案合集

    1  解决 Select选择框遍历时,出现一个空白选项: <select style="width: 20%;margin-left: 5px;height: 31px;" ...

  5. Django之静态文件,中间件,admin后台管理

    静态文件 静态文件的使用 在 网页使用的css文件,js文件和图片等叫做静态文件.1)在项目下新建静态文件夹 static. 2) 配置静态文件所在的物理目录.Settings.py STATIC_U ...

  6. Leetcode之回溯法专题-39. 组合总数(Combination Sum)

    Leetcode之回溯法专题-39. 组合总数(Combination Sum) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  7. 洛谷 P2341 【受欢迎的牛】

    题库:洛谷 题号:2341 题目:受欢迎的牛 link:https://www.luogu.org/problemnew/show/P2341 思路:因为奶牛的爱慕关系具有传递性,所以每个环(强连通分 ...

  8. c# autofac结合WebApi的使用

    一.下载相关类库引用 install-package Autofac install-package Autofac.Mvc4 install-package Autofac.WebApi2 二.配置 ...

  9. hdu-6621 K-th Closest Distance

    题目链接 K-th Closest Distance Problem Description You have an array: a1, a2, , an and you must answer ...

  10. 最短路算法 Dijkstra 入门

    dijkstra算法 是一种单源点最短路算法求出一个点到其他所有点的最短路. 给你这样的一个图,需要求出1号点到其他点的最短距离是多少. 首先我们开一个数组 d[N],d[x] 代表着从起点出发到x点 ...