feat: 设置瓦片多服务重构、支持加载多文件 (#1350)

* fix: 修复 featureScale 错误

* style: lint style

* fix: remove featureScalePlugin async

* feat: 优化简单矢量线瓦片的计算

* feat: 优化简单线图层的网格计算构建

* style: lint style

* style: lint style

* feat: 矢量瓦片更新渲染优化

* fix: 修复 tileLayer 重复创建导致的瓦片更新错误

* feat: 优化矢量瓦片图层本身的性能

* style: lint style

* feat: 优化 reRender 的调用

* feat: 合并瓦片销毁时的重绘

* feat: 去除矢量文本图层的 remapping 映射

* feat: 网格构建异步改造修复

* feat: 瓦片渲染流程优化

* feat: 通用瓦片流程的优化(主线程阻塞优化)

* feat: 补全瓦片更新触发

* feat: 默认顶点属性构建的优化

* style: lint style

* feat: 调整矢量点 uniform 参数

* chore: 去除矢量图层对偏移坐标的支持(不统一)

* style: lint style

* feat: 合并不同瓦片图层触发的重绘

* style: lint style

* chore: 调整瓦片代码结构

* feat: 矢量图层初始化优化

* chore: code clean

* feat: 矢量图层地图绘制数据属性映射优化

* chore: lint style

* feat: 矢量图层地图绘制初始化优化

* feat: maskLayer 初始化优化、debugtestLayer 默认为 basemap 模式

* chore: style

* feat: 绘制指令优化 - picking drawCommand

* style: lint style

* feat: 优化矢量图层初始化资源的创建

* feat: 简化矢量瓦片图层加载完成触发的重绘

* chore: 统一地图图层的样式写法 color、size

* style: lint style

* style: lint style

* style: lint style

* feat: 瓦片渲染执行优化
 Please enter the commit message for your changes. Lines starting

* feat: 优化拾取渲染

* style: lint style

* chore: style change

* style: lint style

* feat: layer plugin list clean

* style: lint style

* feat: 合并shader 使用

* style: lint style

* feat: 优化 source 计算

* feat: 去除 source 中对创建 tileset 的多余判断

* chore: 优化代码写法

* feat: 地图瓦片图层类型定义优化

* chore: data clean

* style: lint style

* style: lint style

* feat: debugLayer add basemap attr

* chore: demo 调整

* feat: 优化瓦片图层的渲染

* feat: 修改瓦片显示更新

* fix: 修复动画模式传值导致的显示效果问题

* fix: 修复 mapbox version 设置错误的问题

* fix: 修复 CanvasLayer render

* style: lint style

* chore: clean citybuilding demo

* style: lint style

* chore: clean point simple code

* chore: clean point text iconfont

* chore: clean polygon fill code

* style: lint style

* chore: clean billboard demo

* chore: clean polygon water/ocean demos

* chore: clean point radar demos

* chore: clean point normal demos

* chore: clean wind layer demos

* chore: clean demos

* feat: clean demos & fix half line insert attri

* style: lint style

* chore: clean mask demo

* chore: adjust website demo

* style: lint style

* chore: clean worker demos

* style: lint style

* fix: 修复箭头顶点重复插入的问题

* fix: 修复线图层弧线的纹理分布

* chore: website demos code clean

* chore: layerService/renderlayers move clear place

* chore: update version 2.9.26 -> 2.9.27-alpha.0

* chore: update version 2.9.27-alpha.0 -> 2.9.27-alpha.3

* feat: 支持 multi raster tile

* feat: add hillshade demo

* feat: 瓦片服务地址设置重构、多文件请求代码优化

* chore: 案例瓦片多服务用法修改

* chore: 类型定义优化 & api rename

Co-authored-by: shihui <yiqianyao.yqy@alibaba-inc.com>
This commit is contained in:
YiQianYao 2022-09-21 16:19:28 +08:00 committed by GitHub
parent c00b2a38d5
commit cc88ddf600
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 681 additions and 131 deletions

View File

@ -1,3 +1,3 @@
### Raster - HillShade
山体阴影
<code src="./rasterData/hillshade.tsx"></code>
<code src="./rasterData/hillshade.tsx"></code>

View File

@ -19,7 +19,7 @@ export default () => {
scene.on('loaded', () => {
const layer = new RasterLayer({})
.source(
'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',

View File

@ -19,8 +19,7 @@ export default () => {
zIndex: 1,
});
layerTile.source(
'//t3.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',
// 'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'//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',
@ -35,7 +34,7 @@ export default () => {
zIndex: 0,
});
layerTile2.source(
'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',

View File

@ -0,0 +1,205 @@
//@ts-ignore
import { Scene, RasterLayer } from '@antv/l7';
//@ts-ignore
import { Mapbox } from '@antv/l7-maps';
import React, { useEffect } from 'react';
export default () => {
useEffect(() => {
const scene = new Scene({
id: 'map',
map: new Mapbox({
center: [-119.5591, 37.715],
zoom: 9,
style: 'mapbox://styles/mapbox/cjaudgl840gn32rnrepcb9b9g',
token: 'pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2w3dHk3dnN4MDYzaDNycDkyMDl2bzh6NiJ9.YIrG9kwUpayLj01f6W23Gw'
}),
});
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 256;
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
scene.on('loaded', () => {
const layer = new RasterLayer();
layer
.source(
// 'https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token=pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2w3dHk3dnN4MDYzaDNycDkyMDl2bzh6NiJ9.YIrG9kwUpayLj01f6W23Gw',
'https://api.mapbox.com/raster/v1/mapbox.mapbox-terrain-dem-v1/{z}/{x}/{y}.webp?sku=101xrmKJip7uQ&access_token=pk.eyJ1IjoiMTg5Njk5NDg2MTkiLCJhIjoiY2w3dHk3dnN4MDYzaDNycDkyMDl2bzh6NiJ9.YIrG9kwUpayLj01f6W23Gw',
// 'https://b.tiles.mapbox.com/v3/aj.sf-dem/12/657/1589.png',
// https://b.tiles.mapbox.com/v3/aj.sf-dem/12/659/1589.png
{
parser: {
type: 'rasterTile',
dataType: 'arraybuffer',
tileSize: 256,
// extent: [-180, -85.051129, 179, 85.051129],
format: async (data: any) => {
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 shadeOptions = {
resolution: 256,
sunEl: 0,
sunAz: 131,
vert: 2
}
const elevationImage = ctx.getImageData(0, 0, 256, 256);
const width = elevationImage.width;
const height = elevationImage.height;
const elevationData = elevationImage.data;
const shadeData = new Uint8ClampedArray(elevationData.length);
const dp = shadeOptions.resolution * 2;
const maxX = width - 1;
const maxY = height - 1;
const pixel = [0, 0, 0, 0];
const twoPi = 2 * Math.PI;
const halfPi = Math.PI / 2;
const sunEl = (Math.PI * shadeOptions.sunEl) / 180;
const sunAz = (Math.PI * shadeOptions.sunAz) / 180;
const cosSunEl = Math.cos(sunEl);
const sinSunEl = Math.sin(sunEl);
let pixelX,
pixelY,
x0,
x1,
y0,
y1,
offset,
z0,
z1,
dzdx,
dzdy,
slope,
aspect,
cosIncidence,
scaled;
function calculateElevation(pixel) {
// The method used to extract elevations from the DEM.
// In this case the format used is
// red + green * 2 + blue * 3
//
// Other frequently used methods include the Mapbox format
// (red * 256 * 256 + green * 256 + blue) * 0.1 - 10000
// and the Terrarium format
// (red * 256 + green + blue / 256) - 32768
//
// return pixel[0] + pixel[1] * 2 + pixel[2] * 3;
return -10000 + (pixel[0] * 256 * 256 + pixel[1] * 2 * 256 + pixel[2]) * 0.1;
}
const arr2: number[] = [];
for (pixelY = 0; pixelY <= maxY; ++pixelY) {
y0 = pixelY === 0 ? 0 : pixelY - 1;
y1 = pixelY === maxY ? maxY : pixelY + 1;
for (pixelX = 0; pixelX <= maxX; ++pixelX) {
x0 = pixelX === 0 ? 0 : pixelX - 1;
x1 = pixelX === maxX ? maxX : pixelX + 1;
// determine elevation for (x0, pixelY)
offset = (pixelY * width + x0) * 4;
pixel[0] = elevationData[offset];
pixel[1] = elevationData[offset + 1];
pixel[2] = elevationData[offset + 2];
pixel[3] = elevationData[offset + 3];
z0 = shadeOptions.vert * calculateElevation(pixel);
// determine elevation for (x1, pixelY)
offset = (pixelY * width + x1) * 4;
pixel[0] = elevationData[offset];
pixel[1] = elevationData[offset + 1];
pixel[2] = elevationData[offset + 2];
pixel[3] = elevationData[offset + 3];
z1 = shadeOptions.vert * calculateElevation(pixel);
dzdx = (z1 - z0) / dp;
// determine elevation for (pixelX, y0)
offset = (y0 * width + pixelX) * 4;
pixel[0] = elevationData[offset];
pixel[1] = elevationData[offset + 1];
pixel[2] = elevationData[offset + 2];
pixel[3] = elevationData[offset + 3];
z0 = shadeOptions.vert * calculateElevation(pixel);
// determine elevation for (pixelX, y1)
offset = (y1 * width + pixelX) * 4;
pixel[0] = elevationData[offset];
pixel[1] = elevationData[offset + 1];
pixel[2] = elevationData[offset + 2];
pixel[3] = elevationData[offset + 3];
z1 = shadeOptions.vert * calculateElevation(pixel);
dzdy = (z1 - z0) / dp;
slope = Math.atan(Math.sqrt(dzdx * dzdx + dzdy * dzdy));
aspect = Math.atan2(dzdy, -dzdx);
if (aspect < 0) {
aspect = halfPi - aspect;
} else if (aspect > halfPi) {
aspect = twoPi - aspect + halfPi;
} else {
aspect = halfPi - aspect;
}
cosIncidence =
sinSunEl * Math.cos(slope) +
cosSunEl * Math.sin(slope) * Math.cos(sunAz - aspect);
offset = (pixelY * width + pixelX) * 4;
scaled = 255 * cosIncidence;
shadeData[offset + 1] = scaled;
shadeData[offset + 2] = scaled;
shadeData[offset + 3] = elevationData[offset + 3];
const r = shadeData[offset]
const g = shadeData[offset + 1]
const b = shadeData[offset + 2]
// (0.30*R)+(0.59*G)+(0.11*B)
arr2.push( 0.30 * r + 0.59 * g + 0.11 * b );
}
}
return {rasterData: arr2, width: width, height: height};
},
},
},
)
.style({
opacity: 0.5,
domain: [0, 255],
rampColors: {
colors: [
'#fff',
'#000',
],
positions: [0, 1.0],
},
});
scene.addLayer(layer)
});
}, []);
return (
<div
id="map"
style={{
height: '500px',
position: 'relative',
}}
/>
);
};

View File

@ -32,7 +32,7 @@ export default () => {
});
layer
.source(
'http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'http://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',

View File

@ -0,0 +1,150 @@
import { RasterLayer, Scene, Source } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';
import * as GeoTIFF from 'geotiff';
const colorList = [
'#419bdf', // Water
'#419bdf',
'#397d49', // Tree
'#397d49',
'#88b053', // Grass
'#88b053',
'#7a87c6', // vegetation
'#7a87c6',
'#e49635', // Crops
'#e49635',
'#dfc35a', // shrub
'#dfc35a',
'#c4281b', // Built Area
'#c4281b',
'#a59b8f', // Bare ground
'#a59b8f',
'#a8ebff', // Snow
'#a8ebff',
'#616161', // Clouds
'#616161'
];
const positions = [
0.0,
0.1,
0.1,
0.2,
0.2,
0.3,
0.3,
0.4,
0.4,
0.5,
0.5,
0.6,
0.6,
0.7,
0.7,
0.8,
0.8,
0.9,
0.9,
1.0
];
export default () => {
useEffect(() => {
const scene = new Scene({
id: 'map',
stencil: true,
map: new GaodeMap({
center: [ 116, 27 ],
zoom: 6,
style: 'dark'
})
});
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/fccd80c0-2611-49f9-9a9f-e2a4dd12226f.json'
)
.then(res => res.json())
.then(maskData => {
const layer = new RasterLayer({
mask: true,
maskfence: maskData
});
const urls = [
'https://ganos.oss-cn-hangzhou.aliyuncs.com/m2/l7/tiff_jx/{z}/{x}/{y}.tiff',
'https://ganos.oss-cn-hangzhou.aliyuncs.com/m2/l7/tiff_jx/{z}/{x}/{y}.tiff',
]
const tileSource = new Source(urls,
{
parser: {
type: 'rasterTile',
dataType: 'arraybuffer',
tileSize: 256,
maxZoom: 13.1,
format: async data => {
const tiff = await GeoTIFF.fromArrayBuffer(data[0]);
const image = await tiff.getImage();
const width = image.getWidth();
const height = image.getHeight();
const values = await image.readRasters();
const rasterData = values[0];
const tiff2 = await GeoTIFF.fromArrayBuffer(data[1]);
const image2 = await tiff2.getImage();
const values2 = await image2.readRasters();
const rasterData2 = values2[0];
const r = rasterData.map((d, i) => {
const d2 = rasterData2[i]
return d/2 + d2/3
})
return { rasterData: r, width, height };
}
}
});
layer.source(tileSource)
.style({
domain: [ 0.001, 11.001 ],
clampLow: false,
rampColors: {
colors: colorList,
positions
}
});
scene.addLayer(layer);
});
});
return () => {
scene.destroy();
};
}, []);
return (
<div
id="map"
style={{
height: '500px',
position: 'relative',
}}
/>
);
};

View File

@ -0,0 +1,4 @@
### Raster - RasterData - Multi
数据栅格 Multi
#### 加载 tiff
<code src="./rasterData/loadMultiTiff.tsx"></code>

View File

@ -15,7 +15,7 @@
"registry": "https://registry.npmjs.org"
}
},
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"npmClient": "yarn",
"useWorkspaces": true,
"publishConfig": {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-component",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,8 +25,8 @@
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"eventemitter3": "^4.0.0",
"inversify": "^5.0.1",
@ -35,7 +35,7 @@
"supercluster": "^7.0.0"
},
"devDependencies": {
"@antv/l7-test-utils": "2.9.26"
"@antv/l7-test-utils": "2.9.27-alpha.3"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",
"publishConfig": {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-core",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,7 +25,7 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.2.2",
"@antv/l7-utils": "2.9.26",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"@turf/helpers": "^6.1.4",
"ajv": "^6.10.2",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -26,13 +26,13 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-component": "2.9.26",
"@antv/l7-core": "2.9.26",
"@antv/l7-layers": "2.9.26",
"@antv/l7-maps": "2.9.26",
"@antv/l7-scene": "2.9.26",
"@antv/l7-source": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-component": "2.9.27-alpha.3",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-layers": "2.9.27-alpha.3",
"@antv/l7-maps": "2.9.27-alpha.3",
"@antv/l7-scene": "2.9.27-alpha.3",
"@antv/l7-source": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,2 +1,2 @@
const version = '2.9.26';
const version = '2.9.27-alpha.3';
export { version };

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-layers",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "L7's collection of built-in layers",
"main": "lib/index.js",
"module": "es/index.js",
@ -27,12 +27,13 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.2.2",
"@antv/l7-core": "2.9.26",
"@antv/l7-maps": "2.9.26",
"@antv/l7-source": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-maps": "2.9.27-alpha.3",
"@antv/l7-source": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"@mapbox/martini": "^0.2.0",
"@turf/clone": "^6.5.0",
"@turf/helpers": "^6.1.4",
"@turf/meta": "^6.0.2",
"@turf/polygon-to-line": "^6.5.0",

View File

@ -10,9 +10,47 @@ uniform bool u_clampLow: true;
uniform bool u_clampHigh: true;
varying vec2 v_texCoord;
// float getBlurIndusty() {
// vec2 u_ViewportSize = vec2(1024);
// float vW = 2.0/u_ViewportSize.x;
// float vH = 2.0/u_ViewportSize.y;
// vec2 vUv = v_texCoord;
// float i11 = texture2D( u_texture, vec2( vUv.x - 1.0 * vW, vUv.y + 1.0 * vH) ).r;
// float i12 = texture2D( u_texture, vec2( vUv.x - 0.0 * vW, vUv.y + 1.0 * vH) ).r;
// float i13 = texture2D( u_texture, vec2( vUv.x + 1.0 * vW, vUv.y + 1.0 * vH) ).r;
// float i21 = texture2D( u_texture, vec2( vUv.x - 1.0 * vW, vUv.y) ).r;
// float i22 = texture2D( u_texture, vec2( vUv.x , vUv.y) ).r;
// float i23 = texture2D( u_texture, vec2( vUv.x + 1.0 * vW, vUv.y) ).r;
// float i31 = texture2D( u_texture, vec2( vUv.x - 1.0 * vW, vUv.y-1.0*vH) ).r;
// float i32 = texture2D( u_texture, vec2( vUv.x - 0.0 * vW, vUv.y-1.0*vH) ).r;
// float i33 = texture2D( u_texture, vec2( vUv.x + 1.0 * vW, vUv.y-1.0*vH) ).r;
// return(
// i11 +
// i12 +
// i13 +
// i21 +
// i21 +
// i22 +
// i23 +
// i31 +
// i32 +
// i33
// )/9.0;
// }
void main() {
float value = texture2D(u_texture,vec2(v_texCoord.x,v_texCoord.y)).r;
// float value = getBlurIndusty();
if (value == u_noDataValue)
gl_FragColor = vec4(0.0, 0, 0, 0.0);
else if ((!u_clampLow && value < u_domain[0]) || (!u_clampHigh && value > u_domain[1]))

View File

@ -1,4 +1,5 @@
import { IParserCfg } from '@antv/l7-core';
import { rasterDataTypes } from '@antv/l7-source';
import VectorLineTile from './line';
import VectorPointLayer from './point';
import VectorPolygonTile from './polygon';
@ -24,7 +25,7 @@ export function getTileFactory(tileType: TileType, parser: IParserCfg) {
case 'TileDebugLayer':
return TestTile;
case 'RasterLayer':
if (parser.dataType === 'arraybuffer') {
if(rasterDataTypes.includes(parser.dataType)) {
return RasterDataFactory;
} else {
return RasterTileFactory;

View File

@ -46,7 +46,7 @@ export class TMSBaseMapTileLayer extends BaseTileLayer {
}
}
private emitTileVisibleEvent(tile: Tile, callback: () => void) {
private dispatchTileVisibleChange(tile: Tile, callback: () => void) {
if (tile.isVisible) {
callback();
} else {
@ -57,7 +57,7 @@ export class TMSBaseMapTileLayer extends BaseTileLayer {
}
private updateTileVisible(tile: Tile, layers: ILayer[]) {
this.emitTileVisibleEvent(tile, () => {
this.dispatchTileVisibleChange(tile, () => {
updateLayersConfig(layers, 'visible', tile.isVisible);
this.layerService.reRender();
});

View File

@ -48,7 +48,7 @@ export class TMSTileLayer extends BaseTileLayer {
}
}
private emitTileVisibleEvent(tile: Tile, callback: () => void) {
private dispatchTileVisibleChange(tile: Tile, callback: () => void) {
if (tile.isVisible) {
callback();
} else {
@ -59,7 +59,7 @@ export class TMSTileLayer extends BaseTileLayer {
}
private updateTileVisible(tile: Tile, layers: ILayer[]) {
this.emitTileVisibleEvent(tile, () => {
this.dispatchTileVisibleChange(tile, () => {
updateLayersConfig(layers, 'visible', tile.isVisible);
this.layerService.reRender();
});

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-map",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "l7 map",
"keywords": [],
"author": "thinkinggis <lzx199065@gmail.com>",
@ -39,7 +39,7 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-utils": "2.9.26",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/unitbezier": "^0.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-maps",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -27,9 +27,9 @@
"license": "ISC",
"dependencies": {
"@amap/amap-jsapi-loader": "^0.0.3",
"@antv/l7-core": "2.9.26",
"@antv/l7-map": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-map": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"@types/amap-js-api": "^1.4.6",
"@types/mapbox-gl": "^1.11.2",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-mini",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,11 +25,11 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-core": "2.9.26",
"@antv/l7-layers": "2.9.26",
"@antv/l7-maps": "2.9.26",
"@antv/l7-scene": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-layers": "2.9.27-alpha.3",
"@antv/l7-maps": "2.9.27-alpha.3",
"@antv/l7-scene": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-renderer",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,12 +25,12 @@
"author": "xiaoiver",
"license": "ISC",
"devDependencies": {
"@antv/l7-test-utils": "2.9.26",
"@antv/l7-test-utils": "2.9.27-alpha.3",
"gl": "^5.0.3"
},
"dependencies": {
"@antv/l7-core": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"l7regl": "^0.0.20",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-scene",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -23,19 +23,19 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-component": "2.9.26",
"@antv/l7-core": "2.9.26",
"@antv/l7-layers": "2.9.26",
"@antv/l7-maps": "2.9.26",
"@antv/l7-renderer": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-component": "2.9.27-alpha.3",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-layers": "2.9.27-alpha.3",
"@antv/l7-maps": "2.9.27-alpha.3",
"@antv/l7-renderer": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"mapbox-gl": "^1.2.1",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {
"@antv/l7-test-utils": "2.9.26"
"@antv/l7-test-utils": "2.9.27-alpha.3"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",
"publishConfig": {

View File

@ -10,21 +10,17 @@ const scene = new Scene({
});
scene.on('loaded', () => {
const layer = new RasterLayer({
zIndex: 1
});
const layer = new RasterLayer();
layer.source(
'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
'https://webrd0{1-3}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',
tileSize: 256,
minZoom: 2,
maxZoom: 18,
zoomOffset: 0
}
}
);
scene.addLayer(layer);
});

View File

@ -15,12 +15,7 @@ scene.on('loaded', () => {
zIndex: 1
});
baseLayer.source(
[
'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'https://webst03.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'https://webst04.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'
],
'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',
@ -38,7 +33,7 @@ scene.on('loaded', () => {
zIndex: 2
});
annotionLayer.source(
'https://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
'https://webst0{1-3}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',

View File

@ -13,7 +13,6 @@ const scene = new Scene({
scene.on('loaded', () => {
fetch(
// 'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
'https://gw.alipayobjects.com/os/bmw-prod/ecd1aaac-44c0-4232-b66c-c0ced76d5c7d.json'
)
.then(res => res.json())
@ -25,7 +24,7 @@ scene.on('loaded', () => {
maskfence: data
});
baseLayer.source(
'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
'https://webst0{1-3}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',
@ -44,15 +43,11 @@ scene.on('loaded', () => {
zIndex: 2
});
annotionLayer.source(
'https://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
'https://webst0{1-3}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
{
parser: {
type: 'rasterTile',
tileSize: 256,
// minZoom: 6,
// maxZoom: 15,
zoomOffset: 0
// extent: [-180, -85.051129, 179, 85.051129],
}
}
);

View File

@ -15,10 +15,7 @@ scene.on('loaded', () => {
zIndex: 1
});
baseLayer.source(
[
'https://t1.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=6557fd8a19b09d6e91ae6abf9d13ccbd',
'https://t2.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=6557fd8a19b09d6e91ae6abf9d13ccbd'
],
'https://t{1-2}.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=6557fd8a19b09d6e91ae6abf9d13ccbd',
{
parser: {
type: 'rasterTile',
@ -38,9 +35,6 @@ scene.on('loaded', () => {
parser: {
type: 'rasterTile',
tileSize: 256,
// minZoom: 6,
// maxZoom: 15,
zoomOffset: 0
}
}
);

View File

@ -1,7 +1,7 @@
{
"private": true,
"name": "@antv/l7-site",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "L7 sites deployed on gh-pages",
"keywords": [
"antv",
@ -37,7 +37,7 @@
},
"dependencies": {
"@antv/gatsby-theme-antv": "1.1.15",
"@antv/l7": "2.9.26",
"@antv/l7": "2.9.27-alpha.3",
"@antv/util": "^2.0.9",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.8",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-source",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,8 +25,8 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.2.2",
"@antv/l7-core": "2.9.26",
"@antv/l7-utils": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-utils": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"@mapbox/geojson-rewind": "^0.5.2",
"@mapbox/vector-tile": "^1.3.1",

View File

@ -6,7 +6,7 @@ import json from './parser/json';
import mapboxVectorTile from './parser/mvt';
import geojsonVTTile from './parser/geojsonvt';
import raster from './parser/raster';
import rasterTile from './parser/raster-tile';
import rasterTile, { rasterDataTypes } from './parser/raster-tile';
import testTile from './parser/testTile';
import Source from './source';
import { cluster } from './transform/cluster';
@ -32,6 +32,9 @@ registerTransform('map', map);
registerTransform('grid', aggregatorToGrid);
registerTransform('hexagon', pointToHexbin);
export {
rasterDataTypes,
}
export {
getTransform,
registerTransform,

View File

@ -153,7 +153,7 @@ export type MapboxVectorTile = {
};
const getVectorTile = async (
url: string | string[],
url: string,
tileParams: TileLoadParams,
tile: Tile,
// coord: string,
@ -216,9 +216,12 @@ export default function mapboxVectorTile(
data: string | string[],
cfg?: ITileParserCFG,
): IParserData {
// TODO: 后续考虑支持多服务
const url = Array.isArray(data) ? data[0] : data;
// const coord = cfg?.coord || 'lnglat'; // lnglat - offset
const getTileData = (tileParams: TileLoadParams, tile: Tile) =>
getVectorTile(data, tileParams, tile);
getVectorTile(url, tileParams, tile);
// getVectorTile(data, tileParams, tile, coord);
const tilesetOptions = {
@ -228,7 +231,7 @@ export default function mapboxVectorTile(
};
return {
data,
data: url,
dataArray: [],
tilesetOptions,
isTile: true,

View File

@ -9,21 +9,31 @@ const DEFAULT_CONFIG: Partial<TilesetManagerOptions> = {
zoomOffset: 0,
};
export const rasterDataTypes = [RasterTileType.ARRAYBUFFER];
/**
*
* @param data
* @param cfg
* @returns
*/
export default function rasterTile(
data: string | string[],
cfg?: ITileParserCFG,
): IParserData {
const tileDataType: RasterTileType = cfg?.dataType || RasterTileType.IMAGE;
const getTileData = (tileParams: TileLoadParams, tile: Tile) => {
if (tileDataType === RasterTileType.IMAGE) {
return getTileImage(data, tileParams, tile);
} else {
return getTileBuffer(
data,
tileParams,
tile,
cfg?.format || defaultFormat,
);
switch (tileDataType) {
case RasterTileType.IMAGE:
return getTileImage(data, tileParams, tile);
case RasterTileType.ARRAYBUFFER:
return getTileBuffer(
data,
tileParams,
tile,
cfg?.format || defaultFormat,
);
default:
return getTileImage(data, tileParams, tile);
}
};

View File

@ -1,6 +1,11 @@
import {
getImage,
getTiffImage,
makeXMLHttpRequestPromise,
ResponseCallback,
IRasterParser,
arrayBufferToTiffImage,
RequestParameters,
getArrayBuffer,
getURLFromTemplate,
Tile,
TileLoadParams,
@ -8,6 +13,7 @@ import {
/**
* raster data tifflercdem
*
* @param url
* @param tileParams
* @param tile
@ -18,13 +24,16 @@ export const getTileBuffer = async (
url: string | string[],
tileParams: TileLoadParams,
tile: Tile,
rasterParser: any,
rasterParser: (imageData: ArrayBuffer) => Promise<IRasterParser>,
): Promise<HTMLImageElement | ImageBitmap> => {
const imgUrl = getURLFromTemplate(url, tileParams);
const requestParameters = {
url: getTileUrl(url, tileParams),
};
return new Promise((resolve, reject) => {
const xhr = getTiffImage(
{ url: imgUrl },
getTiffImage(
tile,
requestParameters,
(err, img) => {
if (err) {
reject(err);
@ -34,16 +43,92 @@ export const getTileBuffer = async (
},
rasterParser,
);
tile.xhrCancel = () => xhr.abort();
});
};
const getTiffImage = async (
tile: Tile,
requestParameters: RequestParameters,
callback: ResponseCallback<HTMLImageElement | ImageBitmap | null>,
rasterParser: any,
) => {
if (Array.isArray(requestParameters.url)) {
const imageDataList = [];
const xhrList: any[] = [];
const errList = [];
const urls = requestParameters.url;
for (let i = 0; i < urls.length; i++) {
const params = {
...requestParameters,
url: urls[i],
};
const { err, data, xhr } = await makeXMLHttpRequestPromise({
...params,
type: 'arrayBuffer',
});
if (err) {
errList.push(err);
}
xhrList.push(xhr);
imageDataList.push(data);
}
setTileXHRCancelFunc(tile, xhrList);
if (errList.length > 0) {
callback(errList as Error[], null);
return;
}
const { rasterData, width, height } = await rasterParser(imageDataList);
const defaultMIN = 0;
const defaultMAX = 8000;
callback(null, {
// @ts-ignore
data: rasterData,
width,
height,
min: defaultMIN,
max: defaultMAX,
});
} else {
const xhr = getArrayBuffer(requestParameters, (err, imgData) => {
if (err) {
callback(err);
} else if (imgData) {
arrayBufferToTiffImage(imgData, callback, rasterParser);
}
});
setTileXHRCancelFunc(tile, [xhr]);
}
};
function setTileXHRCancelFunc(tile: Tile, xhrList: any[]) {
tile.xhrCancel = () => {
xhrList.map((xhr) => {
xhr.abort();
});
};
}
function getTileUrl(url: string | string[], tileParams: TileLoadParams) {
if (Array.isArray(url)) {
return url.map((src) => getURLFromTemplate(src, tileParams));
} else {
return getURLFromTemplate(url, tileParams);
}
}
export const getTileImage = async (
url: string | string[],
tileParams: TileLoadParams,
tile: Tile,
): Promise<HTMLImageElement | ImageBitmap> => {
const imgUrl = getURLFromTemplate(url, tileParams);
// TODO: 后续考虑支持加载多服务
const imgUrl = getURLFromTemplate(
Array.isArray(url) ? url[0] : url,
tileParams,
);
return new Promise((resolve, reject) => {
const xhr = getImage({ url: imgUrl }, (err, img) => {

View File

@ -1,7 +1,7 @@
{
"private": true,
"name": "@antv/l7-test-utils",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "Now Im the model of a modern major general / The venerated Virginian veteran whose men are all / Lining up, to put me up on a pedestal / Writin letters to relatives / Embellishin my elegance and eloquence / But the elephant is in the room / The truth is in ya face when ya hear the British cannons go / BOOM",
"keywords": [],
"author": "lzxue <lzx199065@gmail.com>",
@ -39,9 +39,9 @@
"url": "https://github.com/antvis/L7/issues"
},
"devDependencies": {
"@antv/l7-map": "2.9.26",
"@antv/l7-maps": "2.9.26",
"@antv/l7-scene": "2.9.26",
"@antv/l7-map": "2.9.27-alpha.3",
"@antv/l7-maps": "2.9.27-alpha.3",
"@antv/l7-scene": "2.9.27-alpha.3",
"gl": "^5.0.3",
"l7regl": "^0.0.20"
},

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-three",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "three for L7 ",
"keywords": [
"3D",
@ -44,9 +44,9 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-core": "2.9.26",
"@antv/l7-layers": "2.9.26",
"@antv/l7-scene": "2.9.26",
"@antv/l7-core": "2.9.27-alpha.3",
"@antv/l7-layers": "2.9.27-alpha.3",
"@antv/l7-scene": "2.9.27-alpha.3",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"reflect-metadata": "^0.1.13",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-utils",
"version": "2.9.26",
"version": "2.9.27-alpha.3",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",

View File

@ -2,7 +2,7 @@ import { getReferrer } from './env';
import { $window, $XMLHttpRequest } from './mini-adapter';
export type RequestParameters = {
url: string;
url: string | string[];
headers?: any;
method?: 'GET' | 'POST' | 'PUT';
body?: string;
@ -13,10 +13,11 @@ export type RequestParameters = {
};
export type ResponseCallback<T> = (
error?: Error | null,
error?: Error | Error[] | null,
data?: T | null,
cacheControl?: string | null,
expires?: string | null,
xhr?: any,
) => void;
export class AJAXError extends Error {
@ -53,7 +54,8 @@ function makeFetchRequest(
requestParameters: RequestParameters,
callback: ResponseCallback<any>,
) {
const request = new Request(requestParameters.url, {
const url = Array.isArray(requestParameters.url) ? requestParameters.url[0] : requestParameters.url;
const request = new Request(url, {
method: requestParameters.method || 'GET',
body: requestParameters.body,
credentials: requestParameters.credentials,
@ -94,7 +96,7 @@ function makeFetchRequest(
new AJAXError(
response.status,
response.statusText,
requestParameters.url,
url,
body,
),
),
@ -110,8 +112,9 @@ function makeXMLHttpRequest(
callback: ResponseCallback<any>,
) {
const xhr = new $XMLHttpRequest();
const url = Array.isArray(requestParameters.url) ? requestParameters.url[0] : requestParameters.url;
xhr.open(requestParameters.method || 'GET', requestParameters.url, true);
xhr.open(requestParameters.method || 'GET', url, true);
if (requestParameters.type === 'arrayBuffer') {
xhr.responseType = 'arraybuffer';
}
@ -147,13 +150,14 @@ function makeXMLHttpRequest(
data,
xhr.getResponseHeader('Cache-Control'),
xhr.getResponseHeader('Expires'),
xhr,
);
} else {
const body = new Blob([xhr.response], {
type: xhr.getResponseHeader('Content-Type'),
});
callback(
new AJAXError(xhr.status, xhr.statusText, requestParameters.url, body),
new AJAXError(xhr.status, xhr.statusText, url, body),
);
}
};
@ -162,6 +166,37 @@ function makeXMLHttpRequest(
return xhr;
}
export interface IXhrRequestResult {
err?: Error | Error[] | null,
data?: any | null,
cacheControl?: string | null,
expires?: string | null,
xhr?: any;
}
export function makeXMLHttpRequestPromise(
requestParameters: RequestParameters,
): Promise<IXhrRequestResult> {
return new Promise((resolve, reject) => {
makeXMLHttpRequest(requestParameters, (error, data, cacheControl, expires, xhr) => {
if(error) {
reject({
err: error,
data: null,
xhr
});
} else {
resolve({
err: null,
data ,
cacheControl,
expires,
xhr,
});
}
})
})
}
function makeRequest(
requestParameters: RequestParameters,
callback: ResponseCallback<any>,
@ -271,7 +306,7 @@ export const getImage = (
});
};
const arrayBufferToTiffImage = async (
export const arrayBufferToTiffImage = async (
data: ArrayBuffer,
callback: (err?: Error | null, image?: any) => void,
rasterParser: any,
@ -305,3 +340,9 @@ export const getTiffImage = (
}
});
};
export interface IRasterParser {
rasterData: HTMLImageElement | ImageBitmap | null | undefined;
width: number;
height: number;
}

View File

@ -5,11 +5,42 @@ export function isURLTemplate(s: string) {
return /(?=.*{z})(?=.*{x})(?=.*({y}|{-y}))/.test(s);
}
/**
* https://github.com/openlayers/openlayers/blob/main/src/ol/tileurlfunction.js
* @param {string} url URL.
* @return {Array<string>} Array of urls.
*/
export function expandUrl(url: string) {
const urls = [];
let match = /\{([a-z])-([a-z])\}/.exec(url);
if (match) {
// char range
const startCharCode = match[1].charCodeAt(0);
const stopCharCode = match[2].charCodeAt(0);
let charCode;
for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {
urls.push(url.replace(match[0], String.fromCharCode(charCode)));
}
return urls;
}
match = /\{(\d+)-(\d+)\}/.exec(url);
if (match) {
// number range
const stop = parseInt(match[2], 10);
for (let i = parseInt(match[1], 10); i <= stop; i++) {
urls.push(url.replace(match[0], i.toString()));
}
return urls;
}
urls.push(url);
return urls;
}
/*
*
*/
export function getURLFromTemplate(
template: string | string[],
template: string,
properties: { x: number; y: number; z: number },
) {
if (!template || !template.length) {
@ -18,14 +49,13 @@ export function getURLFromTemplate(
const { x, y, z } = properties;
if (Array.isArray(template)) {
const index = Math.abs(x + y) % template.length;
template = template[index];
}
const urls = expandUrl(template);
const index = Math.abs(x + y) % urls.length;
const url = urls[index];
return template
return url
.replace(/\{x\}/g, x.toString())
.replace(/\{y\}/g, y.toString())
.replace(/\{z\}/g, z.toString())
.replace(/\{-y\}/g, (Math.pow(2, z) - y - 1).toString());
}
}