Skip to content

Commit

Permalink
feat(layer): add point line polygon image layer
Browse files Browse the repository at this point in the history
  • Loading branch information
lzxue committed Oct 12, 2019
1 parent 2570b8c commit 54f28be
Show file tree
Hide file tree
Showing 45 changed files with 1,452 additions and 169 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export * from './services/camera/ICameraService';
export * from './services/config/IConfigService';
export * from './services/scene/ISceneService';
export * from './services/shader/IShaderModuleService';
export * from './services/asset/IIconService';

/** 全部渲染服务接口 */
export * from './services/renderer/IAttribute';
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import getDecorators from 'inversify-inject-decorators';
import { TYPES } from './types';

/** Service interfaces */
import { IIconService} from './services/asset/IIconService';
import { ICameraService } from './services/camera/ICameraService';
import { IGlobalConfigService } from './services/config/IConfigService';
import { ICoordinateSystemService } from './services/coordinate/ICoordinateSystemService';
Expand All @@ -14,6 +15,7 @@ import { ILogService } from './services/log/ILogService';
import { IShaderModuleService } from './services/shader/IShaderModuleService';

/** Service implements */
import IconService from './services/asset/IconService';
import CameraService from './services/camera/CameraService';
import GlobalConfigService from './services/config/ConfigService';
import CoordinateSystemService from './services/coordinate/CoordinateSystemService';
Expand Down Expand Up @@ -44,6 +46,10 @@ container
.bind<ICoordinateSystemService>(TYPES.ICoordinateSystemService)
.to(CoordinateSystemService)
.inSingletonScope();
container
.bind<IIconService>(TYPES.IIconService)
.to(IconService)
.inSingletonScope();
container
.bind<IShaderModuleService>(TYPES.IShaderModuleService)
.to(ShaderModuleService)
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/services/asset/IIconService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ITexture2D } from '../renderer/ITexture2D';
export type IImage = HTMLImageElement | File | string;
export interface IIconValue {
x: number;
y: number;
image: HTMLImageElement;
}
export interface IIcon {
id: string;
image: HTMLImageElement;
height: number;
width: number;
}
export interface IICONMap {
[key: string]: IIconValue;
}
export interface IIconService {
addImage(id: string, image: IImage): void;
getTexture(): ITexture2D;
getIconMap(): IICONMap;
}
85 changes: 85 additions & 0 deletions packages/core/src/services/asset/IconService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { inject, injectable } from 'inversify';
import { buildIconMaping } from '../../utils/font_util';
import { ITexture2D } from '../renderer/ITexture2D';
import {
IIcon,
IICONMap,
IIconService,
IIconValue,
IImage,
} from './IIconService';
const BUFFER = 3;
const MAX_CANVAS_WIDTH = 1024;
const imageSize = 64;
@injectable()
export default class IconService implements IIconService {
private canvas: HTMLCanvasElement;
private iconData: IIcon[];
private iconMap: IICONMap;
private canvasHeigth: number;
private textrure: ITexture2D;
private ctx: CanvasRenderingContext2D;

constructor() {
this.iconData = [];
this.iconMap = {};
this.canvas = document.createElement('canvas');
// this.texture =
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
}

public async addImage(id: string, image: IImage) {
const imagedata = (await this.loadImage(image)) as HTMLImageElement;
this.iconData.push({
id,
image: imagedata,
width: imageSize,
height: imageSize,
});
const { mapping, canvasHeight } = buildIconMaping(
this.iconData,
BUFFER,
MAX_CANVAS_WIDTH,
);
this.iconMap = mapping;
this.canvasHeigth = canvasHeight;
this.updateIconAtlas();
}

public getTexture(): ITexture2D {
throw new Error('Method not implemented.');
}

public getIconMap() {
return this.iconMap;
}

private updateIconAtlas() {
this.canvas.width = MAX_CANVAS_WIDTH;
this.canvas.height = this.canvasHeigth;
Object.keys(this.iconMap).forEach((item: string) => {
const { x, y, image } = this.iconMap[item];
this.ctx.drawImage(image, x, y, imageSize, imageSize);
});
// this.texture.magFilter = THREE.LinearFilter;
// this.texture.minFilter = THREE.LinearFilter;
// this.texture.needsUpdate = true;
}

private loadImage(url: IImage) {
return new Promise((resolve, reject) => {
if (url instanceof HTMLImageElement) {
resolve(url);
return;
}
const image = new Image();
image.onload = () => {
resolve(image);
};
image.onerror = () => {
reject(new Error('Could not load image at ' + url));
};
image.src = url instanceof File ? URL.createObjectURL(url) : url;
});
}
}
2 changes: 1 addition & 1 deletion packages/core/src/services/config/ConfigService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ export default class GlobalConfigService implements IGlobalConfigService {
public reset() {
this.config = defaultGlobalConfig;
}
}
}
10 changes: 6 additions & 4 deletions packages/core/src/services/layer/ILayerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface IStyleScale {
scale: any;
field: string;
type: StyleScaleType;
option: IScaleOption;
}

export interface ILayerGlobalConfig {
Expand All @@ -44,12 +45,13 @@ export interface ILayerGlobalConfig {
type CallBack = (...args: any[]) => any;
export type StyleAttributeField = string | string[];
export type StyleAttributeOption = string | number | boolean | any[] | CallBack;
export type StyleAttrField = string | string[] | number | number[];
export interface ILayerStyleAttribute {
type: string;
names: string[];
field: StyleAttributeField;
values?: any[];
scales?: any[];
scales?: IStyleScale[];
setScales: (scales: IStyleScale[]) => void;
callback?: (...args: any[]) => [];
mapping?(...params: unknown[]): unknown[];
Expand Down Expand Up @@ -77,9 +79,9 @@ export interface ILayer {
};
multiPassRenderer: IMultiPassRenderer;
init(): ILayer;
size(field: string, value?: StyleAttributeOption): ILayer;
color(field: string, value?: StyleAttributeOption): ILayer;
shape(field: string, value?: StyleAttributeOption): ILayer;
size(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
shape(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
// pattern(field: string, value: StyleAttributeOption): ILayer;
// filter(field: string, value: StyleAttributeOption): ILayer;
// active(option: ActiveOption): ILayer;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const TYPES = {
IMapService: Symbol.for('IMapService'),
IRendererService: Symbol.for('IRendererService'),
IShaderModuleService: Symbol.for('IShaderModuleService'),
IIconService: Symbol.for('IIconService'),

/** multi-pass */
ClearPass: Symbol.for('ClearPass'),
Expand Down
68 changes: 68 additions & 0 deletions packages/core/src/utils/font_util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
IIcon,
IICONMap,
IIconService,
IIconValue,
IImage,
} from '../services/asset/IIconService';
export function buildIconMaping(
icons: IIcon[],
buffer: number,
maxCanvasWidth: number,
) {
let xOffset = 0;
let yOffset = 0;
let rowHeight = 0;
let columns = [];
const mapping: IICONMap = {};
for (const icon of icons) {
if (!mapping[icon.id]) {
const { height, width } = icon;

// fill one row
if (xOffset + width + buffer > maxCanvasWidth) {
buildRowMapping(mapping, columns, yOffset);

xOffset = 0;
yOffset = rowHeight + yOffset + buffer;
rowHeight = 0;
columns = [];
}

columns.push({
icon,
xOffset,
});

xOffset = xOffset + width + buffer;
rowHeight = Math.max(rowHeight, height);
}
}

if (columns.length > 0) {
buildRowMapping(mapping, columns, yOffset);
}

const canvasHeight = nextPowOfTwo(rowHeight + yOffset + buffer);

return {
mapping,
canvasHeight,
};
}
function buildRowMapping(
mapping: IICONMap,
columns: Array<{
icon: IIcon;
xOffset: number;
}>,
yOffset: number,
) {
for (const column of columns) {
const { icon, xOffset } = column;
mapping[icon.id] = { ...icon, x: xOffset, y: yOffset, image: icon.image };
}
}
export function nextPowOfTwo(num: number) {
return Math.pow(2, Math.ceil(Math.log2(num)));
}
2 changes: 2 additions & 0 deletions packages/layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
"@l7/core": "^0.0.1",
"@l7/source": "^0.0.1",
"@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",
"earcut": "^2.2.1",
"eventemitter3": "^3.1.0",
Expand Down
Loading

0 comments on commit 54f28be

Please sign in to comment.