Refactor style cache
This commit is contained in:
parent
b83aca7969
commit
6379b64351
@ -6,7 +6,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ngx-openlayers": "1.0.0-next.13",
|
||||
"ol": "^6.0.0"
|
||||
"ol": "6.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "^8.2.0",
|
||||
|
@ -4,8 +4,7 @@ import { IMapState } from '../models/map.state';
|
||||
import { IItemLayer } from '../models/item.layer';
|
||||
import { IQueryState } from '../models/query.state';
|
||||
import { IItem } from '@farmmaps/common';
|
||||
import { Feature } from 'ol';
|
||||
import { Extent } from 'ol/extent';
|
||||
import { Feature,Style } from 'ol';
|
||||
|
||||
export const SETSTATE = '[Map] SetState';
|
||||
export const SETMAPSTATE = '[Map] MapState';
|
||||
@ -35,6 +34,7 @@ export const SELECTBASELAYER = '[Map] SelectBaseLayers';
|
||||
export const SELECTOVERLAYLAYER = '[Map] SelectOverlayLayers';
|
||||
export const ZOOMTOEXTENT = '[Map] ZoomToExtent';
|
||||
export const DOQUERY = '[Map] DoQuery';
|
||||
export const SETSTYLE = '[Map] SetStyle';
|
||||
|
||||
export class SetState implements Action {
|
||||
readonly type = SETSTATE;
|
||||
@ -204,6 +204,12 @@ export class DoQuery implements Action {
|
||||
constructor(public query:IQueryState) { }
|
||||
}
|
||||
|
||||
export class SetStyle implements Action {
|
||||
readonly type = SETSTYLE;
|
||||
|
||||
constructor(public itemType:string,public style:Style) { }
|
||||
}
|
||||
|
||||
export type Actions = SetMapState
|
||||
| Init
|
||||
| SetParent
|
||||
@ -231,5 +237,6 @@ export type Actions = SetMapState
|
||||
| ZoomToExtent
|
||||
| SetState
|
||||
| SetViewExtent
|
||||
| DoQuery;
|
||||
| DoQuery
|
||||
| SetStyle;
|
||||
|
||||
|
@ -58,6 +58,7 @@ import { MapRoutingModule } from './common-map-routing.module';
|
||||
import { LegendComponent } from './components/legend/legend.component';
|
||||
import { LayerVectorImageComponent } from './components/aol/layer-vector-image/layer-vector-image.component';
|
||||
import { StateSerializerService } from './services/state-serializer.service';
|
||||
import {FeatureIconService} from './services/feature-icon.service';
|
||||
import { GeolocationService } from './services/geolocation.service';
|
||||
import {DeviceOrientationService} from './services/device-orientation.service';
|
||||
import { WidgetStatusComponent } from './components/widget-status/widget-status.component';
|
||||
@ -131,6 +132,7 @@ export {
|
||||
AbstractItemListItemComponent,
|
||||
AbstractItemListComponent,
|
||||
StateSerializerService,
|
||||
FeatureIconService,
|
||||
GeolocationService,
|
||||
DeviceOrientationService,
|
||||
IMapState,
|
||||
@ -249,6 +251,7 @@ export class AppCommonMapModule {
|
||||
ngModule: AppCommonMapModule,
|
||||
providers: [
|
||||
StateSerializerService,
|
||||
FeatureIconService,
|
||||
GeolocationService,
|
||||
DeviceOrientationService,
|
||||
{ provide: AbstractFeatureListComponent, useClass: FeatureListCroppingschemeComponent, multi: true },
|
||||
|
@ -14,6 +14,8 @@ import {Vector,Cluster} from 'ol/source';
|
||||
import {Layer} from 'ol/layer';
|
||||
import {GeoJSON} from 'ol/format';
|
||||
import {Select} from 'ol/interaction';
|
||||
import {IStyleCache} from '../../../models/style.cache';
|
||||
import {FeatureIconService} from '../../../services/feature-icon.service';
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-item-source-vector',
|
||||
@ -32,40 +34,9 @@ export class ItemVectorSourceComponent extends SourceVectorComponent implements
|
||||
@Input() selectedFeature: Feature;
|
||||
@Input() selectedItem: IItem;
|
||||
@Output() onFeaturesSelected: EventEmitter<Feature> = new EventEmitter<Feature>();
|
||||
private styleCache = {
|
||||
'file': new style.Style({
|
||||
image: new style.Icon({
|
||||
anchor: [0.5, 1],
|
||||
scale: 0.05,
|
||||
src: this.getIconImageDataUrl("fa fa-file-o")
|
||||
}),
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
width: 1
|
||||
}),
|
||||
fill: new style.Fill({
|
||||
color: 'rgba(0, 0, 255, 0.1)'
|
||||
}),
|
||||
geometry: (feature) => this.geometry(feature)
|
||||
}),
|
||||
'selected': new style.Style({
|
||||
image: new style.Icon({
|
||||
anchor: [0.5, 1],
|
||||
scale: 0.08,
|
||||
src: this.getIconImageDataUrl(null)
|
||||
}),
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
width: 3
|
||||
}),
|
||||
fill: new style.Fill({
|
||||
color: 'rgba(0, 0, 255, 0.1)'
|
||||
}),
|
||||
geometry: (feature) => this.geometry(feature)
|
||||
})
|
||||
};
|
||||
private styleCache:IStyleCache = {};
|
||||
|
||||
constructor(@Host() private layer: LayerVectorComponent, private itemService: ItemService, @Host() private map: MapComponent, private itemTypeService: ItemTypeService) {
|
||||
constructor(@Host() private layer: LayerVectorComponent, private itemService: ItemService, @Host() private map: MapComponent, private itemTypeService: ItemTypeService,private featureIconService$:FeatureIconService) {
|
||||
super(layer);
|
||||
this._format = new GeoJSON();
|
||||
}
|
||||
@ -82,38 +53,6 @@ export class ItemVectorSourceComponent extends SourceVectorComponent implements
|
||||
return geometry;
|
||||
}
|
||||
|
||||
getIconImageDataUrl(iconClass:string, backgroundColor: string = "#c80a6e",color:string = "#ffffff"): string {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 365;
|
||||
canvas.height = 560;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.lineWidth = 6;
|
||||
ctx.fillStyle = backgroundColor;
|
||||
ctx.strokeStyle = "#000000";
|
||||
var path = new Path2D("m182.9 551.7c0 0.1 0.2 0.3 0.2 0.3s175.2-269 175.2-357.4c0-130.1-88.8-186.7-175.4-186.9-86.6 0.2-175.4 56.8-175.4 186.9 0 88.4 175.3 357.4 175.3 357.4z");
|
||||
ctx.fill(path)
|
||||
|
||||
var iconCharacter = "";
|
||||
if (iconClass != null) {
|
||||
var element = document.createElement("i");
|
||||
element.style.display = "none";
|
||||
element.className = iconClass;
|
||||
document.body.appendChild(element);
|
||||
iconCharacter = getComputedStyle(element, "::before").content.replace(/"/g, '');
|
||||
let iconFont = "200px " +getComputedStyle(element, "::before").fontFamily
|
||||
document.body.removeChild(element);
|
||||
ctx.strokeStyle = color;
|
||||
ctx.fillStyle = color;
|
||||
ctx.lineWidth = 15;
|
||||
ctx.font = iconFont;
|
||||
var ts = ctx.measureText(iconCharacter);
|
||||
ctx.fillText(iconCharacter, 182.9 - (ts.width / 2), 250);
|
||||
ctx.strokeText(iconCharacter, 182.9 - (ts.width / 2), 250);
|
||||
}
|
||||
|
||||
return canvas.toDataURL();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.strategy = loadingstrategy.bbox;
|
||||
this.format = new GeoJSON();
|
||||
@ -157,7 +96,7 @@ export class ItemVectorSourceComponent extends SourceVectorComponent implements
|
||||
image: itemType.icon ? new style.Icon({
|
||||
anchor: [0.5, 1],
|
||||
scale: 0.05,
|
||||
src: this.getIconImageDataUrl(itemType.icon)
|
||||
src: this.featureIconService$.getIconImageDataUrl(itemType.icon)
|
||||
}):null,
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
@ -166,13 +105,13 @@ export class ItemVectorSourceComponent extends SourceVectorComponent implements
|
||||
fill: new style.Fill({
|
||||
color: fillColor
|
||||
}),
|
||||
geometry: (feature) => this.geometry(feature)
|
||||
});
|
||||
} else {
|
||||
key = 'file';
|
||||
}
|
||||
}
|
||||
var styleEntry = this.styleCache[key];
|
||||
styleEntry.geometry = (feature) => this.geometry(feature);
|
||||
return styleEntry;
|
||||
});
|
||||
}
|
||||
|
@ -19,10 +19,15 @@ import {commonReducers} from '@farmmaps/common';
|
||||
|
||||
import {commonActions} from '@farmmaps/common';
|
||||
|
||||
import { IListItem, IItem } from '@farmmaps/common';
|
||||
import { IItem } from '@farmmaps/common';
|
||||
import { FolderService, ItemService } from '@farmmaps/common';
|
||||
import { tassign } from 'tassign';
|
||||
|
||||
import {FeatureIconService} from '../services/feature-icon.service';
|
||||
|
||||
import * as style from 'ol/style';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class MapEffects {
|
||||
private _geojsonFormat: GeoJSON;
|
||||
@ -44,10 +49,41 @@ export class MapEffects {
|
||||
ofType(mapActions.INIT),
|
||||
withLatestFrom(this.store$.select(commonReducers.selectGetRootItems)),
|
||||
switchMap(([action, rootItems]) => {
|
||||
let actions=[];
|
||||
for (let rootItem of rootItems) {
|
||||
if (rootItem.itemType == "UPLOADS_FOLDER") return of(new mapActions.SetParent(rootItem.code));
|
||||
if (rootItem.itemType == "UPLOADS_FOLDER") actions.push(new mapActions.SetParent(rootItem.code));
|
||||
}
|
||||
return [];
|
||||
// initialize default feature styles
|
||||
actions.push(new mapActions.SetStyle('file',new style.Style({
|
||||
image: new style.Icon({
|
||||
anchor: [0.5, 1],
|
||||
scale: 0.05,
|
||||
src: this.featureIconService$.getIconImageDataUrl("fa fa-file-o")
|
||||
}),
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
width: 1
|
||||
}),
|
||||
fill: new style.Fill({
|
||||
color: 'rgba(0, 0, 255, 0.1)'
|
||||
})
|
||||
})));
|
||||
actions.push(new mapActions.SetStyle('selected',new style.Style({
|
||||
image: new style.Icon({
|
||||
anchor: [0.5, 1],
|
||||
scale: 0.08,
|
||||
src: this.featureIconService$.getIconImageDataUrl(null)
|
||||
}),
|
||||
stroke: new style.Stroke({
|
||||
color: 'red',
|
||||
width: 3
|
||||
}),
|
||||
fill: new style.Fill({
|
||||
color: 'rgba(0, 0, 255, 0.1)'
|
||||
})
|
||||
})));
|
||||
|
||||
return actions;
|
||||
}
|
||||
));
|
||||
|
||||
@ -231,7 +267,7 @@ export class MapEffects {
|
||||
return of(newAction);
|
||||
}));
|
||||
|
||||
constructor(private actions$: Actions, private store$: Store<mapReducers.State>, private folderService$: FolderService, private itemService$: ItemService) {
|
||||
constructor(private actions$: Actions, private store$: Store<mapReducers.State>, private folderService$: FolderService, private itemService$: ItemService,private featureIconService$:FeatureIconService) {
|
||||
this._geojsonFormat = new GeoJSON();
|
||||
this._wktFormat = new WKT();
|
||||
}
|
||||
|
5
projects/common-map/src/fm-map/models/style.cache.ts
Normal file
5
projects/common-map/src/fm-map/models/style.cache.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import {Style} from 'ol';
|
||||
|
||||
export interface IStyleCache{
|
||||
[id: string]: Style;
|
||||
};
|
@ -4,6 +4,7 @@ import { IItemLayer,ItemLayer} from '../models/item.layer';
|
||||
import { IMapState} from '../models/map.state';
|
||||
import { IQueryState} from '../models/query.state';
|
||||
import { IPeriodState} from '../models/period.state';
|
||||
import { IStyleCache} from '../models/style.cache';
|
||||
import * as mapActions from '../actions/map.actions';
|
||||
import {commonActions} from '@farmmaps/common';
|
||||
import { createSelector, createFeatureSelector } from '@ngrx/store';
|
||||
@ -51,7 +52,8 @@ export interface State {
|
||||
selectedItemLayer: IItemLayer,
|
||||
projection: string,
|
||||
selectedBaseLayer: IItemLayer,
|
||||
selectedOverlayLayer: IItemLayer
|
||||
selectedOverlayLayer: IItemLayer,
|
||||
styleCache:IStyleCache
|
||||
}
|
||||
|
||||
export const initialState: State = {
|
||||
@ -84,7 +86,8 @@ export const initialState: State = {
|
||||
projection: "EPSG:3857",
|
||||
selectedBaseLayer: null,
|
||||
selectedOverlayLayer: null,
|
||||
selectedItemLayer: null
|
||||
selectedItemLayer: null,
|
||||
styleCache: {}
|
||||
}
|
||||
|
||||
export function reducer(state = initialState, action: mapActions.Actions | commonActions.Actions | RouterNavigationAction): State {
|
||||
@ -310,6 +313,12 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
|
||||
return tassign(state, {});
|
||||
}
|
||||
}
|
||||
case mapActions.SETSTYLE:{
|
||||
let a = action as mapActions.SetStyle;
|
||||
let styles = state.styleCache;
|
||||
styles[a.itemType] = a.style;
|
||||
return tassign(state,{styleCache:styles});
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
import { Injectable} from '@angular/core';
|
||||
import { Feature } from 'ol';
|
||||
import { Point } from 'ol/geom';
|
||||
import * as extent from 'ol/extent';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class FeatureIconService {
|
||||
|
||||
getIconImageDataUrl(iconClass:string, backgroundColor: string = "#c80a6e",color:string = "#ffffff"): string {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 365;
|
||||
canvas.height = 560;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.lineWidth = 6;
|
||||
ctx.fillStyle = backgroundColor;
|
||||
ctx.strokeStyle = "#000000";
|
||||
var path = new Path2D("m182.9 551.7c0 0.1 0.2 0.3 0.2 0.3s175.2-269 175.2-357.4c0-130.1-88.8-186.7-175.4-186.9-86.6 0.2-175.4 56.8-175.4 186.9 0 88.4 175.3 357.4 175.3 357.4z");
|
||||
ctx.fill(path)
|
||||
|
||||
var iconCharacter = "";
|
||||
if (iconClass != null) {
|
||||
var element = document.createElement("i");
|
||||
element.style.display = "none";
|
||||
element.className = iconClass;
|
||||
document.body.appendChild(element);
|
||||
iconCharacter = getComputedStyle(element, "::before").content.replace(/"/g, '');
|
||||
let iconFont = "200px " +getComputedStyle(element, "::before").fontFamily
|
||||
document.body.removeChild(element);
|
||||
ctx.strokeStyle = color;
|
||||
ctx.fillStyle = color;
|
||||
ctx.lineWidth = 15;
|
||||
ctx.font = iconFont;
|
||||
var ts = ctx.measureText(iconCharacter);
|
||||
ctx.fillText(iconCharacter, 182.9 - (ts.width / 2), 250);
|
||||
ctx.strokeText(iconCharacter, 182.9 - (ts.width / 2), 250);
|
||||
}
|
||||
|
||||
return canvas.toDataURL();
|
||||
}
|
||||
}
|
@ -4,9 +4,7 @@ import {IItem} from '../models/item'
|
||||
import {AppConfig} from '../shared/app.config';
|
||||
import {HttpClient, HttpXhrBackend} from '@angular/common/http';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
@Injectable()
|
||||
export class ItemTypeService {
|
||||
public itemTypes: IItemTypes;
|
||||
private httpClient: HttpClient;
|
||||
@ -15,10 +13,6 @@ export class ItemTypeService {
|
||||
this.httpClient = new HttpClient(xhrBackend);
|
||||
}
|
||||
|
||||
// itemService.getItemTypes().subscribe((itemTypes) => {
|
||||
// this.itemTypes = itemTypes;
|
||||
// });
|
||||
|
||||
getIcon(itemType: string) {
|
||||
var icon = "fa fa-file-o";
|
||||
if (this.itemTypes[itemType]) icon = this.itemTypes[itemType].icon;
|
||||
|
Loading…
Reference in New Issue
Block a user