deeptwins-engine-3d 0.1.69 → 0.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/Build/DeepTwins/Image/fire.png +0 -0
- package/dist/assets/Build/DeepTwins/Image/fountain.png +0 -0
- package/dist/assets/Build/DeepTwins/Image/smoke.png +0 -0
- package/dist/esm/analyze/LineOfSightAnalysis.d.ts +44 -0
- package/dist/esm/analyze/LineOfSightAnalysis.js +326 -0
- package/dist/esm/analyze/TerrainExcavationAnalysis.d.ts +59 -0
- package/dist/esm/analyze/TerrainExcavationAnalysis.js +612 -0
- package/dist/esm/constant.d.ts +88 -0
- package/dist/esm/constant.js +132 -0
- package/dist/esm/drawCommand/viewShed/RectangularSensorPrimitive.d.ts +3 -0
- package/dist/esm/drawCommand/viewShed/RectangularSensorPrimitive.js +56 -21
- package/dist/esm/drawCommand/viewShed/config.d.ts +2 -2
- package/dist/esm/drawCommand/viewShed/config.js +2 -2
- package/dist/esm/drawer/index.d.ts +1 -1
- package/dist/esm/graphicLayer/BaseSource.d.ts +1 -1
- package/dist/esm/index.d.ts +15 -0
- package/dist/esm/index.js +24 -2
- package/dist/esm/map/Map.d.ts +1 -0
- package/dist/esm/map/Map.js +18 -0
- package/dist/esm/particle/BaseParticle.d.ts +61 -0
- package/dist/esm/particle/BaseParticle.js +196 -0
- package/dist/esm/particle/FireParticle.d.ts +8 -0
- package/dist/esm/particle/FireParticle.js +65 -0
- package/dist/esm/particle/FountainParticle.d.ts +10 -0
- package/dist/esm/particle/FountainParticle.js +80 -0
- package/dist/esm/particle/SmokeParticle.d.ts +8 -0
- package/dist/esm/particle/SmokeParticle.js +65 -0
- package/dist/esm/particle/common.d.ts +18 -0
- package/dist/esm/particle/common.js +23 -0
- package/dist/esm/particle/index.d.ts +5 -0
- package/dist/esm/particle/index.js +5 -0
- package/dist/esm/tileLayer/CustomRasterLayer.d.ts +188 -0
- package/dist/esm/tileLayer/CustomRasterLayer.js +776 -0
- package/dist/esm/visualization/DynamicWater.d.ts +39 -0
- package/dist/esm/visualization/DynamicWater.js +289 -0
- package/dist/esm/visualization/MigrationEffect.d.ts +36 -0
- package/dist/esm/visualization/MigrationEffect.js +397 -0
- package/dist/esm/visualization/RadarScan.d.ts +39 -0
- package/dist/esm/visualization/RadarScan.js +333 -0
- package/dist/umd/deeptwins-engine-3d.min.js +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
var _excluded = ["tilingScheme"];
|
|
3
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
7
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
8
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
9
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
10
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
11
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
12
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
13
|
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
14
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
15
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
16
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
19
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
20
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
21
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
22
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
23
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
24
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
25
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
26
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
27
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
28
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
29
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
30
|
+
import * as turf from '@turf/turf';
|
|
31
|
+
import * as Cesium from 'deeptwins-cesium';
|
|
32
|
+
import proj4 from 'proj4';
|
|
33
|
+
import ImageryLayer from "./ImageryLayer";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* CustomRasterLayer 是一个通用栅格瓦片图层:
|
|
37
|
+
* - 使用 Cesium.UrlTemplateImageryProvider 加载任意 URL 模板瓦片。
|
|
38
|
+
* - 使用 proj4 将瓦片范围和裁剪 GeoJSON 从 dataCrs 转到 renderCrs。
|
|
39
|
+
* - GCJ02 渲染时按 tileLayer/test 的瓦片坐标方案计算瓦片范围。
|
|
40
|
+
* - 可选按 GeoJSON 面要素裁剪瓦片。
|
|
41
|
+
* - 裁剪前先求瓦片 bbox 与裁剪面的交集,避免多面重叠时误裁。
|
|
42
|
+
* - 可选输出调试事件,便于排查范围、瓦片加载、裁剪和丢弃行为。
|
|
43
|
+
*
|
|
44
|
+
* @example 基础瓦片图层
|
|
45
|
+
* ```ts
|
|
46
|
+
* const layer = new DeepTwinsEngine3D.CustomRasterLayer({
|
|
47
|
+
* id: 'base-raster',
|
|
48
|
+
* source: {
|
|
49
|
+
* url: 'https://example.com/tiles/{z}/{x}/{y}.png',
|
|
50
|
+
* minimumLevel: 0,
|
|
51
|
+
* maximumLevel: 18,
|
|
52
|
+
* },
|
|
53
|
+
* debug: true,
|
|
54
|
+
* });
|
|
55
|
+
* map.imageryLayers.add(layer);
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @example 带范围、坐标转换和裁剪的图层
|
|
59
|
+
* ```ts
|
|
60
|
+
* const layer = new DeepTwinsEngine3D.CustomRasterLayer({
|
|
61
|
+
* id: 'project-raster',
|
|
62
|
+
* source: {
|
|
63
|
+
* url: 'https://example.com/project/{z}/{x}/{y}.png',
|
|
64
|
+
* maximumLevel: 20,
|
|
65
|
+
* },
|
|
66
|
+
* // bounds 格式:[minX, minY, maxX, maxY],这里表示 EPSG:3857 米制范围。
|
|
67
|
+
* bounds: [13210000, 3520000, 13230000, 3540000],
|
|
68
|
+
* dataCrs: 'EPSG:3857',
|
|
69
|
+
* renderCrs: 'EPSG:4326',
|
|
70
|
+
* clipFeature: geoJsonPolygon,
|
|
71
|
+
* debug: (event) => console.debug(event),
|
|
72
|
+
* });
|
|
73
|
+
* map.imageryLayers.add(layer);
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @remarks API 文档
|
|
77
|
+
* - `source`:必填,Cesium.UrlTemplateImageryProvider 原生配置。
|
|
78
|
+
* - `layerOptions`:可选,Cesium.ImageryLayer 原生配置。
|
|
79
|
+
* - `bounds`:可选,瓦片范围 `[minX, minY, maxX, maxY]`。
|
|
80
|
+
* - `dataCrs`:可选,bounds 与 clipFeature 的原始坐标系,默认 `EPSG:4326`。
|
|
81
|
+
* - `renderCrs`:可选,bounds、clipFeature 和瓦片范围转换后的目标坐标系,默认 `EPSG:4326`。
|
|
82
|
+
* - `projectionDefs`:可选,自定义 proj4 坐标系定义。
|
|
83
|
+
* - `clipFeature`:可选,GeoJSON Polygon/MultiPolygon/Feature/FeatureCollection。
|
|
84
|
+
* - `autoFitBounds`:可选,创建后自动将相机定位到最终范围,需同时传入 `map`。
|
|
85
|
+
* - `debug`:可选,`true` 使用 console.debug,函数则接收结构化调试事件。
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/** 通用范围格式:[minX, minY, maxX, maxY]。 */
|
|
89
|
+
|
|
90
|
+
/** 调试事件类型,覆盖范围初始化、瓦片加载和裁剪决策。 */
|
|
91
|
+
|
|
92
|
+
/** debug 回调收到的结构化事件。 */
|
|
93
|
+
|
|
94
|
+
/** debug 配置:关闭、console.debug 输出,或自定义事件处理函数。 */
|
|
95
|
+
|
|
96
|
+
/** 内置切片方案名称,或 Cesium 原生 TilingScheme 实例。 */
|
|
97
|
+
|
|
98
|
+
/** CustomRasterLayer 数据源配置,扩展 tilingScheme 字符串默认选项。 */
|
|
99
|
+
|
|
100
|
+
/** CustomRasterLayer 构造配置。 */
|
|
101
|
+
|
|
102
|
+
var DEFAULT_CRS = 'EPSG:4326';
|
|
103
|
+
var GCJ02_CRS = 'GCJ02';
|
|
104
|
+
var WEB_MERCATOR_DEFINITION = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 ' + '+x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs';
|
|
105
|
+
var WGS84_DEFINITION = '+proj=longlat +datum=WGS84 +no_defs +type=crs';
|
|
106
|
+
var GCJ02_A = 6378245.0;
|
|
107
|
+
var GCJ02_EE = 0.006693421622965943;
|
|
108
|
+
|
|
109
|
+
/** 从 EPSG:xxxx、EPSG/0/xxxx 或纯数字 CRS 中提取 EPSG code。 */
|
|
110
|
+
var getEpsgCode = function getEpsgCode(crs) {
|
|
111
|
+
var match = crs.match(/EPSG(?::|\/0\/|::)(\d+)/i) || crs.match(/^(\d+)$/);
|
|
112
|
+
return match === null || match === void 0 ? void 0 : match[1];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/** 统一 CRS 名称。 */
|
|
116
|
+
var normalizeCrs = function normalizeCrs() {
|
|
117
|
+
var crs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_CRS;
|
|
118
|
+
if (/^(gcj02|gcj-02)$/i.test(crs)) {
|
|
119
|
+
return GCJ02_CRS;
|
|
120
|
+
}
|
|
121
|
+
var code = getEpsgCode(crs);
|
|
122
|
+
return code ? "EPSG:".concat(code) : crs;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** 注册调用方传入的 proj4 自定义坐标系定义。 */
|
|
126
|
+
var registerProjectionDefs = function registerProjectionDefs(projectionDefs) {
|
|
127
|
+
Object.entries(projectionDefs || {}).forEach(function (_ref) {
|
|
128
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
129
|
+
name = _ref2[0],
|
|
130
|
+
definition = _ref2[1];
|
|
131
|
+
proj4.defs(normalizeCrs(name), definition);
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** 确保常用 CRS 可被 proj4 识别,其他 CRS 由 projectionDefs 显式注册。 */
|
|
136
|
+
var ensureProjDefinition = function ensureProjDefinition(crs) {
|
|
137
|
+
var projName = normalizeCrs(crs);
|
|
138
|
+
if (projName === GCJ02_CRS) {
|
|
139
|
+
return projName;
|
|
140
|
+
}
|
|
141
|
+
if (proj4.defs(projName)) {
|
|
142
|
+
return projName;
|
|
143
|
+
}
|
|
144
|
+
var code = getEpsgCode(projName);
|
|
145
|
+
if (code === '4326') {
|
|
146
|
+
proj4.defs(projName, WGS84_DEFINITION);
|
|
147
|
+
return projName;
|
|
148
|
+
}
|
|
149
|
+
if (code === '3857') {
|
|
150
|
+
proj4.defs(projName, WEB_MERCATOR_DEFINITION);
|
|
151
|
+
return projName;
|
|
152
|
+
}
|
|
153
|
+
if (code && /^326\d{2}$/.test(code)) {
|
|
154
|
+
var zone = Number(code.slice(3));
|
|
155
|
+
proj4.defs(projName, "+proj=utm +zone=".concat(zone, " +datum=WGS84 +units=m +no_defs +type=crs"));
|
|
156
|
+
return projName;
|
|
157
|
+
}
|
|
158
|
+
if (code && /^327\d{2}$/.test(code)) {
|
|
159
|
+
var _zone = Number(code.slice(3));
|
|
160
|
+
proj4.defs(projName, "+proj=utm +zone=".concat(_zone, " +south +datum=WGS84 +units=m +no_defs +type=crs"));
|
|
161
|
+
return projName;
|
|
162
|
+
}
|
|
163
|
+
throw new Error("Missing proj definition for CRS: ".concat(crs));
|
|
164
|
+
};
|
|
165
|
+
var isWgs84Crs = function isWgs84Crs(crs) {
|
|
166
|
+
return normalizeCrs(crs) === DEFAULT_CRS;
|
|
167
|
+
};
|
|
168
|
+
var isWgs84LikeCrs = function isWgs84LikeCrs(crs) {
|
|
169
|
+
return isWgs84Crs(crs);
|
|
170
|
+
};
|
|
171
|
+
var isOutOfChina = function isOutOfChina(lng, lat) {
|
|
172
|
+
return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
|
|
173
|
+
};
|
|
174
|
+
var transformGcj02Lat = function transformGcj02Lat(lng, lat) {
|
|
175
|
+
var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
|
|
176
|
+
ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;
|
|
177
|
+
ret += (20.0 * Math.sin(lat * Math.PI) + 40.0 * Math.sin(lat / 3.0 * Math.PI)) * 2.0 / 3.0;
|
|
178
|
+
ret += (160.0 * Math.sin(lat / 12.0 * Math.PI) + 320 * Math.sin(lat * Math.PI / 30.0)) * 2.0 / 3.0;
|
|
179
|
+
return ret;
|
|
180
|
+
};
|
|
181
|
+
var transformGcj02Lng = function transformGcj02Lng(lng, lat) {
|
|
182
|
+
var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
|
|
183
|
+
ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 * Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;
|
|
184
|
+
ret += (20.0 * Math.sin(lng * Math.PI) + 40.0 * Math.sin(lng / 3.0 * Math.PI)) * 2.0 / 3.0;
|
|
185
|
+
ret += (150.0 * Math.sin(lng / 12.0 * Math.PI) + 300.0 * Math.sin(lng / 30.0 * Math.PI)) * 2.0 / 3.0;
|
|
186
|
+
return ret;
|
|
187
|
+
};
|
|
188
|
+
var wgs84ToGcj02 = function wgs84ToGcj02(lng, lat) {
|
|
189
|
+
if (isOutOfChina(lng, lat)) {
|
|
190
|
+
return [lng, lat];
|
|
191
|
+
}
|
|
192
|
+
var dLat = transformGcj02Lat(lng - 105.0, lat - 35.0);
|
|
193
|
+
var dLng = transformGcj02Lng(lng - 105.0, lat - 35.0);
|
|
194
|
+
var radLat = lat / 180.0 * Math.PI;
|
|
195
|
+
var magic = Math.sin(radLat);
|
|
196
|
+
magic = 1 - GCJ02_EE * magic * magic;
|
|
197
|
+
var sqrtMagic = Math.sqrt(magic);
|
|
198
|
+
dLat = dLat * 180.0 / (GCJ02_A * (1 - GCJ02_EE) / (magic * sqrtMagic) * Math.PI);
|
|
199
|
+
dLng = dLng * 180.0 / (GCJ02_A / sqrtMagic * Math.cos(radLat) * Math.PI);
|
|
200
|
+
return [lng + dLng, lat + dLat];
|
|
201
|
+
};
|
|
202
|
+
var gcj02ToWgs84 = function gcj02ToWgs84(lng, lat) {
|
|
203
|
+
if (isOutOfChina(lng, lat)) {
|
|
204
|
+
return [lng, lat];
|
|
205
|
+
}
|
|
206
|
+
var _wgs84ToGcj = wgs84ToGcj02(lng, lat),
|
|
207
|
+
_wgs84ToGcj2 = _slicedToArray(_wgs84ToGcj, 2),
|
|
208
|
+
gcjLng = _wgs84ToGcj2[0],
|
|
209
|
+
gcjLat = _wgs84ToGcj2[1];
|
|
210
|
+
return [lng * 2 - gcjLng, lat * 2 - gcjLat];
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/** 转换单个坐标点,保留第三维及后续附加值。 */
|
|
214
|
+
var transformPoint = function transformPoint(point, sourceCrs, targetCrs) {
|
|
215
|
+
var normalizedSourceCrs = normalizeCrs(sourceCrs);
|
|
216
|
+
var normalizedTargetCrs = normalizeCrs(targetCrs);
|
|
217
|
+
if (normalizedSourceCrs === normalizedTargetCrs) {
|
|
218
|
+
return _toConsumableArray(point);
|
|
219
|
+
}
|
|
220
|
+
if (normalizedSourceCrs === GCJ02_CRS) {
|
|
221
|
+
var wgs84Point = gcj02ToWgs84(point[0], point[1]);
|
|
222
|
+
if (isWgs84LikeCrs(normalizedTargetCrs)) {
|
|
223
|
+
return [].concat(_toConsumableArray(wgs84Point), _toConsumableArray(point.slice(2)));
|
|
224
|
+
}
|
|
225
|
+
var _targetProj = ensureProjDefinition(normalizedTargetCrs);
|
|
226
|
+
var _proj = proj4(DEFAULT_CRS, _targetProj, wgs84Point),
|
|
227
|
+
_proj2 = _slicedToArray(_proj, 2),
|
|
228
|
+
_x = _proj2[0],
|
|
229
|
+
_y = _proj2[1];
|
|
230
|
+
return [_x, _y].concat(_toConsumableArray(point.slice(2)));
|
|
231
|
+
}
|
|
232
|
+
if (normalizedTargetCrs === GCJ02_CRS) {
|
|
233
|
+
var _wgs84Point = isWgs84LikeCrs(normalizedSourceCrs) ? [point[0], point[1]] : proj4(ensureProjDefinition(normalizedSourceCrs), DEFAULT_CRS, [point[0], point[1]]);
|
|
234
|
+
var _wgs84ToGcj3 = wgs84ToGcj02(_wgs84Point[0], _wgs84Point[1]),
|
|
235
|
+
_wgs84ToGcj4 = _slicedToArray(_wgs84ToGcj3, 2),
|
|
236
|
+
_x2 = _wgs84ToGcj4[0],
|
|
237
|
+
_y2 = _wgs84ToGcj4[1];
|
|
238
|
+
return [_x2, _y2].concat(_toConsumableArray(point.slice(2)));
|
|
239
|
+
}
|
|
240
|
+
var sourceProj = ensureProjDefinition(normalizedSourceCrs);
|
|
241
|
+
var targetProj = ensureProjDefinition(normalizedTargetCrs);
|
|
242
|
+
var _proj3 = proj4(sourceProj, targetProj, [point[0], point[1]]),
|
|
243
|
+
_proj4 = _slicedToArray(_proj3, 2),
|
|
244
|
+
x = _proj4[0],
|
|
245
|
+
y = _proj4[1];
|
|
246
|
+
return [x, y].concat(_toConsumableArray(point.slice(2)));
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/** 转换 bbox 四角后重新计算外接范围,避免旋转/投影畸变导致范围不足。 */
|
|
250
|
+
var transformBounds = function transformBounds(bounds, sourceCrs, targetCrs) {
|
|
251
|
+
var corners = [[bounds[0], bounds[1]], [bounds[0], bounds[3]], [bounds[2], bounds[1]], [bounds[2], bounds[3]]].map(function (point) {
|
|
252
|
+
return transformPoint(point, sourceCrs, targetCrs);
|
|
253
|
+
});
|
|
254
|
+
var xList = corners.map(function (_ref3) {
|
|
255
|
+
var _ref4 = _slicedToArray(_ref3, 1),
|
|
256
|
+
x = _ref4[0];
|
|
257
|
+
return x;
|
|
258
|
+
});
|
|
259
|
+
var yList = corners.map(function (_ref5) {
|
|
260
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
261
|
+
y = _ref6[1];
|
|
262
|
+
return y;
|
|
263
|
+
});
|
|
264
|
+
return [Math.min.apply(Math, _toConsumableArray(xList)), Math.min.apply(Math, _toConsumableArray(yList)), Math.max.apply(Math, _toConsumableArray(xList)), Math.max.apply(Math, _toConsumableArray(yList))];
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/** Cesium.Rectangle 弧度范围转经纬度 bbox。 */
|
|
268
|
+
var rectangleToBounds = function rectangleToBounds(rectangle) {
|
|
269
|
+
return [Cesium.Math.toDegrees(rectangle.west), Cesium.Math.toDegrees(rectangle.south), Cesium.Math.toDegrees(rectangle.east), Cesium.Math.toDegrees(rectangle.north)];
|
|
270
|
+
};
|
|
271
|
+
var boundsToRectangle = function boundsToRectangle(bounds, result) {
|
|
272
|
+
return Cesium.Rectangle.fromDegrees(bounds[0], bounds[1], bounds[2], bounds[3], result);
|
|
273
|
+
};
|
|
274
|
+
var normalizeBounds = function normalizeBounds(bounds) {
|
|
275
|
+
if (!bounds || bounds.length < 4 || bounds.slice(0, 4).some(function (value) {
|
|
276
|
+
return !Number.isFinite(value);
|
|
277
|
+
})) {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
return [bounds[0], bounds[1], bounds[2], bounds[3]];
|
|
281
|
+
};
|
|
282
|
+
var transformRectangle = function transformRectangle(rectangle, sourceCrs, targetCrs, result) {
|
|
283
|
+
return boundsToRectangle(transformBounds(rectangleToBounds(rectangle), sourceCrs, targetCrs), result);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/** 将内置 tilingScheme 名称解析为 Cesium 原生切片方案实例。 */
|
|
287
|
+
var createSourceTilingScheme = function createSourceTilingScheme(tilingScheme) {
|
|
288
|
+
if (!tilingScheme || tilingScheme === 'webMercator') {
|
|
289
|
+
return new Cesium.WebMercatorTilingScheme();
|
|
290
|
+
}
|
|
291
|
+
if (tilingScheme === 'geographic') {
|
|
292
|
+
return new Cesium.GeographicTilingScheme();
|
|
293
|
+
}
|
|
294
|
+
return tilingScheme;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
/** 创建按目标坐标系渲染的瓦片坐标方案,逻辑对齐 tileLayer/test。 */
|
|
298
|
+
var createRenderTilingScheme = function createRenderTilingScheme(tilingScheme, renderCrs) {
|
|
299
|
+
if (isWgs84Crs(renderCrs)) {
|
|
300
|
+
return tilingScheme;
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
get ellipsoid() {
|
|
304
|
+
return tilingScheme.ellipsoid;
|
|
305
|
+
},
|
|
306
|
+
get rectangle() {
|
|
307
|
+
return transformRectangle(tilingScheme.rectangle, DEFAULT_CRS, renderCrs);
|
|
308
|
+
},
|
|
309
|
+
get projection() {
|
|
310
|
+
return tilingScheme.projection;
|
|
311
|
+
},
|
|
312
|
+
getNumberOfXTilesAtLevel: function getNumberOfXTilesAtLevel(level) {
|
|
313
|
+
return tilingScheme.getNumberOfXTilesAtLevel(level);
|
|
314
|
+
},
|
|
315
|
+
getNumberOfYTilesAtLevel: function getNumberOfYTilesAtLevel(level) {
|
|
316
|
+
return tilingScheme.getNumberOfYTilesAtLevel(level);
|
|
317
|
+
},
|
|
318
|
+
tileXYToNativeRectangle: function tileXYToNativeRectangle(x, y, level, result) {
|
|
319
|
+
return tilingScheme.tileXYToNativeRectangle(x, y, level, result);
|
|
320
|
+
},
|
|
321
|
+
rectangleToNativeRectangle: function rectangleToNativeRectangle(rectangle, result) {
|
|
322
|
+
return tilingScheme.rectangleToNativeRectangle(transformRectangle(rectangle, renderCrs, DEFAULT_CRS), result);
|
|
323
|
+
},
|
|
324
|
+
tileXYToRectangle: function tileXYToRectangle(x, y, level, result) {
|
|
325
|
+
return transformRectangle(tilingScheme.tileXYToRectangle(x, y, level), DEFAULT_CRS, renderCrs, result);
|
|
326
|
+
},
|
|
327
|
+
positionToTileXY: function positionToTileXY(position, level, result) {
|
|
328
|
+
var _transformPoint = transformPoint([Cesium.Math.toDegrees(position.longitude), Cesium.Math.toDegrees(position.latitude)], renderCrs, DEFAULT_CRS),
|
|
329
|
+
_transformPoint2 = _slicedToArray(_transformPoint, 2),
|
|
330
|
+
lng = _transformPoint2[0],
|
|
331
|
+
lat = _transformPoint2[1];
|
|
332
|
+
return tilingScheme.positionToTileXY(Cesium.Cartographic.fromDegrees(lng, lat), level, result);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
/** 递归转换 GeoJSON coordinates,兼容点、线、面、多面等嵌套结构。 */
|
|
338
|
+
var transformCoordinates = function transformCoordinates(coordinates, sourceCrs, targetCrs) {
|
|
339
|
+
if (!Array.isArray(coordinates)) {
|
|
340
|
+
return coordinates;
|
|
341
|
+
}
|
|
342
|
+
if (typeof coordinates[0] === 'number' && typeof coordinates[1] === 'number') {
|
|
343
|
+
return transformPoint(coordinates, sourceCrs, targetCrs);
|
|
344
|
+
}
|
|
345
|
+
return coordinates.map(function (item) {
|
|
346
|
+
return transformCoordinates(item, sourceCrs, targetCrs);
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/** 转换 GeoJSON Geometry,包含 GeometryCollection。 */
|
|
351
|
+
var transformGeometry = function transformGeometry(geometry, sourceCrs, targetCrs) {
|
|
352
|
+
if (!geometry) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (geometry.type === 'GeometryCollection') {
|
|
356
|
+
var _geometry$geometries;
|
|
357
|
+
(_geometry$geometries = geometry.geometries) === null || _geometry$geometries === void 0 || _geometry$geometries.forEach(function (item) {
|
|
358
|
+
return transformGeometry(item, sourceCrs, targetCrs);
|
|
359
|
+
});
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (geometry.coordinates) {
|
|
363
|
+
geometry.coordinates = transformCoordinates(geometry.coordinates, sourceCrs, targetCrs);
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/** 深拷贝并转换 GeoJSON,避免修改调用方持有的原始对象。 */
|
|
368
|
+
var transformGeoJson = function transformGeoJson(geoJson, sourceCrs, targetCrs) {
|
|
369
|
+
if (!geoJson) {
|
|
370
|
+
return geoJson;
|
|
371
|
+
}
|
|
372
|
+
var clonedGeoJson = JSON.parse(JSON.stringify(geoJson));
|
|
373
|
+
if (normalizeCrs(sourceCrs) === normalizeCrs(targetCrs)) {
|
|
374
|
+
return clonedGeoJson;
|
|
375
|
+
}
|
|
376
|
+
if (clonedGeoJson.type === 'FeatureCollection') {
|
|
377
|
+
var _clonedGeoJson$featur;
|
|
378
|
+
(_clonedGeoJson$featur = clonedGeoJson.features) === null || _clonedGeoJson$featur === void 0 || _clonedGeoJson$featur.forEach(function (feature) {
|
|
379
|
+
return transformGeometry(feature.geometry, sourceCrs, targetCrs);
|
|
380
|
+
});
|
|
381
|
+
return clonedGeoJson;
|
|
382
|
+
}
|
|
383
|
+
if (clonedGeoJson.type === 'Feature') {
|
|
384
|
+
transformGeometry(clonedGeoJson.geometry, sourceCrs, targetCrs);
|
|
385
|
+
return clonedGeoJson;
|
|
386
|
+
}
|
|
387
|
+
transformGeometry(clonedGeoJson, sourceCrs, targetCrs);
|
|
388
|
+
return clonedGeoJson;
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/** 将 Geometry 包装为 Turf 可处理的 Feature。 */
|
|
392
|
+
var createFeature = function createFeature(geometry) {
|
|
393
|
+
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
394
|
+
return {
|
|
395
|
+
type: 'Feature',
|
|
396
|
+
properties: properties,
|
|
397
|
+
geometry: geometry
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* 收集可裁剪的 Polygon,忽略点线等非面要素。
|
|
403
|
+
* MultiPolygon 会拆成多个 Polygon,避免重叠面在 canvas evenodd 填充时互相抵消。
|
|
404
|
+
*/
|
|
405
|
+
var collectPolygonFeatures = function collectPolygonFeatures(geoJson) {
|
|
406
|
+
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
407
|
+
if (!geoJson) {
|
|
408
|
+
return [];
|
|
409
|
+
}
|
|
410
|
+
if (geoJson.type === 'FeatureCollection') {
|
|
411
|
+
return geoJson.features.flatMap(function (feature) {
|
|
412
|
+
return collectPolygonFeatures(feature);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
if (geoJson.type === 'Feature') {
|
|
416
|
+
return collectPolygonFeatures(geoJson.geometry, geoJson.properties || {});
|
|
417
|
+
}
|
|
418
|
+
if (geoJson.type === 'GeometryCollection') {
|
|
419
|
+
return geoJson.geometries.flatMap(function (geometry) {
|
|
420
|
+
return collectPolygonFeatures(geometry, properties);
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
if (geoJson.type === 'Polygon') {
|
|
424
|
+
return [createFeature(geoJson, properties)];
|
|
425
|
+
}
|
|
426
|
+
if (geoJson.type === 'MultiPolygon') {
|
|
427
|
+
return geoJson.coordinates.map(function (coordinates) {
|
|
428
|
+
return createFeature({
|
|
429
|
+
type: 'Polygon',
|
|
430
|
+
coordinates: coordinates
|
|
431
|
+
}, properties);
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return [];
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
/** 使用 turf 计算裁剪面的 bbox,作为裁剪范围。 */
|
|
438
|
+
var getClipFeatureBounds = function getClipFeatureBounds(clipFeatures) {
|
|
439
|
+
if (!clipFeatures.length) {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
var bbox = turf.bbox(turf.featureCollection(clipFeatures));
|
|
443
|
+
if (bbox.length < 4 || bbox.some(function (value) {
|
|
444
|
+
return !Number.isFinite(value);
|
|
445
|
+
})) {
|
|
446
|
+
return undefined;
|
|
447
|
+
}
|
|
448
|
+
return normalizeBounds(bbox);
|
|
449
|
+
};
|
|
450
|
+
var getImageSize = function getImageSize(image) {
|
|
451
|
+
return {
|
|
452
|
+
width: image.width,
|
|
453
|
+
height: image.height
|
|
454
|
+
};
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* 通用自定义栅格图层。
|
|
459
|
+
*
|
|
460
|
+
* 继承项目现有 ImageryLayer 封装,内部使用 UrlTemplateImageryProvider。
|
|
461
|
+
* 若传入 clipFeature,会在 Cesium 创建纹理前用 canvas 对瓦片进行透明裁剪。
|
|
462
|
+
*/
|
|
463
|
+
var CustomRasterLayer = /*#__PURE__*/function (_ImageryLayer) {
|
|
464
|
+
_inherits(CustomRasterLayer, _ImageryLayer);
|
|
465
|
+
var _super = _createSuper(CustomRasterLayer);
|
|
466
|
+
/** 创建通用栅格图层。 */
|
|
467
|
+
function CustomRasterLayer(options) {
|
|
468
|
+
var _options$map;
|
|
469
|
+
var _this;
|
|
470
|
+
_classCallCheck(this, CustomRasterLayer);
|
|
471
|
+
if (!(options !== null && options !== void 0 && options.source)) {
|
|
472
|
+
throw new Error('CustomRasterLayer source is required.');
|
|
473
|
+
}
|
|
474
|
+
registerProjectionDefs(options.projectionDefs);
|
|
475
|
+
var dataCrs = normalizeCrs(options.dataCrs || DEFAULT_CRS);
|
|
476
|
+
var renderCrs = normalizeCrs(options.renderCrs || DEFAULT_CRS);
|
|
477
|
+
var transformedClipFeature = transformGeoJson(options.clipFeature, dataCrs, renderCrs);
|
|
478
|
+
var clipFeatures = collectPolygonFeatures(transformedClipFeature);
|
|
479
|
+
var _options$source = options.source,
|
|
480
|
+
sourceTilingSchemeOption = _options$source.tilingScheme,
|
|
481
|
+
sourceOptionsRest = _objectWithoutProperties(_options$source, _excluded);
|
|
482
|
+
var tileBounds = options.bounds ? transformBounds(options.bounds, dataCrs, renderCrs) : undefined;
|
|
483
|
+
var clipBounds = getClipFeatureBounds(clipFeatures);
|
|
484
|
+
var renderBounds = clipBounds || tileBounds;
|
|
485
|
+
var sourceRectangleBounds = sourceOptionsRest.rectangle ? rectangleToBounds(sourceOptionsRest.rectangle) : undefined;
|
|
486
|
+
var fitBounds = clipBounds || tileBounds || sourceRectangleBounds;
|
|
487
|
+
var tilingScheme = createRenderTilingScheme(createSourceTilingScheme(sourceTilingSchemeOption), renderCrs);
|
|
488
|
+
var sourceOptions = _objectSpread(_objectSpread({}, sourceOptionsRest), {}, {
|
|
489
|
+
tilingScheme: tilingScheme
|
|
490
|
+
}, renderBounds ? {
|
|
491
|
+
rectangle: boundsToRectangle(renderBounds)
|
|
492
|
+
} : {});
|
|
493
|
+
var imageProvider = new Cesium.UrlTemplateImageryProvider(sourceOptions);
|
|
494
|
+
_this = _super.call(this, imageProvider, options.layerOptions);
|
|
495
|
+
/** 图层 id,方便业务图层集合按 id 管理。 */
|
|
496
|
+
_defineProperty(_assertThisInitialized(_this), "id", void 0);
|
|
497
|
+
/** 图层层级,方便业务图层集合排序。 */
|
|
498
|
+
_defineProperty(_assertThisInitialized(_this), "zIndex", void 0);
|
|
499
|
+
/** Cesium 瓦片数据源实例。 */
|
|
500
|
+
_defineProperty(_assertThisInitialized(_this), "source", void 0);
|
|
501
|
+
_defineProperty(_assertThisInitialized(_this), "_debug", void 0);
|
|
502
|
+
_defineProperty(_assertThisInitialized(_this), "_clipFeatures", void 0);
|
|
503
|
+
_defineProperty(_assertThisInitialized(_this), "_fitBounds", void 0);
|
|
504
|
+
_defineProperty(_assertThisInitialized(_this), "_mapContext", void 0);
|
|
505
|
+
_this.id = options.id;
|
|
506
|
+
_this.zIndex = options.zIndex;
|
|
507
|
+
_this.source = imageProvider;
|
|
508
|
+
_this._debug = options.debug;
|
|
509
|
+
_this._clipFeatures = clipFeatures;
|
|
510
|
+
_this._fitBounds = fitBounds;
|
|
511
|
+
_this._mapContext = (_options$map = options.map) === null || _options$map === void 0 ? void 0 : _options$map._mapContext;
|
|
512
|
+
_this.logDebug({
|
|
513
|
+
type: 'range',
|
|
514
|
+
bounds: options.bounds,
|
|
515
|
+
tileBounds: tileBounds,
|
|
516
|
+
clipBounds: clipBounds,
|
|
517
|
+
renderBounds: renderBounds,
|
|
518
|
+
dataCrs: dataCrs,
|
|
519
|
+
renderCrs: renderCrs
|
|
520
|
+
});
|
|
521
|
+
if (options.autoFitBounds && normalizeBounds(fitBounds)) {
|
|
522
|
+
_this.fitToBounds(options.map, options.fitBoundsOptions);
|
|
523
|
+
}
|
|
524
|
+
return _this;
|
|
525
|
+
}
|
|
526
|
+
_createClass(CustomRasterLayer, [{
|
|
527
|
+
key: "getMap",
|
|
528
|
+
value: function getMap() {
|
|
529
|
+
return this._mapContext && this._mapContext.getMap();
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/** 将相机定位到当前图层最终渲染范围。 */
|
|
533
|
+
}, {
|
|
534
|
+
key: "fitToBounds",
|
|
535
|
+
value: function fitToBounds() {
|
|
536
|
+
var _map$camera;
|
|
537
|
+
var map = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getMap();
|
|
538
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
539
|
+
duration: 0
|
|
540
|
+
};
|
|
541
|
+
if (!map) {
|
|
542
|
+
throw new Error('CustomRasterLayer fitToBounds requires a map.');
|
|
543
|
+
}
|
|
544
|
+
var fitBounds = normalizeBounds(this._fitBounds);
|
|
545
|
+
if (!fitBounds) {
|
|
546
|
+
throw new Error('CustomRasterLayer fitToBounds requires valid bounds.');
|
|
547
|
+
}
|
|
548
|
+
var fitOptions = options || {
|
|
549
|
+
duration: 0
|
|
550
|
+
};
|
|
551
|
+
if (typeof map.setCameraViewByBbox === 'function') {
|
|
552
|
+
map.setCameraViewByBbox(fitBounds, fitOptions);
|
|
553
|
+
return this;
|
|
554
|
+
}
|
|
555
|
+
if ((_map$camera = map.camera) !== null && _map$camera !== void 0 && _map$camera.flyTo) {
|
|
556
|
+
map.camera.flyTo(_objectSpread({
|
|
557
|
+
destination: boundsToRectangle(fitBounds)
|
|
558
|
+
}, fitOptions));
|
|
559
|
+
return this;
|
|
560
|
+
}
|
|
561
|
+
throw new Error('CustomRasterLayer fitToBounds requires a map camera.');
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Cesium 内部纹理创建钩子。
|
|
566
|
+
*
|
|
567
|
+
* 这里按 tileLayer/test 的 ClipLayer 逻辑处理裁剪:
|
|
568
|
+
* - 完全在裁剪面内:原图保留。
|
|
569
|
+
* - 完全不相交:替换为空透明 canvas。
|
|
570
|
+
* - 部分相交:按瓦片与裁剪面的交集裁剪 canvas。
|
|
571
|
+
*/
|
|
572
|
+
}, {
|
|
573
|
+
key: "_createTexture",
|
|
574
|
+
value: function _createTexture(context, imagery) {
|
|
575
|
+
var _this2 = this;
|
|
576
|
+
var tileBbox = rectangleToBounds(imagery.rectangle);
|
|
577
|
+
this.logDebug({
|
|
578
|
+
type: 'tile-loaded',
|
|
579
|
+
x: imagery.x,
|
|
580
|
+
y: imagery.y,
|
|
581
|
+
level: imagery.level,
|
|
582
|
+
bbox: tileBbox,
|
|
583
|
+
imageSize: getImageSize(imagery.image)
|
|
584
|
+
});
|
|
585
|
+
if (!this._clipFeatures.length) {
|
|
586
|
+
return this.createTexture(context, imagery);
|
|
587
|
+
}
|
|
588
|
+
try {
|
|
589
|
+
var tileFeature = turf.bboxPolygon(tileBbox);
|
|
590
|
+
var isWithin = this._clipFeatures.some(function (feature) {
|
|
591
|
+
return turf.booleanWithin(tileFeature, feature);
|
|
592
|
+
});
|
|
593
|
+
if (isWithin) {
|
|
594
|
+
this.logDebug({
|
|
595
|
+
type: 'tile-kept',
|
|
596
|
+
x: imagery.x,
|
|
597
|
+
y: imagery.y,
|
|
598
|
+
level: imagery.level,
|
|
599
|
+
bbox: tileBbox,
|
|
600
|
+
reason: 'within-clip'
|
|
601
|
+
});
|
|
602
|
+
return this.createTexture(context, imagery);
|
|
603
|
+
}
|
|
604
|
+
var intersections = this.getClipIntersections(tileFeature);
|
|
605
|
+
if (!intersections.length) {
|
|
606
|
+
this.logDebug({
|
|
607
|
+
type: 'tile-discarded',
|
|
608
|
+
x: imagery.x,
|
|
609
|
+
y: imagery.y,
|
|
610
|
+
level: imagery.level,
|
|
611
|
+
bbox: tileBbox,
|
|
612
|
+
reason: 'outside-clip'
|
|
613
|
+
});
|
|
614
|
+
imagery.image = this.createTileCanvas(imagery);
|
|
615
|
+
return this.createTexture(context, imagery);
|
|
616
|
+
}
|
|
617
|
+
var canvas = this.createTileCanvas(imagery);
|
|
618
|
+
var canvasContext = canvas.getContext('2d');
|
|
619
|
+
if (!canvasContext) {
|
|
620
|
+
return this.createTexture(context, imagery);
|
|
621
|
+
}
|
|
622
|
+
canvasContext.drawImage(imagery.image, 0, 0, imagery.image.width, imagery.image.height);
|
|
623
|
+
this.clip(canvasContext, intersections.flatMap(function (intersection) {
|
|
624
|
+
return _this2.geometryToPathArray({
|
|
625
|
+
boundPolygon: intersection,
|
|
626
|
+
bbox: tileBbox,
|
|
627
|
+
width: imagery.image.width,
|
|
628
|
+
height: imagery.image.height
|
|
629
|
+
});
|
|
630
|
+
}));
|
|
631
|
+
this.logDebug({
|
|
632
|
+
type: 'tile-clipped',
|
|
633
|
+
x: imagery.x,
|
|
634
|
+
y: imagery.y,
|
|
635
|
+
level: imagery.level,
|
|
636
|
+
bbox: tileBbox,
|
|
637
|
+
reason: 'intersects-clip'
|
|
638
|
+
});
|
|
639
|
+
void createImageBitmap(canvas).then(function (image) {
|
|
640
|
+
imagery.image = image;
|
|
641
|
+
_this2.createTexture(context, imagery);
|
|
642
|
+
});
|
|
643
|
+
return undefined;
|
|
644
|
+
} catch (error) {
|
|
645
|
+
this.logDebug({
|
|
646
|
+
type: 'tile-error',
|
|
647
|
+
x: imagery.x,
|
|
648
|
+
y: imagery.y,
|
|
649
|
+
level: imagery.level,
|
|
650
|
+
bbox: tileBbox,
|
|
651
|
+
error: error
|
|
652
|
+
});
|
|
653
|
+
return this.createTexture(context, imagery);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/** 调用 Cesium 原始纹理创建逻辑。 */
|
|
658
|
+
}, {
|
|
659
|
+
key: "createTexture",
|
|
660
|
+
value: function createTexture(context, imagery) {
|
|
661
|
+
return ImageryLayer.prototype._createTexture.call(this, context, imagery);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/** 获取当前瓦片与所有裁剪面的交集,用交集路径裁剪当前瓦片。 */
|
|
665
|
+
}, {
|
|
666
|
+
key: "getClipIntersections",
|
|
667
|
+
value: function getClipIntersections(tileFeature) {
|
|
668
|
+
var intersections = [];
|
|
669
|
+
this._clipFeatures.forEach(function (feature) {
|
|
670
|
+
if (!turf.booleanIntersects(tileFeature, feature)) {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
var intersection = turf.intersect(tileFeature, feature);
|
|
674
|
+
if (intersection !== null && intersection !== void 0 && intersection.geometry) {
|
|
675
|
+
intersections.push(intersection);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
return intersections;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/** 创建与当前瓦片同尺寸的透明 canvas。 */
|
|
682
|
+
}, {
|
|
683
|
+
key: "createTileCanvas",
|
|
684
|
+
value: function createTileCanvas(imagery) {
|
|
685
|
+
var canvas = document.createElement('canvas');
|
|
686
|
+
canvas.width = imagery.image.width;
|
|
687
|
+
canvas.height = imagery.image.height;
|
|
688
|
+
return canvas;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/** 将地理坐标转换为当前瓦片画布像素坐标。 */
|
|
692
|
+
}, {
|
|
693
|
+
key: "pointToPixel",
|
|
694
|
+
value: function pointToPixel(options) {
|
|
695
|
+
for (var i = 0; i < options.coors.length; i += 1) {
|
|
696
|
+
var coorTmp = options.coors[i];
|
|
697
|
+
var pointTmp = [];
|
|
698
|
+
for (var j = 0; j < coorTmp.length; j += 1) {
|
|
699
|
+
pointTmp.push([(coorTmp[j][0] - options.bbox[0]) / (options.bbox[2] - options.bbox[0]) * options.width, options.height - (options.bbox[3] - coorTmp[j][1]) / (options.bbox[3] - options.bbox[1]) * options.height]);
|
|
700
|
+
}
|
|
701
|
+
options.pointArr.push(pointTmp);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/** 将裁剪后的 geometry 转换为画布 path 坐标数组。 */
|
|
706
|
+
}, {
|
|
707
|
+
key: "geometryToPathArray",
|
|
708
|
+
value: function geometryToPathArray(options) {
|
|
709
|
+
var _this3 = this;
|
|
710
|
+
var featureType = options.boundPolygon.geometry.type;
|
|
711
|
+
var pointArr = [];
|
|
712
|
+
if (featureType === 'Polygon') {
|
|
713
|
+
this.pointToPixel({
|
|
714
|
+
pointArr: pointArr,
|
|
715
|
+
coors: options.boundPolygon.geometry.coordinates,
|
|
716
|
+
bbox: options.bbox,
|
|
717
|
+
width: options.width,
|
|
718
|
+
height: options.height
|
|
719
|
+
});
|
|
720
|
+
} else if (featureType === 'MultiPolygon') {
|
|
721
|
+
options.boundPolygon.geometry.coordinates.forEach(function (polygon) {
|
|
722
|
+
_this3.pointToPixel({
|
|
723
|
+
pointArr: pointArr,
|
|
724
|
+
coors: polygon,
|
|
725
|
+
bbox: options.bbox,
|
|
726
|
+
width: options.width,
|
|
727
|
+
height: options.height
|
|
728
|
+
});
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
return pointArr;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/** 按 path 坐标裁剪当前瓦片画布。 */
|
|
735
|
+
}, {
|
|
736
|
+
key: "clip",
|
|
737
|
+
value: function clip(context, pointArr) {
|
|
738
|
+
context.save();
|
|
739
|
+
context.globalCompositeOperation = 'destination-in';
|
|
740
|
+
context.beginPath();
|
|
741
|
+
for (var i = 0; i < pointArr.length; i += 1) {
|
|
742
|
+
var pointTmp = pointArr[i];
|
|
743
|
+
for (var j = 0; j < pointTmp.length; j += 1) {
|
|
744
|
+
if (j === 0) {
|
|
745
|
+
context.moveTo(pointTmp[j][0], pointTmp[j][1]);
|
|
746
|
+
} else {
|
|
747
|
+
context.lineTo(pointTmp[j][0], pointTmp[j][1]);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
context.closePath();
|
|
752
|
+
context.fillStyle = '#000000';
|
|
753
|
+
context.fill();
|
|
754
|
+
context.restore();
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/** 输出结构化 debug 事件。 */
|
|
758
|
+
}, {
|
|
759
|
+
key: "logDebug",
|
|
760
|
+
value: function logDebug(event) {
|
|
761
|
+
if (!this._debug) {
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
var debugEvent = _objectSpread({
|
|
765
|
+
layerId: this.id
|
|
766
|
+
}, event);
|
|
767
|
+
if (typeof this._debug === 'function') {
|
|
768
|
+
this._debug(debugEvent);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
console.debug('[CustomRasterLayer]', debugEvent);
|
|
772
|
+
}
|
|
773
|
+
}]);
|
|
774
|
+
return CustomRasterLayer;
|
|
775
|
+
}(ImageryLayer);
|
|
776
|
+
export { CustomRasterLayer as default };
|