/*``
* @Author: tjc
* @Date: 2017-04-20 17:03:05
* @Last Modified by: hydata
* @Last Modified time: 2018-05-10 17:11:35
* @Email: 304861063@qq.com
* @File Path: F:\work\hyMap\src\components\layer\buildingLayer.js
* @File Name: clustersLayer.js
* @Descript:雷达图查询图层
*/
import mapboxgl from 'mapbox-gl';
import baseLayer from './baseLayer';
import baseUtil from '../../util/baseUtil';
import radarLayer from './radarLayer';
const turf = require('../../tools/turf');
class QueryLayer extends baseLayer {
/**
* 初始化
* @param options
* @extends baseLayer
*/
constructor(options) {
super(options);
this.id = 'hy-queryLayer-' + baseUtil.guid();
this.center = [0, 0];
this.minRadius = 0.05;
this.maxRadius = 10;
this.radius = this.minRadius;
this.queryLayers = [];
this.marker;
this.threebox = options.threebox;
this.init();
this.isLoad = false;
}
init() {
}
/**
* 初始化数据
*/
initData() {
return {
'id': this.id,
'type': 'fill',
'source': {
'type': 'geojson',
'data': {}
},
'layout': {},
'paint': {
'fill-color': 'rgb(14,139,225)',
'fill-opacity': 0.2,
'fill-outline-color': '#059639'
}
};
}
/**
* 加载雷达
* @param {*} center
* @param {*} radius
*/
initRadar(center, radius) {
if (this.radar) {
this.radar.showRadarLayer();
} else {
this.radar = new radarLayer({
threebox: this.threebox,
map: this.map,
center: center,
radius: radius,
color: '#ff0000'
});
}
}
/**
* 设置雷达半径
* @param {*} newRadius
*/
setRadarRadius(newRadius) {
// this.radar && this.radar.changeRadius(this.center, newRadius);
this.radar && this.radar.setRadarOptions(this.center, newRadius);
}
/**
* 设置空间查询半径
* @param {*} radius
*/
setCoords(radius) {
this.radius = radius;
this.setMarker(radius);
const circle = turf.circle(this.center, radius,
{
steps: 72,
units: 'kilometers',
properties: { id: 'circlePolygon', value: 'circle' }
});
if (this.showRadar) {
this.setRadarRadius(radius);
} else {
if (this.isLoad) {
this.map.getSource(this.id).setData(circle);
} else {
this.geojson = this.initData();
this.geojson.source.data = circle;
this.addLayer(this.geojson);
this.isLoad = true;
}
}
return circle;
}
/**
* 设置半径
* @param {*} radius
* @param {*} relative
*/
setRadius(radius, relative = false) {
this.map.fire('drawStart', {
radius,
center: this.center
});
if (relative) {
radius = this.radius + radius;
}
if (radius < this.minRadius) {
radius = this.minRadius;
console.error('半径不能小于' + this.minRadius);
}
const circle = this.setCoords(radius);
this.query(circle);
}
/**
* 增加拖拽标记
*/
addMarker() {
//获取图标容器
let el = document.createElement('div');
el.className = 'queryBtn';
//显示雷达半径
this.label = document.createElement('span');
this.label.className = 'text';
this.label.innerHTML = this.radius * 1000 + 'm';
let btn = document.createElement('span');
btn.className = 'btn';
let close = document.createElement('span');
close.innerHTML = '×';
close.className = 'close';
el.appendChild(btn);
el.appendChild(this.label);
el.appendChild(close);
close.addEventListener('mousedown', (event) => {
this.clear();
event.stopPropagation();
});
let mouseMove = false;
//对图标添加拖拽监听,放大缩小雷达
el.addEventListener('mousedown', (event) => {
mouseMove = true;
event.stopPropagation();
});
// 将图标放置至地图上
let markerPosition = turf.transformTranslate(this.centerPoint, this.radius, 90);
this.marker = new mapboxgl.Marker(el).setLngLat(markerPosition.geometry.coordinates).addTo(this.map);
//注册事件
this.map.on('mousemove', (ev) => {
if (mouseMove) {
const to = turf.point([ev.lngLat.lng, this.center[1]]);
let distance = turf.distance(this.centerPoint, to, { units: 'kilometers' });
if (distance >= this.minRadius && distance <= this.maxRadius) {
this.setCoords(distance);
}
}
});
this.map.on('mouseup', () => {
if (mouseMove) {
this.setRadius(this.radius);
mouseMove = false;
}
});
}
/**
* 设置标注位置
* @param distance
*/
setMarker(distance) {
let position = turf.transformTranslate(this.centerPoint, distance, 90);
this.label.innerHTML = distance * 1000 > 3000 ? distance.toFixed(2) + 'km' : (distance * 1000).toFixed(0) + 'm';
this.marker.setLngLat(position.geometry.coordinates);
}
/**
* 查询
* @param geometry
*/
query(geometry) {
if (this.map.realReady) {
let style = this.map.getStyle();
let sources = style.sources;
let result = {};
for (let i in sources) {
let source = sources[i];
// if (layers[i].type !== 'line' && layers[i].metadata && layers[i].metadata['hy_key'] === 'hyLayer') {
if (source.type === 'geojson' && source.data['_LKey'] === 'hyLayer') {
//空间过滤
if (source.data.features.length > 0 && source.data.features[0].geometry.type === 'Point') {
let features = turf.pointsWithinPolygon(source.data, geometry);
if (features.features.length > 0) {
result[i] = features.features;
}
}
}
}
this.queryResult = result;
this.queryFun && this.queryFun({ result, geometry });
} else {
setTimeout((geometry) => {
this.query(geometry);
}, 100);
}
}
/**
* 设置空间查询回调
* @param {Function} fun function
*/
setQueryFun(fun) {
if (fun) {
this.queryFun = fun;
}
}
/**
*获取查询结果
* @returns {{}|*}
*/
getQueryResult() {
return this.queryResult;
}
/**
*空间查询
* @param {Array} center 中心点
* @param {Number} radius 半径
* @param {Boolean} radar 展示动画
* @param {Number} maxRadius 最小半径
* @param {Number} minRadius 最大半径
* @param {Boolean} showMoveSign 显示拖动标记
* @param {Array} layers 查询图层
* @param {requestCallback} result 查询结果回调
*/
spatialQuery({
center = [0, 0],
radius = 100,
radar = false,
maxRadius = 20,
minRadius = 0.05,
showMoveSign = true,layers, result
} = {}) {
this.maxRadius = maxRadius;
this.minRadius = minRadius;
radius /= 1000;
radius = radius < this.minRadius ? this.minRadius : radius;
radius = radius > this.maxRadius ? this.maxRadius : radius;
this.radius = radius;
this.center = center;
this.centerPoint = turf.point(center);
if (!this.marker && showMoveSign) {
this.addMarker(center, radius);
}
if (radar) {
this.showRadar = true;
this.initRadar(center, radius);
}
this.setQueryFun(result);
this.setRadius(radius);
}
/**
* 清空查询结果
*/
clear() {
this.isLoad = false;
this.marker && this.marker.remove();
this.marker = null;
if (this.radar) {
this.radar.clear();
} else {
this.dispose();
}
this.map.fire('drawClear');
}
}
export default QueryLayer;