diff --git a/dev-demos/features/tile/raster/satellite.tsx b/dev-demos/features/tile/raster/satellite.tsx
index f2e3610b66..c0b63f6c78 100644
--- a/dev-demos/features/tile/raster/satellite.tsx
+++ b/dev-demos/features/tile/raster/satellite.tsx
@@ -1,6 +1,11 @@
import { Scene, RasterLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';
+import { encodeParams, sign } from './signGenerator';
+const canvas = document.createElement('canvas');
+canvas.width = 256;
+canvas.height = 256;
+const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
export default () => {
useEffect(() => {
@@ -8,42 +13,139 @@ export default () => {
id: 'map',
pickBufferScale: 1.0,
map: new GaodeMap({
- center: [121.268, 30.3628],
+ center: [127.471855, 46.509622], // 绥化市-北林区
pitch: 0,
style: 'blank',
zoom: 10,
}),
});
- const layerTile = new RasterLayer({
- zIndex: 1,
- });
- layerTile.source(
- '//t{0-4}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=f1f2021a42d110057042177cd22d856f',
- {
- parser: {
- type: 'rasterTile',
- tileSize: 256,
+ const Base64toArrayBuffer = (base64Data) => {
+ const padding = '='.repeat((4 - (base64Data.length % 4)) % 4);
+ const base64 = (base64Data + padding).replace(/-/g, '+').replace(/_/g, '/');
+
+ const rawData = window.atob(base64);
+ const outputArray = new Uint8Array(rawData.length);
+
+ for (let i = 0; i < rawData.length; ++i) {
+ outputArray[i] = rawData.charCodeAt(i);
+ }
+ return outputArray;
+ }
+
+ const getUrlQueryParams = (url = location.search): any => {
+ const params = {};
+ const keys = url.match(/([^?&]+)(?==)/g);
+ const values = url.match(/(?<==)([^&]*)/g);
+ for (const index in keys) {
+ // @ts-ignore
+ params[keys[index]] = values?.[index];
+ }
+ return params;
+ };
+
+
+ // const layerTile = new RasterLayer({
+ // zIndex: 1,
+ // });
+ // layerTile.source(
+ // '//t{0-4}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=f1f2021a42d110057042177cd22d856f',
+ // {
+ // parser: {
+ // type: 'rasterTile',
+ // tileSize: 256,
- },
- },
- );
+ // },
+ // },
+ // );
const layerTile2 = new RasterLayer({
zIndex: 0,
- });
- layerTile2.source(
- 'http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
+ }).source(
+ // 'http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
+ `https://openapi.alipay.com/gateway.do?x={x}&y={y}&z={z}&index=1001&crow_type=101`,
{
parser: {
type: 'rasterTile',
+ dataType:'customArrayBuffer',
tileSize: 256,
- },
+
+ getCustomData: ({x,y,z},callback)=>{
+ const biz_content = { x, y, z, index:1001, crow_type:101 };
+ const newUrl = sign('anttech.ai.cv.rs.xytile.get', biz_content, {
+ charset: 'utf-8',
+ version: '1.0',
+ });
+
+ const signStr = Object.keys(encodeParams(newUrl))
+ .sort()
+ .map((key) => {
+ let data = encodeParams(newUrl)[key];
+ if (Array.prototype.toString.call(data) !== '[object String]') {
+ data = JSON.stringify(data);
+ }
+ return `${key}=${data}`;
+ })
+ .join('&');
+
+ const url = `https://openapi.alipay.com/gateway.do?${signStr}`;
+ fetch(url).then(res=>res.json()).then(response=>{
+ const bufferData = Base64toArrayBuffer(response?.anttech_ai_cv_rs_xytile_get_response?.image || '');
+ callback(null, bufferData);
+
+ })
+ },
+ format: async (data: any) => {
+ // console.log(bands)
+ const blob: Blob = new Blob([new Uint8Array(data)], {
+ type: 'image/png',
+ });
+ const img = await createImageBitmap(blob);
+ ctx.clearRect(0, 0, 256, 256);
+ ctx.drawImage(img, 0, 0, 256, 256);
+ const imgData = ctx.getImageData(0, 0, 256, 256).data;
+ const channelR: number[] = [];
+ const channelG: number[] = [];
+ const channelB: number[] = [];
+ for (let i = 0; i < imgData.length; i += 4) {
+ const R = imgData[i];
+ const G = imgData[i + 1];
+ const B = imgData[i + 2];
+ channelR.push(R);
+ channelG.push(G);
+ channelB.push(B);
+ }
+ return [
+ { rasterData: channelR, width: 256, height: 256 },
+ // { rasterData: channelG, width: 256, height: 256 },
+ // { rasterData: channelB, width: 256, height: 256 },
+ ];
+ },
+ // operation: {
+ // type:'rgb',
+ // options:{
+ // RMinMax:[0,255],
+ // GMinMax:[0,255],
+ // BMinMax:[0,255],
+ // }
+ // },
+ }
+
},
);
+ layerTile2.style({
+ opacity: 1,
+ clampLow: false,
+ clampHigh: false,
+ domain: [0, 150],
+ rampColors: {
+ colors: ['rgba(0, 0, 0, 0)','rgba(0, 0, 0, 0)','#EAC300','#EAC300' ],
+ positions: [0,0.2,0.6,1],
+ },
+ });
scene.on('loaded', () => {
- scene.addLayer(layerTile);
+ // scene.addLayer(layerTile);
scene.addLayer(layerTile2);
});
}, []);
diff --git a/dev-demos/features/tile/raster/signGenerator.ts b/dev-demos/features/tile/raster/signGenerator.ts
new file mode 100644
index 0000000000..3ca68c6548
--- /dev/null
+++ b/dev-demos/features/tile/raster/signGenerator.ts
@@ -0,0 +1,114 @@
+import moment from 'moment';
+import JSEncrypt from 'jsencrypt';
+import CryptoJS from 'crypto-js';
+
+// const key =
+// 遥感地图网页应用 2021003154649392 私钥
+// 'MIIEpQIBAAKCAQEAmGPwXSi1MjuIvEh0Gl75d62tTQF/vzMkFDuLjx5RJ/DiSntXbmVV3ZJjICNOKLaWCemHvBerJfXtDQUAJWVo8FwJJQrla3oGHQp38vUNtRLGQQkozzWeSslaXZc/cEDLBfjogzk4jojEXuFpgbzY0BJZg+KHh6k7TK/Tf6Zrn19fxVojeAx8njguIjlDbZAtnaNYlq3fYIVzPX3nd/xTQmLwHKjeuJ626i+zdo57oNKHOOStX/0Isf6y4rj8cdPrmxfWDw86vV1Pd378sKL0vejOrS6TLoYG8sMGk8Fi//ecXnY1068vYl2tQOIqHiZb8XGCFIYoNWefvHPsufqkQwIDAQABAoIBAQCAnfDTn7T2tZqdVwVu8HPbF6Gp2bcJF8++p9cNLwhODpffRySuzyZegNva1xFzeU8/BHQEQ3G2805ka7EI3wNnwjYRppWlVXLtddVxIHS2PCdJ4sInyNhVxIXZcfsf8f+ohcEwZ84dNr+OWO+kiU/wpVwZ3MqIrEOZYNi/5yT0d8jdNNMsDGeGwGzULN/eIqgiF9l3vbn4w79WoUTOll6yxC/8ZYa9TX8yFWGKjElmr6K/c2x2NuRpToQgYv5iqN6m1biUNmkoqQ3cbysGAKP2Vb7S9GEjI6Kcp3TwfyrE65s7pS0aU6lNfuqzjNuulRDnxAXP2+fHSOcZBFQSu7TpAoGBAOPO+9jbezq6eQ9seruN8UMriTiFRU02E+HNihCbM2Vvwbb4wet25dJYL4TqRT+CawQA7XQ85/8QCl0mpUOFDJa6agYSby2Eai2IDZ5KxvdDNXDuQv+R4Wh2TV3xjK4tyrUZhYGZZ8g1MrxuilvR7/gG41pl0X28aDHxzjWgV4JtAoGBAKs/sccl4QbINq2AUB/rWKFv2SNVMTpq13/PtRCeVe49Gin9SpEuYm5XD/0n9hNRDiYul8Hwcq1ff5O+bEi+UJyqyVDjJs82onhCJOY+hWkTcluQCkjKNqKyTciys0gsZorY8/oxzkZ7aBQSkhZ4+ReR8tf2Ti46QTB1ft/55xNvAoGBAKINb6JIH1UbqVqLdJNO2b1Kjwah5zaRrXsHV5uQi/MwmMCsHGZ/4eTLzqHidPhEshPbBQ+W9AHBS14QS6fIUbg3S4yeOHBMratOCUH9N6RVLwLyur5K6+n/nfGiDs0ozfYd/Za/pdAJ59mbWNkQcoAhhkGcBHZJPGWq+WG0egvRAoGBAJnLPTS17w7xNjHBf7P634E0etTBiNGG7HyLpHgFSvUHiPzWzmXuO1YO+HwJrHSSodtmksII2GSd1GxyYrs9uBXLR7tOFSeZUHYiKRNiaNwCK/zRMntGp6Sb70FkQ6B4x6rAxvQWUMN5xvHn760g/cvONkL/oBziEnObwdMSkxUfAoGAQ2zEYHRAas8lichIbcrmfvtBUSfAKIEJO+rXeNoxjEKPHRERlCVnAs/O5OmxbB+oZzyrK16+LGM+3jnDEf0kdT49cqkMK1n8CJR2W9MrbK8jMFZOR0XW7vQ0J0vnc5R6vobf3U4jFq8nVK3ehOUicVIqre6LEiHKVQUqC3y+Vl4=';
+// 遥感地图网页应用 2021003154694648 私钥
+// 'MIIEpQIBAAKCAQEA1N165ud87194oMhMT4oCsoF+DenzjhRMEo4WxlSbWsyGRExQh7MSZ+aZZS8RWDLSfy3VNpUhpYllDiGg/Ng2q6SE4inU2O5IBghBKWJoznld+0CiUCKFEFukRYtUszedHiN5rlfE4E/PsUF0RiV8VRCPMdsHsfQvwYJ54CAuFKKcD4FLHrBmHb7X7D569gGJYEyf4L5iBxLoFgoiMnUwoY2SZr4ge+kW94RvNuUCWHDDA8o5/Z8SMztotrwRE1utHgqbPSV1wIn1vppQs8tH2qp8m0s5lT11iEqoJ6NPNlglU6s/4p7CV4genTvXOPyGqVKxz1i29m2LebU0khSwzwIDAQABAoIBAQCyEOBp3kXV3HCFV2j2tIWTG93997JFLVeBwhjtKgOXjjXXVlubWMJR5kZ1rUz+Ee2idA3DDjfKSUge7STFvnzlUsfShZnHKnVXjnosC2WPK1nh/2yISogzaeXeQzLEhQZLGvQEUumfl0QvjIie0WbTpfmThB1I0PNOFj6rrV++482DNdOfIGPAjWb+Id32vbQxgzUtFNsSno85l4EFRZQ9hfXsljxRuDeA4VLUWo7ZpOztNVO95emhAWgWQ2S0/YNgVO04UVVfiCQSqa80HpNz4l+4WnCQEDKrOA4kY64h988g7MG1bN9uaV9zQ6u6wh/Ijb4vvIL/ShwaQHvWtE5RAoGBAPJFgPcyv7Eatg6WMM+bW5ihf6Q2x3KUvocAtnhjLb0DNGsewJGknCU0dE5BQN0TdbV3H1mncLaBOl7XFT2Rvgs0KdUzCBi60uyMtFSRnty/UarE5vdUH8pKWX+OniRcMr9nYD1k/CxWrBKfhOwi8rxgaIJkbIjzHWzwKbZoeEvXAoGBAODtZSKmBc83v5fRR4eSr0QPDzjvzEOZc/g5AOzKhJx+2d496t25bULuxWEsHonvZweLNZraM2wV/lM6wLbmEj1FYHvcuU9TvInceqCbKcXSCkZOpqyuUKJGQVHIAswno07cekp2SFB+1OABYSvEWqVeYg3rqzVjGqVrvuBae2PJAoGBAMTzJbVPhzAVk9zl0cZj+KFq4JYBhkAqlXywYqYZkkwut8VBWbDMjbddHhOjznQqZq1fqpe6m9Fx2p7Q4M6NlV4MSNmtw64+6kss00hQnUG9MknOCikUNUfBC2K78OmEHiklg8JFPw9YYkg9b9R7ULM8+JjPxL/MS6aM0owb/3c/AoGBAKXir2okY7h19xmywTxdlGFvcdyeDln0vLDe6a25lqAMdgYQSD2KWei5TFzkOwmjxKqtorU4JCCc/9rGRAcgG2eQ2R3ApfK5YR2Tu+TjSqWYyPcdXpOQY+uqQNZd2qJSwYCR3qc4IREs2Tb0DYRH5kp8F3kIzFYtZyOFGVtBoCrxAoGAdZnOWrUyXx6OJg98+TtV5HMkNIVbdGjjoJvmvxgXnABHKbyRjnP4WxARQiiBga/qh07+Ovo4EkbyWf5oqkogzY+F969A5zeSQCuJ7Gu6HzBdjcAIRzq8hDqBiFSskYBFz/Ohn8JL8Y757JXYgjur6AppOk4KElC0o/ZOXkPjg7k=';
+// RSA 签名
+const encrypt = new JSEncrypt();
+// encrypt.setPrivateKey(key);
+
+const AK = {
+ appId: '2021003154694648', // 遥感地图网页应用
+ key:
+ 'MIIEpQIBAAKCAQEA1N165ud87194oMhMT4oCsoF+DenzjhRMEo4WxlSbWsyGRExQh7MSZ+aZZS8RWDLSfy3VNpUhpYllDiGg/Ng2q6SE4inU2O5IBghBKWJoznld+0CiUCKFEFukRYtUszedHiN5rlfE4E/PsUF0RiV8VRCPMdsHsfQvwYJ54CAuFKKcD4FLHrBmHb7X7D569gGJYEyf4L5iBxLoFgoiMnUwoY2SZr4ge+kW94RvNuUCWHDDA8o5/Z8SMztotrwRE1utHgqbPSV1wIn1vppQs8tH2qp8m0s5lT11iEqoJ6NPNlglU6s/4p7CV4genTvXOPyGqVKxz1i29m2LebU0khSwzwIDAQABAoIBAQCyEOBp3kXV3HCFV2j2tIWTG93997JFLVeBwhjtKgOXjjXXVlubWMJR5kZ1rUz+Ee2idA3DDjfKSUge7STFvnzlUsfShZnHKnVXjnosC2WPK1nh/2yISogzaeXeQzLEhQZLGvQEUumfl0QvjIie0WbTpfmThB1I0PNOFj6rrV++482DNdOfIGPAjWb+Id32vbQxgzUtFNsSno85l4EFRZQ9hfXsljxRuDeA4VLUWo7ZpOztNVO95emhAWgWQ2S0/YNgVO04UVVfiCQSqa80HpNz4l+4WnCQEDKrOA4kY64h988g7MG1bN9uaV9zQ6u6wh/Ijb4vvIL/ShwaQHvWtE5RAoGBAPJFgPcyv7Eatg6WMM+bW5ihf6Q2x3KUvocAtnhjLb0DNGsewJGknCU0dE5BQN0TdbV3H1mncLaBOl7XFT2Rvgs0KdUzCBi60uyMtFSRnty/UarE5vdUH8pKWX+OniRcMr9nYD1k/CxWrBKfhOwi8rxgaIJkbIjzHWzwKbZoeEvXAoGBAODtZSKmBc83v5fRR4eSr0QPDzjvzEOZc/g5AOzKhJx+2d496t25bULuxWEsHonvZweLNZraM2wV/lM6wLbmEj1FYHvcuU9TvInceqCbKcXSCkZOpqyuUKJGQVHIAswno07cekp2SFB+1OABYSvEWqVeYg3rqzVjGqVrvuBae2PJAoGBAMTzJbVPhzAVk9zl0cZj+KFq4JYBhkAqlXywYqYZkkwut8VBWbDMjbddHhOjznQqZq1fqpe6m9Fx2p7Q4M6NlV4MSNmtw64+6kss00hQnUG9MknOCikUNUfBC2K78OmEHiklg8JFPw9YYkg9b9R7ULM8+JjPxL/MS6aM0owb/3c/AoGBAKXir2okY7h19xmywTxdlGFvcdyeDln0vLDe6a25lqAMdgYQSD2KWei5TFzkOwmjxKqtorU4JCCc/9rGRAcgG2eQ2R3ApfK5YR2Tu+TjSqWYyPcdXpOQY+uqQNZd2qJSwYCR3qc4IREs2Tb0DYRH5kp8F3kIzFYtZyOFGVtBoCrxAoGAdZnOWrUyXx6OJg98+TtV5HMkNIVbdGjjoJvmvxgXnABHKbyRjnP4WxARQiiBga/qh07+Ovo4EkbyWf5oqkogzY+F969A5zeSQCuJ7Gu6HzBdjcAIRzq8hDqBiFSskYBFz/Ohn8JL8Y757JXYgjur6AppOk4KElC0o/ZOXkPjg7k=',
+};
+
+const openAPIConfig: any = {
+ gateway: 'http://openapi.stable.dl.alipaydev.com/gateway.do',
+ timeout: 5000,
+ charset: 'utf-8',
+ version: '1.0',
+ appId: '2021003154694648',
+ camelcase: false,
+};
+
+export async function callByOpenAPI(
+ method: string,
+ // modelId: string,
+ // version: string,
+ // appId: string = '',
+ bizContent: Object,
+) {
+ const params = sign(method, bizContent, openAPIConfig);
+ const encodedParams = encodeParams(params);
+ // console.log('encodedParams :>> ', encodedParams);
+ return encodedParams;
+}
+
+/**
+ * 签名
+ * @description https://opendocs.alipay.com/common/02kf5q
+ * @param {string} method 调用接口方法名,比如 alipay.ebpp.bill.add
+ * @param {object} bizContent 业务请求参数
+ * @param {object} config sdk 配置
+ */
+export function sign(method: string, bizContent: any = {}, config: any): any {
+ const signParams = Object.assign({
+ method,
+ appId: config.appId || AK.appId,
+ charset: config.charset,
+ version: config.version,
+ signType: 'RSA2',
+ timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
+ // appAuthToken: '202210BB64237396751c42aa9c225985256e2D92',
+ // ws_service_url: 'mysearchgw-36.gz00b.dev.alipay.net:12200', // 可选,开发环境需要传,预发环境不需要传
+ });
+
+ encrypt.setPrivateKey(config.key || AK.key);
+
+ if (bizContent) {
+ signParams.bizContent = JSON.stringify(toSnakeCases(bizContent));
+ }
+
+ // params key 驼峰转下划线
+ const deCamelizeParams = toSnakeCases(signParams);
+
+ // 排序
+ const signStr = Object.keys(deCamelizeParams)
+ .sort()
+ .map((key) => {
+ let data = deCamelizeParams[key];
+ if (Array.prototype.toString.call(data) !== '[object String]') {
+ data = JSON.stringify(data);
+ }
+ return `${key}=${data}`;
+ })
+ .join('&');
+
+ // console.log('signStr :>> ', signStr);
+
+ // 计算签名
+ const sign = RSAEncrypt(signStr);
+ return Object.assign(deCamelizeParams, { sign });
+}
+
+function RSAEncrypt(signStr: string) {
+ const start = Date.now();
+ const encrypted = encrypt.sign(signStr, CryptoJS.SHA256, 'sha256');
+ // console.log('encrypted :>> ', encrypted, Date.now() - start);
+ return encrypted;
+}
+
+function toSnakeCases(params: any) {
+ const out: { [key in string]: any } = {};
+ Object.keys(params).forEach((key) => {
+ const newKey = key.replace(
+ /([A-Z])/g,
+ (match) => '_' + match.toLowerCase(),
+ );
+ out[newKey] = params[key];
+ });
+ return out;
+}
+
+export function encodeParams(params: any) {
+ const out: { [key in string]: any } = {};
+ Object.keys(params).forEach((key) => {
+ out[key] = encodeURIComponent(params[key]);
+ });
+ return out;
+}
diff --git a/dev-demos/features/tile/rasterImage.md b/dev-demos/features/tile/rasterImage.md
index 5cf250bd80..7c2ba1b74e 100644
--- a/dev-demos/features/tile/rasterImage.md
+++ b/dev-demos/features/tile/rasterImage.md
@@ -3,6 +3,3 @@ raster 图片瓦片
#### 卫星图
-
-#### 图片瓦片 - 颜色映射
-
\ No newline at end of file
diff --git a/package.json b/package.json
index c36f698302..d32e80f948 100644
--- a/package.json
+++ b/package.json
@@ -154,7 +154,9 @@
"webpack-merge": "^4.1.4",
"wellknown": "^0.5.0",
"worker-loader": "^2.0.0",
- "yorkie": "^2.0.0"
+ "yorkie": "^2.0.0",
+ "crypto-js": "^4.1.1",
+ "jsencrypt": "^3.2.1"
},
"scripts": {
"dev": "npm run worker && dumi dev",
diff --git a/packages/core/src/services/source/ISourceService.ts b/packages/core/src/services/source/ISourceService.ts
index c0cc9da2b5..54cd2144d5 100644
--- a/packages/core/src/services/source/ISourceService.ts
+++ b/packages/core/src/services/source/ISourceService.ts
@@ -8,6 +8,8 @@ export enum RasterTileType {
IMAGE = 'image',
ARRAYBUFFER = 'arraybuffer',
RGB = 'rgb',
+ CUSTOMRGB = 'customRGB',
+ CUSTOMARRAYBUFFER = 'customArrayBuffer',
}
export interface IGeojsonvtOptions {
@@ -28,6 +30,7 @@ export interface ITileParserCFG {
minZoom?: number;
maxZoom?: number;
zoomOffset?: number;
+ getCustomData: (tile: { x: number, y: number, z: number },cb:(err:any,data:any)=>void)=>void,
extent?: [number, number, number, number];
requestParameters: Partial;
updateStrategy?: 'overlap' | 'replace';
diff --git a/packages/layers/src/tile/tileFactory/index.ts b/packages/layers/src/tile/tileFactory/index.ts
index d495ef5b7e..9a77b4ab2d 100644
--- a/packages/layers/src/tile/tileFactory/index.ts
+++ b/packages/layers/src/tile/tileFactory/index.ts
@@ -36,8 +36,10 @@ export function getTileFactory(layer: ILayer) {
const { dataType } = layer.getSource().parser;
switch(dataType) {
case 'rgb':
+ case 'customRGB':
return RasterRGBTile;
case 'arraybuffer':
+ case 'customArrayBuffer':
return RasterTile
case "terrainRGB" :
return RasterTerrainRGBTile
diff --git a/packages/source/src/parser/raster-tile.ts b/packages/source/src/parser/raster-tile.ts
index bbb4ff5d9a..4c9d9a8965 100644
--- a/packages/source/src/parser/raster-tile.ts
+++ b/packages/source/src/parser/raster-tile.ts
@@ -6,6 +6,7 @@ import {
TilesetManagerOptions,
} from '@antv/l7-utils';
import { IParserData } from '../interface';
+import { getCustomData } from '../utils/tile/getCustomData';
import {
defaultFormat,
getTileBuffer,
@@ -61,6 +62,15 @@ export default function rasterTile(
cfg?.format || defaultFormat,
cfg?.operation,
);
+ case RasterTileType.CUSTOMARRAYBUFFER:
+ case RasterTileType.CUSTOMRGB:
+ return getCustomData(
+ tile,
+ // @ts-ignore
+ cfg?.getCustomData,
+ cfg?.format || defaultFormat,
+ cfg?.operation,
+ );
default:
return getTileImage(data as string | string[], tileParams, tile, cfg);
}
diff --git a/packages/source/src/utils/tile/getCustomData.ts b/packages/source/src/utils/tile/getCustomData.ts
new file mode 100644
index 0000000000..f09f78ed12
--- /dev/null
+++ b/packages/source/src/utils/tile/getCustomData.ts
@@ -0,0 +1,38 @@
+import { IRasterFormat, IBandsOperation } from '../../interface';
+// import { bindCancel } from './request';
+import {
+ SourceTile,
+} from '@antv/l7-utils';
+import { processRasterData } from '../bandOperation/bands';
+
+export const getCustomData = async (
+ tile: SourceTile,
+ getCustomData: (tile: { x: number, y: number, z: number }, cb: (err: any, data: any) => void) => void,
+ rasterFormat: IRasterFormat,
+ operation?: IBandsOperation,
+) => {
+ return new Promise((resolve, reject) => {
+ getCustomData({
+ x: tile.x,
+ y: tile.y,
+ z: tile.z
+ }, (err, data) => {
+ if(err){
+ reject(err)
+ }
+ if (data) {
+ processRasterData([{data,bands:[0]}], rasterFormat, operation, (err: any, img: any) => {
+ if (err) {
+ reject(err);
+ } else if (img) {
+ resolve(img);
+ }
+ },);
+ }
+
+ })
+ })
+
+}
+
+
diff --git a/packages/source/src/utils/tile/getRasterTile.ts b/packages/source/src/utils/tile/getRasterTile.ts
index aaec7c3638..f2a75e7af8 100644
--- a/packages/source/src/utils/tile/getRasterTile.ts
+++ b/packages/source/src/utils/tile/getRasterTile.ts
@@ -36,7 +36,7 @@ export const getTileBuffer = async (
getRasterFile(
tile,
requestParameters,
- (err, img) => {
+ (err:any, img:any) => {
if (err) {
reject(err);
} else if (img) {