fix(fix confilict): conflict

This commit is contained in:
thinkinggis 2019-11-14 18:22:08 +08:00
parent 47d198e2a6
commit 40aba768c6
107 changed files with 2305 additions and 359 deletions

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-99b5b2f90b0432fb92044e231041ffca-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-b627c832a1f77c6bd67b3f67116e04eb-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-30a51869612bca077eda87f35f662bad-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-0b8b19ff19f6a64f7b2cae67200ccd88-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828139761000,"key":"transformer-remark-markdown-toc-99b5b2f90b0432fb92044e231041ffca-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-6e9c5aea4f7ea7c85d806fb35a09a394-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-e0eda26454f7aaeda47989e111060318-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-51cffb57f20c685f94203902c79f04c6-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828184475000,"key":"transformer-remark-markdown-html-94a83b1b7402a40717e5c1b92c85015a-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828139769000,"key":"transformer-remark-markdown-toc-57531815410aa78dc10e42270cb201dd-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":""}

View File

@ -1 +0,0 @@
{"expireTime":9007200828139770000,"key":"transformer-remark-markdown-toc-51dbb367647851670b43ae45a9e937df-gatsby-remark-prettiergatsby-remark-prismjsgatsby-remark-external-linksgatsby-remark-autolink-headersgatsby-remark-reading-time-{\"heading\":null,\"maxDepth\":6,\"pathToSlugField\":\"fields.slug\"}-","val":""}

Binary file not shown.

View File

@ -1,3 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
}

View File

@ -5,7 +5,7 @@ const scene = new Scene({
style: 'light',
pitch: 0,
center: [116.49434030056, 39.868073421167621],
type: 'amap',
type: 'mapbox',
zoom: 16,
});
@ -35,9 +35,9 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/c3f8bda2-081b-449d-aa9f-941
})
.shape('square')
.style({
coverage: 0.8,
coverage: 1.0,
angle: 0,
opacity: 0.6,
opacity: 1.0,
})
.color('count', [
'#002466',
@ -50,6 +50,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/c3f8bda2-081b-449d-aa9f-941
'#730D1C',
]);
scene.addLayer(layer);
console.log(layer);
});

View File

@ -0,0 +1,54 @@
import { HeatMapGridLayer, HeatMapGrid3dLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
const scene = new Scene({
id: 'map',
style: 'light',
pitch: 0,
center: [114.0500, 22.5441],
zoom: 14,
type: 'mapbox',
});
fetch(
'https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json',
)
.then((res) => res.json())
.then((data) => {
const layer = new HeatMapGrid3dLayer({})
.source(data, {
transforms: [
{
type: 'hexagon',
size: 200,
field: 'h12',
method: 'sum',
},
],
})
.size('sum', [0, 600])
.scale('sum', {
type: 'quantize',
})
.shape('hexagon')
.style({
coverage: 0.8,
angle: 0,
opacity: 1.0,
})
.color(
'sum',
[
'#ffffcc',
'#ffeda0',
'#fed976',
'#feb24c',
'#fd8d3c',
'#fc4e2a',
'#e31a1c',
'#bd0026',
'#800026',
].reverse(),
);
scene.addLayer(layer);
console.log(layer);
});

View File

@ -1,5 +1,5 @@
import { Scene } from '@l7/scene';
import { HeatMapGridLayer } from '@l7/layers';
import { HeatMapGridLayer, HeatMapGrid3dLayer } from '@l7/layers';
const scene = new Scene({
id: 'map',
style: 'light',
@ -13,39 +13,34 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64
.then((res) => res.json())
.then((data) => {
const layer =
new HeatMapGridLayer({
new HeatMapGrid3dLayer({
})
.source(data, {
transforms: [
{
type: 'grid',
size: 100000,
type: 'hexagon',
size: 200000,
field: 'capacity',
method: 'sum',
},
],
})
.size('sum', (value) => {
return value;
return value * 50;
})
.scale('sum',{
type:'quantile',
})
.shape('square')
.shape('hexagon')
.style({
coverage: 1,
coverage: 0.9,
angle: 0,
opacity: 1.0,
})
.color('sum', [
'#002466',
'#105CB3',
'#2894E0',
'#CFF6FF',
'#FFF5B8',
'#FFAB5C',
'#F27049',
'#730D1C',
'#2E8AE6',
'#69D1AB',
'#DAF291',
'#FFD591',
'#FF7A45',
'#CF1D49',
]);
scene.addLayer(layer);

View File

@ -4,37 +4,27 @@ const scene = new Scene({
id: 'map',
style: 'dark',
pitch: 0,
center: [116.49434030056, 39.868073421167621],
center: [103.693879, 34.38704],
type: 'mapbox',
zoom: 3,
zoom: 3.69,
});
fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json')
fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json')
.then((res) => res.json())
.then((data) => {
const layer =
new HeatMapLayer({
})
.source(data)
.size('capacity', [0, 1])
.shape('heatmap')
// weight映射通道
.style({
intensity: 10,
radius: 5,
opacity: 1.0,
rampColors: {
colors: [
'#2E8AE6',
'#69D1AB',
'#DAF291',
'#FFD591',
'#FF7A45',
'#CF1D49',
],
positions: [0,0.2, 0.4, 0.6, 0.8, 1.0],
},
});
.source(data).size('mag', [0, 1.0]) // weight映射通道
.style({
intensity: 2,
radius: 20,
opacity: 1.0,
rampColors: {
colors: ['#2E8AE6', '#69D1AB', '#DAF291', '#FFD591', '#FF7A45', '#CF1D49'],
positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0]
}
})
scene.addLayer(layer);

View File

@ -36,6 +36,6 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64
},
});
scene.addLayer(layer);
console.log(layer)
});

View File

@ -1,4 +1,4 @@
---
title: 热力图
title: 经典热力图
order: 0
---

View File

@ -0,0 +1,108 @@
import { HeatMapHexagonLayer, HeatMapGrid3dLayer } from '@l7/layers';
import { Scene } from '@l7/scene';
const scene = new Scene({
id: 'map',
style: 'light',
pitch: 43,
center: [119.9719107,29.4924299],
zoom: 7.2,
type: 'mapbox',
});
window.mapScene = scene;
const colorObj = {
redyellow: [
'#8A191A', '#AE3235',
'#CC464B', '#E26A5D',
'#EC8765', '#F0A66C',
'#F4BC8F', '#FFCEA7',
'#FFE4CE', '#FFF2E8'
],
yellow: [
'#7B320A', '#B35B21',
'#D2722E', '#F0883A',
'#FBA045', '#FAB04B',
'#FAC760', '#FBD78C',
'#FCE6B3', '#FCF3DB'
],
blue_green: [
'#094D4A', '#146968',
'#1D7F7E', '#289899',
'#34B6B7', '#4AC5AF',
'#5FD3A6', '#7BE39E',
'#A1EDB8', '#CEF8D6'
],
blue: [
'#0A3663', '#1558AC',
'#3771D9', '#4D89E5',
'#64A5D3', '#72BED6',
'#83CED6', '#A6E1E0',
'#B8EFE2', '#D7F9F0'
],
purple: [
'#312B60', '#4A457E',
'#615C99', '#816CAD',
'#A67FB5', '#C997C7',
'#DEB8D4', '#F5D4E6',
'#FAE4F1', '#FFF3FC'
],
color1: [
'#E4682F', '#FF8752',
'#FFA783', '#FFBEA8',
'#FFDCD6', '#EEF3FF',
'#C8D7F5', '#A5C1FC',
'#7FA7F9', '#5F8AE5'
],
color2: [
'#F1646A', '#F48789',
'#F7A9AC', '#FBCCCD',
'#FDEEEE', '#EEF3FF',
'#C8DAFE', '#A5C1FC',
'#80A8FB', '#5B8EF8'
],
color3: [
'#EEF3FF', '#C8DAFE',
'#A5C1FC', '#80A8FB',
'#5B8EF8', '#FCF6FA',
'#F5E4EF', '#F7CDDF',
'#ED9CBE', '#D1749B'
]
}
fetch(
'https://gw.alipayobjects.com/os/basement_prod/a1a8158d-6fe3-424b-8e50-694ccf61c4d7.csv',
)
.then((res) => res.text())
.then((data) => {
const layer = new HeatMapGrid3dLayer({})
.source(data, {
parser:{
type:'csv',
x:'lng',
y:'lat',
},
transforms: [
{
type: 'hexagon',
size: 2500,
field: 'v',
method: 'sum',
},
],
})
.size('sum', (sum)=>{
return sum * 200;
})
.shape('hexagon')
.style({
coverage: 0.8,
angle: 0,
opacity: 1.0,
})
.color(
'sum',
colorObj.blue.slice(0,7).reverse(),
);
scene.addLayer(layer);
console.log(layer);
});

View File

@ -0,0 +1,4 @@
---
title: 蜂窝热力图
order: 1
---

View File

@ -1,4 +1,4 @@
---
title: 弧线
title: 弧线地图
order: 1
---

View File

@ -17,7 +17,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json')
})
.source(data)
.size('ELEV', (h) => {
return h % 50 === 0 ? 1.0 : 0.5;
return [h % 50 === 0 ? 1.0 : 0.5, (h -1300) *20 ];
})
.shape('line')
.scale('ELEV', {

View File

@ -5,16 +5,24 @@
},
"demos": [
{
"filename": "path.js",
"title": "路径"
"filename": "road_light.js",
"title": "路径",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*1gddQ6x8Jq4AAAAAAAAAAABkARQnAQ"
},
{
"filename": "line.js",
"title": "等高线"
"title": "等高线",
"screenshot":""
},
{
"filename": "line2.js",
"title": "等值线"
"title": "等值线",
"screenshot":""
},
{
"filename": "road_dark.js",
"title": "路径",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*1FVsSLUncw4AAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -0,0 +1,29 @@
import { Scene } from '@l7/scene';
import { LineLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
center: [116.3956,39.9392],
pitch: 0,
zoom: 10,
rotation: 0,
type: 'mapbox',
style: 'dark',
});
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','#F6BD16' ]
)
scene.addLayer(layer);
console.log(layer);
});

View File

@ -0,0 +1,29 @@
import { Scene } from '@l7/scene';
import { LineLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
center: [116.3956,39.9392],
pitch: 0,
zoom: 10,
rotation: 0,
type: 'mapbox',
style: 'light',
});
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);
console.log(layer);
});

View File

@ -1,4 +1,4 @@
---
title: 路径
title: 路径地图
order: 0
---

View File

@ -0,0 +1,44 @@
import { Scene } from '@l7/scene';
import { Point3dLayer} from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 35.210526315789465,
type: 'amap',
style: 'dark',
center: [108.524505, 29.873128],
zoom: 4.4,
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
.then((res) => res.json())
.then((data) => {
const pointLayer =
new Point3dLayer({
})
.source(data.list, {
parser: {
type: 'json',
x: 'j',
y: 'w'
}
})
.shape('cylinder')
.size('t', function(level) {
return [1, 2, level * 2 + 20];
})
.color('t',[
'#094D4A', '#146968',
'#1D7F7E', '#289899',
'#34B6B7', '#4AC5AF',
'#5FD3A6', '#7BE39E',
'#A1EDB8', '#CEF8D6'
],)
.style({
opacity: 1.0,
})
scene.addLayer(pointLayer);
console.log(pointLayer);
});

View File

@ -0,0 +1,38 @@
import { Scene } from '@l7/scene';
import { Point3dLayer} from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 35.210526315789465,
type: 'amap',
style: 'light',
center: [108.524505, 29.873128],
zoom: 4.4,
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
.then((res) => res.json())
.then((data) => {
const pointLayer =
new Point3dLayer({
})
.source(data.list, {
parser: {
type: 'json',
x: 'j',
y: 'w'
}
})
.shape('cylinder')
.size('t', function(level) {
return [1, 2, level * 2 + 20];
})
.color('#006CFF')
.style({
opacity: 1.0,
})
scene.addLayer(pointLayer);
console.log(pointLayer);
});

View File

@ -0,0 +1,25 @@
{
"title": {
"zh": "中文分类",
"en": "Category"
},
"demos": [
{
"filename": "column_light.js",
"title": "3D柱图_浅色底图",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*5WdiT7MmU_cAAAAAAAAAAABkARQnAQ"
},
{
"filename": "world.js",
"title": "气泡图 - 电厂装机量"
},
{
"filename": "column_dark.js",
"title": "3D柱图_深色底图",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*WkpEQqzuM-oAAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -0,0 +1,38 @@
import { Scene } from '@l7/scene';
import { Point3dLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'light',
center: [121.40, 31.258134],
zoom: 15,
});
fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json')
.then((res) => res.json())
.then((data) => {
const pointLayer =
new Point3dLayer({
})
.source(data, {
parser: {
type: 'json',
x: 'longitude',
y: 'latitude'
}
}).shape('name',['cylinder', 'triangleColumn', 'hexagonColumn'])
.size('unit_price', (h)=>{
return [ 5,5, h / 1000 ]
})
.color('name',['#49B5AD', "#5B8FF9"])
.style({
opacity: 1.0,
})
scene.addLayer(pointLayer);
});

View File

@ -0,0 +1,4 @@
---
title: 3D柱状地图
order: 4
---

View File

@ -0,0 +1,36 @@
import { Scene } from '@l7/scene';
import { PointLayer, PointImageLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'light',
center: [140.067171, 36.26186],
zoom: 5.32,
maxZoom: 10
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json')
.then((res) => res.json())
.then((data) => {
const pointLayer =
new PointLayer({
})
.source(data)
.shape('circle')
.size('mag', [5, 16])
.scale('mag',{
type:'quantile'
})
.color('mag',(mag)=>{
return mag > 4.5? "#5B8FF9" : '#5CCEA1';
})
.style({
opacity: 0.3,
strokeWidth: 1
})
scene.addLayer(pointLayer);
});

View File

@ -5,18 +5,21 @@
},
"demos": [
{
"filename": "point.js",
"title": "气泡图"
"filename": "buble.js",
"title": "气泡图",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_9ETS5_1yCEAAAAAAAAAAABkARQnAQ"
},
{
"filename": "world.js",
"title": "气泡图 - 电厂装机量"
"title": "气泡图 - 电厂装机量",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*DMREQYwsCF4AAAAAAAAAAABkARQnAQ"
},
{
"filename": "text.js",
"title": "文本"
"filename": "normal.js",
"title": "城市亮度图",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Xp7iRaORYuIAAAAAAAAAAABkARQnAQ"
}
]

View File

@ -0,0 +1,36 @@
import { Scene } from '@l7/scene';
import { PointNormalLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 64.88,
type: 'amap',
style: 'dark',
center: [114.060288, 22.53684],
zoom: 15.63,
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7aa5236699.json')
.then((res) => res.json())
.then((data) => {
const pointLayer =
new PointNormalLayer({
})
.source(data)
.size(2)
.color('h8',[
'#0A3663', '#1558AC',
'#3771D9', '#4D89E5',
'#64A5D3', '#72BED6',
'#83CED6', '#A6E1E0',
'#B8EFE2', '#D7F9F0'
])
.style({
opacity:1.,
})
scene.addLayer(pointLayer);
})

View File

@ -5,24 +5,26 @@ const scene = new Scene({
pitch: 0,
type: 'mapbox',
style: 'dark',
center: [121.40, 31.258134],
zoom: 1,
center: [ 96.99215001469588, 29.281597225674773],
zoom: 2.194613775109773,
maxZoom: 10
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json')
.then((res) => res.json())
.then((data) => {
data.features = data.features.filter(item=>{
return item.properties.capacity> 800;
})
const pointLayer =
new PointLayer({
})
.source(data).shape('circle')
.size('capacity', [0, 20])
.color('status', ['#ced1cc','#ffc83e','#ff8767','#dd54b6','#a45edb'])
.size('capacity', [0, 16])
.color('capacity',['#34B6B7', '#4AC5AF','#5FD3A6', '#7BE39E','#A1EDB8', '#CEF8D6'])
.style({
opacity: 0.3,
strokeWidth: 1,
opacity: 0.5,
strokeWidth: 0
})
scene.addLayer(pointLayer);

View File

@ -1,5 +1,5 @@
---
title: 气泡图
title: 气泡
order: 0
redirect_from:
- /zh/examples

View File

@ -0,0 +1,141 @@
import { Scene } from '@l7/scene';
import { Marker } from '@l7/component'
import * as G2Plot from '@antv/g2plot'
const scene = new Scene({
id: 'map',
type: 'amap',
style: 'light',
center: [-122.80009283836715, 37.05881309947238],
pitch: 0,
zoom: 5
});
// fetch('https://gw.alipayobjects.com/os/basement_prod/0b96cca4-7e83-449a-93d0-2a77053e74ab.json')
// .then((res) => res.text())
// .then((data) => {
// data.nodes.forEach(function (item) {
// const el = document.createElement('div');
// const total = item.gdp.Agriculture + item.gdp.Industry + item.gdp.Service;
// const size = Math.max(Math.min(parseInt(total / 20000), 150), 30);
// const itemData = [{
// item: 'Agriculture',
// count: item.gdp.Agriculture,
// percent: item.gdp.Agriculture / total
// }, {
// item: 'Industry',
// count: item.gdp.Industry,
// percent: item.gdp.Industry / total
// }, {
// item: 'Service',
// count: item.gdp.Service,
// percent: item.gdp.Service / total
// }];
// const config = {
// "title": {
// "visible": false,
// "text": "环图",
// "style": {
// "fill": "rgba(0, 0, 0, 0.85)"
// }
// },
// "description": {
// "visible": false,
// "text": "一个简单的环图",
// "style": {
// "fill": "rgba(0, 0, 0, 0.85)",
// "bottom_margin": 10
// }
// },
// "padding": "auto",
// "legend": {
// "visible": false,
// "position": "top-left"
// },
// "tooltip": {
// "visible": false,
// "shared": false,
// "crosshairs": null
// },
// "xAxis": {
// "visible": true,
// "autoHideLabel": false,
// "autoRotateLabel": false,
// "autoRotateTitle": false,
// "grid": {
// "visible": false
// },
// "line": {
// "visible": false
// },
// "tickLine": {
// "visible": true
// },
// "label": {
// "visible": true
// },
// "title": {
// "visible": false,
// "offset": 12
// }
// },
// "yAxis": {
// "visible": true,
// "autoHideLabel": false,
// "autoRotateLabel": false,
// "autoRotateTitle": true,
// "grid": {
// "visible": true
// },
// "line": {
// "visible": false
// },
// "tickLine": {
// "visible": false
// },
// "label": {
// "visible": true
// },
// "title": {
// "visible": false,
// "offset": 12
// }
// },
// "label": {
// "visible": true,
// "type": "outer",
// "style": {
// "fill": "rgba(0, 0, 0, 0.65)"
// }
// },
// "width": 317,
// "height": 249,
// "forceFit": false,
// "radius": 1,
// "pieStyle": {
// "stroke": "white",
// "lineWidth": 1
// },
// "innerRadius": 0.74,
// "animation": false,
// "colorField": "x",
// "angleField": "y",
// "color": null
// }
// const plot = new G2Plot.Ring(el, {
// data: itemData,
// ...config,
// });
// plot.render();
// var popup = new L7.Popup({
// anchor: 'left'
// }).setText(item.name);
// new Marker({
// element: el
// }).setLnglat(item.coordinates).setPopup(popup).addTo(scene);
// });
// });

View File

@ -0,0 +1,14 @@
{
"title": {
"zh": "中文分类",
"en": "Category"
},
"demos": [
{
"filename": "normal.js",
"title": "海量点",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Kva7R7AimzsAAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -0,0 +1,4 @@
---
title: 复合图表地图
order: 7
---

View File

@ -0,0 +1,4 @@
---
title: "聚合地图"
order: 6
---

View File

@ -1,4 +1,4 @@
---
title: 符号图
order: 1
title: 符号
order: 2
---

View File

@ -0,0 +1,14 @@
{
"title": {
"zh": "中文分类",
"en": "Category"
},
"demos": [
{
"filename": "normal.js",
"title": "海量点",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Kva7R7AimzsAAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -0,0 +1,34 @@
import { Scene } from '@l7/scene';
import { PointNormalLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
type: 'amap',
style: 'dark',
center: [121.417463, 31.215175],
pitch: 0,
zoom: 11
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/rmsportal/BElVQFEFvpAKzddxFZxJ.txt')
.then((res) => res.text())
.then((data) => {
const pointLayer =
new PointNormalLayer({
})
.source(data, {
parser: {
type: 'csv',
y: 'lat',
x: 'lng'
}
}).size(0.5)
.color('#080298')
.style({
opacity:1.,
})
scene.addLayer(pointLayer);
})

View File

@ -0,0 +1,94 @@
import { Scene } from '@l7/scene';
import { PointLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
type: 'amap',
style: 'light',
center: [-122.80009283836715, 37.05881309947238],
pitch: 0,
zoom: 5.740491857794806
});
const colorObj = {
redyellow: [
'#8A191A', '#AE3235',
'#CC464B', '#E26A5D',
'#EC8765', '#F0A66C',
'#F4BC8F', '#FFCEA7',
'#FFE4CE', '#FFF2E8'
],
yellow: [
'#7B320A', '#B35B21',
'#D2722E', '#F0883A',
'#FBA045', '#FAB04B',
'#FAC760', '#FBD78C',
'#FCE6B3', '#FCF3DB'
],
blue_green: [
'#094D4A', '#146968',
'#1D7F7E', '#289899',
'#34B6B7', '#4AC5AF',
'#5FD3A6', '#7BE39E',
'#A1EDB8', '#CEF8D6'
],
blue: [
'#0A3663', '#1558AC',
'#3771D9', '#4D89E5',
'#64A5D3', '#72BED6',
'#83CED6', '#A6E1E0',
'#B8EFE2', '#D7F9F0'
],
purple: [
'#312B60', '#4A457E',
'#615C99', '#816CAD',
'#A67FB5', '#C997C7',
'#DEB8D4', '#F5D4E6',
'#FAE4F1', '#FFF3FC'
],
color1: [
'#E4682F', '#FF8752',
'#FFA783', '#FFBEA8',
'#FFDCD6', '#EEF3FF',
'#C8D7F5', '#A5C1FC',
'#7FA7F9', '#5F8AE5'
],
color2: [
'#F1646A', '#F48789',
'#F7A9AC', '#FBCCCD',
'#FDEEEE', '#EEF3FF',
'#C8DAFE', '#A5C1FC',
'#80A8FB', '#5B8EF8'
],
color3: [
'#EEF3FF', '#C8DAFE',
'#A5C1FC', '#80A8FB',
'#5B8EF8', '#FCF6FA',
'#F5E4EF', '#F7CDDF',
'#ED9CBE', '#D1749B'
]
}
fetch('https://gw.alipayobjects.com/os/basement_prod/6c4bb5f2-850b-419d-afc4-e46032fc9f94.csv')
.then((res) => res.text())
.then((data) => {
const pointLayer =
new PointLayer({
})
.source(data,{
parser:{
type:'csv',
x:'Longitude',
y:'Latitude'
}
})
.shape('circle')
.size(4)
.color('Magnitude',colorObj.yellow)
.style({
opacity: 0.5,
strokeWidth: 0,
})
scene.addLayer(pointLayer);
});

View File

@ -0,0 +1,4 @@
---
title: "散点地图"
order: 1
---

View File

@ -0,0 +1,121 @@
import { Scene } from '@l7/scene';
import { Polygon3DLayer } from '@l7/layers'
const colorObj = {
redyellow: [
'#8A191A', '#AE3235',
'#CC464B', '#E26A5D',
'#EC8765', '#F0A66C',
'#F4BC8F', '#FFCEA7',
'#FFE4CE', '#FFF2E8'
],
yellow: [
'#7B320A', '#B35B21',
'#D2722E', '#F0883A',
'#FBA045', '#FAB04B',
'#FAC760', '#FBD78C',
'#FCE6B3', '#FCF3DB'
],
blue_green: [
'#094D4A', '#146968',
'#1D7F7E', '#289899',
'#34B6B7', '#4AC5AF',
'#5FD3A6', '#7BE39E',
'#A1EDB8', '#CEF8D6'
],
blue: [
'#0A3663', '#1558AC',
'#3771D9', '#4D89E5',
'#64A5D3', '#72BED6',
'#83CED6', '#A6E1E0',
'#B8EFE2', '#D7F9F0'
],
purple: [
'#312B60', '#4A457E',
'#615C99', '#816CAD',
'#A67FB5', '#C997C7',
'#DEB8D4', '#F5D4E6',
'#FAE4F1', '#FFF3FC'
],
color1: [
'#E4682F', '#FF8752',
'#FFA783', '#FFBEA8',
'#FFDCD6', '#EEF3FF',
'#C8D7F5', '#A5C1FC',
'#7FA7F9', '#5F8AE5'
],
color2: [
'#F1646A', '#F48789',
'#F7A9AC', '#FBCCCD',
'#FDEEEE', '#EEF3FF',
'#C8DAFE', '#A5C1FC',
'#80A8FB', '#5B8EF8'
],
color3: [
'#EEF3FF', '#C8DAFE',
'#A5C1FC', '#80A8FB',
'#5B8EF8', '#FCF6FA',
'#F5E4EF', '#F7CDDF',
'#ED9CBE', '#D1749B'
]
}
const scene = new Scene({
id: 'map',
type: 'amap',
style: 'dark',
center: [120.173104, 30.244072],
pitch: 66.50572,
zoom: 15.79,
minZoom: 10
});
const polygon ={
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
114.05817031860352,
22.543714416963457
],
[
114.07087326049805,
22.543714416963457
],
[
114.07087326049805,
22.55504986643093
],
[
114.05817031860352,
22.55504986643093
],
[
114.05817031860352,
22.543714416963457
]
]
]
}
}
]
}
fetch('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json')
.then((res) => res.json())
.then((data) => {
const layer =
new Polygon3DLayer ({
})
.source(data)
.shape('extrude')
.size('floor', [10, 200])
.color('rgba(242,246,250,0.96)')
.style({
opacity: 1.0
}).render();
scene.addLayer(layer);
console.log(layer);
});

View File

@ -0,0 +1,13 @@
{
"title": {
"zh": "中文分类",
"en": "Category"
},
"demos": [
{
"filename": "polygon.js",
"title": "3D 建筑面",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*JgXVSoV03n4AAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -0,0 +1,30 @@
import { Scene } from '@l7/scene';
import { Polygon3DLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 15.05263,
type: 'amap',
style: 'dark',
center: [114.056128, 22.529272],
zoom: 14.2,
});
window.mapScene = scene;
fetch('https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae9d0eb0117.json')
.then((res) => res.json())
.then((data) => {
const layer =
new Polygon3DLayer ({
})
.source(data)
.shape('fill')
.size('h20',[100, 120, 160, 200, 260, 500])
.color('h20', ['#816CAD',
'#A67FB5', '#C997C7',
'#DEB8D4', '#F5D4E6',
'#FAE4F1', '#FFF3FC'])
.style({
opacity: 1.0
});
scene.addLayer(layer);
});

View File

@ -0,0 +1,4 @@
---
title: 3D填充图
order: 0
---

View File

@ -0,0 +1,84 @@
import { Scene } from '@l7/scene';
import { PolygonLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'light',
center: [116.3237, 39.8829],
zoom: 8
});
const colorObj = {
redyellow: [
'#8A191A', '#AE3235',
'#CC464B', '#E26A5D',
'#EC8765', '#F0A66C',
'#F4BC8F', '#FFCEA7',
'#FFE4CE', '#FFF2E8'
],
yellow: [
'#7B320A', '#B35B21',
'#D2722E', '#F0883A',
'#FBA045', '#FAB04B',
'#FAC760', '#FBD78C',
'#FCE6B3', '#FCF3DB'
],
blue_green: [
'#094D4A', '#146968',
'#1D7F7E', '#289899',
'#34B6B7', '#4AC5AF',
'#5FD3A6', '#7BE39E',
'#A1EDB8', '#CEF8D6'
],
blue: [
'#0A3663', '#1558AC',
'#3771D9', '#4D89E5',
'#64A5D3', '#72BED6',
'#83CED6', '#A6E1E0',
'#B8EFE2', '#D7F9F0'
],
purple: [
'#312B60', '#4A457E',
'#615C99', '#816CAD',
'#A67FB5', '#C997C7',
'#DEB8D4', '#F5D4E6',
'#FAE4F1', '#FFF3FC'
],
color1: [
'#E4682F', '#FF8752',
'#FFA783', '#FFBEA8',
'#FFDCD6', '#EEF3FF',
'#C8D7F5', '#A5C1FC',
'#7FA7F9', '#5F8AE5'
],
color2: [
'#F1646A', '#F48789',
'#F7A9AC', '#FBCCCD',
'#FDEEEE', '#EEF3FF',
'#C8DAFE', '#A5C1FC',
'#80A8FB', '#5B8EF8'
],
color3: [
'#EEF3FF', '#C8DAFE',
'#A5C1FC', '#80A8FB',
'#5B8EF8', '#FCF6FA',
'#F5E4EF', '#F7CDDF',
'#ED9CBE', '#D1749B'
]
}
fetch('https://gw.alipayobjects.com/os/basement_prod/1d27c363-af3a-469e-ab5b-7a7e1ce4f311.json')
.then((res) => res.json())
.then((data) => {
const layer =
new PolygonLayer({
})
.source(data)
.color('unit_price', colorObj.blue_green)
.shape('fill')
.style({
opacity: 1
})
scene.addLayer(layer);
console.log(layer);
});

View File

@ -5,9 +5,14 @@
},
"demos": [
{
"filename": "point.js",
"title": "面图层",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*KCyXTJrePiYAAAAAAAAAAABkARQnAQ"
"filename": "polygon.js",
"title": "全国地图行政区划",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*AoD6SZ4kz0wAAAAAAAAAAABkARQnAQ"
},
{
"filename": "fill.js",
"title": "北京房价填充图",
"screenshot": ""
}
]
}

View File

@ -5,8 +5,8 @@ const scene = new Scene({
pitch: 0,
type: 'amap',
style: 'light',
center: [121.40, 31.258134],
zoom: 3,
center: [102.430994, 29.877025],
zoom: 3.52,
});
fetch('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json')

View File

@ -1,5 +1,5 @@
---
title: 面图层
title: 填充地图
order: 0
redirect_from:
- /zh/examples

View File

@ -0,0 +1,25 @@
import { Scene } from '@l7/scene';
import { ImageLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'light',
center: [121.2680, 30.3628],
zoom: 13,
});
const layer = new ImageLayer({});
layer.source(
'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
{
parser: {
type: 'image',
extent: [121.168, 30.2828, 121.384, 30.4219],
},
},
);
scene.on('loaded',()=>{
scene.addLayer(layer);
})

View File

@ -1,39 +0,0 @@
import { Scene } from '@l7/scene';
import { LineLayer } from '@l7/layers'
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'mapbox',
style: 'light',
center: [102.602992, 23.107329],
zoom: 13,
});
fetch('https://gw.alipayobjects.com/os/rmsportal/ZVfOvhVCzwBkISNsuKCc.json')
.then((res) => res.json())
.then((data) => {
const layer =
new LineLayer({
})
.source(data)
.size(1)
.shape('line')
.color(
'ELEV',
[
'#E8FCFF',
'#CFF6FF',
'#A1E9ff',
'#65CEF7',
'#3CB1F0',
'#2894E0',
'#1772c2',
'#105CB3',
'#0D408C',
'#002466',
].reverse(),
)
scene.addLayer(layer);
console.log(layer);
});

View File

@ -1,13 +1,17 @@
{
"title": {
"zh": "图库",
"zh": "栅格图层",
"en": "Gallery"
},
"demos": [
{
"filename": "line.js",
"title": "线图层",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*KCyXTJrePiYAAAAAAAAAAABkARQnAQ"
"filename": "image.js",
"title": "图片",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*ZrCaR53185IAAAAAAAAAAABkARQnAQ"
},
{
"filename": "raster.js",
"title": "地形"
}
]
}

View File

@ -0,0 +1,70 @@
import { Scene } from '@l7/scene';
import { RasterLayer } from '@l7/layers'
// import * as GeoTIFF from 'geotiff/dist/geotiff.bundle.js';
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'light',
center: [121.2680, 30.3628],
zoom: 13,
});
async function addLayer() {
const tiffdata = await this.getTiffData();
const layer = new RasterLayer({});
layer
.source(tiffdata.data, {
parser: {
type: 'raster',
width: tiffdata.width,
height: tiffdata.height,
min: 0,
max: 8000,
extent: [73.482190241, 3.82501784112, 135.106618732, 57.6300459963],
},
})
.style({
opacity: 0.8,
rampColors: {
colors: [
'#002466',
'#0D408C',
'#105CB3',
'#1A76C7',
'#2894E0',
'#3CB4F0',
'#65CEF7',
'#98E3FA',
'#CFF6FF',
'#E8FCFF',
],
positions: [0, 0.02, 0.05, 0.1, 0.2, 0.3, 0.5, 0.6, 0.8, 1.0],
},
});
return layer;
}
addLayer()
scene.on('loaded',()=>{
const layer = addLayer();
scene.addLayer(layer);
})
async function getTiffData() {
const response = await fetch(
'https://gw.alipayobjects.com/os/rmsportal/XKgkjjGaAzRyKupCBiYW.dat',
);
const arrayBuffer = await response.arrayBuffer();
const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer);
const image = await tiff.getImage();
const width = image.getWidth();
const height = image.getHeight();
const values = await image.readRasters();
return {
data: values[0],
width,
height,
min: 0,
max: 8000,
};
}

View File

@ -0,0 +1,57 @@
import { Scene } from '@l7/scene';
import { PointLayer } from '@l7/layers'
import { Scale, Zoom, Layers } from '@l7/component';
const scene = new Scene({
id: 'map',
pitch: 0,
type: 'amap',
style: 'dark',
center: [121.40, 31.258134],
zoom: 5,
});
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('circle')
.size('unit_price', [5, 25])
.color('name',['#49B5AD', "#5B8FF9"])
.style({
opacity: 0.3,
strokeWidth: 1,
})
scene.addLayer(pointLayer);
var overlayers = {
"围栏填充": pointLayer,
};
var baseLayers = {
"基础地图": pointLayer,
};
const layersControl = new Layers({
overlayers: overlayers,
baseLayers,
});
scene.addControl(layersControl);
});
const zoomControl = new Zoom();
const scaleControl = new Scale();
scene.addControl(zoomControl);
scene.addControl(scaleControl);

View File

@ -1,5 +1,7 @@
import './packages/component/src/css/l7.css';
// window.GeoTIFF = require('geotiff/dist/geotiff.bundle.js')
window.scene = require('@l7/scene');
window.layers= require('@l7/layers');
window.component= require('@l7/component');
window.G2Plot = require('@antv/g2plot');

View File

@ -4,6 +4,11 @@ module.exports = {
resolve: '@antv/gatsby-theme-antv',
options: {
pathPrefix: '/gatsby-theme-antv',
GATrackingId: 'UA-148148901-7',
pathPrefix: '/l7',
theme: {
'primary-color': '#722ED1',
},
},
},
],

View File

@ -131,5 +131,9 @@
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"dependencies": {
"@antv/g2plot": "^0.1.0-beta.5",
"geotiff": "^1.0.0-beta.6"
}
}

View File

@ -791,8 +791,8 @@
padding: 8px;
}
.l7-control-layers label input[type="radio"], input[type="checkbox"]{
width: 19px;
height: 19px;
width: 14px;
height: 14px;
margin: 0;
vertical-align: middle;
-ms-transform: scale(1.5); /* IE 9 */

View File

@ -5,9 +5,11 @@ import { IModuleParams, IShaderModuleService } from './IShaderModuleService';
import common from '../../shaders/common.glsl';
import decode from '../../shaders/decode.glsl';
import light from '../../shaders/light.glsl';
import lighting from '../../shaders/lighting.glsl';
import pickingFrag from '../../shaders/picking.frag.glsl';
import pickingVert from '../../shaders/picking.vert.glsl';
import project from '../../shaders/project.glsl';
import projection from '../../shaders/projection.glsl';
import sdf2d from '../../shaders/sdf_2d.glsl';
@ -26,8 +28,10 @@ export default class ShaderModuleService implements IShaderModuleService {
this.registerModule('common', { vs: common, fs: common });
this.registerModule('decode', { vs: decode, fs: '' });
this.registerModule('projection', { vs: projection, fs: '' });
this.registerModule('project', { vs: project, fs: '' });
this.registerModule('sdf_2d', { vs: '', fs: sdf2d });
this.registerModule('lighting', { vs: lighting, fs: '' });
this.registerModule('light', { vs: light, fs: '' });
this.registerModule('picking', { vs: pickingVert, fs: pickingFrag });
}

View File

@ -0,0 +1,25 @@
#define ambientRatio 0.5
#define diffuseRatio 0.3
#define specularRatio 0.2
float calc_lighting(vec4 pos) {
vec3 worldPos = vec3(pos * u_ModelMatrix);
vec3 worldNormal = vec3(vec4(a_Normal,1.0));
// //cal light weight
vec3 viewDir = normalize(u_CameraPosition - worldPos);
vec3 lightDir = normalize(vec3(1, -10.5, 12));
vec3 halfDir = normalize(viewDir+lightDir);
// //lambert
float lambert = dot(worldNormal, lightDir);
//specular
float specular = pow( max(0.0, dot(worldNormal, halfDir)), 32.0);
//sum to light weight
float lightWeight = ambientRatio + diffuseRatio * lambert + specularRatio * specular;
return lightWeight;
}

View File

@ -0,0 +1,34 @@
#define E 2.718281828459045
vec2 ProjectFlat(vec2 lnglat){
float maxs=85.0511287798;
float lat=max(min(maxs,lnglat.y),-maxs);
float scale= 268435456.;
float d=PI/180.;
float x=lnglat.x*d;
float y=lat*d;
y=log(tan((PI/4.)+(y/2.)));
float a=.5/PI,
b=.5,
c=-.5/PI;
d=.5;
x=scale*(a*x+b);
y=scale*(c*y+d);
return vec2(x,y);
}
vec2 unProjectFlat(vec2 px){
float a=.5/PI;
float b=.5;
float c=-.5/PI;
float d=.5;
float scale = 268435456.;
float x=(px.x/scale-b)/a;
float y=(px.y/scale-d)/c;
y=(atan(pow(E,y))-(PI/4.))*2.;
d=PI/180.;
float lat=y/d;
float lng=x/d;
return vec2(lng,lat);
}

View File

@ -41,6 +41,7 @@ float project_scale(float meters) {
return meters * u_PixelsPerMeter.z;
}
// offset coords -> world coords
vec4 project_offset(vec4 offset) {
float dy = offset.y;
@ -103,6 +104,14 @@ vec2 project_pixel_size_to_clipspace(vec2 pixels) {
return offset * u_FocalDistance;
}
float project_pixel(float pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// P20 坐标系下,为了和 Web 墨卡托坐标系统一zoom 默认减1
return pixel * pow(2.0, (19.0 - u_Zoom));
}
return pixel;
}
vec2 project_pixel(vec2 pixel) {
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {

View File

@ -45,7 +45,7 @@ export function triangle(): IPath {
return polygonPath(3);
}
export function hexagon(): IPath {
return polygonPath(6);
return polygonPath(6, 1);
}
export function pentagon(): IPath {
return polygonPath(5);

View File

@ -1,8 +1,11 @@
import { lngLatToMeters } from '@l7/utils';
import earcut from 'earcut';
import { vec3 } from 'gl-matrix';
import { IPath } from './Path';
export interface IExtrudeGeomety {
positions: number[];
index: number[];
normals?: number[];
}
/**
*
@ -41,8 +44,8 @@ export default function extrudePolygon(path: IPath[]): IExtrudeGeomety {
(i + 1) * dimensions,
);
let nextPoint = flattengeo.vertices.slice(
(i + 1) * dimensions,
(i + 2) * dimensions,
(i + 3) * dimensions,
);
if (nextPoint.length === 0) {
nextPoint = flattengeo.vertices.slice(0, dimensions);
@ -62,7 +65,7 @@ export default function extrudePolygon(path: IPath[]): IExtrudeGeomety {
nextPoint[1],
0,
);
indexArray.push(...[1, 2, 0, 3, 2, 1].map((v) => v + indexOffset));
indexArray.push(...[0, 2, 1, 2, 3, 1].map((v) => v + indexOffset));
}
return {
positions,
@ -81,3 +84,102 @@ export function fillPolygon(points: IPath[]) {
index: triangles,
};
}
export function extrude_PolygonNormal(
path: IPath[],
needFlat = false,
): IExtrudeGeomety {
const p1 = path[0][0];
const p2 = path[0][path[0].length - 1];
if (p1[0] === p2[0] && p1[1] === p2[1]) {
path[0] = path[0].slice(0, path[0].length - 1);
}
const n = path[0].length;
const flattengeo = earcut.flatten(path);
const { vertices, dimensions } = flattengeo;
const positions = [];
const indexArray = [];
const normals = [];
// 设置顶部z值
for (let j = 0; j < vertices.length / dimensions; j++) {
if (dimensions === 2) {
positions.push(vertices[j * 2], vertices[j * 2 + 1], 1);
} else {
positions.push(vertices[j * 3], vertices[j * 3 + 1], 1);
}
normals.push(0, 0, 1);
}
const triangles = earcut(
flattengeo.vertices,
flattengeo.holes,
flattengeo.dimensions,
);
indexArray.push(...triangles);
for (let i = 0; i < n; i++) {
const prePoint = flattengeo.vertices.slice(
i * dimensions,
(i + 1) * dimensions,
);
let nextPoint = flattengeo.vertices.slice(
(i + 1) * dimensions,
(i + 2) * dimensions,
);
if (nextPoint.length === 0) {
nextPoint = flattengeo.vertices.slice(0, dimensions);
}
const indexOffset = positions.length / 3;
positions.push(
prePoint[0],
prePoint[1],
1,
nextPoint[0],
nextPoint[1],
1,
prePoint[0],
prePoint[1],
0,
nextPoint[0],
nextPoint[1],
0,
);
const normal = computeVertexNormals(
[nextPoint[0], nextPoint[1], 1],
[prePoint[0], prePoint[1], 0],
[prePoint[0], prePoint[1], 1],
needFlat,
);
normals.push(...normal, ...normal, ...normal, ...normal);
indexArray.push(...[1, 2, 0, 3, 2, 1].map((v) => v + indexOffset));
}
return {
positions,
index: indexArray,
normals,
};
}
function computeVertexNormals(
p1: [number, number, number],
p2: [number, number, number],
p3: [number, number, number],
needFlat: boolean = false,
) {
const cb = vec3.create();
const ab = vec3.create();
const normal = vec3.create();
if (needFlat) {
p1 = lngLatToMeters(p1) as [number, number, number];
p2 = lngLatToMeters(p2) as [number, number, number];
p3 = lngLatToMeters(p3) as [number, number, number];
}
const pA = vec3.fromValues(...p1);
const pB = vec3.fromValues(...p2);
const pC = vec3.fromValues(...p3);
vec3.sub(cb, pC, pB);
vec3.sub(ab, pA, pB);
vec3.cross(normal, cb, ab);
const newNormal = vec3.create();
vec3.normalize(newNormal, normal);
return newNormal;
}

View File

@ -1,13 +1,19 @@
import { IEncodeFeature } from '@l7/core';
import { aProjectFlat, lngLatToMeters } from '@l7/utils';
import { vec3 } from 'gl-matrix';
import getNormals from '../utils/polylineNormal';
import extrudePolygon, { fillPolygon, IExtrudeGeomety } from './shape/extrude';
import extrudePolygon, {
extrude_PolygonNormal,
fillPolygon,
IExtrudeGeomety,
} from './shape/extrude';
import {
geometryShape,
IPosition,
ShapeType2D,
ShapeType3D,
} from './shape/Path';
type IShape = ShapeType2D & ShapeType3D;
interface IGeometryCache {
[key: string]: IExtrudeGeomety;
}
@ -31,11 +37,15 @@ export function PointFillTriangulation(feature: IEncodeFeature) {
*/
export function PointExtrudeTriangulation(feature: IEncodeFeature) {
const { shape } = feature;
const { positions, index } = getGeometry(shape as ShapeType3D);
const { positions, index, normals } = getGeometry(
shape as ShapeType3D,
false,
);
return {
vertices: positions,
indices: index,
normals: Array.from(computeVertexNormals(positions, index)),
normals,
// normals: Array.from(computeVertexNormals(positions, index, 3, false)),
size: 3,
};
}
@ -70,12 +80,15 @@ export function LineTriangulation(feature: IEncodeFeature) {
export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as IPosition[][];
const { positions, index } = extrudePolygon(coordinates);
const { positions, index, normals } = extrude_PolygonNormal(
coordinates,
true,
);
return {
vertices: positions, // [ x, y, z ]
indices: index,
normals: Array.from(computeVertexNormals(positions, index)),
normals,
size: 3,
};
}
@ -83,13 +96,10 @@ export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
export function HeatmapGridTriangulation(feature: IEncodeFeature) {
const { shape } = feature;
const { positions, index } = getHeatmapGeometry(
shape as ShapeType2D | ShapeType3D,
);
const { positions, index } = getHeatmapGeometry(shape as IShape);
return {
vertices: positions, // [ x, y, z ] 多边形顶点
indices: index,
normals: Array.from(computeVertexNormals(positions, index)),
size: 3,
};
}
@ -213,14 +223,14 @@ export function HeatmapTriangulation(feature: IEncodeFeature) {
* 3d geomerty
* @param shape 3D形状
*/
function getGeometry(shape: ShapeType3D): IExtrudeGeomety {
function getGeometry(shape: ShapeType3D, needFlat = false): IExtrudeGeomety {
if (GeometryCache && GeometryCache[shape]) {
return GeometryCache[shape];
}
const path = geometryShape[shape]
? geometryShape[shape]()
: geometryShape.cylinder();
const geometry = extrudePolygon([path]);
const geometry = extrude_PolygonNormal([path], needFlat);
GeometryCache[shape] = geometry;
return geometry;
}
@ -229,6 +239,7 @@ function computeVertexNormals(
positions: number[],
indexArray: number[],
dim: number = 3,
needFlat: boolean = false,
) {
const normals = new Float32Array((positions.length / dim) * 3);
let vA: number;
@ -241,11 +252,19 @@ function computeVertexNormals(
vA = indexArray[i + 0] * 3;
vB = indexArray[i + 1] * 3;
vC = indexArray[i + 2] * 3;
const [ax, ay] = [positions[vA], positions[vA + 1]];
let p1 = [positions[vA], positions[vA + 1]];
let p2 = [positions[vB], positions[vB + 1]];
let p3 = [positions[vC], positions[vC + 1]];
if (needFlat) {
p1 = lngLatToMeters(p1);
p2 = lngLatToMeters(p2);
p3 = lngLatToMeters(p3);
}
const [ax, ay] = p1;
const pA = vec3.fromValues(ax, ay, positions[vA + 2]);
const [bx, by] = [positions[vB], positions[vB + 1]];
const [bx, by] = p2;
const pB = vec3.fromValues(bx, by, positions[vB + 2]);
const [cx, cy] = [positions[vC], positions[vC + 1]];
const [cx, cy] = p3;
const pC = vec3.fromValues(cx, cy, positions[vC + 2]);
vec3.sub(cb, pC, pB);
vec3.sub(ab, pA, pB);

View File

@ -0,0 +1,124 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { PointExtrudeTriangulation } from '../core/triangulation';
import heatmapGrid3dVert from './shaders/hexagon_3d_vert.glsl';
import heatmapGridFrag from './shaders/hexagon_frag.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
}
export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
public name: string = 'hexgaon';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const { opacity, coverage } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_coverage: coverage || 1.0,
u_radius: [
this.getSource().data.xOffset,
this.getSource().data.yOffset,
],
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'grid3dheatmap',
vertexShader: heatmapGrid3dVert,
fragmentShader: heatmapGridFrag,
triangulation: PointExtrudeTriangulation,
depth: { enable: true },
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'pos', // 顶点经纬度位置
type: AttributeType.Attribute,
descriptor: {
name: 'a_Pos',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (feature: IEncodeFeature, featureIdx: number) => {
const coordinates = feature.coordinates as number[];
return [coordinates[0], coordinates[1], 0];
},
},
});
}
}

View File

@ -1,14 +1,14 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { HeatmapGridTriangulation } from '../core/triangulation';
import heatmapGridVert from './shaders/grid_vert.glsl';
import heatmapGridFrag from './shaders/hexagon_frag.glsl';
import heatmapGridVert from './shaders/hexagon_vert.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
}
export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
public name: string = 'PointLayer';
public name: string = 'heatMapGridLayer';
protected getConfigSchema() {
return {
@ -28,7 +28,7 @@ export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
model.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_coverage: coverage || 1.0,
u_coverage: coverage || 0.9,
u_radius: [
this.getSource().data.xOffset,
this.getSource().data.yOffset,
@ -48,6 +48,7 @@ export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
fragmentShader: heatmapGridFrag,
triangulation: HeatmapGridTriangulation,
depth: { enable: false },
primitive: gl.TRIANGLES,
}),
];
}
@ -65,7 +66,7 @@ export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
data: [],
type: gl.FLOAT,
},
size: 3,
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
@ -79,29 +80,6 @@ export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
layer.styleAttributeService.registerStyleAttribute({
name: 'pos', // 顶点经纬度位置
type: AttributeType.Attribute,

View File

@ -56,7 +56,9 @@ export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
protected renderModels() {
const { clear, useFramebuffer } = this.rendererService;
const shapeAttr = this.styleAttributeService.getLayerStyleAttribute('shape');
const shapeAttr = this.styleAttributeService.getLayerStyleAttribute(
'shape',
);
const shapeType = shapeAttr?.scale?.field || 'heatmap';
useFramebuffer(this.heatmapFramerBuffer, () => {
clear({
@ -68,18 +70,23 @@ export default class HeatMapLayer extends BaseLayer<IHeatMapLayerStyleOptions> {
this.drawIntensityMode();
});
// this.draw3DHeatMap();
shapeType === 'heatmap' ? this.drawColorMode(): this.draw3DHeatMap();
shapeType === 'heatmap' ? this.drawColorMode() : this.draw3DHeatMap();
// this.drawIntensityMode();
return this;
}
protected buildModels() {
const shapeAttr = this.styleAttributeService.getLayerStyleAttribute('shape');
const shapeAttr = this.styleAttributeService.getLayerStyleAttribute(
'shape',
);
const shapeType = shapeAttr?.scale?.field || 'heatmap';
this.registerBuiltinAttributes(this);
this.intensityModel = this.buildHeatMapIntensity();
this.models = [this.intensityModel];
this.colorModel = shapeType === 'heatmap' ? this.buildHeatmapColor(): this.build3dHeatMap();
this.colorModel =
shapeType === 'heatmap'
? this.buildHeatmapColor()
: this.build3dHeatMap();
this.models.push(this.colorModel);
const { rampColors } = this.getStyleOptions();
const imageData = generateColorRamp(rampColors as IColorRamp);

View File

@ -0,0 +1,102 @@
import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { HeatmapGridTriangulation } from '../core/triangulation';
import heatmapGridFrag from './shaders/hexagon_frag.glsl';
import heatmapGridVert from './shaders/hexagon_vert.glsl';
interface IHeatMapLayerStyleOptions {
opacity: number;
coverage: number;
}
export default class HeatMapGrid extends BaseLayer<IHeatMapLayerStyleOptions> {
public name: string = 'heatMapGridLayer';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const { opacity, coverage } = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_opacity: opacity || 1.0,
u_coverage: coverage || 0.9,
u_radius: [
this.getSource().data.xOffset,
this.getSource().data.yOffset,
],
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'hexagonheatmap',
vertexShader: heatmapGridVert,
fragmentShader: heatmapGridFrag,
triangulation: HeatmapGridTriangulation,
depth: { enable: false },
primitive: gl.TRIANGLES,
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'pos', // 顶点经纬度位置
type: AttributeType.Attribute,
descriptor: {
name: 'a_Pos',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
update: (feature: IEncodeFeature, featureIdx: number) => {
const coordinates = feature.coordinates as number[];
return [coordinates[0], coordinates[1], 0];
},
},
});
}
}

View File

@ -0,0 +1,24 @@
precision highp float;
// 多边形顶点坐标
attribute vec3 a_Position;
// 多边形经纬度坐标
attribute vec3 a_Pos;
attribute float a_Size;
attribute vec4 a_Color;
uniform vec2 u_radius;
uniform float u_coverage: 0.9;
uniform float u_angle: 0;
uniform mat4 u_ModelMatrix;
varying vec4 v_color;
#pragma include "projection"
#pragma include "project"
void main() {
v_color = a_Color;
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
vec2 offset = a_Position.xy * u_radius * rotationMatrix ;
// vec2 lnglat = unProjectFlat(a_Pos.xy);
vec4 project_pos = project_position(vec4(a_Pos.xy + offset, 0, 1.0));
gl_Position = project_common_position_to_clipspace(project_pos);
}

View File

@ -0,0 +1,29 @@
precision highp float;
// 多边形顶点坐标
attribute vec3 a_Position;
// 多边形经纬度坐标
attribute vec3 a_Pos;
attribute vec3 a_Normal;
attribute float a_Size;
attribute vec4 a_Color;
uniform vec2 u_radius;
uniform float u_coverage: 0.9;
uniform float u_angle: 0;
uniform mat4 u_ModelMatrix;
varying vec4 v_color;
#pragma include "projection"
#pragma include "project"
#pragma include "light"
void main() {
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 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);
}

View File

@ -1,6 +1,6 @@
precision highp float;
varying vec4 v_color;
uniform float u_opacity: 0.1;
uniform float u_opacity: 1;
void main() {
gl_FragColor = v_color;
gl_FragColor.a *= u_opacity;

View File

@ -1,18 +1,24 @@
precision highp float;
// 多边形顶点坐标
attribute vec3 a_Position;
// 多边形经纬度坐标
attribute vec3 a_Pos;
attribute float a_Size;
attribute vec4 a_Color;
uniform vec2 u_radius;
uniform float u_coverage: 1.;
uniform float u_coverage: 0.9;
uniform float u_angle: 0;
uniform mat4 u_ModelMatrix;
varying vec4 v_color;
#pragma include "projection"
#pragma include "project"
void main() {
v_color = a_Color;
mat2 rotationMatrix = mat2(cos(u_angle), sin(u_angle), -sin(u_angle), cos(u_angle));
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix ));
vec4 project_pos = project_position(vec4(a_Pos.xy + offset, 0, 1.0));
vec2 offset =(vec2(a_Position.xy * u_radius * rotationMatrix * u_coverage));
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));
}

View File

@ -1,6 +1,6 @@
import { IEncodeFeature, IParseDataItem } from '@l7/core';
// @ts-ignore
import Martini from '@mapbox/martini';
export function heatMap3DTriangulation(width: number, height: number) {
const indices = [];
const vertices = [];

View File

@ -1,7 +1,9 @@
import { container, ILayerPlugin, TYPES } from '@l7/core';
import BaseLayer from './core/BaseLayer';
import HeatMapGrid3dLayer from './heatmap/gird3d';
import HeatMapGridLayer from './heatmap/grid';
import HeatMapLayer from './heatmap/heatmap';
import HeatMapHexagonLayer from './heatmap/hexagon';
import ArcLineLayer from './line/arc';
import Arc2DLineLayer from './line/arc2d';
import Arc3DLineLayer from './line/arc3d';
@ -10,6 +12,7 @@ import LineLayer from './line/index';
import Point3dLayer from './point/extrude';
import PointLayer from './point/fill';
import PointImageLayer from './point/image';
import PointNormalLayer from './point/normal';
import TextLayer from './point/text';
// import Point from './point/point';
import PolygonLayer from './polygon';
@ -84,13 +87,16 @@ export {
DashLineLayer,
Polygon3DLayer,
ImageLayer,
HeatMapGridLayer,
ArcLineLayer,
Arc2DLineLayer,
Arc3DLineLayer,
RasterLayer,
HeatMapLayer,
TextLayer,
PointNormalLayer,
HeatMapGrid3dLayer,
HeatMapHexagonLayer,
HeatMapGridLayer,
// ImageLayer,
// HeatMapLayer,
};

View File

@ -67,7 +67,7 @@ export default class LineLayer extends BaseLayer<IPointLayerStyleOptions> {
data: [],
type: gl.FLOAT,
},
size: 1,
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
@ -75,7 +75,7 @@ export default class LineLayer extends BaseLayer<IPointLayerStyleOptions> {
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0];
},
},
});

View File

@ -1,7 +1,7 @@
attribute float a_Miter;
attribute vec4 a_Color;
attribute float a_Size;
attribute vec2 a_Size;
attribute vec3 a_Normal;
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
@ -12,8 +12,8 @@ varying vec2 v_normal;
void main() {
v_normal = vec2(reverse_offset_normal(a_Normal) * sign(a_Miter));
v_color = a_Color;
vec3 size = a_Miter * a_Size * reverse_offset_normal(a_Normal); //v_normal * vec3(1., -1., 1.0);
vec3 size = a_Miter * a_Size.x * reverse_offset_normal(a_Normal); //v_normal * vec3(1., -1., 1.0);
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, a_Size.y, 1.0));
}

View File

@ -13,10 +13,10 @@ import {
TYPES,
} from '@l7/core';
import { IParseDataItem } from '@l7/source';
import { extent } from 'd3-array';
import { extent, ticks } from 'd3-array';
import * as d3 from 'd3-scale';
import { inject, injectable } from 'inversify';
import { isNil, isNumber, isString, uniq } from 'lodash';
import { isNil, isString, uniq } from 'lodash';
const dateRegex = /^(?:(?!0000)[0-9]{4}([-/.]+)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))(\s+([01]|([01][0-9]|2[0-3])):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9]))?$/;
@ -73,6 +73,9 @@ export default class FeatureScalePlugin implements ILayerPlugin {
}
});
}
private isNumber(n: any) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
private caculateScalesForAttributes(
attributes: IStyleAttribute[],
@ -83,6 +86,7 @@ export default class FeatureScalePlugin implements ILayerPlugin {
if (attribute.scale) {
// 创建Scale
const attributeScale = attribute.scale;
const type = attribute.name;
attributeScale.names = this.parseFields(attribute!.scale!.field || []);
const scales: IStyleScale[] = attributeScale.names.map(
(field: string) => {
@ -96,14 +100,21 @@ export default class FeatureScalePlugin implements ILayerPlugin {
scales.forEach((scale) => {
// 如果设置了回调, 这不需要设置让range
if (!attributeScale.callback) {
if(attributeScale.values) {
if (attributeScale.values) {
if (
scale.option?.type === 'linear' &&
attributeScale.values.length > 2
) {
const tick = scale.scale.ticks(attributeScale.values.length);
if (type === 'color') {
scale.scale.domain(tick);
}
}
scale.scale.range(attributeScale.values);
} else if(scale.option?.type==='cat') {
} else if (scale.option?.type === 'cat') {
// 如果没有设置初值且 类型为catrange ==domain;
scale.scale.range(scale.option.domain);
}
}
});
} else {
@ -137,14 +148,13 @@ export default class FeatureScalePlugin implements ILayerPlugin {
const styleScale = this.createScale(field, dataArray);
this.scaleCache[scalekey] = styleScale;
if (
styleScale.type === StyleScaleType.VARIABLE &&
attribute.scale?.values &&
attribute.scale?.values.length > 0
) {
// 只有变量初始化range
styleScale.scale.range(attribute.scale?.values);
}
// if (
// styleScale.type === StyleScaleType.VARIABLE &&
// attribute.scale?.values &&
// attribute.scale?.values.length > 0
// ) { // 只有变量初始化range
// styleScale.scale.range(attribute.scale?.values);
// }
return this.scaleCache[scalekey];
}
@ -174,7 +184,6 @@ export default class FeatureScalePlugin implements ILayerPlugin {
option: scaleOption,
};
if (!data || !data.length) {
if (scaleOption && scaleOption.type) {
styleScale.scale = this.createDefaultScale(scaleOption);
} else {
@ -185,7 +194,7 @@ export default class FeatureScalePlugin implements ILayerPlugin {
}
const firstValue = data!.find((d) => !isNil(d[field]))?.[field];
// 常量 Scale
if (isNumber(field) || (isNil(firstValue) && !scaleOption)) {
if (this.isNumber(field) || (isNil(firstValue) && !scaleOption)) {
styleScale.scale = d3.scaleOrdinal([field]);
styleScale.type = StyleScaleType.CONSTANT;
} else {

View File

@ -0,0 +1,113 @@
import {
AttributeType,
gl,
IEncodeFeature,
ILayer,
ILayerPlugin,
ILogService,
IStyleAttributeService,
lazyInject,
TYPES,
} from '@l7/core';
import BaseLayer from '../core/BaseLayer';
import { rgb2arr } from '../utils/color';
import normalFrag from './shaders/normal_frag.glsl';
import normalVert from './shaders/normal_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
strokeWidth: number;
strokeColor: string;
}
export function PointTriangulation(feature: IEncodeFeature) {
const coordinates = feature.coordinates as number[];
return {
vertices: [...coordinates],
indices: [0],
size: coordinates.length,
};
}
export default class PointNormalLayer extends BaseLayer<
IPointLayerStyleOptions
> {
public name: string = 'PointLayer';
protected getConfigSchema() {
return {
properties: {
opacity: {
type: 'number',
minimum: 0,
maximum: 1,
},
},
};
}
protected renderModels() {
const {
opacity = 1,
strokeColor = 'rgb(0,0,0,0)',
strokeWidth = 1,
} = this.getStyleOptions();
this.models.forEach((model) =>
model.draw({
uniforms: {
u_opacity: opacity,
u_stroke_width: strokeWidth,
u_stroke_color: rgb2arr(strokeColor),
},
}),
);
return this;
}
protected buildModels() {
this.registerBuiltinAttributes(this);
this.models = [
this.buildLayerModel({
moduleName: 'normalpoint',
vertexShader: normalVert,
fragmentShader: normalFrag,
triangulation: PointTriangulation,
depth: { enable: false },
primitive: gl.POINTS,
blend: {
enable: true,
func: {
srcRGB: gl.ONE,
srcAlpha: 1,
dstRGB: gl.ONE,
dstAlpha: 1,
},
},
}),
];
}
private registerBuiltinAttributes(layer: ILayer) {
// point layer size;
layer.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size } = feature;
return Array.isArray(size) ? [size[0]] : [size as number];
},
},
});
}
}

View File

@ -1,61 +0,0 @@
uniform float u_blur : 0;
uniform float u_opacity : 1;
uniform float u_stroke_width : 1;
uniform vec4 u_stroke_color : [1, 1, 1, 1];
uniform float u_stroke_opacity : 1;
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
#pragma include "sdf_2d"
void main() {
int shape = int(floor(v_data.w + 0.5));
lowp float antialiasblur = v_data.z;
float antialiased_blur = -max(u_blur, antialiasblur);
float r = v_radius / (v_radius + u_stroke_width);
float outer_df;
float inner_df;
// 'circle', 'triangle', 'square', 'pentagon', 'hexagon', 'octogon', 'hexagram', 'rhombus', 'vesica'
if (shape == 0) {
outer_df = sdCircle(v_data.xy, 1.0);
inner_df = sdCircle(v_data.xy, r);
} else if (shape == 1) {
outer_df = sdEquilateralTriangle(1.1 * v_data.xy);
inner_df = sdEquilateralTriangle(1.1 / r * v_data.xy);
} else if (shape == 2) {
outer_df = sdBox(v_data.xy, vec2(1.));
inner_df = sdBox(v_data.xy, vec2(r));
} else if (shape == 3) {
outer_df = sdPentagon(v_data.xy, 0.8);
inner_df = sdPentagon(v_data.xy, r * 0.8);
} else if (shape == 4) {
outer_df = sdHexagon(v_data.xy, 0.8);
inner_df = sdHexagon(v_data.xy, r * 0.8);
} else if (shape == 5) {
outer_df = sdOctogon(v_data.xy, 1.0);
inner_df = sdOctogon(v_data.xy, r);
} else if (shape == 6) {
outer_df = sdHexagram(v_data.xy, 0.52);
inner_df = sdHexagram(v_data.xy, r * 0.52);
} else if (shape == 7) {
outer_df = sdRhombus(v_data.xy, vec2(1.0));
inner_df = sdRhombus(v_data.xy, vec2(r));
} else if (shape == 8) {
outer_df = sdVesica(v_data.xy, 1.1, 0.8);
inner_df = sdVesica(v_data.xy, r * 1.1, r * 0.8);
}
float opacity_t = smoothstep(0.0, antialiased_blur, outer_df);
float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
antialiased_blur,
0.0,
inner_df
);
gl_FragColor = opacity_t * mix(v_color * u_opacity, u_stroke_color * u_stroke_opacity, color_t);
}

View File

@ -1,52 +0,0 @@
attribute vec4 a_packed_data;
attribute vec2 a_Position;
uniform mat4 u_ModelMatrix;
uniform float u_stroke_width : 2;
varying vec4 v_data;
varying vec4 v_color;
varying float v_radius;
#pragma include "decode"
#pragma include "projection"
void main() {
// unpack color(vec2)
v_color = decode_color(a_packed_data.xy);
// unpack picking_id
float picking_id = a_packed_data.w;
// unpack data(extrude(4-bit), radius(16-bit))
float compressed = a_packed_data.z;
// extrude(4-bit)
vec2 extrude;
extrude.x = floor(compressed * SHIFT_RIGHT23);
compressed -= extrude.x * SHIFT_LEFT23;
extrude.x = extrude.x - 1.;
extrude.y = floor(compressed * SHIFT_RIGHT21);
compressed -= extrude.y * SHIFT_LEFT21;
extrude.y = extrude.y - 1.;
float shape_type = floor(compressed * SHIFT_RIGHT17);
compressed -= shape_type * SHIFT_LEFT17;
// radius(16-bit)
float radius = compressed;
v_radius = radius;
vec2 offset = project_pixel(extrude * (radius + u_stroke_width));
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
// TODO: billboard
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
// anti-alias
float antialiasblur = 1.0 / (radius + u_stroke_width);
// construct point coords
v_data = vec4(extrude, antialiasblur, shape_type);
}

View File

@ -1,4 +1,9 @@
precision highp float;
#define ambientRatio 0.5
#define diffuseRatio 0.3
#define specularRatio 0.2
attribute vec3 a_Position;
attribute vec3 a_Pos;
attribute vec4 a_Color;
@ -9,11 +14,36 @@ uniform mat4 u_ModelMatrix;
varying vec4 v_color;
#pragma include "projection"
#pragma include "light"
void main() {
vec3 size = a_Size * a_Position;
v_color = vec4(a_Normal,1.0);
vec2 offset = project_pixel(size.xy);
vec4 project_pos = project_position(vec4(a_Pos.xy, 0, 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, size.z, 1.0));
vec4 pos = vec4(project_pos.xy + offset, project_pixel(size.z), 1.0);
float lightWeight = calc_lighting(pos);
// vec3 worldPos = vec3(pos * u_ModelMatrix);
// vec3 worldNormal = vec3(vec4(a_Normal,1.0));
// // //cal light weight
// vec3 viewDir = normalize(u_CameraPosition - worldPos);
// vec3 lightDir = normalize(vec3(1, -10.5, 12));
// vec3 halfDir = normalize(viewDir+lightDir);
// // //lambert
// float lambert = dot(worldNormal, lightDir);
// //specular
// float specular = pow( max(0.0, dot(worldNormal, halfDir)), 32.0);
// //sum to light weight
// float lightWeight = ambientRatio + diffuseRatio * lambert + specularRatio * specular;
v_color =vec4(a_Color.rgb*lightWeight, a_Color.w);
gl_Position = project_common_position_to_clipspace(pos);
}

View File

@ -0,0 +1,7 @@
uniform float u_opacity : 1;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
gl_FragColor.a = u_opacity;
}

View File

@ -0,0 +1,17 @@
attribute vec3 a_Position;
uniform mat4 u_ModelMatrix;
attribute float a_Size;
attribute vec4 a_Color;
varying vec4 v_color;
#pragma include "projection"
void main() {
v_color = a_Color;
vec4 project_pos = project_position(vec4(a_Position, 1.0));
gl_Position = project_common_position_to_clipspace(project_pos);
gl_PointSize = a_Size * 2.0 * u_DevicePixelRatio;
}

View File

@ -54,6 +54,7 @@ export default class PolygonLayer extends BaseLayer<IPolygonLayerStyleOptions> {
vertexShader: polygon_vert,
fragmentShader: polygon_frag,
triangulation: polygonTriangulation,
depth: { enable: false },
}),
];
}

View File

@ -6,7 +6,7 @@ import pointExtrudeVert from './shaders/polygon_extrude_vert.glsl';
interface IPointLayerStyleOptions {
opacity: number;
}
export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
export default class PolygonLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PolygonLayer';
protected getConfigSchema() {
@ -41,15 +41,6 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
vertexShader: pointExtrudeVert,
fragmentShader: pointExtrudeFrag,
triangulation: PolygonExtrudeTriangulation,
blend: {
enable: true,
func: {
srcRGB: gl.SRC_ALPHA,
srcAlpha: 1,
dstRGB: gl.ONE_MINUS_SRC_ALPHA,
dstAlpha: 1,
},
},
}),
];
}

View File

@ -1,3 +1,9 @@
precision highp float;
#define ambientRatio 0.5
#define diffuseRatio 0.3
#define specularRatio 0.2
attribute vec4 a_Color;
attribute vec3 a_Position;
attribute vec3 a_Normal;
@ -8,15 +14,32 @@ varying vec4 v_Color;
#pragma include "projection"
#pragma include "picking"
#pragma include "lighting"
void main() {
vec4 project_pos = project_position(vec4(a_Position.xy, a_Position.z * a_Size, 1.0));
vec4 project_pos = project_position(vec4(a_Position.xy, project_pixel(a_Position.z * a_Size), 1.0));
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
vec3 viewDir = normalize(u_CameraPosition - project_pos.xyz);
vec3 normal = project_offset_normal(a_Normal);
v_Color.rgb *= calc_lighting(a_Position, normal, viewDir);
vec3 worldPos = vec3(project_pos * u_ModelMatrix);
vec3 worldNormal = vec3(vec4(a_Normal,1.0) * u_ModelMatrix);
// vec3 worldNormal = project_normal(a_Normal);
// //cal light weight
vec3 viewDir = normalize(u_CameraPosition - worldPos);
vec3 lightDir = normalize(vec3(1, -10.5, 12));
vec3 halfDir = normalize(viewDir+lightDir);
// //lambert
float lambert = dot(worldNormal, lightDir);
//specular
float specular = pow( max(0.0, dot(worldNormal, halfDir)), 16.0);
//sum to light weight
float lightWeight = ambientRatio + diffuseRatio * lambert + specularRatio * specular;
// v_Color = a_Color;
v_Color =vec4(a_Color.rgb * lightWeight, a_Color.w);
setPickingColor(a_PickingColor);
}

View File

@ -19,7 +19,7 @@ interface IPointLayerStyleOptions {
}
export default class ImageLayer extends BaseLayer<IPointLayerStyleOptions> {
public name: string = 'PointLayer';
public name: string = 'ImageLayer';
protected texture: ITexture2D;
protected getConfigSchema() {

View File

@ -3,7 +3,6 @@ uniform mat4 u_ModelMatrix;
attribute vec3 a_Position;
attribute vec2 a_Uv;
varying vec2 v_texCoord;
#pragma include "projection"
void main() {
v_texCoord = a_Uv;

View File

@ -1,7 +1,7 @@
export const MapTheme: {
[key: string]: any;
} = {
light: 'mapbox://styles/zcxduo/ck233y3ru1di71cnulo9jdg2v',
dark: 'mapbox://styles/zcxduo/ck241p6413s0b1cpayzldv7x7',
normal: 'mapbox://styles/zcxduo/ck2mzfaem0vdw1covi2yy793s',
light: 'mapbox://styles/mapbox/light-v10',
dark: 'mapbox://styles/mapbox/dark-v10',
normal: 'mapbox://styles/mapbox/streets-v11',
};

View File

@ -2,6 +2,7 @@
*
*/
import { IParserCfg, IParserData, ISourceCFG, ITransform } from '@l7/core';
import { aProjectFlat, metersToLngLat } from '@l7/utils';
import { statMap } from './statistics';
interface IGridHash {
@ -19,8 +20,8 @@ export function aggregatorToGrid(data: IParserData, option: ITransform) {
const { gridHash, gridOffset } = _pointsGridHash(dataArray, size);
const layerData = _getGridLayerDataFromGridHash(gridHash, gridOffset, option);
return {
yOffset: gridOffset.yOffset / 1.6,
xOffset: gridOffset.xOffset / 1.6,
yOffset: gridOffset.yOffset / 1.8,
xOffset: gridOffset.xOffset / 1.8,
radius: gridOffset.xOffset,
dataArray: layerData,
};
@ -37,8 +38,8 @@ function _pointsGridHash(dataArray: any[], size: number) {
latMax = pLat > latMax ? pLat : latMax;
}
}
const centerLat = (latMin + latMax) / 2;
// const centerLat = 34.54083;
// const centerLat = (latMin + latMax) / 2;
const centerLat = 34.54083;
const gridOffset = _calculateGridLatLonOffset(size, centerLat);
if (gridOffset.xOffset <= 0 || gridOffset.yOffset <= 0) {
return { gridHash: {}, gridOffset };

View File

@ -0,0 +1,94 @@
/**
*
*/
import {
IParseDataItem,
IParserCfg,
IParserData,
ISourceCFG,
ITransform,
} from '@l7/core';
import { aProjectFlat, metersToLngLat } from '@l7/utils';
import { statMap } from './statistics';
interface IGridHash {
[key: string]: any;
}
interface IGridOffset {
yOffset: number;
xOffset: number;
}
interface IRawData {
coordinates: [number, number];
[key: string]: any;
}
const R_EARTH = 6378000;
export function aggregatorToGrid(data: IParserData, option: ITransform) {
const dataArray = data.dataArray;
const { size = 10 } = option;
const pixlSize = ((size / (2 * Math.PI * R_EARTH)) * (256 << 20)) / 2;
const screenPoints: IRawData[] = dataArray.map((point: IParseDataItem) => {
const [x, y] = aProjectFlat(point.coordinates);
return {
...point,
coordinates: [parseInt(x.toFixed(0), 10), parseInt(y.toFixed(0), 10)],
};
});
const gridHash = _pointsGridHash(screenPoints, pixlSize);
const layerData = _getGridLayerDataFromGridHash(gridHash, pixlSize, option);
return {
yOffset: pixlSize / 2,
xOffset: pixlSize / 2,
dataArray: layerData,
};
}
function _pointsGridHash(dataArray: any[], size: number) {
const gridHash: IGridHash = {};
for (const point of dataArray) {
const x = point.coordinates[0];
const y = point.coordinates[1];
const latIdx = Math.floor(y / size);
const lonIdx = Math.floor(x / size);
const key = `${latIdx}-${lonIdx}`;
gridHash[key] = gridHash[key] || { count: 0, points: [] };
gridHash[key].count += 1;
gridHash[key].points.push(point);
}
return gridHash;
}
function _getGridLayerDataFromGridHash(
gridHash: IGridHash,
size: number,
option: ITransform,
) {
return Object.keys(gridHash).reduce((accu, key, i) => {
const idxs = key.split('-');
const latIdx = parseInt(idxs[0], 10);
const lonIdx = parseInt(idxs[1], 10);
const item: {
[key: string]: any;
} = {};
if (option.field && option.method) {
const columns = getColumn(gridHash[key].points, option.field);
item[option.method] = statMap[option.method](columns);
}
Object.assign(item, {
_id: i + 1,
coordinates: [lonIdx * size, latIdx * size],
count: gridHash[key].count,
});
// @ts-ignore
accu.push(item);
return accu;
}, []);
}
function getColumn(data: any[], columnName: string) {
return data.map((item) => {
return item[columnName] * 1;
});
}

View File

@ -1,4 +1,4 @@
import { aProjectFlat, unProjectFlat } from '@l7/utils';
import { aProjectFlat, metersToLngLat } from '@l7/utils';
import { hexbin } from 'd3-hexbin';
const R_EARTH = 6378000;
import {
@ -45,16 +45,18 @@ export function pointToHexbin(data: IParserData, option: ITransform) {
return {
[option.method]: hex[option.method],
count: hex.length,
coordinates: unProjectFlat([hex.x, hex.y]),
coordinates: [hex.x, hex.y],
_id: index + 1,
};
}),
radius: pixlSize,
xOffset: pixlSize,
yOffset: pixlSize,
};
return result;
}
function getColumn(data: IHexBinItem<IRawData>, columnName: string) {
return data.map((item: IRawData) => {
return item[columnName];
return item[columnName] * 1;
});
}

View File

@ -45,7 +45,7 @@ function sum(x: number[]) {
let transition;
for (let i = 1; i < x.length; i++) {
transition = sumNum + x[i];
transition = sumNum + x[i] * 1;
// Here we need to update the correction in a different fashion
// if the new absolute value is greater than the absolute sum
@ -59,7 +59,7 @@ function sum(x: number[]) {
}
// Returning the corrected sum
return sumNum + correction;
return sumNum + correction * 1;
}
function mean(x: number[]) {
if (x.length === 0) {

Some files were not shown because too many files have changed in this diff Show More