// 地图初始化
initMap() {
let vm = this;
//地图加载
this.map = new AMap.Map("map", {
viewMode: "2D",
zoom: 4,
center: [105, 36],
resizeEnable: true
});
let autoOptions = {
input: "tipinput"
};
AMap.plugin(
[
"AMap.PlaceSearch",
"AMap.AutoComplete",
"AMap.Geocoder",
"AMap.HeatMap"
],
function() {
// 输入时会出现提示
var auto = new AMap.Autocomplete(autoOptions);
// 地理编码
vm.geocoder = new AMap.Geocoder({});
vm.heatmap = new AMap.HeatMap(vm.map, {
radius: 50, //给定半径
opacity: [0, 0.8]
});
function debounce(func, wait, immediate) {
let timeout;
const debounced = function() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
debounced.cancel = () => {
clearTimeout(timeout);
};
return debounced;
}
const index = new Supercluster({
minZoom: 0, // min zoom to generate clusters on
maxZoom: 21, // max zoom level to cluster the points on
minPoints: 1, // minimum points to form a cluster
radius: 40, // cluster radius in pixels
extent: 512, // tile extent (radius is calculated relative to it)
nodeSize: 64, // size of the KD-tree leaf node, affects performance
log: false, // whether to log timing info
// whether to generate numeric ids for input features (in vector tiles)
generateId: false,
// a reduce function for calculating custom cluster properties
reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }
// properties to use for individual points when running the reducer
map: props => props // props => ({sum: props.my_value})
});
index.load(vm.heatmapData.map(p => ({ ...p, x: p.lng, y: p.lat })));
let markers = [];
const render = () => {
let bounds = vm.map.getBounds();
if (bounds.toBounds) {
bounds = bounds.toBounds();
}
const bbox = [
bounds.southWest.lng,
bounds.southWest.lat,
bounds.northEast.lng,
bounds.northEast.lat
];
// bbox
const views = index.getClusters(bbox, vm.map.getZoom());
const clusters = views.filter(view => view.isClutser); // 多个点聚合之后的点
const data = views.filter(view => !view.isClutser); // 原始点
vm.heatmap.setDataSet({
data: clusters.map(c => ({ ...c, lng: c.x, lat: c.y })),
max: 15
});
};
render();
const listener = debounce(render, 200);
vm.map.on("zoom", listener);
vm.map.on("moveend", listener);
auto.on("select", select); //注册监听,当选中某条记录时会触发
function select(e) {
vm.address = e.poi.name;
vm.radius = "200";
vm.disable = false;
}
}
);
vm.map.off("dblclick", markerClick);
vm.map.on("dblclick", markerClick);
async function markerClick(e) {
console.log("dblclicke", e, e.lnglat);
vm.disable = false;
vm.radius = "200";
vm.pointLat = "";
vm.pointLng = "";
vm.lat = e.lnglat.lat ? e.lnglat.lat : "";
vm.lng = e.lnglat.lng ? e.lnglat.lng : "";
// 查询列表
vm.getList();
// 画圈
vm.setCirCle();
// vm.map.setFitView();
// 逆地理编码,经纬度解析
vm.geocoder.getAddress([vm.lng, vm.lat], function(status, result) {
if (status === "complete" && result.regeocode) {
vm.address = result.regeocode.formattedAddress;
}
});
}
vm.setMessPoint();
},
setCirCle() {
let vm = this;
let lng = vm.pointLng ? vm.pointLng : vm.lng;
let lat = vm.pointLat ? vm.pointLat : vm.lat;
if (this.circle) {
this.map.remove(this.circle);
}
this.circle = new AMap.Circle({
center: new AMap.LngLat(lng, lat), // 圆心位置
radius: vm.radius ? vm.radius : 200, // 圆半径
fillColor: "transparent", // 圆形填充颜色
strokeColor: "red", // 描边颜色
strokeWeight: 2 // 描边宽度
});
vm.map.add(this.circle);
vm.map.setZoomAndCenter(14, [lng, lat]);
},
setMessPoint() {
let vm = this;
const markers = this.gatherPoint.map((point, index) => ({
lnglat: [point.lng, point.lat],
name: index,
style: index,
count: point.count,
pointLat: point.pointLat,
pointLng: point.pointLng
}));
var styles = [];
for (let n in this.gatherPoint) {
let point = this.getCountSize(this.gatherPoint[n].count);
styles.push({
// url: "https://webapi.amap.com/images/mass/mass0.png",
// url: "https://a.amap.com/jsapi_demos/static/images/mass2.png",
url: require("../../assets/image/circle2.png"),
anchor: new AMap.Pixel(6, 6),
size: new AMap.Size(point, point),
zIndex: 3,
opacity: 1
});
}
vm.mass = new AMap.MassMarks(markers, {
opacity: 0.8,
zIndex: 1111,
cursor: "pointer",
style: styles
});
function massClick(e) {
vm.pointLng = e.data.pointLng ? e.data.pointLng : "";
vm.pointLat = e.data.pointLat ? e.data.pointLat : "";
vm.lng = "";
vm.lat = "";
vm.disable = false;
vm.radius = "";
vm.getList();
vm.geocoder.getAddress(e.data.lnglat, function(status, result) {
if (status === "complete" && result.regeocode) {
vm.address = result.regeocode.formattedAddress;
}
});
}
vm.mass.off("click", massClick);
vm.mass.on("click", massClick);
var marker = new AMap.Marker({ content: " ", map: vm.map });
vm.mass.on("mouseover", function(e) {
marker.setPosition(e.data.lnglat);
marker.setLabel({ content: e.data.count });
});
vm.mass.on("mouseout", function(e) {
marker.setLabel({ content: "" });
});
vm.mass.setMap(this.map);
},
getCountSize(count) {
if (count >= 0 && count < 10) {
return 10 * 0.3;
} else {
let length = parseInt(count).toString().length; // 几位数
let multiple = Math.pow(10, length - 1); // 倍数
let hBit = parseInt(count / multiple); // 最高位
if (count >= 10 && count < 100) {
return (hBit + 1) * multiple * 0.153;
} else if (count >= 100 && count < 500) {
return (hBit + 1) * multiple * 0.078;
} else if (count >= 500) {
return (hBit + 1) * multiple * 0.066;
}
}
},
vm.geocoder.getLocation(vm.address, async function(status, result) {
// 输入的地址查询成功时
if (status === "complete" && result.geocodes.length) {
console.log("result", result);
const { lng, lat } = result.geocodes[0].location;
vm.lng = lng;
vm.lat = lat;
vm.pointLat = "";
vm.pointLng = "";
vm.getList();
await vm.queryAllGatherPoint();
await vm.getHeatMapData();
vm.setCirCle();
let paramArr = [];
let operation = "查询";
paramArr.push(this.paramObj1, this.paramObj2, this.paramObj3);
buryingOperation(paramArr, operation);
} else {
// 地址无法解析时提示错误并清空相关信息
if (!vm.address) {
vm.address = "";
vm.radius = "";
vm.pointLng = "";
vm.pointLat = "";
vm.lat = "";
vm.lng = "";
}
Message.error("根据地址查询位置失败");
}
});
}