dzadsod/src/admin/templates/js/bmaps.ts

1132 lines
46 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

namespace APPMAP {
// 对城市信息初始化
// 对inpout初始化
class base {
// 当前地图经纬度
protected mapLng: string = '116.395645'
protected mapLat: string = '39.929986'
// 当前地图的经纬度对象
protected mapPoints: object = {}
// input值
protected inputLng: string = ''
protected inputLat: string = ''
// input值对象
protected inputPoints: object = {}
// input生成标注点对象,跟模态框同步的对象标注点
protected cacheMarker: object = {}
// 城市信息
protected allCity: string = ''
protected selectProv: string = ''
protected selectCity: string = ''
protected selectDist: string = ''
protected address: string = ''
// 场所
protected placeName: string = ''
// dom
private lngDom: any = {}
private latDom: any = {}
constructor() {
this.mapLng = CL.c.maplng || this.mapLng
this.mapLat = CL.c.maplat || this.mapLat
// 若是inputLng值变化同步到input输入框
this.watch(this, 'inputLng', () => {
this.setInputLng()
})
// 若是inputLat值变化同步到input输入框
this.watch(this, 'inputLat', () => {
this.setInputLat()
})
this.initHtmlDom()
// 进行初始化
this.getInputLngLat()
// 判断input是否有值有的话直接传递给默认值
this.syncMapLngLat()
// 获取城市信息
this.getCity()
// 城市信息
$(document).on('change keyup', '.city-js select', () => {
// 清空详细地址
if ($(".city-mapjs-address").length) $(".city-mapjs-address").val('')
});
// 包含详细地址的变化
$(document).on('change keyup', '.city-js select, .city-mapjs-address', () => {
this.getCity()
});
}
// 全局dom
initHtmlDom() {
// 经纬度
this.lngDom = $(".city-mapjs-lng")
this.latDom = $(".city-mapjs-lat")
}
// 判断是否为空
isEmpty(val: any) {
switch (val) {
case ',':
return true
case '请选择':
return true
case '请选择所在地区':
return true
}
return APPFUN.isEmpty(val)
}
// 获取经纬度
getInputLngLat() {
this.inputLng = this.lngDom.val()
this.inputLat = this.latDom.val()
}
// 同步到地图经纬度
syncMapLngLat() {
if (!this.isEmpty(this.inputLng) && !this.isEmpty(this.inputLat)) {
this.mapLng = this.inputLng
this.mapLat = this.inputLat
}
}
// 对input赋值
setInputLngLat() {
this.setInputLng()
this.setInputLat()
}
setInputLng() {
this.lngDom.val(this.inputLng)
this.lngDom.trigger('input')
}
setInputLat() {
this.latDom.val(this.inputLat)
this.latDom.trigger('input')
}
// 获取地址信息
getCity() {
//获取城市信息
this.selectProv = this.isCity($(".city-js select.prov").find("option:selected").val())
this.selectCity = this.isCity($(".city-js select.city").find("option:selected").val())
this.selectDist = this.isCity($(".city-js select.dist").find("option:selected").val())
this.address = this.isCity($(".city-mapjs-address").val())
// 拼装一个除了省信息以外的地址字符串
this.allCity = this.selectCity + this.selectDist + this.address;
}
// 判断城市信息是否为空
isCity(string: string) {
return !this.isEmpty(string) ? string : ''
}
// 根据城市信息判断地图级别
level() {
let level = 12
// 省份 20km
if (!this.isEmpty(this.selectProv)) level = 11
// 市区 5km
if (!this.isEmpty(this.selectCity)) level = 13
// 县市区 500M
if (!this.isEmpty(this.selectDist)) level = 15
// 详细地址 200M
if (!this.isEmpty(this.selectDist) && !this.isEmpty(this.address)) level = 18
return level;
}
// 对参数进行监听,做出对应的操作
watch(JsonObj: any, key: string, closure?: any) {
// 缓存值
let cacheData: any = {};
cacheData[key] = JsonObj[key];
Object.defineProperty(JsonObj, key, {
enumerable: true, // 该属性可被枚举
configurable: true, // 该属性可以被删除以及属性描述符可以被改变
get() {
// 需要从缓存值获取不能直接obj获取
return cacheData[key]
},
set(newValue) {
const oldValue = cacheData[key];
// 改变原来的值也就是修改JsonObj的值
cacheData[key] = newValue;
if (typeof closure === 'function' && oldValue !== newValue) closure(newValue, oldValue)
}
})
}
}
// 初始一个地图并返回本地图对象
class initialMap extends base {
// 展示类型的地图对象缓存
protected showMap: any = {}
// 模态框地图对象缓存
protected modalMap: any = {}
// 地图模式
protected mapType: boolean = false
protected myGeos: any = {}
// 缓存ajax查询结果
protected mapLngLatList: any = {}
protected mapCacheMarker: any = {}
constructor() {
super()
this.myGeos = new BMapGL.Geocoder();
// 将input信息转为对象,若是input有值 直接初始化后传递给地图
if (!this.isEmpty(this.inputLng) && !this.isEmpty(this.inputLat)) {
this.inputPoints = this.mapPoints = this.lnglatToPoints(this.inputLng, this.inputLat)
} else {
// 若是经纬度不存在,则城市信息存在则以城市信息为准,但是城市信息获取对象有延迟,则需要调整到后面
// 使用默认值对地图的经纬度转成对象
this.mapPoints = this.lnglatToPoints(this.mapLng, this.mapLat)
}
}
// 将字符串经纬度转换成经纬度对象
lnglatToPoints(lng: string, lat: string) {
let point = {}
if (!this.isEmpty(lng) && !this.isEmpty(lat)) point = new BMapGL.Point(lng, lat)
return point
}
// 初始化一个地图
initMap(domId: string, level?: any) {
const map = new BMapGL.Map(domId, {enableMapClick: false});
// 初始化地图,设置中心点坐标和地图级别
console.log(this.level())
map.centerAndZoom(this.mapPoints, level || this.level());
// 开启鼠标滚轮缩放
map.enableScrollWheelZoom(true);
// 地图配置
map.setDisplayOptions({
// 隐藏POI文字
// poiText: false,
// 隐藏POI的Icon
poiIcon: false
})
return map
}
// 旋转地图角度
setHeadingTilt(map: any) {
// 地图当前旋转角度
// map.setHeading(64.5);
// 地图当前状态倾斜角度
map.setTilt(65);
}
// 将城市信息转化为经纬度,并根据经纬度调整地图
citySyncMap(mapOjb: any, level?: number) {
// 异步执行建议在地图加载完成(tilesloaded)后再进行地图调整,否则无效
this.myGeos.getPoint(this.allCity || this.selectProv, (point: any) => {
if (point) {
this.mapPoints = point
this.mapLng = point.lng
this.mapLat = point.lat
mapOjb.panTo(point);
// 让他自动调整地图
if (level && level > 0) mapOjb.setZoom(level);
} else {
console.log("您选择地址没有解析到结果!")
}
}, this.selectProv);
}
// 根据小区名称调整地图
placeNameMap(map, callbackQuery, callbackPolygon) {
// this.mapPoints this.selectCity
const local = new BMapGL.LocalSearch(this.selectCity, {
renderOptions: {
map: map
// panel:"r-result" 查询得到的信息列表
},
pageCapacity: 1,
});
// local.disableAutoViewport()
// forceLocal限定在区域内
local.search(this.placeName, {forceLocal: true});
// 自动标注后回调
local.setMarkersSetCallback((e) => {
// 获取数组第一个值
let city = e.pop()
// address: "山东省泰安市岱岳区杏林路"
// city: "泰安市"
// detailUrl: "https://api.map.baidu.com/place/detail?uid=7df64328bc0d8e4788f15d0a&output=html&source=jsapi"
// isAccurate: true
// marker: az {latLng: cZ, hashCode: "mz_2h", _type: "overlay", _visible: true, _visibleInternal: true, …}
// phoneNumber: undefined
// point: cZ {lng: 117.07973971764177, lat: 36.18540716406726}
// postcode: undefined
// province: "山东省"
// tags: (2) ["地产小区", "小区/楼盘"]
// title: "东瑞·长城一品"
// type: 0
// uid: "7df64328bc0d8e4788f15d0a"
// url: "https://map.baidu.com?s=inf%26uid%3D7df64328bc0d8e4788f15d0a%26c%3D325&i=0&sr=1"
// 目前只调整位置,然后删除标记,目前因为需求只是获取地图显示位置,不需要他进行标注
map.removeOverlay(city.marker)
// isAccurate 为true 精确定位 false 模糊定位
setTimeout(() => {
if (city.isAccurate === true) {
// 精准查询则按小区名
map.panTo(city.point)
map.setZoom(18)
// 对小区画线
callbackQuery(city.uid, callbackPolygon)
} else {
// 模糊查询则按地址查询
this.citySyncMap(map)
}
}, 50)
});
}
// 获取经纬度列表
ajaxlnglatList(map: any, formJson: object, clickEvent: boolean = false, closure?: any) {
$.getJSON(M.url.own_name + "c=ajax&a=doallmap", formJson, (listJson: any) => {
this.mapLngLatList = listJson
$.each(listJson, (i: number, val: any) => {
// 值的转换为了后面统一使用,对应后期数据库的值
val.maplng = val.v_maplng
val.maplat = val.v_maplat
// 根据clickEvent 判断是否要启用标注点的信息提示
const clickClosure = clickEvent ? this.addOpenInfo(map, val) : ''
if (!this.isEmpty(val.maplng) && !this.isEmpty(val.maplat)) this.addMapOverlay(map, val.maplng, val.maplat, false, val.id, clickClosure);
// 暂时考虑加入一个回调
// if (typeof closure === 'function') closure(val);
})
})
}
// 标注图标样式
myIcon() {
return new BMapGL.Icon(
// 图片地址
M.url.own_tem + "/img/markers.png",
// 标注的大小,跟图片上的标注图样大小一致
new BMapGL.Size(21, 25),
// 其他参数
{
// 图片的大小
imageSize: new BMapGL.Size(42, 325),
// 指定定位位置。
// 当标注显示在地图上时,其所指向的地理位置距离图标左上
// 角各偏移10像素和25像素。您可以看到在本例中该位置即是
// 图标中央下端的尖角位置。
anchor: new BMapGL.Size(10, 25),
// 设置图片偏移。
// 当您需要从一幅较大的图片中截取某部分作为标注图标时,您
// 需要指定大图的偏移位置此做法与css sprites技术类似。
// 设置图片偏移
// imageOffset: new BMapGL.Size(0, 0)
imageOffset: new BMapGL.Size(0, 300)
}
);
}
// 地图点的标注
addMapOverlay(appmapl: any, lng: string, lat: string, icons: boolean = false, listId?, clickClosure?: any) {
if (this.isEmpty(lng)) return false;
// 获取经纬度 创建标注
const points = this.lnglatToPoints(lng, lat)
const marker = new BMapGL.Marker(points);
// 给标注点添加点击回调
if (typeof clickClosure === 'function') {
marker.addEventListener("click", (e: any) => {
clickClosure(e)
})
// 因为marker不会直接存在dom地图打开后才会生成dom
// 将所有的标注点缓存,方便手动触发标注点的点击事件
this.watch(marker, 'domElement', () => {
this.mapCacheMarker[listId] = $(marker.domElement)
})
}
// 标注图标,需要单独标注的颜色,则进行缓存
if (icons) {
// 缓存一下
this.cacheMarker = marker
marker.setIcon(this.myIcon());
}
// 添加到地图
appmapl.addOverlay(marker);
return points
}
// 添加标注信息窗口
addOpenInfo(map: any, value: any) {
const opts = {
// width: 250, // 信息窗口宽度
// height: 80, // 信息窗口高度
maxWidth: 350,
enableAutoPan: true,
title: value.v_name // 信息窗口标题,设置为小区名称
};
// 组织内容
// let content = `<p>类型:${value.}</p>`
let content = `<p>${value.v_province}${value.v_city}${value.v_district}${value.v_address}</p>`
// 返回一个函数方便点击事件二次调用
return (e: any) => {
const p = e.target;
const point = this.lnglatToPoints(p.getPosition().lng, p.getPosition().lat);
const infoWindow = new BMapGL.InfoWindow(content, opts); // 创建信息窗口对象
map.openInfoWindow(infoWindow, point); //开启信息窗口
}
}
}
// 展示型的地图动作操作
class showMap extends initialMap {
constructor() {
super();
// 获取地图状态
this.getMapType()
// 初始化
this.showInitMap()
// 启动城市信息监听
this.watchCity()
}
showInitMap() {
// 初始化地图
this.showMap = this.initMap("showmap")
// 旋转地图角度
this.setHeadingTilt(this.showMap)
// 地图初始化完成后若是没有input的值且又存在城市信息则按照城市信息调整地图
if (this.isEmpty(this.inputLng) && this.isEmpty(this.inputLat) && !this.isEmpty(this.allCity)) this.citySyncMap(this.showMap)
// 根据地图状态处理标记
if (this.mapType) this.addMapOverlay(this.showMap, this.inputLng, this.inputLat, true)
}
getMapType() {
// true 则进行标记
// false 不进行地图标记
return this.mapType = $('#showmap').data('type') === 'showmap' ? false : true;
}
watchCity() {
const $fun = () => {
this.citySyncMap(this.showMap)
}
// 监听指定的参数
this.watch(this, 'selectProv', $fun)
this.watch(this, 'allCity', $fun)
// 只是针对纯展示型地图,不带标记的
if (!this.mapType) {
// 禁止拖拽
// this.showMap.disableDragging()
// 若是地图经纬度变化时是否同步给input
this.watch(this, 'mapLng', () => {
this.inputLng = this.mapLng
})
this.watch(this, 'mapLat', () => {
this.inputLat = this.mapLat
})
}
}
}
// 模态框地图动作操作
class modalMap extends showMap {
// 模态框的缓存信息
protected modalLng: string = ''
protected modalLat: string = ''
// input值对象
protected modalPoints: object = {}
constructor() {
super();
//验证信息
$('#mapmodal').on('click', () => {
// 获取城市信息
// this.getCity()
if (this.isEmpty(this.selectCity)) {
$.include(M['url']['static2_vendor'] + 'alertify/alertify.js', function () {
alertify.logPosition("右下角");
alertify.error("请选择城市。");
})
} else {
// 获取小区名称
this.placeName = $('select[name="v_name"]').find("option:selected").val()
let html = '范围:' + this.selectProv + '<small style="padding-left:15px;">' + this.allCity + '</small>';
html += '<span class="tag tag-sm tag-outline tag-danger font-size-16 m-l-5">' + this.placeName + '</span>';
$('h4.modal-title').html(html)
// 打开模态框
$('#appmaps').modal('show')
}
});
//模态框
$('#appmaps').on('shown.bs.modal', () => {
// 延迟效果可以让模态框加载时看起来没有卡的感觉
setTimeout(() => {
// 解决因页面产品滚动条导致的点击地图获取的经纬度不准确问题
// 让滚动条回滚到顶部
document.body.scrollTop = document.documentElement.scrollTop = 0
// 初始化模态框
this.modalInitMap()
// 主要是用来排除掉当前小区的标记
const mapId = $('#modalmap').data('mapid') || '';
// // ajax查找 当前地区点的标注并添加在地图上
this.ajaxlnglatList(this.modalMap, {
id: mapId,
province: this.selectProv,
city: this.selectCity,
district: this.selectDist
})
// 根据小区名称 且经纬度为空 调整地图核心
if (this.placeName && this.isEmpty(this.inputLng) && this.isEmpty(this.inputLat)) {
this.placeNameMap(this.modalMap, this.queryHouseOutline, this.showPolygon(this.modalMap))
}
//点击百度地图时触发
this.modalMap.addEventListener("click", (e: any) => {
//清除单个标注
this.modalMap.removeOverlay(this.cacheMarker);
//赋值给输入框
this.modalLng = e.latlng.lng
this.modalLat = e.latlng.lat;
// 他变化时要同时针对多个地图直接变化
this.modalPoints = this.addMapOverlay(this.modalMap, this.modalLng, this.modalLat, true)
});
}, 200)
});
// 保存
$('#appmaps .button-save').on('click', () => {
//判断是否同步信息到展示地图
if (!this.isEmpty(this.modalLng) && !this.isEmpty(this.modalLat)) {
//返回值
this.inputLng = this.modalLng
this.inputLat = this.modalLat
//展示图的操作
if (!this.isEmpty(this.showMap)) {
//清除展示地图的标注
this.showMap.clearOverlays();
//地图显示
this.mapPoints = this.inputPoints = this.modalPoints
this.showMap.panTo(this.mapPoints)
//对地图一进行标注
this.addMapOverlay(this.showMap, this.inputLng, this.inputLat, true);
}
}
//关闭对话框
$('#appmaps').modal('hide');
});
// 关闭
$('#appmaps').on('hidden.bs.modal', () => {
//清除标注
this.modalMap.clearOverlays()
// 还原信息
this.modalLng = this.modalLat = ''
this.modalPoints = {}
//清除模态框数据
$('#appmaps').removeData("bs.modal")
// 销毁地图
this.modalMap.destroy()
});
}
// 初始化
modalInitMap() {
// 初始化地图
this.modalMap = this.initMap("modalmap")
// 添加当前经纬度标记
if (!this.isEmpty(this.inputLng) && !this.isEmpty(this.inputLat)) this.addMapOverlay(this.modalMap, this.inputLng, this.inputLat, true);
}
// 本接口采集于百度地图,并非官方文档提供,稳定性有待考究
// 获取指定小区的边界经纬度
queryHouseOutline(uid: number, callback: any) {
let baseURL = 'https://map.baidu.com/?reqflag=pcmap&coord_type=3&from=webmap&qt=ext&ext_ver=new&l=18';
let url = baseURL + "&uid=" + uid;
callback && (window['queryHouseOutlineCallback'] = callback);
$.ajax({
type: "get",
async: false,
url: url,
dataType: "jsonp",
jsonpCallback: "queryHouseOutlineCallback",
success: function (datas) {
}
});
}
// 墨卡托坐标解析
parseGeo(mocator: string) {
if (typeof mocator != 'string') return {}
const t = mocator.split("|");
let n = parseInt(t[0]);
let i = t[1];
let r = t[2];
let o: any = r.split(";");
if (n === 4) {
let a = []
for (let s = 0; s < o.length - 1; s++) {
// @ts-ignore
"1" === o[s].split("-")[0] && a.push(o[s].split("-")[1]);
}
o = a;
o.push("");
}
let u = [];
switch (n) {
case 1:
// @ts-ignore
u.push(o[0]);
break;
case 2:
case 3:
case 4:
for (let s = 0; s < o.length - 1; s++) {
let l = o[s];
if (l.length > 100) {
l = l.replace(/(-?[1-9]\d*\.\d*|-?0\.\d*[1-9]\d*|-?0?\.0+|0|-?[1-9]\d*),(-?[1-9]\d*\.\d*|-?0\.\d*[1-9]\d*|-?0?\.0+|0|-?[1-9]\d*)(,)/g,
"$1,$2;");
// @ts-ignore
u.push(l);
} else {
let c = []
for (let d = l.split(","), f = 0; f < d.length; f += 2) {
let p = d[f], h = d[f + 1];
// @ts-ignore
c.push(p + "," + h);
}
// @ts-ignore
u.push(c.join(";"))
}
}
break;
default:
break;
}
// @ts-ignore
if (u.length <= 1) u = u.toString();
return {
type: n,
bound: i,
points: u
}
}
// 墨卡托坐标转百度坐标
coordinateToPoints(map, coordinate) {
let points = [];
if (coordinate) {
const arr = coordinate.split(";");
if (arr) {
for (let i = 0; i < arr.length; i++) {
const coord = arr[i].split(",");
if (coord && coord.length == 2) {
// coord 墨卡托平面坐标转换为经纬度球体坐标
const point = map.mercatorToLnglat(coord[0], coord[1]);
// @ts-ignore
points.push(new BMapGL.Point(point[0], point[1]));
}
}
}
}
return points;
}
// 显示多边形
showPolygon(map) {
return (datas) => {
let geo = datas.content.geo
if (geo) {
// 存在geo 则标记边界
// map.clearOverlays();
const geoObj = this.parseGeo(geo);
//边界点
const points = this.coordinateToPoints(map, geoObj.points);
//建立多边形覆盖物
const ply = new BMapGL.Polygon(points, {
// 蓝色:#3e8ef7、浅蓝色#0bb2d4、绿色#17b3a3
// 橘色:#eb6709、红色#ff4c52、紫色#9463f7
strokeColor: "#ff4c52",
strokeWeight: 2,
strokeOpacity: 1,
strokeStyle: 'dashed', // solid默认、dashed
fillColor: "transparent",
fillOpacity: 0
});
map.addOverlay(ply); //添加覆盖物
map.setViewport(ply.getPath()); //调整视野
}
}
}
}
// 通过地图选择
class selectMap extends initialMap {
// 目前的形式地图只初始化一次,模态框关闭不影响二次打开继续之前的操作
protected selectMapInitType = false
// 地图实例对象
public selectMap: any = {}
// 地图工具对象
protected drawingManager: any = {}
//本次覆盖物对象缓存
protected overlaysCache = {
overlays: {},
hashCode: '',
drawingMode: ''
}
// 绘制覆盖物缓存 hashCode = 覆盖物对象
protected overlays = {}
// 绘制覆盖物类型对照 hashCode = 类型
// Marker 点 || Circle 圆 || Polyline 线 || Polygon 多边 || rectangle 矩形
protected hashCode = {}
// 绘制覆盖物选中的小区对照 hashCode = 小区ID
protected markerID = {
marker: [],
polyline: [],
circle: [],
rectangle: [],
polygon: []
}
// 选中小区缓存过渡 初次筛选
protected villageFilterList = {}
// 选中的小区数组 id = 小区对象
protected villageList = {}
constructor() {
super();
// 在地图弹窗内进行小区条件筛选
$(document).on('change', 'select[name="vtype"]', () => {
this.filter()
})
this.watch(this, 'selectProv', () => {
this.filter()
})
this.watch(this, 'allCity', () => {
this.filter()
})
//模态框
$('#selectMapId').on('shown.bs.modal', () => {
if (this.selectMapInitType) return false
// 设置地图高度,达到满屏效果
this.setHeight()
// 延迟效果可以让模态框加载时看起来没有卡的感觉
setTimeout(() => {
// 解决因页面产品滚动条导致的点击地图获取的经纬度不准确问题
// 让滚动条回滚到顶部
document.body.scrollTop = document.documentElement.scrollTop = 0
// 初始化模态框
this.selectInitMap()
// ajax查找 当前地区点的标注并添加在地图上
this.ajaxlnglatList(this.selectMap, {
id: '',
province: this.selectProv,
city: this.selectCity,
district: this.selectDist,
allinfo: 'all'
}, true)
// 初始化绘制工具
this.drawingManagerInit()
// 绘制结束后的回调
this.drawingManager.addEventListener("overlaycomplete", (e) => {
let overlay = e.overlay
let hashCode = overlay.hashCode
let drawingMode = e.drawingMode
this.overlays[hashCode] = overlay
this.hashCode[hashCode] = drawingMode
// 本次操作的值缓存
this.overlaysCache = {
overlays: overlay,
hashCode: hashCode,
drawingMode: drawingMode
}
// 筛选选中的小区
let latLngNum = 0
// 初始化
this.villageFilterList = {}
$.each(this.mapLngLatList, (i: number, val: any) => {
latLngNum++
// 值的转换为了后面统一使用,对应后期数据库的值
let points = this.lnglatToPoints(val.v_maplng, val.v_maplat)
let result = false
// 只有矩形需要获取覆盖物的范围,其他的直接将覆盖物对象传入即可
switch (drawingMode) {
case 'polyline':
// 折线
result = BMapGLLib.GeoUtils.isPointOnPolyline(points, overlay)
break;
case 'circle':
// 圆
result = BMapGLLib.GeoUtils.isPointInCircle(points, overlay)
break;
case 'rectangle':
// 矩形
let bounds = overlay.getBounds()
result = BMapGLLib.GeoUtils.isPointInRect(points, bounds)
break;
case 'polygon':
// 多边形
result = BMapGLLib.GeoUtils.isPointInPolygon(points, overlay)
break;
default:
break;
}
if (result == true) {
if (!this.markerID[drawingMode][hashCode]) this.markerID[drawingMode][hashCode] = []
this.markerID[drawingMode][hashCode].push(val.id)
// 缓存本次的值
this.villageFilterList[val.id] = val
}
// 打开弹窗 选中小区缓存筛选
if (latLngNum === Object.keys(this.mapLngLatList).length) this.confirmOperate()
})
});
// 标记为已经初始化过
if (this.selectMapInitType === false) this.selectMapInitType = true
}, 100)
});
// 清空
$('#selectMapId .mapreset').on('click', (e: any) => {
// 重置
this.mapreset()
this.listNum('selectMapId')
this.input()
})
// 删除指定小区
$('#selectMapId').on('click', 'li button', (e) => {
const domLi = $(e.target).parents('li')
this.delFilterList(domLi.data('id'))
domLi.remove()
})
// 保存
$('#selectMapId .button-save').on('click', () => {
// 将ID写入某个input
let keysArr = Object.keys(this.villageList)
let keysStr = keysArr.toString()
this.input(keysStr)
//关闭对话框
$('#selectMapId').modal('hide');
});
// 关闭
$('#selectMapId').on('hidden.bs.modal', () => {
//清除标注
// this.modalMap.clearOverlays()
//清除模态框数据
// $('#selectMapId').removeData("bs.modal")
// 销毁地图
// this.selectMap.destroy()
});
// 点击LI地图上打开对应的标注
$('.villageList ul').on('click', 'li[data-id] h5', (e) => {
let id = $(e.target).parents('li').data('id')
let listInfo = this.villageList[id]
// 转移地图核心为标注点
let point: any = this.lnglatToPoints(listInfo.maplng, listInfo.maplat)
this.selectMap.panTo(point);
// 触发标注点的点击事件
this.mapCacheMarker[id].trigger('click')
})
}
// 设置同步地图和选中列表展示的高度
// outerHeight 包含padding margin border
// height 不含padding margin border
setHeight() {
const headerHeight = $("#selectMapId .modal-header").outerHeight(true)
// const footerHeight = $("#selectMapId .modal-footer").height()
const wHeight = $(document.body).height()
const mapHeight = wHeight - headerHeight - 15
// 设置高度
$(".selectMapHeight").height(mapHeight)
// 选中内容高度
const panelHeading = $(".selectMapHeight .panel-heading").outerHeight(true)
const panelFooter = $(".selectMapHeight .panel-footer").outerHeight(true)
const panelBody = $(".selectMapHeight .panel-body").outerHeight(true) - $(".selectMapHeight .panel-body").height()
$(".selectMapHeight .panel-body").height(mapHeight - panelHeading - panelFooter - panelBody)
}
// 设置首次筛选列表内容高度
setFilterModalBodyHeight() {
// 首次筛选的内容高度
const filterListmodalHeight = $("#filterListmodal").outerHeight(true)
const modalHeader = $("#filterListmodal .modal-header").outerHeight(true)
const modalFooter = $("#filterListmodal .modal-footer").outerHeight(true)
const modalBody = $("#filterListmodal .modal-body").outerHeight(true) - $("#filterListmodal .modal-body").height()
$("#filterListmodal .filterList").height(filterListmodalHeight - modalHeader - modalBody - modalFooter)
}
// 初始化地图
selectInitMap() {
this.selectMap = this.initMap("selectMap")
}
// 实例化鼠标绘制工具
drawingManagerInit() {
// 源码:https://github.com/huiyan-fe/BMapGLLib/blob/master/DrawingManager/src/DrawingManager.js#L44
const styleOptions = {
strokeColor: '#5E87DB', // 边线颜色
fillColor: '#5E87DB', // 填充颜色。当参数为空时,圆形没有填充颜色
strokeWeight: 2, // 边线宽度,以像素为单位
strokeOpacity: 1, // 边线透明度取值范围0-1
fillOpacity: 0.2 // 填充透明度取值范围0-1
};
const labelOptions = {
borderRadius: '2px',
background: '#FFFBCC',
border: '1px solid #E1E1E1',
color: '#703A04',
fontSize: '12px',
letterSpacing: '0',
padding: '5px'
};
this.drawingManager = new BMapGLLib.DrawingManager(this.selectMap, {
// isOpen: true, //是否开启绘制模式
enableDrawingTool: true, // 是否显示工具栏
enableCalculate: true, // 绘制是否进行测距(画线时候)、测面(画圆、多边形、矩形)
drawingToolOptions: {
enableTips: true,
customContainer: 'selectbox_Drawing',
hasCustomStyle: true,
anchor: BMAP_ANCHOR_TOP_RIGHT,
offset: new BMapGL.Size(25, 15), // 偏离值,调整工具的位置
scale: 1, // 工具栏缩放比例
drawingModes: [
// BMAP_DRAWING_MARKER,
BMAP_DRAWING_POLYLINE,
BMAP_DRAWING_RECTANGLE,
BMAP_DRAWING_POLYGON,
BMAP_DRAWING_CIRCLE,
]
},
enableSorption: true, // 是否开启边界吸附功能
sorptionDistance: 20, // 边界吸附距离
enableGpc: true, // 是否开启延边裁剪功能
circleOptions: styleOptions, // 圆的样式
polylineOptions: styleOptions, // 线的样式
polygonOptions: styleOptions, // 多边形的样式
rectangleOptions: styleOptions, // 矩形的样式
labelOptions: labelOptions // label的样式
});
}
// 选中区域确定后的处理
confirmOperate() {
// 执行循环结果后的内容
this.addHtmlShow('filterList')
// 打开筛选模态框
$('#filterListmodal').modal('show')
$('#filterListmodal').on('shown.bs.modal', () => {
this.listNum('filterListmodal')
// 处理列表
this.setFilterModalBodyHeight()
})
// 筛选中时重选
$('#filterListmodal .mapreset').on('click', (e: any) => {
//关闭对话框
$('#filterListmodal').modal('hide');
// 主要是取消选中区域覆盖物
this.mapresetClose()
})
// 保存
$('#filterListmodal .button-save').on('click', () => {
//关闭对话框
$('#filterListmodal').modal('hide');
// 并将保存的结果插入到选中小区表
this.addHtmlShow('villageList')
})
// 删除指定小区
$('#filterListmodal').on('click', 'li button', (e) => {
const domLi = $(e.target).parents('li')
this.delFilterList(domLi.data('id'), 'filterList')
domLi.remove()
})
// 关闭
$('#selectMapId').on('hidden.bs.modal', () => {
//清除模态框数据
$('#selectMapId').removeData("bs.modal")
})
}
// 选中区域HTML输出
// 判断输出到哪个dom
addHtmlShow(domclass?) {
let dom = $(`.${domclass}`).find('ul')
// 暂时直接输出,不考虑分页问题
let listNum = domclass === 'filterList' ? 0 : (Object.keys(this.villageList).length || 0)
let initListNum = 0
$.each(this.villageFilterList, (i: number, val: any) => {
// 组织HTML结构
if (domclass !== 'filterList') {
if (this.villageList[i] && Object.keys(this.villageList[i]).length > 0) return true
// 赋值给最终结果
this.villageList[i] = val
}
// 输出html
let li = this.htmlLi(i, val)
listNum === 0 ? dom.html(li) : dom.prepend(li)
listNum++
initListNum++
if (initListNum === Object.keys(this.villageFilterList).length) {
this.listNum('selectMapId')
}
})
}
// 组织HTML结构
htmlLi(key, val) {
// 组织HTML结构
let address = val.v_city + val.v_district + val.v_address
return `<li class="list-group-item village-list-item" data-id="${key}">
<h5>${val.v_name}</h5>
<button type="button" class="float-right close">
<i class="icon wb-close m-0 font-danger" aria-hidden="true"></i>
</button>
<p>地址:${address}</p>
</li>`
}
// 重选,或者取消
mapresetClose() {
// 主要是取消选中区域覆盖物
let hashCode = this.overlaysCache.hashCode
let drawingMode = this.overlaysCache.drawingMode
delete this.overlays[hashCode]
delete this.hashCode[hashCode]
delete this.markerID[drawingMode][hashCode]
this.selectMap.removeOverlay(this.overlaysCache.overlays)
}
// 清空选中的所有内容操作
mapreset() {
// 无法禁止在removeOverlay删除小区标注点换成单个删除
$.each(this.overlays, (i, val: any) => {
this.selectMap.removeOverlay(val)
delete this.overlays[i]
// 后期若是要达到精准需要单独处理
delete this.hashCode[i]
})
// 全部还原
this.markerID = {
marker: [],
polyline: [],
circle: [],
rectangle: [],
polygon: []
}
// 全部还原
this.villageList = {}
$('.villageList ul').html(`<li class="list-group-item">没有选中小区</li>`)
}
// 删除指定的数据
delFilterList(id, domclass?) {
if (domclass === 'filterList') {
delete this.villageFilterList[id]
this.listNum('filterListmodal', 'del')
} else {
delete this.villageList[id]
this.listNum('selectMapId', 'del')
}
}
// 计算选中个数
listNum(domclass?, type?) {
if (domclass === 'filterListmodal') {
let listNum = this.villageFilterList ? Object.keys(this.villageFilterList).length : 0
$('#filterListmodal .listNum').html(listNum)
if (listNum === 0 && type === 'del') {
this.mapresetClose()
//关闭对话框
$('#filterListmodal').modal('hide');
}
} else {
let listNums = this.villageList ? Object.keys(this.villageList).length : 0
$('#selectMapId .listNum').html(listNums)
$('button[data-target="#selectMapId"] .listNum').html(listNums > 0 ? listNums : '')
if (listNums === 0 && type === 'del') this.mapreset()
}
}
// 将指传递到input
input(keysStr?) {
const inputVid = $('input[name="v_id"]')
inputVid.val(keysStr)
inputVid.trigger('change')
}
// 根据条件筛选小区
filter() {
// 获取指定的值
let vtype: any
if ($('select[name="vtype"]').length) {
vtype = $('select[name="vtype"]').val()
vtype = vtype ? vtype.join(',') : ''
}
// 需要将缓存全部删除掉
$('#selectMapId .mapreset').trigger('click')
//清除标注
this.selectMap.clearOverlays()
// 提交后端
this.ajaxlnglatList(this.selectMap, {
id: '',
province: this.selectProv,
city: this.selectCity,
district: this.selectDist,
vtype: vtype,
allinfo: 'all'
}, true)
// 调整地图核心位置
this.citySyncMap(this.selectMap, this.level())
}
}
// @ts-ignore
export function bmaps() {
// 模态框
if ($('#modalmap').length) {
new modalMap()
} else if ($('#showmap').length) {
// 展示形式
new showMap()
} else if ($('#selectMap').length) {
// 地图选择形式
// $('button[data-target="#selectMapId"]').on('click', () => {})
// 目前的形式地图只初始化一次,模态框关闭不影响二次打开继续之前的操作
new selectMap()
// 测试时自动启动模态框
// $('button[data-target="#selectMapId"]').click()
}
}
}