Skip to content

Commit

Permalink
feat(line): greatCircle
Browse files Browse the repository at this point in the history
  • Loading branch information
lzxue committed Jul 15, 2019
1 parent 3ed7ed4 commit 4977426
Show file tree
Hide file tree
Showing 13 changed files with 226 additions and 81 deletions.
53 changes: 53 additions & 0 deletions demos/greatcircle.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://gw.alipayobjects.com/os/rmsportal/PqLCOJpqoOUfuPRacUzE.css" />
<title>弧线图</title>
<style> ::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/ document.body.clientHeight; </script>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script src="../build/L7.js"></script>
<script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
<style>
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
<script>
var scene = new L7.Scene({
id: 'map',
mapStyle: 'dark', // 样式URL
center: [116.2825, 39.9],
pitch: 0,
zoom: 4
});
scene.on('loaded', function() {
$.get('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt', function(data) {

scene.LineLayer({
zIndex: 2
}).source(data, {
parser:{
type:'csv',
x: 'lng1',
y: 'lat1',
x1: 'lng2',
y1: 'lat2'
}
}
).color('rgb(13,64,140)').style({
opacity: 0.6
})
.shape('greatCircle')
.size(1)
.render();
});
});
</script>
</body>
</html>
6 changes: 0 additions & 6 deletions src/core/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,6 @@ export default class Layer extends Base {
cfg.mapType = this.scene.mapType;
cfg.zoom = this.scene.getZoom();
this.layerSource = new source(cfg);
// this.scene.workerPool.runTask({
// command: 'geojson',
// data: cfg
// }).then(data => {
// console.log(data);
// });
return this;
}
color(field, values) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default class Scene extends Base {

_initEngine(mapContainer) {
this._engine = new Engine(mapContainer, this);
this.registerMapEvent();
// this._engine.run();
// this.registerMapEvent();
this._engine.run();
// this.workerPool = new WorkerPool();
compileBuiltinModules();
}
Expand Down
57 changes: 3 additions & 54 deletions src/geom/buffer/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,14 @@ import { lineShape } from '../shape';

export default class LineBuffer extends BufferBase {
geometryBuffer() {
const layerData = this.get('layerData');
const shapeType = this.shapeType = this.get('shapeType');
const positions = [];
const positionsIndex = [];
const instances = [];
if (shapeType === 'line') {
this.attributes = this._getMeshLineAttributes();
return;
} else if (shapeType === 'arc') {
this.attributes = this._getArcLineAttributes();
return;
}
layerData.forEach((item, index) => {
const props = item;
const attrData = this._getShape(item.coordinates, props, index);
positions.push(...attrData.positions);
positionsIndex.push(...attrData.indexes);
if (attrData.hasOwnProperty('instances')) {
instances.push(...attrData.instances);
}
});
this.bufferStruct.style = layerData;
this.bufferStruct.verts = positions;
this.bufferStruct.indexs = positionsIndex;
if (instances.length > 0) {
this.bufferStruct.instances = instances;
}
this.attributes = this._toAttributes(this.bufferStruct);
}

_getShape(geo, props, index) {
Expand All @@ -55,6 +35,7 @@ export default class LineBuffer extends BufferBase {
const indexArray = [];
const sizes = [];
const instances = [];
const pickingIds = [];
layerData.forEach(item => {
const props = item;
const positionCount = positions.length / 3;
Expand All @@ -64,8 +45,10 @@ export default class LineBuffer extends BufferBase {
indexArray.push(...attrData.indexArray);
instances.push(...attrData.instances);
sizes.push(...attrData.sizes);
pickingIds.push(...attrData.pickingIds);
});
return {
pickingIds,
positions,
colors,
indexArray,
Expand Down Expand Up @@ -111,38 +94,4 @@ export default class LineBuffer extends BufferBase {
attrDashArray
};
}

_toAttributes(bufferStruct) {
const vertCount = bufferStruct.verts.length;
const vertices = new Float32Array(vertCount * 3);
const pickingIds = new Float32Array(vertCount);
const inposs = new Float32Array(vertCount * 4);
const colors = new Float32Array(vertCount * 4);
for (let i = 0; i < vertCount; i++) {
const index = bufferStruct.indexs[i];
const color = bufferStruct.style[index].color;
const id = bufferStruct.style[index].id;
vertices[i * 3] = bufferStruct.verts[i][0];
vertices[i * 3 + 1] = bufferStruct.verts[i][1];
vertices[i * 3 + 2] = bufferStruct.verts[i][2];
colors[i * 4] = color[0];
pickingIds[i] = id;
colors[i * 4 + 1] = color[1];
colors[i * 4 + 2] = color[2];
colors[i * 4 + 3] = color[3];
if (bufferStruct.instances) { // 弧线
inposs[i * 4] = bufferStruct.instances[i][0];
inposs[i * 4 + 1] = bufferStruct.instances[i][1];
inposs[i * 4 + 2] = bufferStruct.instances[i][2];
inposs[i * 4 + 3] = bufferStruct.instances[i][3];
}

}
return {
pickingIds,
vertices,
colors,
inposs
};
}
}
13 changes: 8 additions & 5 deletions src/geom/material/lineMaterial.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as THREE from '../../core/three';
import Material from './material';
import { getModule, wrapUniforms } from '../../util/shaderModule';
import arcline_frag from '../shader/arcline_frag.glsl';
import arcline_vert from '../shader/arcline_vert.glsl';
import merge from '@antv/util/lib/deep-mix';

export function LineMaterial(options) {
Expand All @@ -23,17 +21,22 @@ export function LineMaterial(options) {
return material;
}
export function ArcLineMaterial(options) {
let moduleName = 'arcline';
if (options.shapeType === 'greatCircle') {
moduleName = 'greatcircle';
}
const { vs, fs } = getModule(moduleName);
const material = new Material({
uniforms: {
u_opacity: { value: options.u_opacity || 1.0 },
segmentNumber: { value: 49 },
segmentNumber: { value: 29 },
u_time: { value: 0 },
u_zoom: { value: options.u_zoom || 10 },
u_activeId: { value: options.activeId || 0 },
u_activeColor: { value: options.activeColor || [ 1.0, 0, 0, 1.0 ] }
},
vertexShader: arcline_vert,
fragmentShader: arcline_frag,
vertexShader: vs,
fragmentShader: fs,
transparent: true,
blending: THREE.AdditiveBlending
});
Expand Down
15 changes: 7 additions & 8 deletions src/geom/shader/arcline_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ attribute vec4 a_instance;
attribute float a_size;
uniform float u_zoom;
uniform float u_time;
uniform float u_activeId : 0;
uniform vec4 u_activeColor : [ 1.0, 0, 0, 1.0 ];
uniform mat4 matModelViewProjection;
uniform float segmentNumber;
varying vec4 v_color;
Expand Down Expand Up @@ -42,7 +44,6 @@ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {


void main() {
float visindex =mod(u_time *10.,segmentNumber);
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
vec2 source = a_instance.rg;
vec2 target = a_instance.ba;
Expand All @@ -55,13 +56,11 @@ void main() {
vec3 next = getPos(source, target, nextSegmentRatio);
vec2 offset = getExtrusionOffset((next.xy - curr.xy) * indexDir, position.y);
gl_Position =matModelViewProjection * vec4(vec3(curr + vec3(offset, 0.0)),1.0);
// float apha = 0.;
// if( position.x> 0. && position.x <visindex)
// apha =1.0;
// vec3 c1 = vec3(0.929,0.972,0.917);
// vec3 c2 = vec3(0.062,0.325,0.603);
// v_color = mix(c1, c2, segmentRatio);
v_color = a_color;

// picking
if(pickingId == u_activeId) {
v_color = u_activeColor;
}
worldId = id_toPickColor(pickingId);

}
95 changes: 95 additions & 0 deletions src/geom/shader/great_circle_line_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#define PI 3.1415926535
precision mediump float;
attribute vec4 a_color;
attribute vec4 a_instance;
attribute float a_size;
uniform float u_zoom;
uniform float u_time;
uniform float u_activeId : 0;
uniform vec4 u_activeColor : [ 1.0, 0, 0, 1.0 ];
uniform mat4 matModelViewProjection;
uniform float segmentNumber;
varying vec4 v_color;
#pragma include "project"
float maps (float value, float start1, float stop1, float start2, float stop2) {
return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));
}

float getSegmentRatio(float index) {
return smoothstep(0.0, 1.0, index / (segmentNumber - 1.0));
}

float paraboloid(vec2 source, vec2 target, float ratio) {
vec2 x = mix(source, target, ratio);
vec2 center = mix(source, target, 0.5);
float dSourceCenter = distance(source, center);
float dXCenter = distance(x, center);
return (dSourceCenter + dXCenter) * (dSourceCenter - dXCenter);
}

vec3 getPos(vec2 source, vec2 target, float segmentRatio) {
float vertex_height = paraboloid(source, target, segmentRatio);

return vec3(
mix(source, target, segmentRatio),
sqrt(max(0.0, vertex_height))
);
}
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
vec2 offset = dir_screenspace * offset_direction * a_size * pow(2.0,20.0-u_zoom) / 2.0;
return offset;
}
float getAngularDist (vec2 source, vec2 target) {
vec2 delta = source - target;
vec2 sin_half_delta = sin(delta / 2.0);
float a =
sin_half_delta.y * sin_half_delta.y +
cos(source.y) * cos(target.y) *
sin_half_delta.x * sin_half_delta.x;
return 2.0 * atan(sqrt(a), sqrt(1.0 - a));
}
vec2 interpolate (vec2 source, vec2 target, float angularDist, float t) {
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
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)));
}

void main() {
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
vec2 source = radians(unProjectFlat(a_instance.rg));
vec2 target = radians(unProjectFlat(a_instance.ba));
float angularDist = getAngularDist(source, target);
float segmentIndex = position.x;
float segmentRatio = getSegmentRatio(segmentIndex);
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
float nextSegmentRatio = getSegmentRatio(segmentIndex + indexDir);



vec3 curr = vec3(degrees(interpolate(source, target, angularDist, segmentRatio)), 0.0);
vec3 next = vec3(degrees(interpolate(source, target, angularDist, nextSegmentRatio)), 0.0);
vec2 offset = getExtrusionOffset((ProjectFlat(next.xy) - ProjectFlat(curr.xy)) * indexDir, position.y);
gl_Position =matModelViewProjection * vec4(vec3(vec3(ProjectFlat(curr.xy),2.) + vec3(offset, 0.0)),1.0);
v_color = a_color;
// picking
if(pickingId == u_activeId) {
v_color = u_activeColor;
}
worldId = id_toPickColor(pickingId);

}
10 changes: 10 additions & 0 deletions src/geom/shader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ import point_line_vert from '../shader/point_meshLine_vert.glsl';
import mesh_line_frag from '../shader/meshline_frag.glsl';
import mesh_line_vert from '../shader/meshline_vert.glsl';

// arc line
import arc_line_frag from '../shader/arcline_frag.glsl';
import arc_line_vert from '../shader/arcline_vert.glsl';
import great_circle_line_vert from '../shader/great_circle_line_vert.glsl';


// 原生线
import line_frag from '../shader/line_frag.glsl';
import line_vert from '../shader/line_vert.glsl';
Expand Down Expand Up @@ -54,20 +60,24 @@ import pick_color from './shaderChunks/pick_color.glsl';
import decode from './shaderChunks/decode.glsl';
import lighting from './shaderChunks/lighting.glsl';
import sdf_2d from './shaderChunks/sdf_2d.glsl';
import project from './shaderChunks/project.glsl';

export function compileBuiltinModules() {
registerModule('point', { vs: point_vert, fs: point_frag });
registerModule('common', { vs: common, fs: common });
registerModule('decode', { vs: decode, fs: '' });
registerModule('lighting', { vs: lighting, fs: '' });
registerModule('sdf_2d', { vs: '', fs: sdf_2d });
registerModule('project', { vs: project, fs: '' });
registerModule('pick_color', { vs: pick_color, fs: pick_color });
registerModule('circle', { vs: circle_vert, fs: circle_frag });
registerModule('polygon', { vs: polygon_vert, fs: polygon_frag });
registerModule('grid', { vs: grid_vert, fs: grid_frag });
registerModule('hexagon', { vs: hexagon_vert, fs: hexagon_frag });
registerModule('pointline', { vs: point_line_vert, fs: point_line_frag });
registerModule('meshline', { vs: mesh_line_vert, fs: mesh_line_frag });
registerModule('arcline', { vs: arc_line_vert, fs: arc_line_frag });
registerModule('greatcircle', { vs: great_circle_line_vert, fs: arc_line_frag });
registerModule('line', { vs: line_vert, fs: line_frag });
registerModule('heatmap_color', { vs: heatmap_color_vert, fs: heatmap_color_frag });
registerModule('heatmap_intensity', { vs: heatmap_intensity_vert, fs: heatmap_intensity_frag });
Expand Down
1 change: 0 additions & 1 deletion src/geom/shader/meshline_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ uniform float u_duration : 2.0;
uniform float u_interval : 1.0;
uniform float u_trailLength : 0.2;
#endif

void main() {
v_color = a_color;
v_distance = a_distance;
Expand Down
Loading

0 comments on commit 4977426

Please sign in to comment.