mirror of https://gitee.com/antv-l7/antv-l7
commit
1fb2e9d3a2
|
@ -42,11 +42,11 @@ scene.addLayer(layer);
|
||||||
|
|
||||||
### minZoom
|
### minZoom
|
||||||
|
|
||||||
图层显示最小缩放等级,(0-18) {number} Mapbox (0-24) 高德 (3-18)
|
图层显示最小缩放等级,(0-18) {number} Mapbox (0-24) 高德 (2-19)
|
||||||
|
|
||||||
### maxZoom
|
### maxZoom
|
||||||
|
|
||||||
图层显示最大缩放等级 (0-18) {number} Mapbox (0-24) 高德 (3-18)
|
图层显示最大缩放等级 (0-18) {number} Mapbox (0-24) 高德 (2-19)
|
||||||
|
|
||||||
### autoFit
|
### autoFit
|
||||||
|
|
||||||
|
@ -590,3 +590,17 @@ layer.on('inited', (option) => {});
|
||||||
|
|
||||||
- target 当前 layer
|
- target 当前 layer
|
||||||
- type 事件类型
|
- type 事件类型
|
||||||
|
|
||||||
|
## 图层框选
|
||||||
|
|
||||||
|
### boxSelect
|
||||||
|
|
||||||
|
参数 option
|
||||||
|
- box [x1: number, y1: number, x2: number, y2: number] 相较于
|
||||||
|
- cb (...args: any[]) => void 传入的回调方法,返回框选内部的 feature
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
layer.boxSelect(box, cb);
|
||||||
|
// (x1, y1), (x2, y2) 框选的方框左上角和右下角相对于地图左上角的像素坐标
|
||||||
|
// cb 是传入的回调函数,回调函数返回的参数是选中的 feature 对象数组,对象的字段和用户传入的数据相关
|
||||||
|
```
|
||||||
|
|
|
@ -9,7 +9,7 @@ order: 1
|
||||||
|
|
||||||
### 数据
|
### 数据
|
||||||
|
|
||||||
绘制弧线只需提供起止点坐标即可
|
绘制弧线只需提供起止点坐标即可(起止点调换位置,弧线的形状会对称相反,飞线动画的方向也会相反)
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
source(data, {
|
source(data, {
|
||||||
|
|
|
@ -1,71 +1,5 @@
|
||||||
---
|
---
|
||||||
title: LineLayer
|
title: LineLayer
|
||||||
order: 2
|
order: 0
|
||||||
---
|
---
|
||||||
`markdown:docs/common/style.md`
|
`markdown:docs/api/layer/line_layer/linelayer.zh.md`
|
||||||
## 线图层
|
|
||||||
|
|
||||||
### shape
|
|
||||||
|
|
||||||
线图层支持 4 种 shape
|
|
||||||
|
|
||||||
- line 绘制路径图,
|
|
||||||
- arc 绘制弧线 通过贝塞尔曲线算法技术弧线
|
|
||||||
- greatcircle 大圆航线,地图两个点的最近距离不是两个点连线,而是大圆航线
|
|
||||||
- arc3d 3d 弧线地图 3D 视角
|
|
||||||
|
|
||||||
⚠️ 弧线只需要设置起止点坐标即可
|
|
||||||
|
|
||||||
```
|
|
||||||
new LineLayer()
|
|
||||||
.source(data, {
|
|
||||||
parser: {
|
|
||||||
type: 'csv',
|
|
||||||
x: 'lng1',
|
|
||||||
y: 'lat1',
|
|
||||||
x1: 'lng2',
|
|
||||||
y1: 'lat2',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
如果 geojson 数据绘制弧线图 coordinates 第一对坐标为起点,第二对为终点
|
|
||||||
|
|
||||||
```
|
|
||||||
{
|
|
||||||
"type": "FeatureCollection",
|
|
||||||
"features": [
|
|
||||||
{
|
|
||||||
"type": "Feature",
|
|
||||||
"properties": {},
|
|
||||||
"geometry": {
|
|
||||||
"type": "LineString",
|
|
||||||
"coordinates": [
|
|
||||||
[
|
|
||||||
106.5234375,
|
|
||||||
57.51582286553883
|
|
||||||
],
|
|
||||||
[
|
|
||||||
136.40625,
|
|
||||||
61.77312286453146
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### size
|
|
||||||
|
|
||||||
线图层 可以设置高度
|
|
||||||
|
|
||||||
- size 类型为 number 则表示 line 的宽度
|
|
||||||
- size 类型为 [number , number] 分别表示宽度和高度
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
lineLayer.size(1); // 线的宽度为 1
|
|
||||||
lineLayer.size([1, 2]); // 宽度为1,高度2
|
|
||||||
```
|
|
||||||
`markdown:docs/common/layer/base.md`
|
|
||||||
|
|
|
@ -1,5 +1,71 @@
|
||||||
---
|
---
|
||||||
title: LineLayer
|
title: LineLayer
|
||||||
order: 0
|
order: 2
|
||||||
---
|
---
|
||||||
`markdown:docs/api/layer/line_layer/linelayer.en.md`
|
`markdown:docs/common/style.md`
|
||||||
|
## 线图层
|
||||||
|
|
||||||
|
### shape
|
||||||
|
|
||||||
|
线图层支持 4 种 shape
|
||||||
|
|
||||||
|
- line 绘制路径图,
|
||||||
|
- arc 绘制弧线 通过贝塞尔曲线算法技术弧线
|
||||||
|
- greatcircle 大圆航线,地图两个点的最近距离不是两个点连线,而是大圆航线
|
||||||
|
- arc3d 3d 弧线地图 3D 视角
|
||||||
|
|
||||||
|
⚠️ 弧线只需要设置起止点坐标即可
|
||||||
|
|
||||||
|
```
|
||||||
|
new LineLayer()
|
||||||
|
.source(data, {
|
||||||
|
parser: {
|
||||||
|
type: 'csv',
|
||||||
|
x: 'lng1',
|
||||||
|
y: 'lat1',
|
||||||
|
x1: 'lng2',
|
||||||
|
y1: 'lat2',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
如果 geojson 数据绘制弧线图 coordinates 第一对坐标为起点,第二对为终点
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"properties": {},
|
||||||
|
"geometry": {
|
||||||
|
"type": "LineString",
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
106.5234375,
|
||||||
|
57.51582286553883
|
||||||
|
],
|
||||||
|
[
|
||||||
|
136.40625,
|
||||||
|
61.77312286453146
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### size
|
||||||
|
|
||||||
|
线图层 可以设置高度
|
||||||
|
|
||||||
|
- size 类型为 number 则表示 line 的宽度
|
||||||
|
- size 类型为 [number , number] 分别表示宽度和高度
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
lineLayer.size(1); // 线的宽度为 1
|
||||||
|
lineLayer.size([1, 2]); // 宽度为1,高度2
|
||||||
|
```
|
||||||
|
`markdown:docs/common/layer/base.md`
|
||||||
|
|
|
@ -34,7 +34,7 @@ shape 支持
|
||||||
|
|
||||||
**图片标注**
|
**图片标注**
|
||||||
|
|
||||||
通过 `Scene.addImage()` 可以添加图片资源,
|
通过 `Scene.addImage()` 可以添加图片资源
|
||||||
|
|
||||||
### 代码示例
|
### 代码示例
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ L7 在内部解决了不同地图底图之间差异,同时 L7 层面统一管
|
||||||
### 引入 Map
|
### 引入 Map
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import { GaodeMap } from '@antv/l7-maps';
|
import { GaodeMap } from '@antv/l7-maps'; // 默认引入高德2.0
|
||||||
|
import { GaodeMapV1 } from '@antv/l7-maps'; // 默认引入高德1.x 版本
|
||||||
|
|
||||||
import { Mapbox } from '@antv/l7-maps';
|
import { Mapbox } from '@antv/l7-maps';
|
||||||
```
|
```
|
||||||
|
@ -70,7 +71,7 @@ const scene = new Scene({
|
||||||
|
|
||||||
⚠️ 传入地图实例需要自行引入相关地图的 API
|
⚠️ 传入地图实例需要自行引入相关地图的 API
|
||||||
|
|
||||||
⚠️ viewMode 设置为 3D 模式
|
⚠️ viewMode 设置为 3D 模式(GaodeMap2.0 支持 2D 模式,可以不设置)
|
||||||
|
|
||||||
#### 传入高德地图实例
|
#### 传入高德地图实例
|
||||||
|
|
||||||
|
@ -92,11 +93,13 @@ const scene = new Scene({
|
||||||
[示例地址](/zh/examples/tutorial/map#amapInstance)
|
[示例地址](/zh/examples/tutorial/map#amapInstance)
|
||||||
[代码地址](https://github.com/antvis/L7/blob/master/examples/tutorial/map/demo/amapInstance.js)
|
[代码地址](https://github.com/antvis/L7/blob/master/examples/tutorial/map/demo/amapInstance.js)
|
||||||
|
|
||||||
|
[示例地址( 2D )](/zh/examples/tutorial/map#amapInstance2d)
|
||||||
|
[代码地址](https://github.com/antvis/L7/blob/master/examples/tutorial/map/demo/amapInstance.js)
|
||||||
|
|
||||||
#### 传入 Mapbox 地图实例
|
#### 传入 Mapbox 地图实例
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
mapboxgl.accessToken =
|
mapboxgl.accessToken = 'xxxx - token';
|
||||||
'pk.eyJ1IjoibHp4dWUiLCJhIjoiYnhfTURyRSJ9.Ugm314vAKPHBzcPmY1p4KQ';
|
|
||||||
const map = new mapboxgl.Map({
|
const map = new mapboxgl.Map({
|
||||||
container: 'map', // container id
|
container: 'map', // container id
|
||||||
style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
|
style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
|
||||||
|
|
|
@ -113,7 +113,7 @@ L7 Logo 的显示位置 默认左下角
|
||||||
|
|
||||||
<description> _number_ </description>
|
<description> _number_ </description>
|
||||||
|
|
||||||
地图初始显示级别 {number} Mapbox (0-24) 高德 (3-18)
|
地图初始显示级别 {number} Mapbox (0-24) 高德 (2-19)
|
||||||
|
|
||||||
### center 地图中心
|
### center 地图中心
|
||||||
|
|
||||||
|
@ -146,11 +146,11 @@ L7 Logo 的显示位置 默认左下角
|
||||||
|
|
||||||
### minZoom 最小缩放等级
|
### minZoom 最小缩放等级
|
||||||
|
|
||||||
地图最小缩放等级 {number} default 0 Mapbox 0-24) 高德 (3-18)
|
地图最小缩放等级 {number} default 0 Mapbox 0-24) 高德 (2-19)
|
||||||
|
|
||||||
### maxZoom 最大缩放等级
|
### maxZoom 最大缩放等级
|
||||||
|
|
||||||
地图最大缩放等级 {number} default 22 Mapbox(0-24) 高德 (3-18)
|
地图最大缩放等级 {number} default 22 Mapbox(0-24) 高德 (2-19)
|
||||||
|
|
||||||
### rotateEnable 是否允许旋转
|
### rotateEnable 是否允许旋转
|
||||||
|
|
||||||
|
@ -166,7 +166,167 @@ L7 Logo 的显示位置 默认左下角
|
||||||
|
|
||||||
高德地图适用,是否关闭偏移坐标系
|
高德地图适用,是否关闭偏移坐标系
|
||||||
|
|
||||||
## 方法
|
## Layer 方法
|
||||||
|
|
||||||
|
### addLayer(layer) 增加图层对象
|
||||||
|
|
||||||
|
增加图层对象
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `layer` {ILayer} 图层对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.addLayer(layer);
|
||||||
|
```
|
||||||
|
|
||||||
|
### getLayer(id) 获取对应的图层对象
|
||||||
|
|
||||||
|
获取对应的图层对象
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `id` {string}
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.getLayer('layerID');
|
||||||
|
```
|
||||||
|
|
||||||
|
### getLayers() 获取所有的地图图层
|
||||||
|
|
||||||
|
获取所有的地图图层
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.getLayers();
|
||||||
|
```
|
||||||
|
|
||||||
|
### getLayerByName(name) 根据图层名称获取图层
|
||||||
|
|
||||||
|
根据图层名称获取图层
|
||||||
|
|
||||||
|
参数
|
||||||
|
|
||||||
|
- `name` {string} layer 初始化可配置图层 name
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.getLayerByName(name); // return Layer 图层对象
|
||||||
|
```
|
||||||
|
|
||||||
|
### removeLayer 移除 layer 图层
|
||||||
|
|
||||||
|
移除 layer 图层
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeLayer(layer);
|
||||||
|
```
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `layer` {Layer}
|
||||||
|
|
||||||
|
### removeAllLayer() 移除所有的图层对象
|
||||||
|
|
||||||
|
移除所有的图层对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeAllLayer();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 控制组件方法
|
||||||
|
|
||||||
|
### addControl(ctl) 添加组件控件
|
||||||
|
|
||||||
|
添加组件控件
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `crl` { IControl } 用户创建的控件对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.addControl(ctl);
|
||||||
|
```
|
||||||
|
|
||||||
|
### removeControl(ctr) 移除用户添加的组件控件
|
||||||
|
|
||||||
|
移除用户添加的组件控件
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `ctl` { IControl } 用户创建的控件对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeControl(ctl);
|
||||||
|
```
|
||||||
|
|
||||||
|
### getControlByName(name) 根据控件的名称来获取控件
|
||||||
|
|
||||||
|
根据控件的名称来获取控件
|
||||||
|
|
||||||
|
- `name` { string }
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const zoomControl = new Zoom({
|
||||||
|
// zoom 控件
|
||||||
|
name: 'z1', // 用户传入的控件名称(也可以不传入,该控件默认名称为 zoom)
|
||||||
|
position: 'topright',
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.getControlByName('z1');
|
||||||
|
```
|
||||||
|
|
||||||
|
## 标记方法
|
||||||
|
|
||||||
|
### addMarker(maker) 添加标记
|
||||||
|
|
||||||
|
往场景中添加标记对象
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `maker` { IMarker } Marker 实例
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const marker = new Marker({
|
||||||
|
element: el,
|
||||||
|
}).setLnglat({ lng: nodes[i].x * 1, lat: nodes[i].y });
|
||||||
|
scene.addMarker(marker);
|
||||||
|
```
|
||||||
|
|
||||||
|
### addMarkerLayer(layer) 添加 Marker 统一管理图层
|
||||||
|
|
||||||
|
当用户需要添加许多个 Marker 实例时,为了方便管理可以使用 markerLayer 对象统一管理
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `layer` { IMarkerLayer } 标记图层对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const markerLayer = new MarkerLayer();
|
||||||
|
scene.addMarkerLayer(markerLayer);
|
||||||
|
```
|
||||||
|
|
||||||
|
[示例地址](/zh/examples/point/marker#markerlayer)
|
||||||
|
|
||||||
|
### removeMarkerLayer(layer) 移除标签图层
|
||||||
|
|
||||||
|
移除标签图层
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `layer` { IMarkerLayer } 标记图层对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeMarkerLayer(markerLayer);
|
||||||
|
```
|
||||||
|
|
||||||
|
### removeAllMakers() 移除场景中所有的标签对象
|
||||||
|
|
||||||
|
移除场景中所有的标签对象
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeAllMakers();
|
||||||
|
```
|
||||||
|
|
||||||
|
## 地图方法
|
||||||
|
|
||||||
### getZoom 获取缩放等级
|
### getZoom 获取缩放等级
|
||||||
|
|
||||||
|
@ -178,30 +338,6 @@ scene.getZoom();
|
||||||
|
|
||||||
return {float} 当前缩放等级
|
return {float} 当前缩放等级
|
||||||
|
|
||||||
### getLayers() 获取所有图层
|
|
||||||
|
|
||||||
获取所有的地图图层
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
scene.getLayers();
|
|
||||||
```
|
|
||||||
|
|
||||||
### getLayerByName(name) 根据名称获取图层
|
|
||||||
|
|
||||||
根据图层名称获取图层
|
|
||||||
|
|
||||||
参数
|
|
||||||
|
|
||||||
- name {string}
|
|
||||||
|
|
||||||
layer 初始化可配置图层 name
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
scene.getLayerByName(name);
|
|
||||||
```
|
|
||||||
|
|
||||||
return Layer 图层对象
|
|
||||||
|
|
||||||
### getCenter() 获取地图中心
|
### getCenter() 获取地图中心
|
||||||
|
|
||||||
获取地图中心点
|
获取地图中心点
|
||||||
|
@ -385,18 +521,6 @@ scene.fitBounds([
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
### removeLayer 移除图层
|
|
||||||
|
|
||||||
移除 layer
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
scene.removeLayer(layer);
|
|
||||||
```
|
|
||||||
|
|
||||||
参数
|
|
||||||
|
|
||||||
- `layer` {Layer}
|
|
||||||
|
|
||||||
### exportMap 导出地图图片
|
### exportMap 导出地图图片
|
||||||
|
|
||||||
导出地图,目前仅支持导出可视化层,不支持底图导出
|
导出地图,目前仅支持导出可视化层,不支持底图导出
|
||||||
|
@ -411,10 +535,133 @@ scene.exportMap('png');
|
||||||
|
|
||||||
scene 销毁方法,离开页面,或者不需要使用地图可以调用
|
scene 销毁方法,离开页面,或者不需要使用地图可以调用
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
scene.destroy();
|
scene.destroy();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## iconfont 映射支持
|
||||||
|
|
||||||
|
### addIconFont(name, fontUnicode) 增加对数据中 unicode 的映射支持
|
||||||
|
|
||||||
|
支持对用户传入的数据进行 unicode 的映射,在内部维护一组名称和对应 key 的键值对
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `name` {string}
|
||||||
|
- `fontUnicode` {string}
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.addIconFont('icon1', '');
|
||||||
|
scene.addIconFont('icon2', '');
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
const pointIconFontLayer = new PointLayer({})
|
||||||
|
.source(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
j: 140,
|
||||||
|
w: 34,
|
||||||
|
m: 'icon1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
j: 140,
|
||||||
|
w: 36,
|
||||||
|
m: 'icon2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'j',
|
||||||
|
y: 'w',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.shape('m', 'text')
|
||||||
|
.size(12)
|
||||||
|
.color('w', ['#f00', '#f00', '#0f0'])
|
||||||
|
.style({
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true,
|
||||||
|
textAllowOverlap: true,
|
||||||
|
});
|
||||||
|
scene.addLayer(pointIconFontLayer);
|
||||||
|
```
|
||||||
|
|
||||||
|
### addIconFonts(options) 同时传入多组 name - unicode 的键值对
|
||||||
|
|
||||||
|
同时传入多组 name - unicode 的键值对
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `options` { Array<[name, unicode]> }
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.addIconFonts([
|
||||||
|
['icon1', ''],
|
||||||
|
['icon2', ''],
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 全局资源
|
||||||
|
|
||||||
|
### addImage(id, img) 全局中添加的图片资源
|
||||||
|
|
||||||
|
在 L7 的图层对象可以使用在 scene 全局中添加的图片资源
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `id` {string}
|
||||||
|
- `img` {HTMLImageElement | File | string}
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.addImage(
|
||||||
|
'02',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg',
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
[示例地址](/zh/examples/gallery/animate#animate_path_texture)
|
||||||
|
|
||||||
|
### hasImage(id) 判断全局图片资源
|
||||||
|
|
||||||
|
判断是否已经在全局添加过相应的图片资源
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `id` {string}
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.hasImage('imageID');
|
||||||
|
```
|
||||||
|
|
||||||
|
### removeImage(id) 全局删除图片资源
|
||||||
|
|
||||||
|
从全局删除对应的图片资源
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `id` {string}
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
scene.removeImage('imageID');
|
||||||
|
```
|
||||||
|
|
||||||
|
### addFontFace(fontFamily, fontPath) 添加字体文件
|
||||||
|
|
||||||
|
添加字体文件
|
||||||
|
|
||||||
|
参数 :
|
||||||
|
|
||||||
|
- `fontFamily` {string} 用户为自己定义的字体名称
|
||||||
|
- `fontPath` {string} 导入的文件地址
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
let fontFamily = 'iconfont';
|
||||||
|
let fontPath =
|
||||||
|
'//at.alicdn.com/t/font_2534097_iiet9d3nekn.woff2?t=1620444089776';
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
```
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
### on
|
### on
|
||||||
|
|
|
@ -7,7 +7,7 @@ order: 0
|
||||||
|
|
||||||
## 概述
|
## 概述
|
||||||
|
|
||||||
source 地理数据处理模块,主要包含数据解析(parser),和数据处理(transform);
|
source 地理数据处理模块,主要包含数据解析(parser),和数据处理(transform)
|
||||||
|
|
||||||
- data
|
- data
|
||||||
- option
|
- option
|
||||||
|
@ -18,7 +18,7 @@ source 地理数据处理模块,主要包含数据解析(parser),和数据
|
||||||
|
|
||||||
### parser
|
### parser
|
||||||
|
|
||||||
不同数据类型处理成统一数据格式。矢量数据包括 GeoJON, CSV,Json 等不同数据格式,栅格数据,包括 Raster,Image 数据。将来还会支持瓦片格式数据。
|
不同数据类型处理成统一数据格式。矢量数据包括 GeoJON, CSV,Json 等不同数据格式,栅格数据,包括 Raster,Image 数据。将来还会支持瓦片格式数据。
|
||||||
|
|
||||||
空间数据分矢量数据和栅格数据两大类
|
空间数据分矢量数据和栅格数据两大类
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
### minZoom
|
### minZoom
|
||||||
<description> _number_ **可选** _default:_ `0`</description>
|
<description> _number_ **可选** _default:_ `0`</description>
|
||||||
|
|
||||||
图层显示最小缩放等级,(0-18) {number} Mapbox (0-24) 高德 (3-18)
|
图层显示最小缩放等级,(0-18) {number} Mapbox (0-24) 高德 (2-19)
|
||||||
|
|
||||||
### maxZoom
|
### maxZoom
|
||||||
<description> _number_ **可选** _default:_ `22`</description>
|
<description> _number_ **可选** _default:_ `22`</description>
|
||||||
图层显示最大缩放等级 (0-18) {number} Mapbox (0-24) 高德 (3-18)
|
图层显示最大缩放等级 (0-18) {number} Mapbox (0-24) 高德 (2-19)
|
||||||
|
|
||||||
### autoFit
|
### autoFit
|
||||||
<description> _bool_ **可选** _default:_ `false`</description>
|
<description> _bool_ **可选** _default:_ `false`</description>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Scene } from '@antv/l7';
|
import { Scene } from '@antv/l7';
|
||||||
import { DrillDownLayer } from '@antv/l7-district';
|
import { DrillDownLayer } from '@antv/l7-district';
|
||||||
import { Mapbox } from '@antv/l7-maps';
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
const colors = [ '#B8E1FF', '#7DAAFF', '#3D76DD', '#0047A5', '#001D70' ];
|
const colors = [ '#B8E1FF', '#7DAAFF', '#3D76DD', '#0047A5', '#001D70' ];
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
map: new Mapbox({
|
map: new GaodeMap({
|
||||||
center: [ 116.2825, 39.9 ],
|
center: [ 116.2825, 39.9 ],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
style: 'blank',
|
style: 'blank',
|
||||||
|
|
|
@ -9,6 +9,16 @@
|
||||||
"title": "中国地图钻取",
|
"title": "中国地图钻取",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_8e1672/afts/img/A*xjjARqU70xoAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_8e1672/afts/img/A*xjjARqU70xoAAAAAAAAAAABkARQnAQ"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"filename": "drill_down_view.js",
|
||||||
|
"title": "中国地图钻取",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*KphnSq_0C6sAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "drill_down_province.js",
|
||||||
|
"title": "省级地图钻取",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*fVHISrzrz44AAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "drill_down_bubble.js",
|
"filename": "drill_down_bubble.js",
|
||||||
"title": "中国地图钻取气泡图",
|
"title": "中国地图钻取气泡图",
|
||||||
|
|
|
@ -203,7 +203,7 @@ class Province extends React.Component {
|
||||||
});
|
});
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
map: new Mapbox({
|
map: new GaodeMap({
|
||||||
center: [116.2825, 39.9],
|
center: [116.2825, 39.9],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
style: 'blank',
|
style: 'blank',
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import { Scene, LineLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [ 120.19382669582967, 30.258134 ],
|
||||||
|
pitch: 20,
|
||||||
|
zoom: 18,
|
||||||
|
style: 'light'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
scene.addImage(
|
||||||
|
'02',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg'
|
||||||
|
);
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const layer = new LineLayer()
|
||||||
|
.source(data)
|
||||||
|
.size(4)
|
||||||
|
.shape('line')
|
||||||
|
.texture('02')
|
||||||
|
.color('#25d8b7')
|
||||||
|
.animate({
|
||||||
|
interval: 1, // 间隔
|
||||||
|
duration: 1, // 持续时间,延时
|
||||||
|
trailLength: 2 // 流线长度
|
||||||
|
})
|
||||||
|
.style({
|
||||||
|
lineTexture: true, // 开启线的贴图功能
|
||||||
|
iconStep: 100 // 设置贴图纹理的间距
|
||||||
|
});
|
||||||
|
scene.addLayer(layer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,7 +4,7 @@ import { GaodeMap } from '@antv/l7-maps';
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
map: new GaodeMap({
|
map: new GaodeMap({
|
||||||
style: 'amap://styles/a49ef8d081db7b85adb2e90ba7941f1e?isPublic=true',
|
style: 'dark',
|
||||||
center: [ 120.173104, 30.244072 ],
|
center: [ 120.173104, 30.244072 ],
|
||||||
pitch: 70.41138037735848,
|
pitch: 70.41138037735848,
|
||||||
zoom: 17.18,
|
zoom: 17.18,
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
"en": "Gallery"
|
"en": "Gallery"
|
||||||
},
|
},
|
||||||
"demos": [
|
"demos": [
|
||||||
|
{
|
||||||
|
"filename": "animate_path_texture.js",
|
||||||
|
"title": "路径贴图",
|
||||||
|
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*0UrUTakTFQsAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "animate_path.js",
|
"filename": "animate_path.js",
|
||||||
"title": "路径动画",
|
"title": "路径动画",
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
"en": "line"
|
"en": "line"
|
||||||
},
|
},
|
||||||
"demos": [
|
"demos": [
|
||||||
|
{
|
||||||
|
"filename": "wind.js",
|
||||||
|
"title": "风场弧线",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*LpcBTKiazZcAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "arcCircle.js",
|
"filename": "arcCircle.js",
|
||||||
"title": "大圆弧线",
|
"title": "大圆弧线",
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Scene, LineLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
pitch: 0,
|
||||||
|
style: 'light',
|
||||||
|
center: [ 60, 40.7128 ],
|
||||||
|
zoom: 2
|
||||||
|
})
|
||||||
|
});
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/bmw-prod/7455fead-1dc0-458d-b91a-fb4cf99e701e.txt'
|
||||||
|
)
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(data => {
|
||||||
|
const layer = new LineLayer({ blend: 'normal' })
|
||||||
|
.source(data,
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'csv',
|
||||||
|
x: 'lng1',
|
||||||
|
y: 'lat1',
|
||||||
|
x1: 'lng2',
|
||||||
|
y1: 'lat2'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.size(1)
|
||||||
|
.shape('arc')
|
||||||
|
.color('#6495ED')
|
||||||
|
.animate({
|
||||||
|
duration: 4,
|
||||||
|
interval: 0.2,
|
||||||
|
trailLength: 0.6
|
||||||
|
});
|
||||||
|
// .forward(false)
|
||||||
|
scene.addLayer(layer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -16,14 +16,19 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "road_light.js",
|
"filename": "road_light.js",
|
||||||
"title": "路径",
|
"title": "路径light",
|
||||||
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*LuXiTZAq_84AAAAAAAAAAABkARQnAQ"
|
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*LuXiTZAq_84AAAAAAAAAAABkARQnAQ"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "road_dark.js",
|
"filename": "road_dark.js",
|
||||||
"title": "路径",
|
"title": "路径dark",
|
||||||
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*DDjQRLEnwpoAAAAAAAAAAABkARQnAQ"
|
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*DDjQRLEnwpoAAAAAAAAAAABkARQnAQ"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"filename": "road_red.js",
|
||||||
|
"title": "路径2d",
|
||||||
|
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*1cF2RYwkcq8AAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"filename": "road_dark_dash.js",
|
"filename": "road_dark_dash.js",
|
||||||
"title": "路径虚线",
|
"title": "路径虚线",
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import {
|
||||||
|
Scene,
|
||||||
|
LineLayer
|
||||||
|
} from '@antv/l7';
|
||||||
|
import {
|
||||||
|
GaodeMap
|
||||||
|
} from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [ 116.3956, 39.9392 ],
|
||||||
|
pitch: 0,
|
||||||
|
zoom: 10,
|
||||||
|
rotation: 0,
|
||||||
|
style: 'amap://styles/light',
|
||||||
|
viewMode: '2D'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/basement_prod/0d2f0113-f48b-4db9-8adc-a3937243d5a3.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const layer = new LineLayer({})
|
||||||
|
.source(data)
|
||||||
|
.size(1.5)
|
||||||
|
.shape('line')
|
||||||
|
.color('标准名称', [ '#5B8FF9', '#5CCEA1', '#5D7092' ]);
|
||||||
|
scene.addLayer(layer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -18,6 +18,11 @@
|
||||||
"filename": "weather.js",
|
"filename": "weather.js",
|
||||||
"title": "天气",
|
"title": "天气",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*-nk1RZJeGooAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*-nk1RZJeGooAAAAAAAAAAABkARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "road.js",
|
||||||
|
"title": "路线图",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*2HLeQ4AjxacAAAAAAAAAAAAAARQnAQ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
import { Scene, LineLayer, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [ 120.115, 30.221 ],
|
||||||
|
pitch: 40,
|
||||||
|
zoom: 16,
|
||||||
|
viewMode: '3D'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/bmw-prod/91d27a97-869a-459b-a617-498dcc9c3e7f.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
scene.addImage(
|
||||||
|
'road',
|
||||||
|
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*haGlTpW2BQgAAAAAAAAAAAAAARQnAQ'
|
||||||
|
);
|
||||||
|
|
||||||
|
const layer = new LineLayer()
|
||||||
|
.source(data)
|
||||||
|
.size(8)
|
||||||
|
.shape('line')
|
||||||
|
.texture('road')
|
||||||
|
.color('rgb(20, 180, 90)')
|
||||||
|
.animate({
|
||||||
|
interval: 1, // 间隔
|
||||||
|
duration: 1, // 持续时间,延时
|
||||||
|
trailLength: 2 // 流线长度
|
||||||
|
})
|
||||||
|
.style({
|
||||||
|
lineTexture: true, // 开启线的贴图功能
|
||||||
|
iconStep: 200 // 设置贴图纹理的间距
|
||||||
|
});
|
||||||
|
scene.addLayer(layer);
|
||||||
|
|
||||||
|
scene.addImage(
|
||||||
|
'start',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/ebb0af57-4a8a-46e0-a296-2d51f9fa8007.svg'
|
||||||
|
);
|
||||||
|
scene.addImage(
|
||||||
|
'visitor',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/64db255d-b636-4929-b072-068e75178b23.svg'
|
||||||
|
);
|
||||||
|
scene.addImage(
|
||||||
|
'museum',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/0630591d-64db-4057-a04d-d65f43aebf0f.svg'
|
||||||
|
);
|
||||||
|
scene.addImage(
|
||||||
|
'supermarket',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/ab42799d-dea6-4d37-bd62-3ee3e06bf6c0.svg'
|
||||||
|
);
|
||||||
|
scene.addImage(
|
||||||
|
'tower',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/6d27cf89-638c-432b-a8c4-cac289ee98a8.svg'
|
||||||
|
);
|
||||||
|
scene.addImage(
|
||||||
|
'end',
|
||||||
|
'https://gw.alipayobjects.com/zos/bmw-prod/59717737-5652-479f-9e6b-e7d2c5441446.svg'
|
||||||
|
);
|
||||||
|
const imageLayer = new PointLayer()
|
||||||
|
.source([{
|
||||||
|
lng: 120.11025885601617,
|
||||||
|
lat: 30.22006389085372,
|
||||||
|
icon: 'start'
|
||||||
|
}, {
|
||||||
|
lng: 120.11123578376913,
|
||||||
|
lat: 30.220443561196277,
|
||||||
|
icon: 'visitor'
|
||||||
|
}, {
|
||||||
|
lng: 120.11408457779198,
|
||||||
|
lat: 30.22019805564678,
|
||||||
|
icon: 'museum'
|
||||||
|
}, {
|
||||||
|
lng: 120.11683172384723,
|
||||||
|
lat: 30.21875509667716,
|
||||||
|
icon: 'supermarket'
|
||||||
|
}, {
|
||||||
|
lng: 120.11945546294194,
|
||||||
|
lat: 30.218724022876376,
|
||||||
|
icon: 'tower'
|
||||||
|
}, {
|
||||||
|
lng: 120.1184189041221,
|
||||||
|
lat: 30.21783201718256,
|
||||||
|
icon: 'end'
|
||||||
|
}
|
||||||
|
], {
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('icon', [ 'start', 'visitor', 'museum', 'supermarket', 'tower', 'end' ])
|
||||||
|
.size(35)
|
||||||
|
.style({
|
||||||
|
offsets: [ 0, 20 ]
|
||||||
|
});
|
||||||
|
scene.addLayer(imageLayer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { Scene, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
style: 'light',
|
||||||
|
center: [ 112, 23.69 ],
|
||||||
|
zoom: 2.5
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/basement_prod/9078fd36-ce8d-4ee2-91bc-605db8315fdf.csv'
|
||||||
|
)
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(data => {
|
||||||
|
const pointLayer = new PointLayer({})
|
||||||
|
.source(data, {
|
||||||
|
parser: {
|
||||||
|
type: 'csv',
|
||||||
|
x: 'Longitude',
|
||||||
|
y: 'Latitude'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('circle')
|
||||||
|
.active(true)
|
||||||
|
.animate(true)
|
||||||
|
.size(40)
|
||||||
|
.color('#ffa842')
|
||||||
|
.style({
|
||||||
|
opacity: 1,
|
||||||
|
offsets: [ 40, 40 ]
|
||||||
|
});
|
||||||
|
const pointLayer2 = new PointLayer({})
|
||||||
|
.source(data, {
|
||||||
|
parser: {
|
||||||
|
type: 'csv',
|
||||||
|
x: 'Longitude',
|
||||||
|
y: 'Latitude'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('circle')
|
||||||
|
.active(true)
|
||||||
|
.animate(true)
|
||||||
|
.size(50)
|
||||||
|
.color('#f00')
|
||||||
|
.style({
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.addLayer(pointLayer);
|
||||||
|
scene.addLayer(pointLayer2);
|
||||||
|
});
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { Scene, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
style: 'light',
|
||||||
|
center: [ 120.19382669582967, 30.258134 ],
|
||||||
|
zoom: 10
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const radius = 0.1;
|
||||||
|
|
||||||
|
function pointOnCircle(angle) {
|
||||||
|
return {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {},
|
||||||
|
geometry: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: [
|
||||||
|
120.19382669582967 + Math.cos(angle) * radius,
|
||||||
|
30.258134 + Math.sin(angle) * radius
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const layer = new PointLayer({})
|
||||||
|
.source(pointOnCircle(0))
|
||||||
|
.shape('circle')
|
||||||
|
.size(15) // default 1
|
||||||
|
.active(false)
|
||||||
|
.color('#2F54EB')
|
||||||
|
.style({
|
||||||
|
stroke: '#fff',
|
||||||
|
strokeWidth: 2,
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
scene.addLayer(layer);
|
||||||
|
layer.setData(pointOnCircle(1000));
|
||||||
|
|
||||||
|
function animateMarker(timestamp) {
|
||||||
|
layer.setData(pointOnCircle(timestamp / 1000));
|
||||||
|
scene.render();
|
||||||
|
requestAnimationFrame(animateMarker);
|
||||||
|
}
|
||||||
|
animateMarker(0);
|
|
@ -8,8 +8,16 @@
|
||||||
"filename": "scatter.js",
|
"filename": "scatter.js",
|
||||||
"title": "散点图",
|
"title": "散点图",
|
||||||
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*LnlmQ7sFWigAAAAAAAAAAABkARQnAQ"
|
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*LnlmQ7sFWigAAAAAAAAAAABkARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "dynamicScatter.js",
|
||||||
|
"title": "动态散点",
|
||||||
|
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*iourTIHnDk0AAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "animatePoint.js",
|
||||||
|
"title": "水波散点",
|
||||||
|
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*BsEnTrJ5JRcAAAAAAAAAAAAAARQnAQ"
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Scene, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [ 110, 30 ],
|
||||||
|
pitch: 0,
|
||||||
|
// style: 'light',
|
||||||
|
style: 'amap://styles/453e2f8e11603fc8f7548fe18959e9e9',
|
||||||
|
zoom: 5
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const fontFamily = 'iconfont';
|
||||||
|
const fontPath = '//at.alicdn.com/t/font_2534097_fcae9o2mxbv.woff2?t=1622200439140';
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
scene.addIconFont('icon1', '');
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/bmw-prod/70408903-80db-4278-a318-461604acb2df.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const pointLayer = new PointLayer({})
|
||||||
|
.source(data.list, {
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'j',
|
||||||
|
y: 'w'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('icon', 'text')
|
||||||
|
.size(20)
|
||||||
|
.color('w', [ '#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99' ])
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 40, 0 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||||
|
padding: [ 0, 0 ], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||||
|
stroke: '#ffffff', // 描边颜色
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true,
|
||||||
|
textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(pointLayer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,268 @@
|
||||||
|
import { Scene, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [ 120.5, 30.2 ],
|
||||||
|
pitch: 0,
|
||||||
|
style: 'amap://styles/453e2f8e11603fc8f7548fe18959e9e9',
|
||||||
|
zoom: 8.5,
|
||||||
|
zooms: [ 8, 10 ],
|
||||||
|
viewMode: '2D'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const dataColor = {
|
||||||
|
bigRainBC: '#285A8C',
|
||||||
|
middleRainBC: '#326EA0',
|
||||||
|
smallRainBC: '#4678AA',
|
||||||
|
sunBC: '#00BFFF',
|
||||||
|
cloudBC: '#1E90FF'
|
||||||
|
};
|
||||||
|
const originData = [
|
||||||
|
{
|
||||||
|
lng: 121.7,
|
||||||
|
lat: 30.6,
|
||||||
|
iconType: 'hugeRain',
|
||||||
|
iconColor: '#4678D2',
|
||||||
|
backgoundColor: dataColor.bigRainBC,
|
||||||
|
temperature: '20℃',
|
||||||
|
weather: '大雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 119.2,
|
||||||
|
lat: 30.0,
|
||||||
|
iconType: 'smallRain',
|
||||||
|
iconColor: '#6EA0FF',
|
||||||
|
backgoundColor: dataColor.smallRainBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '小雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 119.67,
|
||||||
|
lat: 30.2,
|
||||||
|
iconType: 'sun',
|
||||||
|
iconColor: '#FFA500',
|
||||||
|
backgoundColor: dataColor.sunBC,
|
||||||
|
temperature: '28℃',
|
||||||
|
weather: '晴朗'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 119.63,
|
||||||
|
lat: 30.6,
|
||||||
|
iconType: 'sun',
|
||||||
|
iconColor: '#FFA500',
|
||||||
|
backgoundColor: dataColor.sunBC,
|
||||||
|
temperature: '28℃',
|
||||||
|
weather: '晴朗'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120,
|
||||||
|
lat: 30,
|
||||||
|
iconType: 'sun',
|
||||||
|
iconColor: '#FFA500',
|
||||||
|
backgoundColor: dataColor.sunBC,
|
||||||
|
temperature: '28℃',
|
||||||
|
weather: '晴朗'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120.2,
|
||||||
|
lat: 30.5,
|
||||||
|
iconType: 'sun',
|
||||||
|
iconColor: '#FFA500',
|
||||||
|
backgoundColor: dataColor.sunBC,
|
||||||
|
temperature: '28℃',
|
||||||
|
weather: '晴朗'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121.5,
|
||||||
|
lat: 31.4,
|
||||||
|
iconType: 'cloud',
|
||||||
|
iconColor: '#F0F8FF',
|
||||||
|
backgoundColor: dataColor.cloudBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '多云'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120,
|
||||||
|
lat: 31,
|
||||||
|
iconType: 'cloud',
|
||||||
|
iconColor: '#F0F8FF',
|
||||||
|
backgoundColor: dataColor.cloudBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '多云'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120.6,
|
||||||
|
lat: 30.8,
|
||||||
|
iconType: 'cloud',
|
||||||
|
iconColor: '#F0F8FF',
|
||||||
|
backgoundColor: dataColor.cloudBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '多云'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120.5,
|
||||||
|
lat: 31.3,
|
||||||
|
iconType: 'cloud',
|
||||||
|
iconColor: '#F0F8FF',
|
||||||
|
backgoundColor: dataColor.cloudBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '多云'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121.3,
|
||||||
|
lat: 30.2,
|
||||||
|
iconType: 'smallRain',
|
||||||
|
iconColor: '#6EA0FF',
|
||||||
|
backgoundColor: dataColor.smallRainBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '小雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121,
|
||||||
|
lat: 30.5,
|
||||||
|
iconType: 'smallRain',
|
||||||
|
iconColor: '#6EA0FF',
|
||||||
|
backgoundColor: dataColor.smallRainBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '小雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120.6,
|
||||||
|
lat: 30,
|
||||||
|
iconType: 'middleRain',
|
||||||
|
iconColor: '#6495ED',
|
||||||
|
backgoundColor: dataColor.middleRainBC,
|
||||||
|
temperature: '24℃',
|
||||||
|
weather: '中雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 120.2,
|
||||||
|
lat: 29.7,
|
||||||
|
iconType: 'smallRain',
|
||||||
|
iconColor: '#6EA0FF',
|
||||||
|
backgoundColor: dataColor.smallRainBC,
|
||||||
|
temperature: '22℃',
|
||||||
|
weather: '小雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121.7,
|
||||||
|
lat: 29.8,
|
||||||
|
iconType: 'middleRain',
|
||||||
|
iconColor: '#6495ED',
|
||||||
|
backgoundColor: dataColor.middleRainBC,
|
||||||
|
temperature: '24℃',
|
||||||
|
weather: '中雨'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121.5,
|
||||||
|
lat: 30,
|
||||||
|
iconType: 'hugeRain',
|
||||||
|
iconColor: '#4678D2',
|
||||||
|
backgoundColor: dataColor.bigRainBC,
|
||||||
|
temperature: '20℃',
|
||||||
|
weather: '大雨'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const fontFamily = 'iconfont';
|
||||||
|
const fontPath = '//at.alicdn.com/t/font_2534097_ao9soua2obv.woff2?t=1622021146076';
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
scene.addIconFonts([
|
||||||
|
[ 'smallRain', '' ],
|
||||||
|
[ 'middleRain', '' ],
|
||||||
|
[ 'hugeRain', '' ],
|
||||||
|
[ 'sun', '' ],
|
||||||
|
[ 'cloud', '' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
|
||||||
|
const layer = new PointLayer()
|
||||||
|
.source(originData, {
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('circle')
|
||||||
|
.color('backgoundColor')
|
||||||
|
.size(42);
|
||||||
|
scene.addLayer(layer);
|
||||||
|
|
||||||
|
|
||||||
|
const pointIconFontLayer = new PointLayer({})
|
||||||
|
.source(originData, {
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.shape('iconType', 'text')
|
||||||
|
.size(30)
|
||||||
|
.color('iconColor')
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 38, 10 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true,
|
||||||
|
textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(pointIconFontLayer);
|
||||||
|
|
||||||
|
const textLayer = new PointLayer({})
|
||||||
|
.source(originData,
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.shape('temperature', 'text')
|
||||||
|
.size(10)
|
||||||
|
.color('#ffffff')
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 5, -55 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||||
|
spacing: 2, // 字符间距
|
||||||
|
padding: [ 1, 1 ], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||||
|
stroke: '#ffffff', // 描边颜色
|
||||||
|
strokeWidth: 0.3, // 描边宽度
|
||||||
|
strokeOpacity: 1.0,
|
||||||
|
fontFamily: 'Times New Roman',
|
||||||
|
textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(textLayer);
|
||||||
|
|
||||||
|
const textLayer2 = new PointLayer({})
|
||||||
|
.source(originData,
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.shape('weather', 'text')
|
||||||
|
.size(14)
|
||||||
|
.color('#ffffff')
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 5, -15 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||||
|
spacing: 2, // 字符间距
|
||||||
|
padding: [ 1, 1 ], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||||
|
stroke: '#ffffff', // 描边颜色
|
||||||
|
strokeWidth: 0.3, // 描边宽度
|
||||||
|
strokeOpacity: 1.0,
|
||||||
|
fontFamily: 'Times New Roman',
|
||||||
|
textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(textLayer2);
|
||||||
|
|
||||||
|
});
|
|
@ -13,7 +13,26 @@
|
||||||
"filename": "polygon_text.js",
|
"filename": "polygon_text.js",
|
||||||
"title": "面数据标注",
|
"title": "面数据标注",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*rCFqRp3iQosAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*rCFqRp3iQosAAAAAAAAAAABkARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "iconfont.js",
|
||||||
|
"title": "图标标注",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*8PfqQ6-lQ0EAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "iconfonts.js",
|
||||||
|
"title": "天气图标标注",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*JAhxTaabap4AAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "temperture.js",
|
||||||
|
"title": "气温图标标注",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*36umQaf_hVEAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "updown.js",
|
||||||
|
"title": "走势图标标注",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*P5plS5ZsYZkAAAAAAAAAAAAAARQnAQ"
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { GaodeMap } from '@antv/l7-maps';
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
map: new GaodeMap({
|
map: new GaodeMap({
|
||||||
center: [ 120.19382669582967, 30.258134 ],
|
center: [ 110, 36 ],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
style: 'light',
|
style: 'light',
|
||||||
zoom: 3
|
zoom: 3
|
||||||
|
@ -40,4 +40,5 @@ scene.on('loaded', () => {
|
||||||
|
|
||||||
scene.addLayer(pointLayer);
|
scene.addLayer(pointLayer);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { Scene, PointLayer, PolygonLayer, LineLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
style: 'dark',
|
||||||
|
pitch: 40,
|
||||||
|
center: [ 118.8, 32.056 ],
|
||||||
|
zoom: 12.5
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const fontFamily = 'iconfont';
|
||||||
|
const fontPath =
|
||||||
|
'//at.alicdn.com/t/font_2534097_x6rsov3i1g.woff2?t=1622107341225';
|
||||||
|
scene.addIconFont('icon', '');
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
|
||||||
|
const colors = [
|
||||||
|
'#87CEFA',
|
||||||
|
'#00BFFF',
|
||||||
|
|
||||||
|
'#7FFFAA',
|
||||||
|
'#00FF7F',
|
||||||
|
'#32CD32',
|
||||||
|
|
||||||
|
'#F0E68C',
|
||||||
|
'#FFD700',
|
||||||
|
|
||||||
|
'#FF7F50',
|
||||||
|
'#FF6347',
|
||||||
|
'#FF0000'
|
||||||
|
];
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch('https://gw.alipayobjects.com/os/bmw-prod/94763191-2816-4c1a-8d0d-8bcf4181056a.json')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
|
||||||
|
const filllayer = new PolygonLayer({
|
||||||
|
name: 'fill',
|
||||||
|
zIndex: 3
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('fill')
|
||||||
|
.color('count', [ '#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f' ])
|
||||||
|
.style({
|
||||||
|
opacity: 0.6
|
||||||
|
});
|
||||||
|
scene.addLayer(filllayer);
|
||||||
|
|
||||||
|
const linelayer = new LineLayer({
|
||||||
|
zIndex: 5,
|
||||||
|
name: 'line2'
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('line')
|
||||||
|
.size(1)
|
||||||
|
.color('#fff')
|
||||||
|
.style({
|
||||||
|
opacity: 0.3
|
||||||
|
});
|
||||||
|
scene.addLayer(linelayer);
|
||||||
|
|
||||||
|
const pointLayer = new PointLayer({
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('icon', 'text')
|
||||||
|
.size(30)
|
||||||
|
.color('count', t => {
|
||||||
|
const c = Number(t.replace('℃', ''));
|
||||||
|
return colors[Math.floor(((c - 18) / 16) * 10)];
|
||||||
|
})
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 30, 5 ],
|
||||||
|
padding: [ 2, 2 ],
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true
|
||||||
|
// textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(pointLayer);
|
||||||
|
|
||||||
|
const tempertureLayer = new PointLayer({
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('count', 'text')
|
||||||
|
.size(12)
|
||||||
|
.color('count', t => {
|
||||||
|
const c = Number(t.replace('℃', ''));
|
||||||
|
return colors[Math.floor(((c - 18) / 16) * 10)];
|
||||||
|
})
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 35, 30 ],
|
||||||
|
padding: [ 1, 1 ]
|
||||||
|
});
|
||||||
|
scene.addLayer(tempertureLayer);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { Scene, PointLayer, PolygonLayer, LineLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
style: 'dark',
|
||||||
|
pitch: 40,
|
||||||
|
center: [ 118.8, 32.056 ],
|
||||||
|
zoom: 12.5
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const fontFamily = 'iconfont';
|
||||||
|
const fontPath =
|
||||||
|
'//at.alicdn.com/t/font_2534097_bl34aphh10n.woff2?t=1622180820063';
|
||||||
|
scene.addIconFont('up', '');
|
||||||
|
scene.addIconFont('down', '');
|
||||||
|
scene.addFontFace(fontFamily, fontPath);
|
||||||
|
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/bmw-prod/41802695-0f7e-4a81-ab16-539c4e39df0d.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const filllayer = new PolygonLayer({
|
||||||
|
name: 'fill',
|
||||||
|
zIndex: 3
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('fill')
|
||||||
|
.color('count', [ '#f2f0f7', '#dadaeb', '#bcbddc', '#9e9ac8', '#756bb1', '#54278f' ])
|
||||||
|
.style({
|
||||||
|
opacity: 0.6
|
||||||
|
});
|
||||||
|
scene.addLayer(filllayer);
|
||||||
|
|
||||||
|
const linelayer = new LineLayer({
|
||||||
|
zIndex: 5,
|
||||||
|
name: 'line2'
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('line')
|
||||||
|
.size(1)
|
||||||
|
.color('#fff')
|
||||||
|
.style({
|
||||||
|
opacity: 0.3
|
||||||
|
});
|
||||||
|
scene.addLayer(linelayer);
|
||||||
|
|
||||||
|
const pointLayer = new PointLayer({
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('icon', 'text')
|
||||||
|
.size(15)
|
||||||
|
.color('count', n => (n > 0 ? '#0f0' : '#f00'))
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 30, 5 ],
|
||||||
|
padding: [ 2, 2 ],
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true
|
||||||
|
// textAllowOverlap: true
|
||||||
|
});
|
||||||
|
scene.addLayer(pointLayer);
|
||||||
|
|
||||||
|
const textLayer = new PointLayer({
|
||||||
|
zIndex: 10
|
||||||
|
})
|
||||||
|
.source(data)
|
||||||
|
.shape('count', 'text')
|
||||||
|
.size(12)
|
||||||
|
.color('count', n => (n > 0 ? '#0f0' : '#f00'))
|
||||||
|
.style({
|
||||||
|
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||||
|
textOffset: [ 40, 10 ],
|
||||||
|
padding: [ 1, 1 ]
|
||||||
|
});
|
||||||
|
scene.addLayer(textLayer);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
title: COVID-19 地图
|
title: COVID-19(新冠肺炎)地图
|
||||||
order: 0
|
order: 0
|
||||||
---
|
---
|
||||||
[![github](https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Nk9mQ48ZoZMAAAAAAAAAAABkARQnAQ)](https://github.com/antvis/L7)
|
[![github](https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*Nk9mQ48ZoZMAAAAAAAAAAABkARQnAQ)](https://github.com/antvis/L7)
|
||||||
|
|
|
@ -42,13 +42,15 @@ const World = React.memo(function Map() {
|
||||||
options={{
|
options={{
|
||||||
autoFit: true,
|
autoFit: true,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
source={{
|
source={{
|
||||||
data,
|
data,
|
||||||
|
// @ts-ignore
|
||||||
parser: {
|
parser: {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
x: 'longitude',
|
x: 'longitude',
|
||||||
y: 'latitude',
|
y: 'latitude',
|
||||||
},
|
}
|
||||||
}}
|
}}
|
||||||
shape={{
|
shape={{
|
||||||
field: 'name',
|
field: 'name',
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
"demos": [
|
"demos": [
|
||||||
{
|
{
|
||||||
"filename": "Point_image.tsx",
|
"filename": "Point_image.tsx",
|
||||||
"title": "点标注图",
|
"title": "图片标注图",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_855bab/afts/img/A*HQShTKuKq6wAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*w-8iQpR1NEQAAAAAAAAAAAAAARQnAQ"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename": "marker.tsx",
|
"filename": "marker.tsx",
|
||||||
|
@ -18,6 +18,6 @@
|
||||||
"filename": "popup.tsx",
|
"filename": "popup.tsx",
|
||||||
"title": "信息窗",
|
"title": "信息窗",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/rms_855bab/afts/img/A*RWngRL7rZKQAAAAAAAAAAAAAARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_855bab/afts/img/A*RWngRL7rZKQAAAAAAAAAAAAAARQnAQ"
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ const World = React.memo(function Map() {
|
||||||
{popupInfo && (
|
{popupInfo && (
|
||||||
<Popup
|
<Popup
|
||||||
key="popup"
|
key="popup"
|
||||||
|
// @ts-ignore
|
||||||
lnglat={popupInfo.lngLat}
|
lnglat={popupInfo.lngLat}
|
||||||
option={{ closeButton: false, offsets: [0, 10] }}
|
option={{ closeButton: false, offsets: [0, 10] }}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { Scale, Zoom, Scene } from '@antv/l7';
|
|
||||||
import { Mapbox } from '@antv/l7-maps';
|
|
||||||
const scene = new Scene({
|
|
||||||
id: 'map',
|
|
||||||
map: new Mapbox({
|
|
||||||
style: 'light',
|
|
||||||
pitch: 0,
|
|
||||||
center: [ 107.054293, 35.246265 ],
|
|
||||||
zoom: 4.056
|
|
||||||
})
|
|
||||||
});
|
|
||||||
scene.on('loaded', () => {
|
|
||||||
const zoomControl = new Zoom();
|
|
||||||
const scaleControl = new Scale();
|
|
||||||
scene.addControl(zoomControl);
|
|
||||||
scene.addControl(scaleControl);
|
|
||||||
});
|
|
|
@ -5,14 +5,9 @@
|
||||||
},
|
},
|
||||||
"demos": [
|
"demos": [
|
||||||
{
|
{
|
||||||
"filename": "amap.js",
|
"filename": "layer_highlight.js",
|
||||||
"title": "高德底图组件",
|
"title": "交互高亮图层",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*yXzQRYcGTyoAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*jBzZRp_umUoAAAAAAAAAAAAAARQnAQ"
|
||||||
},
|
|
||||||
{
|
|
||||||
"filename": "mapbox.js",
|
|
||||||
"title": "MapBox底图组件",
|
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_SIYR50bbcoAAAAAAAAAAABkARQnAQ"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ window.onLoad = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const url = 'https://webapi.amap.com/maps?v=1.4.15&key=15cd8a57710d40c9b7c0e3cc120f1200&callback=onLoad';
|
// const url = 'https://webapi.amap.com/maps?v=1.4.15&key=15cd8a57710d40c9b7c0e3cc120f1200&callback=onLoad';
|
||||||
|
const url = 'https://webapi.amap.com/maps?v=2.0&key=ff533602d57df6f8ab3b0fea226ae52f&callback=onLoad';
|
||||||
const jsapi = document.createElement('script');
|
const jsapi = document.createElement('script');
|
||||||
jsapi.charset = 'utf-8';
|
jsapi.charset = 'utf-8';
|
||||||
jsapi.src = url;
|
jsapi.src = url;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { Scene, PointLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
|
||||||
|
window.onLoad = function() {
|
||||||
|
const map = new AMap.Map('map', {
|
||||||
|
pitch: 0,
|
||||||
|
mapStyle: 'amap://styles/darkblue',
|
||||||
|
center: [ 121.435159, 31.256971 ],
|
||||||
|
zoom: 14.89,
|
||||||
|
minZoom: 10
|
||||||
|
});
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
mapInstance: map
|
||||||
|
})
|
||||||
|
});
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
fetch(
|
||||||
|
'https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json'
|
||||||
|
)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
const pointLayer = new PointLayer()
|
||||||
|
.source(data, {
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'longitude',
|
||||||
|
y: 'latitude'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.shape('name', [
|
||||||
|
'circle',
|
||||||
|
'triangle',
|
||||||
|
'square',
|
||||||
|
'pentagon',
|
||||||
|
'hexagon',
|
||||||
|
'octogon',
|
||||||
|
'hexagram',
|
||||||
|
'rhombus',
|
||||||
|
'vesica'
|
||||||
|
])
|
||||||
|
.size('unit_price', [ 10, 25 ])
|
||||||
|
.color('name', [ '#5B8FF9', '#5CCEA1', '#5D7092', '#F6BD16', '#E86452' ])
|
||||||
|
.style({
|
||||||
|
opacity: 0.3,
|
||||||
|
strokeWidth: 2
|
||||||
|
});
|
||||||
|
scene.addLayer(pointLayer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const url = 'https://webapi.amap.com/maps?v=2.0&key=ff533602d57df6f8ab3b0fea226ae52f&callback=onLoad';
|
||||||
|
const jsapi = document.createElement('script');
|
||||||
|
jsapi.charset = 'utf-8';
|
||||||
|
jsapi.src = url;
|
||||||
|
document.head.appendChild(jsapi);
|
|
@ -17,7 +17,12 @@
|
||||||
{
|
{
|
||||||
"filename": "amapInstance.js",
|
"filename": "amapInstance.js",
|
||||||
"title": "通过高德地图实例化",
|
"title": "通过高德地图实例化",
|
||||||
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_SIYR50bbcoAAAAAAAAAAABkARQnAQ"
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*C5d2RJ08hOkAAAAAAAAAAAAAARQnAQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename": "amapInstance2d.js",
|
||||||
|
"title": "通过高德地图实例化(2d)",
|
||||||
|
"screenshot": "https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*C5d2RJ08hOkAAAAAAAAAAAAAARQnAQ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default class Control extends EventEmitter {
|
||||||
name: `${controlId++}`,
|
name: `${controlId++}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public setPosition(position: PositionName = "bottomright") {
|
public setPosition(position: PositionName = 'bottomright') {
|
||||||
// 考虑组件的自动布局,需要销毁重建
|
// 考虑组件的自动布局,需要销毁重建
|
||||||
const controlService = this.controlService;
|
const controlService = this.controlService;
|
||||||
if (controlService) {
|
if (controlService) {
|
||||||
|
|
|
@ -474,5 +474,3 @@
|
||||||
.amap-logo{
|
.amap-logo{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,8 @@ export default class Marker extends EventEmitter {
|
||||||
// this.sceneSerive.getSceneContainer().appendChild(element as HTMLElement);
|
// this.sceneSerive.getSceneContainer().appendChild(element as HTMLElement);
|
||||||
this.mapsService.getMarkerContainer().appendChild(element as HTMLElement);
|
this.mapsService.getMarkerContainer().appendChild(element as HTMLElement);
|
||||||
this.registerMarkerEvent(element as HTMLElement);
|
this.registerMarkerEvent(element as HTMLElement);
|
||||||
this.mapsService.on('camerachange', this.update);
|
this.mapsService.on('camerachange', this.update); // 注册高德1.x 的地图事件监听
|
||||||
|
this.mapsService.on('viewchange', this.update); // 注册高德2.0 的地图事件监听
|
||||||
this.update();
|
this.update();
|
||||||
this.added = true;
|
this.added = true;
|
||||||
this.emit('added');
|
this.emit('added');
|
||||||
|
|
|
@ -32,6 +32,7 @@ const VALID_PROPS = [
|
||||||
'cutoff',
|
'cutoff',
|
||||||
'radius',
|
'radius',
|
||||||
];
|
];
|
||||||
|
|
||||||
function getDefaultCharacterSet() {
|
function getDefaultCharacterSet() {
|
||||||
const charSet = [];
|
const charSet = [];
|
||||||
for (let i = 32; i < 128; i++) {
|
for (let i = 32; i < 128; i++) {
|
||||||
|
@ -51,6 +52,7 @@ function setTextStyle(
|
||||||
ctx.textBaseline = 'middle';
|
ctx.textBaseline = 'middle';
|
||||||
// ctx.textAlign = 'left';
|
// ctx.textAlign = 'left';
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateAlphaChannel(alphaChannel: number[], imageData: ImageData) {
|
function populateAlphaChannel(alphaChannel: number[], imageData: ImageData) {
|
||||||
// populate distance value from tinySDF to image alpha channel
|
// populate distance value from tinySDF to image alpha channel
|
||||||
for (let i = 0; i < alphaChannel.length; i++) {
|
for (let i = 0; i < alphaChannel.length; i++) {
|
||||||
|
@ -60,7 +62,23 @@ function populateAlphaChannel(alphaChannel: number[], imageData: ImageData) {
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class FontService implements IFontService {
|
export default class FontService implements IFontService {
|
||||||
|
public get scale() {
|
||||||
|
return HEIGHT_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get canvas(): HTMLCanvasElement {
|
||||||
|
const data = this.cache.get(this.key);
|
||||||
|
return data && data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get mapping(): IFontMapping {
|
||||||
|
const data = this.cache.get(this.key);
|
||||||
|
return data && data.mapping;
|
||||||
|
}
|
||||||
public fontAtlas: IFontAtlas;
|
public fontAtlas: IFontAtlas;
|
||||||
|
|
||||||
|
// iconFontMap 记录用户设置的 iconfont unicode 和名称的键值关系
|
||||||
|
public iconFontMap: Map<string, string>;
|
||||||
private iconFontGlyphs: {
|
private iconFontGlyphs: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
} = {};
|
} = {};
|
||||||
|
@ -79,46 +97,52 @@ export default class FontService implements IFontService {
|
||||||
sdf: true,
|
sdf: true,
|
||||||
cutoff: DEFAULT_CUTOFF,
|
cutoff: DEFAULT_CUTOFF,
|
||||||
radius: DEFAULT_RADIUS,
|
radius: DEFAULT_RADIUS,
|
||||||
|
iconfont: false,
|
||||||
};
|
};
|
||||||
this.key = '';
|
this.key = '';
|
||||||
|
this.iconFontMap = new Map();
|
||||||
}
|
}
|
||||||
public addIconGlyphs(glyphs: IIconFontGlyph[]): void {
|
public addIconGlyphs(glyphs: IIconFontGlyph[]): void {
|
||||||
glyphs.forEach((glyph) => {
|
glyphs.forEach((glyph) => {
|
||||||
this.iconFontGlyphs[glyph.name] = glyph.unicode;
|
this.iconFontGlyphs[glyph.name] = glyph.unicode;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加对 iconfont unicode 的映射
|
||||||
|
* @param fontUnicode
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public addIconFont(name: string, fontUnicode: string): void {
|
||||||
|
this.iconFontMap.set(name, fontUnicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义 iconfont 别称对应的 unicode 编码,若是当前的 map 中没有对应的键值对,那么就返回原值
|
||||||
|
* @param name
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getIconFontKey(name: string): string {
|
||||||
|
return this.iconFontMap.get(name) || name;
|
||||||
|
}
|
||||||
|
|
||||||
public getGlyph(name: string): string {
|
public getGlyph(name: string): string {
|
||||||
if (this.iconFontGlyphs[name]) {
|
if (this.iconFontGlyphs[name]) {
|
||||||
return String.fromCharCode(parseInt(this.iconFontGlyphs[name], 16));
|
return String.fromCharCode(parseInt(this.iconFontGlyphs[name], 16));
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
public get scale() {
|
|
||||||
return HEIGHT_SCALE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get canvas(): HTMLCanvasElement {
|
|
||||||
const data = this.cache.get(this.key);
|
|
||||||
return data && data.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get mapping(): IFontMapping {
|
|
||||||
const data = this.cache.get(this.key);
|
|
||||||
return data && data.mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setFontOptions(option: Partial<IFontOptions>) {
|
public setFontOptions(option: Partial<IFontOptions>) {
|
||||||
this.fontOptions = {
|
this.fontOptions = {
|
||||||
...this.fontOptions,
|
...this.fontOptions,
|
||||||
...option,
|
...option,
|
||||||
};
|
};
|
||||||
|
|
||||||
// const oldKey = this.key;
|
// const oldKey = this.key;
|
||||||
this.key = this.getKey();
|
this.key = this.getKey();
|
||||||
|
|
||||||
const charSet = this.getNewChars(this.key, this.fontOptions.characterSet);
|
const charSet = this.getNewChars(this.key, this.fontOptions.characterSet);
|
||||||
const cachedFontAtlas = this.cache.get(this.key);
|
const cachedFontAtlas = this.cache.get(this.key);
|
||||||
|
|
||||||
if (cachedFontAtlas && charSet.length === 0) {
|
if (cachedFontAtlas && charSet.length === 0) {
|
||||||
// update texture with cached fontAtlas
|
// update texture with cached fontAtlas
|
||||||
return;
|
return;
|
||||||
|
@ -137,6 +161,7 @@ export default class FontService implements IFontService {
|
||||||
|
|
||||||
public destroy(): void {
|
public destroy(): void {
|
||||||
this.cache.clear();
|
this.cache.clear();
|
||||||
|
this.iconFontMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private generateFontAtlas(
|
private generateFontAtlas(
|
||||||
|
@ -152,6 +177,7 @@ export default class FontService implements IFontService {
|
||||||
sdf,
|
sdf,
|
||||||
radius,
|
radius,
|
||||||
cutoff,
|
cutoff,
|
||||||
|
iconfont,
|
||||||
} = this.fontOptions;
|
} = this.fontOptions;
|
||||||
let canvas = cachedFontAtlas && cachedFontAtlas.data;
|
let canvas = cachedFontAtlas && cachedFontAtlas.data;
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
|
@ -197,7 +223,22 @@ export default class FontService implements IFontService {
|
||||||
// tinySDF.size equals `fontSize + buffer * 2`
|
// tinySDF.size equals `fontSize + buffer * 2`
|
||||||
const imageData = ctx.getImageData(0, 0, tinySDF.size, tinySDF.size);
|
const imageData = ctx.getImageData(0, 0, tinySDF.size, tinySDF.size);
|
||||||
for (const char of characterSet) {
|
for (const char of characterSet) {
|
||||||
populateAlphaChannel(tinySDF.draw(char), imageData);
|
if (iconfont) {
|
||||||
|
// @ts-ignore
|
||||||
|
// const icon = eval(
|
||||||
|
// '("' + char.replace('&#x', '\\u').replace(';', '') + '")',
|
||||||
|
// );
|
||||||
|
|
||||||
|
const icon = String.fromCharCode(
|
||||||
|
parseInt(char.replace('&#x', '').replace(';', ''), 16),
|
||||||
|
);
|
||||||
|
const iconData = tinySDF.draw(icon);
|
||||||
|
populateAlphaChannel(iconData, imageData);
|
||||||
|
} else {
|
||||||
|
populateAlphaChannel(tinySDF.draw(char), imageData);
|
||||||
|
}
|
||||||
|
// populateAlphaChannel(tinySDF.draw(char), imageData);
|
||||||
|
|
||||||
// 考虑到描边,需要保留 sdf 的 buffer,不能像 deck.gl 一样直接减去
|
// 考虑到描边,需要保留 sdf 的 buffer,不能像 deck.gl 一样直接减去
|
||||||
ctx.putImageData(imageData, mapping[char].x, mapping[char].y);
|
ctx.putImageData(imageData, mapping[char].x, mapping[char].y);
|
||||||
}
|
}
|
||||||
|
@ -221,6 +262,7 @@ export default class FontService implements IFontService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private getKey() {
|
private getKey() {
|
||||||
|
return 'key';
|
||||||
const {
|
const {
|
||||||
fontFamily,
|
fontFamily,
|
||||||
fontWeight,
|
fontWeight,
|
||||||
|
@ -231,11 +273,18 @@ export default class FontService implements IFontService {
|
||||||
cutoff,
|
cutoff,
|
||||||
} = this.fontOptions;
|
} = this.fontOptions;
|
||||||
if (sdf) {
|
if (sdf) {
|
||||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer} ${radius} ${cutoff}`;
|
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer} ${radius} ${cutoff} `;
|
||||||
}
|
}
|
||||||
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
|
return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param characterSet
|
||||||
|
* @returns
|
||||||
|
* 若是相同的 key,那么将字符存储到同同一个字符列表中
|
||||||
|
*/
|
||||||
private getNewChars(key: string, characterSet: string[]): string[] {
|
private getNewChars(key: string, characterSet: string[]): string[] {
|
||||||
const cachedFontAtlas = this.cache.get(key);
|
const cachedFontAtlas = this.cache.get(key);
|
||||||
if (!cachedFontAtlas) {
|
if (!cachedFontAtlas) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ export interface IFontOptions {
|
||||||
sdf: boolean;
|
sdf: boolean;
|
||||||
cutoff: number;
|
cutoff: number;
|
||||||
radius: number;
|
radius: number;
|
||||||
|
iconfont: boolean;
|
||||||
}
|
}
|
||||||
export interface IFontMappingOption {
|
export interface IFontMappingOption {
|
||||||
characterSet: string[];
|
characterSet: string[];
|
||||||
|
@ -29,6 +30,10 @@ export interface IFontMapping {
|
||||||
[key: string]: IFontMappingItem;
|
[key: string]: IFontMappingItem;
|
||||||
[key: number]: IFontMappingItem;
|
[key: number]: IFontMappingItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IFontIconFontMapItem {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
export interface IFontAtlas {
|
export interface IFontAtlas {
|
||||||
xOffset: number;
|
xOffset: number;
|
||||||
yOffset: number;
|
yOffset: number;
|
||||||
|
@ -44,11 +49,14 @@ export interface IIconFontGlyph {
|
||||||
}
|
}
|
||||||
export interface IFontService {
|
export interface IFontService {
|
||||||
mapping: IFontMapping;
|
mapping: IFontMapping;
|
||||||
|
iconFontMap: Map<string, string>;
|
||||||
fontAtlas: IFontAtlas;
|
fontAtlas: IFontAtlas;
|
||||||
canvas: HTMLCanvasElement;
|
canvas: HTMLCanvasElement;
|
||||||
scale: number;
|
scale: number;
|
||||||
init(): void;
|
init(): void;
|
||||||
addIconGlyphs(glyphs: IIconFontGlyph[]): void;
|
addIconGlyphs(glyphs: IIconFontGlyph[]): void;
|
||||||
|
addIconFont(name: string, fontUnicode: string): void;
|
||||||
|
getIconFontKey(name: string): string;
|
||||||
getGlyph(name: string): string;
|
getGlyph(name: string): string;
|
||||||
setFontOptions(option: Partial<IFontOptions>): void;
|
setFontOptions(option: Partial<IFontOptions>): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import TinySDF from '@mapbox/tiny-sdf';
|
||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
import { inject, injectable } from 'inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { TYPES } from '../../types';
|
import { TYPES } from '../../types';
|
||||||
|
@ -96,6 +98,9 @@ export default class IconService extends EventEmitter implements IIconService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将新增的 icon 图像存储到画布上(正方形)
|
||||||
|
*/
|
||||||
private updateIconAtlas() {
|
private updateIconAtlas() {
|
||||||
this.canvas.width = MAX_CANVAS_WIDTH;
|
this.canvas.width = MAX_CANVAS_WIDTH;
|
||||||
this.canvas.height = this.canvasHeight;
|
this.canvas.height = this.canvasHeight;
|
||||||
|
@ -117,6 +122,9 @@ export default class IconService extends EventEmitter implements IIconService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算 icon 在画布上的排布(是否需要换行)
|
||||||
|
*/
|
||||||
private updateIconMap() {
|
private updateIconMap() {
|
||||||
const { mapping, canvasHeight } = buildIconMaping(
|
const { mapping, canvasHeight } = buildIconMaping(
|
||||||
this.iconData,
|
this.iconData,
|
||||||
|
|
|
@ -24,7 +24,8 @@ export default class CameraService implements ICameraService {
|
||||||
/**
|
/**
|
||||||
* ViewMatrix 逆矩阵,用于计算相机位置
|
* ViewMatrix 逆矩阵,用于计算相机位置
|
||||||
*/
|
*/
|
||||||
private viewMatrixInverse: number[];
|
// private viewMatrixInverse: number[];
|
||||||
|
private viewMatrixInverse: mat4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 相机位置
|
* 相机位置
|
||||||
|
@ -42,10 +43,12 @@ export default class CameraService implements ICameraService {
|
||||||
this.viewport = viewport;
|
this.viewport = viewport;
|
||||||
|
|
||||||
// 计算逆矩阵
|
// 计算逆矩阵
|
||||||
this.viewMatrixInverse = (mat4.invert(
|
// this.viewMatrixInverse = (mat4.invert(
|
||||||
mat4.create(),
|
// mat4.create(), (this.getViewMatrix() as unknown) as mat4,
|
||||||
(this.getViewMatrix() as unknown) as mat4,
|
// ) as unknown) as number[];
|
||||||
) as unknown) as number[];
|
|
||||||
|
this.viewMatrixInverse = mat4.create();
|
||||||
|
mat4.invert(this.viewMatrixInverse, viewport.getViewMatrix() as mat4);
|
||||||
|
|
||||||
this.cameraPosition = [
|
this.cameraPosition = [
|
||||||
this.viewMatrixInverse[12],
|
this.viewMatrixInverse[12],
|
||||||
|
|
|
@ -79,6 +79,7 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
|
||||||
duration: 4,
|
duration: 4,
|
||||||
trailLength: 0.15,
|
trailLength: 0.15,
|
||||||
},
|
},
|
||||||
|
forward: true, // 默认是正方向
|
||||||
};
|
};
|
||||||
|
|
||||||
// @see https://github.com/epoberezkin/ajv#options
|
// @see https://github.com/epoberezkin/ajv#options
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { inject, injectable } from 'inversify';
|
||||||
import { TYPES } from '../../types';
|
import { TYPES } from '../../types';
|
||||||
import { getDistanceScales } from '../../utils/project';
|
import { getDistanceScales } from '../../utils/project';
|
||||||
import { ICameraService } from '../camera/ICameraService';
|
import { ICameraService } from '../camera/ICameraService';
|
||||||
|
// import { IMapService } from '../map/IMapService'
|
||||||
import {
|
import {
|
||||||
CoordinateSystem,
|
CoordinateSystem,
|
||||||
ICoordinateSystemService,
|
ICoordinateSystemService,
|
||||||
|
@ -17,6 +18,10 @@ export default class CoordinateSystemService
|
||||||
@inject(TYPES.ICameraService)
|
@inject(TYPES.ICameraService)
|
||||||
private readonly cameraService: ICameraService;
|
private readonly cameraService: ICameraService;
|
||||||
|
|
||||||
|
// map.getCenter
|
||||||
|
// @inject(TYPES.IMapService)
|
||||||
|
// private readonly mapService: IMapService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1. Web 墨卡托坐标系
|
* 1. Web 墨卡托坐标系
|
||||||
* 2. 偏移经纬度,用于解决高精度抖动问题
|
* 2. 偏移经纬度,用于解决高精度抖动问题
|
||||||
|
|
|
@ -17,6 +17,7 @@ export enum CoordinateSystem {
|
||||||
P20 = 5.0,
|
P20 = 5.0,
|
||||||
P20_OFFSET = 6.0,
|
P20_OFFSET = 6.0,
|
||||||
METER_OFFSET = 7.0,
|
METER_OFFSET = 7.0,
|
||||||
|
P20_2 = 8.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 后续传入 Shader 的变量
|
// 后续传入 Shader 的变量
|
||||||
|
@ -27,6 +28,8 @@ export const CoordinateUniform = {
|
||||||
PixelsPerDegree: 'u_PixelsPerDegree',
|
PixelsPerDegree: 'u_PixelsPerDegree',
|
||||||
PixelsPerDegree2: 'u_PixelsPerDegree2',
|
PixelsPerDegree2: 'u_PixelsPerDegree2',
|
||||||
PixelsPerMeter: 'u_PixelsPerMeter',
|
PixelsPerMeter: 'u_PixelsPerMeter',
|
||||||
|
|
||||||
|
Mvp: 'u_Mvp',
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ICoordinateSystemService {
|
export interface ICoordinateSystemService {
|
||||||
|
|
|
@ -130,6 +130,7 @@ export interface ILayer {
|
||||||
scale(field: string | number | IScaleOptions, cfg?: IScale): ILayer;
|
scale(field: string | number | IScaleOptions, cfg?: IScale): ILayer;
|
||||||
size(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
size(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
||||||
color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
||||||
|
texture(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
||||||
shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
||||||
label(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
label(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
|
||||||
animate(option: Partial<IAnimateOption> | boolean): ILayer;
|
animate(option: Partial<IAnimateOption> | boolean): ILayer;
|
||||||
|
@ -244,6 +245,8 @@ export interface ILayerConfig {
|
||||||
enableMultiPassRenderer: boolean;
|
enableMultiPassRenderer: boolean;
|
||||||
passes: Array<string | [string, { [key: string]: unknown }]>;
|
passes: Array<string | [string, { [key: string]: unknown }]>;
|
||||||
|
|
||||||
|
forward: boolean; // 正方向
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开启拾取
|
* 开启拾取
|
||||||
*/
|
*/
|
||||||
|
@ -274,6 +277,10 @@ export interface ILayerConfig {
|
||||||
*/
|
*/
|
||||||
enableLighting: boolean;
|
enableLighting: boolean;
|
||||||
animateOption: Partial<IAnimateOption>;
|
animateOption: Partial<IAnimateOption>;
|
||||||
|
/**
|
||||||
|
* layer point text 是否是 iconfont 模式
|
||||||
|
*/
|
||||||
|
iconfont: boolean;
|
||||||
onHover(pickedFeature: IPickedFeature): void;
|
onHover(pickedFeature: IPickedFeature): void;
|
||||||
onClick(pickedFeature: IPickedFeature): void;
|
onClick(pickedFeature: IPickedFeature): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,10 @@ export interface IMapWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMapService<RawMap = {}> {
|
export interface IMapService<RawMap = {}> {
|
||||||
|
version: string;
|
||||||
map: RawMap;
|
map: RawMap;
|
||||||
init(): void;
|
init(): void;
|
||||||
|
initViewPort?(): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
onCameraChanged(callback: (viewport: IViewport) => void): void;
|
onCameraChanged(callback: (viewport: IViewport) => void): void;
|
||||||
// init map
|
// init map
|
||||||
|
@ -85,6 +87,12 @@ export interface IMapService<RawMap = {}> {
|
||||||
scale: [number, number, number],
|
scale: [number, number, number],
|
||||||
origin: IMercator,
|
origin: IMercator,
|
||||||
): number[];
|
): number[];
|
||||||
|
lngLatToCoord?(lnglat: [number, number]): [number, number];
|
||||||
|
lngLatToCoords?(
|
||||||
|
lnglatArray: number[][][] | number[][],
|
||||||
|
): number[][][] | number[][] | number[][][] | number[][];
|
||||||
|
// lngLatToCoords?(lnglatArray: any): any;
|
||||||
|
getCustomCoordCenter?(): [number, number];
|
||||||
exportMap(type: 'jpg' | 'png'): string;
|
exportMap(type: 'jpg' | 'png'): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +186,9 @@ export interface IMapCamera {
|
||||||
center: [number, number];
|
center: [number, number];
|
||||||
// 相机高度
|
// 相机高度
|
||||||
cameraHeight: number;
|
cameraHeight: number;
|
||||||
|
cameraPosition?: [number, number, number];
|
||||||
|
up?: [number, number, number];
|
||||||
|
lookAt?: [number, number, number];
|
||||||
// 偏移原点,例如 P20 坐标系下
|
// 偏移原点,例如 P20 坐标系下
|
||||||
offsetOrigin: [number, number];
|
offsetOrigin: [number, number];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { IRenderConfig } from '../renderer/IRendererService';
|
||||||
export interface ISceneService {
|
export interface ISceneService {
|
||||||
destroyed: boolean;
|
destroyed: boolean;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
|
fontFamily: string;
|
||||||
|
loadFont: boolean;
|
||||||
on(type: string, handle: (...args: any[]) => void): void;
|
on(type: string, handle: (...args: any[]) => void): void;
|
||||||
off(type: string, handle: (...args: any[]) => void): void;
|
off(type: string, handle: (...args: any[]) => void): void;
|
||||||
removeAllListeners(event?: string): this;
|
removeAllListeners(event?: string): this;
|
||||||
|
@ -16,6 +18,7 @@ export interface ISceneService {
|
||||||
getSceneContainer(): HTMLDivElement;
|
getSceneContainer(): HTMLDivElement;
|
||||||
getMarkerContainer(): HTMLElement;
|
getMarkerContainer(): HTMLElement;
|
||||||
exportPng(type?: 'png' | 'jpg'): string;
|
exportPng(type?: 'png' | 'jpg'): string;
|
||||||
|
addFontFace(fontname: string, fontpath: string): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
}
|
}
|
||||||
// scene 事件
|
// scene 事件
|
||||||
|
|
|
@ -35,6 +35,10 @@ export default class Scene extends EventEmitter implements ISceneService {
|
||||||
public destroyed: boolean = false;
|
public destroyed: boolean = false;
|
||||||
|
|
||||||
public loaded: boolean = false;
|
public loaded: boolean = false;
|
||||||
|
// loadFont 判断用户当前是否添加自定义字体
|
||||||
|
public loadFont: boolean = false;
|
||||||
|
// fontFamily 用户当前自己添加的字体的名称
|
||||||
|
public fontFamily: string = '';
|
||||||
|
|
||||||
@inject(TYPES.SceneID)
|
@inject(TYPES.SceneID)
|
||||||
private readonly id: string;
|
private readonly id: string;
|
||||||
|
@ -139,15 +143,32 @@ export default class Scene extends EventEmitter implements ISceneService {
|
||||||
*/
|
*/
|
||||||
this.hooks.init.tapPromise('initMap', async () => {
|
this.hooks.init.tapPromise('initMap', async () => {
|
||||||
// 等待首次相机同步
|
// 等待首次相机同步
|
||||||
await new Promise((resolve) => {
|
await new Promise<void>((resolve) => {
|
||||||
this.map.onCameraChanged((viewport: IViewport) => {
|
this.map.onCameraChanged((viewport: IViewport) => {
|
||||||
this.cameraService.init();
|
this.cameraService.init();
|
||||||
this.cameraService.update(viewport);
|
this.cameraService.update(viewport);
|
||||||
resolve();
|
if (this.map.version !== 'GAODE2.x') {
|
||||||
|
// not amap2
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.map.init();
|
|
||||||
|
if (this.map.version !== 'GAODE2.x') {
|
||||||
|
// not amap2
|
||||||
|
this.map.init();
|
||||||
|
} else {
|
||||||
|
// amap2
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.map.version === 'GAODE2.x' && this.map.initViewPort) {
|
||||||
|
// amap2
|
||||||
|
await this.map.init();
|
||||||
|
this.map.initViewPort();
|
||||||
|
}
|
||||||
// this.controlService.addControls();
|
// this.controlService.addControls();
|
||||||
|
|
||||||
// 重新绑定非首次相机更新事件
|
// 重新绑定非首次相机更新事件
|
||||||
this.map.onCameraChanged(this.handleMapCameraChanged);
|
this.map.onCameraChanged(this.handleMapCameraChanged);
|
||||||
this.map.addMarkerContainer();
|
this.map.addMarkerContainer();
|
||||||
|
@ -208,7 +229,6 @@ export default class Scene extends EventEmitter implements ISceneService {
|
||||||
// 执行异步并行初始化任务
|
// 执行异步并行初始化任务
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.initPromise = this.hooks.init.promise();
|
this.initPromise = this.hooks.init.promise();
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,15 +242,20 @@ export default class Scene extends EventEmitter implements ISceneService {
|
||||||
if (this.rendering || this.destroyed) {
|
if (this.rendering || this.destroyed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rendering = true;
|
this.rendering = true;
|
||||||
// 首次初始化,或者地图的容器被强制销毁的需要重新初始化
|
// 首次初始化,或者地图的容器被强制销毁的需要重新初始化
|
||||||
if (!this.inited) {
|
if (!this.inited) {
|
||||||
// 还未初始化完成需要等待
|
// 还未初始化完成需要等待
|
||||||
|
|
||||||
await this.initPromise;
|
await this.initPromise;
|
||||||
if (this.destroyed) {
|
if (this.destroyed) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
if (this.loadFont && document.fonts) {
|
||||||
|
// @ts-ignore
|
||||||
|
await document.fonts.load(`24px ${this.fontFamily}`, 'L7text');
|
||||||
|
}
|
||||||
// FIXME: 初始化 marker 容器,可以放到 map 初始化方法中?
|
// FIXME: 初始化 marker 容器,可以放到 map 初始化方法中?
|
||||||
this.logger.info(' render inited');
|
this.logger.info(' render inited');
|
||||||
this.layerService.initLayers();
|
this.layerService.initLayers();
|
||||||
|
@ -243,12 +268,30 @@ export default class Scene extends EventEmitter implements ISceneService {
|
||||||
// 尝试初始化未初始化的图层
|
// 尝试初始化未初始化的图层
|
||||||
this.layerService.renderLayers();
|
this.layerService.renderLayers();
|
||||||
// 组件需要等待layer 初始化完成之后添加
|
// 组件需要等待layer 初始化完成之后添加
|
||||||
|
|
||||||
this.logger.debug(`scene ${this.id} render`);
|
this.logger.debug(`scene ${this.id} render`);
|
||||||
|
|
||||||
this.rendering = false;
|
this.rendering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户自定义添加第三方字体 (用户使用 layer/point/text/iconfont 的前提需要加载第三方字体文件)
|
||||||
|
* @param fontFamily
|
||||||
|
* @param fontPath
|
||||||
|
*/
|
||||||
|
public addFontFace(fontFamily: string, fontPath: string): void {
|
||||||
|
this.fontFamily = fontFamily;
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.type = 'text/css';
|
||||||
|
style.innerText = `
|
||||||
|
@font-face{
|
||||||
|
font-family: '${fontFamily}';
|
||||||
|
src: url('${fontPath}') format('woff2'),
|
||||||
|
url('${fontPath}') format('woff'),
|
||||||
|
url('${fontPath}') format('truetype');
|
||||||
|
}`;
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
this.loadFont = true;
|
||||||
|
}
|
||||||
|
|
||||||
public getSceneContainer(): HTMLDivElement {
|
public getSceneContainer(): HTMLDivElement {
|
||||||
return this.$container as HTMLDivElement;
|
return this.$container as HTMLDivElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,3 +38,33 @@ float pixelDistance(vec2 from, vec2 to) {
|
||||||
vec2 b1 = ProjectFlat(to);
|
vec2 b1 = ProjectFlat(to);
|
||||||
return distance(a1, b1);
|
return distance(a1, b1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gaode2.0
|
||||||
|
vec2 customProject(vec2 lnglat) { // 经纬度 => 平面坐标
|
||||||
|
float t = lnglat.x;
|
||||||
|
float e = lnglat.y;
|
||||||
|
float Sm = 180.0 / PI;
|
||||||
|
float Tm = 6378137.0;
|
||||||
|
float Rm = PI / 180.0;
|
||||||
|
float r = 85.0511287798;
|
||||||
|
e = max(min(r, e), -r);
|
||||||
|
t *= Rm;
|
||||||
|
e *= Rm;
|
||||||
|
e = log(tan(PI / 4.0 + e / 2.0));
|
||||||
|
return vec2(t * Tm, e * Tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 unProjCustomCoord(vec2 point) { // 平面坐标 => 经纬度
|
||||||
|
float Sm = 57.29577951308232; //180 / Math.PI
|
||||||
|
float Tm = 6378137.0;
|
||||||
|
float t = point.x;
|
||||||
|
float e = point.y;
|
||||||
|
return vec2(t / Tm * Sm, (2.0 * atan(exp(e / Tm)) - PI / 2.0) * Sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float customPixelDistance(vec2 from, vec2 to) {
|
||||||
|
vec2 a1 = ProjectFlat(from);
|
||||||
|
vec2 b1 = ProjectFlat(to);
|
||||||
|
return distance(a1, b1);
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
#define COORDINATE_SYSTEM_P20_OFFSET 6.0
|
#define COORDINATE_SYSTEM_P20_OFFSET 6.0
|
||||||
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
|
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
|
||||||
|
|
||||||
|
#define COORDINATE_SYSTEM_P20_2 8.0
|
||||||
|
|
||||||
uniform mat4 u_ViewMatrix;
|
uniform mat4 u_ViewMatrix;
|
||||||
uniform mat4 u_ProjectionMatrix;
|
uniform mat4 u_ProjectionMatrix;
|
||||||
uniform mat4 u_ViewProjectionMatrix;
|
uniform mat4 u_ViewProjectionMatrix;
|
||||||
|
@ -28,6 +30,8 @@ uniform float u_DevicePixelRatio;
|
||||||
uniform float u_FocalDistance;
|
uniform float u_FocalDistance;
|
||||||
uniform vec3 u_CameraPosition;
|
uniform vec3 u_CameraPosition;
|
||||||
|
|
||||||
|
// uniform mat4 u_Mvp;
|
||||||
|
|
||||||
// web mercator coords -> world coords
|
// web mercator coords -> world coords
|
||||||
vec2 project_mercator(vec2 lnglat) {
|
vec2 project_mercator(vec2 lnglat) {
|
||||||
float x = lnglat.x;
|
float x = lnglat.x;
|
||||||
|
@ -69,6 +73,10 @@ vec3 reverse_offset_normal(vec3 vector) {
|
||||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 ||u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET ) {
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 ||u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET ) {
|
||||||
return vector * vec3(1.0, -1.0, 1.0);
|
return vector * vec3(1.0, -1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.0
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +105,18 @@ vec4 project_position(vec4 position) {
|
||||||
position.w
|
position.w
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
|
// return vec4(
|
||||||
|
// (position.xy * WORLD_SCALE * u_ZoomScale) * vec2(1., -1.),
|
||||||
|
// project_scale(position.z),
|
||||||
|
// position.w);
|
||||||
|
|
||||||
|
return vec4(
|
||||||
|
position.xy,
|
||||||
|
project_scale(position.z),
|
||||||
|
position.w);
|
||||||
|
}
|
||||||
return position;
|
return position;
|
||||||
|
|
||||||
// TODO: 瓦片坐标系 & 常规世界坐标系
|
// TODO: 瓦片坐标系 & 常规世界坐标系
|
||||||
|
@ -111,6 +131,10 @@ float project_pixel(float pixel) {
|
||||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||||
}
|
}
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
|
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
||||||
|
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
|
||||||
|
}
|
||||||
return pixel;
|
return pixel;
|
||||||
}
|
}
|
||||||
vec2 project_pixel(vec2 pixel) {
|
vec2 project_pixel(vec2 pixel) {
|
||||||
|
@ -118,6 +142,10 @@ vec2 project_pixel(vec2 pixel) {
|
||||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||||
}
|
}
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
|
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
||||||
|
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
|
||||||
|
}
|
||||||
return pixel * -1.;
|
return pixel * -1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +155,7 @@ vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatr
|
||||||
// Needs to be divided with project_uCommonUnitsPerMeter
|
// Needs to be divided with project_uCommonUnitsPerMeter
|
||||||
position.w *= u_PixelsPerMeter.z;
|
position.w *= u_PixelsPerMeter.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
return viewProjectionMatrix * position + center;
|
return viewProjectionMatrix * position + center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,5 +182,4 @@ vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjec
|
||||||
|
|
||||||
bool isEqual( float a, float b) {
|
bool isEqual( float a, float b) {
|
||||||
return a< b + 0.001 && a > b - 0.001;
|
return a< b + 0.001 && a > b - 0.001;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ export function buildMapping({
|
||||||
});
|
});
|
||||||
|
|
||||||
const rowHeight = fontHeight + buffer * 2;
|
const rowHeight = fontHeight + buffer * 2;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mapping,
|
mapping,
|
||||||
xOffset: x,
|
xOffset: x,
|
||||||
|
|
|
@ -14,6 +14,7 @@ attribute vec2 a_Uv;
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
varying vec4 v_Color;
|
varying vec4 v_Color;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "light"
|
#pragma include "light"
|
||||||
|
@ -23,7 +24,12 @@ void main() {
|
||||||
vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0);
|
vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0);
|
||||||
vec4 project_pos = project_position(pos);
|
vec4 project_pos = project_position(pos);
|
||||||
v_texCoord = a_Uv;
|
v_texCoord = a_Uv;
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
float lightWeight = calc_lighting(pos);
|
float lightWeight = calc_lighting(pos);
|
||||||
// v_Color = a_Color;
|
// v_Color = a_Color;
|
||||||
|
|
|
@ -375,6 +375,16 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为对应的图层传入纹理的编号名称(point/image 在 shape 方法中传入纹理名称的方法并不通用)
|
||||||
|
public texture(
|
||||||
|
field: StyleAttributeField,
|
||||||
|
values?: StyleAttributeOption,
|
||||||
|
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
|
||||||
|
) {
|
||||||
|
this.updateStyleAttribute('texture', field, values, updateOptions);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public rotate(
|
public rotate(
|
||||||
field: StyleAttributeField,
|
field: StyleAttributeField,
|
||||||
values?: StyleAttributeOption,
|
values?: StyleAttributeOption,
|
||||||
|
@ -482,7 +492,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
||||||
...this.rawConfig,
|
...this.rawConfig,
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.container) {
|
if (this.container) {
|
||||||
this.updateLayerConfig(this.rawConfig);
|
this.updateLayerConfig(this.rawConfig);
|
||||||
this.styleNeedUpdate = true;
|
this.styleNeedUpdate = true;
|
||||||
|
@ -500,6 +509,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): ILayer {
|
public render(): ILayer {
|
||||||
// if (
|
// if (
|
||||||
// this.needPick() &&
|
// this.needPick() &&
|
||||||
|
|
|
@ -8,4 +8,7 @@ export interface ILineLayerStyleOptions {
|
||||||
lineType?: keyof typeof lineStyleType;
|
lineType?: keyof typeof lineStyleType;
|
||||||
dashArray?: [number, number];
|
dashArray?: [number, number];
|
||||||
segmentNumber: number;
|
segmentNumber: number;
|
||||||
|
forward?: boolean;
|
||||||
|
lineTexture?: boolean;
|
||||||
|
iconStep?: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ export function PointFillTriangulation(feature: IEncodeFeature) {
|
||||||
*/
|
*/
|
||||||
export function PointExtrudeTriangulation(feature: IEncodeFeature) {
|
export function PointExtrudeTriangulation(feature: IEncodeFeature) {
|
||||||
const { shape } = feature;
|
const { shape } = feature;
|
||||||
|
// console.log('PointExtrudeTriangulation', feature)
|
||||||
const { positions, index, normals } = getGeometry(
|
const { positions, index, normals } = getGeometry(
|
||||||
shape as ShapeType3D,
|
shape as ShapeType3D,
|
||||||
false,
|
false,
|
||||||
|
@ -69,19 +70,45 @@ export function PointImageTriangulation(feature: IEncodeFeature) {
|
||||||
* @param feature 映射feature
|
* @param feature 映射feature
|
||||||
*/
|
*/
|
||||||
export function LineTriangulation(feature: IEncodeFeature) {
|
export function LineTriangulation(feature: IEncodeFeature) {
|
||||||
const { coordinates } = feature;
|
const { coordinates, originCoordinates, version } = feature;
|
||||||
let path = coordinates as number[][][] | number[][];
|
// let path = coordinates as number[][][] | number[][];
|
||||||
if (!Array.isArray(path[0][0])) {
|
// if (!Array.isArray(path[0][0])) {
|
||||||
path = [coordinates] as number[][][];
|
// path = [coordinates] as number[][][];
|
||||||
}
|
// }
|
||||||
|
|
||||||
const line = new ExtrudePolyline({
|
const line = new ExtrudePolyline({
|
||||||
dash: true,
|
dash: true,
|
||||||
join: 'bevel', //
|
join: 'bevel',
|
||||||
});
|
|
||||||
path.forEach((item: any) => {
|
|
||||||
// 处理带洞的多边形
|
|
||||||
line.extrude(item as number[][]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (version === 'GAODE2.x') {
|
||||||
|
// 处理高德2.0几何体构建
|
||||||
|
let path1 = coordinates as number[][][] | number[][]; // 计算位置
|
||||||
|
if (!Array.isArray(path1[0][0])) {
|
||||||
|
path1 = [coordinates] as number[][][];
|
||||||
|
}
|
||||||
|
let path2 = originCoordinates as number[][][] | number[][]; // 计算法线
|
||||||
|
if (!Array.isArray(path2[0][0])) {
|
||||||
|
path2 = [originCoordinates] as number[][][];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < path1.length; i++) {
|
||||||
|
// 高德2.0在计算线时,需要使用经纬度计算发现,使用 customCoords.lnglatToCoords 计算的数据来计算顶点的位置
|
||||||
|
const item1 = path1[i];
|
||||||
|
const item2 = path2[i];
|
||||||
|
line.extrude_gaode2(item1 as number[][], item2 as number[][]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 处理非高德2.0的几何体构建
|
||||||
|
let path = coordinates as number[][][] | number[][];
|
||||||
|
if (!Array.isArray(path[0][0])) {
|
||||||
|
path = [coordinates] as number[][][];
|
||||||
|
}
|
||||||
|
path.forEach((item: any) => {
|
||||||
|
line.extrude(item as number[][]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const linebuffer = line.complex;
|
const linebuffer = line.complex;
|
||||||
return {
|
return {
|
||||||
vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ]
|
vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ]
|
||||||
|
@ -199,6 +226,7 @@ export function LineArcTriangulation(feature: IEncodeFeature) {
|
||||||
coordinates[1][0],
|
coordinates[1][0],
|
||||||
coordinates[1][1],
|
coordinates[1][1],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (i !== segNum - 1) {
|
if (i !== segNum - 1) {
|
||||||
indexArray.push(
|
indexArray.push(
|
||||||
...[0, 1, 2, 1, 3, 2].map((v) => {
|
...[0, 1, 2, 1, 3, 2].map((v) => {
|
||||||
|
@ -214,6 +242,11 @@ export function LineArcTriangulation(feature: IEncodeFeature) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建热力图密度图的顶点
|
||||||
|
* @param feature
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function HeatmapTriangulation(feature: IEncodeFeature) {
|
export function HeatmapTriangulation(feature: IEncodeFeature) {
|
||||||
const coordinates = feature.coordinates as number[];
|
const coordinates = feature.coordinates as number[];
|
||||||
if (coordinates.length === 2) {
|
if (coordinates.length === 2) {
|
||||||
|
@ -256,6 +289,7 @@ function getGeometry(shape: ShapeType3D, needFlat = false): IExtrudeGeomety {
|
||||||
: geometryShape.cylinder();
|
: geometryShape.cylinder();
|
||||||
const geometry = extrude_PolygonNormal([path], needFlat);
|
const geometry = extrude_PolygonNormal([path], needFlat);
|
||||||
GeometryCache[shape] = geometry;
|
GeometryCache[shape] = geometry;
|
||||||
|
// console.log('geometry', geometry)
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,10 @@ export default class GridModel extends BaseModel {
|
||||||
},
|
},
|
||||||
size: 3,
|
size: 3,
|
||||||
update: (feature: IEncodeFeature, featureIdx: number) => {
|
update: (feature: IEncodeFeature, featureIdx: number) => {
|
||||||
const coordinates = feature.coordinates as number[];
|
// const coordinates = feature.coordinates as number[];
|
||||||
|
const coordinates = (feature.version === 'GAODE2.x'
|
||||||
|
? feature.originCoordinates
|
||||||
|
: feature.coordinates) as number[];
|
||||||
return [coordinates[0], coordinates[1], 0];
|
return [coordinates[0], coordinates[1], 0];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,11 +5,11 @@ import {
|
||||||
IModel,
|
IModel,
|
||||||
IModelUniform,
|
IModelUniform,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
|
import { aProjectFlat, Satistics, unProjectFlat } from '@antv/l7-utils';
|
||||||
import BaseModel from '../../core/BaseModel';
|
import BaseModel from '../../core/BaseModel';
|
||||||
import { PointExtrudeTriangulation } from '../../core/triangulation';
|
import { PointExtrudeTriangulation } from '../../core/triangulation';
|
||||||
import heatmapGrid3dVert from '../shaders/hexagon_3d_vert.glsl';
|
import heatmapGrid3dVert from '../shaders/hexagon_3d_vert.glsl';
|
||||||
import heatmapGridFrag from '../shaders/hexagon_frag.glsl';
|
import heatmapGridFrag from '../shaders/hexagon_frag.glsl';
|
||||||
|
|
||||||
interface IHeatMapLayerStyleOptions {
|
interface IHeatMapLayerStyleOptions {
|
||||||
opacity: number;
|
opacity: number;
|
||||||
coverage: number;
|
coverage: number;
|
||||||
|
@ -112,7 +112,11 @@ export default class Grid3DModel extends BaseModel {
|
||||||
},
|
},
|
||||||
size: 3,
|
size: 3,
|
||||||
update: (feature: IEncodeFeature, featureIdx: number) => {
|
update: (feature: IEncodeFeature, featureIdx: number) => {
|
||||||
const coordinates = feature.coordinates as number[];
|
const coordinates = (feature.version === 'GAODE2.x'
|
||||||
|
? feature.originCoordinates
|
||||||
|
: feature.coordinates) as number[];
|
||||||
|
// const coordinates = feature.coordinates as number[];
|
||||||
|
// const coordinates = feature.originCoordinates as number[];
|
||||||
return [coordinates[0], coordinates[1], 0];
|
return [coordinates[0], coordinates[1], 0];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
|
import { generateColorRamp, IColorRamp } from '@antv/l7-utils';
|
||||||
import { mat4 } from 'gl-matrix';
|
import { mat4 } from 'gl-matrix';
|
||||||
|
import { inject, injectable } from 'inversify';
|
||||||
import BaseModel from '../../core/BaseModel';
|
import BaseModel from '../../core/BaseModel';
|
||||||
import { HeatmapTriangulation } from '../../core/triangulation';
|
import { HeatmapTriangulation } from '../../core/triangulation';
|
||||||
import heatmap3DFrag from '../shaders/heatmap_3d_frag.glsl';
|
import heatmap3DFrag from '../shaders/heatmap_3d_frag.glsl';
|
||||||
|
@ -25,7 +26,7 @@ interface IHeatMapLayerStyleOptions {
|
||||||
angle: number;
|
angle: number;
|
||||||
rampColors: IColorRamp;
|
rampColors: IColorRamp;
|
||||||
}
|
}
|
||||||
|
@injectable()
|
||||||
export default class HeatMapModel extends BaseModel {
|
export default class HeatMapModel extends BaseModel {
|
||||||
protected texture: ITexture2D;
|
protected texture: ITexture2D;
|
||||||
protected colorTexture: ITexture2D;
|
protected colorTexture: ITexture2D;
|
||||||
|
@ -256,13 +257,20 @@ export default class HeatMapModel extends BaseModel {
|
||||||
const {
|
const {
|
||||||
opacity,
|
opacity,
|
||||||
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions;
|
||||||
const invert = mat4.invert(
|
|
||||||
mat4.create(),
|
// const invert = mat4.invert(
|
||||||
mat4.fromValues(
|
// mat4.create(),
|
||||||
// @ts-ignore
|
// mat4.fromValues(
|
||||||
...this.cameraService.getViewProjectionMatrixUncentered(),
|
// // @ts-ignore
|
||||||
),
|
// ...this.cameraService.getViewProjectionMatrixUncentered(),
|
||||||
) as mat4;
|
// ),
|
||||||
|
// ) as mat4;
|
||||||
|
const invert = mat4.create();
|
||||||
|
mat4.invert(
|
||||||
|
invert,
|
||||||
|
this.cameraService.getViewProjectionMatrixUncentered() as mat4,
|
||||||
|
);
|
||||||
|
|
||||||
this.colorModel.draw({
|
this.colorModel.draw({
|
||||||
uniforms: {
|
uniforms: {
|
||||||
u_opacity: opacity || 1.0,
|
u_opacity: opacity || 1.0,
|
||||||
|
|
|
@ -65,7 +65,12 @@ export default class HexagonModel extends BaseModel {
|
||||||
},
|
},
|
||||||
size: 3,
|
size: 3,
|
||||||
update: (feature: IEncodeFeature, featureIdx: number) => {
|
update: (feature: IEncodeFeature, featureIdx: number) => {
|
||||||
const coordinates = feature.coordinates as number[];
|
// const coordinates = (feature.verison==='GAODE2.x'?feature.originoordinates:feature.coordinates) as number[];
|
||||||
|
const coordinates = (feature.version === 'GAODE2.x'
|
||||||
|
? feature.originCoordinates
|
||||||
|
: feature.coordinates) as number[];
|
||||||
|
// const coordinates = feature.coordinates as number[];
|
||||||
|
// const coordinates = feature.originCoordinates as number[];
|
||||||
return [coordinates[0], coordinates[1], 0];
|
return [coordinates[0], coordinates[1], 0];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,8 +9,11 @@ uniform vec2 u_radius;
|
||||||
uniform float u_coverage: 0.9;
|
uniform float u_coverage: 0.9;
|
||||||
uniform float u_angle: 0;
|
uniform float u_angle: 0;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
|
||||||
|
uniform vec2 u_SceneCenterMKT;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "project"
|
#pragma include "project"
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
@ -20,9 +23,20 @@ void main() {
|
||||||
|
|
||||||
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
||||||
vec2 offset = a_Position.xy * u_radius * rotationMatrix * u_coverage ;
|
vec2 offset = a_Position.xy * u_radius * rotationMatrix * u_coverage ;
|
||||||
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
// vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
||||||
vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
// vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(project_pos);
|
// gl_Position = project_common_position_to_clipspace(project_pos);
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
||||||
|
vec2 customLnglat = customProject(lnglat) - u_SceneCenterMKT; // 将经纬度转换为高德2.0需要的平面坐标
|
||||||
|
vec4 project_pos = project_position(vec4(customLnglat, 0, 1.0));
|
||||||
|
gl_Position = u_Mvp * (project_pos);
|
||||||
|
} else {
|
||||||
|
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
||||||
|
vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
||||||
|
gl_Position = project_common_position_to_clipspace(project_pos);
|
||||||
|
}
|
||||||
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,5 +11,4 @@ void main(){
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
// gl_FragColor.a = color.a * smoothstep(0.1,0.2,intensity)* u_opacity;
|
// gl_FragColor.a = color.a * smoothstep(0.1,0.2,intensity)* u_opacity;
|
||||||
gl_FragColor.a = color.a * smoothstep(0.,0.1,intensity) * u_opacity;
|
gl_FragColor.a = color.a * smoothstep(0.,0.1,intensity) * u_opacity;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ uniform mat4 u_InverseViewProjectionMatrix;
|
||||||
uniform mat4 u_ViewProjectionMatrixUncentered;
|
uniform mat4 u_ViewProjectionMatrixUncentered;
|
||||||
varying float v_intensity;
|
varying float v_intensity;
|
||||||
|
|
||||||
|
|
||||||
vec2 toBezier(float t, vec2 P0, vec2 P1, vec2 P2, vec2 P3) {
|
vec2 toBezier(float t, vec2 P0, vec2 P1, vec2 P2, vec2 P3) {
|
||||||
float t2 = t * t;
|
float t2 = t * t;
|
||||||
float one_minus_t = 1.0 - t;
|
float one_minus_t = 1.0 - t;
|
||||||
|
@ -21,26 +22,25 @@ vec2 toBezier(float t, vec4 p){
|
||||||
void main() {
|
void main() {
|
||||||
v_texCoord = a_Uv;
|
v_texCoord = a_Uv;
|
||||||
|
|
||||||
vec2 pos =(a_Uv * vec2(2.0) - vec2(1.0));
|
vec2 pos = a_Uv * vec2(2.0) - vec2(1.0); // 将原本 0 -> 1 的 uv 转换为 -1 -> 1 的标准坐标空间(NDC)
|
||||||
|
|
||||||
|
vec4 p1 = vec4(pos, 0.0, 1.0); // x/y 平面上的点(z == 0)可以认为是三维上的点被投影到平面后的点
|
||||||
|
vec4 p2 = vec4(pos, 1.0, 1.0); // 平行于x/y平面、z==1 的平面上的点
|
||||||
|
|
||||||
vec4 p1 = vec4(pos, 0.0, 1.0);
|
vec4 inverseP1 = u_InverseViewProjectionMatrix * p1; // 根据视图投影矩阵的逆矩阵平面上的反算出三维空间中的点(p1平面上的点)
|
||||||
vec4 p2 = vec4(pos, 1.0, 1.0);
|
|
||||||
|
|
||||||
vec4 inverseP1 = u_InverseViewProjectionMatrix * p1;
|
|
||||||
vec4 inverseP2 = u_InverseViewProjectionMatrix * p2;
|
vec4 inverseP2 = u_InverseViewProjectionMatrix * p2;
|
||||||
|
|
||||||
inverseP1 = inverseP1 / inverseP1.w;
|
inverseP1 = inverseP1 / inverseP1.w; // 归一化操作(归一化后为世界坐标)
|
||||||
inverseP2 = inverseP2 / inverseP2.w;
|
inverseP2 = inverseP2 / inverseP2.w;
|
||||||
|
|
||||||
float zPos = (0.0 - inverseP1.z) / (inverseP2.z - inverseP1.z);
|
float zPos = (0.0 - inverseP1.z) / (inverseP2.z - inverseP1.z); // ??
|
||||||
vec4 position = inverseP1 + zPos * (inverseP2 - inverseP1);
|
vec4 position = inverseP1 + zPos * (inverseP2 - inverseP1);
|
||||||
|
|
||||||
vec4 b= vec4(0.5000, 0, 1, 0.5000);
|
vec4 b= vec4(0.5000, 0.0, 1.0, 0.5000);
|
||||||
float fh;
|
float fh;
|
||||||
|
|
||||||
v_intensity = texture2D(u_texture, v_texCoord).r;
|
v_intensity = texture2D(u_texture, v_texCoord).r;
|
||||||
fh = toBezier(v_intensity, b).y;
|
fh = toBezier(v_intensity, b).y;
|
||||||
gl_Position = u_ViewProjectionMatrixUncentered * vec4(position.xy, fh * project_pixel(50.), 1.0);
|
gl_Position = u_ViewProjectionMatrixUncentered * vec4(position.xy, fh * project_pixel(50.), 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ uniform float u_radius;
|
||||||
varying vec2 v_extrude;
|
varying vec2 v_extrude;
|
||||||
varying float v_weight;
|
varying float v_weight;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
#define GAUSS_COEF 0.3989422804014327
|
#define GAUSS_COEF 0.3989422804014327
|
||||||
|
|
||||||
|
@ -24,5 +25,11 @@ void main(){
|
||||||
vec2 offset = project_pixel(v_extrude * u_radius);
|
vec2 offset = project_pixel(v_extrude * u_radius);
|
||||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,21 +11,54 @@ uniform vec2 u_radius;
|
||||||
uniform float u_coverage: 0.9;
|
uniform float u_coverage: 0.9;
|
||||||
uniform float u_angle: 0;
|
uniform float u_angle: 0;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
|
||||||
|
uniform vec2 u_SceneCenterMKT;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "project"
|
#pragma include "project"
|
||||||
#pragma include "light"
|
#pragma include "light"
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
||||||
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage));
|
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage));
|
||||||
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
// vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 实际的经纬度
|
||||||
vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0));
|
// vec2 lnglat = (a_Pos.xy + offset);
|
||||||
float lightWeight = calc_lighting(project_pos);
|
// vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0));
|
||||||
v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
|
// gl_Position = project_common_position_to_clipspace(project_pos);
|
||||||
|
// float lightWeight = calc_lighting(project_pos);
|
||||||
|
// v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
// vec2 lnglat = (a_Pos.xy + offset);
|
||||||
|
// vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0));
|
||||||
|
|
||||||
|
// float lightWeight = calc_lighting(project_pos);
|
||||||
|
// v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
|
||||||
|
|
||||||
|
// gl_Position = u_Mvp * vec4(lnglat , a_Position.z * a_Size, 1.0);
|
||||||
|
vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 经纬度
|
||||||
|
vec2 customLnglat = customProject(lnglat) - u_SceneCenterMKT; // 将经纬度转换为高德2.0需要的平面坐标
|
||||||
|
vec4 project_pos = project_position(vec4(customLnglat, a_Position.z * a_Size, 1.0));
|
||||||
|
|
||||||
|
float lightWeight = calc_lighting(project_pos);
|
||||||
|
v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
|
||||||
|
|
||||||
|
gl_Position = u_Mvp * vec4(customLnglat , a_Position.z * a_Size, 1.0);
|
||||||
|
} else {
|
||||||
|
vec2 lnglat = unProjectFlat(a_Pos.xy + offset); // 实际的经纬度
|
||||||
|
vec4 project_pos = project_position(vec4(lnglat, a_Position.z * a_Size, 1.0));
|
||||||
|
|
||||||
|
float lightWeight = calc_lighting(project_pos);
|
||||||
|
v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
|
||||||
|
|
||||||
|
gl_Position = project_common_position_to_clipspace(project_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(project_pos);
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,11 @@ uniform vec2 u_radius;
|
||||||
uniform float u_coverage: 0.9;
|
uniform float u_coverage: 0.9;
|
||||||
uniform float u_angle: 0;
|
uniform float u_angle: 0;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
|
||||||
|
uniform vec2 u_SceneCenterMKT;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "project"
|
#pragma include "project"
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
@ -21,7 +24,18 @@ void main() {
|
||||||
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
|
||||||
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage));
|
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage));
|
||||||
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
vec2 lnglat = unProjectFlat(a_Pos.xy + offset);
|
||||||
vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0., 1.0));
|
// vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0., 1.0));
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
// gl_Position = u_Mvp * (vec4(project_pos.xy, 0., 1.0));
|
||||||
|
// gl_Position = u_Mvp * (vec4(a_Pos.xy + offset, 0., 1.0));
|
||||||
|
vec2 customLnglat = customProject(lnglat) - u_SceneCenterMKT;
|
||||||
|
vec4 project_pos = project_position(vec4(customLnglat, 0, 1.0));
|
||||||
|
gl_Position = u_Mvp * vec4(project_pos.xy, 0.0, 1.0);
|
||||||
|
} else {
|
||||||
|
vec4 project_pos = project_position(vec4(lnglat, 0, 1.0));
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, 0., 1.0));
|
||||||
|
}
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
attribute vec2 a_Uv;
|
attribute vec2 a_Uv;
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
|
@ -7,5 +8,10 @@ varying vec2 v_texCoord;
|
||||||
void main() {
|
void main() {
|
||||||
v_texCoord = a_Uv;
|
v_texCoord = a_Uv;
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xy,0., 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ export default class ArcModel extends BaseModel {
|
||||||
opacity,
|
opacity,
|
||||||
lineType = 'solid',
|
lineType = 'solid',
|
||||||
dashArray = [10, 5],
|
dashArray = [10, 5],
|
||||||
|
forward = true,
|
||||||
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
||||||
if (dashArray.length === 2) {
|
if (dashArray.length === 2) {
|
||||||
dashArray.push(0, 0);
|
dashArray.push(0, 0);
|
||||||
|
@ -33,6 +34,7 @@ export default class ArcModel extends BaseModel {
|
||||||
u_line_type: lineStyleObj[lineType || 'solid'],
|
u_line_type: lineStyleObj[lineType || 'solid'],
|
||||||
u_dash_array: dashArray,
|
u_dash_array: dashArray,
|
||||||
u_blur: 0.9,
|
u_blur: 0.9,
|
||||||
|
u_lineDir: forward ? 1 : -1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,11 @@ import {
|
||||||
gl,
|
gl,
|
||||||
IAnimateOption,
|
IAnimateOption,
|
||||||
IEncodeFeature,
|
IEncodeFeature,
|
||||||
|
IImage,
|
||||||
ILayerConfig,
|
ILayerConfig,
|
||||||
IModel,
|
IModel,
|
||||||
IModelUniform,
|
IModelUniform,
|
||||||
|
ITexture2D,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
|
|
||||||
import BaseModel from '../../core/BaseModel';
|
import BaseModel from '../../core/BaseModel';
|
||||||
|
@ -18,19 +20,32 @@ const lineStyleObj: { [key: string]: number } = {
|
||||||
dash: 1.0,
|
dash: 1.0,
|
||||||
};
|
};
|
||||||
export default class LineModel extends BaseModel {
|
export default class LineModel extends BaseModel {
|
||||||
|
protected texture: ITexture2D;
|
||||||
public getUninforms(): IModelUniform {
|
public getUninforms(): IModelUniform {
|
||||||
const {
|
const {
|
||||||
opacity,
|
opacity,
|
||||||
lineType = 'solid',
|
lineType = 'solid',
|
||||||
dashArray = [10, 5, 0, 0],
|
dashArray = [10, 5, 0, 0],
|
||||||
|
lineTexture = false,
|
||||||
|
iconStep = 100,
|
||||||
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
||||||
if (dashArray.length === 2) {
|
if (dashArray.length === 2) {
|
||||||
dashArray.push(0, 0);
|
dashArray.push(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.rendererService.getDirty()) {
|
||||||
|
this.texture.bind();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
u_opacity: opacity || 1.0,
|
u_opacity: opacity || 1.0,
|
||||||
u_line_type: lineStyleObj[lineType],
|
u_line_type: lineStyleObj[lineType],
|
||||||
u_dash_array: dashArray,
|
u_dash_array: dashArray,
|
||||||
|
|
||||||
|
u_texture: this.texture, // 贴图
|
||||||
|
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
|
||||||
|
u_icon_step: iconStep,
|
||||||
|
u_textSize: [1024, this.iconService.canvasHeight || 128],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public getAnimateUniforms(): IModelUniform {
|
public getAnimateUniforms(): IModelUniform {
|
||||||
|
@ -42,9 +57,33 @@ export default class LineModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public initModels(): IModel[] {
|
public initModels(): IModel[] {
|
||||||
|
// const { createTexture2D } = this.rendererService;
|
||||||
|
// this.texture = createTexture2D({
|
||||||
|
// height: 0,
|
||||||
|
// width: 0,
|
||||||
|
// });
|
||||||
|
// let url = 'https://gw-office.alipayobjects.com/bmw-prod/e91c3630-b79e-45a3-a2b9-feee4b4ccd41.svg'
|
||||||
|
// this.loadImage(url).then((img) => {
|
||||||
|
// this.texture = createTexture2D({
|
||||||
|
// data: img as HTMLImageElement,
|
||||||
|
// width: (img as HTMLImageElement).width,
|
||||||
|
// height: (img as HTMLImageElement).height,
|
||||||
|
// });
|
||||||
|
// this.layerService.renderLayers();
|
||||||
|
// })
|
||||||
|
this.updateTexture();
|
||||||
|
this.iconService.on('imageUpdate', this.updateTexture);
|
||||||
|
|
||||||
return this.buildModels();
|
return this.buildModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearModels() {
|
||||||
|
if (this.texture) {
|
||||||
|
this.texture.destroy();
|
||||||
|
}
|
||||||
|
this.iconService.off('imageUpdate', this.updateTexture);
|
||||||
|
}
|
||||||
|
|
||||||
public buildModels(): IModel[] {
|
public buildModels(): IModel[] {
|
||||||
return [
|
return [
|
||||||
this.layer.buildLayerModel({
|
this.layer.buildLayerModel({
|
||||||
|
@ -182,5 +221,68 @@ export default class LineModel extends BaseModel {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.styleAttributeService.registerStyleAttribute({
|
||||||
|
name: 'uv',
|
||||||
|
type: AttributeType.Attribute,
|
||||||
|
descriptor: {
|
||||||
|
name: 'a_iconMapUV',
|
||||||
|
buffer: {
|
||||||
|
// give the WebGL driver a hint that this buffer may change
|
||||||
|
usage: gl.DYNAMIC_DRAW,
|
||||||
|
data: [],
|
||||||
|
type: gl.FLOAT,
|
||||||
|
},
|
||||||
|
size: 2,
|
||||||
|
update: (
|
||||||
|
feature: IEncodeFeature,
|
||||||
|
featureIdx: number,
|
||||||
|
vertex: number[],
|
||||||
|
attributeIdx: number,
|
||||||
|
) => {
|
||||||
|
const iconMap = this.iconService.getIconMap();
|
||||||
|
const { texture } = feature;
|
||||||
|
const { x, y } = iconMap[texture as string] || { x: 0, y: 0 };
|
||||||
|
return [x, y];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadImage(url: IImage) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (url instanceof HTMLImageElement) {
|
||||||
|
resolve(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const image = new Image();
|
||||||
|
image.crossOrigin = 'anonymous';
|
||||||
|
image.onload = () => {
|
||||||
|
resolve(image);
|
||||||
|
};
|
||||||
|
image.onerror = () => {
|
||||||
|
reject(new Error('Could not load image at ' + url));
|
||||||
|
};
|
||||||
|
image.src = url instanceof File ? URL.createObjectURL(url) : url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTexture = () => {
|
||||||
|
const { createTexture2D } = this.rendererService;
|
||||||
|
if (this.texture) {
|
||||||
|
this.texture.update({
|
||||||
|
data: this.iconService.getCanvas(),
|
||||||
|
});
|
||||||
|
this.layer.render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.texture = createTexture2D({
|
||||||
|
data: this.iconService.getCanvas(),
|
||||||
|
mag: gl.NEAREST,
|
||||||
|
min: gl.NEAREST,
|
||||||
|
premultiplyAlpha: false,
|
||||||
|
width: 1024,
|
||||||
|
height: this.iconService.canvasHeight || 128,
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ attribute vec4 a_Color;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform float segmentNumber;
|
uniform float segmentNumber;
|
||||||
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -85,6 +86,11 @@ void main() {
|
||||||
vec2 offset = getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y);
|
vec2 offset = getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y);
|
||||||
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + project_pixel(offset), curr.z, 1.0));
|
||||||
|
}
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,16 @@ void main() {
|
||||||
alpha = smoothstep(0., 1., alpha);
|
alpha = smoothstep(0., 1., alpha);
|
||||||
gl_FragColor.a *= alpha;
|
gl_FragColor.a *= alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if(u_line_texture == LineTexture) { // while load texture
|
||||||
|
// //v_u; // 水平
|
||||||
|
// float v = length(v_offset)/(v_a); // 横向
|
||||||
|
// vec2 uv= v_iconMapUV / u_textSize + vec2(v_u, v) / u_textSize * 64.;
|
||||||
|
// // gl_FragColor = vec4(v_u, v, 0.0, 1.0);
|
||||||
|
// // gl_FragColor = vec4(1.0, 0.0, 0.0, v_u);
|
||||||
|
// gl_FragColor = filterColor(gl_FragColor + texture2D(u_texture, uv));
|
||||||
|
// } else {
|
||||||
|
// gl_FragColor = filterColor(gl_FragColor);
|
||||||
|
// }
|
||||||
gl_FragColor = filterColor(gl_FragColor);
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ attribute vec3 a_Position;
|
||||||
attribute vec4 a_Instance;
|
attribute vec4 a_Instance;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform float segmentNumber;
|
uniform float segmentNumber;
|
||||||
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -68,21 +69,44 @@ float getAngularDist (vec2 source, vec2 target) {
|
||||||
sin_half_delta.x * sin_half_delta.x;
|
sin_half_delta.x * sin_half_delta.x;
|
||||||
return 2.0 * atan(sqrt(a), sqrt(1.0 - a));
|
return 2.0 * atan(sqrt(a), sqrt(1.0 - a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 midPoint(vec2 source, vec2 target) {
|
||||||
|
vec2 center = target - source;
|
||||||
|
float r = length(center);
|
||||||
|
float theta = atan(center.y, center.x);
|
||||||
|
float thetaOffset = 0.314;
|
||||||
|
float r2 = r / 2.0 / cos(thetaOffset);
|
||||||
|
float theta2 = theta + thetaOffset;
|
||||||
|
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
float bezier3(vec3 arr, float t) {
|
||||||
|
float ut = 1. - t;
|
||||||
|
return (arr.x * ut + arr.y * t) * ut + (arr.y * ut + arr.z * t) * t;
|
||||||
|
}
|
||||||
|
|
||||||
vec2 interpolate (vec2 source, vec2 target, float angularDist, float t) {
|
vec2 interpolate (vec2 source, vec2 target, float angularDist, float t) {
|
||||||
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
|
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
|
||||||
if(abs(angularDist - PI) < 0.001) {
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
return (1.0 - t) * source + t * target;
|
vec2 mid = midPoint(source, target);
|
||||||
|
vec3 x = vec3(source.x, mid.x, target.x);
|
||||||
|
vec3 y = vec3(source.y, mid.y, target.y);
|
||||||
|
return vec2(bezier3(x ,t), bezier3(y,t));
|
||||||
|
}else {
|
||||||
|
if(abs(angularDist - PI) < 0.001) {
|
||||||
|
return (1.0 - t) * source + t * target;
|
||||||
|
}
|
||||||
|
float a = sin((1.0 - t) * angularDist) / sin(angularDist);
|
||||||
|
float b = sin(t * angularDist) / sin(angularDist);
|
||||||
|
vec2 sin_source = sin(source);
|
||||||
|
vec2 cos_source = cos(source);
|
||||||
|
vec2 sin_target = sin(target);
|
||||||
|
vec2 cos_target = cos(target);
|
||||||
|
float x = a * cos_source.y * cos_source.x + b * cos_target.y * cos_target.x;
|
||||||
|
float y = a * cos_source.y * sin_source.x + b * cos_target.y * sin_target.x;
|
||||||
|
float z = a * sin_source.y + b * sin_target.y;
|
||||||
|
return vec2(atan(y, x), atan(z, sqrt(x * x + y * y)));
|
||||||
}
|
}
|
||||||
float a = sin((1.0 - t) * angularDist) / sin(angularDist);
|
|
||||||
float b = sin(t * angularDist) / sin(angularDist);
|
|
||||||
vec2 sin_source = sin(source);
|
|
||||||
vec2 cos_source = cos(source);
|
|
||||||
vec2 sin_target = sin(target);
|
|
||||||
vec2 cos_target = cos(target);
|
|
||||||
float x = a * cos_source.y * cos_source.x + b * cos_target.y * cos_target.x;
|
|
||||||
float y = a * cos_source.y * sin_source.x + b * cos_target.y * sin_target.x;
|
|
||||||
float z = a * sin_source.y + b * sin_target.y;
|
|
||||||
return vec2(atan(y, x), atan(z, sqrt(x * x + y * y)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -108,7 +132,13 @@ void main() {
|
||||||
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
||||||
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
|
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
|
||||||
// vec4 project_pos = project_position(vec4(curr.xy, 0, 1.0));
|
// vec4 project_pos = project_position(vec4(curr.xy, 0, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, curr.z, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, curr.z, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(curr.xy + offset, curr.z, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, curr.z, 1.0));
|
||||||
|
}
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#define LineTypeSolid 0.0
|
#define LineTypeSolid 0.0
|
||||||
#define LineTypeDash 1.0
|
#define LineTypeDash 1.0
|
||||||
#define Animate 0.0
|
#define Animate 0.0
|
||||||
|
// #define LineTexture 1.0
|
||||||
attribute vec4 a_Color;
|
attribute vec4 a_Color;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
attribute vec4 a_Instance;
|
attribute vec4 a_Instance;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform float segmentNumber;
|
uniform float segmentNumber;
|
||||||
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -14,7 +16,17 @@ varying vec2 v_normal;
|
||||||
varying float v_distance_ratio;
|
varying float v_distance_ratio;
|
||||||
uniform float u_line_type: 0.0;
|
uniform float u_line_type: 0.0;
|
||||||
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
|
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
|
||||||
|
uniform float u_lineDir: 1.0;
|
||||||
varying vec4 v_dash_array;
|
varying vec4 v_dash_array;
|
||||||
|
|
||||||
|
// uniform float u_icon_step: 100;
|
||||||
|
// uniform float u_line_texture;
|
||||||
|
// varying float v_u;
|
||||||
|
// varying vec2 v_offset;
|
||||||
|
// varying float v_a;
|
||||||
|
// attribute vec2 a_iconMapUV;
|
||||||
|
// varying vec2 v_iconMapUV;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "project"
|
#pragma include "project"
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
@ -31,7 +43,14 @@ vec2 midPoint(vec2 source, vec2 target) {
|
||||||
float r2 = r / 2.0 / cos(thetaOffset);
|
float r2 = r / 2.0 / cos(thetaOffset);
|
||||||
float theta2 = theta + thetaOffset;
|
float theta2 = theta + thetaOffset;
|
||||||
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
|
vec2 mid = vec2(r2*cos(theta2) + source.x, r2*sin(theta2) + source.y);
|
||||||
return mid;
|
if(u_lineDir == 1.0) { // 正向
|
||||||
|
return mid;
|
||||||
|
} else { // 逆向
|
||||||
|
// (mid + vmin)/2 = (s + t)/2
|
||||||
|
vec2 vmid = source + target - mid;
|
||||||
|
return vmid;
|
||||||
|
}
|
||||||
|
// return mid;
|
||||||
}
|
}
|
||||||
float getSegmentRatio(float index) {
|
float getSegmentRatio(float index) {
|
||||||
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.));
|
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.));
|
||||||
|
@ -61,10 +80,12 @@ vec2 getNormal(vec2 line_clipspace, float offset_direction) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
v_color = a_Color;
|
v_color = a_Color;
|
||||||
|
|
||||||
vec2 source = a_Instance.rg;
|
vec2 source = a_Instance.rg;
|
||||||
vec2 target = a_Instance.ba;
|
vec2 target = a_Instance.ba;
|
||||||
float segmentIndex = a_Position.x;
|
float segmentIndex = a_Position.x;
|
||||||
float segmentRatio = getSegmentRatio(segmentIndex);
|
float segmentRatio = getSegmentRatio(segmentIndex);
|
||||||
|
|
||||||
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
|
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
|
||||||
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
|
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);
|
||||||
if(u_line_type == LineTypeDash) {
|
if(u_line_type == LineTypeDash) {
|
||||||
|
@ -74,12 +95,40 @@ void main() {
|
||||||
}
|
}
|
||||||
if(u_aimate.x == Animate) {
|
if(u_aimate.x == Animate) {
|
||||||
v_distance_ratio = segmentIndex / segmentNumber;
|
v_distance_ratio = segmentIndex / segmentNumber;
|
||||||
|
if(u_lineDir != 1.0) {
|
||||||
|
v_distance_ratio = 1.0 - v_distance_ratio;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio), 0.0, 1.0));
|
vec4 curr = project_position(vec4(interpolate(source, target, segmentRatio), 0.0, 1.0));
|
||||||
vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio), 0.0, 1.0));
|
vec4 next = project_position(vec4(interpolate(source, target, nextSegmentRatio), 0.0, 1.0));
|
||||||
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
v_normal = getNormal((next.xy - curr.xy) * indexDir, a_Position.y);
|
||||||
|
|
||||||
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
|
vec2 offset = project_pixel(getExtrusionOffset((next.xy - curr.xy) * indexDir, a_Position.y));
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
|
// if(LineTexture == u_line_texture) { // 开启贴图模式
|
||||||
|
// v_iconMapUV = a_iconMapUV;
|
||||||
|
|
||||||
|
// float arctotal_Distance = length(source - target);
|
||||||
|
// float pixelLen = project_pixel(u_icon_step);
|
||||||
|
// v_u = fract(segmentRatio * (floor(arctotal_Distance/pixelLen)));
|
||||||
|
// // v_u = fract(segmentIndex/(segmentNumber) * (2.0));
|
||||||
|
// // v_u = fract(segmentIndex/(segmentNumber - 1.0) * 1.0 + 0.3);
|
||||||
|
// // v_u = fract(mod(1.0- v_distance_ratio, 0.2)* (1.0/ 0.5));
|
||||||
|
// // v_u = fract(clamp(v_u, 0.0, 1.0)*2.0);
|
||||||
|
// // v_u = fract(((segmentIndex * indexDir) / (segmentNumber - 1.)) * (floor(arctotal_Distance/pixelLen)));
|
||||||
|
// // float s = 6.0;
|
||||||
|
// // float l = segmentNumber/s;
|
||||||
|
// // v_u = mod(segmentIndex, l) / (segmentNumber/s);
|
||||||
|
// v_a = project_pixel(a_Size);
|
||||||
|
// v_offset = offset + offset * sign(a_Position.y);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(curr.xy + offset, 0, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(curr.xy + offset, 0, 1.0));
|
||||||
|
}
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
#define LineTypeSolid 0.0
|
#define LineTypeSolid 0.0
|
||||||
#define LineTypeDash 1.0
|
#define LineTypeDash 1.0
|
||||||
#define Animate 0.0
|
#define Animate 0.0
|
||||||
|
#define LineTexture 1.0
|
||||||
uniform float u_blur : 0.99;
|
uniform float u_blur : 0.99;
|
||||||
uniform float u_line_type: 0.0;
|
uniform float u_line_type: 0.0;
|
||||||
uniform float u_opacity : 1.0;
|
uniform float u_opacity : 1.0;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_normal;
|
varying vec2 v_normal;
|
||||||
|
|
||||||
|
// line texture
|
||||||
|
uniform float u_line_texture;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
uniform vec2 u_textSize;
|
||||||
|
|
||||||
// dash
|
// dash
|
||||||
uniform float u_dash_offset : 0.0;
|
uniform float u_dash_offset : 0.0;
|
||||||
|
@ -15,19 +20,27 @@ varying float v_distance_ratio;
|
||||||
varying vec4 v_dash_array;
|
varying vec4 v_dash_array;
|
||||||
varying float v_side;
|
varying float v_side;
|
||||||
|
|
||||||
|
varying float v_distance;
|
||||||
|
varying vec2 v_offset;
|
||||||
|
varying float v_a;
|
||||||
|
varying float v_pixelLen;
|
||||||
|
varying vec2 v_iconMapUV;
|
||||||
|
varying float v_strokeWidth;
|
||||||
|
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
|
||||||
uniform float u_time;
|
uniform float u_time;
|
||||||
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; // 控制运动
|
||||||
// [animate, duration, interval, trailLength],
|
// [animate, duration, interval, trailLength],
|
||||||
void main() {
|
void main() {
|
||||||
|
float animateSpeed = 0.0; // 运动速度
|
||||||
gl_FragColor = v_color;
|
gl_FragColor = v_color;
|
||||||
// anti-alias
|
// anti-alias
|
||||||
// float blur = 1.0 - smoothstep(u_blur, 1., length(v_normal.xy));
|
// float blur = 1.0 - smoothstep(u_blur, 1., length(v_normal.xy));
|
||||||
gl_FragColor.a *= u_opacity;
|
gl_FragColor.a *= u_opacity; // 全局透明度
|
||||||
if(u_aimate.x == Animate) {
|
if(u_aimate.x == Animate) {
|
||||||
float alpha =1.0 - fract( mod(1.0- v_distance_ratio, u_aimate.z)* (1.0/ u_aimate.z) + u_time / u_aimate.y);
|
animateSpeed = u_time / u_aimate.y;
|
||||||
|
float alpha =1.0 - fract( mod(1.0- v_distance_ratio, u_aimate.z)* (1.0/ u_aimate.z) + animateSpeed);
|
||||||
alpha = (alpha + u_aimate.w -1.0) / u_aimate.w;
|
alpha = (alpha + u_aimate.w -1.0) / u_aimate.w;
|
||||||
alpha = smoothstep(0., 1., alpha);
|
alpha = smoothstep(0., 1., alpha);
|
||||||
gl_FragColor.a *= alpha;
|
gl_FragColor.a *= alpha;
|
||||||
|
@ -43,5 +56,28 @@ void main() {
|
||||||
// gl_FragColor.a *=(1.0- step(v_dash_array.x, mod(v_distance_ratio, dashLength)));
|
// gl_FragColor.a *=(1.0- step(v_dash_array.x, mod(v_distance_ratio, dashLength)));
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = filterColor(gl_FragColor);
|
if(u_line_texture == LineTexture) { // while load texture
|
||||||
|
float u = fract(mod(v_distance, v_pixelLen)/v_pixelLen - animateSpeed);
|
||||||
|
float v = length(v_offset)/(v_a*2.0);
|
||||||
|
v = max(smoothstep(0.95, 1.0, v), v);
|
||||||
|
vec2 uv= v_iconMapUV / u_textSize + vec2(u, v) / u_textSize * 64.;
|
||||||
|
// gl_FragColor = filterColor(gl_FragColor + texture2D(u_texture, vec2(u, v)));
|
||||||
|
gl_FragColor = filterColor(gl_FragColor + texture2D(u_texture, uv));
|
||||||
|
} else {
|
||||||
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
|
}
|
||||||
|
// gl_FragColor = filterColor(vec4(1.0, 0.0, 0.0, 1.0));
|
||||||
|
|
||||||
|
// float r = max(smoothstep( 0.95, 1.0, v_strokeWidth/(v_a*2.0)), v_strokeWidth/(v_a*2.0));
|
||||||
|
// if(rV < r || rV > 1.0 - r) {
|
||||||
|
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
// }
|
||||||
|
// float v = length(v_offset)/(v_a*2.0);
|
||||||
|
// if(v > 0.9) {
|
||||||
|
// gl_FragColor = vec4(0.17647, 0.43921568, 0.2, 1.0);
|
||||||
|
// } else if(v < 0.1) {
|
||||||
|
// gl_FragColor = vec4(0.17647, 0.43921568, 0.2, 1.0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// gl_FragColor = filterColor(gl_FragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,18 @@ attribute vec2 a_Size;
|
||||||
attribute vec3 a_Normal;
|
attribute vec3 a_Normal;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
|
|
||||||
|
attribute vec2 a_iconMapUV;
|
||||||
|
|
||||||
// dash line
|
// dash line
|
||||||
attribute float a_Total_Distance;
|
attribute float a_Total_Distance;
|
||||||
attribute float a_Distance;
|
attribute float a_Distance;
|
||||||
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform float u_line_type: 0.0;
|
uniform float u_line_type: 0.0;
|
||||||
uniform vec4 u_dash_array: [10.0, 5.,0, 0];
|
uniform vec4 u_dash_array: [10.0, 5., 0, 0];
|
||||||
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ];
|
||||||
|
uniform float u_icon_step: 100;
|
||||||
|
|
||||||
#pragma include "projection"
|
#pragma include "projection"
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
@ -26,23 +30,52 @@ varying vec2 v_normal;
|
||||||
varying float v_distance_ratio;
|
varying float v_distance_ratio;
|
||||||
varying float v_side;
|
varying float v_side;
|
||||||
|
|
||||||
|
varying float v_distance;
|
||||||
|
varying vec2 v_offset;
|
||||||
|
varying float v_size;
|
||||||
|
varying float v_a;
|
||||||
|
varying float v_pixelLen;
|
||||||
|
varying vec2 v_iconMapUV;
|
||||||
|
// varying float v_strokeWidth;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
|
v_iconMapUV = a_iconMapUV;
|
||||||
|
v_distance = a_Distance;
|
||||||
|
v_pixelLen = project_pixel(u_icon_step);
|
||||||
|
|
||||||
if(u_line_type == LineTypeDash) {
|
if(u_line_type == LineTypeDash) {
|
||||||
v_distance_ratio = a_Distance / a_Total_Distance;
|
v_distance_ratio = a_Distance / a_Total_Distance;
|
||||||
|
// v_distance_ratio = 0.01;
|
||||||
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / a_Total_Distance;
|
v_dash_array = pow(2.0, 20.0 - u_Zoom) * u_dash_array / a_Total_Distance;
|
||||||
}
|
}
|
||||||
if(u_aimate.x == Animate) {
|
if(u_aimate.x == Animate) {
|
||||||
v_distance_ratio = a_Distance / a_Total_Distance;
|
v_distance_ratio = a_Distance / a_Total_Distance;
|
||||||
}
|
}
|
||||||
v_normal = vec2(reverse_offset_normal(a_Normal) * sign(a_Miter));
|
v_normal = vec2(reverse_offset_normal(a_Normal) * sign(a_Miter));
|
||||||
|
|
||||||
|
|
||||||
v_color = a_Color;
|
v_color = a_Color;
|
||||||
|
v_a = project_pixel(a_Size.x);
|
||||||
|
|
||||||
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
|
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
|
||||||
|
|
||||||
vec2 offset = project_pixel(size.xy);
|
vec2 offset = project_pixel(size.xy);
|
||||||
|
// v_strokeWidth = project_pixel(2.0);
|
||||||
|
|
||||||
|
v_offset = offset + offset * sign(a_Miter);
|
||||||
|
|
||||||
v_side = a_Miter * a_Size.x;
|
v_side = a_Miter * a_Size.x;
|
||||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0));
|
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
// gl_Position = u_Mvp * (vec4(project_pos.xy + offset, a_Size.y, 1.0));
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xy + offset, a_Size.y / 10.0, 1.0)); // 额外除 10.0 是为了和gaode1.x的高度兼容
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
import {
|
import {
|
||||||
IEncodeFeature,
|
IEncodeFeature,
|
||||||
|
IFontService,
|
||||||
IGlobalConfigService,
|
IGlobalConfigService,
|
||||||
ILayer,
|
ILayer,
|
||||||
ILayerPlugin,
|
ILayerPlugin,
|
||||||
|
ILngLat,
|
||||||
ILogService,
|
ILogService,
|
||||||
|
IMapService,
|
||||||
IParseDataItem,
|
IParseDataItem,
|
||||||
IStyleAttribute,
|
IStyleAttribute,
|
||||||
IStyleAttributeService,
|
IStyleAttributeService,
|
||||||
TYPES,
|
TYPES,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { rgb2arr } from '@antv/l7-utils';
|
import { rgb2arr, unProjectFlat } from '@antv/l7-utils';
|
||||||
import { inject, injectable } from 'inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class DataMappingPlugin implements ILayerPlugin {
|
export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
|
@ -20,6 +24,12 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
@inject(TYPES.ILogService)
|
@inject(TYPES.ILogService)
|
||||||
private readonly logger: ILogService;
|
private readonly logger: ILogService;
|
||||||
|
|
||||||
|
@inject(TYPES.IMapService)
|
||||||
|
private readonly mapService: IMapService;
|
||||||
|
|
||||||
|
@inject(TYPES.IFontService)
|
||||||
|
private readonly fontService: IFontService;
|
||||||
|
|
||||||
public apply(
|
public apply(
|
||||||
layer: ILayer,
|
layer: ILayer,
|
||||||
{
|
{
|
||||||
|
@ -99,13 +109,15 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
data: IParseDataItem[],
|
data: IParseDataItem[],
|
||||||
predata?: IEncodeFeature[],
|
predata?: IEncodeFeature[],
|
||||||
): IEncodeFeature[] {
|
): IEncodeFeature[] {
|
||||||
return data.map((record: IParseDataItem, i) => {
|
// console.log('data', data[0])
|
||||||
|
const mappedData = data.map((record: IParseDataItem, i) => {
|
||||||
const preRecord = predata ? predata[i] : {};
|
const preRecord = predata ? predata[i] : {};
|
||||||
const encodeRecord: IEncodeFeature = {
|
const encodeRecord: IEncodeFeature = {
|
||||||
id: record._id,
|
id: record._id,
|
||||||
coordinates: record.coordinates,
|
coordinates: record.coordinates,
|
||||||
...preRecord,
|
...preRecord,
|
||||||
};
|
};
|
||||||
|
|
||||||
attributes
|
attributes
|
||||||
.filter((attribute) => attribute.scale !== undefined)
|
.filter((attribute) => attribute.scale !== undefined)
|
||||||
.forEach((attribute: IStyleAttribute) => {
|
.forEach((attribute: IStyleAttribute) => {
|
||||||
|
@ -121,9 +133,44 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
encodeRecord[attribute.name] =
|
encodeRecord[attribute.name] =
|
||||||
Array.isArray(values) && values.length === 1 ? values[0] : values;
|
Array.isArray(values) && values.length === 1 ? values[0] : values;
|
||||||
|
|
||||||
|
// 增加对 layer/text/iconfont unicode 映射的解析
|
||||||
|
if (attribute.name === 'shape') {
|
||||||
|
encodeRecord.shape = this.fontService.getIconFontKey(
|
||||||
|
encodeRecord[attribute.name] as string,
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return encodeRecord;
|
return encodeRecord;
|
||||||
}) as IEncodeFeature[];
|
}) as IEncodeFeature[];
|
||||||
|
// console.log('mappedData', mappedData[0])
|
||||||
|
|
||||||
|
// 根据地图的类型判断是否需要对点位数据进行处理, 若是高德2.0则需要对坐标进行相对偏移
|
||||||
|
if (mappedData.length > 0 && this.mapService.version === 'GAODE2.x') {
|
||||||
|
if (typeof mappedData[0].coordinates[0] === 'number') {
|
||||||
|
// 单个的点数据
|
||||||
|
// @ts-ignore
|
||||||
|
mappedData.map((d) => {
|
||||||
|
d.version = 'GAODE2.x';
|
||||||
|
// @ts-ignore
|
||||||
|
d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据)
|
||||||
|
// @ts-ignore
|
||||||
|
d.coordinates = this.mapService.lngLatToCoord(d.coordinates);
|
||||||
|
// d.coordinates = this.mapService.lngLatToCoord(unProjectFlat(d.coordinates));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 连续的线、面数据
|
||||||
|
// @ts-ignore
|
||||||
|
mappedData.map((d) => {
|
||||||
|
d.version = 'GAODE2.x';
|
||||||
|
// @ts-ignore
|
||||||
|
d.originCoordinates = cloneDeep(d.coordinates); // 为了兼容高德1.x 需要保存一份原始的经纬度坐标数据(许多上层逻辑依赖经纬度数据)
|
||||||
|
// @ts-ignore
|
||||||
|
d.coordinates = this.mapService.lngLatToCoords(d.coordinates);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mappedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyAttributeMapping(
|
private applyAttributeMapping(
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import { ILayer, ILayerPlugin, IMapService, TYPES } from '@antv/l7-core';
|
import {
|
||||||
|
ILayer,
|
||||||
|
ILayerPlugin,
|
||||||
|
ILngLat,
|
||||||
|
IMapService,
|
||||||
|
TYPES,
|
||||||
|
} from '@antv/l7-core';
|
||||||
import Source from '@antv/l7-source';
|
import Source from '@antv/l7-source';
|
||||||
import { injectable } from 'inversify';
|
import { injectable } from 'inversify';
|
||||||
|
import { cloneDeep } from 'lodash';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class DataSourcePlugin implements ILayerPlugin {
|
export default class DataSourcePlugin implements ILayerPlugin {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
ICoordinateSystemService,
|
ICoordinateSystemService,
|
||||||
ILayer,
|
ILayer,
|
||||||
ILayerPlugin,
|
ILayerPlugin,
|
||||||
|
IMapService,
|
||||||
IRendererService,
|
IRendererService,
|
||||||
TYPES,
|
TYPES,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
|
@ -29,13 +30,28 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
||||||
@inject(TYPES.IRendererService)
|
@inject(TYPES.IRendererService)
|
||||||
private readonly rendererService: IRendererService;
|
private readonly rendererService: IRendererService;
|
||||||
|
|
||||||
|
@inject(TYPES.IMapService)
|
||||||
|
private readonly mapService: IMapService;
|
||||||
|
|
||||||
public apply(layer: ILayer) {
|
public apply(layer: ILayer) {
|
||||||
|
const version = this.mapService.version;
|
||||||
|
|
||||||
|
let mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // default matrix (for gaode2.x)
|
||||||
|
let sceneCenterMKT = [0, 0];
|
||||||
layer.hooks.beforeRender.tap('ShaderUniformPlugin', () => {
|
layer.hooks.beforeRender.tap('ShaderUniformPlugin', () => {
|
||||||
// 重新计算坐标系参数
|
// 重新计算坐标系参数
|
||||||
this.coordinateSystemService.refresh();
|
this.coordinateSystemService.refresh();
|
||||||
|
|
||||||
|
if (version === 'GAODE2.x') {
|
||||||
|
// @ts-ignore
|
||||||
|
mvp = this.mapService.map.customCoords.getMVPMatrix();
|
||||||
|
// mvp = amapCustomCoords.getMVPMatrix()
|
||||||
|
// @ts-ignore
|
||||||
|
sceneCenterMKT = this.mapService.getCustomCoordCenter();
|
||||||
|
}
|
||||||
|
|
||||||
const { width, height } = this.rendererService.getViewportSize();
|
const { width, height } = this.rendererService.getViewportSize();
|
||||||
layer.models.forEach((model) =>
|
layer.models.forEach((model) => {
|
||||||
model.addUniforms({
|
model.addUniforms({
|
||||||
// 相机参数,包含 VP 矩阵、缩放等级
|
// 相机参数,包含 VP 矩阵、缩放等级
|
||||||
[CameraUniform.ProjectionMatrix]: this.cameraService.getProjectionMatrix(),
|
[CameraUniform.ProjectionMatrix]: this.cameraService.getProjectionMatrix(),
|
||||||
|
@ -52,13 +68,16 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
||||||
[CoordinateUniform.PixelsPerDegree]: this.coordinateSystemService.getPixelsPerDegree(),
|
[CoordinateUniform.PixelsPerDegree]: this.coordinateSystemService.getPixelsPerDegree(),
|
||||||
[CoordinateUniform.PixelsPerDegree2]: this.coordinateSystemService.getPixelsPerDegree2(),
|
[CoordinateUniform.PixelsPerDegree2]: this.coordinateSystemService.getPixelsPerDegree2(),
|
||||||
[CoordinateUniform.PixelsPerMeter]: this.coordinateSystemService.getPixelsPerMeter(),
|
[CoordinateUniform.PixelsPerMeter]: this.coordinateSystemService.getPixelsPerMeter(),
|
||||||
|
// 坐标系是高德2.0的时候单独计算
|
||||||
|
[CoordinateUniform.Mvp]: mvp,
|
||||||
|
u_SceneCenterMKT: sceneCenterMKT,
|
||||||
// 其他参数,例如视口大小、DPR 等
|
// 其他参数,例如视口大小、DPR 等
|
||||||
u_ViewportSize: [width, height],
|
u_ViewportSize: [width, height],
|
||||||
u_DevicePixelRatio: window.devicePixelRatio,
|
u_DevicePixelRatio: window.devicePixelRatio,
|
||||||
u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||||
u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0,
|
u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0,
|
||||||
}),
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
// TODO:脏检查,决定是否需要渲染
|
// TODO:脏检查,决定是否需要渲染
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,6 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
|
||||||
public buildModels() {
|
public buildModels() {
|
||||||
const modelType = this.getModelType();
|
const modelType = this.getModelType();
|
||||||
this.layerModel = new PointModels[modelType](this);
|
this.layerModel = new PointModels[modelType](this);
|
||||||
|
|
||||||
this.models = this.layerModel.initModels();
|
this.models = this.layerModel.initModels();
|
||||||
}
|
}
|
||||||
public rebuildModels() {
|
public rebuildModels() {
|
||||||
|
|
|
@ -108,7 +108,6 @@ export default class ImageModel extends BaseModel {
|
||||||
attributeIdx: number,
|
attributeIdx: number,
|
||||||
) => {
|
) => {
|
||||||
const iconMap = this.iconService.getIconMap();
|
const iconMap = this.iconService.getIconMap();
|
||||||
|
|
||||||
const { shape } = feature;
|
const { shape } = feature;
|
||||||
const { x, y } = iconMap[shape as string] || { x: 0, y: 0 };
|
const { x, y } = iconMap[shape as string] || { x: 0, y: 0 };
|
||||||
return [x, y];
|
return [x, y];
|
||||||
|
|
|
@ -292,7 +292,7 @@ export default class TextModel extends BaseModel {
|
||||||
return padBounds(bounds, 0.5);
|
return padBounds(bounds, 0.5);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 生成文字纹理
|
* 生成文字纹理(生成文字纹理字典)
|
||||||
*/
|
*/
|
||||||
private initTextFont() {
|
private initTextFont() {
|
||||||
const {
|
const {
|
||||||
|
@ -315,12 +315,39 @@ export default class TextModel extends BaseModel {
|
||||||
characterSet,
|
characterSet,
|
||||||
fontWeight,
|
fontWeight,
|
||||||
fontFamily,
|
fontFamily,
|
||||||
|
iconfont: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成文字布局
|
* 生成 iconfont 纹理字典
|
||||||
*/
|
*/
|
||||||
private generateGlyphLayout() {
|
private initIconFontTex() {
|
||||||
|
const {
|
||||||
|
fontWeight = '400',
|
||||||
|
fontFamily = 'sans-serif',
|
||||||
|
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
|
||||||
|
const data = this.layer.getEncodedData();
|
||||||
|
const characterSet: string[] = [];
|
||||||
|
data.forEach((item: IEncodeFeature) => {
|
||||||
|
let { shape = '' } = item;
|
||||||
|
shape = shape.toString();
|
||||||
|
if (characterSet.indexOf(shape) === -1) {
|
||||||
|
characterSet.push(shape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.fontService.setFontOptions({
|
||||||
|
characterSet,
|
||||||
|
fontWeight,
|
||||||
|
fontFamily,
|
||||||
|
iconfont: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成文字布局(对照文字纹理字典提取对应文字的位置很好信息)
|
||||||
|
*/
|
||||||
|
private generateGlyphLayout(iconfont: boolean) {
|
||||||
// TODO:更新文字布局
|
// TODO:更新文字布局
|
||||||
const { mapping } = this.fontService;
|
const { mapping } = this.fontService;
|
||||||
const {
|
const {
|
||||||
|
@ -330,7 +357,7 @@ export default class TextModel extends BaseModel {
|
||||||
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPointTextLayerStyleOptions;
|
||||||
const data = this.layer.getEncodedData();
|
const data = this.layer.getEncodedData();
|
||||||
this.glyphInfo = data.map((feature: IEncodeFeature) => {
|
this.glyphInfo = data.map((feature: IEncodeFeature) => {
|
||||||
const { shape = '', coordinates, id, size = 1 } = feature;
|
const { shape = '', id, size = 1 } = feature;
|
||||||
|
|
||||||
const shaping = shapeText(
|
const shaping = shapeText(
|
||||||
shape.toString(),
|
shape.toString(),
|
||||||
|
@ -341,21 +368,31 @@ export default class TextModel extends BaseModel {
|
||||||
'center',
|
'center',
|
||||||
spacing,
|
spacing,
|
||||||
textOffset,
|
textOffset,
|
||||||
|
iconfont,
|
||||||
);
|
);
|
||||||
const glyphQuads = getGlyphQuads(shaping, textOffset, false);
|
const glyphQuads = getGlyphQuads(shaping, textOffset, false);
|
||||||
feature.shaping = shaping;
|
feature.shaping = shaping;
|
||||||
feature.glyphQuads = glyphQuads;
|
feature.glyphQuads = glyphQuads;
|
||||||
feature.centroid = calculteCentroid(coordinates);
|
// feature.centroid = calculteCentroid(coordinates);
|
||||||
|
|
||||||
|
feature.centroid = calculteCentroid(feature.coordinates);
|
||||||
|
|
||||||
|
// 此时地图高德2.0 originCentroid == centroid
|
||||||
|
feature.originCentroid =
|
||||||
|
feature.version === 'GAODE2.x'
|
||||||
|
? calculteCentroid(feature.originCoordinates)
|
||||||
|
: (feature.originCentroid = feature.centroid);
|
||||||
|
|
||||||
this.glyphInfoMap[id as number] = {
|
this.glyphInfoMap[id as number] = {
|
||||||
shaping,
|
shaping,
|
||||||
glyphQuads,
|
glyphQuads,
|
||||||
centroid: calculteCentroid(coordinates),
|
centroid: calculteCentroid(feature.coordinates),
|
||||||
};
|
};
|
||||||
return feature;
|
return feature;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 文字避让
|
* 文字避让 depend on originCentorid
|
||||||
*/
|
*/
|
||||||
private filterGlyphs() {
|
private filterGlyphs() {
|
||||||
const {
|
const {
|
||||||
|
@ -374,7 +411,11 @@ export default class TextModel extends BaseModel {
|
||||||
const collisionIndex = new CollisionIndex(width, height);
|
const collisionIndex = new CollisionIndex(width, height);
|
||||||
const filterData = this.glyphInfo.filter((feature: IEncodeFeature) => {
|
const filterData = this.glyphInfo.filter((feature: IEncodeFeature) => {
|
||||||
const { shaping, id = 0 } = feature;
|
const { shaping, id = 0 } = feature;
|
||||||
const centroid = feature.centroid as [number, number];
|
// const centroid = feature.centroid as [number, number];
|
||||||
|
// const centroid = feature.originCentroid as [number, number];
|
||||||
|
const centroid = (feature.version === 'GAODE2.x'
|
||||||
|
? feature.originCentroid
|
||||||
|
: feature.centroid) as [number, number];
|
||||||
const size = feature.size as number;
|
const size = feature.size as number;
|
||||||
const fontScale: number = size / 24;
|
const fontScale: number = size / 24;
|
||||||
const pixels = this.mapService.lngLatToContainer(centroid);
|
const pixels = this.mapService.lngLatToContainer(centroid);
|
||||||
|
@ -404,10 +445,13 @@ export default class TextModel extends BaseModel {
|
||||||
* 初始化文字布局
|
* 初始化文字布局
|
||||||
*/
|
*/
|
||||||
private initGlyph() {
|
private initGlyph() {
|
||||||
// 1.生成文字纹理
|
const { iconfont = false } = this.layer.getLayerConfig();
|
||||||
this.initTextFont();
|
// 1.生成文字纹理(或是生成 iconfont)
|
||||||
|
iconfont ? this.initIconFontTex() : this.initTextFont();
|
||||||
|
// this.initTextFont();
|
||||||
|
|
||||||
// 2.生成文字布局
|
// 2.生成文字布局
|
||||||
this.generateGlyphLayout();
|
this.generateGlyphLayout(iconfont);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 更新文字纹理
|
* 更新文字纹理
|
||||||
|
|
|
@ -11,6 +11,7 @@ attribute vec3 a_Size;
|
||||||
attribute vec3 a_Normal;
|
attribute vec3 a_Normal;
|
||||||
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform vec2 u_offsets;
|
uniform vec2 u_offsets;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
|
||||||
|
@ -30,6 +31,12 @@ void main() {
|
||||||
float lightWeight = calc_lighting(pos);
|
float lightWeight = calc_lighting(pos);
|
||||||
v_color =vec4(a_Color.rgb * lightWeight, a_Color.w);
|
v_color =vec4(a_Color.rgb * lightWeight, a_Color.w);
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(pos);
|
// gl_Position = project_common_position_to_clipspace(pos);
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * pos;
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(pos);
|
||||||
|
}
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ attribute vec2 a_Extrude;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
attribute float a_Shape;
|
attribute float a_Shape;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
uniform float u_stroke_width : 2;
|
uniform float u_stroke_width : 2;
|
||||||
uniform vec2 u_offsets;
|
uniform vec2 u_offsets;
|
||||||
|
@ -16,24 +17,16 @@ varying float v_radius;
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
vec2 extrude = a_Extrude;
|
||||||
|
float shape_type = a_Shape;
|
||||||
|
float newSize = setPickingSize(a_Size);
|
||||||
|
|
||||||
// unpack color(vec2)
|
// unpack color(vec2)
|
||||||
v_color = a_Color;
|
v_color = a_Color;
|
||||||
vec2 extrude = a_Extrude;
|
|
||||||
|
|
||||||
float shape_type = a_Shape;
|
|
||||||
|
|
||||||
float newSize = setPickingSize(a_Size);
|
|
||||||
|
|
||||||
// radius(16-bit)
|
// radius(16-bit)
|
||||||
v_radius = newSize;
|
v_radius = newSize;
|
||||||
|
|
||||||
vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets);
|
|
||||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: billboard
|
// TODO: billboard
|
||||||
// anti-alias
|
// anti-alias
|
||||||
float antialiasblur = 1.0 / u_DevicePixelRatio / (newSize + u_stroke_width);
|
float antialiasblur = 1.0 / u_DevicePixelRatio / (newSize + u_stroke_width);
|
||||||
|
@ -41,8 +34,17 @@ void main() {
|
||||||
// construct point coords
|
// construct point coords
|
||||||
v_data = vec4(extrude, antialiasblur,shape_type);
|
v_data = vec4(extrude, antialiasblur,shape_type);
|
||||||
|
|
||||||
|
vec2 offset = project_pixel(extrude * (newSize + u_stroke_width) + u_offsets);
|
||||||
|
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * vec4(project_pos.xy + offset, 0.0, 1.0);
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, project_pixel(setPickingOrder(0.0)), 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||||
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ uniform float u_opacity : 1;
|
||||||
varying float v_size;
|
varying float v_size;
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
void main(){
|
void main(){
|
||||||
vec2 pos= v_uv / u_textSize + gl_PointCoord / u_textSize * 64.;
|
vec2 pos= v_uv / u_textSize + gl_PointCoord / u_textSize * 64.;
|
||||||
vec4 textureColor=texture2D(u_texture,pos);
|
vec4 textureColor=texture2D(u_texture,pos);
|
||||||
if(all(lessThan(v_color, vec4(1.0+0.00001))) && all(greaterThan(v_color, vec4(1.0-0.00001))) || v_color==vec4(1.0)){
|
if(all(lessThan(v_color, vec4(1.0+0.00001))) && all(greaterThan(v_color, vec4(1.0-0.00001))) || v_color==vec4(1.0)){
|
||||||
gl_FragColor= textureColor;
|
gl_FragColor= textureColor;
|
||||||
}else {
|
}else {
|
||||||
gl_FragColor= step(0.01, textureColor.z) * v_color;
|
gl_FragColor= step(0.01, textureColor.z) * v_color;
|
||||||
}
|
}
|
||||||
gl_FragColor.a =gl_FragColor.a * u_opacity;
|
gl_FragColor.a =gl_FragColor.a * u_opacity;
|
||||||
gl_FragColor = filterColor(gl_FragColor);
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ attribute float a_Size;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_uv;
|
varying vec2 v_uv;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform float u_stroke_width : 1;
|
uniform float u_stroke_width : 1;
|
||||||
uniform vec2 u_offsets;
|
uniform vec2 u_offsets;
|
||||||
varying float v_size;
|
varying float v_size;
|
||||||
|
@ -19,7 +20,14 @@ void main() {
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
v_size = a_Size;
|
v_size = a_Size;
|
||||||
vec2 offset = project_pixel(u_offsets);
|
vec2 offset = project_pixel(u_offsets);
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0));
|
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0);
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy + offset),project_pos.z, 1.0));
|
||||||
|
}
|
||||||
gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio;
|
gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio;
|
||||||
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
attribute vec4 a_Color;
|
attribute vec4 a_Color;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
@ -11,9 +12,18 @@ uniform vec2 u_offsets;
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
void main() {
|
void main() {
|
||||||
v_color = a_Color;
|
v_color = a_Color;
|
||||||
vec2 offset = project_pixel(u_offsets);
|
// vec2 offset = project_pixel(u_offsets);
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.);
|
// vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.);
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w));
|
// gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w));\
|
||||||
|
//
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * vec4(a_Position, 1.0);
|
||||||
|
} else { // else
|
||||||
|
vec2 offset = project_pixel(u_offsets);
|
||||||
|
vec4 project_pos = project_position(vec4(a_Position, 1.0)) + vec4(a_Size / 2.,-a_Size /2.,0.,0.);
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(vec2(project_pos.xy+offset),project_pos.z,project_pos.w));
|
||||||
|
}
|
||||||
|
|
||||||
gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio;
|
gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio;
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ attribute float a_Rotate;
|
||||||
|
|
||||||
uniform vec2 u_sdf_map_size;
|
uniform vec2 u_sdf_map_size;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
varying vec2 v_uv;
|
varying vec2 v_uv;
|
||||||
varying float v_gamma_scale;
|
varying float v_gamma_scale;
|
||||||
|
@ -25,15 +26,25 @@ void main() {
|
||||||
|
|
||||||
// 文本缩放比例
|
// 文本缩放比例
|
||||||
float fontScale = a_Size / FONT_SIZE;
|
float fontScale = a_Size / FONT_SIZE;
|
||||||
v_fontScale = fontScale;
|
v_fontScale = fontScale;
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
|
||||||
|
|
||||||
vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
highp float angle_sin = sin(a_Rotate);
|
// vec4 projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
highp float angle_cos = cos(a_Rotate);
|
|
||||||
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
highp float angle_sin = sin(a_Rotate);
|
||||||
gl_Position = vec4(projected_position.xy / projected_position.w
|
highp float angle_cos = cos(a_Rotate);
|
||||||
+ rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0);
|
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||||
|
|
||||||
|
// gl_Position = vec4(projected_position.xy / projected_position.w + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec4 projected_position;
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
projected_position = u_Mvp * (vec4(a_Position.xyz, 1.0));
|
||||||
|
} else { // else
|
||||||
|
projected_position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = vec4(projected_position.xy / projected_position.w + rotation_matrix * a_textOffsets * fontScale / u_ViewportSize * 2.0 * u_DevicePixelRatio, 0.0, 1.0);
|
||||||
v_gamma_scale = gl_Position.w;
|
v_gamma_scale = gl_Position.w;
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ attribute vec3 a_Position;
|
||||||
attribute vec3 a_Normal;
|
attribute vec3 a_Normal;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
varying vec4 v_Color;
|
varying vec4 v_Color;
|
||||||
|
|
||||||
|
@ -20,7 +21,14 @@ void main() {
|
||||||
vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0);
|
vec4 pos = vec4(a_Position.xy, a_Position.z * a_Size, 1.0);
|
||||||
vec4 project_pos = project_position(pos);
|
vec4 project_pos = project_position(pos);
|
||||||
|
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
// gl_Position = u_Mvp * (vec4(project_pos.xyz * vec3(1.0, 1.0, -1.0), 1.0));
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
float lightWeight = calc_lighting(pos);
|
float lightWeight = calc_lighting(pos);
|
||||||
// v_Color = a_Color;
|
// v_Color = a_Color;
|
||||||
|
|
|
@ -3,6 +3,7 @@ attribute vec3 a_Position;
|
||||||
attribute vec3 a_Normal;
|
attribute vec3 a_Normal;
|
||||||
attribute float a_Size;
|
attribute float a_Size;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
varying vec4 v_Color;
|
varying vec4 v_Color;
|
||||||
|
|
||||||
|
@ -12,7 +13,13 @@ varying vec4 v_Color;
|
||||||
void main() {
|
void main() {
|
||||||
v_Color = a_Color;
|
v_Color = a_Color;
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
setPickingColor(a_PickingColor);
|
setPickingColor(a_PickingColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ interface IRasterLayerStyleOptions {
|
||||||
|
|
||||||
export default class RasterLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
export default class RasterLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
public type: string = 'RasterLayer';
|
public type: string = 'RasterLayer';
|
||||||
protected texture: ITexture2D;
|
protected rasterTexture: ITexture2D;
|
||||||
protected colorTexture: ITexture2D;
|
protected colorTexture: ITexture2D;
|
||||||
|
|
||||||
public getAnimateUniforms(): IModelUniform {
|
public getAnimateUniforms(): IModelUniform {
|
||||||
|
@ -39,7 +39,7 @@ export default class RasterLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
public buildModels() {
|
public buildModels() {
|
||||||
const parserDataItem = this.getSource().data.dataArray[0];
|
const parserDataItem = this.getSource().data.dataArray[0];
|
||||||
const { createTexture2D } = this.rendererService;
|
const { createTexture2D } = this.rendererService;
|
||||||
this.texture = createTexture2D({
|
this.rasterTexture = createTexture2D({
|
||||||
data: parserDataItem.data,
|
data: parserDataItem.data,
|
||||||
width: parserDataItem.width,
|
width: parserDataItem.width,
|
||||||
height: parserDataItem.height,
|
height: parserDataItem.height,
|
||||||
|
@ -65,7 +65,7 @@ export default class RasterLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
model.draw({
|
model.draw({
|
||||||
uniforms: {
|
uniforms: {
|
||||||
u_opacity: opacity || 1,
|
u_opacity: opacity || 1,
|
||||||
u_texture: this.texture,
|
u_texture: this.rasterTexture,
|
||||||
u_min: min,
|
u_min: min,
|
||||||
u_width: width,
|
u_width: width,
|
||||||
u_height: height,
|
u_height: height,
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface IRasterLayerStyleOptions {
|
||||||
|
|
||||||
export default class Raster2dLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
export default class Raster2dLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
public type: string = 'RasterLayer';
|
public type: string = 'RasterLayer';
|
||||||
protected texture: ITexture2D;
|
protected rasterTexture: ITexture2D;
|
||||||
protected colorTexture: ITexture2D;
|
protected colorTexture: ITexture2D;
|
||||||
|
|
||||||
public buildModels() {
|
public buildModels() {
|
||||||
|
@ -21,7 +21,7 @@ export default class Raster2dLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
const source = this.getSource();
|
const source = this.getSource();
|
||||||
const { createTexture2D } = this.rendererService;
|
const { createTexture2D } = this.rendererService;
|
||||||
const parserDataItem = this.getSource().data.dataArray[0];
|
const parserDataItem = this.getSource().data.dataArray[0];
|
||||||
this.texture = createTexture2D({
|
this.rasterTexture = createTexture2D({
|
||||||
data: parserDataItem.data,
|
data: parserDataItem.data,
|
||||||
width: parserDataItem.width,
|
width: parserDataItem.width,
|
||||||
height: parserDataItem.height,
|
height: parserDataItem.height,
|
||||||
|
@ -61,12 +61,12 @@ export default class Raster2dLayer extends BaseLayer<IRasterLayerStyleOptions> {
|
||||||
const { opacity } = this.getLayerConfig();
|
const { opacity } = this.getLayerConfig();
|
||||||
const parserDataItem = this.getSource().data.dataArray[0];
|
const parserDataItem = this.getSource().data.dataArray[0];
|
||||||
const { min, max } = parserDataItem;
|
const { min, max } = parserDataItem;
|
||||||
if (this.texture) {
|
if (this.rasterTexture) {
|
||||||
this.models.forEach((model) =>
|
this.models.forEach((model) =>
|
||||||
model.draw({
|
model.draw({
|
||||||
uniforms: {
|
uniforms: {
|
||||||
u_opacity: opacity || 1,
|
u_opacity: opacity || 1,
|
||||||
u_texture: this.texture,
|
u_texture: this.rasterTexture,
|
||||||
u_min: min,
|
u_min: min,
|
||||||
u_max: max,
|
u_max: max,
|
||||||
u_colorTexture: this.colorTexture,
|
u_colorTexture: this.colorTexture,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
attribute vec2 a_Uv;
|
attribute vec2 a_Uv;
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
|
@ -8,4 +9,10 @@ void main() {
|
||||||
v_texCoord = a_Uv;
|
v_texCoord = a_Uv;
|
||||||
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xy,0., 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy,0., 1.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
uniform vec4 u_extent;
|
uniform vec4 u_extent;
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
uniform sampler2D u_colorTexture;
|
uniform sampler2D u_colorTexture;
|
||||||
|
@ -32,6 +33,12 @@ void main() {
|
||||||
|
|
||||||
// vec2 range = u_extent.zw - u_extent.xy;
|
// vec2 range = u_extent.zw - u_extent.xy;
|
||||||
// vec4 project_pos = project_position(vec4(pos, 0, 1.0));
|
// vec4 project_pos = project_position(vec4(pos, 0, 1.0));
|
||||||
gl_Position = project_common_position_to_clipspace(vec4(pos.xy, project_scale(value) * u_heightRatio, 1.0));
|
// gl_Position = project_common_position_to_clipspace(vec4(pos.xy, project_scale(value) * u_heightRatio, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(pos.xy, project_scale(value) * u_heightRatio, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(pos.xy, project_scale(value) * u_heightRatio, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,51 @@ export default class ExtrudePolyline {
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extrude_gaode2(points: number[][], originPoints: number[][]) {
|
||||||
|
const complex = this.complex;
|
||||||
|
if (points.length <= 1) {
|
||||||
|
return complex;
|
||||||
|
}
|
||||||
|
this.lastFlip = -1;
|
||||||
|
this.started = false;
|
||||||
|
this.normal = null;
|
||||||
|
this.totalDistance = 0;
|
||||||
|
// 去除数组里重复的点
|
||||||
|
// points = getArrayUnique(points);
|
||||||
|
const total = points.length;
|
||||||
|
let count = complex.startIndex;
|
||||||
|
for (let i = 1; i < total; i++) {
|
||||||
|
const last = points[i - 1] as vec2;
|
||||||
|
const originLast = originPoints[i - 1] as vec2;
|
||||||
|
|
||||||
|
const cur = points[i] as vec2;
|
||||||
|
const originCur = originPoints[i] as vec2;
|
||||||
|
|
||||||
|
const next = i < points.length - 1 ? points[i + 1] : null;
|
||||||
|
const originNext =
|
||||||
|
i < originPoints.length - 1 ? originPoints[i + 1] : null;
|
||||||
|
|
||||||
|
const amt = this.segment_gaode2(
|
||||||
|
complex,
|
||||||
|
count,
|
||||||
|
last,
|
||||||
|
cur,
|
||||||
|
next as vec2,
|
||||||
|
originLast,
|
||||||
|
originCur,
|
||||||
|
originNext as vec2,
|
||||||
|
);
|
||||||
|
count += amt;
|
||||||
|
}
|
||||||
|
if (this.dash) {
|
||||||
|
for (let i = 0; i < complex.positions.length / 6; i++) {
|
||||||
|
complex.positions[i * 6 + 5] = this.totalDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
complex.startIndex = complex.positions.length / 6;
|
||||||
|
return complex;
|
||||||
|
}
|
||||||
public extrude(points: number[][]) {
|
public extrude(points: number[][]) {
|
||||||
const complex = this.complex;
|
const complex = this.complex;
|
||||||
if (points.length <= 1) {
|
if (points.length <= 1) {
|
||||||
|
@ -115,6 +160,222 @@ export default class ExtrudePolyline {
|
||||||
complex.startIndex = complex.positions.length / 6;
|
complex.startIndex = complex.positions.length / 6;
|
||||||
return complex;
|
return complex;
|
||||||
}
|
}
|
||||||
|
private segment_gaode2(
|
||||||
|
complex: any,
|
||||||
|
index: number,
|
||||||
|
last: vec2,
|
||||||
|
cur: vec2,
|
||||||
|
next: vec2,
|
||||||
|
originLast: vec2,
|
||||||
|
originCur: vec2,
|
||||||
|
originNext: vec2,
|
||||||
|
) {
|
||||||
|
let count = 0;
|
||||||
|
const indices = complex.indices;
|
||||||
|
const positions = complex.positions;
|
||||||
|
const normals = complex.normals;
|
||||||
|
const capSquare = this.cap === 'square';
|
||||||
|
const joinBevel = this.join === 'bevel';
|
||||||
|
const flatCur = aProjectFlat([originCur[0], originCur[1]]) as [
|
||||||
|
number,
|
||||||
|
number,
|
||||||
|
];
|
||||||
|
const flatLast = aProjectFlat([originLast[0], originLast[1]]) as [
|
||||||
|
number,
|
||||||
|
number,
|
||||||
|
];
|
||||||
|
direction(lineA, cur, last);
|
||||||
|
let segmentDistance = 0;
|
||||||
|
if (this.dash) {
|
||||||
|
segmentDistance = this.lineSegmentDistance(flatCur, flatLast);
|
||||||
|
this.totalDistance += segmentDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.normal) {
|
||||||
|
this.normal = vec2.create();
|
||||||
|
computeNormal(this.normal, lineA);
|
||||||
|
}
|
||||||
|
if (!this.started) {
|
||||||
|
this.started = true;
|
||||||
|
|
||||||
|
// if the end cap is type square, we can just push the verts out a bit
|
||||||
|
if (capSquare) {
|
||||||
|
// vec2.scaleAndAdd(capEnd, last, lineA, -this.thickness);
|
||||||
|
const out1 = vec2.create();
|
||||||
|
const out2 = vec2.create();
|
||||||
|
vec2.add(out1, this.normal, lineA);
|
||||||
|
vec2.add(out2, this.normal, lineA);
|
||||||
|
normals.push(out2[0], out2[1], 0);
|
||||||
|
normals.push(out1[0], out1[1], 0);
|
||||||
|
positions.push(
|
||||||
|
last[0],
|
||||||
|
last[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance - segmentDistance,
|
||||||
|
-this.thickness,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
positions.push(
|
||||||
|
last[0],
|
||||||
|
last[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance - segmentDistance,
|
||||||
|
this.thickness,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.extrusions(
|
||||||
|
positions,
|
||||||
|
normals,
|
||||||
|
last,
|
||||||
|
this.normal,
|
||||||
|
this.thickness,
|
||||||
|
this.totalDistance - segmentDistance,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indices.push(index + 0, index + 1, index + 2);
|
||||||
|
|
||||||
|
if (!next) {
|
||||||
|
computeNormal(this.normal, lineA);
|
||||||
|
if (capSquare) {
|
||||||
|
const out1 = vec2.create();
|
||||||
|
const out2 = vec2.create();
|
||||||
|
vec2.sub(out2, lineA, this.normal);
|
||||||
|
vec2.add(out1, lineA, this.normal);
|
||||||
|
|
||||||
|
normals.push(out2[0], out2[1], 0);
|
||||||
|
normals.push(out1[0], out1[1], 0);
|
||||||
|
|
||||||
|
positions.push(
|
||||||
|
cur[0],
|
||||||
|
cur[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance,
|
||||||
|
this.thickness,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
positions.push(
|
||||||
|
cur[0],
|
||||||
|
cur[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance,
|
||||||
|
this.thickness,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.extrusions(
|
||||||
|
positions,
|
||||||
|
normals,
|
||||||
|
cur,
|
||||||
|
this.normal,
|
||||||
|
this.thickness,
|
||||||
|
this.totalDistance,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
indices.push(
|
||||||
|
...(this.lastFlip === 1
|
||||||
|
? [index, index + 2, index + 3]
|
||||||
|
: [index + 2, index + 1, index + 3]),
|
||||||
|
);
|
||||||
|
count += 2;
|
||||||
|
} else {
|
||||||
|
if (isPointEqual(cur, next)) {
|
||||||
|
vec2.add(
|
||||||
|
next,
|
||||||
|
cur,
|
||||||
|
vec2.normalize(next, vec2.subtract(next, cur, last)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
direction(lineB, next, cur);
|
||||||
|
// stores tangent & miter
|
||||||
|
|
||||||
|
const [miterLen, miter] = computeMiter(
|
||||||
|
tangent,
|
||||||
|
vec2.create(),
|
||||||
|
lineA,
|
||||||
|
lineB,
|
||||||
|
this.thickness,
|
||||||
|
);
|
||||||
|
// normal(tmp, lineA)
|
||||||
|
|
||||||
|
// get orientation
|
||||||
|
let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1;
|
||||||
|
let bevel = joinBevel;
|
||||||
|
if (!bevel && this.join === 'miter') {
|
||||||
|
const limit = miterLen;
|
||||||
|
if (limit > this.miterLimit) {
|
||||||
|
bevel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bevel) {
|
||||||
|
normals.push(this.normal[0], this.normal[1], 0);
|
||||||
|
normals.push(miter[0], miter[1], 0);
|
||||||
|
|
||||||
|
positions.push(
|
||||||
|
cur[0],
|
||||||
|
cur[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance,
|
||||||
|
-this.thickness * flip,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
positions.push(
|
||||||
|
cur[0],
|
||||||
|
cur[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance,
|
||||||
|
this.thickness * flip,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
indices.push(
|
||||||
|
...(this.lastFlip !== -flip
|
||||||
|
? [index, index + 2, index + 3]
|
||||||
|
: [index + 2, index + 1, index + 3]),
|
||||||
|
);
|
||||||
|
|
||||||
|
// now add the bevel triangle
|
||||||
|
indices.push(index + 2, index + 3, index + 4);
|
||||||
|
|
||||||
|
computeNormal(tmp, lineB);
|
||||||
|
vec2.copy(this.normal, tmp); // store normal for next round
|
||||||
|
normals.push(this.normal[0], this.normal[1], 0);
|
||||||
|
positions.push(
|
||||||
|
cur[0],
|
||||||
|
cur[1],
|
||||||
|
0,
|
||||||
|
this.totalDistance,
|
||||||
|
-this.thickness * flip,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
count += 3;
|
||||||
|
} else {
|
||||||
|
this.extrusions(
|
||||||
|
positions,
|
||||||
|
normals,
|
||||||
|
cur,
|
||||||
|
miter,
|
||||||
|
miterLen,
|
||||||
|
this.totalDistance,
|
||||||
|
);
|
||||||
|
indices.push(
|
||||||
|
...(this.lastFlip === 1
|
||||||
|
? [index, index + 2, index + 3]
|
||||||
|
: [index + 2, index + 1, index + 3]),
|
||||||
|
);
|
||||||
|
|
||||||
|
flip = -1;
|
||||||
|
|
||||||
|
// the miter is now the normal for our next join
|
||||||
|
vec2.copy(this.normal, miter);
|
||||||
|
count += 2;
|
||||||
|
}
|
||||||
|
this.lastFlip = flip;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
private segment(
|
private segment(
|
||||||
complex: any,
|
complex: any,
|
||||||
index: number,
|
index: number,
|
||||||
|
@ -329,7 +590,6 @@ export default class ExtrudePolyline {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private extrusions(
|
private extrusions(
|
||||||
positions: number[],
|
positions: number[],
|
||||||
normals: number[],
|
normals: number[],
|
||||||
|
|
|
@ -197,6 +197,81 @@ function shapeLines(
|
||||||
shaping.right = shaping.left + maxLineLength;
|
shaping.right = shaping.left + maxLineLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shapeIconFont(
|
||||||
|
shaping: any,
|
||||||
|
glyphMap: any,
|
||||||
|
iconfonts: any[],
|
||||||
|
lineHeight: number,
|
||||||
|
textAnchor: anchorType,
|
||||||
|
textJustify: string,
|
||||||
|
spacing: number,
|
||||||
|
) {
|
||||||
|
// buffer 为 4
|
||||||
|
const yOffset = -8;
|
||||||
|
|
||||||
|
let x = 0;
|
||||||
|
let y = yOffset;
|
||||||
|
|
||||||
|
let maxLineLength = 0;
|
||||||
|
const positionedGlyphs = shaping.positionedGlyphs;
|
||||||
|
|
||||||
|
const justify =
|
||||||
|
textJustify === 'right' ? 1 : textJustify === 'left' ? 0 : 0.5;
|
||||||
|
|
||||||
|
const lineStartIndex = positionedGlyphs.length;
|
||||||
|
iconfonts.forEach((iconfont) => {
|
||||||
|
const glyph = glyphMap[iconfont];
|
||||||
|
const baselineOffset = 0;
|
||||||
|
|
||||||
|
if (glyph) {
|
||||||
|
positionedGlyphs.push({
|
||||||
|
glyph: iconfont,
|
||||||
|
x,
|
||||||
|
y: y + baselineOffset,
|
||||||
|
vertical: false, // TODO:目前只支持水平方向
|
||||||
|
scale: 1,
|
||||||
|
metrics: glyph,
|
||||||
|
});
|
||||||
|
x += glyph.advance + spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 左右对齐
|
||||||
|
if (positionedGlyphs.length !== lineStartIndex) {
|
||||||
|
const lineLength = x - spacing;
|
||||||
|
maxLineLength = Math.max(lineLength, maxLineLength);
|
||||||
|
justifyLine(
|
||||||
|
positionedGlyphs,
|
||||||
|
glyphMap,
|
||||||
|
lineStartIndex,
|
||||||
|
positionedGlyphs.length - 1,
|
||||||
|
justify,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
y += lineHeight;
|
||||||
|
});
|
||||||
|
|
||||||
|
const { horizontalAlign, verticalAlign } = getAnchorAlignment(textAnchor);
|
||||||
|
align(
|
||||||
|
positionedGlyphs,
|
||||||
|
justify,
|
||||||
|
horizontalAlign,
|
||||||
|
verticalAlign,
|
||||||
|
maxLineLength,
|
||||||
|
lineHeight,
|
||||||
|
iconfonts.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算包围盒
|
||||||
|
const height = y - yOffset;
|
||||||
|
|
||||||
|
shaping.top += -verticalAlign * height;
|
||||||
|
shaping.bottom = shaping.top + height;
|
||||||
|
shaping.left += -horizontalAlign * maxLineLength;
|
||||||
|
shaping.right = shaping.left + maxLineLength;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算文本中每个独立字符相对锚点的位置
|
* 计算文本中每个独立字符相对锚点的位置
|
||||||
*
|
*
|
||||||
|
@ -207,6 +282,7 @@ function shapeLines(
|
||||||
* @param {string} textJustify 左右对齐
|
* @param {string} textJustify 左右对齐
|
||||||
* @param {number} spacing 字符间距
|
* @param {number} spacing 字符间距
|
||||||
* @param {[number, number]} translate 文本水平 & 垂直偏移量
|
* @param {[number, number]} translate 文本水平 & 垂直偏移量
|
||||||
|
* @param {[boolean]} isIconFont 是否是 iconfont
|
||||||
* @return {boolean|shaping} 每个字符相对于锚点的位置
|
* @return {boolean|shaping} 每个字符相对于锚点的位置
|
||||||
*/
|
*/
|
||||||
export function shapeText(
|
export function shapeText(
|
||||||
|
@ -217,6 +293,7 @@ export function shapeText(
|
||||||
textJustify: string,
|
textJustify: string,
|
||||||
spacing: number,
|
spacing: number,
|
||||||
translate: [number, number] = [0, 0],
|
translate: [number, number] = [0, 0],
|
||||||
|
isIconFont: boolean,
|
||||||
) {
|
) {
|
||||||
// TODO:处理换行
|
// TODO:处理换行
|
||||||
const lines = text.split('\n');
|
const lines = text.split('\n');
|
||||||
|
@ -231,16 +308,25 @@ export function shapeText(
|
||||||
lineCount: lines.length,
|
lineCount: lines.length,
|
||||||
text,
|
text,
|
||||||
};
|
};
|
||||||
|
isIconFont
|
||||||
shapeLines(
|
? shapeIconFont(
|
||||||
shaping,
|
shaping,
|
||||||
glyphs,
|
glyphs,
|
||||||
lines,
|
lines,
|
||||||
lineHeight,
|
lineHeight,
|
||||||
textAnchor,
|
textAnchor,
|
||||||
textJustify,
|
textJustify,
|
||||||
spacing,
|
spacing,
|
||||||
);
|
)
|
||||||
|
: shapeLines(
|
||||||
|
shaping,
|
||||||
|
glyphs,
|
||||||
|
lines,
|
||||||
|
lineHeight,
|
||||||
|
textAnchor,
|
||||||
|
textJustify,
|
||||||
|
spacing,
|
||||||
|
);
|
||||||
if (!positionedGlyphs.length) {
|
if (!positionedGlyphs.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ export default class Viewport implements IViewport {
|
||||||
|
|
||||||
// 计算透视投影矩阵 projectionMatrix
|
// 计算透视投影矩阵 projectionMatrix
|
||||||
mat4.perspective(this.projectionMatrix, fov, aspect, near, far);
|
mat4.perspective(this.projectionMatrix, fov, aspect, near, far);
|
||||||
|
|
||||||
// 计算相机矩阵 viewMatrix
|
// 计算相机矩阵 viewMatrix
|
||||||
const eye = vec3.fromValues(
|
const eye = vec3.fromValues(
|
||||||
cameraHeight * Math.sin(pitchInRadians) * Math.sin(rotationInRadians),
|
cameraHeight * Math.sin(pitchInRadians) * Math.sin(rotationInRadians),
|
||||||
|
@ -46,7 +45,6 @@ export default class Viewport implements IViewport {
|
||||||
Math.sin(pitchInRadians),
|
Math.sin(pitchInRadians),
|
||||||
);
|
);
|
||||||
mat4.lookAt(this.viewMatrix, eye, vec3.fromValues(0, 0, 0), up);
|
mat4.lookAt(this.viewMatrix, eye, vec3.fromValues(0, 0, 0), up);
|
||||||
|
|
||||||
this.viewUncenteredMatrix = mat4.clone(this.viewMatrix);
|
this.viewUncenteredMatrix = mat4.clone(this.viewMatrix);
|
||||||
|
|
||||||
// 移动相机位置
|
// 移动相机位置
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue