Merge pull request #185 from antvis/map

Map
This commit is contained in:
@thinkinggis 2020-02-05 15:37:35 +08:00 committed by GitHub
commit 091ea42031
31 changed files with 1043 additions and 791 deletions

View File

@ -76,6 +76,19 @@ const scene = new L7.Scene({
需传入 dom 容器或者容器 id  {domObject || string} [必选]
### logoPosition
L7 Logo 的显示位置 默认左下角
- bottomright
- topright
- bottomleft,
- topleft`
### logoVisible
是否显示 L7 的 Logo {boolean} true
### zoom
地图初始显示级别 {number} 0-22

View File

@ -76,6 +76,19 @@ const scene = new L7.Scene({
需传入 dom 容器或者容器 id  {domObject || string} [必选]
### logoPosition
L7 Logo 的显示位置 默认左下角
- bottomright
- topright
- bottomleft,
- topleft`
### logoVisible
是否显示 L7 的 Logo {boolean} true
### zoom
地图初始显示级别 {number} 0-22

View File

@ -14,7 +14,7 @@
"message": "chore: publish"
}
},
"version": "2.0.13",
"version": "2.0.14",
"npmClient": "yarn",
"useWorkspaces": true,
"publishConfig": {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-component",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,8 +24,8 @@
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.0.13",
"@antv/l7-utils": "^2.0.13",
"@antv/l7-core": "^2.0.14",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"eventemitter3": "^4.0.0",
"inversify": "^5.0.1",

View File

@ -175,8 +175,12 @@ export default class Layers extends Control {
for (let i = inputs.length - 1; i >= 0; i--) {
input = inputs[i];
layer = this.layerService.getLayer(input.layerId);
if (layer) {
input.disabled = !layer.inited || !layer.isVisible();
if (layer && layer.inited) {
const minZoom = layer.getMinZoom();
const maxZoom = layer.getMaxZoom();
input.disabled = zoom < minZoom || zoom > maxZoom;
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-core",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -22,7 +22,7 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-utils": "^2.0.13",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"@mapbox/tiny-sdf": "^1.1.1",
"ajv": "^6.10.2",

View File

@ -12,6 +12,8 @@ import WarnInfo, { IWarnInfo } from './warnInfo';
*/
const defaultSceneConfig: Partial<ISceneConfig> = {
id: 'map',
logoPosition: 'bottomleft',
logoVisible: true,
};
/**

View File

@ -1,11 +1,13 @@
import Ajv from 'ajv';
import { PositionName } from '../component/IControlService';
import { ILayerConfig } from '../layer/ILayerService';
import { IMapWrapper } from '../map/IMapService';
import { IRenderConfig } from '../renderer/IRendererService';
export interface ISceneConfig extends IRenderConfig {
id: string | HTMLDivElement;
map: IMapWrapper;
logoPosition?: PositionName;
logoVisible?: boolean;
}
interface IValidateResult {

View File

@ -141,6 +141,9 @@ export interface ILayer {
isVisible(): boolean;
setMaxZoom(min: number): ILayer;
setMinZoom(max: number): ILayer;
getMinZoom(): number;
getMaxZoom(): number;
get(name: string): number;
setBlend(type: keyof typeof BlendType): void;
// animate(field: string, option: any): ILayer;
render(): ILayer;

View File

@ -10,7 +10,7 @@ export interface ISceneService {
addLayer(layer: ILayer): void;
render(): void;
getSceneContainer(): HTMLDivElement;
ExportMap2Png(): string;
exportPng(): string;
destroy(): void;
}
// scene 事件

View File

@ -226,10 +226,11 @@ export default class Scene extends EventEmitter implements ISceneService {
return this.$container as HTMLDivElement;
}
public ExportMap2Png(): string {
public exportPng(): string {
const renderCanvas = this.$container?.getElementsByTagName('canvas')[0];
this.render();
const layersPng = renderCanvas?.toDataURL() as string;
// this.render();
DOM.printCanvas(renderCanvas as HTMLCanvasElement);
const layersPng = renderCanvas?.toDataURL('image/png') as string;
return layersPng;
}
@ -237,11 +238,11 @@ export default class Scene extends EventEmitter implements ISceneService {
this.emit('destroy');
this.inited = false;
this.layerService.destroy();
this.rendererService.destroy();
this.interactionService.destroy();
this.controlService.destroy();
this.markerService.destroy();
this.removeAllListeners();
this.rendererService.destroy();
this.map.destroy();
unbind(this.$container as HTMLDivElement, this.handleWindowResized);
window

View File

@ -16,11 +16,11 @@ vec4 filterHighlightColor(vec4 color) {
if (selected) {
vec4 highLightColor = u_HighlightColor * COLOR_SCALE;
// float highLightAlpha = highLightColor.a;
// float highLightRatio = highLightAlpha / (highLightAlpha + color.a * (1.0 - highLightAlpha));
float highLightAlpha = highLightColor.a;
float highLightRatio = highLightAlpha / (highLightAlpha + color.a * (1.0 - highLightAlpha));
// vec3 resultRGB = mix(color.rgb, highLightColor.rgb, highLightRatio);
return highLightColor;
vec3 resultRGB = mix(color.rgb, highLightColor.rgb, highLightRatio);
return vec4(resultRGB, color.a);
} else {
return color;
}

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7",
"version": "2.0.13",
"version": "2.0.14",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,11 +24,11 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-component": "^2.0.13",
"@antv/l7-core": "^2.0.13",
"@antv/l7-layers": "^2.0.13",
"@antv/l7-maps": "^2.0.13",
"@antv/l7-scene": "^2.0.13",
"@antv/l7-component": "^2.0.14",
"@antv/l7-core": "^2.0.14",
"@antv/l7-layers": "^2.0.14",
"@antv/l7-maps": "^2.0.14",
"@antv/l7-scene": "^2.0.14",
"@babel/runtime": "^7.7.7"
},
"gitHead": "9fabb78790428d2025b89fb6146fc555cb1d987d",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-layers",
"version": "2.0.13",
"version": "2.0.14",
"description": "L7's collection of built-in layers",
"main": "lib/index.js",
"module": "es/index.js",
@ -22,13 +22,12 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.0.13",
"@antv/l7-source": "^2.0.13",
"@antv/l7-utils": "^2.0.13",
"@antv/l7-core": "^2.0.14",
"@antv/l7-source": "^2.0.14",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"@mapbox/martini": "^0.1.0",
"@turf/meta": "^6.0.2",
"@types/d3-color": "^1.2.2",
"d3-array": "^2.3.1",
"d3-color": "^1.4.0",
"d3-scale": "^3.1.0",
@ -47,7 +46,8 @@
"@types/d3-scale": "^2.1.1",
"@types/earcut": "^2.1.0",
"@types/gl-matrix": "^2.4.5",
"@types/lodash": "^4.14.138"
"@types/lodash": "^4.14.138",
"@types/d3-color": "^1.2.2"
},
"gitHead": "9fabb78790428d2025b89fb6146fc555cb1d987d",
"publishConfig": {

View File

@ -629,6 +629,22 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
return this;
}
public getMinZoom(): number {
const { minZoom } = this.getLayerConfig();
return minZoom as number;
}
public getMaxZoom(): number {
const { maxZoom } = this.getLayerConfig();
return maxZoom as number;
}
public get(name: string) {
const cfg = this.getLayerConfig();
// @ts-ignore
return cfg[name];
}
public setMaxZoom(maxZoom: number): ILayer {
this.updateLayerConfig({
maxZoom,

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-maps",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -23,8 +23,8 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.0.13",
"@antv/l7-utils": "^2.0.13",
"@antv/l7-core": "^2.0.14",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"gl-matrix": "^3.1.0",
"inversify": "^5.0.1",

View File

@ -1,11 +0,0 @@
import { IAMapInstance } from '../../typings/index';
import BaseMapWrapper from '../BaseMapWrapper';
import AMapService from './index';
export default class AMapWrapper extends BaseMapWrapper<
AMap.Map & IAMapInstance
> {
protected getServiceConstructor() {
return AMapService;
}
}

View File

@ -1,393 +1,11 @@
/**
* AMapService
*/
import {
Bounds,
CoordinateSystem,
ICoordinateSystemService,
IGlobalConfigService,
ILngLat,
ILogService,
IMapConfig,
IMapService,
IPoint,
IViewport,
MapServiceEvent,
MapStyle,
TYPES,
} from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import { IAMapEvent, IAMapInstance } from '../../typings/index';
import { MapTheme } from './theme';
import Viewport from './Viewport';
let mapdivCount = 0;
import { IAMapInstance } from '../../typings/index';
import BaseMapWrapper from '../BaseMapWrapper';
import AMapService from './map';
const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200';
const AMAP_VERSION: string = '1.4.15';
/**
*
*/
const AMAP_SCRIPT_ID: string = 'amap-script';
/**
*
*/
let amapLoaded = false;
/**
*
*/
let pendingResolveQueue: Array<() => void> = [];
const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; // 暂时关闭 fix 统一不同坐标系,不同底图的高度位置
/**
* AMapService
*/
@injectable()
export default class AMapService
implements IMapService<AMap.Map & IAMapInstance> {
/**
*
*/
public map: AMap.Map & IAMapInstance;
@inject(TYPES.IGlobalConfigService)
private readonly configService: IGlobalConfigService;
@inject(TYPES.ILogService)
private readonly logger: ILogService;
@inject(TYPES.MapConfig)
private readonly config: Partial<IMapConfig>;
@inject(TYPES.ICoordinateSystemService)
private readonly coordinateSystemService: ICoordinateSystemService;
@inject(TYPES.IEventEmitter)
private eventEmitter: any;
private markerContainer: HTMLElement;
private $mapContainer: HTMLElement | null;
private viewport: Viewport;
private cameraChangedCallback: (viewport: IViewport) => void;
public addMarkerContainer(): void {
const mapContainer = this.map.getContainer();
if (mapContainer !== null) {
const amap = mapContainer.getElementsByClassName(
'amap-maps',
)[0] as HTMLElement;
this.markerContainer = DOM.create('div', 'l7-marker-container', amap);
}
}
public getMarkerContainer(): HTMLElement {
return this.markerContainer;
}
// map event
public on(type: string, handler: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.on(type, handler);
} else {
this.map.on(type, handler);
}
}
public off(type: string, handler: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.off(type, handler);
} else {
this.map.off(type, handler);
}
}
public getContainer(): HTMLElement | null {
return this.map.getContainer();
}
public getSize(): [number, number] {
const size = this.map.getSize();
return [size.getWidth(), size.getHeight()];
}
public getType() {
return 'amap';
}
public getZoom(): number {
// 统一返回 Mapbox 缩放等级
return this.map.getZoom() - 1;
}
public setZoom(zoom: number): void {
return this.map.setZoom(zoom);
}
public getCenter(): ILngLat {
const center = this.map.getCenter();
return {
lng: center.getLng(),
lat: center.getLat(),
};
}
public getPitch(): number {
return this.map.getPitch();
}
public getRotation(): number {
// 统一返回逆时针旋转角度
return 360 - this.map.getRotation();
}
public getBounds(): Bounds {
// @ts-ignore
const amapBound = this.map.getBounds().toBounds();
const NE = amapBound.getNorthEast();
const SW = amapBound.getSouthWest();
const center = this.getCenter();
const maxlng =
center.lng > NE.getLng() || center.lng < SW.getLng()
? 180 - NE.getLng()
: NE.getLng();
const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng();
// 兼容 Mapbox统一返回西南、东北
return [
[minlng, SW.getLat()],
[maxlng, NE.getLat()],
];
}
public getMinZoom(): number {
const zooms = this.map.get('zooms') as [number, number];
return zooms[0] - 1;
}
public getMaxZoom(): number {
const zooms = this.map.get('zooms') as [number, number];
return zooms[1] - 1;
}
public setRotation(rotation: number): void {
return this.map.setRotation(rotation);
}
public zoomIn(): void {
this.map.zoomIn();
}
public zoomOut(): void {
this.map.zoomOut();
}
public panTo(p: [number, number]): void {
this.map.panTo(p);
}
public panBy(pixel: [number, number]): void {
this.map.panTo(pixel);
}
public fitBounds(extent: Bounds): void {
this.map.setBounds(
new AMap.Bounds([extent[0][0], extent[0][1], extent[1][0], extent[1][1]]),
);
}
public setZoomAndCenter(zoom: number, center: [number, number]): void {
this.map.setZoomAndCenter(zoom, center);
}
public setMapStyle(style: string): void {
this.map.setMapStyle(this.getMapStyle(style));
}
public pixelToLngLat(pixel: [number, number]): ILngLat {
const lngLat = this.map.pixelToLngLat(new AMap.Pixel(pixel[0], pixel[1]));
return { lng: lngLat.getLng(), lat: lngLat.getLat() };
}
public lngLatToPixel(lnglat: [number, number]): IPoint {
const p = this.map.lnglatToPixel(new AMap.LngLat(lnglat[0], lnglat[1]));
return {
x: p.getX(),
y: p.getY(),
};
}
public containerToLngLat(pixel: [number, number]): ILngLat {
const ll = new AMap.Pixel(pixel[0], pixel[1]);
const lngLat = this.map.containerToLngLat(ll);
return {
lng: lngLat?.getLng(),
lat: lngLat?.getLat(),
};
}
public lngLatToContainer(lnglat: [number, number]): IPoint {
const ll = new AMap.LngLat(lnglat[0], lnglat[1]);
const pixel = this.map.lngLatToContainer(ll);
return {
x: pixel.getX(),
y: pixel.getY(),
};
}
public async init(): Promise<void> {
const {
id,
style = 'light',
minZoom = 0,
maxZoom = 18,
token = AMAP_API_KEY,
mapInstance,
plugin = [],
...rest
} = this.config;
// 高德地图创建独立的container
// tslint:disable-next-line:typedef
await new Promise((resolve) => {
const resolveMap = () => {
if (mapInstance) {
this.map = mapInstance as AMap.Map & IAMapInstance;
this.$mapContainer = this.map.getContainer();
setTimeout(() => {
this.map.on('camerachange', this.handleCameraChanged);
resolve();
}, 30);
} else {
this.$mapContainer = this.creatAmapContainer(
id as string | HTMLDivElement,
);
const map = new AMap.Map(this.$mapContainer, {
mapStyle: this.getMapStyle(style as string),
zooms: [minZoom, maxZoom],
viewMode: '3D',
...rest,
});
// 监听地图相机事件
map.on('camerachange', this.handleCameraChanged);
// @ts-ignore
this.map = map;
setTimeout(() => {
resolve();
}, 10);
}
};
if (!amapLoaded && !mapInstance) {
if (token === AMAP_API_KEY) {
this.logger.warn(this.configService.getSceneWarninfo('MapToken'));
}
amapLoaded = true;
plugin.push('Map3D');
this.loadAMapScript(
`https://webapi.amap.com/maps?v=${AMAP_VERSION}&key=${token}&plugin=${plugin.join(
',',
)}`,
).then(() => {
resolveMap();
if (pendingResolveQueue.length) {
pendingResolveQueue.forEach((r) => r());
pendingResolveQueue = [];
}
});
} else {
if ((amapLoaded && window.AMap) || mapInstance) {
resolveMap();
} else {
pendingResolveQueue.push(resolveMap);
}
}
});
this.viewport = new Viewport();
}
public emit(name: string, ...args: any[]) {
this.eventEmitter.emit(name, ...args);
}
public once(name: string, ...args: any[]) {
this.eventEmitter.once(name, ...args);
}
public destroy() {
this.map.destroy();
// @ts-ignore
delete window.initAMap;
const $jsapi = document.getElementById(AMAP_SCRIPT_ID);
if ($jsapi) {
document.head.removeChild($jsapi);
}
}
public getMapContainer() {
return this.$mapContainer;
}
public onCameraChanged(callback: (viewport: IViewport) => void): void {
this.cameraChangedCallback = callback;
}
private handleCameraChanged = (e: IAMapEvent): void => {
const {
fov,
near,
far,
height,
pitch,
rotation,
aspect,
position,
} = e.camera;
const { lng, lat } = this.getCenter();
if (this.cameraChangedCallback) {
// resync viewport
this.viewport.syncWithMapCamera({
aspect,
// AMap 定义 rotation 为顺时针方向,而 Mapbox 为逆时针
// @see https://docs.mapbox.com/mapbox-gl-js/api/#map#getbearing
bearing: 360 - rotation,
far,
fov,
cameraHeight: height,
near,
pitch,
// AMap 定义的缩放等级 与 Mapbox 相差 1
zoom: this.map.getZoom() - 1,
center: [lng, lat],
offsetOrigin: [position.x, position.y],
});
// set coordinate system
if (this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD) {
this.coordinateSystemService.setCoordinateSystem(
CoordinateSystem.P20_OFFSET,
);
} else {
this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20);
}
this.cameraChangedCallback(this.viewport);
}
};
private getMapStyle(name: string): string {
return MapTheme[name] ? MapTheme[name] : name;
}
private creatAmapContainer(id: string | HTMLDivElement) {
let $wrapper = id as HTMLDivElement;
if (typeof id === 'string') {
$wrapper = document.getElementById(id) as HTMLDivElement;
}
const $amapdiv = document.createElement('div');
$amapdiv.style.cssText += `
position: absolute;
top: 0;
height: 100%;
width: 100%;
`;
$amapdiv.id = 'l7_amap_div' + mapdivCount++;
$wrapper.appendChild($amapdiv);
return $amapdiv;
}
private loadAMapScript(src: string) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => {
resolve();
};
script.onerror = reject;
document.head.appendChild(script);
});
export default class AMapWrapper extends BaseMapWrapper<
AMap.Map & IAMapInstance
> {
protected getServiceConstructor() {
return AMapService;
}
}

View File

@ -0,0 +1,393 @@
/**
* AMapService
*/
import {
Bounds,
CoordinateSystem,
ICoordinateSystemService,
IGlobalConfigService,
ILngLat,
ILogService,
IMapConfig,
IMapService,
IPoint,
IViewport,
MapServiceEvent,
MapStyle,
TYPES,
} from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import { IAMapEvent, IAMapInstance } from '../../typings/index';
import { MapTheme } from './theme';
import Viewport from './Viewport';
let mapdivCount = 0;
const AMAP_API_KEY: string = '15cd8a57710d40c9b7c0e3cc120f1200';
const AMAP_VERSION: string = '1.4.15';
/**
*
*/
const AMAP_SCRIPT_ID: string = 'amap-script';
/**
*
*/
let amapLoaded = false;
/**
*
*/
let pendingResolveQueue: Array<() => void> = [];
const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12; // 暂时关闭 fix 统一不同坐标系,不同底图的高度位置
/**
* AMapService
*/
@injectable()
export default class AMapService
implements IMapService<AMap.Map & IAMapInstance> {
/**
*
*/
public map: AMap.Map & IAMapInstance;
@inject(TYPES.IGlobalConfigService)
private readonly configService: IGlobalConfigService;
@inject(TYPES.ILogService)
private readonly logger: ILogService;
@inject(TYPES.MapConfig)
private readonly config: Partial<IMapConfig>;
@inject(TYPES.ICoordinateSystemService)
private readonly coordinateSystemService: ICoordinateSystemService;
@inject(TYPES.IEventEmitter)
private eventEmitter: any;
private markerContainer: HTMLElement;
private $mapContainer: HTMLElement | null;
private viewport: Viewport;
private cameraChangedCallback: (viewport: IViewport) => void;
public addMarkerContainer(): void {
const mapContainer = this.map.getContainer();
if (mapContainer !== null) {
const amap = mapContainer.getElementsByClassName(
'amap-maps',
)[0] as HTMLElement;
this.markerContainer = DOM.create('div', 'l7-marker-container', amap);
}
}
public getMarkerContainer(): HTMLElement {
return this.markerContainer;
}
// map event
public on(type: string, handler: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.on(type, handler);
} else {
this.map.on(type, handler);
}
}
public off(type: string, handler: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.off(type, handler);
} else {
this.map.off(type, handler);
}
}
public getContainer(): HTMLElement | null {
return this.map.getContainer();
}
public getSize(): [number, number] {
const size = this.map.getSize();
return [size.getWidth(), size.getHeight()];
}
public getType() {
return 'amap';
}
public getZoom(): number {
// 统一返回 Mapbox 缩放等级
return this.map.getZoom() - 1;
}
public setZoom(zoom: number): void {
return this.map.setZoom(zoom);
}
public getCenter(): ILngLat {
const center = this.map.getCenter();
return {
lng: center.getLng(),
lat: center.getLat(),
};
}
public getPitch(): number {
return this.map.getPitch();
}
public getRotation(): number {
// 统一返回逆时针旋转角度
return 360 - this.map.getRotation();
}
public getBounds(): Bounds {
// @ts-ignore
const amapBound = this.map.getBounds().toBounds();
const NE = amapBound.getNorthEast();
const SW = amapBound.getSouthWest();
const center = this.getCenter();
const maxlng =
center.lng > NE.getLng() || center.lng < SW.getLng()
? 180 - NE.getLng()
: NE.getLng();
const minlng = center.lng < SW.getLng() ? SW.getLng() - 180 : SW.getLng();
// 兼容 Mapbox统一返回西南、东北
return [
[minlng, SW.getLat()],
[maxlng, NE.getLat()],
];
}
public getMinZoom(): number {
const zooms = this.map.get('zooms') as [number, number];
return zooms[0] - 1;
}
public getMaxZoom(): number {
const zooms = this.map.get('zooms') as [number, number];
return zooms[1] - 1;
}
public setRotation(rotation: number): void {
return this.map.setRotation(rotation);
}
public zoomIn(): void {
this.map.zoomIn();
}
public zoomOut(): void {
this.map.zoomOut();
}
public panTo(p: [number, number]): void {
this.map.panTo(p);
}
public panBy(pixel: [number, number]): void {
this.map.panTo(pixel);
}
public fitBounds(extent: Bounds): void {
this.map.setBounds(
new AMap.Bounds([extent[0][0], extent[0][1], extent[1][0], extent[1][1]]),
);
}
public setZoomAndCenter(zoom: number, center: [number, number]): void {
this.map.setZoomAndCenter(zoom, center);
}
public setMapStyle(style: string): void {
this.map.setMapStyle(this.getMapStyle(style));
}
public pixelToLngLat(pixel: [number, number]): ILngLat {
const lngLat = this.map.pixelToLngLat(new AMap.Pixel(pixel[0], pixel[1]));
return { lng: lngLat.getLng(), lat: lngLat.getLat() };
}
public lngLatToPixel(lnglat: [number, number]): IPoint {
const p = this.map.lnglatToPixel(new AMap.LngLat(lnglat[0], lnglat[1]));
return {
x: p.getX(),
y: p.getY(),
};
}
public containerToLngLat(pixel: [number, number]): ILngLat {
const ll = new AMap.Pixel(pixel[0], pixel[1]);
const lngLat = this.map.containerToLngLat(ll);
return {
lng: lngLat?.getLng(),
lat: lngLat?.getLat(),
};
}
public lngLatToContainer(lnglat: [number, number]): IPoint {
const ll = new AMap.LngLat(lnglat[0], lnglat[1]);
const pixel = this.map.lngLatToContainer(ll);
return {
x: pixel.getX(),
y: pixel.getY(),
};
}
public async init(): Promise<void> {
const {
id,
style = 'light',
minZoom = 0,
maxZoom = 18,
token = AMAP_API_KEY,
mapInstance,
plugin = [],
...rest
} = this.config;
// 高德地图创建独立的container
// tslint:disable-next-line:typedef
await new Promise((resolve) => {
const resolveMap = () => {
if (mapInstance) {
this.map = mapInstance as AMap.Map & IAMapInstance;
this.$mapContainer = this.map.getContainer();
setTimeout(() => {
this.map.on('camerachange', this.handleCameraChanged);
resolve();
}, 30);
} else {
this.$mapContainer = this.creatAmapContainer(
id as string | HTMLDivElement,
);
const map = new AMap.Map(this.$mapContainer, {
mapStyle: this.getMapStyle(style as string),
zooms: [minZoom, maxZoom],
viewMode: '3D',
...rest,
});
// 监听地图相机事件
map.on('camerachange', this.handleCameraChanged);
// @ts-ignore
this.map = map;
setTimeout(() => {
resolve();
}, 10);
}
};
if (!amapLoaded && !mapInstance) {
if (token === AMAP_API_KEY) {
this.logger.warn(this.configService.getSceneWarninfo('MapToken'));
}
amapLoaded = true;
plugin.push('Map3D');
this.loadAMapScript(
`https://webapi.amap.com/maps?v=${AMAP_VERSION}&key=${token}&plugin=${plugin.join(
',',
)}`,
).then(() => {
resolveMap();
if (pendingResolveQueue.length) {
pendingResolveQueue.forEach((r) => r());
pendingResolveQueue = [];
}
});
} else {
if ((amapLoaded && window.AMap) || mapInstance) {
resolveMap();
} else {
pendingResolveQueue.push(resolveMap);
}
}
});
this.viewport = new Viewport();
}
public emit(name: string, ...args: any[]) {
this.eventEmitter.emit(name, ...args);
}
public once(name: string, ...args: any[]) {
this.eventEmitter.once(name, ...args);
}
public destroy() {
this.map.destroy();
// @ts-ignore
delete window.initAMap;
const $jsapi = document.getElementById(AMAP_SCRIPT_ID);
if ($jsapi) {
document.head.removeChild($jsapi);
}
}
public getMapContainer() {
return this.$mapContainer;
}
public onCameraChanged(callback: (viewport: IViewport) => void): void {
this.cameraChangedCallback = callback;
}
private handleCameraChanged = (e: IAMapEvent): void => {
const {
fov,
near,
far,
height,
pitch,
rotation,
aspect,
position,
} = e.camera;
const { lng, lat } = this.getCenter();
if (this.cameraChangedCallback) {
// resync viewport
this.viewport.syncWithMapCamera({
aspect,
// AMap 定义 rotation 为顺时针方向,而 Mapbox 为逆时针
// @see https://docs.mapbox.com/mapbox-gl-js/api/#map#getbearing
bearing: 360 - rotation,
far,
fov,
cameraHeight: height,
near,
pitch,
// AMap 定义的缩放等级 与 Mapbox 相差 1
zoom: this.map.getZoom() - 1,
center: [lng, lat],
offsetOrigin: [position.x, position.y],
});
// set coordinate system
if (this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD) {
this.coordinateSystemService.setCoordinateSystem(
CoordinateSystem.P20_OFFSET,
);
} else {
this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.P20);
}
this.cameraChangedCallback(this.viewport);
}
};
private getMapStyle(name: string): string {
return MapTheme[name] ? MapTheme[name] : name;
}
private creatAmapContainer(id: string | HTMLDivElement) {
let $wrapper = id as HTMLDivElement;
if (typeof id === 'string') {
$wrapper = document.getElementById(id) as HTMLDivElement;
}
const $amapdiv = document.createElement('div');
$amapdiv.style.cssText += `
position: absolute;
top: 0;
height: 100%;
width: 100%;
`;
$amapdiv.id = 'l7_amap_div' + mapdivCount++;
$wrapper.appendChild($amapdiv);
return $amapdiv;
}
private loadAMapScript(src: string) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => {
resolve();
};
script.onerror = reject;
document.head.appendChild(script);
});
}
}

View File

@ -1,4 +1,4 @@
import GaodeMap from './amap/Wrapper';
import Mapbox from './mapbox/Wrapper';
import GaodeMap from './amap/';
import Mapbox from './mapbox/';
export { GaodeMap, Mapbox };

View File

@ -1,12 +0,0 @@
import { Map } from 'mapbox-gl';
import { IMapboxInstance } from '../../typings/index';
import BaseMapWrapper from '../BaseMapWrapper';
import MapboxService from './index';
export default class MapboxWrapper extends BaseMapWrapper<
Map & IMapboxInstance
> {
protected getServiceConstructor() {
return MapboxService;
}
}

View File

@ -1,328 +1,12 @@
/**
* MapboxService
*/
import {
Bounds,
CoordinateSystem,
ICoordinateSystemService,
IGlobalConfigService,
ILngLat,
ILogService,
IMapConfig,
IMapService,
IPoint,
IViewport,
MapServiceEvent,
MapStyle,
TYPES,
} from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import mapboxgl, { IControl, Map } from 'mapbox-gl';
import { Map } from 'mapbox-gl';
import { IMapboxInstance } from '../../typings/index';
import Viewport from './Viewport';
const EventMap: {
[key: string]: any;
} = {
mapmove: 'move',
camerachange: 'move',
};
import { MapTheme } from './theme';
import BaseMapWrapper from '../BaseMapWrapper';
import MapboxService from './map';
const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12;
const MAPBOX_API_KEY =
'pk.eyJ1IjoibHp4dWUiLCJhIjoiYnhfTURyRSJ9.Ugm314vAKPHBzcPmY1p4KQ';
/**
* AMapService
*/
@injectable()
export default class MapboxService
implements IMapService<Map & IMapboxInstance> {
public map: Map & IMapboxInstance;
@inject(TYPES.MapConfig)
private readonly config: Partial<IMapConfig>;
@inject(TYPES.IGlobalConfigService)
private readonly configService: IGlobalConfigService;
@inject(TYPES.ILogService)
private readonly logger: ILogService;
@inject(TYPES.ICoordinateSystemService)
private readonly coordinateSystemService: ICoordinateSystemService;
@inject(TYPES.IEventEmitter)
private eventEmitter: any;
private viewport: Viewport;
private markerContainer: HTMLElement;
private cameraChangedCallback: (viewport: IViewport) => void;
private $mapContainer: HTMLElement | null;
// init
public addMarkerContainer(): void {
const container = this.map.getCanvasContainer();
this.markerContainer = DOM.create('div', 'l7-marker-container', container);
}
public getMarkerContainer(): HTMLElement {
return this.markerContainer;
}
// map event
public on(type: string, handle: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.on(type, handle);
} else {
// 统一事件名称
this.map.on(EventMap[type] || type, handle);
}
}
public off(type: string, handle: (...args: any[]) => void): void {
this.map.off(EventMap[type] || type, handle);
}
public getContainer(): HTMLElement | null {
return this.map.getContainer();
}
public getSize(): [number, number] {
const size = this.map.transform;
return [size.width, size.height];
}
// get mapStatus method
public getType() {
return 'mapbox';
}
public getZoom(): number {
return this.map.getZoom();
}
public setZoom(zoom: number) {
return this.map.setZoom(zoom);
}
public getCenter(): ILngLat {
return this.map.getCenter();
}
public getPitch(): number {
return this.map.getPitch();
}
public getRotation(): number {
return this.map.getBearing();
}
public getBounds(): Bounds {
return this.map.getBounds().toArray() as Bounds;
}
public getMinZoom(): number {
return this.map.getMinZoom();
}
public getMaxZoom(): number {
return this.map.getMaxZoom();
}
public setRotation(rotation: number): void {
this.map.setBearing(rotation);
}
public zoomIn(): void {
this.map.zoomIn();
}
public zoomOut(): void {
this.map.zoomOut();
}
public panTo(p: [number, number]): void {
this.map.panTo(p);
}
public panBy(pixel: [number, number]): void {
this.panTo(pixel);
}
public fitBounds(bound: Bounds): void {
this.map.fitBounds(bound);
}
public setMaxZoom(max: number): void {
this.map.setMaxZoom(max);
}
public setMinZoom(min: number): void {
this.map.setMinZoom(min);
}
public setZoomAndCenter(zoom: number, center: [number, number]): void {
this.map.flyTo({
zoom,
center,
});
}
public setMapStyle(style: string): void {
this.map.setStyle(this.getMapStyle(style));
}
// TODO: 计算像素坐标
public pixelToLngLat(pixel: [number, number]): ILngLat {
return this.map.unproject(pixel);
}
public lngLatToPixel(lnglat: [number, number]): IPoint {
return this.map.project(lnglat);
}
public containerToLngLat(pixel: [number, number]): ILngLat {
return this.map.unproject(pixel);
}
public lngLatToContainer(lnglat: [number, number]): IPoint {
return this.map.project(lnglat);
}
public async init(): Promise<void> {
const {
id = 'map',
attributionControl = false,
style = 'light',
token = MAPBOX_API_KEY,
rotation = 0,
mapInstance,
...rest
} = this.config;
this.viewport = new Viewport();
/**
* TODO: 使用 mapbox v0.53.x custom layer gl context
* @see https://github.com/mapbox/mapbox-gl-js/blob/master/debug/threejs.html#L61-L64
*/
// 判断全局 mapboxgl 对象的加载
if (!mapInstance && !mapboxgl) {
// 用户有时传递进来的实例是继承于 mapbox 实例化的,不一定是 mapboxgl 对象。
this.logger.error(this.configService.getSceneWarninfo('SDK'));
}
if (
token === MAPBOX_API_KEY &&
style !== 'blank' &&
!mapboxgl.accessToken &&
!mapInstance // 如果用户传递了 mapInstance应该不去干预实例的 accessToken。
) {
this.logger.warn(this.configService.getSceneWarninfo('MapToken'));
}
// 判断是否设置了 accessToken
if (!mapInstance && !mapboxgl.accessToken) {
// 用户有时传递进来的实例是继承于 mapbox 实例化的,不一定是 mapboxgl 对象。
mapboxgl.accessToken = token;
}
if (mapInstance) {
// @ts-ignore
this.map = mapInstance;
this.$mapContainer = this.map.getContainer();
} else {
this.$mapContainer = this.creatAmapContainer(id);
// @ts-ignore
this.map = new mapboxgl.Map({
container: id,
style: this.getMapStyle(style),
attributionControl,
bearing: rotation,
...rest,
});
}
this.map.on('load', this.handleCameraChanged);
this.map.on('move', this.handleCameraChanged);
// 不同于高德地图,需要手动触发首次渲染
this.handleCameraChanged();
}
public destroy() {
this.eventEmitter.removeAllListeners();
if (this.map) {
this.map.remove();
this.$mapContainer = null;
this.removeLogoControl();
}
}
public emit(name: string, ...args: any[]) {
this.eventEmitter.emit(name, ...args);
}
public once(name: string, ...args: any[]) {
this.eventEmitter.once(name, ...args);
}
public getMapContainer() {
return this.$mapContainer;
}
public onCameraChanged(callback: (viewport: IViewport) => void): void {
this.cameraChangedCallback = callback;
}
private handleCameraChanged = () => {
// @see https://github.com/mapbox/mapbox-gl-js/issues/2572
const { lat, lng } = this.map.getCenter().wrap();
// resync
this.viewport.syncWithMapCamera({
bearing: this.map.getBearing(),
center: [lng, lat],
viewportHeight: this.map.transform.height,
pitch: this.map.getPitch(),
viewportWidth: this.map.transform.width,
zoom: this.map.getZoom(),
// mapbox 中固定相机高度为 viewport 高度的 1.5 倍
cameraHeight: 0,
});
// set coordinate system
if (this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD) {
this.coordinateSystemService.setCoordinateSystem(
CoordinateSystem.LNGLAT_OFFSET,
);
} else {
this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.LNGLAT);
}
this.cameraChangedCallback(this.viewport);
};
private creatAmapContainer(id: string | HTMLDivElement) {
let $wrapper = id as HTMLDivElement;
if (typeof id === 'string') {
$wrapper = document.getElementById(id) as HTMLDivElement;
}
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;
}
return MapTheme[name] ? MapTheme[name] : name;
export default class MapboxWrapper extends BaseMapWrapper<
Map & IMapboxInstance
> {
protected getServiceConstructor() {
return MapboxService;
}
}

View File

@ -0,0 +1,328 @@
/**
* MapboxService
*/
import {
Bounds,
CoordinateSystem,
ICoordinateSystemService,
IGlobalConfigService,
ILngLat,
ILogService,
IMapConfig,
IMapService,
IPoint,
IViewport,
MapServiceEvent,
MapStyle,
TYPES,
} from '@antv/l7-core';
import { DOM } from '@antv/l7-utils';
import { inject, injectable } from 'inversify';
import mapboxgl, { IControl, Map } from 'mapbox-gl';
import { IMapboxInstance } from '../../typings/index';
import Viewport from './Viewport';
const EventMap: {
[key: string]: any;
} = {
mapmove: 'move',
camerachange: 'move',
};
import { MapTheme } from './theme';
const LNGLAT_OFFSET_ZOOM_THRESHOLD = 12;
const MAPBOX_API_KEY =
'pk.eyJ1IjoibHp4dWUiLCJhIjoiYnhfTURyRSJ9.Ugm314vAKPHBzcPmY1p4KQ';
/**
* AMapService
*/
@injectable()
export default class MapboxService
implements IMapService<Map & IMapboxInstance> {
public map: Map & IMapboxInstance;
@inject(TYPES.MapConfig)
private readonly config: Partial<IMapConfig>;
@inject(TYPES.IGlobalConfigService)
private readonly configService: IGlobalConfigService;
@inject(TYPES.ILogService)
private readonly logger: ILogService;
@inject(TYPES.ICoordinateSystemService)
private readonly coordinateSystemService: ICoordinateSystemService;
@inject(TYPES.IEventEmitter)
private eventEmitter: any;
private viewport: Viewport;
private markerContainer: HTMLElement;
private cameraChangedCallback: (viewport: IViewport) => void;
private $mapContainer: HTMLElement | null;
// init
public addMarkerContainer(): void {
const container = this.map.getCanvasContainer();
this.markerContainer = DOM.create('div', 'l7-marker-container', container);
}
public getMarkerContainer(): HTMLElement {
return this.markerContainer;
}
// map event
public on(type: string, handle: (...args: any[]) => void): void {
if (MapServiceEvent.indexOf(type) !== -1) {
this.eventEmitter.on(type, handle);
} else {
// 统一事件名称
this.map.on(EventMap[type] || type, handle);
}
}
public off(type: string, handle: (...args: any[]) => void): void {
this.map.off(EventMap[type] || type, handle);
}
public getContainer(): HTMLElement | null {
return this.map.getContainer();
}
public getSize(): [number, number] {
const size = this.map.transform;
return [size.width, size.height];
}
// get mapStatus method
public getType() {
return 'mapbox';
}
public getZoom(): number {
return this.map.getZoom();
}
public setZoom(zoom: number) {
return this.map.setZoom(zoom);
}
public getCenter(): ILngLat {
return this.map.getCenter();
}
public getPitch(): number {
return this.map.getPitch();
}
public getRotation(): number {
return this.map.getBearing();
}
public getBounds(): Bounds {
return this.map.getBounds().toArray() as Bounds;
}
public getMinZoom(): number {
return this.map.getMinZoom();
}
public getMaxZoom(): number {
return this.map.getMaxZoom();
}
public setRotation(rotation: number): void {
this.map.setBearing(rotation);
}
public zoomIn(): void {
this.map.zoomIn();
}
public zoomOut(): void {
this.map.zoomOut();
}
public panTo(p: [number, number]): void {
this.map.panTo(p);
}
public panBy(pixel: [number, number]): void {
this.panTo(pixel);
}
public fitBounds(bound: Bounds): void {
this.map.fitBounds(bound);
}
public setMaxZoom(max: number): void {
this.map.setMaxZoom(max);
}
public setMinZoom(min: number): void {
this.map.setMinZoom(min);
}
public setZoomAndCenter(zoom: number, center: [number, number]): void {
this.map.flyTo({
zoom,
center,
});
}
public setMapStyle(style: string): void {
this.map.setStyle(this.getMapStyle(style));
}
// TODO: 计算像素坐标
public pixelToLngLat(pixel: [number, number]): ILngLat {
return this.map.unproject(pixel);
}
public lngLatToPixel(lnglat: [number, number]): IPoint {
return this.map.project(lnglat);
}
public containerToLngLat(pixel: [number, number]): ILngLat {
return this.map.unproject(pixel);
}
public lngLatToContainer(lnglat: [number, number]): IPoint {
return this.map.project(lnglat);
}
public async init(): Promise<void> {
const {
id = 'map',
attributionControl = false,
style = 'light',
token = MAPBOX_API_KEY,
rotation = 0,
mapInstance,
...rest
} = this.config;
this.viewport = new Viewport();
/**
* TODO: 使用 mapbox v0.53.x custom layer gl context
* @see https://github.com/mapbox/mapbox-gl-js/blob/master/debug/threejs.html#L61-L64
*/
// 判断全局 mapboxgl 对象的加载
if (!mapInstance && !mapboxgl) {
// 用户有时传递进来的实例是继承于 mapbox 实例化的,不一定是 mapboxgl 对象。
this.logger.error(this.configService.getSceneWarninfo('SDK'));
}
if (
token === MAPBOX_API_KEY &&
style !== 'blank' &&
!mapboxgl.accessToken &&
!mapInstance // 如果用户传递了 mapInstance应该不去干预实例的 accessToken。
) {
this.logger.warn(this.configService.getSceneWarninfo('MapToken'));
}
// 判断是否设置了 accessToken
if (!mapInstance && !mapboxgl.accessToken) {
// 用户有时传递进来的实例是继承于 mapbox 实例化的,不一定是 mapboxgl 对象。
mapboxgl.accessToken = token;
}
if (mapInstance) {
// @ts-ignore
this.map = mapInstance;
this.$mapContainer = this.map.getContainer();
} else {
this.$mapContainer = this.creatAmapContainer(id);
// @ts-ignore
this.map = new mapboxgl.Map({
container: id,
style: this.getMapStyle(style),
attributionControl,
bearing: rotation,
...rest,
});
}
this.map.on('load', this.handleCameraChanged);
this.map.on('move', this.handleCameraChanged);
// 不同于高德地图,需要手动触发首次渲染
this.handleCameraChanged();
}
public destroy() {
this.eventEmitter.removeAllListeners();
if (this.map) {
this.map.remove();
this.$mapContainer = null;
this.removeLogoControl();
}
}
public emit(name: string, ...args: any[]) {
this.eventEmitter.emit(name, ...args);
}
public once(name: string, ...args: any[]) {
this.eventEmitter.once(name, ...args);
}
public getMapContainer() {
return this.$mapContainer;
}
public onCameraChanged(callback: (viewport: IViewport) => void): void {
this.cameraChangedCallback = callback;
}
private handleCameraChanged = () => {
// @see https://github.com/mapbox/mapbox-gl-js/issues/2572
const { lat, lng } = this.map.getCenter().wrap();
// resync
this.viewport.syncWithMapCamera({
bearing: this.map.getBearing(),
center: [lng, lat],
viewportHeight: this.map.transform.height,
pitch: this.map.getPitch(),
viewportWidth: this.map.transform.width,
zoom: this.map.getZoom(),
// mapbox 中固定相机高度为 viewport 高度的 1.5 倍
cameraHeight: 0,
});
// set coordinate system
if (this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD) {
this.coordinateSystemService.setCoordinateSystem(
CoordinateSystem.LNGLAT_OFFSET,
);
} else {
this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.LNGLAT);
}
this.cameraChangedCallback(this.viewport);
};
private creatAmapContainer(id: string | HTMLDivElement) {
let $wrapper = id as HTMLDivElement;
if (typeof id === 'string') {
$wrapper = document.getElementById(id) as HTMLDivElement;
}
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;
}
return MapTheme[name] ? MapTheme[name] : name;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-renderer",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,7 +25,7 @@
"gl": "^4.4.0"
},
"dependencies": {
"@antv/l7-core": "^2.0.13",
"@antv/l7-core": "^2.0.14",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"lodash": "^4.17.15",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-scene",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -22,11 +22,11 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-component": "^2.0.13",
"@antv/l7-core": "^2.0.13",
"@antv/l7-maps": "^2.0.13",
"@antv/l7-renderer": "^2.0.13",
"@antv/l7-utils": "^2.0.13",
"@antv/l7-component": "^2.0.14",
"@antv/l7-core": "^2.0.14",
"@antv/l7-maps": "^2.0.14",
"@antv/l7-renderer": "^2.0.14",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"mapbox-gl": "^1.2.1",

View File

@ -57,7 +57,7 @@ class Scene
private container: Container;
public constructor(config: ISceneConfig) {
const { id, map } = config;
const { id, map, logoPosition, logoVisible } = config;
// 创建场景容器
const sceneContainer = createSceneContainer();
@ -93,14 +93,16 @@ class Scene
// 初始化 scene
this.sceneService.init(config);
// TODO: 初始化组件
this.addControl(new Logo());
if (logoVisible) {
this.addControl(new Logo({ position: logoPosition }));
}
}
public getMapService(): IMapService<unknown> {
return this.mapService;
}
public ExportMap2Png(): string {
return this.sceneService.ExportMap2Png();
public exportPng(): string {
return this.sceneService.exportPng();
}
public get map() {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-source",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,8 +24,8 @@
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.0.13",
"@antv/l7-utils": "^2.0.13",
"@antv/l7-core": "^2.0.14",
"@antv/l7-utils": "^2.0.14",
"@babel/runtime": "^7.7.7",
"@mapbox/geojson-rewind": "^0.4.0",
"@turf/helpers": "^6.1.4",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-utils",
"version": "2.0.13",
"version": "2.0.14",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -23,7 +23,11 @@
"license": "ISC",
"dependencies": {
"@babel/runtime": "^7.7.7",
"@turf/helpers": "^6.1.4"
"@turf/helpers": "^6.1.4",
"d3-color": "^1.4.0"
},
"devDependencies": {
"@types/d3-color": "^1.2.2"
},
"gitHead": "00d23ef70d9ec76eec26833fc50ac18fe584cf26",
"publishConfig": {

View File

@ -1,5 +1,5 @@
// @ts-ignore
import { PointLayer, PolygonLayer, Scale, Scene } from '@antv/l7';
import { Layers, PointLayer, PolygonLayer, Scale, Scene } from '@antv/l7';
import { Mapbox } from '@antv/l7-maps';
import * as React from 'react';
@ -70,7 +70,16 @@ export default class ScaleComponent extends React.Component {
layer.setSelect(e.featureId);
});
const scaleControl = new Scale();
const layers = {
点图层: pointLayer,
面图层: layer,
};
const layerControl = new Layers({
overlayers: layers,
});
scene.addControl(scaleControl);
scene.addControl(layerControl);
}
public render() {

View File

@ -23,7 +23,7 @@ export default class Point3D extends React.Component {
center: [120.19382669582967, 30.258134],
pitch: 0,
style: 'dark',
zoom: 3,
zoom: 0,
}),
});
// scene.on('loaded', () => {

View File

@ -0,0 +1,183 @@
// code from https://github.com/santilland/plotty/blob/master/src/colorscales.js
export const colorScales: {
[key: string]: any;
} = {
rainbow: {
colors: [
'#96005A',
'#0000C8',
'#0019FF',
'#0098FF',
'#2CFF96',
'#97FF00',
'#FFEA00',
'#FF6F00',
'#FF0000',
],
positions: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
},
jet: {
colors: ['#000083', '#003CAA', '#05FFFF', '#FFFF00', '#FA0000', '#800000'],
positions: [0, 0.125, 0.375, 0.625, 0.875, 1],
},
hsv: {
colors: [
'#ff0000',
'#fdff02',
'#f7ff02',
'#00fc04',
'#00fc0a',
'#01f9ff',
'#0200fd',
'#0800fd',
'#ff00fb',
'#ff00f5',
'#ff0006',
],
positions: [
0,
0.169,
0.173,
0.337,
0.341,
0.506,
0.671,
0.675,
0.839,
0.843,
1,
],
},
hot: {
colors: ['#000000', '#e60000', '#ffd200', '#ffffff'],
positions: [0, 0.3, 0.6, 1],
},
cool: {
colors: ['#00ffff', '#ff00ff'],
positions: [0, 1],
},
spring: {
colors: ['#ff00ff', '#ffff00'],
positions: [0, 1],
},
summer: {
colors: ['#008066', '#ffff66'],
positions: [0, 1],
},
autumn: {
colors: ['#ff0000', '#ffff00'],
positions: [0, 1],
},
winter: {
colors: ['#0000ff', '#00ff80'],
positions: [0, 1],
},
bone: {
colors: ['#000000', '#545474', '#a9c8c8', '#ffffff'],
positions: [0, 0.376, 0.753, 1],
},
copper: {
colors: ['#000000', '#ffa066', '#ffc77f'],
positions: [0, 0.804, 1],
},
greys: {
colors: ['#000000', '#ffffff'],
positions: [0, 1],
},
yignbu: {
colors: [
'#081d58',
'#253494',
'#225ea8',
'#1d91c0',
'#41b6c4',
'#7fcdbb',
'#c7e9b4',
'#edf8d9',
'#ffffd9',
],
positions: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
},
greens: {
colors: [
'#00441b',
'#006d2c',
'#238b45',
'#41ab5d',
'#74c476',
'#a1d99b',
'#c7e9c0',
'#e5f5e0',
'#f7fcf5',
],
positions: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
},
wind: {
colors: [
'#3288bd',
'#66c2a5',
'#abdda4',
'#e6f598',
'#fee08b',
'#fdae61',
'#f46d43',
'#d53e4f',
],
positions: [0, 0.1, 0.2, 0.6, 0.7, 0.8, 0.9, 1],
},
yiorrd: {
colors: [
'#800026',
'#bd0026',
'#e31a1c',
'#fc4e2a',
'#fd8d3c',
'#feb24c',
'#fed976',
'#ffeda0',
'#ffffcc',
],
positions: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],
},
bluered: {
colors: ['#0000ff', '#ff0000'],
positions: [0, 1],
},
rdbu: {
colors: ['#050aac', '#6a89f7', '#bebebe', '#dcaa84', '#e6915a', '#b20a1c'],
positions: [0, 0.35, 0.5, 0.6, 0.7, 1],
},
picnic: {
colors: [
'#0000ff',
'#3399ff',
'#66ccff',
'#99ccff',
'#ccccff',
'#ffffff',
'#ffccff',
'#ff99ff',
'#ff66cc',
'#ff6666',
'#ff0000',
],
positions: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
},
portland: {
colors: ['#0c3383', '#0a88ba', '#f2d338', '#f28f38', '#d91e1e'],
positions: [0, 0.25, 0.5, 0.75, 1],
},
blackbody: {
colors: ['#000000', '#e60000', '#e6d200', '#ffffff', '#a0c8ff'],
positions: [0, 0.2, 0.4, 0.7, 1],
},
earth: {
colors: ['#000082', '#00b4b4', '#28d228', '#e6e632', '#784614', '#ffffff'],
positions: [0, 0.1, 0.2, 0.4, 0.6, 1],
},
electric: {
colors: ['#000000', '#1e0064', '#780064', '#a05a00', '#e6c800', '#fffadc'],
positions: [0, 0.15, 0.4, 0.6, 0.8, 1],
},
};
// export default colorScales;