引入地图插件
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode: '自己的密钥'
}
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=自己的key&plugin=AMap.Geocoder&plugin=AMap.MouseTool&plugin=AMap.DistrictSearch&plugin=AMap.PolyEditor"></script>
<script type="text/javascript" src="https://webapi.amap.com/ui/1.1/main.js"></script>
海量点
AMapUI.load(['ui/misc/PointSimplifier', "lib/$"], (DistrictCluster, PointSimplifier, $) => {
this.PointSimplifier = new PointSimplifier({
map: this.map, // 所属的地图实例
autoSetFitView: false, // 禁止自动更新地图视野
zIndex: 110,
maxChildrenOfQuadNode: 50,
getPosition: function(item) { // item为数据源的每一项元素
if (!item) {
return null
}
return [item.lng, item.lat] // 返回经纬度
},
getHoverTitle: function(dataItem) {
return '设备编号:' + dataItem.vehicleNo
},
renderOptions: {
pointStyle: { // 点的样式
width: 6,
height: 6,
fillStyle: '#00f'
},
hoverTitleStyle: { // 鼠标hover时的title信息
position: 'top'
}
}
})
// 添加点击事件
this.PointSimplifier.on('pointClick', (e, point) => this.markerClick(point.data))
// 加载数据,data为数据源,是一个数组
this.PointSimplifier.setData(data)
})
行政区划聚合
普通显示
// 加载区划聚合相关组件
AMapUI.load(['ui/geo/DistrictCluster', 'lib/$'], (DistrictCluster, $) => {
const distCluster = new DistrictCluster({
map: this.map, // 所属的地图实例
zIndex: 11,
autoSetFitView: false, // 禁止自动更新地图视野
getPosition: function(item) {
if (!item) {
return null
}
// 返回经纬度
return [parseFloat(item.lng), parseFloat(item.lat)]
},
renderOptions: {
featureEventSupport: true,
getClusterMarkerPosition:DistrictCluster.ClusterMarkerPositionStrategy.AVERAGE_POINTS_POSITION,
clusterMarkerEventSupport: true,
// 标注信息Marker上需要监听的事件
clusterMarkerEventNames: ["click"],
// 统计数为0的区域不显示
getClusterMarker: function (feature, dataItems, recycledMarker) {
let container, title, body
const nodeClassNames = {
title: "amap-ui-district-cluster-marker-title",
body: "amap-ui-district-cluster-marker-body",
container: "amap-ui-district-cluster-marker"
};
if (recycledMarker) {
container = recycledMarker.getContent()
title = $(container).find("." + nodeClassNames.title)[0]
body = $(container).find("." + nodeClassNames.body)[0]
} else {
container = document.createElement("div")
title = document.createElement("span")
title.className = nodeClassNames.title
body = document.createElement("span")
body.className = nodeClassNames.body
container.appendChild(title)
body.style.boxSizing = "content-box"
title.style.boxSizing = "content-box"
container.style.boxSizing = "content-box"
container.appendChild(body)
}
const props = feature.properties, routeNames = []
const classNameList = [
nodeClassNames.container,
"level_" + props.level,
"adcode_" + props.adcode
];
container.className = classNameList.join(" ")
if (routeNames.length > 0) {
routeNames.push(props.name)
container.setAttribute("title", routeNames.join(">"))
} else {
container.removeAttribute("title")
}
$(title).html(props.name);
$(body).html(dataItems.length)
const resultMarker = recycledMarker || new AMap.Marker({
topWhenClick: true,
offset: new AMap.Pixel(-20, -30),
content: container
});
if (dataItems.length > 0) {
return resultMarker
}
},
// 基础样式
featureStyle: {
fillStyle: "rgba(250,250,250,0)", // 填充色
lineWidth: 0, // 描边线宽
hoverOptions: { // 鼠标Hover后的样式
fillStyle: "rgba(255,255,255,0.2)"
}
},
// 特定区划级别的默认样式
featureStyleByLevel: {
// 全国
country: {
fillStyle: "rgba(250,250,250,0)"
},
// 省
province: {
fillStyle: "rgba(250,250,250,0)"
},
//市
city: {
fillStyle: "rgba(250,250,250,0)"
},
//区县
district: {
fillStyle: "rgba(250,250,250,0)"
}
}
}
});
this.distCluster = distCluster
this.distCluster.setData(data) // data为数据源数组
// 如果是最后一级则获取数据
distCluster.on('clusterMarkerClick', (e, record) => {
if (record.feature.properties.level != 'district') {
return
}
this.loadData()
})
})
鼠标移入区域显示区域聚合,移出则不显示
基于普通显示实现
window.AMapUI.load(["ui/geo/DistrictExplorer", "lib/$"], (DistrictExplorer, $) => {
const districtExplorer = new DistrictExplorer({
eventSupport: true, // 打开事件支持
map: this.map,
});
districtExplorer.loadAreaNode(100000, (error, areaNode) => {
districtExplorer.setAreaNodesForLocating([areaNode])
});
// 移入区域时显示区域聚合,移出后不显示
districtExplorer.on('featureMouseover', (e, feature) => {
const prop = feature.properties
if (prop.name === this.provinceName) {
return
}
this.provinceName = prop.name
// this.allData是数据源数组
// item.province === prop.name 是数据过滤规则,根据自己的业务需求而定
this.distCluster.setData(this.allData.filter(item => item.province === prop.name))
})
// 移出区域时切换或清除区域聚合
districtExplorer.on('featureMouseout', () => {
this.distCluster.setData([])
this.provinceName = ''
})
})
Map 类
setFitView
-
为什么setFitView有时无效
原因:setFitView只对地图覆盖物生效。
地图覆盖物只包括以下几类:
所以不属于以上几类(如信息窗体、海量点、聚合之类)的话,setFitView就不会生效。
解决方案:
示例代码:
// 获取所有数据
getAllData() {
queryAreaList(this.listQuery).then(resData => {
const data = resData.data.data.filter(item => item.encLon && item.encLat)
this.PointSimplifier.setData(data)
if (data.length) { // 若有数据则适配显示所有海量点
this.map.setBounds(this.getDataBounds({dataList: data}))
} else { // 若无数据则重置地图
this.map.setZoomAndCenter(this.mapConfig.zoom, this.mapConfig.center)
}
});
},
/**
* 获取地图显示范围
* dataList: Array 数据源数组,数组的元素类型为Object,如:{encLon: 123, encLat: 456}
* lngKey: [String, Number] 经度字段
* latKey: [String, Number] 纬度字段
* offset: Number 偏移量
* @return {Array} 地图显示范围二维数组
*/
getDataBounds({dataList, lngKey = 'encLon', latKey = 'encLat', offset = 0.8}) {
const first = dataList[0]
let east = first[lngKey]
let south = first[latKey]
let west = first[lngKey]
let north = first[latKey]
for (let i = 1; i < dataList.length; i++) {
const data = dataList[i]
if (data[lngKey] > east) {
east = data[lngKey]
}
if (data[lngKey] < west) {
west = data[lngKey]
}
if (data[latKey] < south) {
south = data[latKey]
}
if (data[latKey] > north) {
north = data[latKey]
}
}
return new AMap.Bounds([west - offset, south - offset], [east + offset, north + offset])
},
未完待续...