先上一张效果图 看看是不是大家想要的效果~ ❤️
希望其中的小点能帮助大家,主要看怎么绘制在地图上的代码即可
1.第一步要加入项目package.json中或者直接yarn install它都可以
想必大家应该都会
"@amap/amap-jsapi-loader": "0.0.7"
2.加入项目中
import React, { PureComponent } from 'react';
import { Radio, Checkbox, Input, Button, message as AntMessage } from 'antd';
import AMapLoader from '@amap/amap-jsapi-loader';
import { services } from '@comall-backend-builder/core';
import './index.less';
const { api } = services;
type Geofence = {
/**
* 圆形围栏中心点,格式:longitude,latitude
*/
center?: string;
/**
* 围栏名称
*/
name: string;
/**
* 多边形围栏坐标点,格式:lon1,lat1;lon2,lat2;lon3,lat3
*/
points: string;
/**
* 圆形围栏半径,单位:米。范围0~5000
*/
radius?: number;
};
type GeofenceValue = {
geofences: Array<Geofence>;
scope: string;
isEdit?: boolean;
};
const DEFAULTSCOPE = 'CUSTOM';
const DEFAULTNAME = '默认区域';
interface GeofencesProps {
onChange: (data: GeofenceValue) => void;
/**
* 当前值
*/
value: GeofenceValue;
row: any;
}
interface GeofencesStates {
/**
* 当前地图实例
*/
map: any;
/**
* 地图api
*/
AMap: any;
/**
* 多边形对象集合
*/
polygons: any;
/**
* 门店位置标记
*/
marker: any;
/**
* 当前的门店维度
*/
centerPosition: any;
/**
* 当前的门店名称
*/
subsiteName: string;
}
export class Geofences extends PureComponent<GeofencesProps, GeofencesStates> {
constructor(props: any) {
super(props);
this.state = {
map: undefined,
AMap: undefined,
polygons: undefined,
marker: undefined,
centerPosition: undefined,
subsiteName: '',
};
}
componentDidMount() {
this.initMap();
}
initMap = () => {
api.get({}, { apiPath: '/admin/amap/config' }).then((result: any) => {
AMapLoader.load({
key: result.key, // 申请好的Web端开发者Key,首次调用 load 时必填
version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ['AMap.Marker', 'AMap.Polygon', 'AMap.PolyEditor'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap: any) => {
let map = new AMap.Map('mapContainer', {
zoom: 13,
});
this.initSubsiteCenterPosition(AMap, map);
this.setState({ AMap, map });
})
.catch((e: any) => {
console.log(e);
});
});
};
initSubsiteCenterPosition = (AMap: any, map: any) => {
const result = {
longitude: 150.644,
latitude: -34.397
}
//以上是我们项目接口返回的一个点的经纬度,在此我就简单设置了
let centerPosition = new AMap.LngLat(result.longitude, result.latitude); // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
this.setState(
{
centerPosition: centerPosition,
},
() => {
this.initGeofrences(AMap, map);
}
);
};
initGeofrences = (AMap: any, map: any) => {
const { centerPosition, subsiteName } = this.state;
//移除所有覆盖物
const { polygons, marker } = this.state;
if (polygons) {
map.remove(polygons);
}
if (marker) {
map.remove(marker);
}
// 创建一个 Marker 实例:
let newMarker = new AMap.Marker({
position: centerPosition,
title: subsiteName,
zIndex: 101,
bubble: true,
});
// 将创建的点标记添加到已有的地图实例:
map.add(newMarker);
let newPolygons = [];
const path = [
centerPosition.offset(-1500, 1500),
centerPosition.offset(1500, 1500),
centerPosition.offset(1500, -1500),
centerPosition.offset(-1500, -1500),
];
let polygon = new AMap.Polygon({
path: path,
strokeColor: '#1791fc',
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: '#1791fc',
zIndex: 100,
bubble: true,
});
newPolygons.push(polygon);
map.add(newPolygons);
// 缩放地图到合适的视野级别
map.setFitView(newPolygons);
//开启多边形编辑
newPolygons.forEach((newPolygon, index) => {
let newPolyEditor = new AMap.PolyEditor(map, newPolygon);
newPolyEditor.open();
newPolyEditor.on('addnode', () => {
this.onPolygonChange(index);
});
newPolyEditor.on('adjust', () => {
this.onPolygonChange(index);
});
newPolyEditor.on('removenode', () => {
this.onPolygonChange(index);
});
});
this.setState({
map,
polygons: newPolygons,
marker: newMarker,
});
//回传默认值
let points = this.getPoints(path);
let newValue: GeofenceValue = {
scope: DEFAULTSCOPE,
geofences: [
{
name: DEFAULTNAME,
points,
},
],
};
this.onChange(newValue);
};
onChange = (data: GeofenceValue) => {
const { onChange } = this.props;
onChange(data);
};
onPolygonChange = (index: number) => {
let { value } = this.props;
const { polygons } = this.state;
let geofences;
let geofence;
if (value) {
geofences = value.geofences;
geofence = geofences[index];
let points;
if (polygons && polygons[index]) {
points = this.getPoints(polygons[index].getPath());
}
geofence = { ...geofence, points };
geofences.splice(index, 1, geofence);
value = { ...value, geofences: geofences };
this.onChange(value);
}
};
onChangeScope = () => {};
onNameChange = (event: any, index: number) => {
let { value } = this.props;
let geofences;
let geofence;
if (value) {
geofences = value.geofences;
geofence = geofences[index];
geofence = { ...geofence, name: event.target.value };
geofences.splice(index, 1, geofence);
value = { ...value, geofences: geofences };
this.onChange(value);
}
};
getPoints = (path: any) => {
return path
.map((point: any) => {
return point.lng + ',' + point.lat;
})
.join(';');
};
addPolygon = () => {
const { AMap, map, centerPosition } = this.state;
const { value } = this.props;
if (value && value.geofences && value.geofences.length >= 10) {
AntMessage.warning('仅支持最多配置10个自定义范围');
return;
}
if (AMap && map && centerPosition) {
const path = [
centerPosition.offset(-1500, 1500),
centerPosition.offset(1500, 1500),
centerPosition.offset(1500, -1500),
centerPosition.offset(-1500, -1500),
];
const points = this.getPoints(path);
let geofences = value.geofences;
geofences.push({
name: DEFAULTNAME,
points,
});
value.geofences = geofences;
this.onChange(value);
setTimeout(() => {
this.initGeofrences(AMap, map);
}, 1000);
}
};
deletePolygon = (index: number) => {
let { value } = this.props;
const { AMap, map } = this.state;
if (value && map) {
const newGeofences = value.geofences.slice();
newGeofences.splice(index, 1);
value.geofences = newGeofences;
this.onChange(value);
setTimeout(() => {
map.clearMap();
this.initGeofrences(AMap, map);
}, 1000);
}
};
render() {
const { value } = this.props;
const geofences = value && value.geofences ? value.geofences : [];
const scope = value && value.scope ? value.scope : DEFAULTSCOPE;
return (
<div className="geofences">
<Radio.Group onChange={this.onChangeScope} value={scope}>
<Radio value={'CUSTOM'}>自定义配送范围</Radio>
</Radio.Group>
<div className="scope-tip">
可以自定义半径5公里内的区域,收货地址在配送范围外的买家,不可以选择下单
</div>
<div className="geofences-wrap">
<div className="map-container" id="mapContainer"></div>
{geofences && geofences.length > 0 && (
<div className="setting-wrap">
<div className="setting-geofences-wrap">
{geofences.map((geofence, index) => {
return (
<Checkbox key={index} checked>
<Input
onChange={(e) => {
this.onNameChange(e, index);
}}
style={{ width: 145 }}
value={geofence.name}
maxLength={10}
/>
{index !== 0 && (
<span
className="setting-delete"
onClick={this.deletePolygon.bind(this, index)}
>
{services.language.getText('common.delete')}
</span>
)}
</Checkbox>
);
})}
</div>
<Button type="default" className="add-btn" onClick={this.addPolygon}>
添加配送区域
</Button>
</div>
)}
</div>
</div>
);
}
}