mirror of https://gitee.com/antv-l7/antv-l7
Merge pull request #265 from antvis/l7-draw
feat: add draw point line polygon
This commit is contained in:
commit
c894e20f06
docs/api/layer
packages
component/src/control
core/src
services
config
interaction
layer
map
renderer/passes
shaders
draw
package.json
src
css
draw_control.tsindex.tsmodes
draw_circle.tsdraw_delete.tsdraw_edit.tsdraw_feature.tsdraw_line.tsdraw_mode.tsdraw_point.tsdraw_polygon.tsdraw_rect.tsdraw_selected.tsindex.ts
render.tsrender
base_render.tsdraw.tsdraw_mid_vertex.tsdraw_result.tsdraw_vertex.tsedit.tsrenderFeature.tsselected.ts
source.tsutil
layers/src
core
line/shaders
line_arc2d_vert.glslline_arc_3d_vert.glslline_arc_great_circle_vert.glslline_bezier_vert.glslline_dash_vert.glslline_vert.glsl
plugins
point/shaders
maps/src
scene/src
source/src/transform
stories
Components/components
Draw
Layers
|
@ -238,7 +238,7 @@ layer.color('white'); // 指定颜色
|
|||
|
||||
- `colors`: string | array | function
|
||||
|
||||
colors 的参数有以下情况: 如果为空,即未指定颜色的数组,那么使用内置的全局的颜色;如果需要指定颜色,则需要以数组格式传入,那么分类的颜色按照数组中的颜色确定。对于颜色的分配顺序。
|
||||
colors 的参数有以下情况: 如果为空,即未指定颜色的数组,那么使用内置的全局的颜色;如果需要指定颜色,则需要以数组格式传入,那么分类的颜色按照数组中的颜色确定.
|
||||
|
||||
```javascript
|
||||
layer.color('name'); // 使用默认的颜色
|
||||
|
|
|
@ -238,7 +238,7 @@ layer.color('white'); // 指定颜色
|
|||
|
||||
- `colors`: string | array | function
|
||||
|
||||
colors 的参数有以下情况: 如果为空,即未指定颜色的数组,那么使用内置的全局的颜色;如果需要指定颜色,则需要以数组格式传入,那么分类的颜色按照数组中的颜色确定。对于颜色的分配顺序。
|
||||
colors 的参数有以下情况: 如果为空,即未指定颜色的数组,那么使用内置的全局的颜色;如果需要指定颜色,则需要以数组格式传入,那么分类的颜色按照数组中的颜色确定。
|
||||
|
||||
```javascript
|
||||
layer.color('name'); // 使用默认的颜色
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class Zoom extends Control {
|
|||
};
|
||||
}
|
||||
|
||||
public onAdd() {
|
||||
public onAdd(): HTMLElement {
|
||||
const zoomName = 'l7-control-zoom';
|
||||
const container = DOM.create('div', zoomName + ' l7-bar');
|
||||
|
||||
|
@ -93,6 +93,7 @@ export default class Zoom extends Control {
|
|||
) {
|
||||
const link = DOM.create('a', className, container) as HTMLLinkElement;
|
||||
link.innerHTML = html;
|
||||
link.title = tile;
|
||||
link.href = 'javascript:void(0)';
|
||||
link.addEventListener('click', fn);
|
||||
return link;
|
||||
|
|
|
@ -4,8 +4,6 @@ import { merge } from 'lodash';
|
|||
import { ILayerConfig } from '../layer/ILayerService';
|
||||
import { IRenderConfig } from '../renderer/IRendererService';
|
||||
import { IGlobalConfigService, ISceneConfig } from './IConfigService';
|
||||
import mapConfigSchema from './mapConfigSchema';
|
||||
import sceneConfigSchema from './sceneConfigSchema';
|
||||
import WarnInfo, { IWarnInfo } from './warnInfo';
|
||||
|
||||
/**
|
||||
|
@ -58,6 +56,8 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
|
|||
maxZoom: 24,
|
||||
visible: true,
|
||||
autoFit: false,
|
||||
pickingBuffer: 0,
|
||||
enablePropagation: false,
|
||||
zIndex: 0,
|
||||
blend: 'normal',
|
||||
pickedFeatureID: -1,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import EventEmitter from 'eventemitter3';
|
||||
import Hammer from 'hammerjs';
|
||||
import { inject, injectable } from 'inversify';
|
||||
// @ts-ignore
|
||||
import { TYPES } from '../../types';
|
||||
import { ILogService } from '../log/ILogService';
|
||||
import { ILngLat, IMapService } from '../map/IMapService';
|
||||
|
@ -58,10 +59,20 @@ export default class InteractionService extends EventEmitter
|
|||
|
||||
private addEventListenerOnMap() {
|
||||
const $containter = this.mapService.getMapContainer();
|
||||
Hammer.defaults.domEvents = true;
|
||||
if ($containter) {
|
||||
const hammertime = new Hammer.Manager($containter);
|
||||
hammertime.add(new Hammer.Tap({ event: 'dblclick', taps: 2 }));
|
||||
hammertime.add(new Hammer.Tap({ event: 'click' }));
|
||||
hammertime.add(
|
||||
new Hammer.Tap({
|
||||
event: 'dblclick',
|
||||
taps: 2,
|
||||
}),
|
||||
);
|
||||
hammertime.add(
|
||||
new Hammer.Tap({
|
||||
event: 'click',
|
||||
}),
|
||||
);
|
||||
hammertime.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
|
||||
hammertime.add(new Hammer.Press({}));
|
||||
// hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });
|
||||
|
@ -86,7 +97,7 @@ export default class InteractionService extends EventEmitter
|
|||
const $containter = this.mapService.getMapContainer();
|
||||
if ($containter) {
|
||||
$containter.removeEventListener('mousemove', this.onHover);
|
||||
this.hammertime.off('dblclick click', this.onHammer);
|
||||
// this.hammertime.off('dblclick click', this.onHammer);
|
||||
this.hammertime.off('panstart panmove panend pancancel', this.onDrag);
|
||||
// $containter.removeEventListener('touchstart', this.onTouch);
|
||||
// $containter.removeEventListener('click', this.onHover);
|
||||
|
@ -102,9 +113,19 @@ export default class InteractionService extends EventEmitter
|
|||
this.emit(InteractionEvent.Drag, interactionTarget);
|
||||
};
|
||||
private onHammer = (target: HammerInput) => {
|
||||
target.srcEvent.stopPropagation();
|
||||
const interactionTarget = this.interactionEvent(target);
|
||||
this.emit(InteractionEvent.Hover, interactionTarget);
|
||||
};
|
||||
private onTouch = (target: TouchEvent) => {
|
||||
const touch = target.touches[0];
|
||||
// @ts-ignore
|
||||
this.onHover({
|
||||
x: touch.pageX,
|
||||
y: touch.pageY,
|
||||
type: 'touch',
|
||||
});
|
||||
};
|
||||
|
||||
private interactionEvent(target: HammerInput) {
|
||||
const { type, pointerType } = target;
|
||||
|
@ -147,7 +168,7 @@ export default class InteractionService extends EventEmitter
|
|||
this.isDoubleTap(x, y, lngLat);
|
||||
return;
|
||||
}
|
||||
if (type !== 'click' || type !== 'click') {
|
||||
if (type !== 'click' && type !== 'dblclick') {
|
||||
this.emit(InteractionEvent.Hover, {
|
||||
x,
|
||||
y,
|
||||
|
@ -161,7 +182,7 @@ export default class InteractionService extends EventEmitter
|
|||
const nowTime = new Date().getTime();
|
||||
let type = 'click';
|
||||
if (
|
||||
nowTime - this.lastClickTime < 500 &&
|
||||
nowTime - this.lastClickTime < 400 &&
|
||||
Math.abs(this.lastClickXY[0] - x) < 10 &&
|
||||
Math.abs(this.lastClickXY[1] - y) < 10
|
||||
) {
|
||||
|
@ -179,7 +200,7 @@ export default class InteractionService extends EventEmitter
|
|||
this.clickTimer = setTimeout(() => {
|
||||
type = 'click';
|
||||
this.emit(InteractionEvent.Hover, { x, y, lngLat, type });
|
||||
}, 500);
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,20 +84,21 @@ export default class PickingService implements IPickingService {
|
|||
useFramebuffer(this.pickingFBO, () => {
|
||||
const layers = this.layerService.getLayers();
|
||||
layers
|
||||
.filter((layer) => layer.needPick())
|
||||
.filter((layer) => layer.needPick(target.type))
|
||||
.reverse()
|
||||
.forEach((layer) => {
|
||||
.some((layer) => {
|
||||
clear({
|
||||
framebuffer: this.pickingFBO,
|
||||
color: [0, 0, 0, 0],
|
||||
stencil: 0,
|
||||
depth: 1,
|
||||
});
|
||||
|
||||
layer.hooks.beforePickingEncode.call();
|
||||
layer.renderModels();
|
||||
layer.hooks.afterPickingEncode.call();
|
||||
this.pickFromPickingFBO(layer, target);
|
||||
const isPicked = this.pickFromPickingFBO(layer, target);
|
||||
return isPicked && !layer.getLayerConfig().enablePropagation;
|
||||
// return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -105,6 +106,7 @@ export default class PickingService implements IPickingService {
|
|||
layer: ILayer,
|
||||
{ x, y, lngLat, type }: IInteractionTarget,
|
||||
) => {
|
||||
let isPicked = false;
|
||||
const { getViewportSize, readPixels } = this.rendererService;
|
||||
const { width, height } = getViewportSize();
|
||||
const { enableHighlight, enableSelect } = layer.getLayerConfig();
|
||||
|
@ -117,7 +119,7 @@ export default class PickingService implements IPickingService {
|
|||
yInDevicePixel > height - 1 * window.devicePixelRatio ||
|
||||
yInDevicePixel < 0
|
||||
) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
let pickedColors: Uint8Array | undefined;
|
||||
pickedColors = readPixels({
|
||||
|
@ -136,6 +138,13 @@ export default class PickingService implements IPickingService {
|
|||
) {
|
||||
const pickedFeatureIdx = decodePickingColor(pickedColors);
|
||||
const rawFeature = layer.getSource().getFeatureById(pickedFeatureIdx);
|
||||
if (
|
||||
pickedFeatureIdx !== layer.getCurrentPickId() &&
|
||||
type === 'mousemove'
|
||||
) {
|
||||
type = 'mouseenter';
|
||||
}
|
||||
|
||||
const target = {
|
||||
x,
|
||||
y,
|
||||
|
@ -150,15 +159,20 @@ export default class PickingService implements IPickingService {
|
|||
// );
|
||||
} else {
|
||||
// trigger onHover/Click callback on layer
|
||||
isPicked = true;
|
||||
layer.setCurrentPickId(pickedFeatureIdx);
|
||||
this.triggerHoverOnLayer(layer, target);
|
||||
this.triggerHoverOnLayer(layer, target); // 触发拾取事件
|
||||
}
|
||||
} else {
|
||||
// 未选中
|
||||
const target = {
|
||||
x,
|
||||
y,
|
||||
lngLat,
|
||||
type: layer.getCurrentPickId() === null ? 'un' + type : 'mouseout',
|
||||
type:
|
||||
layer.getCurrentPickId() !== null && type === 'mousemove'
|
||||
? 'mouseout'
|
||||
: 'un' + type,
|
||||
featureId: null,
|
||||
feature: null,
|
||||
};
|
||||
|
@ -178,8 +192,19 @@ export default class PickingService implements IPickingService {
|
|||
type === 'click' &&
|
||||
pickedColors?.toString() !== [0, 0, 0, 0].toString()
|
||||
) {
|
||||
this.selectFeature(layer, pickedColors);
|
||||
const selectedId = decodePickingColor(pickedColors);
|
||||
if (
|
||||
layer.getCurrentSelectedId() === null ||
|
||||
selectedId !== layer.getCurrentSelectedId()
|
||||
) {
|
||||
this.selectFeature(layer, pickedColors);
|
||||
layer.setCurrentSelectedId(selectedId);
|
||||
} else {
|
||||
this.selectFeature(layer, new Uint8Array([0, 0, 0, 0])); // toggle select
|
||||
layer.setCurrentSelectedId(null);
|
||||
}
|
||||
}
|
||||
return isPicked;
|
||||
};
|
||||
private triggerHoverOnLayer(
|
||||
layer: ILayer,
|
||||
|
|
|
@ -84,7 +84,7 @@ export interface ILayer {
|
|||
layerModelNeedUpdate: boolean;
|
||||
layerModel: ILayerModel;
|
||||
dataState: IDataState; // 数据流状态
|
||||
pickedFeatureID: number;
|
||||
pickedFeatureID: number | null;
|
||||
hooks: {
|
||||
init: SyncBailHook;
|
||||
afterInit: SyncBailHook;
|
||||
|
@ -106,12 +106,14 @@ export interface ILayer {
|
|||
options?: ISourceCFG;
|
||||
};
|
||||
multiPassRenderer: IMultiPassRenderer;
|
||||
needPick(): boolean;
|
||||
needPick(type: string): boolean;
|
||||
getLayerConfig(): Partial<ILayerConfig & ISceneConfig>;
|
||||
getContainer(): Container;
|
||||
setContainer(container: Container): void;
|
||||
setCurrentPickId(id: number | null): void;
|
||||
getCurrentPickId(): number | null;
|
||||
setCurrentSelectedId(id: number | null): void;
|
||||
getCurrentSelectedId(): number | null;
|
||||
prepareBuildModel(): void;
|
||||
renderModels(): void;
|
||||
buildModels(): void;
|
||||
|
@ -221,6 +223,8 @@ export interface ILayerConfig {
|
|||
maxZoom: number;
|
||||
visible: boolean;
|
||||
zIndex: number;
|
||||
pickingBuffer: number;
|
||||
enablePropagation: boolean;
|
||||
autoFit: boolean;
|
||||
fitBoundsOptions?: unknown;
|
||||
name: string; //
|
||||
|
|
|
@ -52,11 +52,12 @@ export interface IMapService<RawMap = {}> {
|
|||
getRotation(): number;
|
||||
getBounds(): Bounds;
|
||||
getMapContainer(): HTMLElement | null;
|
||||
getMapCanvasContainer(): HTMLElement;
|
||||
|
||||
// control with raw map
|
||||
setRotation(rotation: number): void;
|
||||
zoomIn(): void;
|
||||
zoomOut(): void;
|
||||
zoomIn(option?: any, eventData?: any): void;
|
||||
zoomOut(option?: any, eventData?: any): void;
|
||||
panTo(p: Point): void;
|
||||
panBy(pixel: Point): void;
|
||||
fitBounds(bound: Bounds, fitBoundsOptions?: unknown): void;
|
||||
|
|
|
@ -130,7 +130,7 @@ export default class PixelPickingPass<
|
|||
* TODO:支持区域拾取
|
||||
*/
|
||||
private pickFromPickingFBO = ({ x, y, lngLat, type }: IInteractionTarget) => {
|
||||
if (!this.layer.isVisible() || !this.layer.needPick()) {
|
||||
if (!this.layer.isVisible() || !this.layer.needPick(type)) {
|
||||
return;
|
||||
}
|
||||
const {
|
||||
|
|
|
@ -5,6 +5,7 @@ uniform vec3 u_PickingColor : [0, 0, 0];
|
|||
uniform vec4 u_HighlightColor : [0, 0, 0, 0];
|
||||
uniform float u_PickingStage : 0.0;
|
||||
uniform float u_PickingThreshold : 1.0;
|
||||
uniform float u_PickingBuffer: 0.0;
|
||||
|
||||
#define PICKING_NONE 0.0
|
||||
#define PICKING_ENCODE 1.0
|
||||
|
@ -25,3 +26,7 @@ void setPickingColor(vec3 pickingColor) {
|
|||
// Stores the picking color so that the fragment shader can render it during picking
|
||||
v_PickingResult.rgb = pickingColor * COLOR_SCALE;
|
||||
}
|
||||
|
||||
float setPickingSize(float x) {
|
||||
return u_PickingStage == PICKING_ENCODE ? x + u_PickingBuffer : x;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@turf/midpoint": "^5.1.5",
|
||||
"@antv/l7-component": "^2.1.9",
|
||||
"@antv/l7": "^2.1.9",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"@turf/circle": "^6.0.1",
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
.l7-control-draw {
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 0 1px rgba(0,0,0,.1);
|
||||
display: flex;
|
||||
a {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 20px 20px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: block;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
border: 0;
|
||||
margin: 1px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:not(:disabled):hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
a:focus {
|
||||
box-shadow: 0 0 2px 2px #0096ff;
|
||||
}
|
||||
.draw-point {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/f7bf0137-7de9-411a-9a37-4880acc58d29.svg');
|
||||
}
|
||||
.draw-line {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/a784e304-afb2-4888-91b4-e0d0e8058810.svg');
|
||||
}
|
||||
.draw-polygon {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/6dd9914d-d625-4424-8db7-19953e67444f.svg');
|
||||
}
|
||||
.draw-rect {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/fe578687-693b-4c27-afb3-0e675d9431ff.svg');
|
||||
}
|
||||
.draw-circle {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/fa234d68-85aa-4628-b1b6-aad47ab093b4.svg');
|
||||
}
|
||||
.draw-delete {
|
||||
background-image: url('https://gw.alipayobjects.com/zos/bmw-prod/0c9ba44b-aba3-4007-ba4e-ab815279886b.svg');
|
||||
}
|
||||
|
||||
}
|
||||
.horizontal {
|
||||
flex-direction: row;
|
||||
a:focus:first-child {
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
a:focus:last-child {
|
||||
border-radius: 0px 4px 4px 4px;
|
||||
}
|
||||
a+a {
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
a:focus:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
a:focus:last-child {
|
||||
border-radius: 0px 0px 4px 4px;
|
||||
}
|
||||
a+a {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
id="svg5738"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="combine.svg">
|
||||
<defs
|
||||
id="defs5740">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4103"
|
||||
id="linearGradient4184"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3003"
|
||||
y1="10"
|
||||
x2="3017"
|
||||
y2="10"
|
||||
gradientTransform="translate(1,2.6171874e-6)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4103">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4105" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4107" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="2.423006"
|
||||
inkscape:cy="12.173165"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2078"
|
||||
inkscape:window-height="1054"
|
||||
inkscape:window-x="900"
|
||||
inkscape:window-y="296"
|
||||
inkscape:window-maximized="0"
|
||||
showguides="false"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:snap-nodes="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5746"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="0.5px"
|
||||
spacingy="0.5px"
|
||||
color="#0000ff"
|
||||
opacity="0.05882353" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5743">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 12.050781 2 C 11.795262 2 11.539542 2.0971762 11.34375 2.2929688 L 10.298828 3.3378906 C 9.9072437 3.7294757 9.9072437 4.360368 10.298828 4.7519531 L 15.248047 9.7011719 C 15.639631 10.092757 16.270525 10.092757 16.662109 9.7011719 L 17.707031 8.65625 C 18.098616 8.2646649 18.098616 7.6337726 17.707031 7.2421875 L 12.757812 2.2929688 C 12.56202 2.0971762 12.306301 2 12.050781 2 z M 8 8 C 7 8 7 9 7.5 9.5 C 7.833333 9.8333 8.5 10.5 8.5 10.5 L 7.5 11.5 C 7.5 11.5 7 12 7.5 12.5 C 8 13 8.5 12.5 8.5 12.5 L 9.5 11.5 L 10.5 12.5 C 11 13 12 13 12 12 L 12 8 L 8 8 z M 4 10.003906 C 3.74451 10.003906 3.4906916 10.103039 3.2949219 10.298828 L 2.2988281 11.294922 C 1.9072888 11.6865 1.9072888 12.315453 2.2988281 12.707031 L 3.296875 13.707031 C 3.6884144 14.098609 4.3193981 14.098609 4.7109375 13.707031 L 5.7070312 12.710938 C 6.0985706 12.31936 6.0985706 11.688453 5.7070312 11.296875 L 4.7070312 10.298828 C 4.5112616 10.103039 4.25549 10.003906 4 10.003906 z M 7.9960938 14 C 7.7405942 14 7.4848395 14.097187 7.2890625 14.292969 L 6.2949219 15.289062 C 5.9033679 15.680626 5.9033679 16.311561 6.2949219 16.703125 L 7.2929688 17.701172 C 7.6845227 18.092735 8.3135242 18.092735 8.7050781 17.701172 L 9.7011719 16.705078 C 10.092726 16.313515 10.092726 15.684532 9.7011719 15.292969 L 8.703125 14.292969 C 8.507348 14.097187 8.2515933 14 7.9960938 14 z "
|
||||
transform="translate(0,1032.3622)"
|
||||
id="rect9198" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 4.7 KiB |
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
id="svg19167"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel+osxmenu r12911"
|
||||
sodipodi:docname="line.svg">
|
||||
<defs
|
||||
id="defs19169" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="12.898775"
|
||||
inkscape:cy="9.5890152"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="751"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:object-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid19715" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata19172">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
|
||||
d="m 13.5,1035.8622 c -1.380712,0 -2.5,1.1193 -2.5,2.5 0,0.3208 0.04614,0.6244 0.15625,0.9063 l -3.75,3.75 c -0.281836,-0.1102 -0.585421,-0.1563 -0.90625,-0.1563 -1.380712,0 -2.5,1.1193 -2.5,2.5 0,1.3807 1.119288,2.5 2.5,2.5 1.380712,0 2.5,-1.1193 2.5,-2.5 0,-0.3208 -0.04614,-0.6244 -0.15625,-0.9062 l 3.75,-3.75 c 0.281836,0.1101 0.585421,0.1562 0.90625,0.1562 1.380712,0 2.5,-1.1193 2.5,-2.5 0,-1.3807 -1.119288,-2.5 -2.5,-2.5 z"
|
||||
id="rect6467"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 2.4 KiB |
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
id="svg19167"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel+osxmenu r12911"
|
||||
sodipodi:docname="marker.svg">
|
||||
<defs
|
||||
id="defs19169" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="14.164253"
|
||||
inkscape:cy="8.88572"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="751"
|
||||
inkscape:window-x="208"
|
||||
inkscape:window-y="190"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:object-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid19715" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata19172">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 36,1040.3622 c 6e-6,3.3093 -5.988612,10 -5.988612,10 0,0 -5.998776,-6.668 -6.011345,-9.9772 -0.01257,-3.3092 2.656576,-6.0039 5.965792,-6.0227 3.309189,-0.019 6.00884,2.6452 6.033992,5.9543"
|
||||
id="path12561"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccssc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="m 34.000115,1040.3622 c -5e-6,2.2062 -3.992523,7.0001 -3.992523,7.0001 0,0 -3.999291,-4.7787 -4.007679,-6.9849 -0.0084,-2.2062 1.771082,-4.0027 3.97731,-4.0153 2.20621,-0.013 4.006037,1.7635 4.022777,3.9697"
|
||||
id="path12563"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccsc" />
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 9.9667969,1014.3622 C 6.6575809,1014.381 3.98743,1017.0764 4,1020.3856 c 0.012569,3.3092 6.011719,8.9766 6.011719,8.9766 0,0 5.988287,-5.6907 5.988281,-9 l 0,-0.045 c -0.02515,-3.3091 -2.724014,-5.9741 -6.0332031,-5.9551 z m 0.00977,2 c 2.2062061,-0.013 4.0066931,1.7626 4.0234331,3.9688 l 0,0.031 c -5e-6,2.2062 -3.992188,6 -3.992188,6 0,0 -3.999424,-3.7782 -4.007812,-5.9844 -0.0084,-2.2062 1.7703345,-4.003 3.9765625,-4.0156 z"
|
||||
id="path12568"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscsccccscsc" />
|
||||
<path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none"
|
||||
d="M 10 2 C 6.686292 2 4 4.6863 4 8 C 4 11.3137 10 17 10 17 C 10 17 16 11.3137 16 8 C 16 4.6863 13.313708 2 10 2 z M 10 4 C 12.071068 4 13.75 5.6789 13.75 7.75 C 13.75 9.2053278 11.93111 11.644393 10.830078 13 L 9.1699219 13 C 8.0688903 11.644393 6.25 9.2053278 6.25 7.75 C 6.25 5.6789 7.928932 4 10 4 z "
|
||||
transform="translate(0,1032.3622)"
|
||||
id="path17305" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 5.1 KiB |
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
id="svg19167"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel+osxmenu r12911"
|
||||
sodipodi:docname="square.svg">
|
||||
<defs
|
||||
id="defs19169" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="11.681634"
|
||||
inkscape:cy="9.2857143"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="751"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:object-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid19715" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata19172">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate"
|
||||
d="m 5,1039.3622 0,6 2,2 6,0 2,-2 0,-6 -2,-2 -6,0 z m 3,0 4,0 1,1 0,4 -1,1 -4,0 -1,-1 0,-4 z"
|
||||
id="rect7797"
|
||||
sodipodi:nodetypes="cccccccccccccccccc" />
|
||||
<circle
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;enable-background:accumulate"
|
||||
id="path4364"
|
||||
cx="6"
|
||||
cy="1046.3622"
|
||||
r="2" />
|
||||
<circle
|
||||
id="path4368"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;enable-background:accumulate"
|
||||
cx="14"
|
||||
cy="1046.3622"
|
||||
r="2" />
|
||||
<circle
|
||||
id="path4370"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;enable-background:accumulate"
|
||||
cx="6"
|
||||
cy="1038.3622"
|
||||
r="2" />
|
||||
<circle
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.60000002;marker:none;enable-background:accumulate"
|
||||
id="path4372"
|
||||
cx="14"
|
||||
cy="1038.3622"
|
||||
r="2" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 3.3 KiB |
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
id="svg5738"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel+osxmenu r12911"
|
||||
sodipodi:docname="trash.svg"
|
||||
viewBox="0 0 20 20">
|
||||
<defs
|
||||
id="defs5740" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="12.128184"
|
||||
inkscape:cy="8.8461307"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1033"
|
||||
inkscape:window-height="751"
|
||||
inkscape:window-x="20"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:object-nodes="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5746"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5743">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982;marker:none;enable-background:accumulate"
|
||||
d="m 10,1035.7743 c -0.7849253,8e-4 -1.4968376,0.4606 -1.8203125,1.1758 l -3.1796875,0 -1,1 0,1 12,0 0,-1 -1,-1 -3.179688,0 c -0.323475,-0.7152 -1.035387,-1.175 -1.820312,-1.1758 z m -5,4.5879 0,7 c 0,1 1,2 2,2 l 6,0 c 1,0 2,-1 2,-2 l 0,-7 -2,0 0,5.5 -1.5,0 0,-5.5 -3,0 0,5.5 -1.5,0 0,-5.5 z"
|
||||
id="rect2439-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccccccccccccccccc" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 2.5 KiB |
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="20"
|
||||
height="20"
|
||||
id="svg5738"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="uncombine.svg">
|
||||
<defs
|
||||
id="defs5740">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4103"
|
||||
id="linearGradient4184"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="3003"
|
||||
y1="10"
|
||||
x2="3017"
|
||||
y2="10"
|
||||
gradientTransform="translate(1,2.6171874e-6)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4103">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4105" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4107" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.313708"
|
||||
inkscape:cx="-10.273946"
|
||||
inkscape:cy="6.930344"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2078"
|
||||
inkscape:window-height="1054"
|
||||
inkscape:window-x="900"
|
||||
inkscape:window-y="296"
|
||||
inkscape:window-maximized="0"
|
||||
showguides="false"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:snap-nodes="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5746"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="0.5px"
|
||||
spacingy="0.5px"
|
||||
color="#0000ff"
|
||||
opacity="0.05882353" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5743">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1032.3622)">
|
||||
<path
|
||||
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||
d="M 12.005859 2 C 11.75036 2 11.494605 2.097187 11.298828 2.2929688 L 10.302734 3.2890625 C 9.9111804 3.680626 9.9111804 4.3115615 10.302734 4.703125 L 11.302734 5.7011719 C 11.694288 6.0927354 12.32329 6.0927354 12.714844 5.7011719 L 13.710938 4.7050781 C 14.102491 4.3135146 14.102491 3.6825791 13.710938 3.2910156 L 12.712891 2.2929688 C 12.517114 2.097187 12.261359 2 12.005859 2 z M 16.001953 5.9941406 C 15.746463 5.9941406 15.490692 6.0932735 15.294922 6.2890625 L 14.298828 7.2851562 C 13.907289 7.6767342 13.907289 8.3056877 14.298828 8.6972656 L 15.296875 9.6972656 C 15.688414 10.088844 16.319398 10.088844 16.710938 9.6972656 L 17.707031 8.7011719 C 18.098571 8.3095939 18.098571 7.6786873 17.707031 7.2871094 L 16.708984 6.2890625 C 16.513215 6.0932735 16.257443 5.9941406 16.001953 5.9941406 z M 9 7 C 8 7 8 8 8.5 8.5 C 8.833333 8.8333 9.5 9.5 9.5 9.5 L 8.5 10.5 C 8.5 10.5 8 11 8.5 11.5 C 9 12 9.5 11.5 9.5 11.5 L 10.5 10.5 L 11.5 11.5 C 12 12 13 12 13 11 L 13 7 L 9 7 z M 4.0488281 10.001953 C 3.7933087 10.001953 3.5375891 10.099129 3.3417969 10.294922 L 2.2988281 11.337891 C 1.9072437 11.729476 1.9072437 12.360368 2.2988281 12.751953 L 7.2480469 17.701172 C 7.6396313 18.092757 8.270525 18.092757 8.6621094 17.701172 L 9.7050781 16.658203 C 10.096663 16.266618 10.096663 15.635726 9.7050781 15.244141 L 4.7558594 10.294922 C 4.5600672 10.099129 4.3043475 10.001953 4.0488281 10.001953 z "
|
||||
transform="translate(0,1032.3622)"
|
||||
id="rect9198" />
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 4.8 KiB |
|
@ -0,0 +1,142 @@
|
|||
import { Control, IControlOption, PositionType, Scene } from '@antv/l7';
|
||||
import { DOM } from '@antv/l7-utils';
|
||||
import './css/draw.less';
|
||||
import {
|
||||
DrawCircle,
|
||||
DrawDelete,
|
||||
DrawFeature,
|
||||
DrawLine,
|
||||
DrawPoint,
|
||||
DrawPolygon,
|
||||
DrawRect,
|
||||
} from './modes';
|
||||
import { DrawEvent, DrawModes } from './util/constant';
|
||||
export interface IControls {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
|
||||
export interface IDrawControlOption extends IControlOption {
|
||||
pickBuffer: number;
|
||||
controls: IControls;
|
||||
layout: 'horizontal' | 'vertical';
|
||||
}
|
||||
export class DrawControl extends Control {
|
||||
private draw: {
|
||||
[key: string]: DrawFeature;
|
||||
} = {};
|
||||
private drawDelete: DrawDelete;
|
||||
private currentDraw: DrawFeature;
|
||||
private scene: Scene;
|
||||
constructor(scene: Scene, options: Partial<IDrawControlOption>) {
|
||||
super(options);
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
position: PositionType.TOPLEFT,
|
||||
controls: {
|
||||
point: true,
|
||||
},
|
||||
name: 'draw',
|
||||
};
|
||||
}
|
||||
|
||||
public onAdd(): HTMLElement {
|
||||
const { layout } = this.controlOption;
|
||||
const controlClass = 'l7-control-draw' + ' ' + layout;
|
||||
const { controls } = this.controlOption as IDrawControlOption;
|
||||
const container = DOM.create('div', controlClass) as HTMLElement;
|
||||
if (controls.point) {
|
||||
this.draw.point = new DrawPoint(this.scene);
|
||||
this.createButton(
|
||||
'绘制点',
|
||||
'draw-point',
|
||||
container,
|
||||
this.onButtonClick.bind(null, 'point'),
|
||||
);
|
||||
}
|
||||
if (controls.line) {
|
||||
this.draw.line = new DrawLine(this.scene);
|
||||
this.createButton(
|
||||
'绘制线',
|
||||
'draw-line',
|
||||
container,
|
||||
this.onButtonClick.bind(null, 'line'),
|
||||
);
|
||||
}
|
||||
if (controls.polygon) {
|
||||
this.createButton(
|
||||
'绘制面',
|
||||
'draw-polygon',
|
||||
container,
|
||||
this.onButtonClick.bind(null, 'polygon'),
|
||||
);
|
||||
this.draw.polygon = new DrawPolygon(this.scene);
|
||||
}
|
||||
if (controls.rect) {
|
||||
this.draw.rect = new DrawRect(this.scene);
|
||||
this.createButton(
|
||||
'绘制矩形',
|
||||
'draw-rect',
|
||||
container,
|
||||
this.onButtonClick.bind(null, 'rect'),
|
||||
);
|
||||
}
|
||||
if (controls.circle) {
|
||||
this.draw.circle = new DrawCircle(this.scene);
|
||||
this.createButton(
|
||||
'绘制圆',
|
||||
'draw-circle',
|
||||
container,
|
||||
this.onButtonClick.bind(null, 'circle'),
|
||||
);
|
||||
}
|
||||
|
||||
if (controls.delete) {
|
||||
this.drawDelete = new DrawDelete(this.scene);
|
||||
this.createButton(
|
||||
'删除',
|
||||
'draw-delete',
|
||||
container,
|
||||
this.onDeleteMode.bind(null, 'delete'),
|
||||
);
|
||||
}
|
||||
// 监听组件 选中, 编辑
|
||||
return container;
|
||||
}
|
||||
|
||||
private createButton(
|
||||
tile: string,
|
||||
className: string,
|
||||
container: HTMLElement,
|
||||
fn: (...arg: any[]) => any,
|
||||
) {
|
||||
const link = DOM.create('a', className, container) as HTMLLinkElement;
|
||||
link.href = 'javascript:void(0)';
|
||||
link.title = tile;
|
||||
link.addEventListener('mousedown', fn, true);
|
||||
return link;
|
||||
}
|
||||
|
||||
private onButtonClick = (type: string, e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
for (const draw in this.draw) {
|
||||
if (draw === type) {
|
||||
this.draw[draw].enable();
|
||||
this.currentDraw = this.draw[draw];
|
||||
} else {
|
||||
this.draw[draw].disable();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private onDeleteMode = (type: string, e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (!this.currentDraw) {
|
||||
return;
|
||||
}
|
||||
this.currentDraw.deleteMode.enable();
|
||||
return false;
|
||||
};
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
export * from './modes/index';
|
||||
export * from './draw_control';
|
||||
|
|
|
@ -1,96 +1,130 @@
|
|||
import { IInteractionTarget, ILngLat, PointLayer, Scene } from '@antv/l7';
|
||||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import { Feature, FeatureCollection, point } from '@turf/helpers';
|
||||
import selectRender from '../render/selected';
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
Geometries,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import { createCircle } from '../util/create_geometry';
|
||||
import moveFeatures, { movePoint, moveRing } from '../util/move_featrues';
|
||||
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;
|
||||
}
|
||||
let CircleFeatureId = 0;
|
||||
export default class DrawCircle extends DrawFeature {
|
||||
private startPoint: ILngLat;
|
||||
private endPoint: ILngLat;
|
||||
protected startPoint: ILngLat;
|
||||
protected endPoint: ILngLat;
|
||||
protected pointFeatures: Feature[];
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.selectLayer = new selectRender(this);
|
||||
this.type = 'circle';
|
||||
}
|
||||
|
||||
public drawFinish() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public setCurrentFeature(feature: Feature) {
|
||||
this.currentFeature = feature as Feature;
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
this.pointFeatures = feature.properties.pointFeatures;
|
||||
// @ts-ignore
|
||||
this.startPoint = feature.properties.startPoint;
|
||||
// @ts-ignore
|
||||
this.endPoint = feature.properties.endPoint;
|
||||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
this.startPoint = e.lngLat;
|
||||
this.setCursor('grabbing');
|
||||
this.initCenterLayer();
|
||||
this.initDrawFillLayer();
|
||||
this.centerLayer.setData([this.startPoint]);
|
||||
};
|
||||
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
this.endPoint = e.lngLat;
|
||||
const feature = this.createFeature();
|
||||
this.updateDrawFillLayer(feature);
|
||||
const feature = this.createFeature() as Feature<Geometries, Properties>;
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawRender.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
const feature = this.createFeature(`${this.getUniqId()}`);
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawRender.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.disable();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta)[0];
|
||||
const properties = newFeature.properties as {
|
||||
startPoint: [number, number];
|
||||
endPoint: [number, number];
|
||||
};
|
||||
const { startPoint, endPoint } = properties;
|
||||
properties.startPoint = movePoint(startPoint, delta);
|
||||
properties.endPoint = movePoint(endPoint, delta);
|
||||
newFeature.properties = properties;
|
||||
protected moveFeature(delta: ILngLat): void {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
this.drawRender.updateData(featureCollection(newFeature));
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
const newStartPoint = movePoint(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
delta,
|
||||
);
|
||||
this.startPoint = {
|
||||
lat: startPoint[1],
|
||||
lng: startPoint[0],
|
||||
lat: newStartPoint[1],
|
||||
lng: newStartPoint[0],
|
||||
};
|
||||
this.endPoint = {
|
||||
lat: endPoint[1],
|
||||
lng: endPoint[0],
|
||||
newFeature[0].properties = {
|
||||
...newFeature[0].properties,
|
||||
startPoint: this.startPoint,
|
||||
pointFeatures: newPointFeture,
|
||||
};
|
||||
return newFeature;
|
||||
this.centerLayer.setData([this.startPoint]);
|
||||
this.setCurrentFeature(newFeature[0]);
|
||||
}
|
||||
|
||||
protected createFeature(): FeatureCollection {
|
||||
protected createFeature(id: string = '0'): Feature {
|
||||
const points = createPoint([this.endPoint]);
|
||||
const feature = createCircle(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
[this.endPoint.lng, this.endPoint.lat],
|
||||
{
|
||||
pointFeatures: points.features,
|
||||
units: this.getOption('units'),
|
||||
steps: this.getOption('steps'),
|
||||
id: `${CircleFeatureId++}`,
|
||||
id,
|
||||
},
|
||||
);
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: [feature],
|
||||
};
|
||||
return feature;
|
||||
}
|
||||
|
||||
protected editFeature(endPoint: ILngLat): FeatureCollection {
|
||||
protected editFeature(endPoint: ILngLat): void {
|
||||
this.endPoint = endPoint;
|
||||
return this.createFeature();
|
||||
const newFeature = this.createFeature();
|
||||
const properties = newFeature.properties as { pointFeatures: Feature[] };
|
||||
this.drawRender.updateData(featureCollection([newFeature]));
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(properties.pointFeatures),
|
||||
);
|
||||
}
|
||||
|
||||
protected showOtherLayer() {
|
||||
this.centerLayer.setData([this.currentFeature?.properties?.startPoint]);
|
||||
this.centerLayer.show();
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
if (this.currentFeature) {
|
||||
this.centerLayer.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private initCenterLayer() {
|
||||
const centerStyle = this.getStyle('active_point');
|
||||
const centerStyle = this.getStyle('active').point;
|
||||
const layer = new PointLayer()
|
||||
.source([this.startPoint], {
|
||||
parser: {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature } from '@turf/helpers';
|
||||
import { DrawEvent } from '../util/constant';
|
||||
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 {
|
||||
private endPoint: ILngLat;
|
||||
// 绘制完成之后显示
|
||||
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
|
||||
super(scene, options);
|
||||
}
|
||||
|
||||
public enable() {
|
||||
this.emit(DrawEvent.DELETE, '');
|
||||
}
|
||||
public disable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected onDragStart(e: any): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
throw new Error('Method not implemented.');
|
||||
};
|
||||
protected onClick = () => {
|
||||
return null;
|
||||
};
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Popup, Scene } from '@antv/l7';
|
||||
import turfCircle from '@turf/circle';
|
||||
import turfDistance from '@turf/distance';
|
||||
import { Feature, featureCollection, point } from '@turf/helpers';
|
||||
import EditRender from '../render/edit';
|
||||
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature } from '@turf/helpers';
|
||||
import { DrawEvent } from '../util/constant';
|
||||
import DrawFeature, { IDrawOption } from './draw_mode';
|
||||
export type unitsType = 'degrees' | 'radians' | 'miles' | 'kilometers';
|
||||
|
@ -18,7 +15,6 @@ export default class DrawEdit extends DrawFeature {
|
|||
private center: ILngLat;
|
||||
private endPoint: ILngLat;
|
||||
// 绘制完成之后显示
|
||||
private editLayer: EditRender;
|
||||
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
|
||||
super(scene, options);
|
||||
}
|
||||
|
@ -46,6 +42,7 @@ export default class DrawEdit extends DrawFeature {
|
|||
|
||||
protected onDragEnd = () => {
|
||||
this.emit(DrawEvent.UPDATE, null);
|
||||
this.resetCursor();
|
||||
this.disable();
|
||||
};
|
||||
protected onClick = () => {
|
||||
|
|
|
@ -1,31 +1,18 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import turfCircle from '@turf/circle';
|
||||
import turfDistance from '@turf/distance';
|
||||
import { IInteractionTarget, ILayer, ILngLat, Popup, Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
point,
|
||||
} from '@turf/helpers';
|
||||
import EditLayer from '../render/edit';
|
||||
import RenderLayer from '../render/render';
|
||||
import SelectLayer from '../render/selected';
|
||||
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 DrawDelete from './draw_delete';
|
||||
import DrawEdit from './draw_edit';
|
||||
import DrawMode, { IDrawOption } from './draw_mode';
|
||||
import DrawSelected from './draw_selected';
|
||||
let CircleFeatureId = 0;
|
||||
|
||||
export interface IDrawFeatureOption extends IDrawOption {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
|
@ -38,9 +25,11 @@ export default abstract class DrawFeature extends DrawMode {
|
|||
// 绘制完成之后显示
|
||||
public selectMode: DrawSelected;
|
||||
public editMode: DrawEdit;
|
||||
public deleteMode: DrawDelete;
|
||||
|
||||
protected renderLayer: RenderLayer;
|
||||
protected selectLayer: SelectLayer;
|
||||
protected editLayer: EditLayer;
|
||||
protected drawRender: DrawRender;
|
||||
protected drawVertexLayer: DrawVertexLayer;
|
||||
protected centerLayer: ILayer;
|
||||
|
||||
// 编辑过程中显示
|
||||
|
@ -48,20 +37,60 @@ export default abstract class DrawFeature extends DrawMode {
|
|||
protected drawLineLayer: ILayer;
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
this.drawRender = new DrawRender(this);
|
||||
this.drawVertexLayer = new DrawVertexLayer(this);
|
||||
this.renderLayer = new RenderLayer(this);
|
||||
this.selectLayer = new SelectLayer(this);
|
||||
this.editLayer = new EditLayer(this);
|
||||
|
||||
// this.editLayer = new EditLayer(this);
|
||||
this.selectMode = new DrawSelected(this.scene, {});
|
||||
this.editMode = new DrawEdit(this.scene, {});
|
||||
this.deleteMode = new DrawDelete(this.scene, {});
|
||||
|
||||
this.selectMode.on(DrawEvent.UPDATE, this.onDrawUpdate);
|
||||
this.selectMode.on(DrawEvent.Move, this.onDrawMove);
|
||||
this.editMode.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
this.editMode.on(DrawEvent.UPDATE, this.onDrawUpdate);
|
||||
this.editMode.on(DrawEvent.Edit, this.onDrawEdit);
|
||||
this.selectMode.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
|
||||
this.deleteMode.on(DrawEvent.DELETE, this.onDrawDelete);
|
||||
this.on(DrawEvent.CREATE, this.onDrawCreate);
|
||||
this.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
}
|
||||
public abstract drawFinish(): void;
|
||||
public setCurrentFeature(feature: Feature) {
|
||||
this.currentFeature = feature as Feature;
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
this.pointFeatures = feature.properties.pointFeatures;
|
||||
|
||||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
public deleteCurrentFeature() {
|
||||
this.deleteMode.enable();
|
||||
}
|
||||
public disableLayer() {
|
||||
// this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
this.drawRender.disableDrag();
|
||||
}
|
||||
public enableLayer() {
|
||||
this.drawRender.enableDrag();
|
||||
}
|
||||
public clear() {
|
||||
this.drawRender.hide();
|
||||
this.drawVertexLayer.hide();
|
||||
this.hideOtherLayer();
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
}
|
||||
public reset() {
|
||||
this.drawRender.show();
|
||||
this.drawVertexLayer.show();
|
||||
this.showOtherLayer();
|
||||
}
|
||||
|
||||
public addVertex(feature: Feature): void {
|
||||
throw new Error('子类未实现该方法');
|
||||
}
|
||||
protected getDefaultOptions() {
|
||||
return {
|
||||
steps: 64,
|
||||
|
@ -75,72 +104,15 @@ export default abstract class DrawFeature extends DrawMode {
|
|||
|
||||
protected abstract onDragEnd(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract createFeature(e: ILngLat): FeatureCollection;
|
||||
protected abstract createFeature(e?: any): Feature;
|
||||
|
||||
protected abstract moveFeature(e: ILngLat): Feature;
|
||||
protected abstract moveFeature(e: ILngLat): void;
|
||||
|
||||
protected abstract editFeature(e: any): FeatureCollection;
|
||||
protected abstract editFeature(e: any): void;
|
||||
|
||||
protected ondrawLayerClick = () => {
|
||||
if (this.currentFeature === null) {
|
||||
return;
|
||||
}
|
||||
this.currentFeature = null;
|
||||
this.renderLayer.updateData();
|
||||
this.centerLayer.setData([]);
|
||||
this.drawLayer.setData(InitFeature);
|
||||
this.drawLineLayer.setData(InitFeature);
|
||||
return;
|
||||
};
|
||||
protected initDrawFillLayer() {
|
||||
const style = this.getStyle('active_fill');
|
||||
const linestyle = this.getStyle('active_line');
|
||||
this.drawLayer = new PolygonLayer()
|
||||
.source(InitFeature)
|
||||
.color(style.color)
|
||||
.shape('fill')
|
||||
.style(style.style);
|
||||
this.drawLineLayer = new PolygonLayer()
|
||||
.source(InitFeature)
|
||||
.color(linestyle.color)
|
||||
.size(linestyle.size)
|
||||
.shape('line')
|
||||
.style(linestyle.style);
|
||||
this.scene.addLayer(this.drawLayer);
|
||||
this.scene.addLayer(this.drawLineLayer);
|
||||
}
|
||||
protected abstract hideOtherLayer(): void;
|
||||
|
||||
protected updateDrawFillLayer(currentData: any) {
|
||||
this.drawLayer.setData(currentData);
|
||||
this.drawLineLayer.setData(currentData);
|
||||
}
|
||||
|
||||
private removeDrawLayer() {
|
||||
this.scene.removeLayer(this.drawLayer);
|
||||
this.scene.removeLayer(this.drawLineLayer);
|
||||
this.scene.removeLayer(this.centerLayer);
|
||||
}
|
||||
|
||||
private createCircleData(center: ILngLat, endPoint: ILngLat) {
|
||||
const radius = turfDistance(
|
||||
point([center.lng, center.lat]),
|
||||
point([endPoint.lng, endPoint.lat]),
|
||||
this.getOption('units'),
|
||||
);
|
||||
const feature = turfCircle([center.lng, center.lat], radius, {
|
||||
units: this.getOption('units'),
|
||||
steps: this.getOption('steps'),
|
||||
properties: {
|
||||
id: `${CircleFeatureId++}`,
|
||||
active: true,
|
||||
radius,
|
||||
center,
|
||||
endPoint,
|
||||
},
|
||||
});
|
||||
this.currentFeature = feature as Feature;
|
||||
return featureCollection([feature]);
|
||||
}
|
||||
protected abstract showOtherLayer(): void;
|
||||
|
||||
private addDrawPopup(lnglat: ILngLat, dis: number) {
|
||||
const popup = new Popup({
|
||||
|
@ -156,34 +128,50 @@ export default abstract class DrawFeature extends DrawMode {
|
|||
private onModeChange = (mode: DrawModes[any]) => {
|
||||
switch (mode) {
|
||||
case DrawModes.DIRECT_SELECT:
|
||||
this.selectLayer.hide();
|
||||
this.editMode.enable();
|
||||
this.editMode.setEditFeature(this.currentFeature as Feature);
|
||||
this.editLayer.updateData(
|
||||
this.drawRender.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
this.editLayer.show();
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(this.currentFeature?.properties?.pointFeatures),
|
||||
);
|
||||
this.drawVertexLayer.show();
|
||||
this.drawVertexLayer.enableEdit();
|
||||
this.showOtherLayer();
|
||||
this.drawStatus = 'DrawEdit';
|
||||
break;
|
||||
case DrawModes.SIMPLE_SELECT:
|
||||
this.renderLayer.updateData();
|
||||
this.selectMode.setSelectedFeature(this.currentFeature as Feature);
|
||||
this.selectLayer.updateData(
|
||||
this.selectMode.enable();
|
||||
this.drawRender.enableDrag();
|
||||
this.drawRender.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
this.selectLayer.show();
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(this.currentFeature?.properties?.pointFeatures),
|
||||
);
|
||||
this.drawVertexLayer.disableEdit();
|
||||
this.drawVertexLayer.show();
|
||||
this.drawRender.show();
|
||||
this.showOtherLayer();
|
||||
this.drawStatus = 'DrawSelected';
|
||||
break;
|
||||
case DrawModes.STATIC:
|
||||
this.source.setFeatureUnActive(this.currentFeature as Feature);
|
||||
this.renderLayer.updateData();
|
||||
this.source.updateFeature(this.currentFeature as Feature);
|
||||
this.source.clearFeatureActive();
|
||||
this.drawVertexLayer.hide();
|
||||
this.drawVertexLayer.disableEdit();
|
||||
this.hideOtherLayer();
|
||||
this.renderLayer.update(this.source.data);
|
||||
this.renderLayer.enableDrag();
|
||||
this.drawStatus = 'DrawFinish';
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private onDrawCreate = (feature: Feature) => {
|
||||
this.source.addFeature(feature);
|
||||
if (this.popup) {
|
||||
this.popup.remove();
|
||||
}
|
||||
this.removeDrawLayer();
|
||||
};
|
||||
|
||||
private onDrawUpdate = (feature: Feature) => {
|
||||
|
@ -191,14 +179,21 @@ export default abstract class DrawFeature extends DrawMode {
|
|||
};
|
||||
|
||||
private onDrawMove = (delta: ILngLat) => {
|
||||
const feature = this.moveFeature(delta);
|
||||
this.currentFeature = feature;
|
||||
this.selectLayer.updateData(featureCollection([feature]));
|
||||
this.moveFeature(delta);
|
||||
};
|
||||
|
||||
private onDrawEdit = (endpoint: ILngLat) => {
|
||||
const feature = this.editFeature(endpoint);
|
||||
this.currentFeature = feature.features[0];
|
||||
this.editLayer.updateData(feature);
|
||||
this.editFeature(endpoint);
|
||||
};
|
||||
|
||||
private onDrawDelete = () => {
|
||||
if (this.drawStatus === 'DrawSelected') {
|
||||
this.clear();
|
||||
this.source.removeFeature(this.currentFeature as Feature);
|
||||
this.renderLayer.update(this.source.data);
|
||||
// this.reset();
|
||||
}
|
||||
|
||||
// this.source.removeFeature(this.currentFeature as Feature
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature, featureCollection } from '@turf/helpers';
|
||||
import { unitsType } from '../util/constant';
|
||||
import { createLine, createPoint } from '../util/create_geometry';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
import DrawPolygon from './draw_polygon';
|
||||
export interface IDrawRectOption extends IDrawFeatureOption {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
}
|
||||
export default class DrawLine extends DrawPolygon {
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'line';
|
||||
}
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawRender.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
this.currentFeature = newFeature[0];
|
||||
this.pointFeatures = newPointFeture;
|
||||
return this.currentFeature;
|
||||
}
|
||||
protected createFeature(points: ILngLat[]): Feature {
|
||||
const pointfeatures = createPoint(this.points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
const feature = createLine(points, {
|
||||
id: this.getUniqId(),
|
||||
type: 'line',
|
||||
active: true,
|
||||
pointFeatures: this.pointFeatures,
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { IInteractionTarget, IPopup, Scene } from '@antv/l7';
|
||||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { merge, throttle } from 'lodash';
|
||||
import { merge } from 'lodash';
|
||||
import DrawSource from '../source';
|
||||
import LayerStyles from '../util/layerstyle';
|
||||
|
||||
|
@ -17,9 +17,14 @@ export type DrawStatus =
|
|||
| 'DrawFinish'
|
||||
| 'EditFinish';
|
||||
|
||||
let DrawFeatureId = 0;
|
||||
|
||||
export default abstract class DrawMode extends EventEmitter {
|
||||
public source: DrawSource;
|
||||
public scene: Scene;
|
||||
public type: string;
|
||||
public isEnable: boolean = false;
|
||||
|
||||
protected options: {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
|
@ -27,7 +32,7 @@ export default abstract class DrawMode extends EventEmitter {
|
|||
};
|
||||
protected drawStatus: DrawStatus = 'Drawing';
|
||||
protected currentFeature: Feature | null;
|
||||
protected isEnable: boolean = false;
|
||||
protected currentVertex: Feature | null;
|
||||
protected popup: IPopup;
|
||||
constructor(scene: Scene, options: Partial<IDrawOption> = {}) {
|
||||
super();
|
||||
|
@ -45,6 +50,7 @@ export default abstract class DrawMode extends EventEmitter {
|
|||
this.scene.on('dragstart', this.onDragStart);
|
||||
this.scene.on('dragging', this.onDragging);
|
||||
this.scene.on('dragend', this.onDragEnd);
|
||||
this.scene.on('click', this.onClick);
|
||||
this.setCursor(this.getOption('cursor'));
|
||||
this.isEnable = true;
|
||||
}
|
||||
|
@ -56,7 +62,7 @@ export default abstract class DrawMode extends EventEmitter {
|
|||
this.scene.off('dragstart', this.onDragStart);
|
||||
this.scene.off('dragging', this.onDragging);
|
||||
this.scene.off('dragend', this.onDragEnd);
|
||||
// this.scene.off('click', this.onClick);
|
||||
this.scene.off('click', this.onClick);
|
||||
this.resetCursor();
|
||||
// @ts-ignore
|
||||
this.scene.map.dragPan.enable();
|
||||
|
@ -67,23 +73,42 @@ export default abstract class DrawMode extends EventEmitter {
|
|||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
|
||||
public setCurrentVertex(feature: Feature) {
|
||||
this.currentVertex = feature;
|
||||
}
|
||||
public deleteCurrentFeature() {
|
||||
throw new Error('子类未实现该方法');
|
||||
}
|
||||
|
||||
public getCurrentVertex(feature: Feature) {
|
||||
return this.currentVertex;
|
||||
}
|
||||
public getCurrentFeature() {
|
||||
return this.currentVertex;
|
||||
}
|
||||
|
||||
public getOption(key: string) {
|
||||
return this.options[key];
|
||||
}
|
||||
|
||||
public getStyle(id: string) {
|
||||
return this.getOption('style')[id];
|
||||
}
|
||||
|
||||
public getUniqId() {
|
||||
return DrawFeatureId++;
|
||||
}
|
||||
|
||||
public setCursor(cursor: string) {
|
||||
const container = this.scene.getContainer();
|
||||
const container = this.scene.getMapCanvasContainer();
|
||||
if (container) {
|
||||
container.style.cursor = cursor;
|
||||
}
|
||||
}
|
||||
public resetCursor() {
|
||||
const container = this.scene.getContainer();
|
||||
const container = this.scene.getMapCanvasContainer();
|
||||
if (container) {
|
||||
container.style.cursor = 'default';
|
||||
container.removeAttribute('style');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,4 +121,8 @@ export default abstract class DrawMode extends EventEmitter {
|
|||
protected abstract onDragging(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract onDragEnd(e: IInteractionTarget): void;
|
||||
|
||||
protected onClick(e: IInteractionTarget): any {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
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> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'point';
|
||||
}
|
||||
|
||||
public drawFinish() {
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.disable();
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onClick = (e: any) => {
|
||||
const lngLat = e.lngLat;
|
||||
const feature = this.createFeature(lngLat);
|
||||
this.drawRender.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection([feature]));
|
||||
this.drawFinish();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
this.drawRender.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newFeature));
|
||||
this.currentFeature = newFeature[0];
|
||||
this.pointFeatures = newFeature;
|
||||
this.currentFeature.properties = {
|
||||
...this.currentFeature.properties,
|
||||
pointFeatures: newFeature,
|
||||
};
|
||||
return this.currentFeature;
|
||||
}
|
||||
protected createFeature(p: ILngLat): Feature {
|
||||
const feature = point([p.lng, p.lat], {
|
||||
id: this.getUniqId(),
|
||||
pointFeatures: [point([p.lng, p.lat])],
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
|
||||
protected editFeature(endPoint: ILngLat): void {
|
||||
this.createFeature(endPoint);
|
||||
}
|
||||
|
||||
protected showOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
Geometries,
|
||||
point,
|
||||
Position,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import DrawMidVertex from '../render/draw_mid_vertex';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import { createPoint, createPolygon } from '../util/create_geometry';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
|
||||
export interface IDrawRectOption extends IDrawFeatureOption {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
}
|
||||
export default class DrawPolygon extends DrawFeature {
|
||||
protected startPoint: ILngLat;
|
||||
protected endPoint: ILngLat;
|
||||
protected points: ILngLat[] = [];
|
||||
protected pointFeatures: Feature[];
|
||||
protected drawMidVertexLayer: DrawMidVertex;
|
||||
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'polygon';
|
||||
this.drawMidVertexLayer = new DrawMidVertex(this);
|
||||
this.on(DrawEvent.MODE_CHANGE, this.addMidLayerEvent);
|
||||
}
|
||||
public enable() {
|
||||
super.enable();
|
||||
this.scene.on('mousemove', this.onMouseMove);
|
||||
this.scene.on('dblclick', this.onDblClick);
|
||||
// 关闭双击放大
|
||||
}
|
||||
|
||||
public disable() {
|
||||
super.disable();
|
||||
this.scene.off('mousemove', this.onMouseMove);
|
||||
this.scene.off('dblclick', this.onDblClick);
|
||||
}
|
||||
|
||||
public drawFinish() {
|
||||
const feature = this.createFeature(this.points);
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawRender.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 = [];
|
||||
this.disable();
|
||||
}
|
||||
|
||||
public addVertex(vertex: Feature<Geometries, Properties>) {
|
||||
// @ts-ignore
|
||||
const id = vertex.properties.id;
|
||||
const coord = vertex.geometry.coordinates as Position;
|
||||
const feature = this.currentFeature as Feature<Geometries, Properties>;
|
||||
const type = feature.geometry.type;
|
||||
const points = [];
|
||||
if (type === 'Polygon') {
|
||||
const coords = feature.geometry.coordinates as Position[][];
|
||||
coords[0].splice(id + 1, 0, coord);
|
||||
for (let i = 0; i < coords[0].length - 1; i++) {
|
||||
points.push({
|
||||
lng: coords[0][i][0],
|
||||
lat: coords[0][i][1],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const coords = feature.geometry.coordinates as Position[];
|
||||
coords.splice(id + 1, 0, coord);
|
||||
for (const coor of coords) {
|
||||
points.push({
|
||||
lng: coor[0],
|
||||
lat: coor[1],
|
||||
});
|
||||
}
|
||||
}
|
||||
const pointfeatures = createPoint(points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
this.drawRender.updateData(featureCollection([feature]));
|
||||
this.drawVertexLayer.updateData(pointfeatures);
|
||||
this.drawMidVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
// @ts-ignore
|
||||
feature.properties.pointFeatures = pointfeatures.features;
|
||||
this.setCurrentFeature(feature);
|
||||
}
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onClick = (e: any) => {
|
||||
const lngLat = e.lngLat;
|
||||
this.endPoint = lngLat;
|
||||
this.points.push(lngLat);
|
||||
const feature = this.createFeature(this.points);
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
// const pointfeatures = createPoint([this.points[0], this.endPoint]);
|
||||
// this.pointFeatures = pointfeatures.features;
|
||||
this.drawRender.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
this.onDraw();
|
||||
};
|
||||
|
||||
protected onMouseMove = (e: any) => {
|
||||
const lngLat = e.lngLat;
|
||||
if (this.points.length === 0) {
|
||||
return;
|
||||
}
|
||||
const tmpPoints = this.points.slice();
|
||||
tmpPoints.push(lngLat);
|
||||
const feature = this.createFeature(tmpPoints);
|
||||
this.drawRender.update(featureCollection([feature]));
|
||||
};
|
||||
|
||||
protected onDblClick = (e: any) => {
|
||||
const lngLat = e.lngLat;
|
||||
if (this.points.length < 2) {
|
||||
return;
|
||||
}
|
||||
this.points.push(lngLat);
|
||||
this.drawFinish();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): void {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawRender.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
newFeature[0].properties = {
|
||||
...newFeature[0].properties,
|
||||
pointFeatures: newPointFeture,
|
||||
};
|
||||
this.setCurrentFeature(newFeature[0]);
|
||||
}
|
||||
protected createFeature(points: ILngLat[]): Feature {
|
||||
const pointfeatures = createPoint(this.points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
const feature = createPolygon(points, {
|
||||
id: this.getUniqId(),
|
||||
type: 'polygon',
|
||||
active: true,
|
||||
pointFeatures: this.pointFeatures,
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
|
||||
protected editFeature(vertex: ILngLat) {
|
||||
const selectVertexed = this.currentVertex as Feature<
|
||||
Geometries,
|
||||
Properties
|
||||
>;
|
||||
if (selectVertexed === null) {
|
||||
return featureCollection([]);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
const id = selectVertexed.properties.id * 1;
|
||||
selectVertexed.geometry.coordinates = [vertex.lng, vertex.lat];
|
||||
// @ts-ignore
|
||||
this.pointFeatures[id].geometry.coordinates = [vertex.lng, vertex.lat];
|
||||
this.drawVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
this.drawMidVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
this.editPolygonVertex(id, vertex);
|
||||
this.drawRender.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
const feature = this.currentFeature as Feature;
|
||||
feature.properties = {
|
||||
...this.currentFeature?.properties,
|
||||
pointFeatures: this.pointFeatures,
|
||||
};
|
||||
this.setCurrentFeature(feature);
|
||||
}
|
||||
}
|
||||
|
||||
protected onDraw = () => {
|
||||
this.drawVertexLayer.on('mousemove', (e: any) => {
|
||||
this.setCursor('pointer');
|
||||
});
|
||||
this.drawVertexLayer.on('mouseout', () => {
|
||||
this.setCursor('crosshair');
|
||||
});
|
||||
this.drawVertexLayer.on('click', () => {
|
||||
this.resetCursor();
|
||||
this.drawFinish();
|
||||
});
|
||||
};
|
||||
|
||||
protected showOtherLayer() {
|
||||
// if (this.editMode.isEnable) {
|
||||
// this.drawMidVertexLayer.update(featureCollection(this.pointFeatures));
|
||||
// this.drawMidVertexLayer.show();
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected addMidLayerEvent(mode: DrawModes[any]) {
|
||||
switch (mode) {
|
||||
case DrawModes.DIRECT_SELECT:
|
||||
this.drawMidVertexLayer.update(featureCollection(this.pointFeatures));
|
||||
this.drawMidVertexLayer.show();
|
||||
break;
|
||||
case DrawModes.STATIC:
|
||||
this.drawMidVertexLayer.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private editPolygonVertex(id: number, vertex: ILngLat) {
|
||||
const feature = this.currentFeature as Feature<Geometries, Properties>;
|
||||
const type = feature.geometry.type;
|
||||
if (type === 'Polygon') {
|
||||
const coords = feature.geometry.coordinates as Position[][];
|
||||
coords[0][id] = [vertex.lng, vertex.lat];
|
||||
if (-id === 0) {
|
||||
coords[0][coords[0].length - 1] = [vertex.lng, vertex.lat];
|
||||
}
|
||||
} else {
|
||||
const coords = feature.geometry.coordinates as Position[];
|
||||
coords[id] = [vertex.lng, vertex.lat];
|
||||
}
|
||||
this.setCurrentFeature(feature);
|
||||
this.drawRender.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* draw 端点响应事件
|
||||
* select Polyon 响应事件
|
||||
* edit 端点 中心点响应事件
|
||||
*/
|
|
@ -1,103 +1,38 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import { Feature, FeatureCollection, point } from '@turf/helpers';
|
||||
import selectRender from '../render/selected';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import { creatRect } from '../util/create_geometry';
|
||||
import moveFeatures, { movePoint, moveRing } from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
point,
|
||||
} from '@turf/helpers';
|
||||
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 DrawFeature {
|
||||
private startPoint: ILngLat;
|
||||
private endPoint: ILngLat;
|
||||
export default class DrawRect extends DrawCircle {
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.selectLayer = new selectRender(this);
|
||||
this.type = 'rect';
|
||||
}
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
this.startPoint = e.lngLat;
|
||||
this.setCursor('grabbing');
|
||||
this.initCenterLayer();
|
||||
this.initDrawFillLayer();
|
||||
this.centerLayer.setData([this.startPoint]);
|
||||
};
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
this.endPoint = e.lngLat;
|
||||
const feature = this.createFeature();
|
||||
this.updateDrawFillLayer(feature);
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.disable();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta)[0];
|
||||
const properties = newFeature.properties as {
|
||||
startPoint: [number, number];
|
||||
endPoint: [number, number];
|
||||
};
|
||||
const { startPoint, endPoint } = properties;
|
||||
properties.startPoint = movePoint(startPoint, delta);
|
||||
properties.endPoint = movePoint(endPoint, delta);
|
||||
newFeature.properties = properties;
|
||||
this.startPoint = {
|
||||
lat: startPoint[1],
|
||||
lng: startPoint[0],
|
||||
};
|
||||
this.endPoint = {
|
||||
lat: endPoint[1],
|
||||
lng: endPoint[0],
|
||||
};
|
||||
return newFeature;
|
||||
public drawFinish() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected createFeature(): FeatureCollection {
|
||||
const feature = creatRect(
|
||||
protected createFeature(id: string = '0'): Feature {
|
||||
const points = createPoint([this.endPoint]);
|
||||
const feature = createRect(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
[this.endPoint.lng, this.endPoint.lat],
|
||||
{
|
||||
id,
|
||||
pointFeatures: points.features,
|
||||
},
|
||||
);
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: [feature],
|
||||
};
|
||||
}
|
||||
|
||||
protected editFeature(endPoint: ILngLat): FeatureCollection {
|
||||
this.endPoint = endPoint;
|
||||
return this.createFeature();
|
||||
}
|
||||
|
||||
private initCenterLayer() {
|
||||
const centerStyle = this.getStyle('active_point');
|
||||
const layer = new PointLayer()
|
||||
.source([this.startPoint], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
this.scene.addLayer(layer);
|
||||
this.centerLayer = layer;
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,7 @@ import {
|
|||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import turfCircle from '@turf/circle';
|
||||
import turfDistance from '@turf/distance';
|
||||
import { Feature, featureCollection, point } from '@turf/helpers';
|
||||
import EditRender from '../render/selected';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawOption } from './draw_mode';
|
||||
|
@ -29,7 +26,6 @@ export default class DrawSelect extends DrawFeature {
|
|||
private center: ILngLat;
|
||||
private dragStartPoint: ILngLat;
|
||||
// 绘制完成之后显示
|
||||
private editLayer: EditRender;
|
||||
constructor(scene: Scene, options: Partial<IDrawCircleOption> = {}) {
|
||||
super(scene, options);
|
||||
// this.editLayer = new EditRender(this);
|
||||
|
@ -37,11 +33,6 @@ export default class DrawSelect extends DrawFeature {
|
|||
|
||||
public setSelectedFeature(feature: Feature) {
|
||||
this.currentFeature = feature;
|
||||
// this.editLayer.updateData({
|
||||
// type: 'FeatureCollection',
|
||||
// features: [feature],
|
||||
// });
|
||||
// this.editLayer.show();
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
|
@ -74,42 +65,4 @@ export default class DrawSelect extends DrawFeature {
|
|||
protected onClick = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
private createCircleData(center: ILngLat, endPoint: ILngLat) {
|
||||
const radius = turfDistance(
|
||||
point([center.lng, center.lat]),
|
||||
point([endPoint.lng, endPoint.lat]),
|
||||
this.getOption('units'),
|
||||
);
|
||||
const feature = turfCircle([center.lng, center.lat], radius, {
|
||||
units: this.getOption('units'),
|
||||
steps: this.getOption('steps'),
|
||||
properties: {
|
||||
id: `${this.currentFeature?.properties?.id}`,
|
||||
active: true,
|
||||
radius,
|
||||
center,
|
||||
endPoint,
|
||||
},
|
||||
});
|
||||
this.currentFeature = feature as Feature;
|
||||
return featureCollection([feature]);
|
||||
}
|
||||
|
||||
private moveCircle(feature: Feature, delta: ILngLat) {
|
||||
const preCenter = feature?.properties?.center as ILngLat;
|
||||
const preEndPoint = feature?.properties?.endPoint as ILngLat;
|
||||
const newCenter = {
|
||||
lng: preCenter.lng + delta.lng,
|
||||
lat: preCenter.lat + delta.lat,
|
||||
};
|
||||
const newEndPoint = {
|
||||
lng: preEndPoint.lng + delta.lng,
|
||||
lat: preEndPoint.lat + delta.lat,
|
||||
};
|
||||
|
||||
const newCircle = this.createCircleData(newCenter, newEndPoint);
|
||||
// this.centerLayer.setData([newCenter]);
|
||||
this.editLayer.updateData(newCircle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
import DrawCircle from './draw_circle';
|
||||
import DrawDelete from './draw_delete';
|
||||
import DrawFeature from './draw_feature';
|
||||
import DrawLine from './draw_line';
|
||||
import DrawMode from './draw_mode';
|
||||
import DrawPoint from './draw_point';
|
||||
import DrawPolygon from './draw_polygon';
|
||||
import DrawRect from './draw_rect';
|
||||
export { DrawCircle, DrawRect };
|
||||
export {
|
||||
DrawCircle,
|
||||
DrawFeature,
|
||||
DrawRect,
|
||||
DrawPolygon,
|
||||
DrawPoint,
|
||||
DrawLine,
|
||||
DrawMode,
|
||||
DrawDelete,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import { IInteractionTarget, ILayer, Scene } from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
type CallBack = (...args: any[]) => any;
|
||||
import { FeatureCollection } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class BaseRenderLayer {
|
||||
public drawLayers: ILayer[] = [];
|
||||
protected draw: Draw;
|
||||
protected isEnableDrag: boolean;
|
||||
protected isEnableEdit: boolean;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
}
|
||||
public update(feature: FeatureCollection) {
|
||||
if (this.drawLayers.length > 0) {
|
||||
this.updateData(feature);
|
||||
}
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('normal');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public on(type: any, handler: CallBack) {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on(type, handler);
|
||||
}
|
||||
public off(type: any, handler: CallBack) {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off(type, handler);
|
||||
}
|
||||
public updateData(data: any) {
|
||||
this.drawLayers.forEach((layer) => layer.setData(data));
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.removeLayers();
|
||||
}
|
||||
|
||||
public removeLayers() {
|
||||
if (this.drawLayers.length !== 0) {
|
||||
this.drawLayers.forEach((layer) => this.draw.scene.removeLayer(layer));
|
||||
}
|
||||
}
|
||||
public addLayers() {
|
||||
this.drawLayers.forEach((layer) => this.draw.scene.addLayer(layer));
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.drawLayers.forEach((layer) => layer.show());
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.drawLayers.forEach((layer) => layer.hide());
|
||||
}
|
||||
}
|
|
@ -1,82 +1,89 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import { IInteractionTarget, ILayer, Scene } from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
import Draw from '../modes/draw_mode';
|
||||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
export default class DrawLayer {
|
||||
private polygonLayer: ILayer;
|
||||
private lineLayer: ILayer;
|
||||
private draw: Draw;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
this.init();
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('active');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public init() {
|
||||
const style = this.draw.getStyle('normal_fill');
|
||||
const linestyle = this.draw.getStyle('normal_line');
|
||||
this.polygonLayer = new PolygonLayer({
|
||||
zIndex: 0,
|
||||
})
|
||||
.source(InitFeature)
|
||||
.filter('active', (active) => {
|
||||
return !active;
|
||||
})
|
||||
.shape('fill')
|
||||
.active(true)
|
||||
.color(style.color)
|
||||
.style(style.style);
|
||||
|
||||
this.lineLayer = new LineLayer({
|
||||
zIndex: 1,
|
||||
})
|
||||
.source(InitFeature)
|
||||
.shape('line')
|
||||
.filter('active', (active) => {
|
||||
return !active;
|
||||
})
|
||||
.size(linestyle.size)
|
||||
.color(linestyle.color)
|
||||
.style(linestyle.style);
|
||||
this.draw.scene.addLayer(this.polygonLayer);
|
||||
this.draw.scene.addLayer(this.lineLayer);
|
||||
this.addLayerEvent();
|
||||
public enableDrag() {
|
||||
this.show();
|
||||
if (this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseMove);
|
||||
layer.on('mouseout', this.onUnMouseMove);
|
||||
layer.on('click', this.onClick);
|
||||
layer.on('unmousedown', this.onUnClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
public updateData() {
|
||||
this.lineLayer.setData(this.draw.source.data);
|
||||
this.polygonLayer.setData(this.draw.source.data);
|
||||
public disableDrag() {
|
||||
if (!this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseMove);
|
||||
layer.off('mouseout', this.onUnMouseMove);
|
||||
layer.off('click', this.onClick);
|
||||
layer.off('unmousedown', this.onUnClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.draw.scene.removeLayer(this.lineLayer);
|
||||
this.draw.scene.removeLayer(this.polygonLayer);
|
||||
public enableEdit() {
|
||||
if (this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('unclick', this.onUnClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.lineLayer.show();
|
||||
this.polygonLayer.show();
|
||||
public disableEdit() {
|
||||
if (!this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('unclick', this.onUnClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.lineLayer.hide();
|
||||
this.polygonLayer.hide();
|
||||
}
|
||||
private onMouseMove = (e: any) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.selectMode.enable();
|
||||
};
|
||||
private onUnMouseMove = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.selectMode.disable();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.selectMode.disable();
|
||||
this.draw.editMode.enable();
|
||||
this.disableDrag();
|
||||
this.draw.resetCursor();
|
||||
this.enableEdit();
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.DIRECT_SELECT);
|
||||
};
|
||||
|
||||
private addLayerEvent() {
|
||||
this.polygonLayer.on('click', (e) => {
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
});
|
||||
}
|
||||
private onUnClick = (e: any) => {
|
||||
this.draw.selectMode.disable();
|
||||
this.draw.editMode.disable();
|
||||
this.draw.source.setFeatureUnActive(
|
||||
this.draw.getCurrentFeature() as Feature,
|
||||
);
|
||||
this.disableDrag();
|
||||
this.disableEdit();
|
||||
this.hide();
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
import {
|
||||
feature,
|
||||
Feature,
|
||||
featureCollection,
|
||||
FeatureCollection,
|
||||
Point,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import midPoint from '@turf/midpoint';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawVertexLayer extends BaseRender {
|
||||
public update(pointFeatures: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const midFeatures = this.calcMidPointData(pointFeatures);
|
||||
const style = this.draw.getStyle('mid_point');
|
||||
this.drawLayers = renderFeature(midFeatures, style);
|
||||
this.addLayers();
|
||||
this.enableEdit();
|
||||
}
|
||||
public updateData(data: any) {
|
||||
const midFeatures = this.calcMidPointData(data);
|
||||
this.drawLayers.forEach((layer) => layer.setData(midFeatures));
|
||||
}
|
||||
public enableEdit() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseEnter);
|
||||
layer.on('mouseout', this.onMouseOut);
|
||||
layer.on('click', this.onClick);
|
||||
}
|
||||
|
||||
public disableEdit() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseEnter);
|
||||
layer.off('mouseout', this.onMouseOut);
|
||||
layer.off('click', this.onClick);
|
||||
}
|
||||
|
||||
private onMouseEnter = (e: any) => {
|
||||
this.draw.setCursor('pointer');
|
||||
// this.draw.editMode.enable();
|
||||
};
|
||||
private onMouseOut = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
// this.draw.editMode.disable();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.addVertex(e.feature);
|
||||
// 添加一个顶点 1.更新顶点 2.更新重点
|
||||
};
|
||||
|
||||
private calcMidPointData(fe: FeatureCollection) {
|
||||
const midFeatures: Feature[] = [];
|
||||
fe.features.forEach((item, index) => {
|
||||
const preFeature = (item as unknown) as Feature<Point, Properties>;
|
||||
if (this.draw.type === 'line' && index === fe.features.length - 1) {
|
||||
return;
|
||||
}
|
||||
const nextFeature =
|
||||
index !== fe.features.length - 1
|
||||
? ((fe.features[index + 1] as unknown) as Feature<Point, Properties>)
|
||||
: ((fe.features[0] as unknown) as Feature<Point, Properties>);
|
||||
// @ts-ignore
|
||||
const point = midPoint(preFeature, nextFeature) as Feature<
|
||||
Point,
|
||||
Properties
|
||||
>;
|
||||
// @ts-ignore
|
||||
point.properties.id = index;
|
||||
midFeatures.push(point);
|
||||
});
|
||||
return featureCollection(midFeatures);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawResultLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
if (this.drawLayers.length > 0) {
|
||||
this.updateData(feature);
|
||||
return;
|
||||
}
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('normal');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addFilter();
|
||||
this.addLayers();
|
||||
}
|
||||
public enableDrag() {
|
||||
if (this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('click', this.onClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
public disableDrag() {
|
||||
if (!this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('click', this.onClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
public enableDelete() {
|
||||
this.disableDrag();
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('click', this.onDeleteClick);
|
||||
}
|
||||
|
||||
public disableDelete() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('click', this.onDeleteClick);
|
||||
}
|
||||
public addFilter() {
|
||||
this.drawLayers.forEach((layer) =>
|
||||
layer.filter('active', (active) => {
|
||||
return !active;
|
||||
}),
|
||||
);
|
||||
}
|
||||
private onClick = (e: any) => {
|
||||
this.draw.source.setFeatureUnActive(
|
||||
this.draw.getCurrentFeature() as Feature,
|
||||
);
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.source.setFeatureActive(e.feature as Feature);
|
||||
this.updateData(this.draw.source.data);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
};
|
||||
|
||||
private onDeleteClick = (e: any) => {
|
||||
this.draw.source.removeFeature(e.feature);
|
||||
this.updateData(this.draw.source.data);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { FeatureCollection } from '@turf/helpers';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawVertexLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('active');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public enableDrag() {
|
||||
return;
|
||||
}
|
||||
public disableDrag() {
|
||||
return;
|
||||
}
|
||||
|
||||
public enableEdit() {
|
||||
if (this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseEnter);
|
||||
layer.on('mouseout', this.onMouseOut);
|
||||
layer.on('click', this.onClick);
|
||||
this.isEnableEdit = true;
|
||||
}
|
||||
|
||||
public disableEdit() {
|
||||
if (!this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseEnter);
|
||||
layer.off('mouseout', this.onMouseOut);
|
||||
layer.off('click', this.onClick);
|
||||
this.isEnableEdit = false;
|
||||
}
|
||||
|
||||
private onMouseEnter = (e: any) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.setCurrentVertex(e.feature);
|
||||
this.draw.editMode.enable();
|
||||
};
|
||||
private onMouseOut = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.editMode.disable();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.setCurrentVertex(e.feature);
|
||||
this.draw.editMode.enable();
|
||||
};
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
import { Feature } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
export default class EditRenderLayer {
|
||||
private polygonLayer: ILayer;
|
||||
private lineLayer: ILayer;
|
||||
private centerLayer: ILayer;
|
||||
private endPointLayer: ILayer;
|
||||
private draw: Draw;
|
||||
private currentFeature: Feature;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
this.init();
|
||||
}
|
||||
public init() {
|
||||
const style = this.draw.getStyle('active_fill');
|
||||
const linestyle = this.draw.getStyle('active_line');
|
||||
const centerStyle = this.draw.getStyle('active_point');
|
||||
this.polygonLayer = new PolygonLayer()
|
||||
.source(InitFeature)
|
||||
.shape('fill')
|
||||
.color(style.color)
|
||||
.style(style.style);
|
||||
|
||||
this.lineLayer = new LineLayer()
|
||||
.source(InitFeature)
|
||||
.shape('line')
|
||||
.size(linestyle.size)
|
||||
.color(linestyle.color)
|
||||
.style(linestyle.style);
|
||||
this.centerLayer = new PointLayer({
|
||||
zIndex: 3,
|
||||
blend: 'normal',
|
||||
})
|
||||
.source([], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
this.endPointLayer = new PointLayer({
|
||||
zIndex: 4,
|
||||
blend: 'normal',
|
||||
})
|
||||
.source([], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
|
||||
this.draw.scene.addLayer(this.polygonLayer);
|
||||
this.draw.scene.addLayer(this.lineLayer);
|
||||
this.draw.scene.addLayer(this.centerLayer);
|
||||
this.draw.scene.addLayer(this.endPointLayer);
|
||||
}
|
||||
public updateData(data: any) {
|
||||
if (this.currentFeature === undefined) {
|
||||
this.addLayerEvent();
|
||||
}
|
||||
this.currentFeature = data.features[0];
|
||||
this.lineLayer.setData(data);
|
||||
this.polygonLayer.setData(data);
|
||||
const properties = data.features[0].properties;
|
||||
if (properties.startPoint) {
|
||||
this.centerLayer.setData([
|
||||
{
|
||||
lng: properties.startPoint[0],
|
||||
lat: properties.startPoint[1],
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (properties.endPoint) {
|
||||
this.endPointLayer.setData([
|
||||
{
|
||||
lng: properties.endPoint[0],
|
||||
lat: properties.endPoint[1],
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.draw.scene.removeLayer(this.lineLayer);
|
||||
this.draw.scene.removeLayer(this.polygonLayer);
|
||||
this.draw.scene.removeLayer(this.centerLayer);
|
||||
this.draw.scene.removeLayer(this.endPointLayer);
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.lineLayer.show();
|
||||
this.polygonLayer.show();
|
||||
this.centerLayer.show();
|
||||
this.endPointLayer.show();
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.lineLayer.hide();
|
||||
this.polygonLayer.hide();
|
||||
this.centerLayer.hide();
|
||||
this.endPointLayer.hide();
|
||||
}
|
||||
|
||||
private addLayerEvent() {
|
||||
this.endPointLayer.on('mousemove', (e) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.editMode.enable();
|
||||
});
|
||||
this.endPointLayer.on('unmousemove', (e) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.editMode.disable();
|
||||
});
|
||||
this.polygonLayer.on('unclick', (e) => {
|
||||
// 取消选中 回到初始态
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
this.draw.editMode.disable();
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
import { ILayer, LineLayer, PointLayer, PolygonLayer } from '@antv/l7';
|
||||
import { FeatureCollection } from '@turf/helpers';
|
||||
export function renderFeature(fe: FeatureCollection, style: any): ILayer[] {
|
||||
const type = fe.features[0].geometry.type;
|
||||
let layers;
|
||||
switch (type) {
|
||||
case 'Point':
|
||||
layers = drawPoint(fe, style.point);
|
||||
break;
|
||||
case 'LineString':
|
||||
layers = drawLine(fe, style.line);
|
||||
break;
|
||||
case 'Polygon':
|
||||
layers = drawPolyon(fe, style.polygon);
|
||||
break;
|
||||
}
|
||||
return layers as ILayer[];
|
||||
}
|
||||
|
||||
function drawPoint(fe: FeatureCollection, style: any) {
|
||||
const layer = new PointLayer()
|
||||
.source(fe)
|
||||
.shape('circle')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style(style.style);
|
||||
return [layer];
|
||||
}
|
||||
|
||||
function drawLine(fe: FeatureCollection, style: any) {
|
||||
const layer = new LineLayer({
|
||||
pickingBuffer: 3,
|
||||
})
|
||||
.source(fe)
|
||||
.shape('line')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style(style.style);
|
||||
return [layer];
|
||||
}
|
||||
|
||||
function drawPolyon(fe: FeatureCollection, style: any) {
|
||||
const fill = new PolygonLayer()
|
||||
.source(fe)
|
||||
.shape('fill')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style({
|
||||
opacity: style.style.opacity,
|
||||
});
|
||||
const line = new PolygonLayer()
|
||||
.source(fe)
|
||||
.shape('line')
|
||||
.color(style.style.stroke)
|
||||
.size(style.style.strokeWidth)
|
||||
.style({
|
||||
opacity: style.style.strokeOpacity,
|
||||
lineType: style.style.lineType,
|
||||
dashArray: style.style.dashArray,
|
||||
});
|
||||
return [fill, line];
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
import { Feature } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
export default class EditRenderLayer {
|
||||
private polygonLayer: ILayer;
|
||||
private lineLayer: ILayer;
|
||||
private centerLayer: ILayer;
|
||||
private endPointLayer: ILayer;
|
||||
private draw: Draw;
|
||||
private currentFeature: Feature;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
this.init();
|
||||
}
|
||||
public init() {
|
||||
const style = this.draw.getStyle('active_fill');
|
||||
const linestyle = this.draw.getStyle('active_line');
|
||||
const centerStyle = this.draw.getStyle('active_point');
|
||||
this.polygonLayer = new PolygonLayer()
|
||||
.source(InitFeature)
|
||||
.shape('fill')
|
||||
.color(style.color)
|
||||
.style(style.style);
|
||||
|
||||
this.lineLayer = new LineLayer()
|
||||
.source(InitFeature)
|
||||
.shape('line')
|
||||
.size(linestyle.size)
|
||||
.color(linestyle.color)
|
||||
.style(linestyle.style);
|
||||
this.centerLayer = new PointLayer({
|
||||
zIndex: 3,
|
||||
blend: 'normal',
|
||||
})
|
||||
.source([], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
|
||||
this.endPointLayer = new PointLayer({
|
||||
zIndex: 4,
|
||||
blend: 'normal',
|
||||
})
|
||||
.source([], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
|
||||
this.draw.scene.addLayer(this.polygonLayer);
|
||||
this.draw.scene.addLayer(this.lineLayer);
|
||||
this.draw.scene.addLayer(this.centerLayer);
|
||||
}
|
||||
|
||||
public updateData(data: any) {
|
||||
if (this.currentFeature === undefined) {
|
||||
this.addLayerEvent();
|
||||
}
|
||||
this.currentFeature = data.features[0];
|
||||
this.lineLayer.setData(data);
|
||||
this.polygonLayer.setData(data);
|
||||
const properties = data.features[0].properties;
|
||||
if (properties.startPoint) {
|
||||
this.centerLayer.setData([
|
||||
{
|
||||
lng: properties.startPoint[0],
|
||||
lat: properties.startPoint[1],
|
||||
},
|
||||
]);
|
||||
}
|
||||
if (properties.endPoint) {
|
||||
this.endPointLayer.setData([
|
||||
{
|
||||
lng: properties.endPoint[0],
|
||||
lat: properties.endPoint[1],
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.draw.scene.removeLayer(this.lineLayer);
|
||||
this.draw.scene.removeLayer(this.polygonLayer);
|
||||
// this.draw.scene.removeLayer(this.centerLayer);
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.lineLayer.show();
|
||||
this.polygonLayer.show();
|
||||
// this.centerLayer.show();
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.lineLayer.hide();
|
||||
this.polygonLayer.hide();
|
||||
// this.centerLayer.hide();
|
||||
}
|
||||
private addLayerEvent() {
|
||||
this.polygonLayer.on('mousemove', (e) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.selectMode.enable();
|
||||
});
|
||||
this.polygonLayer.on('unmousemove', (e) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.selectMode.disable();
|
||||
});
|
||||
|
||||
this.polygonLayer.on('click', (e) => {
|
||||
// 进入编辑态
|
||||
this.draw.selectMode.disable();
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.DIRECT_SELECT);
|
||||
this.hide();
|
||||
});
|
||||
this.polygonLayer.on('unclick', (e) => {
|
||||
// 取消选中 回到初始态
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
this.draw.selectMode.disable();
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -28,12 +28,20 @@ export default class DrawSource {
|
|||
fe.properties.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
public setFeatureUnActive(feature: Feature) {
|
||||
const fe = this.getFeature(feature?.properties?.id);
|
||||
if (fe && fe.properties) {
|
||||
fe.properties.active = false;
|
||||
}
|
||||
}
|
||||
public clearFeatureActive() {
|
||||
this.data.features.forEach((fe: Feature) => {
|
||||
if (fe && fe.properties) {
|
||||
fe.properties.active = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
public updateFeature(feature: Feature) {
|
||||
this.removeFeature(feature);
|
||||
this.addFeature(feature);
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import turfCircle from '@turf/circle';
|
||||
import turfDistance from '@turf/distance';
|
||||
import { Feature, featureCollection, point } from '@turf/helpers';
|
||||
import {
|
||||
Feature,
|
||||
featureCollection,
|
||||
lineString,
|
||||
point,
|
||||
polygon,
|
||||
} from '@turf/helpers';
|
||||
import { unitsType } from './constant';
|
||||
|
||||
export function createCircle(
|
||||
|
@ -10,6 +16,7 @@ export function createCircle(
|
|||
units: unitsType;
|
||||
steps: number;
|
||||
id: string;
|
||||
pointFeatures: Feature[];
|
||||
},
|
||||
): Feature {
|
||||
const radius = turfDistance(point(center), point(endPoint), options);
|
||||
|
@ -17,20 +24,32 @@ export function createCircle(
|
|||
units: options.units,
|
||||
steps: options.steps,
|
||||
properties: {
|
||||
id: options.id,
|
||||
...options,
|
||||
active: true,
|
||||
type: 'circle',
|
||||
radius,
|
||||
startPoint: center,
|
||||
endPoint,
|
||||
startPoint: {
|
||||
lng: center[0],
|
||||
lat: center[1],
|
||||
},
|
||||
endPoint: {
|
||||
lng: endPoint[0],
|
||||
lat: endPoint[1],
|
||||
},
|
||||
path: [center, endPoint],
|
||||
},
|
||||
});
|
||||
return feature as Feature;
|
||||
}
|
||||
|
||||
export function creatRect(
|
||||
export function createRect(
|
||||
startPoint: [number, number],
|
||||
endPoint: [number, number],
|
||||
options: {
|
||||
id: string;
|
||||
pointFeatures: Feature[];
|
||||
[key: string]: any;
|
||||
},
|
||||
): Feature {
|
||||
const minX = Math.min(startPoint[0], endPoint[0]);
|
||||
const minY = Math.min(startPoint[1], endPoint[1]);
|
||||
|
@ -39,9 +58,17 @@ export function creatRect(
|
|||
const feature = {
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
type: 'rect',
|
||||
active: true,
|
||||
startPoint,
|
||||
endPoint,
|
||||
startPoint: {
|
||||
lng: startPoint[0],
|
||||
lat: startPoint[1],
|
||||
},
|
||||
endPoint: {
|
||||
lng: endPoint[0],
|
||||
lat: endPoint[1],
|
||||
},
|
||||
...options,
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
|
@ -58,3 +85,44 @@ export function creatRect(
|
|||
};
|
||||
return feature as Feature;
|
||||
}
|
||||
|
||||
export function createPolygon(
|
||||
points: Array<{ lng: number; lat: number }>,
|
||||
options: {
|
||||
id?: string | number;
|
||||
pointFeatures: Feature[];
|
||||
[key: string]: any;
|
||||
},
|
||||
): any {
|
||||
const coords = points.map((p) => [p.lng, p.lat]);
|
||||
if (points.length < 2) {
|
||||
return point(coords[0], options);
|
||||
} else if (points.length < 3) {
|
||||
return lineString(coords, options);
|
||||
} else {
|
||||
coords.push(coords[0]);
|
||||
return polygon([coords], options);
|
||||
}
|
||||
}
|
||||
|
||||
export function createLine(
|
||||
points: Array<{ lng: number; lat: number }>,
|
||||
options: any,
|
||||
): any {
|
||||
const coords = points.map((p) => [p.lng, p.lat]);
|
||||
if (points.length < 2) {
|
||||
return point(coords[0], options);
|
||||
} else {
|
||||
return lineString(coords, options);
|
||||
}
|
||||
}
|
||||
|
||||
export function createPoint(points: Array<{ lng: number; lat: number }>) {
|
||||
const features = points.map((p, index) =>
|
||||
point([p.lng, p.lat], {
|
||||
active: true,
|
||||
id: index.toString(),
|
||||
}),
|
||||
);
|
||||
return featureCollection(features);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,71 @@
|
|||
const LayerStyles = {
|
||||
// 正常显示样式
|
||||
normal_fill: {
|
||||
type: 'PolygonLayer',
|
||||
shape: 'fill',
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
active: {
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 5,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
color: '#fbb03b',
|
||||
size: 1,
|
||||
style: {
|
||||
opacity: 1,
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
polygon: {
|
||||
shape: 'fill',
|
||||
color: '#fbb03b',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
stroke: '#fbb03b',
|
||||
strokeWidth: 1,
|
||||
strokeOpacity: 1,
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
},
|
||||
// xai'm'z
|
||||
active_fill: {
|
||||
type: 'PolygonLayer',
|
||||
shape: 'fill',
|
||||
color: '#fbb03b',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
normal: {
|
||||
polygon: {
|
||||
type: 'PolygonLayer',
|
||||
shape: 'fill',
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
stroke: '#3bb2d0',
|
||||
strokeWidth: 1,
|
||||
strokeOpacity: 1,
|
||||
lineType: 'solid',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
size: 1,
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#3bb2d0',
|
||||
size: 3,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
normal_point: {
|
||||
|
@ -28,40 +79,12 @@ const LayerStyles = {
|
|||
},
|
||||
},
|
||||
mid_point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 3,
|
||||
style: {},
|
||||
},
|
||||
active_point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 5,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
normal_line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
size: 1,
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
active_line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
color: '#fbb03b',
|
||||
size: 1,
|
||||
style: {
|
||||
opacity: 1,
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 3,
|
||||
style: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -66,7 +66,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
|||
public maxZoom: number;
|
||||
public inited: boolean = false;
|
||||
public layerModelNeedUpdate: boolean = false;
|
||||
public pickedFeatureID: number = -1;
|
||||
public pickedFeatureID: number | null = null;
|
||||
public selectedFeatureID: number | null = null;
|
||||
|
||||
public dataState: IDataState = {
|
||||
dataSourceNeedUpdate: false,
|
||||
|
@ -612,6 +613,14 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
|||
public getCurrentPickId(): number | null {
|
||||
return this.currentPickId;
|
||||
}
|
||||
|
||||
public setCurrentSelectedId(id: number) {
|
||||
this.selectedFeatureID = id;
|
||||
}
|
||||
|
||||
public getCurrentSelectedId(): number | null {
|
||||
return this.selectedFeatureID;
|
||||
}
|
||||
public isVisible(): boolean {
|
||||
const zoom = this.mapService.getZoom();
|
||||
const {
|
||||
|
@ -834,18 +843,28 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
|
|||
return this.layerService.clock.getElapsedTime() - this.animateStartTime;
|
||||
}
|
||||
|
||||
public needPick(): boolean {
|
||||
public needPick(type: string): boolean {
|
||||
const {
|
||||
enableHighlight = true,
|
||||
enableSelect = true,
|
||||
} = this.getLayerConfig();
|
||||
const eventNames = this.eventNames().filter((name) => {
|
||||
return (
|
||||
name !== 'inited' && name !== 'add' && name !== 'remove' && 'dataupdate' // 非拾取事件排除
|
||||
);
|
||||
});
|
||||
const flag = eventNames.length > 0 || enableHighlight || enableSelect;
|
||||
return this.isVisible() && flag;
|
||||
// 判断layer是否监听事件;
|
||||
let isPick =
|
||||
this.eventNames().indexOf(type) !== -1 ||
|
||||
this.eventNames().indexOf('un' + type) !== -1;
|
||||
if ((type === 'click' || type === 'dblclick') && enableSelect) {
|
||||
isPick = true;
|
||||
}
|
||||
if (
|
||||
type === 'mousemove' &&
|
||||
(enableHighlight ||
|
||||
this.eventNames().indexOf('mouseenter') !== -1 ||
|
||||
this.eventNames().indexOf('unmousemove') !== -1 ||
|
||||
this.eventNames().indexOf('mouseout') !== -1)
|
||||
) {
|
||||
isPick = true;
|
||||
}
|
||||
return this.isVisible() && isPick;
|
||||
}
|
||||
|
||||
public buildModels() {
|
||||
|
|
|
@ -49,7 +49,7 @@ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
|
|||
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 / 2.0;
|
||||
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
|
||||
return offset * vec2(1.0, -1.0);
|
||||
}
|
||||
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
|
||||
|
|
|
@ -51,7 +51,7 @@ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
|
|||
// rotate by 90 degrees
|
||||
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
|
||||
|
||||
vec2 offset = dir_screenspace * offset_direction * a_Size / 2.0;
|
||||
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
|
|||
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 / 2.0;
|
||||
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size)/ 2.0;
|
||||
return offset;
|
||||
}
|
||||
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
|
||||
|
|
|
@ -48,7 +48,7 @@ vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction) {
|
|||
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 / 2.0;
|
||||
vec2 offset = dir_screenspace * offset_direction * setPickingSize(a_Size) / 2.0;
|
||||
return offset * vec2(1.0, -1.0);
|
||||
}
|
||||
vec2 getNormal(vec2 line_clipspace, float offset_direction) {
|
||||
|
|
|
@ -29,7 +29,7 @@ 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 * setPickingSize(a_Size) * 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));
|
||||
|
|
|
@ -38,7 +38,7 @@ void main() {
|
|||
}
|
||||
v_normal = vec2(reverse_offset_normal(a_Normal) * sign(a_Miter));
|
||||
v_color = a_Color;
|
||||
vec3 size = a_Miter * a_Size.x * reverse_offset_normal(a_Normal);
|
||||
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
|
||||
vec2 offset = project_pixel(size.xy);
|
||||
v_side = a_Miter * a_Size.x;
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
|
||||
|
|
|
@ -55,6 +55,7 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
|||
u_ViewportSize: [width, height],
|
||||
u_DevicePixelRatio: window.devicePixelRatio,
|
||||
u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -55,12 +55,6 @@ void main() {
|
|||
}
|
||||
|
||||
float opacity_t = smoothstep(0.0, antialiased_blur, outer_df);
|
||||
if(u_stroke_width <0.01 ) {
|
||||
gl_FragColor = v_color * opacity_t;
|
||||
gl_FragColor.a = gl_FragColor.a * u_opacity;
|
||||
gl_FragColor = filterColor(gl_FragColor);
|
||||
return;
|
||||
}
|
||||
float color_t = u_stroke_width < 0.01 ? 0.0 : smoothstep(
|
||||
antialiased_blur,
|
||||
0.0,
|
||||
|
@ -73,8 +67,8 @@ void main() {
|
|||
|
||||
// gl_FragColor = v_color * color_t;
|
||||
// gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), strokeColor * u_stroke_opacity, color_t);
|
||||
gl_FragColor = opacity_t * mix(vec4(v_color.rgb, v_color.a * u_opacity), strokeColor * u_stroke_opacity, color_t);
|
||||
|
||||
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), strokeColor * u_stroke_opacity, color_t);
|
||||
gl_FragColor.a = gl_FragColor.a * opacity_t;
|
||||
if(u_aimate.x == Animate) {
|
||||
float d = length(v_data.xy);
|
||||
float intensity = clamp(cos(d * PI), 0.0, 1.0) * clamp(cos(2.0 * PI * (d * 2.0 * u_aimate.z - u_aimate.y * u_time)), 0.0, 1.0);
|
||||
|
|
|
@ -21,17 +21,19 @@ void main() {
|
|||
|
||||
float shape_type = a_Shape;
|
||||
|
||||
// radius(16-bit)
|
||||
v_radius = a_Size;
|
||||
float newSize = setPickingSize(a_Size);
|
||||
|
||||
vec2 offset = project_pixel(extrude * (a_Size + u_stroke_width));
|
||||
// radius(16-bit)
|
||||
v_radius = newSize;
|
||||
|
||||
vec2 offset = project_pixel(extrude * (newSize + u_stroke_width));
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
|
||||
// TODO: billboard
|
||||
// anti-alias
|
||||
float antialiasblur = 1.0 / (a_Size + u_stroke_width);
|
||||
float antialiasblur = 1.0 / u_DevicePixelRatio / (newSize + u_stroke_width);
|
||||
|
||||
// construct point coords
|
||||
v_data = vec4(extrude, antialiasblur,shape_type);
|
||||
|
|
|
@ -25,5 +25,6 @@ float r = 1.0 - smoothstep(radius-(radius*0.01),
|
|||
}else {
|
||||
gl_FragColor= step(0.01, textureColor.z) * v_color;
|
||||
}
|
||||
gl_FragColor.a =gl_FragColor.a * u_opacity;
|
||||
gl_FragColor = filterColor(gl_FragColor);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ void main() {
|
|||
highp float gamma_scaled = gamma * v_gamma_scale;
|
||||
|
||||
highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist);
|
||||
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), vec4(u_stroke.rgb, u_stroke.a * u_opacity), smoothstep(0., 0.5, 1. - dist)) * alpha;
|
||||
gl_FragColor = mix(vec4(v_color.rgb, v_color.a * u_opacity), vec4(u_stroke.rgb, u_stroke.a * u_opacity), smoothstep(0., 0.5, 1. - dist));
|
||||
gl_FragColor.a= gl_FragColor.a * alpha;
|
||||
gl_FragColor = filterColor(gl_FragColor);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,10 @@ export default class AMapService
|
|||
return this.map.getContainer();
|
||||
}
|
||||
|
||||
public getMapCanvasContainer(): HTMLElement {
|
||||
return this.map.getContainer() as HTMLElement;
|
||||
}
|
||||
|
||||
public getSize(): [number, number] {
|
||||
const size = this.map.getSize();
|
||||
return [size.getWidth(), size.getHeight()];
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.mapboxgl-ctrl-logo {
|
||||
display: none !important;
|
||||
}
|
|
@ -20,14 +20,18 @@ import {
|
|||
import { DOM } from '@antv/l7-utils';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import mapboxgl, { IControl, Map } from 'mapbox-gl';
|
||||
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||
import { IMapboxInstance } from '../../typings/index';
|
||||
import './logo.css';
|
||||
import Viewport from './Viewport';
|
||||
const EventMap: {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
mapmove: 'move',
|
||||
camerachange: 'move',
|
||||
zoomChange: 'zoom',
|
||||
zoomchange: 'zoom',
|
||||
dragging: 'drag',
|
||||
};
|
||||
import { MapTheme } from './theme';
|
||||
|
@ -87,6 +91,9 @@ export default class MapboxService
|
|||
public getContainer(): HTMLElement | null {
|
||||
return this.map.getContainer();
|
||||
}
|
||||
public getMapCanvasContainer(): HTMLElement {
|
||||
return this.map.getCanvasContainer();
|
||||
}
|
||||
|
||||
public getSize(): [number, number] {
|
||||
const size = this.map.transform;
|
||||
|
@ -138,18 +145,16 @@ export default class MapboxService
|
|||
this.map.setBearing(rotation);
|
||||
}
|
||||
|
||||
public zoomIn(): void {
|
||||
this.map.zoomIn();
|
||||
public zoomIn(option?: any, eventData?: any): void {
|
||||
this.map.zoomIn(option, eventData);
|
||||
}
|
||||
public zoomOut(option?: any, eventData?: any): void {
|
||||
this.map.zoomOut(option, eventData);
|
||||
}
|
||||
|
||||
public setPitch(pitch: number) {
|
||||
return this.map.setPitch(pitch);
|
||||
}
|
||||
|
||||
public zoomOut(): void {
|
||||
this.map.zoomOut();
|
||||
}
|
||||
|
||||
public panTo(p: [number, number]): void {
|
||||
this.map.panTo(p);
|
||||
}
|
||||
|
@ -295,7 +300,6 @@ export default class MapboxService
|
|||
if (this.map) {
|
||||
this.map.remove();
|
||||
this.$mapContainer = null;
|
||||
this.removeLogoControl();
|
||||
}
|
||||
}
|
||||
public emit(name: string, ...args: any[]) {
|
||||
|
@ -356,20 +360,6 @@ export default class MapboxService
|
|||
}
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
private removeLogoControl(): void {
|
||||
// @ts-ignore
|
||||
const controls = this.map._controls as IControl[];
|
||||
const logoCtr = controls.find((ctr: IControl) => {
|
||||
if (ctr.hasOwnProperty('_updateLogo')) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (logoCtr) {
|
||||
this.map.removeControl(logoCtr);
|
||||
}
|
||||
}
|
||||
|
||||
private getMapStyle(name: MapStyle) {
|
||||
if (typeof name !== 'string') {
|
||||
return name;
|
||||
|
|
|
@ -118,6 +118,9 @@ class Scene
|
|||
public getMapContainer(): HTMLElement | null {
|
||||
return this.mapService.getMapContainer();
|
||||
}
|
||||
public getMapCanvasContainer(): HTMLElement {
|
||||
return this.mapService.getMapCanvasContainer() as HTMLElement;
|
||||
}
|
||||
|
||||
public getMapService(): IMapService<unknown> {
|
||||
return this.mapService;
|
||||
|
|
|
@ -19,8 +19,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.8,
|
||||
xOffset: gridOffset.xOffset / 1.8,
|
||||
yOffset: gridOffset.yOffset / 2,
|
||||
xOffset: gridOffset.xOffset / 2,
|
||||
radius: gridOffset.xOffset,
|
||||
type: 'grid',
|
||||
dataArray: layerData,
|
||||
|
@ -31,6 +31,7 @@ function _pointsGridHash(dataArray: any[], size: number) {
|
|||
let latMin = Infinity;
|
||||
let latMax = -Infinity;
|
||||
let pLat;
|
||||
|
||||
for (const point of dataArray) {
|
||||
pLat = point.coordinates[1];
|
||||
if (Number.isFinite(pLat)) {
|
||||
|
@ -38,8 +39,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 };
|
||||
|
@ -95,8 +96,8 @@ function _getGridLayerDataFromGridHash(
|
|||
Object.assign(item, {
|
||||
_id: i,
|
||||
coordinates: [
|
||||
-180 + gridOffset.xOffset * lonIdx,
|
||||
-90 + gridOffset.yOffset * latIdx,
|
||||
-180 + gridOffset.xOffset * (lonIdx + 0.5),
|
||||
-90 + gridOffset.yOffset * (latIdx + 0.5),
|
||||
],
|
||||
rawData: gridHash[key].points,
|
||||
count: gridHash[key].count,
|
||||
|
|
|
@ -24,7 +24,6 @@ export default class MarkerComponent extends React.Component {
|
|||
zoom: 18,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
const popup = new Popup({
|
||||
offsets: [0, 20],
|
||||
|
@ -90,6 +89,7 @@ export default class MarkerComponent extends React.Component {
|
|||
// console.log(this.scene.getZoom());
|
||||
// console.log('选中的点', 1111);
|
||||
// });
|
||||
this.scene = scene;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,14 @@ export default class ScaleComponent extends React.Component {
|
|||
'#CF1D49',
|
||||
])
|
||||
.shape('fill')
|
||||
// .select(true)
|
||||
.select(true)
|
||||
.style({
|
||||
opacity: 1.0,
|
||||
});
|
||||
scene.addLayer(layer);
|
||||
const pointLayer = new PointLayer({
|
||||
name: '02',
|
||||
enablePropagation: true,
|
||||
})
|
||||
.source(pointsData, {
|
||||
cluster: true,
|
||||
|
@ -63,7 +64,7 @@ export default class ScaleComponent extends React.Component {
|
|||
})
|
||||
.size('point_count', [5, 10, 15, 20, 25])
|
||||
.animate(false)
|
||||
.active(true)
|
||||
.active(false)
|
||||
.color('yellow')
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
|
@ -71,7 +72,14 @@ export default class ScaleComponent extends React.Component {
|
|||
});
|
||||
scene.addLayer(pointLayer);
|
||||
layer.on('click', (e) => {
|
||||
layer.setSelect(e.featureId);
|
||||
console.log(1, e);
|
||||
// layer.setSelect(e.featureId);
|
||||
});
|
||||
pointLayer.on('click', (e) => {
|
||||
console.log(2, e);
|
||||
});
|
||||
pointLayer.on('mouseout', (e) => {
|
||||
console.log(2, e);
|
||||
});
|
||||
const scaleControl = new Scale();
|
||||
const layers = {
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { DrawControl } from '@antv/l7-draw';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
|
||||
import * as React from 'react';
|
||||
export default class Circle extends React.Component {
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
pitch: 0,
|
||||
style: 'mapbox://styles/mapbox/satellite-v9', // hosted style id
|
||||
center: [-91.874, 42.76], // starting position
|
||||
zoom: 12, // starting zoom
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
const drawControl = new DrawControl(scene, {
|
||||
position: 'topright',
|
||||
layout: 'horizontal', // horizontal vertical
|
||||
controls: {
|
||||
point: true,
|
||||
polygon: true,
|
||||
line: true,
|
||||
circle: true,
|
||||
rect: true,
|
||||
delete: true,
|
||||
},
|
||||
});
|
||||
scene.on('click', () => {});
|
||||
scene.addControl(drawControl);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { LineLayer, PointLayer, PolygonLayer, Popup, Scene } from '@antv/l7';
|
||||
import { DrawLine } from '@antv/l7-draw';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
|
||||
import * as React from 'react';
|
||||
export default class Circle extends React.Component {
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
pitch: 0,
|
||||
style: 'light',
|
||||
center: [113.775374, 28.31067],
|
||||
zoom: 12,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
const drawLine = new DrawLine(scene);
|
||||
drawLine.enable();
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { LineLayer, PointLayer, PolygonLayer, Popup, Scene } from '@antv/l7';
|
||||
import { DrawPoint } from '@antv/l7-draw';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
|
||||
import * as React from 'react';
|
||||
export default class Circle extends React.Component {
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
pitch: 0,
|
||||
style: 'light',
|
||||
center: [113.775374, 28.31067],
|
||||
zoom: 12,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
const drawPoint = new DrawPoint(scene);
|
||||
drawPoint.enable();
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { LineLayer, PointLayer, PolygonLayer, Popup, Scene } from '@antv/l7';
|
||||
import { DrawPolygon } from '@antv/l7-draw';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
|
||||
import * as React from 'react';
|
||||
export default class Circle extends React.Component {
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
pitch: 0,
|
||||
style: 'light',
|
||||
center: [113.775374, 28.31067],
|
||||
zoom: 12,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
const drawPolygon = new DrawPolygon(scene);
|
||||
drawPolygon.enable();
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,11 +2,19 @@ import { storiesOf } from '@storybook/react';
|
|||
import * as React from 'react';
|
||||
import Circle from './Components/Circle';
|
||||
import DrawCircle from './Components/DrawCircle';
|
||||
import DrawControl from './Components/DrawControl';
|
||||
import Line from './Components/DrawLine';
|
||||
import Point from './Components/DrawPoint';
|
||||
import DrawPolygon from './Components/DrawPolygon';
|
||||
import DrawRect from './Components/DrawRect';
|
||||
import Polygon from './Components/Polygon';
|
||||
|
||||
storiesOf('绘制', module)
|
||||
.add('圆', () => <Circle />, {})
|
||||
.add('矩形', () => <DrawRect />, {})
|
||||
.add('多边形', () => <Polygon />, {})
|
||||
.add('点', () => <Point />, {})
|
||||
.add('路径', () => <Line />, {})
|
||||
.add('绘制组件', () => <DrawControl />, {})
|
||||
.add('绘制圆', () => <DrawCircle />, {})
|
||||
.add('四边形', () => <DrawRect />, {})
|
||||
.add('绘制面', () => <DrawPolygon />, {});
|
||||
|
|
|
@ -21,6 +21,7 @@ import WorldDemo from './components/polygon_line';
|
|||
import ImageLayerDemo from './components/RasterImage';
|
||||
import RasterLayerDemo from './components/RasterLayer';
|
||||
import TextLayerDemo from './components/Text';
|
||||
import GridTest from './components/gridtest';
|
||||
|
||||
// @ts-ignore
|
||||
storiesOf('图层', module)
|
||||
|
@ -44,4 +45,5 @@ storiesOf('图层', module)
|
|||
.add('网格热力图', () => <HexagonLayerDemo />)
|
||||
.add('栅格', () => <RasterLayerDemo />)
|
||||
.add('图片', () => <ImageLayerDemo />)
|
||||
.add('网格测试', () => <GridTest />)
|
||||
.add('世界地图', () => <WorldDemo />);
|
||||
|
|
|
@ -18,7 +18,7 @@ export default class Point3D extends React.Component {
|
|||
style: 'light',
|
||||
center: [-121.24357, 37.58264],
|
||||
pitch: 0,
|
||||
zoom: 6.45,
|
||||
zoom: 10.45,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
@ -53,6 +53,7 @@ export default class Point3D extends React.Component {
|
|||
.style({
|
||||
opacity: 1,
|
||||
strokeWidth: 0,
|
||||
stroke: '#fff',
|
||||
});
|
||||
|
||||
scene.addLayer(pointLayer);
|
||||
|
|
|
@ -23,7 +23,7 @@ export default class TextLayerDemo extends React.Component {
|
|||
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
map: new GaodeMap({
|
||||
center: [120.19382669582967, 30.258134],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
|
@ -41,7 +41,7 @@ export default class TextLayerDemo extends React.Component {
|
|||
})
|
||||
.shape('s', 'text')
|
||||
// .shape('circle')
|
||||
.size(8)
|
||||
.size(18)
|
||||
.filter('t', (t) => {
|
||||
return t < 5;
|
||||
})
|
||||
|
@ -54,7 +54,7 @@ export default class TextLayerDemo extends React.Component {
|
|||
// spacing: 2, // 字符间距
|
||||
// padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||
stroke: '#fff', // 描边颜色
|
||||
strokeWidth: 0, // 描边宽度
|
||||
strokeWidth: 1, // 描边宽度
|
||||
// strokeOpacity: 1.0,
|
||||
});
|
||||
scene.addLayer(pointLayer);
|
||||
|
|
|
@ -23,7 +23,9 @@ export default class DashLineDemo extends React.Component {
|
|||
zoom: 14,
|
||||
}),
|
||||
});
|
||||
const lineLayer = new LineLayer()
|
||||
const lineLayer = new LineLayer({
|
||||
pickingBuffer: 5,
|
||||
})
|
||||
.source(await response.json())
|
||||
.size(1)
|
||||
.shape('line')
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import { HeatmapLayer, Marker, PointLayer, Scene, IPoint } from '@antv/l7';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as dat from 'dat.gui';
|
||||
import * as React from 'react';
|
||||
export default class HexagonLayerDemo extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
private gui: dat.GUI;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
if (this.gui) {
|
||||
this.gui.destroy();
|
||||
}
|
||||
}
|
||||
public async componentDidMount() {
|
||||
const testPoint: [number, number] = [113.868222, 22.506306];
|
||||
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMap({
|
||||
center: testPoint,
|
||||
pitch: 0,
|
||||
zoom: 17,
|
||||
token: '8e2254ff173dbf7ff5029e9c9df20bc3',
|
||||
}),
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
// 网格热力图
|
||||
const testList = [{ lng: testPoint[0], lat: testPoint[1], lev: 1 }];
|
||||
const layer = new HeatmapLayer({})
|
||||
.source(testList, {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
transforms: [
|
||||
{
|
||||
type: 'grid',
|
||||
size: 100,
|
||||
field: 'lev',
|
||||
method: 'sum',
|
||||
},
|
||||
],
|
||||
})
|
||||
.shape('circle')
|
||||
.style({
|
||||
coverage: 1,
|
||||
})
|
||||
.color('count', ['#0B0030', '#6BD5A0'].reverse());
|
||||
scene.addLayer(layer);
|
||||
|
||||
// marker
|
||||
// @ts-ignore
|
||||
const marker = new Marker().setLnglat(testPoint);
|
||||
scene.addMarker(marker);
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ export default class HeatMapLayerDemo extends React.Component {
|
|||
pitch: 58.5,
|
||||
center: [111.8759, 30.6942],
|
||||
rotation: 0.519,
|
||||
zoom: 3.6116,
|
||||
zoom: 14,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
|
|
@ -36,14 +36,14 @@ export default class HexagonLayerDemo extends React.Component {
|
|||
.source(data, {
|
||||
transforms: [
|
||||
{
|
||||
type: 'hexagon',
|
||||
type: 'grid',
|
||||
size: 500000,
|
||||
field: 'name',
|
||||
method: 'mode',
|
||||
},
|
||||
],
|
||||
})
|
||||
.shape('hexagon') // 支持 circle, hexagon,triangle
|
||||
.shape('square') // 支持 circle, hexagon,triangle
|
||||
.color('mode', [
|
||||
'#ffffe5',
|
||||
'#fff7bc',
|
||||
|
|
|
@ -34,12 +34,13 @@ export default class World extends React.Component {
|
|||
style: 'blank',
|
||||
center: [110.19382669582967, 30.258134],
|
||||
pitch: 0,
|
||||
zoom: 0,
|
||||
zoom: 5,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
const layer = new PolygonLayer({
|
||||
name: '01',
|
||||
autoFit: true,
|
||||
});
|
||||
|
||||
layer
|
||||
|
|
Loading…
Reference in New Issue