docs: 完善官方文档

This commit is contained in:
yanxiong 2022-09-27 18:27:59 +08:00
parent 125b309a9f
commit d3da1e1d14
69 changed files with 1267 additions and 581 deletions

View File

@ -1,4 +1,4 @@
import { Mapbox, Scene, ExportImage, PointLayer } from '@antv/l7';
import { GaodeMapV2, Scene, ExportImage, PointLayer } from '@antv/l7';
import React, { useState } from 'react';
// tslint:disable-next-line:no-duplicate-imports
import { FunctionComponent, useEffect } from 'react';
@ -11,15 +11,14 @@ const Demo: FunctionComponent = () => {
useEffect(() => {
const newScene = new Scene({
id: 'map',
map: new Mapbox({
map: new GaodeMapV2({
style: 'normal',
center: [120, 30],
pitch: 0,
zoom: 6.45,
preserveDrawingBuffer: true,
// WebGLParams: {
// preserveDrawingBuffer: true,
// },
WebGLParams: {
preserveDrawingBuffer: true,
},
}),
// logoVisible: false,
});
@ -63,7 +62,7 @@ const Demo: FunctionComponent = () => {
<button
onClick={() => {
control?.setOptions({
imageType: 'jpg',
imageType: 'jpeg',
});
}}
>

View File

@ -1,4 +1,4 @@
import { GaodeMapV2, Scene, MouseLocation, Zoom } from '@antv/l7';
import { GaodeMapV2, Scene, MouseLocation } from '@antv/l7';
import React from 'react';
// tslint:disable-next-line:no-duplicate-imports
import { FunctionComponent, useEffect } from 'react';
@ -19,10 +19,10 @@ const Demo: FunctionComponent = () => {
newScene.on('loaded', () => {
const newControl = new MouseLocation({});
newScene.addControl(newControl);
const zoom = new Zoom({
position: 'topright',
});
newScene.addControl(zoom);
// const zoom = new Zoom({
// position: 'topright',
// });
// newScene.addControl(zoom);
});
}, []);

View File

@ -1,4 +1,5 @@
import { GaodeMapV2, Scene, Navigation } from '@antv/l7';
import { GaodeMapV2, GeoLocate, Scene } from '@antv/l7';
import gcoord from 'gcoord';
import React, { useState } from 'react';
// tslint:disable-next-line:no-duplicate-imports
import { FunctionComponent, useEffect } from 'react';
@ -23,7 +24,11 @@ const Demo: FunctionComponent = () => {
});
newScene.on('loaded', () => {
const newControl = new Navigation({});
const newControl = new GeoLocate({
transform: (position) => {
return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
},
});
newScene.addControl(newControl);
});
}, []);

View File

@ -1,4 +1,4 @@
import { Mapbox, Scene, Scale, Zoom } from '@antv/l7';
import { GaodeMapV2, Scene, Scale } from '@antv/l7';
import React, { useState } from 'react';
// tslint:disable-next-line:no-duplicate-imports
import { FunctionComponent, useEffect } from 'react';
@ -14,10 +14,11 @@ const Demo: FunctionComponent = () => {
// pitch: 0,
// zoom: 6.45,
// }),
map: new Mapbox({
map: new GaodeMapV2({
center: [120, 30],
pitch: 0,
zoom: 6.45,
style: 'normal',
}),
});
@ -27,11 +28,11 @@ const Demo: FunctionComponent = () => {
position: 'rightbottom',
// imperial: true,
});
const zoom = new Zoom({
position: 'rightbottom',
});
// const zoom = new Zoom({
// position: 'rightbottom',
// });
newScene.addControl(scale);
newScene.addControl(zoom);
// newScene.addControl(zoom);
setControl(scale);
});
}, []);

View File

@ -35,10 +35,14 @@ const Demo: FunctionComponent = () => {
.source(
featureCollection([
point([120.104697, 30.260704], {
name: '1',
name: '测试点1',
lng: 120.104697,
lat: 30.260704,
}),
point([120.104697, 30.261715], {
name: '2',
name: '测试点2',
lng: 120.104697,
lat: 30.261715,
}),
]),
)
@ -53,7 +57,7 @@ const Demo: FunctionComponent = () => {
{
type: 'Feature',
properties: {
name: 'luelue',
name: '测试线3',
},
geometry: {
type: 'LineString',
@ -77,13 +81,12 @@ const Demo: FunctionComponent = () => {
fields: [
{
field: 'name',
fieldFormat: (key) => {
formatField: (key) => {
return '名称';
},
valueFormat: (value) => {
return '12345';
},
},
'lng',
'lat',
],
},
{
@ -91,7 +94,7 @@ const Demo: FunctionComponent = () => {
fields: ['name'],
},
],
trigger: 'click',
trigger: 'hover',
});
newScene.addPopup(newPopup);
setPopup(newPopup);

View File

@ -36,8 +36,9 @@ const Demo: FunctionComponent = () => {
lng: 120.104697,
lat: 30.260704,
},
title: '123456',
html: 'fldksja jdklfaj jdfklas d skljf as lkfdsa f adsfa fsd alfk',
anchor: 'bottom-right',
title: 'Popup Title',
html: 'Popup Content',
});
newScene.addPopup(newPopup);

View File

@ -41,10 +41,10 @@ describe('control', () => {
const control = new TestControl();
scene.addControl(control);
control.hide();
expect(control.getContainer().classList).toContain('l7-control-hide');
expect(control.getContainer().classList).toContain('l7-control--hide');
expect(control.getIsShow()).toEqual(false);
control.show();
expect(control.getContainer().classList).not.toContain('l7-control-hide');
expect(control.getContainer().classList).not.toContain('l7-control--hide');
expect(control.getIsShow()).toEqual(true);
});

View File

@ -1,5 +1,5 @@
import { TestScene } from '@antv/l7-test-utils';
import Navigation from '../src/control/navigation';
import Navigation from '../src/control/geoLocate';
describe('navigation', () => {
const scene = TestScene();

View File

@ -36,7 +36,8 @@
"supercluster": "^7.0.0"
},
"devDependencies": {
"@antv/l7-test-utils": "2.9.24"
"@antv/l7-test-utils": "2.9.24",
"gcoord": "^0.3.2"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",
"publishConfig": {

View File

@ -1,10 +1,11 @@
import { DOM } from '@antv/l7-utils';
import { ELType } from '@antv/l7-utils/src/dom';
import Control, { IControlOption } from './control';
export { ButtonControl };
export interface IButtonControlOption extends IControlOption {
btnIcon?: HTMLElement | SVGElement;
btnIcon?: ELType;
btnText?: string;
title?: string;
vertical?: boolean;
@ -35,7 +36,7 @@ export default abstract class ButtonControl<
* DOM
* @protected
*/
protected buttonIcon?: HTMLElement | SVGElement;
protected buttonIcon?: ELType;
/**
*

View File

@ -152,7 +152,7 @@ export default abstract class Control<O extends IControlOption = IControlOption>
*/
public show() {
const container = this.container;
DOM.removeClass(container, 'l7-control-hide');
DOM.removeClass(container, 'l7-control--hide');
this.isShow = true;
this.emit('show', this);
}
@ -162,7 +162,7 @@ export default abstract class Control<O extends IControlOption = IControlOption>
*/
public hide() {
const container = this.container;
DOM.addClass(container, 'l7-control-hide');
DOM.addClass(container, 'l7-control--hide');
this.isShow = false;
this.emit('hide', this);
}
@ -243,12 +243,10 @@ export default abstract class Control<O extends IControlOption = IControlOption>
*/
public setStyle(style?: string | null) {
const container = this.container;
const { style: oldStyle } = this.controlOption;
if (oldStyle) {
DOM.removeStyle(container, oldStyle);
}
if (style) {
DOM.addStyle(container, style);
container.setAttribute('style', style);
} else {
container.removeAttribute('style');
}
}

View File

@ -84,10 +84,10 @@ export default abstract class PopperControl<
});
this.popper
.on('show', () => {
this.emit('popperShow');
this.emit('popperShow', this);
})
.on('hide', () => {
this.emit('popperHide');
this.emit('popperHide', this);
});
return this.popper;
}

View File

@ -15,10 +15,10 @@ type ImageOptionItem = BaseOptionItem & {
img: string;
};
export type OptionItem = ImageOptionItem | NormalOptionItem;
export type ControlOptionItem = ImageOptionItem | NormalOptionItem;
export interface ISelectControlOption extends IPopperControlOption {
options: OptionItem[];
options: ControlOptionItem[];
defaultValue?: string | string[];
}
@ -105,7 +105,7 @@ export default abstract class SelectControl<
*/
protected abstract getIsMultiple(): boolean;
protected getPopperContent(options: OptionItem[]): HTMLElement {
protected getPopperContent(options: ControlOptionItem[]): HTMLElement {
const isImageOptions = this.isImageOptions();
const content = DOM.create(
'div',
@ -191,7 +191,7 @@ export default abstract class SelectControl<
return checkboxDOM;
}
protected onItemClick = (item: OptionItem) => {
protected onItemClick = (item: ControlOptionItem) => {
if (this.getIsMultiple()) {
const targetIndex = this.selectValue.findIndex(
(value) => value === item.value,

View File

@ -30,11 +30,15 @@ export default class ExportImage extends ButtonControl<
};
}
protected onClick = async () => {
const { onExport } = this.controlOption;
public getImage() {
const mapImage = this.mapsService.exportMap('png');
const layerImage = this.scene.exportPng('png');
onExport?.(await this.mergeImage(mapImage, layerImage));
return this.mergeImage(mapImage, layerImage);
}
protected onClick = async () => {
const { onExport } = this.controlOption;
onExport?.(await this.getImage());
};
/**

View File

@ -75,12 +75,16 @@ export default class Fullscreen extends ButtonControl<
};
}
protected onClick = async () => {
public toggleFullscreen = async () => {
if (ScreenFull.isEnabled) {
await ScreenFull.toggle(this.mapContainer);
}
};
protected onClick = () => {
this.toggleFullscreen();
};
protected onFullscreenChange = () => {
this.isFullscreen = !!document.fullscreenElement;
@ -102,6 +106,6 @@ export default class Fullscreen extends ButtonControl<
this.setBtnIcon(btnIcon);
}
this.emit('fullscreenchange', this.isFullscreen);
this.emit('fullscreenChange', this.isFullscreen);
};
}

View File

@ -0,0 +1,70 @@
import { Point } from '@antv/l7-core';
import { isNaN } from 'lodash';
import { createL7Icon } from '../utils/icon';
import ButtonControl, {
IButtonControlOption,
} from './baseControl/buttonControl';
export interface IGeoLocateOption extends IButtonControlOption {
transform: (position: Point) => Point;
}
export { GeoLocate };
export default class GeoLocate extends ButtonControl<IGeoLocateOption> {
constructor(option?: Partial<IGeoLocateOption>) {
super(option);
if (!window.navigator.geolocation) {
console.warn('当前浏览器环境不支持获取地理定位');
}
}
public getDefault(option?: Partial<IGeoLocateOption>): IGeoLocateOption {
return {
...super.getDefault(option),
title: '定位',
btnIcon: createL7Icon('l7-icon-reposition'),
};
}
public onAdd(): HTMLElement {
const button = super.onAdd();
button.addEventListener('click', this.onClick);
return button;
}
/**
* API
*/
public getGeoLocation = () => {
return new Promise<Point>((resolve, reject) => {
window.navigator.geolocation.getCurrentPosition(
({ coords }) => {
const { longitude, latitude } = coords ?? {};
if (!isNaN(longitude) && !isNaN(latitude)) {
resolve([longitude, latitude]);
} else {
reject();
}
},
() => {
reject();
},
);
});
};
public onClick = async () => {
if (!window.navigator.geolocation) {
return;
}
const { transform } = this.controlOption;
const position = await this.getGeoLocation();
const currentZoom = this.mapsService.getZoom();
this.mapsService.setZoomAndCenter(
currentZoom > 15 ? currentZoom : 15,
transform ? transform(position) : position,
);
};
}

View File

@ -2,7 +2,7 @@ import { ILayer } from '@antv/l7-core';
import { createL7Icon } from '../utils/icon';
import SelectControl, {
ISelectControlOption,
OptionItem,
ControlOptionItem,
} from './baseControl/selectControl';
export interface ILayerControlOption extends ISelectControlOption {
@ -37,7 +37,7 @@ export default class LayerControl extends SelectControl<ILayerControlOption> {
});
}
public getLayerOptions(): OptionItem[] {
public getLayerOptions(): ControlOptionItem[] {
return this.layers.map((layer: ILayer) => {
return {
text: layer.name,
@ -47,9 +47,13 @@ export default class LayerControl extends SelectControl<ILayerControlOption> {
}
public setOptions(option: Partial<ILayerControlOption>) {
const isLayerChange = this.checkUpdateOption(option, ['layers']);
if (isLayerChange) {
this.unbindLayerVisibleCallback();
}
super.setOptions(option);
if (this.checkUpdateOption(option, ['layers'])) {
this.layers.forEach(this.bindLayerVisibleCallback);
if (isLayerChange) {
this.bindLayerVisibleCallback();
this.selectValue = this.getLayerVisible();
this.controlOption.options = this.getLayerOptions();
this.popper.setContent(this.getPopperContent(this.controlOption.options));
@ -65,24 +69,28 @@ export default class LayerControl extends SelectControl<ILayerControlOption> {
}
this.on('selectChange', this.onSelectChange);
this.layerService.on('layerChange', this.onLayerChange);
this.layers.forEach(this.bindLayerVisibleCallback);
this.bindLayerVisibleCallback();
return super.onAdd();
}
public bindLayerVisibleCallback = (layer: ILayer) => {
layer.off('show', this.onLayerVisibleChane);
layer.off('hide', this.onLayerVisibleChane);
layer.on('show', this.onLayerVisibleChane);
layer.on('hide', this.onLayerVisibleChane);
public bindLayerVisibleCallback = () => {
this.layers.forEach((layer) => {
layer.on('show', this.onLayerVisibleChane);
layer.on('hide', this.onLayerVisibleChane);
});
};
public unbindLayerVisibleCallback = () => {
this.layers.forEach((layer) => {
layer.off('show', this.onLayerVisibleChane);
layer.off('hide', this.onLayerVisibleChane);
});
};
public onRemove() {
this.off('selectChange', this.onSelectChange);
this.layerService.off('layerChange', this.onLayerChange);
this.layers.forEach((layer) => {
layer.off('show', this.onLayerVisibleChane);
layer.off('hide', this.onLayerVisibleChane);
});
this.unbindLayerVisibleCallback();
}
protected onLayerChange = () => {

View File

@ -2,7 +2,7 @@ import { GaodeMapStyleConfig, MapboxMapStyleConfig } from '../constants';
import { createL7Icon } from '../utils/icon';
import SelectControl, {
ISelectControlOption,
OptionItem,
ControlOptionItem,
} from './baseControl/selectControl';
export { MapTheme };
@ -19,7 +19,7 @@ export default class MapTheme extends SelectControl<ISelectControlOption> {
};
}
public getStyleOptions(): OptionItem[] {
public getStyleOptions(): ControlOptionItem[] {
const mapStyleConfig =
this.mapsService.getType() === 'mapbox'
? MapboxMapStyleConfig

View File

@ -1,4 +1,4 @@
import { ILngLat, Position } from '@antv/l7-core';
import { ILngLat, Position, PositionType } from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import Control, { IControlOption } from './baseControl/control';
@ -22,6 +22,7 @@ export default class MouseLocation extends Control<
): IMouseLocationControlOption {
return {
...super.getDefault(option),
position: PositionType.BOTTOMLEFT,
transform: ([lng, lat]) => {
return [+(+lng).toFixed(6), +(+lat).toFixed(6)];
},

View File

@ -1,52 +0,0 @@
import { Point } from '@antv/l7-core';
import { isNaN } from 'lodash';
import { createL7Icon } from '../utils/icon';
import ButtonControl, {
IButtonControlOption,
} from './baseControl/buttonControl';
export interface INavigationControlOption extends IButtonControlOption {
transform: (position: Point) => Point;
zoom: number;
}
export { Navigation };
export default class Navigation extends ButtonControl<
INavigationControlOption
> {
public getDefault(
option?: Partial<INavigationControlOption>,
): INavigationControlOption {
return {
...super.getDefault(option),
title: '定位',
btnIcon: createL7Icon('l7-icon-reposition'),
zoom: -1,
};
}
public onAdd(): HTMLElement {
const button = super.onAdd();
button.addEventListener('click', this.onClick);
return button;
}
public onClick = () => {
if (!window.navigator.geolocation) {
return;
}
const { transform, zoom } = this.controlOption;
window.navigator.geolocation.getCurrentPosition(({ coords }) => {
const { longitude, latitude } = coords ?? {};
if (!isNaN(longitude) && !isNaN(latitude)) {
const position: Point = [longitude, latitude];
const currentZoom = this.mapsService.getZoom();
this.mapsService.setZoomAndCenter(
zoom >= 0 ? zoom : currentZoom > 15 ? currentZoom : 15,
transform ? transform(position) : position,
);
}
});
};
}

View File

@ -15,8 +15,9 @@ export default class Scale extends Control<IScaleControlOption> {
private mScale: HTMLElement;
private iScale: HTMLElement;
public getDefault() {
public getDefault(option: Partial<IScaleControlOption>) {
return {
...super.getDefault(option),
name: 'scale',
position: PositionType.BOTTOMLEFT,
maxWidth: 100,

View File

@ -1,3 +1,4 @@
import { PositionType } from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import { createL7Icon } from '../utils/icon';
import { Control, IControlOption } from './baseControl';
@ -19,6 +20,7 @@ export default class Zoom extends Control<IZoomControlOption> {
public getDefault(option: Partial<IZoomControlOption>) {
return {
...super.getDefault(option),
position: PositionType.BOTTOMRIGHT,
name: 'zoom',
zoomInText: createL7Icon('l7-icon-enlarge'),
zoomInTitle: 'Zoom in',
@ -65,6 +67,24 @@ export default class Zoom extends Control<IZoomControlOption> {
return this;
}
public zoomIn = () => {
if (
!this.disabled &&
this.mapsService.getZoom() < this.mapsService.getMaxZoom()
) {
this.mapsService.zoomIn();
}
};
public zoomOut = () => {
if (
!this.disabled &&
this.mapsService.getZoom() > this.mapsService.getMinZoom()
) {
this.mapsService.zoomOut();
}
};
private resetButtonGroup(container: HTMLElement) {
DOM.clearChildren(container);
this.zoomInButton = this.createButton(
@ -84,24 +104,6 @@ export default class Zoom extends Control<IZoomControlOption> {
this.updateDisabled();
}
private zoomIn = () => {
if (
!this.disabled &&
this.mapsService.getZoom() < this.mapsService.getMaxZoom()
) {
this.mapsService.zoomIn();
}
};
private zoomOut = () => {
if (
!this.disabled &&
this.mapsService.getZoom() > this.mapsService.getMinZoom()
) {
this.mapsService.zoomOut();
}
};
private createButton(
html: Element | string,
tile: string,

View File

@ -13,7 +13,7 @@
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
&.l7-control-hide {
&.l7-control--hide {
display: none;
}
}
@ -25,7 +25,7 @@
position: absolute;
z-index: 1000;
pointer-events: none;
.l7-control {
.l7-control:not(.l7-control--hide) {
margin-@{value}: @l7-control-space;
}
}

View File

@ -66,7 +66,7 @@
/* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.l7-control-container .l7-control.l7-control-hide {
.l7-control-container .l7-control.l7-control--hide {
display: none;
}
.l7-control-container .l7-top {
@ -76,7 +76,7 @@
z-index: 1000;
pointer-events: none;
}
.l7-control-container .l7-top .l7-control {
.l7-control-container .l7-top .l7-control:not(.l7-control--hide) {
margin-top: 8px;
}
.l7-control-container .l7-right {
@ -86,7 +86,7 @@
z-index: 1000;
pointer-events: none;
}
.l7-control-container .l7-right .l7-control {
.l7-control-container .l7-right .l7-control:not(.l7-control--hide) {
margin-right: 8px;
}
.l7-control-container .l7-bottom {
@ -96,7 +96,7 @@
z-index: 1000;
pointer-events: none;
}
.l7-control-container .l7-bottom .l7-control {
.l7-control-container .l7-bottom .l7-control:not(.l7-control--hide) {
margin-bottom: 8px;
}
.l7-control-container .l7-left {
@ -106,7 +106,7 @@
z-index: 1000;
pointer-events: none;
}
.l7-control-container .l7-left .l7-control {
.l7-control-container .l7-left .l7-control:not(.l7-control--hide) {
margin-left: 8px;
}
.l7-control-container .l7-center {
@ -191,19 +191,19 @@
background-color: #f3f3f3;
}
.l7-button-control:disabled {
background-color: #fbfbfb;
color: #bbbbbb;
background-color: #fafafa;
color: #bdbdbd;
cursor: not-allowed;
}
.l7-button-control:disabled .l7-iconfont {
fill: #bbbbbb;
color: #bbbbbb;
fill: #bdbdbd;
color: #bdbdbd;
}
.l7-button-control:disabled:hover {
background-color: #fbfbfb;
background-color: #fafafa;
}
.l7-button-control:disabled:active {
background-color: #fbfbfb;
background-color: #fafafa;
}
.l7-popper {
position: absolute;
@ -348,6 +348,7 @@
.l7-control-logo {
width: 89px;
height: 16px;
user-select: none;
}
.l7-control-logo img {
height: 100%;
@ -560,3 +561,9 @@
.l7-map:active .l7-popup-track-pointer {
display: none;
}
.l7-layer-popup__row {
font-size: 12px;
}
.l7-layer-popup__row + .l7-layer-popup__row {
margin-top: 4px;
}

View File

@ -9,3 +9,4 @@
@import 'zoom';
@import 'scale';
@import 'popup';
@import 'layerPopup';

View File

@ -0,0 +1,8 @@
@import 'variables';
.l7-layer-popup__row {
font-size: 12px;
& + & {
margin-top: 4px;
}
}

View File

@ -3,6 +3,7 @@
.l7-control-logo {
width: 89px;
height: 16px;
user-select: none;
img {
height: 100%;
width: 100%;

View File

@ -12,8 +12,8 @@
@l7-btn-control-size: 28px;
@l7-btn-icon-size: 16px;
@l7-btn-control-border-radius: 2px;
@l7-btn-control-disabled-bg-color: #fbfbfb;
@l7-btn-control-disabled-font-color: #bbbbbb;
@l7-btn-control-disabled-bg-color: #fafafa;
@l7-btn-control-disabled-font-color: #bdbdbd;
@l7-btn-border-color: #f0f0f0;
@l7-btn-column-height: 44px;

View File

@ -9,7 +9,7 @@ export * from './control/baseControl';
export * from './control/logo';
export * from './control/fullscreen';
export * from './control/exportImage';
export * from './control/navigation';
export * from './control/geoLocate';
export * from './control/mapTheme';
export * from './control/layerControl';
export * from './control/mouseLocation';

View File

@ -2,22 +2,24 @@ import { ILayer, IPopupOption } from '@antv/l7-core';
import { BaseLayer } from '@antv/l7-layers';
import { DOM } from '@antv/l7-utils';
import { Container } from 'inversify';
import { get } from 'lodash';
// import { Container } from 'inversify';
import Popup from './popup';
export type LayerField = {
field: string;
fieldFormat?: (field: string) => string;
valueFormat?: (value: any) => string;
formatField?: (field: string) => string;
formatValue?: (value: any) => string;
getValue?: (feature: any) => string;
};
export type LayerPopupConfigFieldItem = {
export type LayerPopupConfigItem = {
layer: BaseLayer | string;
fields: Array<LayerField | string>;
};
export interface ILayerPopupOption extends IPopupOption {
config: LayerPopupConfigFieldItem[];
config: LayerPopupConfigItem[];
trigger: 'hover' | 'click';
}
@ -26,7 +28,7 @@ type LayerMapInfo = {
onMouseOut?: (layer: BaseLayer, e: any) => void;
onClick?: (layer: BaseLayer, e: any) => void;
onSourceUpdate?: (layer: BaseLayer) => void;
} & Partial<LayerPopupConfigFieldItem>;
} & Partial<LayerPopupConfigItem>;
export { LayerPopup };
@ -215,14 +217,14 @@ export default class LayerPopup extends Popup<ILayerPopupOption> {
}
const { fields } = layerInfo;
fields?.forEach((fieldConfig) => {
const { field, fieldFormat, valueFormat } =
const { field, formatField, formatValue, getValue } =
typeof fieldConfig === 'string'
? ({ field: fieldConfig } as any)
: fieldConfig;
const row = DOM.create('div', 'l7-layer-popup__row');
const value = feature[field];
row.innerHTML = `${fieldFormat ? fieldFormat(field) : field}: ${
valueFormat ? valueFormat(value) : value
const value = getValue ? getValue(e.feature) : get(feature, field);
row.innerHTML = `${formatField ? formatField(field) : field}: ${
formatValue ? formatValue(value) : value
}`;
frag.appendChild(row);
});
@ -235,9 +237,7 @@ export default class LayerPopup extends Popup<ILayerPopupOption> {
* @param config
* @protected
*/
protected getLayerByConfig(
config: LayerPopupConfigFieldItem,
): ILayer | undefined {
protected getLayerByConfig(config: LayerPopupConfigItem): ILayer | undefined {
const layer = config.layer;
if (layer instanceof BaseLayer) {
return layer;

View File

@ -33,12 +33,6 @@ export default class Popup<O extends IPopupOption = IPopupOption>
protected layerService: ILayerService;
protected scene: Container;
/**
*
* @protected
*/
protected lngLat: ILngLat;
/**
* DOM
* @protected
@ -87,6 +81,19 @@ export default class Popup<O extends IPopupOption = IPopupOption>
*/
protected isShow: boolean = true;
protected get lngLat() {
return (
this.popupOption.lngLat ?? {
lng: 0,
lat: 0,
}
);
}
protected set lngLat(newLngLat: ILngLat) {
this.popupOption.lngLat = newLngLat;
}
constructor(cfg?: Partial<O>) {
super();
this.popupOption = {
@ -275,11 +282,15 @@ export default class Popup<O extends IPopupOption = IPopupOption>
return this;
}
public setLngLat(lngLat: ILngLat | [number, number]): this {
return this.setLnglat(lngLat);
}
/**
* Popup
* @param lngLat
*/
public setLnglat(lngLat: ILngLat | number[]): this {
public setLnglat(lngLat: ILngLat | [number, number]): this {
this.lngLat = lngLat as ILngLat;
if (Array.isArray(lngLat)) {
this.lngLat = {
@ -288,8 +299,10 @@ export default class Popup<O extends IPopupOption = IPopupOption>
};
}
if (this.mapsService) {
// 防止事件重复监听
this.mapsService.off('camerachange', this.update);
this.mapsService.off('viewchange', this.update);
this.mapsService.on('camerachange', this.update);
this.mapsService.on('viewchange', this.update);
}
@ -425,7 +438,8 @@ export default class Popup<O extends IPopupOption = IPopupOption>
}
if (this.popupOption.closeButton) {
const closeButton = createL7Icon('l7-icon-guanbi l7-popup-close-button');
const closeButton = createL7Icon('l7-icon-guanbi');
DOM.addClass(closeButton, 'l7-popup-close-button');
this.content.appendChild(closeButton);
if (this.popupOption.closeButtonOffsets) {

View File

@ -39,7 +39,7 @@ export interface IPopupOption {
/**
*
*/
offsets: number[];
offsets: [number, number];
/**
*

View File

@ -1,92 +0,0 @@
---
title: Control
order: 3
---
`markdown:docs/common/style.md`
地图组件 用于控制地图的状态如果平移,缩放,或者展示地图一些的辅助信息如图例,比例尺
L7 目前支持 Control
- Zoom 放大缩小
- Scale 比例尺
- Layers 图层列表
## 构造函数
### option
position: `string` 控件位置支持是个方位
- bottomright
- topright
- bottomleft
- topleft
- topcenter
- bottomcenter
- leftcenter
- rightcenter
### 组件介绍
```
import { Scale, Layers, Zoom } from '@antv/l7';
```
#### Zoom
放大缩小组件 默认左上角
```javascript
const zoomControl = new Zoom({
position: 'topleft',
});
scene.addControl(zoomControl);
```
#### Scale
比例尺组件 默认左下角
```javascript
const scaleControl = new Scale({
position: 'bottomleft',
});
scene.addControl(scaleControl);
```
#### Layers
图层列表目前支持可视化的图层控制
```javascript
const overlayers = {
点图层: layer,
};
const layersControl = new Layers({
overlayers,
});
scene.addControl(layersControl);
```
## 方法
#### setPosition
设置组件位置
```javascript
control.setPosition('bottomright');
```
#### remove
移除地图组件
```javascript
control.remove();
```

View File

@ -1,108 +0,0 @@
---
title: Control 控件
order: 3
---
`markdown:docs/common/style.md`
地图组件用于控制地图的状态如果平移,缩放,或者展示地图一些的辅助信息如图例、比例尺
L7 目前支持 Control
- Zoom 放大缩小
- Scale 比例尺
- Layers 图层列表
## 构造函数
#### option
position: `string` 控件位置支持 8 个方位
- bottomright
- topright
- bottomleft
- topleft
- topcenter
- bottomcenter
- leftcenter
- rightcenter
### 组件介绍
```
import { Scale, Layers, Zoom } from '@antv/l7';
```
#### Zoom
放大缩小组件 默认左上角
```javascript
const zoomControl = new Zoom({
position: 'topleft',
});
scene.addControl(zoomControl);
```
#### Scale
比例尺组件 默认左下角
```javascript
const scaleControl = new Scale({
position: 'bottomleft',
});
scene.addControl(scaleControl);
```
#### Layers
图层列表目前支持可视化的图层控制
配置项
option 控件配置项
overlayers 将一组图层添加到图层列表,
overlayers Object
key: 列表显示的图层名字可以自定义
layer: 图层对象
overlayers 示例
```javascript
const layer = {
图层一: layer1,
图层二: layer2,
};
```
```javascript
const overlayers = {
点图层: layer,
};
const layersControl = new Layers({
overlayers,
});
scene.addControl(layersControl);
```
## 方法
#### setPosition
设置组件位置
```javascript
control.setPosition('bottomright');
```
#### remove
移除地图组件
```javascript
control.remove();
```

View File

@ -0,0 +1,66 @@
---
title: 控件
order: 1
---
地图控件指的是悬停在地图四周,可以对地图以及图层等元素进行**信息呈现**或**交互**的组件。
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*zgFeTocc-_oAAAAAAAAAAAAAARQnAQ)
# 使用
```ts
import { Scene, Zoom } from '@antv/l7';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
// 实例化 Zoom 控件,可以在构造器中传入控件的配置
const zoom = new Zoom({
position: 'leftbottom',
className: 'my-test-class',
});
// 将实例化的控件添加至 L7 中
scene.addControl(zoom);
});
```
# 更新配置
在控件实例化之后,如果需要更新配置,可以调用控件实例的 `setOptions` 方法,同时传入需要更新的配置对象即可。
```ts
const zoom = new Zoom({
position: 'leftbottom',
});
const onPositionChange = () => {
// 通过 setOptions 传入需要更新的配置对象
zoom.setOptions({
position: 'topright',
});
};
```
# 插槽
当前 L7 中的控件支持插入到地图的**左上、左下、右上、右下、上、左、下、右**八个位置的控件插槽中,并且在同一插槽中的多个控件支持**横向**和**纵向**排列。
在初始化所有的控件类时,可以传入 `position` 参数来设置控件对应的插槽以及排列方式。
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*BfG1TI231ysAAAAAAAAAAAAAARQnAQ)
# 配置
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,78 @@
---
title: ExportImage 导出图片
order: 7
---
对当前地图部分进行截图并生成图片的 `Base64` 字符串。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*Yc78QZaeJWkAAAAAAAAAAAAAARQnAQ" width="400"/>
# 说明
截图时被截取的目标仅包含:
- 地图底图
- 图层(不包含 MarkerLayer
**注意:由于当前地图底图对应 `Canvas` 默认开启了缓冲区,导致默认情况下无法截取到地图底图部分。**
因此若开发者需要完整的截图能力,则应当在初始化地图实例时传递以下参数以关闭 `Canvas` 缓冲区。
```ts
new GaodeMapV2({
WebGLParams: {
preserveDrawingBuffer: true,
},
});
new Mapbox({
preserveDrawingBuffer: true,
});
```
# 使用
```ts
import { Scene, ExportImage } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
// 关闭地图缓冲区,否则截图时无法截取到地图部分
WebGLParams: {
preserveDrawingBuffer: true,
},
}),
});
scene.on('loaded', () => {
const zoom = new ExportImage({
zoomInTitle: '放大',
zoomOutTitle: '缩小',
});
scene.addControl(zoom);
});
```
# 配置
| 名称 | 说明 | 类型 |
| --------- | -------------------------------------------------- | -------------------------- |
| imageType | 截图图片的格式 | `'png'` &#124; `'jpeg'` |
| onExport | 截图成功后,用于接收图片 `Base64` 字符串的回调函数 | `(base64: string) => void` |
`markdown:docs/common/control/btn-api.md`
`markdown:docs/common/control/api.md`
# 方法
| 名称 | 说明 | 类型 |
| -------- | ------------------------ | ----------------------- |
| getImage | 获取截图的 Base64 字符串 | `() => Promise<string>` |
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,54 @@
---
title: Fullscreen 全屏
order: 5
---
用于控制地图区域的**全屏**和**退出全屏**的控制按钮控件。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*CcOXRqK5ARgAAAAAAAAAAAAAARQnAQ" width="400"/>
# 使用
```ts
import { Scene, Fullscreen } from '@antv/l7';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
const fullscreen = new Fullscreen({
btnText: '全屏',
exitBtnText: '退出全屏',
});
scene.addControl(fullscreen);
});
```
# 配置
`markdown:docs/common/control/btn-api.md`
| 名称 | 说明 | 类型 |
| ----------- | --------------------------------- | --------------------------------- |
| exitBtnIcon | 退出全屏按钮的图标 | `HTMLElement` &#124; `SVGElement` |
| exitBtnText | 退出全屏按钮的文本 | `string` |
| exitTitle | 退出全屏按钮的文本的 `title` 属性 | `string` |
`markdown:docs/common/control/api.md`
# 方法
| 名称 | 说明 | 类型 |
| ---------------- | ------------------------------- | ------------ |
| toggleFullscreen | 进入/退出全屏地图部分的全屏状态 | `() => void` |
`markdown:docs/common/control/method.md`
# 事件
| 名称 | 说明 | 类型 |
| ---------------- | ------------------------ | --------------------------------- |
| fullscreenChange | 当全屏状态发生变化时触发 | `(isFullscreen: boolean) => void` |
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,58 @@
---
title: GeoLocate 定位
order: 6
---
使用浏览器环境的 `nagigator``getlocation` 方法,使用浏览器打开位置感应能力获取当前用户所在经纬度。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*BOsBRJyYeMEAAAAAAAAAAAAAARQnAQ" width="400"/>
# 说明
**注意:**
- 在使用该能力时,会需要用户对浏览器打开位置感知能力进行鉴权。
- 当前浏览器获取到的坐标是 `WGS84` 地理坐标系,在高德地图上使用会有偏差,可以使用 `transform` 配置进行坐标系的转换。
# 使用
```ts
import { Scene, GeoLocate } from '@antv/l7';
import gcoord from 'gcoord';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
const geoLocate = new GeoLocate({
transform: (position) => {
// 将获取到基于 WGS84 地理坐标系 的坐标转成 GCJ02 坐标系
return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
},
});
scene.addControl(geoLocate);
});
```
# 配置
| 名称 | 说明 | 类型 |
| --------- | ----------------------------------------------------------------------- | -------------------------------------------------- |
| transform | 格式化通过 `getlocation` 获取到的经纬度的函数,可以用于地理坐标系的转换 | `(position: [number, number]) => [number, number]` |
`markdown:docs/common/control/btn-api.md`
`markdown:docs/common/control/api.md`
# 方法
| 名称 | 说明 | 类型 |
| -------------- | ---------------------- |-----------------------------------|
| getGeoLocation | 获取当前用户所在经纬度 | `() => Promise<[number, number]>` |
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,58 @@
---
title: LayerControl 图层显隐
order: 8
---
用于控制目标图层组的**显示**和**隐藏**操作。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*8OCiRYL29CcAAAAAAAAAAAAAARQnAQ" width="400"/>
# 说明
**注意** 在控件中展示的图层名称会默认读取图层的 `name` 属性,因此需要用户在初始化图层时传入图层对应的名称。
# 使用
```ts
import { Scene, LayerControl } from '@antv/l7';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
const layer = new PointLayer({
name: '自定义图层名称',
});
scene.addLayer(layer);
const layerControl = new LayerControl({
layers: [layer],
});
scene.addControl(layerControl);
});
```
# 配置
| 名称 | 说明 | 类型 |
| ------ | ------------------------------------------------------------- | --------------- |
| layers | 需要被控制的 `layer` 数组,不传则默认读取当前 L7 中所有的图层 | `Array<ILayer>` |
`markdown:docs/common/control/popper-api.md`
`markdown:docs/common/control/btn-api.md`
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`
`markdown:docs/common/control/popper-event.md`
`markdown:docs/common/control/select-event.md`

View File

@ -0,0 +1,59 @@
---
title: Logo 标志
order: 2
---
用于在地图上展示 Logo 图片的控件,并且支持超链接点击跳转。
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*CbdSRLizMLIAAAAAAAAAAAAAARQnAQ)
# 说明
当前 L7 会默认在地图左下角展示该控件,如需隐藏可以在 Scene 实例化时配置:
```ts
import { Scene } from '@antv/l7';
const scene = new Scene({
id: 'map',
logoVisible: false,
});
```
# 使用
```ts
import { Scene, Logo } from '@antv/l7';
const scene = new Scene({
//...
});
scene.on('loaded', () => {
const logo = new Logo({
// Logo url
img:
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*GRb1TKp4HcMAAAAAAAAAAAAAARQnAQ',
// 跳转地址
href: 'https://l7.antv.vision/',
});
scene.addControl(logo);
});
```
# 配置
| 名称 | 说明 | 类型 |
| ---- | ---------------------------------------------------- | -------- |
| img | Logo 展示的图片 url | `string` |
| href | 点击 Logo 跳转的超链接,不传则纯展示图片,点击不跳转 | `string` |
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,64 @@
---
title: MapTheme 地图主题
order: 11
---
该控件用于切换地图底图的主题样式。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*xb29TawbZDgAAAAAAAAAAAAAARQnAQ" width="400"/>
# 说明
MapTheme 会根据当前地图底图类型(如 Mapbox、GaodeMapV2默认展示相对应的默认主题选项用于也可以传入自定义的主题选项
# 使用
```ts
import { Scene, MapTheme } from '@antv/l7';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
const mapTheme = new MapTheme({});
scene.addControl(mapTheme);
});
```
# 配置
| 名称 | 说明 | 类型 |
| ------- |------------------------------------------------------------------| --------------------------- |
| options | 用户自定义的地图主题选项,每个选项的类型可见 [IControlOptionItem](#icontroloptionitem) | `Array<IControlOptionItem>` |
## IControlOptionItem
```ts
export type IControlOptionItem = {
// 选项对应的文本
text: string;
// 选项对应地图主题 style 的 key 值
value: string;
// 选项对应展示的图片
img?: string;
};
```
`markdown:docs/common/control/popper-api.md`
`markdown:docs/common/control/btn-api.md`
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`
`markdown:docs/common/control/popper-event.md`
`markdown:docs/common/control/select-event.md`

View File

@ -0,0 +1,47 @@
---
title: MouseLocation 光标经纬度
order: 9
---
用于实时展示当前光标在地图上所对应的经纬度。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*i4F5QZ4K650AAAAAAAAAAAAAARQnAQ" width="400"/>
# 使用
```ts
import { Scene, MouseLocation } from '@antv/l7';
const scene = new Scene({
// ...
});
scene.on('loaded', () => {
const mouseLocation = new MouseLocation({
transform: (position) => {
return position;
},
});
scene.addControl(mouseLocation);
});
```
# 配置
| 名称 | 说明 | 类型 |
| --------- | ---------------------------- | -------------------------------------------------- |
| transform | 转换光标所在经纬度的回调函数 | `(position: [number, number]) => [number, number]` |
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
| 名称 | 说明 | 类型 |
| -------------- | ---------------------------- | -------------------------------------- |
| locationChange | 光标所在经纬度发生变化时触发 | `(position: [number, number]) => void` |
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,46 @@
---
title: Scale 缩放尺
order: 4
---
该控件用于显示地图上的距离与地面上相应距离的比率。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*r3iSQI4SekYAAAAAAAAAAAAAARQnAQ" width="400"/>
# 使用
```ts
import { Scene, Scale } from '@antv/l7';
const scene = new Scene({
//...
});
scene.on('loaded', () => {
const scale = new Scale({
zoomInTitle: '放大',
zoomOutTitle: '缩小',
});
scene.addControl(scale);
});
```
# 配置
| 名称 | 说明 | 类型 | 默认值 |
| -------------- | ------------------------------------ | --------- | ------- |
| lockWidth | 是否固定容器宽度 | `boolean` | `true` |
| maxWidth | 组件的容器最大宽度 | `number` | `100` |
| metric | 展示**千米**格式的比例尺 | `boolean` | `true` |
| imperial | 展示**英里**格式的比例尺 | `boolean` | `false` |
| updateWhenIdle | 是否只在拖拽和缩放结束后才更新比例尺 | `boolean` | `false` |
`markdown:docs/common/control/api.md`
# 方法
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,50 @@
---
title: Zoom 缩放
order: 3
---
用于控制地图**放大**和**缩小**的控件,并且当地图达到最大或最小缩放比时,会禁用对应缩放按钮。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*CJx3Tby-XlEAAAAAAAAAAAAAARQnAQ" width="400"/>
# 使用
```ts
import { Scene, Zoom } from '@antv/l7';
const scene = new Scene({
//...
});
scene.on('loaded', () => {
const zoom = new Zoom({
zoomInTitle: '放大',
zoomOutTitle: '缩小',
});
scene.addControl(zoom);
});
```
# 配置
| 名称 | 说明 | 类型 |
| ------------ | ----------------------- | ------------------------- |
| zoomInText | 放大按钮的展示内容 | `Element` &#124; `string` |
| zoomInTitle | 放大按钮的 `title` 属性 | `string` |
| zoomOutText | 缩小按钮的展示内容 | `Element` &#124; `string` |
| zoomOutTitle | 缩小按钮的 `title` 属性 | `string` |
`markdown:docs/common/control/api.md`
# 方法
| 名称 | 说明 | 类型 |
| ------- | -------- | ------------ |
| zoomIn | 放大地图 | `() => void` |
| zoomOut | 缩小底图 | `() => void` |
`markdown:docs/common/control/method.md`
# 事件
`markdown:docs/common/control/event.md`

View File

@ -0,0 +1,109 @@
---
title: LayerPopup 图层信息框
order: 1
---
LayerPopup 基于 Popup 封装的,专门用于展示图层元素信息的气泡。
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*HC6BT6v3YRIAAAAAAAAAAAAAARQnAQ" width="300"/>
# 说明
LayerPopup 是为了让开发者通过配置快速生成用于展示图层信息的气泡,开发者可以传入需要展示信息气泡的图层,以及需要展示的字段。
LayerPopup 会自行对目标图层的鼠标事件进行监听,当用户点击/悬停在目标图层的某一元素上时,会自动打开 Popup 并展示该元素的字段值。
# 使用
```ts
import { Scene, LayerPopup, PointLayer } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
// ...
}),
});
scene.on('loaded', () => {
const pointLayer = new PointLayer();
pointLayer.source(
[
{
lng: 120,
lat: 30,
name: 'Test 1',
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
);
scene.addLayer(pointLayer);
const layerPopup = new LayerPopup({
config: [
{
layer: pointLayer,
fields: [
{
field: 'name',
formatValue: (name?: string) => name.trim() ?? '-',
},
],
},
],
trigger: 'hover',
});
scene.addPopup(popup);
});
```
# 配置
| 名称 | 说明 | 类型 | 默认值 |
| ------- | --------------------------------------------------------------------------------------------- | ----------------------------- | --------- |
| config | 需要展示 Popup 的图层配置数组,每个选项类型可见 [LayerPopupConfigItem](#layerpopupconfigitem) | `Array<LayerPopupConfigItem>` | `[]` |
| trigger | 鼠标触发 Popup 展示的方式 | `'hover' | 'click'` | `'hover'` |
## LayerPopupConfigItem
| 名称 | 说明 | 类型 |
| ------ | ------------------------------------------------------------------------------------------------- | --------------------- |
| layer | 需要展示 Popup 的目标图层实例,或其的 `id``name` | `BaseLayer | string` |
| fields | 需要展示的字段数组,支持传入字段 key 值字符串,或者针对该字段的详细配置 [LayerField](#layerfield) | `string | LayerField` |
## LayerField
| 名称 | 说明 | 类型 |
| ----------- | --------------------------- | --------------------------- |
| field | 字段的 key 值字符串 | `string` |
| formatField | 对展示的 key 字段进行格式化 | `(field: string) => string` |
| formatValue | 对展示的 value 值进行格式化 | `(value: any) => string` |
| getValue | 自定义获取值的方式 | `(feature: any) => string` |
# 方法
| 名称 | 说明 | 类型 |
| ---------- | --------------------------- | ------------------------------------------------------------------- |
| getOptions | 获取当前 Popup 配置 | `() => IPopupOption` |
| setOptions | 更新当前 Popup 配置 | `(newOption: Partial<IPopupOption>) => this` |
| show | 显示 Popup | `() => this` |
| hide | 隐藏 Popup | `() => this` |
| getIsShow | 判断当前气泡是否展示 | `() => boolean` |
| setHTML | 设置 Popup 内容展示的 HTML | `(html: string | HTMLElement | HTMLElement[]) => this` |
| setText | 设置 Popup 内容展示的文本 | `(text: string) => this` |
| setLngLat | 设置 Popup 锚点所在经纬度 | `(lngLat: { lng: number; lat: number } | [number, number]) => this` |
| panToPopup | 将地图平移至当前 Popup 位置 | `() => this` |
# 事件
| 名称 | 说明 | 类型 |
| ----- | ------------------ | ------------ |
| open | Popup 被添加时触发 | `() => void` |
| close | Popup 被移除时触发 | `() => void` |
| show | Popup 显示时触发 | `() => void` |
| hide | Popup 隐藏时触发 | `() => void` |

View File

@ -3,148 +3,110 @@ title: Popup 信息框
order: 0
---
`markdown:docs/common/style.md`
Popup 是用于在地图上指定经纬度位置,展示自定义内容的气泡。
地图标注信息窗口,用于展示地图要素的属性信息
<img src="https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*N2hWTq-m-8EAAAAAAAAAAAAAARQnAQ" width="300"/>
## 构造函数
# 说明
Popup
Popup 的锚点位置是由经纬度来表达的,当地图缩放/平移时Popup 会自动计算相对于当前地图的坐标并且自动位移。换句话说,如果开发者需要在地图的**指定经纬度位置**展示信息气泡,可以考虑使用 Popup 来实现对应效果。
```javascript
const option = {};
const popup = new L7.Popup(option);
```
开发者可以自定义 Popup 展示内容:
### option
- 纯文本可以通过 `text` 配置或者``setText` 方法控制 Popup 的展示文本。
- 自定义 DOM 可以通过 `html` 配置或者 `setHTML` 方法,支持传入 HTML 字符串或者 DOM 元素或数组的方式控制 Popup 的展示内容。
- closeButton 是否显示关闭按钮,布尔值,默认为 true。
- closeButtonOffsets 显示关闭按钮时生效,[number, number],默认为 [0, 0],以右上角为起始点。
- closeOnClick 是否在点击地图的时候关闭弹框,布尔值,默认为 true
- maxWidth 弹框最宽值,默认为 240px
- anchor 弹框锚点,默认值为 bottom可选值有 center、top、top-left、left、bottom-left、bottom、bottom-right、right、top-right
# 使用
#### 添加到地图
```ts
import { Scene, Popup } from '@antv/l7';
```javascript
scene.addPopup(popup);
```
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
// ...
}),
});
## 方法
#### setLnglat
设置 popup 的经纬度位置
**参数**lnglat
支持数组
```javascript
[112, 32];
```
经纬度对象
```javascript
const lnglat = {
lng: 112.323,
lat: 30.456,
};
```
```javascript
popup.setLnglat([112, 32]);
```
#### setHTML
**参数**html 字符串
设置 popup html 内容
```javascript
var html = `<p>省份
${feature.s} </p><p>地区
${feature.m}</p><p>数值
${feature.t}</p>`;
popup.setHTML(html);
```
#### setDOMContent
- 参数 htmlNode dom 对象
区别于 setHtml 对象只能传字符串
**tips**
如果需要将 react 组件渲染到 popup 可以用此方法。
#### setText
设置 popup 显示文本内容
```javascript
popup.setText('hello world');
```
#### setMaxWidth
设置 popup 最大宽度
```javascript
popup.setMaxWidth('300px');
```
#### open
显示 popup
```javascript
popup.open();
```
#### close
关闭 popup
```javascript
popup.close();
```
#### remove
移除 popup
```javascript
popup.remove();
```
## 事件
### open
```javascript
popup.on('open', () => {});
```
#### close
```javascript
popup.on('close', () => {});
```
## 示例代码
#### 添加 popup
```
var html = '<p>'+feature.m+'</p>';
const popup= new L7.Popup().setLnglat([112, 32]).setHTML(html);
scene.on('loaded', () => {
const popup = new Popup({
// 初始锚点经纬度
lngLat: {
lng: 120,
lat: 30,
},
// Popup 标题
title: 'Popup Title',
// Popup 内容
html: 'Popup Content',
});
scene.addPopup(popup);
// 更新 Popup 锚点经纬度
popup.setLngLat({
lng: 130,
lat: 40,
});
// 更新 Popup 内容
popup.setHTML('New Popup Content');
});
```
## demo 地址
# 配置
[demo1](../../../examples/point/column#column_linear)
[demo2](../../../examples/line/path#bus_light)
| 名称 | 说明 | 类型 | 默认值 |
| ------------------ | ------------------------------------------------------------------------ | -------------------------------------- | ---------- |
| lngLat | Popup 所在的经纬度 | `{ lng: number; lat: number }` | - |
| text | Popup 内容展示的文本内容 | `string` | - |
| html | Popup 内容展示的自定义 HTML可以传 HTML 字符串,也可以传 DOM 对象或数组 | `string | HTMLElement | HTMLElement[]` | - |
| title | Popup 标题展示的自定义 HTML可以传 HTML 字符串,也可以传 DOM 对象或数组 | `string | HTMLElement | HTMLElement[]` | - |
| closeOnClick | 点击地图区域时,是否关闭当前 Popup | `boolean` | `true` |
| closeOnEsc | 点击 Esc 键时,是否关闭当前 Popup | `boolean` | `false` |
| maxWidth | Popup 的最大宽度 | `string` | `240px` |
| anchor | Popup 箭头位置,可以控制 Popup 相对于经纬度点的展示位置 | [AnchorType](#anchortype) | `'bottom'` |
| offsets | Popup 相对于锚点的偏移 | `[number, number]` | `[0, 0]` |
| autoPan | 当 Popup 展示或者位置发生变化时,地图是否要自动平移至 Popup 所在位置 | `boolean` | `false` |
| autoClose | 当有其他 Popup 展示时,是否自动关闭当前气泡 | `boolean` | `true` |
| followCursor | Popup 是否跟随光标移动,若设为 `true`,则 `lngLat` 配置无效 | `boolean` | `false` |
| closeButton | 是否展示关闭 Popup 图标 | `boolean` | `true` |
| closeButtonOffsets | 关闭 Popup 图标的相对偏移 | `[number, number]` | - |
| stopPropagation | Popup 上的鼠标事件是否要阻止其冒泡 | `boolean` | `true` |
## AnchorType
```ts
export type AnchorType =
| 'center'
| 'top'
| 'top-left'
| 'top-right'
| 'bottom'
| 'bottom-left'
| 'bottom-right'
| 'left'
| 'right';
```
# 方法
| 名称 | 说明 | 类型 |
| ---------- | --------------------------- | ------------------------------------------------------------------- |
| getOptions | 获取当前 Popup 配置 | `() => IPopupOption` |
| setOptions | 更新当前 Popup 配置 | `(newOption: Partial<IPopupOption>) => this` |
| show | 显示 Popup | `() => this` |
| hide | 隐藏 Popup | `() => this` |
| getIsShow | 判断当前气泡是否展示 | `() => boolean` |
| setHTML | 设置 Popup 内容展示的 HTML | `(html: string | HTMLElement | HTMLElement[]) => this` |
| setText | 设置 Popup 内容展示的文本 | `(text: string) => this` |
| setLngLat | 设置 Popup 锚点所在经纬度 | `(lngLat: { lng: number; lat: number } | [number, number]) => this` |
| panToPopup | 将地图平移至当前 Popup 位置 | `() => this` |
# 事件
| 名称 | 说明 | 类型 |
| ----- | ------------------ | ------------ |
| open | Popup 被添加时触发 | `() => void` |
| close | Popup 被移除时触发 | `() => void` |
| show | Popup 显示时触发 | `() => void` |
| hide | Popup 隐藏时触发 | `() => void` |

View File

@ -1,33 +0,0 @@
---
title: 控件
order: 1
---
地图控件指的是悬停在地图四周,可以对地图以及图层等元素进行信息呈现或交互的组件。
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*zgFeTocc-_oAAAAAAAAAAAAAARQnAQ)
# 插槽
当前 L7 中的控件支持插入到地图的**左上、左下、右上、右下、上、左、下、右**八个位置的控件插槽中,并且在同一插槽中的多个控件支持**横向**和**纵向**排列。
在初始化所有的控件类时,可以传入 `position` 参数来设置控件对应的插槽以及排列方式:
- `topleft`: ↖ 左上角,纵向排列
- `lefttop`: ↖ 左上角,横向排列
- `topright`: ↗ 右上角,纵向排列
- `righttop`: ↗ 右上角,横向排列
- `bottomleft`: ↙ 左下角,纵向排列
- `leftbottom`: ↙ 左下角,横向排列
- `bottomright`: ↘ 右下角,纵向排列
- `rightbottom`: ↘ 右下角,横向排列
- `topcenter`: ↑ 上方中央,横向排列
- `bottomcenter`: ↓ 下方中间,横向排列
- `leftcenter`: ← 左边中间,纵向排列
- `rightcenter`: → 右边中间,纵向排列
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*BfG1TI231ysAAAAAAAAAAAAAARQnAQ)
# API
`markdown:docs/common/control/api.md`

View File

@ -1,17 +0,0 @@
---
title: Logo
order: 2
---
用于在地图上展示 Logo 图片,并且支持超链接点击跳转。
![](https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*CbdSRLizMLIAAAAAAAAAAAAAARQnAQ)
# API
| 名称 | 说明 | 类型 |
| ---- | ---------------------------------------------------- | -------- |
| img | Logo 展示的图片 url | `string` |
| href | 点击 Logo 跳转的超链接,不传则纯展示图片,点击不跳转 | `string` |
`markdown:docs/common/control/api.md`

View File

@ -1,23 +1,23 @@
| 名称 | 说明 | 类型 |
| --------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------- |
| position | 控件被添加到地图中的插槽位置以及排列方式,详情可见 [控件插槽](/zh/docs/api/control/control#插槽) | [Position](#position) |
| className | 自定义样式名 | `string` |
| style | 自定义样式 | `string` |
| 名称 | 说明 | 类型 |
| --------- | ---------------------------------------------------------------------------------------------- | --------------------- |
| position | 控件被添加到地图中的位置以及排列方式,详情可见 [控件插槽](/zh/docs/api/control/control#插槽) | [Position](#position) |
| className | 自定义样式名 | `string` |
| style | 自定义样式 | `string` |
## Position
```ts
export type Position =
| 'topright'
| 'topleft'
| 'bottomright'
| 'bottomleft'
| 'topcenter'
| 'bottomcenter'
| 'leftcenter'
| 'rightcenter'
| 'lefttop'
| 'righttop'
| 'leftbottom'
| 'rightbottom';
| 'topleft' // ↖ 左上角,纵向排列
| 'lefttop' // ↖ 左上角,横向排列
| 'topright' // ↗ 右上角,纵向排列
| 'righttop' // ↗ 右上角,横向排列
| 'bottomleft' // ↙ 左下角,纵向排列
| 'leftbottom' // ↙ 左下角,横向排列
| 'bottomright' // ↘ 右下角,纵向排列
| 'rightbottom' // ↘ 右下角,横向排列
| 'topcenter' // ↑ 上方中央,横向排列
| 'bottomcenter' // ↓ 下方中间,横向排列
| 'leftcenter' // ← 左边中间,纵向排列
| 'rightcenter'; // → 右边中间,纵向排列
```

View File

@ -0,0 +1,6 @@
| 名称 | 说明 | 类型 |
| -------- | ------------------------------------------------------- | --------------------------------- |
| btnIcon | 按钮图标 | `HTMLElement` &#124; `SVGElement` |
| btnText | 按钮内容文本 | `string` |
| title | 按钮的 `title` 属性 | `string` |
| vertical | 在 btnIcon 有值的情况下,按钮内的图标和文案是否纵向排列 | `boolean` |

View File

@ -0,0 +1,6 @@
| 名称 | 说明 | 类型 |
| ------ | ------------------ | ---------------- |
| add | 组件被添加时的事件 | `(this) => void` |
| remove | 组件被移除时的事件 | `(this) => void` |
| show | 组件显示时的事件 | `(this) => void` |
| hide | 组件隐藏时的事件 | `(this) => void` |

View File

@ -0,0 +1,7 @@
| 名称 | 说明 | 类型 |
| ------------ | --------------------------------------------- | -------------------------------------- |
| setOptions | 更新配置,参数需要参考对应组件的[配置](#配置) | `(newOption: Partial<Option>) => void` |
| getOptions | 获取当前[配置](#配置) | `() => Option` |
| show | 显示组件 | `() => void` |
| hide | 隐藏组件 | `() => void` |
| getContainer | 获取当前控件对应的 `DOM` 容器 | `() => HTMLElement` |

View File

@ -0,0 +1,4 @@
| 名称 | 说明 | 类型 |
| ---------- | ---------------- | ---------------- |
| popperShow | 气泡显示时的回调 | `(this) => void` |
| popperHide | 气泡隐藏时的回调 | `(this) => void` |

View File

@ -0,0 +1,23 @@
| 名称 | 说明 | 类型 |
| --------------- | -------------------- | ----------------------------------- |
| popperPlacement | 气泡相对于按钮的位置 | [PopperPlacement](#PopperPlacement) |
| popperTrigger | 气泡弹出的触发方式 | `'click'` &#124; `'hover'` |
| popperClassName | 气泡容器自定义样式名 | `string` |
## PopperPlacement
```ts
export type PopperPlacement =
| 'top-start'
| 'top'
| 'top-end'
| 'left-start'
| 'left'
| 'left-end'
| 'bottom-start'
| 'bottom'
| 'bottom-end'
| 'right-start'
| 'right'
| 'right-end';
```

View File

@ -0,0 +1,3 @@
| 名称 | 说明 | 类型 |
| ------------ | ---------------------- | ---------------------- |
| selectChange | 当所选值发生改变时触发 | `string` &#124; `string[]` |

View File

@ -0,0 +1 @@
`markdown:docs/api/component/control/control.zh.md`

View File

@ -0,0 +1 @@
`markdown:docs/api/component/control/control.zh.md`

View File

@ -0,0 +1,22 @@
import { Scene, GaodeMapV2, ExportImage } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
pitch: 0,
style: 'normal',
center: [120.154672, 30.241095],
zoom: 12,
WebGLParams: {
preserveDrawingBuffer: true,
},
}),
});
scene.on('loaded', () => {
const exportImage = new ExportImage({
onExport: (base64) => {
alert(base64);
},
});
scene.addControl(exportImage);
});

View File

@ -0,0 +1,15 @@
import { Scene, GaodeMapV2, Fullscreen } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
pitch: 0,
style: 'normal',
center: [120.154672, 30.241095],
zoom: 12,
}),
});
scene.on('loaded', () => {
const fullscreen = new Fullscreen();
scene.addControl(fullscreen);
});

View File

@ -0,0 +1,21 @@
import { Scene, GaodeMapV2, GeoLocate } from '@antv/l7';
import gcoord from 'gcoord';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
pitch: 0,
style: 'normal',
center: [120.154672, 30.241095],
zoom: 12,
}),
});
scene.on('loaded', () => {
const geoLocate = new GeoLocate({
transform: (position) => {
// 将获取到基于 WGS84 地理坐标系 的坐标转成 GCJ02 坐标系
return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
},
});
scene.addControl(geoLocate);
});

View File

@ -0,0 +1,48 @@
{
"title": {
"zh": "分类",
"en": "Category"
},
"demos": [
{
"filename": "zoom.ts",
"title": {
"zh": "Zoom",
"en": "Zoom"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*ubU4QaQne7QAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "scale.ts",
"title": {
"zh": "Scale",
"en": "Scale"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*KZr4S4AcVAIAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "fullscreen.ts",
"title": {
"zh": "Fullscreen",
"en": "Fullscreen"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*GOcVSqyqlsIAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "geoLocate.ts",
"title": {
"zh": "GeoLocate",
"en": "GeoLocate"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*GOcVSqyqlsIAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "exportImage.ts",
"title": {
"zh": "ExportImage",
"en": "ExportImage"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*GOcVSqyqlsIAAAAAAAAAAAAAARQnAQ"
}
]
}

View File

@ -0,0 +1,15 @@
import { Scene, GaodeMapV2, Scale } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
pitch: 0,
style: 'normal',
center: [120.154672, 30.241095],
zoom: 12,
}),
});
scene.on('loaded', () => {
const scale = new Scale();
scene.addControl(scale);
});

View File

@ -0,0 +1,16 @@
import { Scene, GaodeMapV2, Zoom } from '@antv/l7';
const scene = new Scene({
id: 'map',
map: new GaodeMapV2({
pitch: 0,
style: 'normal',
center: [120.154672, 30.241095],
zoom: 12,
}),
logoVisible: false,
});
scene.on('loaded', () => {
const zoom = new Zoom();
scene.addControl(zoom);
});

View File

@ -0,0 +1,4 @@
---
title: Controls
order: 0
---

View File

@ -0,0 +1,4 @@
---
title: 控件
order: 0
---

View File

@ -208,7 +208,7 @@ module.exports = {
order: 8,
},
{
slug: 'api/control',
slug: 'api/component/control',
title: {
zh: '控件 Control',
en: 'Control',
@ -404,6 +404,15 @@ module.exports = {
},
order: 8,
},
{
slug: 'component',
icon: 'map',
title: {
zh: '组件',
en: 'Component',
},
order: 9,
},
{
slug: 'react',
icon: 'map',

View File

@ -5,6 +5,7 @@ export enum anchorType {
'TOP-RIGHT' = 'top-right',
'BOTTOM' = 'bottom',
'BOTTOM-LEFT' = 'bottom-left',
'BOTTOM-RIGHT' = 'bottom-right',
'LEFT' = 'left',
'RIGHT' = 'right',
}

View File

@ -1,7 +1,8 @@
import { pull } from 'lodash';
import { $window } from './mini-adapter';
type ELType = HTMLElement | SVGElement;
export type ELType = HTMLElement | SVGElement;
export function getContainer(domId: string | HTMLDivElement) {
let $dom = domId as HTMLDivElement;
if (typeof domId === 'string') {

View File

@ -233,7 +233,7 @@
.l7-control-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
.l7-control-hide {
.l7-control--hide {
display: none;
}
.l7-control {