123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /* Copyright© 2000 - 2018 SuperMap Software Co.Ltd. All rights reserved.
- * This program are made available under the terms of the Apache License, Version 2.0
- * which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
- importScripts('https://iclient.supermap.io/web/libs/turf/5.1.6/turf.min.js')
- /**
- * 空间分析所需工具类
- */
- onmessage = function (event) {
- if (event.data) {
- let params = event.data;
- postMessage(analysis(params))
- }
- }
- //IDW 插值
- function interpolate(points, cellSize, options) {
- options = options || {};
- if (typeof options !== 'object') {
- throw new Error('options is invalid');
- }
- var gridType = options.gridType;
- var property = options.property;
- var weight = options.weight;
- if (!points) {
- throw new Error('points is required');
- }
- turf.collectionOf(points, 'Point', 'input must contain Points');
- if (!cellSize) {
- throw new Error('cellSize is required');
- }
- if (weight !== undefined && typeof weight !== 'number') {
- throw new Error('weight must be a number');
- }
- property = property || 'elevation';
- gridType = gridType || 'square';
- weight = weight || 1;
- var box = options.bbox || turf.bbox(points);
- var grid;
- switch (gridType) {
- case 'point':
- case 'points':
- grid = squareGrid(box, cellSize, options, gridType);
- break;
- case 'square':
- case 'squares':
- grid = squareGrid(box, cellSize, options, gridType);
- break;
- case 'hex':
- case 'hexes':
- grid = turf.hexGrid(box, cellSize, options);
- break;
- case 'triangle':
- case 'triangles':
- grid = turf.triangleGrid(box, cellSize, options);
- break;
- default:
- throw new Error('invalid gridType');
- }
- var results = [];
- var gridFeatures = grid.features;
- var pointFeatures = points.features;
- for (var i = 0, len = gridFeatures.length; i < len; i++) {
- var zw = 0;
- var sw = 0;
- var gridFeature = gridFeatures[i];
- for (var j = 0, leng = pointFeatures.length; j < leng; j++) {
- var point = pointFeatures[j];
- var gridPoint = (gridType === 'point') ? gridFeature : turf.centroid(gridFeature);
- var d = turf.distance(gridPoint, point, options);
- var zValue;
- if (point.properties[property]) {
- zValue = point.properties[property];
- }
- if (zValue === undefined) {
- zValue = point.geometry.coordinates[2];
- }
- if (zValue === undefined) {
- throw new Error('zValue is missing');
- }
- if (d === 0) {
- zw = zValue;
- }
- var w = 1.0 / Math.pow(d, weight);
- sw += w;
- zw += w * zValue;
- }
- var newFeature = turf.clone(gridFeature);
- newFeature.properties[property] = zw / sw;
- results.push(newFeature);
- }
- return turf.featureCollection(results);
- }
- function squareGrid(bbox, cellSide, options, gridType) {
- options = options || {};
- if (!turf.isObject(options)) {
- throw new Error('options is invalid');
- }
- var properties = options.properties;
- var mask = options.mask;
- var results = [];
- if (cellSide === null || cellSide === undefined) {
- throw new Error('cellSide is required');
- }
- if (!turf.isNumber(cellSide)) {
- throw new Error('cellSide is invalid');
- }
- if (!bbox) {
- throw new Error('bbox is required');
- }
- if (!Array.isArray(bbox)) {
- throw new Error('bbox must be array');
- }
- if (bbox.length !== 4) {
- throw new Error('bbox must contain 4 numbers');
- }
- if (mask && ['Polygon', 'MultiPolygon'].indexOf(turf.getType(mask)) === -1) {
- throw new Error('options.mask must be a (Multi)Polygon');
- }
- var west = bbox[0];
- var south = bbox[1];
- var east = bbox[2];
- var north = bbox[3];
- var bboxWidth = (east - west);
- var bboxHeight = (north - south);
- var cellWidth = cellSide / 111.94;
- var cellHeight = cellSide / 111.94;
- var columns = Math.floor(bboxWidth / cellWidth);
- var rows = Math.floor(bboxHeight / cellHeight);
- var deltaX = (bboxWidth - columns * cellWidth) / 2;
- var deltaY = (bboxHeight - rows * cellHeight) / 2;
- var currentX = west + deltaX;
- if (gridType === "square" || gridType === "squares") {
- // for (var column = 0; column < columns; column++) {
- // var currentY = south + deltaY;
- // for (var row = 0; row < rows; row++) {
- // var cellPoly = turf.polygon([[
- // [currentX, currentY],
- // [currentX, currentY + cellHeight],
- // [currentX + cellWidth, currentY + cellHeight],
- // [currentX + cellWidth, currentY],
- // [currentX, currentY]
- // ]], properties);
- // if (mask) {
- // if (intersect(mask, cellPoly)) results.push(cellPoly);
- // } else {
- // results.push(cellPoly);
- // }
- // currentY += cellHeight;
- // }
- // currentX += cellWidth;
- // }
- return null;
- } else {
- while (currentX <= east) {
- var currentY1 = south + deltaY;
- while (currentY1 <= north) {
- var cellPt = turf.point([currentX, currentY1], properties);
- if (mask) {
- if (turf.booleanWithin(cellPt, mask)) {
- results.push(cellPt);
- }
- } else {
- results.push(cellPt);
- }
- currentY1 += cellHeight;
- }
- currentX += cellWidth;
- }
- }
- return turf.featureCollection(results);
- }
- function processBuffer(buffer, saveAttrs) {
- var featureCollection = [];
- //var maxBounds = [-180, -90, 180, 90];
- //获取缓冲区异常feature, 并从原featureCollection中删除
- for (var i = 0, len = buffer.features.length; i < len; i++) {
- var feature = buffer.features[i];
- //不保留原有的属性值
- if (!saveAttrs) {
- //对字段属性进行for循环
- for (var pro in feature.properties) {
- var shouldDeleted = true;
- //序号和参考地点保留
- if (pro === 'ID') {
- shouldDeleted = false;
- }
- //删除除了位置和序号字段的其他字段属性
- if (shouldDeleted) delete feature.properties[pro];
- }
- }
- var bbox = turf.bbox(buffer.features[i]);
- //bounds的x轴距离作为判断依据,看数据误差<=1,这里写大一点防止意外
- if (parseInt(bbox[2] - bbox[0]) > 5) {
- //if(util.isRectOverlap(maxBounds, turf.bbox(buffer.features[i]))) {
- //删除功能,第一个参数为第一项位置,第二个参数为要删除几个。 array.splice(index, num) ,返回值为删除内容,array为结果值。
- //删除位置为i的一个要素
- featureCollection.push(buffer.features.splice(i, 1)[0]);
- i--;
- len--;
- }
- }
- //将异常feature分割为两个正常feature,重新添加到featureCollextion中
- var newCod;
- for (var k = 0; k < featureCollection.length; k++) {
- newCod = [];
- //获取不正常features
- var abnormalFeature = featureCollection[k];
- //获取不正常features的坐标
- var coordinates = turf.getCoords(abnormalFeature)[0];
- //对坐标进行循环
- for (var j = 0, leng = coordinates.length; j < leng; j++) {
- if (coordinates[j][0] < 0) {
- newCod.push(coordinates.splice(j, 1)[0]);
- j--;
- leng--;
- }
- }
- //闭合polygon
- if (newCod.length > 3) {
- if (newCod[newCod.length - 1][0] !== newCod[0][0] || newCod[newCod.length - 1][1] !== newCod[0][1]) {
- newCod.push(newCod[0]);
- }
- //两个feature属性相同
- buffer.features.push(turf.polygon([newCod], abnormalFeature.properties));
- }
- //闭合polygon
- if (coordinates.length > 3) {
- if (coordinates[coordinates.length - 1][0] !== coordinates[0][0] || coordinates[coordinates.length - 1][1] !== coordinates[0][1]) {
- coordinates.push(coordinates[0]);
- }
- buffer.features.push(abnormalFeature);
- }
- }
- }
- //feature合并
- function unionFeature(featureCollection, isFirst) {
- var results = [];
- var features = featureCollection.features;
- var featureLength = features.length;
- var oneceTotal = 2; //两两合并 直到最后剩一个多面对象为止(分网格 合并)
- var total = Math.round(featureLength / oneceTotal);
- //数组顺序打乱
- if (!isFirst) this.random(features);
- for (var i = 0; i <= total; i++) {
- var start = i * oneceTotal;
- var result = featureCollection.features[start];
- for (var j = 1; j < oneceTotal; j++) {
- var index = start + j;
- if (featureCollection.features[index]) {
- try {
- result = this.union(result, featureCollection.features[index]);
- } catch (e) {
- results.push(featureCollection.features[index]);
- }
- }
- }
- if (result) results.push(result);
- }
- if (results && results.length > 1) {
- //结果还是多个 继续合并
- return this.unionFeature(turf.featureCollection(results), false);
- } else {
- return results[0];
- }
- }
- //数组顺序打乱
- function random(arr) {
- arr.sort(function () { return 0.5 - Math.random() });
- }
- function union(features, polys) {
- let result = turf.union(features, polys);
- return result;
- }
- //多面转单面
- function toPolygons(multiPolygon) {
- var polygons = [];
- if (turf.getType(multiPolygon) === "Polygon") {
- polygons = [multiPolygon];
- } else {
- var coords = turf.getCoords(multiPolygon);
- polygons = coords.map(function (coord) {
- var poly = turf.polygon(coord);
- poly.bbox = turf.bbox(poly);
- poly.properties = multiPolygon.properties;
- return poly;
- });
- }
- return polygons;
- }
- function analysis(params) {
- let analysisMethod = params.analysisMethod;
- if (analysisMethod === "isolines") {
- let grid = interpolate(params.pointGrid, params.analysisCellSize, params.options);
- return turf.isolines(grid, params.breaks, { zProperty: params.zProperty });
- } else if (analysisMethod === "buffer") {
- let buffer = turf.buffer(params.geoJson, params.radius, { unit: params.unit });
- this.processBuffer(buffer, params.isSave);
- if (params.isUnion) {
- if (buffer.features.length > 0) {
- var unied = this.unionFeature(buffer, true);
- var result = this.toPolygons(unied);
- return turf.featureCollection(result);
- }
- return null;
- }
- return buffer;
- }
- }
|