import { Http } from "../Http";
import { AstHelper } from "@gvol-org/geovis-brain-core";
import { BatchAsync } from "./batchAsync";
import { FeatureCollection } from "../models/FeatureCollection";
/**
* @class BatchProcessing.image
* @since BatchProcessing
* @todo image.toExec
* @todo image.toJob
*/
export class image extends BatchAsync {
/**
* @hideconstructor
* @see BatchProcessing.image
* @returns BatchProcessing.image
*/
constructor(...param: any[]) {
super();
if (!(this instanceof image)) {
return new image(param);
}
}
static setBatchProcessMap(mapsdk: any) {
this.mapSdk = mapsdk;
}
static mapSdk: any;
/**
* 对影像进行批处理
* @param {Object} args 批处理对象
* @tutorial BatchProcessing.image
*/
static toExec(args: Object) {
if (!Http.userIsVip) {
// window['httpp'].abortSubject$.next();
throw new Error("仅支持vip用户使用批处理功能");
}
if (args["scale"]) {
Http.scale = args["scale"].toString();
}
let newObj = JSON.parse(JSON.stringify(args));
let { newChain, newOrder } = AstHelper.objectParamChain(newObj);
newChain.push({
"functionName": "BatchProcessing.image.toExec",
"arguments": {
"args": newObj
},
"order": newOrder
})
// console.log('执行toExec方法....创建调用链');
let batchObj = new BatchAsync();
batchObj.execute(async () => {
let data = await Http.getRequest(newChain, false, true);
Http.responseSubject$.next(data);
// console.log("batch接到的数据>>>", data);
if (data && data.data.status == "success") {
batchObj.param = data;
this.batchSubject$.next(data.data.detail);
} else {
console.log("应当删除batch");
}
});
return batchObj;
}
static processLayerIds: string[] = [];
/**
* 批量导出
* @param {Object} args 批处理对象
* @tutorial BatchProcessing.image
*/
static toJob(args: {
result: FeatureCollection;
resultType?: string;
scale?: number;
description?: string;
export?: object;
mergeFlag?:boolean
}) {
if (!Http.userIsVip) {
throw new Error("仅支持vip用户使用批处理功能");
}
if (!this.mapSdk) {
console.log("批处理函数需要预先设置map----by weiyc")
return;
}
if (args["scale"]) {
Http.scale = args["scale"].toString();
}
if(args.mergeFlag == undefined){
args.mergeFlag = false;
}
let newObj = JSON.parse(JSON.stringify(args));
let { newChain, newOrder } = AstHelper.objectParamChain(newObj);
newChain.push({
"functionName": "BatchProcessing.image.toJob",
"arguments": {
"args": newObj
},
"order": newOrder
})
let batchObj = new BatchAsync();
batchObj.execute(async () => {
// await this.getBatchProcessResult(newChain);
let data = await Http.getRequest(newChain, false, true);
Http.responseSubject$.next(data);
if (data && data.data.status == "success") {
batchObj.param = data;
this.refreshTaskList$.next(true);
// console.log("subjecttttt", this.exportSubject$);
// this.exportSubject$.next(data.data.detail);
}
});
return batchObj;
}
//轮询实时上球逻辑----已弃用
private static async getBatchProcessResult(chain: any, lastSourceId?: string) {
let data = await Http.getRequest(chain, false, true);
Http.responseSubject$.next(data);
console.log("batch接到的数据>>>", data);
if (data && data.data.status == "success") {
let detail = data.data.detail;
if(detail.tempViewUrl){
let sourceOption = {
url: detail.tempViewUrl
}
if(detail["properties"] && detail["properties"]["bbox"]){
sourceOption["bbox"] = detail["properties"]["bbox"];
}
lastSourceId = this.addProcessLayer(sourceOption, lastSourceId);
// 一秒后再次轮询
setTimeout(() => {
this.getBatchProcessResult(chain, lastSourceId)
}, 1000);
}else if(detail.url){
let sourceOption = {
url: detail.url,
sourceLayer: detail["sourceLayer"]
}
if (detail["properties"] && detail["properties"]["bbox"]) {
sourceOption["bbox"] = detail["properties"]["bbox"];
}
// 上球最终图层
this.addProcessLayer(sourceOption, lastSourceId);
} else {
console.log("批处理最终结果异常");
return;
}
} else {
console.log("batch返回结果失败");
}
}
//根据requestid请求批处理结果上球预览
public static async addBatchLayer(requestid: string){
//请求批处理中间(最终)结果
let url = `${Http.astUrl}/getResult?requestId=${requestid}`;
let data = await window["httpp"].getData(url, requestid);
console.log(data);
if (data && data.data.status == "success") {
let detail = data.data.detail;
if(detail.tempViewUrl){
let sourceOption = {
url: detail.tempViewUrl
}
if(detail["properties"] && detail["properties"]["bbox"]){
sourceOption["bbox"] = detail["properties"]["bbox"];
}
this.addProcessLayer(sourceOption, requestid);
}else if(detail.url){
let sourceOption = {
url: detail.url,
sourceLayer: detail["sourceLayer"]
}
if (detail["properties"] && detail["properties"]["bbox"]) {
sourceOption["bbox"] = detail["properties"]["bbox"];
}
// 上球最终图层
this.addProcessLayer(sourceOption, requestid);
} else {
console.log("批处理最终结果异常");
return;
}
} else {
console.log("batch返回结果失败");
}
}
//根据requestid删除批处理上球图层
public static removeBatchLayer(requestid: string){
if (this.sourceLayerIdsMap.has(requestid)) {
let layerIds = this.sourceLayerIdsMap.get(requestid);
layerIds.forEach((lid: any) => {
this.mapSdk.map.removeLayer(lid);
});
this.mapSdk.map.removeSource(requestid);
this.sourceLayerIdsMap.delete(requestid);
}
}
private static sourceLayerIdsMap: Map<string, string[]> = new Map();
private static addProcessLayer(urlObj: object, lastSourceId?: string) {
//删除上次的图层
if (lastSourceId) {
if (this.sourceLayerIdsMap.has(lastSourceId)) {
let layerIds = this.sourceLayerIdsMap.get(lastSourceId);
layerIds.forEach((lid: any) => {
this.mapSdk.map.removeLayer(lid);
});
this.mapSdk.map.removeSource(lastSourceId);
this.sourceLayerIdsMap.delete(lastSourceId);
}
}
// 随机生成8位字符sourceId
function generateRandom8CharString() {
const possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let randomString = '';
for (let i = 0; i < 8; i++) {
randomString += possibleChars.charAt(Math.floor(Math.random() * possibleChars.length));
}
return randomString;
}
//加图层,共.json/.TIF/.fgb/.pbf四种数据格式
let sourceId = generateRandom8CharString();
//提取url后缀
var matches = urlObj["url"].match(/\.([^.]+)$/);
var extension = matches ? matches[1] : "";
if (extension == "json") {
fetch(urlObj["url"], {
signal: Http.signal
}).then(
response => response.json()).then(
response => {
console.log(".json文件结果", response)
let geojsonData = {
"type": response.type,
"features": response.features
};
let source = {
type: "geojson",
data: geojsonData,
};
this.addLayerByVector(source, sourceId);
this.sourceLayerIdsMap.set(sourceId, [sourceId + "Circle", sourceId + "Line", sourceId + "Fill"]);
}).catch(error => {
console.error('请求失败', error);
return;
});
} else if (extension == "TIF") {
let source = {
'type': 'raster',
'tiles': [urlObj["url"]],
'tileSize': 256,
};
if(urlObj["bbox"]){
source["bounds"] = urlObj["bbox"];
//执行飞入
this.mapSdk.map.fitBounds(urlObj["bbox"]);
}
this.addLayerByRaster(source, sourceId);
this.sourceLayerIdsMap.set(sourceId, [sourceId + "Layer"]);
} else if (extension == "fgb") {
let source = {
'type': 'raster',
'tiles': [urlObj["url"] + "¶m=null"],
'tileSize': 256,
};
if(urlObj["bbox"]){
source["bounds"] = urlObj["bbox"];
//执行飞入
this.mapSdk.map.fitBounds(urlObj["bbox"]);
}
this.addLayerByRaster(source, sourceId);
this.sourceLayerIdsMap.set(sourceId, [sourceId + "Layer"]);
} else if (extension == "pbf") {
let source = {
type: 'vector',
tiles: [urlObj["url"]]
};
if(urlObj["bbox"]){
source["bounds"] = urlObj["bbox"];
//执行飞入
this.mapSdk.map.fitBounds(urlObj["bbox"]);
}
this.addLayerByVector(source, sourceId, urlObj["sourceLayer"]);
this.sourceLayerIdsMap.set(sourceId, [sourceId + "Circle", sourceId + "Line", sourceId + "Fill"]);
} else {
console.log("批处理返回未知数据格式");
return undefined;
}
return sourceId;
}
private static addLayerByVector(source: object, sourceId: string, sourceLayer?: string) {
this.mapSdk.map.addSource(sourceId, source);
let circleLayer = {
id: sourceId + "Circle",
type: "circle",
source: sourceId,
paint: {
"circle-opacity": 1,
"circle-radius": 1,
"circle-color": "#0000FF"
}
};
let lineLayer = {
id: sourceId + "Line",
type: "line",
source: sourceId,
paint: {
"line-color": "#0000FF",
"line-opacity": 0.9,
"line-width": 2,
}
};
let fillLayer = {
id: sourceId + "Fill",
type: "fill",
source: sourceId,
paint: {
"fill-color": "#0000FF",
"fill-opacity": 0.5
}
};
if(sourceLayer){
circleLayer["source-layer"] = sourceLayer;
lineLayer["source-layer"] = sourceLayer;
fillLayer["source-layer"] = sourceLayer;
}
this.mapSdk.map.addLayer(circleLayer);
this.mapSdk.map.addLayer(lineLayer);
this.mapSdk.map.addLayer(fillLayer);
}
private static addLayerByRaster(source: object, sourceId: string){
this.mapSdk.map.addSource(sourceId, source);
this.mapSdk.map.addLayer({
id: sourceId + "Layer",
type: 'raster',
source: sourceId,
paint: {
'raster-opacity': 1
}
});
}
static clearMap() {
this.sourceLayerIdsMap.forEach((value: any, key: any) => {
value.forEach((lid: any) => {
this.mapSdk.map.removeLayer(lid);
});
const style = this.mapSdk.map.getStyle();
let hasSource = style.sources.hasOwnProperty(key);
if(hasSource){
this.mapSdk.map.removeSource(key);
}
});
this.sourceLayerIdsMap.clear();
}
}