class DemoAMap {
|
constructor(id, opt, fn) {
|
this.demo = demo
|
this.option = demo.copy(Object.assign({
|
icons: [] // 图标库
|
}, (opt || {})))
|
let f = null;
|
if (!AMap.v || !this.demo.version) {
|
f = this.code('AMap OR demo is null')
|
fn ? fn(f) : null
|
return f
|
}
|
id = id || '#map'
|
this.id = id
|
this.ids = id.replace('#', '')
|
if (!this.demo.$.id(this.ids)) {
|
f = this.code('dom is null')
|
fn ? fn(f) : null
|
return f
|
}
|
let init = function (opt) {
|
// 默认配置
|
let os = {
|
rotation: 0, features: ['bg', 'road', 'point'], showBuildingBlock: !0, zoom: opt.zoom || 13
|
}
|
if (opt.layer && opt.layer.length && opt.layer.indexOf(3) >= 0) {
|
os.viewMode = '3D'
|
os.pitch = 60
|
}
|
return os
|
}
|
// 初始化
|
this.map = new AMap.Map(this.ids, init(this.option));
|
this._init()
|
fn ? fn(this.code('success', 1, {
|
map: this.map
|
})) : null
|
}
|
code(err, c, d) {
|
return { err, code: c || 0, data: d || {} }
|
}
|
// 设置内置图表样式
|
style(s, fn) {
|
let ts = this
|
if (!ts.map) return
|
let q = (label, value) => { return { label, value } }
|
let v = [q('默认', 'normal'), q('幻影黑', 'dark'), q('月光银', 'light'),
|
q('远山黛', 'whitesmoke'), q('草色青', 'fresh'), q('雅士灰', 'grey'), q('涂鸦', 'graffiti')
|
, q('马卡龙', 'macaron'), q('靛青蓝', 'blue'), q('极夜蓝', 'darkblue'), q('酱籽', 'wine')]
|
let c = v.filter((r, v) => {
|
return isNaN(s) ? (r.value === s) : (v === +s)
|
})
|
if (!s || !c.length) {
|
let b = v.map((k, v) => {
|
k.id = v
|
return k
|
})
|
fn ? fn(ts.code('', 0, b)) : null
|
return b
|
}
|
c = c[0]
|
fn ? fn(ts.code('', 1, c)) : null
|
this.map.setMapStyle('amap://styles/' + c.value)
|
}
|
// 设置图层显示
|
features(s, f) {
|
if (!s) return ['bg', 'point', 'road', 'building']
|
if (!this.map) return
|
let d = this.map.getFeatures()
|
let q = (d.indexOf(s) >= 0)
|
if (!f) {
|
if (q) return
|
d.push(s)
|
} else {
|
if (!q) return
|
d = d.filter(r => { return r !== s })
|
}
|
this.map.setFeatures(d)
|
}
|
_init() {
|
this.use = {
|
polygon: !1,
|
circle: !1
|
}
|
this.list = {
|
polygon: [],
|
polygonEdit: [],
|
circle: [],
|
layer: [],
|
model: []
|
}
|
this.layer(this.option)
|
this.icons = this.option.icons || []
|
this.version = '0.05'
|
this.updateTime = '2021/06/05 18:00:00'
|
this.createTime = '2021/05/10 10:00:00'
|
}
|
_use_reset(name) {
|
for (let i in this.use) {
|
this.use[i] = !1
|
}
|
if (this.demo._is_obj(this.use[name]).code !== 7) {
|
this.use[name] = !0
|
}
|
}
|
_filter_list(name, num, id) {
|
let event = (this.list[name].filter(r => {
|
return r[(id || 'id')] === num
|
})[0] || {}).event
|
return event
|
}
|
_lngLat(e) {
|
let p = {
|
lng: e.lnglat.getLng(),
|
lat: e.lnglat.getLat()
|
}
|
p.path = [p.lng, p.lat]
|
return p
|
}
|
// 定位
|
center(lng, lat) {
|
this.map.setCenter([lng, lat])
|
}
|
clearMap(){
|
this.map.clearMap()
|
}
|
// --------------------------------------------------------- 绘制信息窗 ---------------------------------------------------------
|
model(opt, fn, html) {
|
let ts = this
|
opt = opt || {}
|
let f = null
|
if (!(opt.lng && opt.lat)) {
|
f = ts.code('定位出错:经纬度不存在')
|
fn ? fn(f) : null
|
return f
|
}
|
let id = opt.id || 'a-map-model-' + ts.demo.rand(4)
|
var infoWindow = new AMap.InfoWindow({
|
isCustom: true,
|
anchor: 'bottom-left',
|
content: html ? html(opt, id) : '这是信息窗体',
|
offset: new AMap.Pixel(-20, -40)
|
});
|
|
infoWindow.open(this.map, [+opt.lng, +opt.lat])
|
let r = {
|
event: infoWindow, opt, id: Date.now() + '-' + ts.demo.rand(4)
|
}
|
ts.list.model.push(r)
|
setTimeout(() => {
|
let dom = ts.demo.js('#' + id)
|
if (dom.dom) {
|
r.dom = dom
|
ts.demo.js(dom.find('.close'), 0).click(() => {
|
infoWindow.close()
|
ts.list.model = ts.list.model.filter(s => {
|
return s.id !== r.id
|
})
|
fn ? fn(ts.code('close', 2, {})) : null
|
})
|
fn ? fn(ts.code('', 1, r)) : null
|
}
|
}, 800);
|
return r
|
}
|
// --------------------------------------------------------- 绘制图层 ---------------------------------------------------------
|
layer(opt, fn) {
|
// new AMap.TileLayer.Satellite() // 卫星
|
// new AMap.TileLayer.RoadNet() // 路网
|
// new AMap.TileLayer.Traffic() // 实时路况
|
// new AMap.Buildings({ // 楼块图层
|
// zooms: [16, 18],
|
// zIndex: 10,
|
// heightFactor: 2//2倍于默认高度,3D下有效
|
// })
|
let ts = this
|
let a = ['实时路况', '路网', '卫星', '楼块']
|
let old = ts.list.layer || []
|
if (old.length) {
|
old.forEach(r => {
|
ts.map.remove(r.event)
|
})
|
ts.list.layer = []
|
}
|
if (opt.layer && opt.layer.length) {
|
opt.layer.forEach(v => {
|
let lay = null
|
switch (+v) {
|
case 0:
|
lay = new AMap.TileLayer.Traffic()
|
break;
|
case 1:
|
lay = new AMap.TileLayer.RoadNet()
|
break;
|
case 2:
|
lay = new AMap.TileLayer.Satellite()
|
break;
|
case 3:
|
lay = new AMap.Buildings({
|
zooms: [16, 18],
|
heightFactor: 2,
|
opacity: 0.5
|
})
|
ts.map.setPitch(60)
|
break;
|
default:
|
}
|
ts.list.layer.push({ id: +v, event: lay })
|
})
|
ts.map.add(ts.list.layer.map(r => { return r.event }))
|
fn ? fn() : null
|
}
|
return a.map((r, v) => { return { id: v, text: r } })
|
}
|
// --------------------------------------------------------- 绘制点 ---------------------------------------------------------
|
circle_check_ico(name) {
|
let ts = this
|
let ico = ts.icons.filter(r => {
|
return r.name === name && r.offset.length
|
})[0] || {}
|
let oo = { name: ico.name }
|
if (ico.name) {
|
oo.icon = ico.icon
|
oo.offset = new AMap.Pixel(ico.offset[0] || 0, ico.offset[1] || 0)
|
}
|
return oo
|
}
|
circle_dot(event, name, type) {
|
let ts = this
|
let ico = ts.circle_check_ico(name)
|
if (ico.name) {
|
ts.circleAll(type, function (arr, event) {
|
if (event.length) {
|
event.forEach(r => {
|
let ov = ts.circle_check_ico(r.data.opt.iconName)
|
if (ov.name) {
|
r.event.setIcon(ov.icon)
|
r.event.setOffset(ov.offset)
|
}
|
})
|
}
|
})
|
event.setIcon(ico.icon)
|
event.setOffset(ico.offset)
|
}
|
}
|
_circle_handler(e, fn, fs) {
|
let ts = this
|
|
let create = function (o) {
|
let id = o.id || 'circle-' + Date.now()
|
let oo = {
|
position: new AMap.LngLat(o.lng, o.lat),
|
title: o.title || '',
|
extData: { id, opt: o }
|
}
|
let ico = ts.circle_check_ico(o.iconName)
|
if (ico.name) {
|
oo.icon = ico.icon
|
oo.offset = ico.offset
|
}
|
var event = new AMap.Marker(oo);
|
ts.map.add(event)
|
let f = { id, event, type: o.type, data: event.getExtData() }
|
ts.list.circle.push(f)
|
|
if (o.label) {
|
let ol = o.labelData || {
|
offset: new AMap.Pixel(0, 0),
|
content: "<div data-amap-circle-label>" + o.label + "</div>",
|
direction: 'center'
|
}
|
event.setLabel(ol)
|
}
|
// 点击事件 点击自己触发
|
event.on('click', () => {
|
ts.center(o.lng, o.lat)
|
fn ? fn(f) : null
|
})
|
if (fs) {
|
fn ? fn(f) : null
|
}
|
}
|
if (e.pointer) {
|
create(e)
|
} else {
|
let p = ts._lngLat(e)
|
create(Object.assign(e, { type: 'circle', title: '新的' }, p))
|
}
|
}
|
// 创建点
|
circle(opt, fn) {
|
let ts = this
|
opt = opt || {}
|
ts._use_reset('circle')
|
ts.use.polygon = !!opt.polygon
|
|
if (opt.close) {
|
ts.map.off('click', ts._circle_handler)
|
ts._use_reset('')
|
ts.use.polygon = !!opt.polygon
|
return 0
|
}
|
|
if (opt.lng && opt.lat) {
|
if (opt.type === 'polygon') {
|
let r = opt.newPath[opt.newPath.length - 1]
|
this._circle_handler(Object.assign(opt, r, { pointer: 1 }))
|
} else if (ts.demo._is_obj(opt.lng).code === 4) {
|
opt.lng.forEach((r, v) => {
|
this._circle_handler({ lng: r, lat: opt.lat[v], type: opt.type, pointer: 1 }, e => {
|
fn ? fn(e) : null
|
})
|
})
|
} else {
|
opt.pointer = 1
|
this._circle_handler(opt, e => {
|
fn ? fn(e) : null
|
})
|
}
|
} else {
|
if (opt.clear) {
|
// 删除旧的
|
ts.circleDel('circle')
|
}
|
if (opt.close) return 0
|
ts.map.on('click', ts._circle_handler, ts)
|
}
|
}
|
// 删除点
|
circleDel(type) {
|
let ts = this
|
ts.list.circle.filter(r => {
|
return r.type === type
|
}).map(r => { return r.event }).forEach(v => {
|
ts.map.remove(v)
|
})
|
ts.list.circle = ts.list.circle.filter(r => {
|
return r.type === type
|
})
|
}
|
// 获取所有点
|
circleAll(type, fn) {
|
let ts = this
|
let arr = []
|
let eve = []
|
ts.circle({ close: 1 })
|
ts.list.circle.filter(r => {
|
return r.type === type
|
}).map(r => { return r.event }).forEach(v => {
|
let d = v.getExtData()
|
arr.push(d)
|
eve.push({ event: v, data: d })
|
})
|
fn ? fn(arr, eve) : null
|
return arr
|
}
|
// --------------------------------------------------------- 绘制多边形 ---------------------------------------------------------
|
// 多边形
|
polygon(opt, fn, center) {
|
let ts = this
|
// 绘制多边形
|
ts._use_reset('polygon')
|
ts.circle({ close: 1 })
|
|
// 检测配置
|
opt = opt || {}
|
let newPath = [] // 点击取点数据
|
|
let clickHandler = function (e) {
|
arrPush(ts._lngLat(e))
|
}
|
let arrPush = function (a) {
|
newPath.push(a)
|
let lng = ts.demo.array(newPath.map(r => { return r.lng })).unique()
|
let lat = ts.demo.array(newPath.map(r => { return r.lat })).unique()
|
if (lng.length !== newPath.length) {
|
fn ? fn(ts.code('经度不可选同一个点')) : null
|
newPath.splice(-1, 1)
|
return 0
|
}
|
if (lat.length !== newPath.length) {
|
fn ? fn(ts.code('纬度不可选同一个点')) : null
|
newPath.splice(-1, 1)
|
return 0
|
}
|
// 生成点标记 a
|
ts.circle({ polygon: 1, lng, lat, opt, newPath, type: 'polygon' })
|
|
// 生成多边形
|
if (newPath.length >= 3) {
|
// 取消生成的点标记
|
ts.map.off('click', clickHandler)
|
run(newPath.map(r => { return r.path }), opt)
|
|
ts.circleDel('polygon')
|
newPath = []
|
}
|
}
|
|
let run = function (path, opt) {
|
let id = Date.now()
|
let con = opt.poyConfig || {}
|
var polygon = new AMap.Polygon({
|
path,
|
fillColor: con.color || '#fff', // 多边形填充颜色
|
fillOpacity: 0.5,
|
strokeOpacity: con.opacity || 0.6,
|
strokeWeight: con.lineWidth || 2, // 线条宽度,默认为 1
|
strokeColor: con.line || 'cyan', // 线条颜色
|
extData: { path, opt, id }
|
});
|
ts.map.add(polygon)
|
// 缩放地图到合适的视野级别
|
if (!center) {
|
ts.map.setFitView([polygon])
|
}
|
// ts.map.setZoom(16)
|
var polyEditor = new AMap.PolyEditor(ts.map, polygon)
|
// 编辑
|
polyEditor.open()
|
ts.list.polygon.push({ id, event: polygon })
|
ts.list.polygonEdit.push({ id, event: polyEditor })
|
ts.use.polygon = !0
|
fn ? fn(ts.code('success', 1, {
|
id, area: polygon.getArea(), path: polygon.getPath().map(r => {
|
return { lng: r.lng, lat: r.lat }
|
}), data: opt, event: polygon, edit: polyEditor
|
})) : null
|
|
}
|
|
// 已存在数据
|
if (opt.path && opt.path.length >= 3) {
|
run(opt.path, opt)
|
} else {
|
// 定位 开始点击 3个点
|
ts.map.on('click', clickHandler)
|
}
|
|
}
|
// 多边形结束编辑
|
polygonEnd(opt, fn) {
|
let ts = this
|
if (!ts.use.polygon) {
|
fn ? fn(ts.code('polygon no edit')) : null
|
return 0
|
}
|
opt = opt || {}
|
let edit = ts._filter_list('polygonEdit', opt.id)
|
|
if (!edit) return 0
|
|
edit.close()
|
// 点击 自己 进入 编辑状态
|
|
let event = ts._filter_list('polygon', opt.id)
|
|
let fns = function () {
|
edit.open()
|
ts.use.polygon = !0
|
event.off('click', fns)
|
}
|
ts.use.polygon = !1
|
if (opt.click) {
|
event.on('click', fns)
|
}
|
}
|
// 多边形提交
|
polygonSubmit(opt, fn, tp) {
|
let ts = this
|
if (!tp) {
|
ts.polygonEnd(opt)
|
}
|
let event = ts._filter_list('polygon', opt.id)
|
if (!event) {
|
fn ? fn(ts.code('event is undefined')) : null
|
return 0
|
}
|
let obj = {
|
path: event.getPath().map(r => {
|
return { lng: r.lng, lat: r.lat }
|
}),
|
area: event.getArea()
|
}
|
fn ? fn(this.code('', 1, obj)) : null
|
return obj
|
}
|
// 多边形删除
|
polygonDel(opt, fn) {
|
let ts = this
|
ts.polygonEnd(opt)
|
let event = ts._filter_list('polygon', opt.id)
|
if (!event) {
|
fn ? fn(ts.code('event is undefined')) : null
|
return 0
|
}
|
ts.map.remove(event)
|
fn ? fn(this.code('', 1)) : null
|
}
|
// 多边形实时获取
|
polygonGets(id, fn) {
|
let ts = this
|
let edit = ts._filter_list('polygonEdit', id)
|
|
if (!edit) return 0
|
|
edit.on('adjust', function () {
|
ts.polygonSubmit({ id }, vs => {
|
fn ? fn(ts.code(vs.err, vs.code, vs.data)) : null
|
}, true)
|
})
|
}
|
// 多边形配置
|
polygonOption(opt) {
|
let ts = this
|
opt = opt || {}
|
let event = ts._filter_list('polygon', opt.id)
|
if (!event) return 0
|
|
let con = opt.config || {}
|
|
event.setOptions({
|
fillColor: con.color || '#fff', // 多边形填充颜色
|
fillOpacity: con.bgcOpacity || 0.5,
|
strokeOpacity: con.opacity || 0.6,
|
strokeWeight: con.lineWidth || 2, // 线条宽度,默认为 1
|
strokeColor: con.line || 'cyan', // 线条颜色
|
})
|
|
return event.getOptions()
|
}
|
// 多边形删除所有
|
polygonDelAll() {
|
let ts = this
|
if (ts.list.polygon.length) {
|
ts.list.polygon.forEach(v => {
|
ts.map.remove(v.event)
|
})
|
}
|
return ts
|
}
|
// --------------------------------------------------------- 其他 ---------------------------------------------------------
|
// ip定位获取当前城市
|
ip(fn) {
|
let ts = this
|
AMap.plugin('AMap.CitySearch', function () {
|
var citySearch = new AMap.CitySearch()
|
citySearch.getLocalCity(function (status, result) {
|
if (status === 'complete' && result.info === 'OK') {
|
// 查询成功,result即为当前所在城市信息
|
fn ? fn(ts.code('', 1, {
|
code: result.adcode,
|
city: result.city,
|
province: result.province,
|
})) : null
|
} else { fn ? fn(ts.code(status + ':' + JSON.stringify(result), 0, { status, result })) : null }
|
})
|
})
|
}
|
// 经纬度查地址信息
|
address(opt, fn) {
|
opt = opt || {}
|
let ts = this
|
let init = function (code) {
|
AMap.plugin('AMap.Geocoder', function () {
|
var geocoder = new AMap.Geocoder({
|
// city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
|
city: code
|
})
|
|
var v = opt.path || [0, 0]
|
|
geocoder.getAddress(v, function (status, result) {
|
if (status === 'complete' && result.info === 'OK') {
|
// result为对应的地理位置详细信息
|
let os = {
|
address: result.regeocode.formattedAddress,
|
detail: result.regeocode.addressComponent,
|
path: v,
|
ext: opt,
|
city: code
|
}
|
fn ? fn(ts.code('', 1, os)) : null
|
} else {
|
fn ? fn(ts.code(status, 0, { status, result })) : null
|
}
|
})
|
})
|
}
|
if (!opt.code) {
|
ts.ip(e => {
|
if (e.code) {
|
// e.data.code
|
init(e.data.code)
|
} else { ts.demo.toast(e.err) }
|
})
|
} else {
|
init(opt.code)
|
}
|
}
|
// poi 搜索
|
poi(opt, fn) {
|
opt = opt || {}
|
let ts = this
|
let init = function (code) {
|
var placeSearch = new AMap.PlaceSearch({
|
// city 指定搜索所在城市,支持传入格式有:城市名、citycode和adcode
|
city: code,
|
pageSize: opt.limit || 10,
|
pageIndex: opt.page || 1,
|
citylimit: opt.citylimit || !1
|
})
|
placeSearch.search(opt.search, function (status, result) {
|
// 查询成功时,result即对应匹配的POI信息
|
if (status === 'complete' && result.info === 'OK') {
|
let c = result.poiList || {}
|
let os = {
|
count: c.count,
|
total: Math.ceil(c.count / c.pageSize),
|
limit: c.pageSize,
|
page: c.pageIndex,
|
list: (c.pois || []).filter(r => { return r.name && r.address && ts.demo._is_obj(r.address).code === 3 }).map(v => {
|
v.lng = (v.location || {}).lng
|
v.lat = (v.location || {}).lat
|
v.title = v.name
|
return v
|
}),
|
city: code,
|
ext: opt,
|
search: opt.search
|
}
|
c = null
|
fn ? fn(ts.code('', 1, os)) : null
|
} else {
|
fn ? fn(ts.code(status, 0, { status, result })) : null
|
}
|
})
|
}
|
if (!opt.code) {
|
ts.ip(e => {
|
if (e.code) {
|
// e.data.code
|
init(e.data.code)
|
} else { ts.demo.toast(e.err) }
|
})
|
} else {
|
init(opt.code)
|
}
|
}
|
// zoom 增减
|
zoom(n) {
|
let a = this.map.getZooms()
|
let b = this.map.getZoom()
|
let c = n ? (b += 1) : (b -= 1)
|
c = c >= a[1] ? a[1] : c <= a[0] ? a[0] : c
|
this.map.setZoom(c)
|
return c
|
}
|
}
|