UNPKG

@mapgis/webclient-es6-mapboxgl

Version:

478 lines (403 loc) 16.8 kB
import { Common } from '@mapgis/webclient-es6-service'; const { Zondy, copyAttributesWithClip } = Common; import {Theme as FeatureTheme} from './feature/Theme'; import {SmicBrokenLine} from './levelRender/SmicBrokenLine'; import {SmicPoint} from './levelRender/SmicPoint'; import {SmicPolygon} from './levelRender/SmicPolygon'; /** * @private * @class Zondy.Theme.ThemeVector * @classdesc 矢量专题要素类。 * @extends Zondy.Theme * @param {Zondy.Feature.Vector} data - 用户数据,的类型为矢量数据 feature。 * @param {Zondy.Layer} layer - 此专题要素所在图层。 * @param {Object} style - 样式。 * @param {Object} options - 创建专题要素时的可选参数。 * @param {number} [options.nodesClipPixel=2] - 节点抽稀像素距离, 单位:像素。 * @param {boolean} [options.isHoverAble=true] - 图形是否可 hover。 * @param {boolean} [options.isMultiHover=true] - 是否使用多图形高亮,isHoverAble 为 true 时生效。 * @param {boolean} [options.isClickAble=true] - 图形是否可点击。 * @param {Object} [options.highlightStyle] - 高亮样式。 */ class ThemeVector extends FeatureTheme { constructor(data, layer, style, options, shapeOptions) { super(data, layer); //数据的 geometry 属性必须存在且类型是 Zondy.Geometry 或其子类的类型 if (!data.fGeom) { return; } /** * @member {Zondy.Bounds} [Zondy.Theme.ThemeVector.prototype.dataBounds] * @description 用户数据的(feature.geometry)地理范围。 */ this.dataBounds = data.bound; /** * @member {number} [Zondy.Theme.ThemeVector.prototype.nodesClipPixel=2] * @description 节点抽稀像素距离。 */ this.nodesClipPixel = 2; /** * @member {boolean} [Zondy.Theme.ThemeVector.prototype.isHoverAble=true] * @description 图形是否可 hover。 */ this.isHoverAble = true; /** * @member {boolean} [Zondy.Theme.ThemeVector.prototype.isMultiHover=true] * @description 是否使用多图形高亮,isHoverAble 为 true 时生效。 */ this.isMultiHover = true; /** * @member {boolean} [Zondy.Theme.ThemeVector.prototype.isClickAble=true] * @description 图形是否可点击。 */ this.isClickAble = true; /** * @member {Object} [Zondy.Theme.ThemeVector.prototype.highlightStyle] * @description 高亮样式。 */ this.highlightStyle = null; /** * @member {Object} [Zondy.Theme.ThemeVector.prototype.shapeOptions] * @description 添加到渲染器前修改 shape 的一些属性,非特殊情况通常不允许这么做。 */ this.shapeOptions = {}; /** * @member {Object} [Zondy.Theme.ThemeVector.prototype.style] * @description 可视化图形的 style。在子类中规定其对象结构和默认属性值。 */ this.style = style || {}; this.CLASS_NAME = "Zondy.Theme.ThemeVector"; this.style = style ? style : {}; if (options) { copyAttributesWithClip(this, options, ["shapeOptions", "dataBounds"]) } if (shapeOptions) { copyAttributesWithClip(this.shapeOptions, shapeOptions); } //设置基础参数 dataBounds、lonlat、location var geometry = data.fGeom; this.lonlat = [(this.dataBounds.xmin + this.dataBounds.xmax) / 2.0, (this.dataBounds.ymin + this.dataBounds.ymax) / 2.0]; this.location = this.getLocalXY(this.lonlat); //将地理要素转为专题要素 switch (data.ftype) { case 0: break; case 1: this.pointsToTF(data.fGeom.PntGeom); break; case 2: this.linesToTF(data.fGeom.LinGeom) break; case 3: this.regsToTF(data.fGeom.RegGeom); break; } } /** * @function Zondy.Theme.ThemeVector.prototype.destroy * @override */ destroy() { this.style = null; this.dataBounds = null; this.nodesClipPixel = null; this.isHoverAble = null; this.isMultiHover = null; this.isClickAble = null; this.highlightStyle = null; this.shapeOptions = null; super.destroy(); } /** * @function Zondy.Theme.ThemeVector.prototype.pointsToTF * @description 转换点要素。 * @param {Zondy.Geometry} geometry - 用户数据几何地理信息,这里必须是点。 */ pointsToTF(geometry) { if (geometry == null || geometry.length <= 0) { return; } var components = geometry.components; //节点像素坐标 var localLX = []; //参考位置,参考中心为 var refLocal = []; var location = this.location; var pointList = []; //节点抽稀距离 var nCPx = this.nodesClipPixel; for (var i = 0; i < geometry.length; i++) { var components_i = geometry[i]; refLocal = []; localLX = this.getLocalXY([components_i.Dot.x, components_i.Dot.y]); refLocal[0] = localLX[0] - location[0]; refLocal[1] = localLX[1] - location[1]; //抽稀 if (pointList.length > 0) { var lastLocalXY = pointList[pointList.length - 1]; if ((Math.abs(lastLocalXY[0] - refLocal[0]) <= nCPx) && (Math.abs(lastLocalXY[1] - refLocal[1]) <= nCPx)) { continue; } } //使用参考点 pointList.push(refLocal); //赋 style var style = new Object(); style.r = 6; //防止漏设此参数,默认 6 像素 style = copyAttributesWithClip(style, this.style); style.x = refLocal[0]; style.y = refLocal[1]; //创建图形 var shape = new SmicPoint({ style: style, clickable: this.isClickAble, hoverable: this.isHoverAble }); //设置高亮样式 if (this.highlightStyle) { shape.highlightStyle = this.highlightStyle; } //设置参考中心,指定图形位置 shape.refOriginalPosition = location; //储存数据 id 属性,用于事件 shape.refDataID = this.data.FID; //储存数据 id 属性,用于事件-多图形同时高亮 shape.isHoverByRefDataID = this.isMultiHover; //修改一些 shape 可选属性,通常不需要这么做 if (this.shapeOptions) { copyAttributesWithClip(shape, this.shapeOptions); } this.shapes.push(shape); } } /** * @function Zondy.Theme.ThemeVector.prototype.lineToTF * @description 转换线要素。 * @param {Zondy.Geometry} geometry - 用户数据几何地理信息,这里必须是线。 */ linesToTF(geometry) { if (geometry == null || geometry.length <= 0) { return; } for (var i = 0; i < geometry.length; i++) { this.lineToTF(geometry[i]); } } lineToTF(geometry) { var components = []; if (geometry.Line != null && geometry.Line.Arcs != null && geometry.Line.Arcs.length > 0) { var arcs = geometry.Line.Arcs; for (var i = 0; i < arcs.length; i++) { var dots = arcs[i].Dots; for (var j = 0; j < dots.length; j++) { components.push([dots[j].x, dots[j].y]); } } } if (components.length <= 0) { return; } //节点像素坐标 var localLX = []; //参考位置,参考中心为 var refLocal = []; var location = this.location; var pointList = []; //节点抽稀距离 var nCPx = this.nodesClipPixel; for (var i = 0; i < components.length; i++) { var components_i = components[i]; refLocal = []; localLX = this.getLocalXY(components_i); refLocal[0] = localLX[0] - location[0]; refLocal[1] = localLX[1] - location[1]; //抽稀 - 2 px if (pointList.length > 0) { var lastLocalXY = pointList[pointList.length - 1]; if ((Math.abs(lastLocalXY[0] - refLocal[0]) <= nCPx) && (Math.abs(lastLocalXY[1] - refLocal[1]) <= nCPx)) { continue; } } //使用参考点 pointList.push(refLocal); } if (pointList.length < 2) { return null; } //赋 style var style = new Object(); style = copyAttributesWithClip(style, this.style, ['pointList']); style.pointList = pointList; //创建图形 var shape = new SmicBrokenLine({ style: style, clickable: this.isClickAble, hoverable: this.isHoverAble }); //设置高亮样式 if (this.highlightStyle) { shape.highlightStyle = this.highlightStyle; } //设置参考中心,指定图形位置 shape.refOriginalPosition = this.location; //储存数据 id 属性,用于事件 shape.refDataID = this.data.FID; //储存数据 id 属性,用于事件-多图形同时高亮 shape.isHoverByRefDataID = this.isMultiHover; //添加到渲染器前修改 shape 的一些属性,非特殊情况通常不允许这么做 if (this.shapeOptions) { copyAttributesWithClip(shape, this.shapeOptions); } this.shapes.push(shape); } /** * @function Zondy.Theme.ThemeVector.prototype.regsToTF * @description 转面要素。 * @param {Zondy.Geometry} geometry - 用户数据几何地理信息,这里必须是面。 */ regsToTF(geometry) { if (geometry == null || geometry.length <= 0) { return; } for (var i = 0; i < geometry.length; i++) { this.regToTF(geometry[i]); } } regToTF(geometry) { var components = geometry.Rings; if (components == null || components.length <= 0) { return; } //节点像素坐标 var localLX = []; //参考位置,参考中心为 var refLocal = []; var location = this.location; var pointList = []; //岛洞 var holePolygonPointList = []; var holePolygonPointLists = []; //节点抽稀距离 var nCPx = this.nodesClipPixel; for (var i = 0; i < components.length; i++) { if (i === 0) { // 第一个 component 正常绘制 pointList = []; if (components[i] != null && components[i].Arcs != null && components[i].Arcs.length > 0) { var arcs = components[i].Arcs; for (var j = 0; j < arcs.length; j++) { var dots = arcs[j].Dots; for (var k = 0; k < dots.length; k++) { refLocal = []; localLX = this.getLocalXY([dots[k].x, dots[k].y]); refLocal[0] = localLX[0] - location[0]; refLocal[1] = localLX[1] - location[1]; //抽稀 - 2 px if (pointList.length > 0) { var lastLocalXY = pointList[pointList.length - 1]; if ((Math.abs(lastLocalXY[0] - refLocal[0]) <= nCPx) && (Math.abs(lastLocalXY[1] - refLocal[1]) <= nCPx)) { continue; } } //使用参考点 pointList.push(refLocal); } } } } else { // 其它 component 作为岛洞 holePolygonPointList = []; if (components[i] != null && components[i].Arcs != null && components[i].Arcs.length > 0) { var arcs = components[i].Arcs; for (var j = 0; j < arcs.length; j++) { var dots = arcs[j].Dots; for (var k = 0; k < dots.length; k++) { refLocal = []; localLX = this.getLocalXY([dots[k].x, dots[k].y]); refLocal[0] = localLX[0] - location[0]; refLocal[1] = localLX[1] - location[1]; //抽稀 - 2 px if (holePolygonPointList.length > 0) { var lastXY = holePolygonPointList[holePolygonPointList.length - 1]; if ((Math.abs(lastXY[0] - refLocal[0]) <= nCPx) && (Math.abs(lastXY[1] - refLocal[1]) <= nCPx)) { continue; } } //使用参考点 holePolygonPointList.push(refLocal); } } } } if (holePolygonPointList.length < 2) { continue; } holePolygonPointLists.push(holePolygonPointList); } if (pointList.length < 2) { return; } //赋 style var style = {}; style = copyAttributesWithClip(style, this.style, ['pointList']); style.pointList = pointList; //创建图形 var shape = new SmicPolygon({ style: style, clickable: this.isClickAble, hoverable: this.isHoverAble }); //设置高亮样式 if (this.highlightStyle) { shape.highlightStyle = this.highlightStyle; } //设置参考中心,指定图形位置 shape.refOriginalPosition = this.location; //储存数据 id 属性,用于事件 shape.refDataID = this.data.FID; //储存数据 id 属性,用于事件-多图形同时高亮 shape.isHoverByRefDataID = this.isMultiHover; //岛洞面 if (holePolygonPointLists.length > 0) { shape.holePolygonPointLists = holePolygonPointLists; } //修改一些 shape 可选属性,通常不需要这么做 if (this.shapeOptions) { copyAttributesWithClip(shape, this.shapeOptions); } this.shapes.push(shape); } /** * @function Zondy.Theme.ThemeVector.prototype.updateAndAddShapes * @description 修改位置,针对地图平移操作,地图漫游操作后调用此函数。 */ updateAndAddShapes() { var newLocalLX = this.getLocalXY(this.lonlat); this.location = newLocalLX; var render = this.layer.renderer; for (var i = 0, len = this.shapes.length; i < len; i++) { var shape = this.shapes[i]; //设置参考中心,指定图形位置 shape.refOriginalPosition = newLocalLX; render.addShape(shape); } } /** * @function Zondy.Theme.ThemeVector.prototype.getShapesCount * @description 获得专题要素中可视化图形的数量。 * @return {number} 可视化图形的数量。 */ getShapesCount() { return this.shapes.length; } /** * @function Zondy.Theme.ThemeVector.prototype.getLocalXY * @description 地理坐标转为像素坐标。 * @param lonlat - {Zondy.LonLat} 专题要素地理位置。 */ getLocalXY(lonlat) { return this.layer.getLocalXY(lonlat); } } export {ThemeVector}; Zondy.Theme.ThemeVector = ThemeVector;