fix(heatmap): 修复热力图某些设备上黑色 fix #278

This commit is contained in:
thinkinggis 2020-04-09 20:54:39 +08:00
parent 62052648bc
commit b8f58992d1
25 changed files with 223 additions and 97 deletions

View File

@ -40,9 +40,46 @@ control 配置项
| -------- | --------------------------------------------- | ---------- | ------------------------------- |
| position | `bottomright、topright、 bottomleft topleft` | `topright` | 组件位置 |
| layout | `horizontal、 vertical` | `vertical` | 组件布局 支持水平和垂直两种布局 |
| controls | | 子组件 |
| controls | `controlOptions` | | 设置 UI 组件添加哪些绘制工具 |
| style | | | 地图绘制样式 |
**controlOptions**
UI 组件配置项
- point `boolean | drawOption` 绘制点工具配置
- line `boolean | drawOption` 绘制线工具配置
- polygon `boolean | drawOption` 绘制面工具配置
- circle `boolean | drawOption` 绘制圆工具配置
- rect `boolean | drawOption` 绘制矩形工具配置
- delete `boolean | drawOption` 添加删除工具
默认配置
```
{
point: true,
line: true,
polygon: true,
rect: true,
circle: true,
delete: true
}
```
示例
```
{
point: false,
line: {
editEnable: false,
},
polygon: true,
rect: true,
circle: true,
delete: false
```
### 添加到地图
```javascript
@ -109,6 +146,11 @@ const drawPoint = new DrawPolygon(scene);
drawPoint.enable();
```
### 配置项 DrawOption
- editEnable boolean 是否允许编辑
- selectEnable boolean 是否允许选中
### 方法
#### enable
@ -139,7 +181,7 @@ drawPoint.enable();
- normal 正常显示状态
```javascript
{
const style = {
active: {
point: {
type: 'PointLayer',

View File

@ -32,7 +32,7 @@
"@types/enzyme-adapter-react-16": "^1.0.3",
"@types/gl": "^4.1.0",
"@types/jest": "^24.0.18",
"@types/node": "^12.12.22",
"@types/node": "^13.11.1",
"@types/storybook__react": "^4.0.2",
"@types/supercluster": "^5.0.1",
"awesome-typescript-loader": "^5.2.1",

View File

@ -14,7 +14,9 @@ export default {
exclude: 'node_modules/**',
typescript: require('typescript')
}),
resolve(),
resolve({
preferBuiltins: false
}),
postcss({
plugins: [
url({ url: 'inline' })
@ -31,6 +33,9 @@ export default {
}),
terser()
],
external: [
'@antv/l7'
],
output: [
{
format: 'umd',

View File

@ -2,7 +2,7 @@
* @Author: lzxue
* @Date: 2020-04-03 19:24:16
* @Last Modified by: mikey.zhaopeng
* @Last Modified time: 2020-04-08 11:12:08
* @Last Modified time: 2020-04-09 19:34:41
*/
import { Control, DOM, IControlOption, PositionType, Scene } from '@antv/l7';
import './css/draw.less';
@ -15,6 +15,7 @@ import {
DrawPolygon,
DrawRect,
} from './modes';
import { IDrawFeatureOption } from './modes/draw_feature';
const DrawType: {
[key: string]: any;
} = {
@ -24,9 +25,10 @@ const DrawType: {
circle: DrawCircle,
rect: DrawRect,
};
import { isObject, polygon } from '@turf/helpers';
import { DrawEvent, DrawModes } from './util/constant';
export interface IControls {
[key: string]: boolean;
[key: string]: boolean | IDrawFeatureOption;
}
export interface IDrawControlOption extends IControlOption {
@ -50,6 +52,11 @@ export class DrawControl extends Control {
position: PositionType.TOPLEFT,
controls: {
point: true,
line: true,
polygon: true,
rect: true,
circle: true,
delete: true,
},
name: 'draw',
};
@ -68,14 +75,15 @@ export class DrawControl extends Control {
public onRemove() {
for (const draw in this.draw) {
if (this.draw[draw]) {
this.draw[draw].destory();
this.draw[draw].destroy();
}
}
}
private addControls(controls: IControls, container: HTMLElement) {
for (const type in controls) {
if (DrawType[type]) {
const draw = new DrawType[type](this.scene);
if (DrawType[type] && controls[type] !== false) {
const drawOption = isObject(controls[type]) ? controls[type] : false;
const draw = new DrawType[type](this.scene, drawOption);
draw.on(DrawEvent.MODE_CHANGE, this.onModeChange.bind(null, type));
this.draw[type] = draw;
this.createButton(
@ -84,7 +92,7 @@ export class DrawControl extends Control {
container,
this.onButtonClick.bind(null, type),
);
} else if (type === 'delete') {
} else if (type === 'delete' && controls[type] !== false) {
const draw = new DrawDelete(this.scene);
draw.on(DrawEvent.MODE_CHANGE, this.onModeChange.bind(null, type));
this.createButton(

View File

@ -15,16 +15,12 @@ import { DrawEvent, DrawModes, unitsType } from '../util/constant';
import { createCircle, createPoint } from '../util/create_geometry';
import moveFeatures, { movePoint } from '../util/move_featrues';
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
export interface IDrawRectOption extends IDrawFeatureOption {
units: unitsType;
steps: number;
}
export default class DrawCircle extends DrawFeature {
protected startPoint: ILngLat;
protected endPoint: ILngLat;
protected pointFeatures: Feature[];
protected centerLayer: ILayer;
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
this.type = 'circle';
}
@ -44,7 +40,7 @@ export default class DrawCircle extends DrawFeature {
this.source.setFeatureActive(feature);
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '绘制圆',

View File

@ -1,16 +1,11 @@
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
import { Feature } from '@turf/helpers';
import { DrawEvent } from '../util/constant';
import { IDrawFeatureOption } from './draw_feature';
import DrawFeature, { IDrawOption } from './draw_mode';
export type unitsType = 'degrees' | 'radians' | 'miles' | 'kilometers';
export interface IDrawCircleOption extends IDrawOption {
units: unitsType;
steps: number;
}
export default class DrawDelete extends DrawFeature {
// 绘制完成之后显示
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
}
@ -20,7 +15,7 @@ export default class DrawDelete extends DrawFeature {
public disable() {
return null;
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '删除图形',

View File

@ -1,16 +1,12 @@
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
import { Feature } from '@turf/helpers';
import { DrawEvent } from '../util/constant';
import { IDrawFeatureOption } from './draw_feature';
import DrawFeature, { IDrawOption } from './draw_mode';
export type unitsType = 'degrees' | 'radians' | 'miles' | 'kilometers';
export interface IDrawCircleOption extends IDrawOption {
units: unitsType;
steps: number;
}
export default class DrawEdit extends DrawFeature {
private endPoint: ILngLat;
// 绘制完成之后显示
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
}
@ -21,6 +17,7 @@ export default class DrawEdit extends DrawFeature {
protected onDragStart = (e: IInteractionTarget) => {
// @ts-ignore
};
protected getDefaultOptions() {
return {
steps: 64,

View File

@ -4,28 +4,31 @@ import {
FeatureCollection,
featureCollection,
point,
Units,
unitsFactors,
} from '@turf/helpers';
import DrawRender from '../render/draw';
import RenderLayer from '../render/draw_result';
import DrawVertexLayer from '../render/draw_vertex';
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
import { DrawEvent, DrawModes } from '../util/constant';
import DrawDelete from './draw_delete';
import DrawEdit from './draw_edit';
import DrawMode, { IDrawOption } from './draw_mode';
import DrawSelected from './draw_selected';
export interface IDrawFeatureOption extends IDrawOption {
units: unitsType;
units: Units;
steps: number;
editEnable: boolean;
selectEnable: boolean;
cursor: string;
}
const InitFeature = {
type: 'FeatureCollection',
features: [],
};
export default abstract class DrawFeature extends DrawMode {
// 绘制完成之后显示
public selectMode: DrawSelected;
public editMode: DrawEdit;
public deleteMode: DrawDelete;
public editEnable: boolean;
public selectEnable: boolean;
protected normalLayer: RenderLayer;
protected drawLayer: DrawRender;
@ -36,6 +39,8 @@ export default abstract class DrawFeature extends DrawMode {
this.drawLayer = new DrawRender(this);
this.drawVertexLayer = new DrawVertexLayer(this);
this.normalLayer = new RenderLayer(this);
this.selectEnable = this.getOption('selectEnable');
this.editEnable = this.getOption('editEnable');
// this.editLayer = new EditLayer(this);
this.selectMode = new DrawSelected(this.scene, {});
@ -90,20 +95,22 @@ export default abstract class DrawFeature extends DrawMode {
}
public onRemove() {
this.destory();
this.selectMode.destory();
this.editMode.destory();
this.destroy();
this.selectMode.destroy();
this.editMode.destroy();
this.source.destroy();
this.drawLayer.destroy();
this.drawVertexLayer.destroy();
this.normalLayer.destroy();
document.removeEventListener('keydown', this.addKeyDownEvent);
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
steps: 64,
units: 'kilometres',
units: 'kilometers',
cursor: 'crosshair',
editEnable: true,
selectEnable: true,
};
}
protected abstract onDragStart(e: IInteractionTarget): void;
@ -136,6 +143,9 @@ export default abstract class DrawFeature extends DrawMode {
private onModeChange = (mode: DrawModes[any]) => {
switch (mode) {
case DrawModes.DIRECT_SELECT:
if (!this.editEnable) {
return;
}
this.editMode.enable();
this.editMode.setEditFeature(this.currentFeature as Feature);
this.drawLayer.updateData(
@ -150,6 +160,13 @@ export default abstract class DrawFeature extends DrawMode {
this.drawStatus = 'DrawEdit';
break;
case DrawModes.SIMPLE_SELECT:
if (!this.selectEnable) {
this.drawLayer.hide();
this.drawVertexLayer.hide();
this.hideOtherLayer();
this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
return;
}
this.selectMode.setSelectedFeature(this.currentFeature as Feature);
this.selectMode.enable();
this.drawLayer.enableSelect();

View File

@ -15,7 +15,7 @@ export default class DrawLine extends DrawPolygon {
this.type = 'line';
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '绘制线',

View File

@ -88,11 +88,11 @@ export default abstract class DrawMode extends EventEmitter {
throw new Error('子类未实现该方法');
}
public getCurrentVertex() {
return this.currentVertex;
public getCurrentVertex(): Feature {
return this.currentVertex as Feature;
}
public getCurrentFeature() {
return this.currentVertex;
public getCurrentFeature(): Feature {
return this.currentFeature as Feature;
}
public getOption(key: string) {
@ -119,13 +119,13 @@ export default abstract class DrawMode extends EventEmitter {
container.removeAttribute('style');
}
}
public destory() {
public destroy() {
DrawFeatureId = 0;
this.removeAllListeners();
this.disable();
}
protected getDefaultOptions() {
protected getDefaultOptions(): any {
return {};
}

View File

@ -3,14 +3,10 @@ import { Feature, featureCollection, point } from '@turf/helpers';
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
import moveFeatures from '../util/move_featrues';
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
export interface IDrawRectOption extends IDrawFeatureOption {
units: unitsType;
steps: number;
}
export default class DrawPoint extends DrawFeature {
protected pointFeatures: Feature[];
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
this.type = 'point';
}
@ -20,7 +16,7 @@ export default class DrawPoint extends DrawFeature {
this.disable();
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '绘制点',

View File

@ -49,7 +49,6 @@ export default class DrawPolygon extends DrawFeature {
this.drawLayer.update(featureCollection([feature]));
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
// @ts-ignore
// feature.properties.pointFeatures = pointfeatures;
this.emit(DrawEvent.CREATE, this.currentFeature);
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
this.points = [];
@ -92,7 +91,7 @@ export default class DrawPolygon extends DrawFeature {
this.setCurrentFeature(feature);
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '绘制多边形',
@ -169,13 +168,13 @@ export default class DrawPolygon extends DrawFeature {
return feature;
}
protected editFeature(vertex: ILngLat) {
protected editFeature(vertex: ILngLat): void {
const selectVertexed = this.currentVertex as Feature<
Geometries,
Properties
>;
if (selectVertexed === null) {
return featureCollection([]);
return;
} else {
// @ts-ignore
const id = selectVertexed.properties.id * 1;

View File

@ -9,19 +9,15 @@ import { unitsType } from '../util/constant';
import { createPoint, createRect } from '../util/create_geometry';
import DrawCircle from './draw_circle';
import { IDrawFeatureOption } from './draw_feature';
export interface IDrawRectOption extends IDrawFeatureOption {
units: unitsType;
steps: number;
}
export default class DrawRect extends DrawCircle {
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
this.type = 'rect';
}
public drawFinish() {
return null;
}
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
...super.getDefaultOptions(),
title: '绘制矩形',

View File

@ -12,12 +12,8 @@ import {
import { Feature, featureCollection, point } from '@turf/helpers';
import { DrawEvent, DrawModes } from '../util/constant';
import moveFeatures from '../util/move_featrues';
import { IDrawFeatureOption } from './draw_feature';
import DrawFeature, { IDrawOption } from './draw_mode';
export type unitsType = 'degrees' | 'radians' | 'miles' | 'kilometers';
export interface IDrawCircleOption extends IDrawOption {
units: unitsType;
steps: number;
}
const InitFeature = {
type: 'FeatureCollection',
features: [],
@ -26,7 +22,7 @@ export default class DrawSelect extends DrawFeature {
private center: ILngLat;
private dragStartPoint: ILngLat;
// 绘制完成之后显示
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
super(scene, options);
}
@ -38,10 +34,11 @@ export default class DrawSelect extends DrawFeature {
this.scene.setMapStatus({ dragEnable: false });
this.dragStartPoint = e.lngLat;
};
protected getDefaultOptions() {
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
return {
steps: 64,
units: 'kilometres',
units: 'kilometers',
cursor: 'move',
};
}

View File

@ -23,7 +23,9 @@ export default class DrawLayer extends BaseRender {
const layer = this.drawLayers[0];
layer.on('mouseenter', this.onMouseMove);
layer.on('mouseout', this.onUnMouseMove);
layer.on('click', this.onClick);
if (this.draw.editEnable) {
layer.on('click', this.onClick);
}
layer.on('unclick', this.onUnClick);
this.isEnableDrag = true;
}

View File

@ -18,6 +18,9 @@ export default class DrawResultLayer extends BaseRender {
if (this.isEnableDrag) {
return;
}
if (!this.draw.selectEnable) {
return;
}
const layer = this.drawLayers[0];
layer.on('click', this.onClick);
this.isEnableDrag = true;

View File

@ -3,6 +3,7 @@ import turfDistance from '@turf/distance';
import {
Feature,
featureCollection,
FeatureCollection,
lineString,
point,
polygon,
@ -116,7 +117,9 @@ export function createLine(
}
}
export function createPoint(points: Array<{ lng: number; lat: number }>) {
export function createPoint(
points: Array<{ lng: number; lat: number }>,
): FeatureCollection {
const features = points.map((p, index) =>
point([p.lng, p.lat], {
active: true,

View File

@ -1,5 +1,4 @@
import { version } from '../src/version';
describe('version', () => {
it('should match the `version` field of package.json', () => {
const expected = require('../package.json').version;

View File

@ -93,9 +93,8 @@ export default class HeatMapModel extends BaseModel {
});
// 初始化颜色纹理
this.colorTexture = createTexture2D({
data: imageData.data,
data: new Uint8Array(imageData.data),
width: imageData.width,
height: imageData.height,
wrapS: gl.CLAMP_TO_EDGE,

View File

@ -0,0 +1,3 @@
.amap-logo{
display: none !important;
}

View File

@ -20,6 +20,7 @@ import {
import { DOM } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import { IAMapEvent, IAMapInstance } from '../../typings/index';
import './logo.css';
import { MapTheme } from './theme';
import Viewport from './Viewport';
let mapdivCount = 0;
@ -258,7 +259,6 @@ export default class AMapService
if (mapInstance) {
this.map = mapInstance as AMap.Map & IAMapInstance;
this.$mapContainer = this.map.getContainer();
this.removeLogoControl();
setTimeout(() => {
this.map.on('camerachange', this.handleCameraChanged);
resolve();
@ -274,10 +274,6 @@ export default class AMapService
viewMode: '3D',
...rest,
});
map.on('complete', () => {
this.removeLogoControl();
});
// 监听地图相机事件
map.on('camerachange', this.handleCameraChanged);
// @ts-ignore
@ -425,12 +421,4 @@ export default class AMapService
document.head.appendChild(script);
});
}
private removeLogoControl(): void {
// @ts-ignore
const logo = document.getElementsByClassName('amap-logo');
if (logo && logo[0]) {
logo[0].setAttribute('style', 'display: none !important');
}
}
}

View File

@ -23,7 +23,10 @@ export default class Circle extends React.Component {
this.scene = scene;
scene.on('loaded', () => {
const drawRect = new DrawRect(scene);
const drawRect = new DrawRect(scene, {
editEnable: false,
selectEnable: false,
});
drawRect.enable();
});
}

View File

@ -0,0 +1,78 @@
import { HeatmapLayer, Scene } from '@antv/l7';
import { GaodeMap, Mapbox } from '@antv/l7-maps';
// @ts-ignore
import * as React from 'react';
export default class HeatMapLayerDemo extends React.Component {
// @ts-ignore
private scene: Scene;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
map: new Mapbox({
style: 'dark',
pitch: 58.5,
center: [116.49434030056, 39.868073421167621],
zoom: 13,
}),
});
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/basement_prod/c3f8bda2-081b-449d-aa9f-9413b779205b.json',
)
.then((res) => res.json())
.then((data) => {
const layer = new HeatmapLayer({})
.source(data, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.size('count', [0, 1])
.shape('heatmap3D')
// weight映射通道
.style({
intensity: 10,
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);
});
});
this.scene = scene;
}
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
);
}
}

View File

@ -7,7 +7,7 @@
"jsx": "react",
"target": "es5",
"lib": ["es6", "dom"],
"types": ["reflect-metadata", "jest" ],
"types": ["reflect-metadata", "jest", "node"],
"module": "esnext",
"moduleResolution": "node",
"esModuleInterop": true,
@ -20,7 +20,7 @@
"@antv/l7-*": ["packages/*/src"],
"@antv/l7": ["packages/l7/src"],
"*": ["node_modules", "packages", "typings/*"]
}
},
},
"awesomeTypescriptLoaderOptions": {
"useBabel": true,

View File

@ -4990,10 +4990,10 @@
resolved "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8"
integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q==
"@types/node@^12.12.22":
version "12.12.30"
resolved "https://registry.npmjs.org/@types/node/-/node-12.12.30.tgz#3501e6f09b954de9c404671cefdbcc5d9d7c45f6"
integrity sha512-sz9MF/zk6qVr3pAnM0BSQvYIBK44tS75QC5N+VbWSE4DjCV/pJ+UzCW/F+vVnl7TkOPcuwQureKNtSSwjBTaMg==
"@types/node@^13.11.1":
version "13.11.1"
resolved "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
"@types/node@^8.5.7":
version "8.10.59"