好几年前写的了,之前公司有这个需求,左键点击自由区域,右键取消。地图是用的vue-amap集成的高德地图,支持高德地图本身的api,选择之后判断所选区域内是否存在商户.
<div class="amap-page-container flex_column">
<div class="nav flex_b_center shadow_border_normal">
<div class="navLeft">
<span class="area">发货方:</span>
<el-select v-model="value1" clearable placeholder="请选择">
<el-option v-for="item in option" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-checkbox v-model="checked" class="alreadyEquipped">已配驱仓</el-checkbox>
<el-button type="primary" plain class="alreadyEquipped screen">筛选</el-button>
<el-button type="text" class="alreadyEquipped">更多筛选</el-button>
</div>
<div>
<el-button type="success" class="draw enclosure" plain @click="addFence">添加围栏</el-button>
<el-button type="success" class="draw" plain @click="removeFence">清除围栏</el-button>
</div>
</div>
<div class="section main flex_1_auto shadow_border_normal flex_column">
<div class="toolbar section_title">当前坐标: {{ lng }}, {{ lat }}</div>
<el-amap vid="amapDemo" :center="center" :zoom="zoom" class="amap-demo flex_1_auto" :events="events" pitch-enable="false" :amap-manager="amapManager">
<el-amap-marker v-for="marker in markers" :key="marker.title" :events="marker.events" :position="marker.position" :icon="marker.icon" />
<el-amap-polygon v-for="(item, index) in polygons" :key="index" :path="item.path" :fill-color="item.bgc" stroke-color="#ccc" stroke-opacity="0.5" stroke-style="solid" />
<el-amap-info-window v-if="window" :position="window.position" :visible="window.visible" :content="window.content" :offset="window.offset" :close-when-click-map="true" :is-custom="true">
<div id="info-window">
<div class="info-box">
<span>{{ window.title }}</span>
<p>电话:{{ window.phone }}</p>
<p>地址:{{ window.address }}</p>
</div>
</div>
</el-amap-info-window>
</el-amap>
</div>
<el-dialog title="运输订单明细" :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="dialogVisible" width="55%" :before-close="handleClose">
<div class="table_box">
<el-table
:data="tableData"
height="192"
size="mini"
stripe
:row-style="{height: '20px'}"
:cell-style="{padding: '0'}"
border
style="width: 100%"
:header-cell-style="{ whiteSpace: 'nowrap', color: '#333', background: '#f5f5f5' }"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="orderNumber" label="订单号" />
<el-table-column prop="state" label="出入库状态" />
<el-table-column prop="inboundStatus" label="入站状态" />
<el-table-column prop="shipper" label="托运人" />
<el-table-column prop="store" label="门店" />
<el-table-column prop="area" label="区县" />
<el-table-column prop="street" label="街道" />
<el-table-column prop="address" label="详细地址" width="180" />
<el-table-column prop="package" label="包裹数" />
</el-table>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">保存调度单</el-button>
<el-button @click="dialogVisible = false">关闭</el-button>
</span>
</el-dialog>
</div>
import shop from '@/assets/img/shop.png'
import VueAMap from 'vue-amap'
const amapManager = new VueAMap.AMapManager()
export default {
name: 'AmapPage',
data: function() {
const self = this
return {
data: [
{
position: '104.06588,30.711449',
title: '金牛区超市',
address: '四川省成都市金牛区',
phone: '13333333333',
url: shop
},
{
position: '104.020531,30.647579',
title: '武侯区超市',
address: '四川省成都市武侯区',
phone: '13333333334',
url: shop
},
{
position: '104.063156,30.76506',
title: '金牛区超市2',
address: '四川省成都市金牛区',
phone: '13333333335',
url: shop
},
{
position: '103.882744,30.682142',
title: '温江区超市',
address: '四川省成都市温江区',
phone: '13333333336',
url: shop
},
{
position: '103.921722,30.750826',
title: '郫都区超市',
address: '四川省成都市郫都区',
phone: '13333333337',
url: shop
},
{
position: '103.596519,30.877319',
title: '都江堰市超市',
address: '四川省成都市都江堰市',
phone: '13333333338',
url: shop
},
{
position: '104.271965,30.997131',
title: '广汉市超市',
address: '四川省成都市广汉市',
phone: '13333333339',
url: shop
},
{
position: '103.669716,30.625669',
title: '崇州市超市',
address: '四川省成都市崇州市',
phone: '13333333330',
url: shop
},
{
position: '104.096039,30.552134',
title: '天府新区超市',
address: '四川省成都市天府新区',
phone: '13133333333',
url: shop
},
{
position: '104.190353,30.571352',
title: '龙泉驿区超市',
address: '四川省成都市龙泉驿区',
phone: '13233333336',
url: shop
},
{
position: '104.272118,30.882921',
title: '青白江区超市',
address: '四川省成都市青白江区',
phone: '13433333336',
url: shop
},
{
position: '103.92377,30.57447',
title: '双流区超市',
address: '四川省成都市双流区',
phone: '13533333336',
url: shop
}
],
zoom: 10, // 初始化地图显示层级
center: [104.10194, 30.65984], // 地图中心点坐标
markers: [],
windows: [],
window: '',
checked: false,
dialogVisible: false,
amapManager,
fenceForm: {
coordinate: []
},
rectangle: null,
mouseTool: null,
overlays: [],
// 发货方表单
option: [
{
value: '选项1',
label: '发货方1'
},
{
value: '选项2',
label: '发货方2'
}
],
// 订单追踪详情表单
tableData: [
{
orderNumber: 'LP0D466724666943',
state: '未出库',
inboundStatus: '未收货',
shipper: '',
store: '赵小姐的店',
area: '九龙坡区',
street: '石桥铺街道',
address: '重庆市沙坪坝区联芳街道香榭街80号-赵小姐的店',
package: '3'
},
{
orderNumber: 'LP0D466366979762',
state: '未出库',
inboundStatus: '未收货',
shipper: '',
store: '赵小姐的店',
area: '九龙坡区',
street: '石桥铺街道',
address: '重庆市沙坪坝区联芳街道香榭街80号-赵小姐的店',
package: '7'
}
],
// 区域
polygons: [
{
path: [],
bgc: 'rgba(80,237,23,0.5)'
}
],
retangles: [
{
center: [104.10194, 30.65984],
bounds: [
[104.10194, 30.65984],
[104.30194, 30.85984]
],
fillOpacity: 0.5,
strokeColor: '#80d8ff',
fillColor: '#ffffff',
events: {
click: e => {
console.log(e.lnglat)
}
}
}
],
value1: '请选择发货方',
// 多边形绘制(点击型) 左键标点 右键取消
events: {
click(e) {
const { lng, lat } = e.lnglat
self.lng = lng
self.lat = lat
const arr = []
arr.push(lng)
arr.push(lat)
// console.log(lat)
self.polygons.forEach(element => {
element.path.push(arr)
})
self.markers.forEach(e => {
var point = e.position
self.polygons.forEach(element => {
var isPointInRing = AMap.GeometryUtil.isPointInRing(point, element.path)
if (isPointInRing == true) {
self.dialogVisible = true
}
})
})
},
rightclick() {
self.polygons.forEach(element => {
element.path = []
})
}
},
lng: 0,
lat: 0
}
},
mounted() {
this.point()
},
methods: {
point() {
const markers = []
const windows = []
const that = this
this.data.forEach((item, index) => {
markers.push({
position: item.position.split(','),
icon: item.url,
events: {
click() {
// 方法:鼠标移动到点标记上,显示相应窗体
that.windows.forEach(window => {
window.visible = false // 关闭窗体
})
that.window = that.windows[index]
that.$nextTick(() => {
that.window.visible = true
})
}
}
})
windows.push({
position: item.position.split(','),
isCustom: true,
offset: [115, 55], // 窗体偏移
showShadow: false,
visible: false, // 初始是否显示
address: item.address,
title: item.title,
phone: item.phone
})
})
// 加点
this.markers = markers
// 加弹窗
this.windows = windows
},
handleClose() {},
// 绘制矩形
addFence() {
const _this = this
const map = amapManager.getMap()
if (this.fenceForm.coordinate.length > 0) {
alert('围栏已存在!')
return
}
if (this.rectangle) {
map.remove(this.rectangle)
}
map.plugin(['AMap.MouseTool'], function() {
const mouseTool = new AMap.MouseTool(map)
_this.mouseTool = mouseTool
mouseTool.rectangle()
AMap.event.addListener(mouseTool, 'draw', function(e) {
_this.fenceForm.coordinate = []
const path = e.obj.getPath()
_this.markers.forEach(e => {
var point = e.position
var isPointInRing = AMap.GeometryUtil.isPointInRing(point, path)
if (isPointInRing == true) {
_this.dialogVisible = true
}
})
path.forEach(e => {
_this.fenceForm.coordinate.push([e.getLng(), e.getLat()])
})
mouseTool.close(false)
})
})
},
removeFence() {
this.fenceForm.coordinate = []
if (this.mouseTool) {
this.mouseTool.close(true)
}
if (this.rectangle) {
amapManager.getMap().remove(this.rectangle)
}
}
}
}
.toolbar {
padding: 10px;
padding-top: 0;
color: #4ea9ea;
}
.amap-demo {
height: 100%;
border-radius: 5px;
}
.amap-page-container {
position: relative;
}
#info-window {
width: 211px;
height: 80px;
margin-left: 30px;
background: rgba(255, 255, 255, 0.9);
border-radius: 4px;
overflow: hidden;
span {
font-weight: bold;
display: block;
margin-top: 15px;
margin-bottom: 5px;
}
.info-box {
margin-left: 10px;
}
}
.detail {
width: 100%;
height: 24px;
color: #fff;
background-color: #1a73e8;
position: absolute;
bottom: 0;
font-size: 12px;
line-height: 24px;
text-align: center;
cursor: pointer;
}
::v-deep .amap-icon img {
width: 30px;
height: 30px;
}
.nav {
display: flex;
background-color: #fff;
padding: 10px;
margin: 10px 10px 0;
align-items: center;
.navLeft {
display: flex;
align-items: center;
.alreadyEquipped {
margin: 0px 10px;
}
}
}
.main {
margin-bottom: 10px;
::v-deep th{
height: 20px;
padding: 1px;
}
}
::v-deep .el-dialog {
background-color: #fff;
}