LanLingXiangMu/public/bigScreen/lib/mars3d/plugins/pbf/style/TaitanPbfStyle.js

335 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//taitan公司自定义的Sld 样式
//sld与mvt样式区别sld针对一个要素多个rule的样式可以同时独立生效而mvt只能给一个要素设置一个样式
(function (window) {
function TaitanPbfStyle(options) {
this.ol = null;
this.json = {};
this.options = {};
this.style = {};
this.iconCache = {};
this.properties = null;
this.type = null;
this.scale = null;
this.resolution = null;
this.filterIsPass = null;
this.scaleIsPass = true;
this.init(options);
}
TaitanPbfStyle.prototype = {
constructor: TaitanPbfStyle,
defaults: {
ol: null,
json: {}
},
init: function (options) {
let opts = Object.assign({}, this.defaults, options);
this.json = opts.json;
this.ol = opts.ol;
},
reset: function () {
this.options = {};
this.style = {};
this.properties = null;
this.type = null;
this.scale = null;
this.resolution = null;
this.filterIsPass = null;
this.scaleIsPass = true;
},
getStyle: function () {
let This = this;
return function (feature, resolution) {
This.reset();
This.type = feature.getGeometry().getType();
This.properties = feature.getProperties();
This.resolution = resolution;
This.scale = 1 / (0.0254 / (96 * resolution));
This.filter();
return This.buildStyle();
}
},
// 根据options组装最终的样式对象
buildStyle: function () {
if (Object.keys(this.options).length == 0) return [new this.ol.style.Style({})];
// if (JSON.stringify(this.options) == '{}') return;
// 组装基础样式
switch (this.type.toLowerCase()) {
case 'point':
if (this.options.image.imageStyle) this.style.image = this.options.image.imageStyle;
break;
case 'linestring':
if (this.options.stroke) this.style.stroke = this.options.stroke;
break;
case 'polygon':
if (this.options.fill) this.style.fill = this.options.fill;
if (this.options.stroke) this.style.stroke = this.options.stroke;
break;
default:
break;
}
// 组装label样式,这里控制了下显示层级只有分辨率小于40的时候才会显示label后续可以做成可配置项
if (this.resolution < 40 && this.options.text) {
this.style.text = new this.ol.style.Text({
text: this.options.text.text ? this.options.text.text + '' : '',
textBaseline: "top",
overflow: 'line',
font: `${this.options.text.font || 10}px sans-serif`,
offsetX: this.options.text.offsetX,
offsetY: this.options.text.offsetY,
fill: this.options.text.fill,
stroke: this.options.text.stroke,
rotateWithView: false
})
}
// 组装层级样式
this.style.zIndex = this.options.zIndex || 1;
return [new this.ol.style.Style(this.style)];
},
// 构建样式options
buildOptions: function (rule) {
// rule.Symbolizer.WellKnownName = 'img';
// rule.Symbolizer.src = 'https://unpkg.com/@mapbox/maki@4.0.0/icons/park-15.svg';
this.options.image = {};
this.options.image.rotation = rule.Symbolizer.Rotation || 0;
if (rule.Symbolizer.FillColor && rule.Symbolizer.WellKnownName != 'img') {
let imgFillColor = this.buildRgba(rule.Symbolizer.FillColor, rule.Symbolizer.FillOpacity);
this.options.image.fill = new this.ol.style.Fill({
color: imgFillColor
});
if (rule.Symbolizer.StrokeColor) {
let imgStrokeColor = this.buildRgba(rule.Symbolizer.StrokeColor, rule.Symbolizer.StrokeOpacity);
this.options.image.stroke = new this.ol.style.Stroke({
color: imgStrokeColor,
width: rule.Symbolizer.StrokeWidth,
lineDash: rule.Symbolizer.StrokeDasharray.split(' ')
});
}
}
this.options.image.render = "image";
switch (rule.Symbolizer.WellKnownName) {
case 'circle':
// 圆形
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.imageStyle = new this.ol.style.Circle(this.options.image);
break;
case 'square':
// 正方形
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.points = 4;
this.options.image.angle = Math.PI / 4;
this.options.image.imageStyle = new this.ol.style.RegularShape(this.options.image);
break;
case 'triangle':
// 三角形
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.points = 3;
this.options.image.angle = 0;
this.options.image.imageStyle = new this.ol.style.RegularShape(this.options.image);
break;
case 'star':
// 五角形
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.points = 5;
this.options.image.radius2 = rule.Symbolizer.Size / 2.5;
this.options.image.angle = 0;
this.options.image.imageStyle = new this.ol.style.RegularShape(this.options.image);
break;
case 'cross':
// 十字架
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.points = 4;
this.options.image.radius2 = 0;
this.options.image.angle = 0;
this.options.image.imageStyle = new this.ol.style.RegularShape(this.options.image);
break;
case 'x':
// ×形
this.options.image.radius = rule.Symbolizer.Size;
this.options.image.points = 4;
this.options.image.radius2 = 0;
this.options.image.angle = Math.PI / 4;
this.options.image.imageStyle = new this.ol.style.RegularShape(this.options.image);
break;
case 'img':
let icon = this.iconCache[rule.Symbolizer.src];
if (!icon) {
this.options.image.src = rule.Symbolizer.src;
this.options.image.anchorXUnits = 'fraction';
this.options.image.anchorYUnits = 'fraction';
this.options.image.anchor = [0.5, 0.5];
this.options.image.offset = [0, 0];
this.options.image.scale = 1;
this.options.image.rotation = rule.Symbolizer.Rotation;
this.options.image.crossOrigin = 'anonymous',
this.options.image.imageStyle = new this.ol.style.Icon(this.options.image);
this.iconCache[rule.Symbolizer.src] = this.options.image.imageStyle;
} else {
this.options.image.imageStyle = icon;
}
break;
default:
break;
}
// 构建option中的填充色
if (rule.Symbolizer.FillColor) {
let fillColor = this.buildRgba(rule.Symbolizer.FillColor, rule.Symbolizer.FillOpacity);
this.options.fill = new this.ol.style.Fill({
color: fillColor
});
}
// 构建option中的边框
let strokeColor, strokeWidth, strokeDasharray;
if (rule.Symbolizer.StrokeColor) {
strokeColor = this.buildRgba(rule.Symbolizer.StrokeColor, rule.Symbolizer.StrokeOpacity);
if (rule.Symbolizer.StrokeWidth && rule.Symbolizer.StrokeWidth > 1) {
strokeWidth = rule.Symbolizer.StrokeWidth;
}
if (rule.Symbolizer.StrokeDasharray && rule.Symbolizer.StrokeDasharray.split(' ')) {
strokeDasharray = rule.Symbolizer.StrokeDasharray.split(' ');
}
this.options.stroke = new this.ol.style.Stroke({
color: strokeColor,
width: strokeWidth,
lineDash: strokeDasharray
});
}
// 构建option中的标签
if (rule.Label && JSON.stringify(rule.Label) != '{}') {
this.options.text = {};
this.options.text.text = this.properties[rule.Label.PropertyName];
this.options.text.font = rule.Label.FontSize;
this.options.text.offsetX = rule.Label.AnchorPointX;
this.options.text.offsetY = rule.Label.AnchorPointY;
if (rule.Label.FillColor) {
let fillColor = this.buildRgba(rule.Label.FillColor, rule.Label.FillOpacity);
this.options.text.fill = new this.ol.style.Fill({
color: fillColor
});
}
if (rule.Label.HaloFillColor) {
let haloFillColor = this.buildRgba(rule.Label.HaloFillColor, rule.Label.HaloFillOpacity);
this.options.text.stroke = new this.ol.style.Stroke({
color: haloFillColor,
width: rule.Label.HaloRadius
});
}
}
},
// 根据属性和比例条件进行判断
filter: function () {
for (let rule of this.json.Rule) {
// 每次循环开始前将重置filterIsPass参数
this.filterIsPass = undefined;
// 判断属性过滤条件如果属性过滤条件参数不存在或者为空则不做进一步的判断直接赋值true
if (rule.Filter instanceof Object == false ||
JSON.stringify(rule.Filter) == '{}' ||
rule.Filter.Conditions == undefined ||
rule.Filter.Conditions.length == 0) {
this.filterIsPass = true;
} else {
this.filterConditions(rule.Filter);
}
this.buildOptions(rule);
// 判断比例条件是否符合
// let minScale = rule.MinScaleDenominator ? rule.MinScaleDenominator : 10;
// let maxScale = rule.MaxScaleDenominator ? rule.MaxScaleDenominator : 10000000000;
// this.scaleIsPass = (this.scale < minScale || this.scale > maxScale) ? false : true;
// if (this.filterIsPass && this.scaleIsPass) this.buildOptions(rule);
}
},
// 根据属性过滤条件进行判断
filterConditions: function (filter) {
for (let condition of filter.Conditions) {
let bool, val = this.properties[condition.PropertyName] + '' || '';
switch (condition.Condition) {
case 'PropertyIsEqualTo':
bool = (val == condition.Literal);
break;
case 'PropertyIsNotEqualTo':
bool = (val != condition.Literal);
break;
case 'PropertyIsLike':
bool = (val.indexOf(condition.Literal) > -1);
break;
case 'PropertyIsBetween':
let num = parseFloat(val);
bool = (num >= condition.LowerBoundary.Literal) && (num <= condition.UpperBoundary.Literal);
break;
default:
break;
}
if (filter.FilterType == 'And') {
this.filterIsPass = (this.filterIsPass == undefined) ? bool : (this.filterIsPass && bool);
} else if (filter.FilterType == 'Or') {
this.filterIsPass = (this.filterIsPass == undefined) ? bool : (this.filterIsPass || bool);
}
}
},
hexToRgb: function (hex) {
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
},
buildRgba: function (hex, opa) {
hex = this.hexToRgb(hex);
if (hex == 'null') return "";
return `rgba(${hex.r},${hex.g},${hex.b},${opa})`;
}
}
//对外接口
window.mars3d.TaitanPbfStyle = TaitanPbfStyle;
})(window);