Browse Source

data update & polyline support

pull/2535/head
Artem Halushko 6 years ago
parent
commit
f6ca099613
  1. 5
      ui-ngx/package-lock.json
  2. 1
      ui-ngx/package.json
  3. 22
      ui-ngx/src/app/core/utils.ts
  4. 61
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  5. 8
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts
  6. 1
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts
  7. 80
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts
  8. 24
      ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts
  9. 9
      ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts
  10. 3
      ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts
  11. 10
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts
  12. 1
      ui-ngx/tsconfig.json

5
ui-ngx/package-lock.json

@ -1897,6 +1897,11 @@
"@types/geojson": "7946.0.7"
}
},
"@types/lodash": {
"version": "4.14.149",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
"integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ=="
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",

1
ui-ngx/package.json

@ -38,6 +38,7 @@
"@ngx-share/core": "^7.1.4",
"@ngx-translate/core": "^12.1.1",
"@ngx-translate/http-loader": "^4.0.0",
"@types/lodash": "^4.14.149",
"ace-builds": "^1.4.8",
"angular-gridster2": "^9.0.1",
"angular2-hotkeys": "^2.1.5",

22
ui-ngx/src/app/core/utils.ts

@ -101,7 +101,7 @@ export function isNumber(value: any): boolean {
}
export function isNumeric(value: any): boolean {
return (value - parseFloat( value ) + 1) >= 0;
return (value - parseFloat(value) + 1) >= 0;
}
export function isString(value: any): boolean {
@ -226,9 +226,9 @@ function hashCode(str) {
var i, char;
if (str.length == 0) return hash;
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
@ -424,24 +424,24 @@ export function getDescendantProp(obj: any, path: string): any {
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
}
export function imageLoader(imageUrl: string): Observable<HTMLImageElement>{
export function imageLoader(imageUrl: string): Observable<HTMLImageElement> {
const image = new Image();
const imageLoad$ = fromEvent(image, 'load').pipe(map(event=>image));
const imageLoad$ = fromEvent(image, 'load').pipe(map(event => image));
image.src = imageUrl;
return imageLoad$;
}
const imageAspectMap = {};
export function aspectCache(imageUrl: string): Observable<number>{
if(imageUrl?.length){
export function aspectCache(imageUrl: string): Observable<number> {
if (imageUrl?.length) {
const hash = hashCode(imageUrl);
let aspect = imageAspectMap[hash];
if(aspect){
if (aspect) {
return of(aspect);
}
else return imageLoader(imageUrl).pipe(map(image=>{
aspect = image.width/image.height;
else return imageLoader(imageUrl).pipe(map(image => {
aspect = image.width / image.height;
imageAspectMap[hash] = aspect;
return aspect;
}))

61
ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts

@ -9,11 +9,13 @@ import { MapOptions, MarkerSettings } from './map-models';
import { Marker } from './markers';
import { Observable, of, BehaviorSubject, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { Polyline } from './polyline';
export default class LeafletMap {
export default abstract class LeafletMap {
markers = [];
markers: Map<string, Marker> = new Map();
tooltips = [];
poly: Polyline;
map: L.Map;
map$: BehaviorSubject<L.Map> = new BehaviorSubject(null);
ready$: Observable<L.Map> = this.map$.pipe(filter(map => !!map));
@ -22,6 +24,7 @@ export default class LeafletMap {
constructor($container: HTMLElement, options: MapOptions) {
console.log("LeafletMap -> constructor -> options", options)
this.options = options;
}
@ -123,29 +126,69 @@ export default class LeafletMap {
return this.map.getCenter();
}
convertPosition(expression: L.LatLngExpression | { x, y }): L.LatLngExpression {
return expression as L.LatLngExpression;
convertPosition(expression: any): L.LatLng {
return L.latLng(expression[this.options.latKeyName], expression[this.options.lngKeyName]) as L.LatLng;
}
////Markers
updateMarkers(markersData) {
markersData.forEach(data => {
if (this.markers.get(data.aliasName)) {
this.updateMarker(data.aliasName, this.convertPosition(data), this.options as MarkerSettings)
}
else {
this.createMarker(data.aliasName, this.convertPosition(data), this.options as MarkerSettings);
}
});
}
createMarker(location, settings: MarkerSettings) {
private createMarker(key, location, settings: MarkerSettings) {
this.ready$.subscribe(() => {
let defaultSettings: MarkerSettings = {
color: '#FD2785'
}
this.markers.push(new Marker(this.map, this.convertPosition(location), { ...defaultSettings, ...settings }))
this.markers.set(key, new Marker(this.map, location, { ...defaultSettings, ...settings }))
});
}
updateMarker() {
private updateMarker(key, location: L.LatLng, settings: MarkerSettings) {
const marker: Marker = this.markers.get(key);
if (!location.equals(marker.location)) {
marker.updateMarkerPosition(location);
}
//other implements later
}
deleteMarker() {
private deleteMarker() {
}
//polyline
updatePolylines(polyData) {
if (this.poly) {
}
else {
this.map$
this.createPolyline(polyData.map(data => this.convertPosition(data)), this.options);
}
/* markersData.forEach(data => {
if (this.markers.get(data.aliasName)) {
this.updateMarker(data.aliasName, this.convertPosition(data), this.options as MarkerSettings)
}
else {
this.createMarker(data.aliasName, this.convertPosition(data), this.options as MarkerSettings);
}
});*/
}
createPolyline(locations, settings) {
this.ready$.subscribe(() =>
this.poly = new Polyline(this.map, locations, settings)
)
}
}

8
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts

@ -4,6 +4,10 @@ export interface MapOptions {
dontFitMapBounds?: boolean,
disableScrollZooming?: boolean,
minZoomLevel?: number,
latKeyName?: string,
lngKeyName?: string,
xPosKeyName?: string,
yPosKeyName?: string,
mapProvider: MapProviders,
mapUrl?: string;
credentials?: any, // declare credentials format
@ -19,9 +23,9 @@ export enum MapProviders {
tencent = 'tencent-map'
}
export interface MarkerSettings{
export interface MarkerSettings {
showLabel?: boolean,
draggable?: boolean,
displayTooltip?: boolean,
color: string
color?: string
}

1
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts

@ -1,5 +1,6 @@
export interface MapWidgetInterface {
resize(),
update(),
onInit(),
onDataUpdated();
onResize();

80
ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts

@ -13,44 +13,21 @@ import {
} from './schemes';
import { MapWidgetStaticInterface, MapWidgetInterface } from './map-widget.interface';
import { OpenStreetMap, TencentMap, GoogleMap, HEREMap, ImageMap } from './providers';
const providerSets = {
'openstreet-map': {
MapClass: OpenStreetMap,
schema: openstreetMapSettingsSchema,
name: "Openstreet"
},
'tencent-map': {
MapClass: TencentMap,
schema: tencentMapSettingsSchema,
name: "Tencent"
},
'google-map': {
MapClass: GoogleMap,
schema: googleMapSettingsSchema,
name: "Openstreet"
},
'here': {
MapClass: HEREMap,
schema: hereMapSettingsSchema,
name: "HERE"
},
'image-map': {
MapClass: ImageMap,
schema: imageMapSettingsSchema
}
}
import { WidgetSubscription } from '@app/core/public-api';
import { parseData, parseArray } from './maps-utils';
export let TbMapWidgetV2: MapWidgetStaticInterface;
TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
map: LeafletMap;
provider: MapProviders;
schema;
data;
constructor(mapProvider: MapProviders, drawRoutes, ctx, $element) {
console.log(ctx.settings);
constructor(mapProvider: MapProviders, private drawRoutes, ctx, $element) {
console.log("TbMapWidgetV2 -> constructor -> ctx", ctx)
// console.log(ctx.subscriptions, ctx.data, ctx.datasources);
this.data = ctx.data;
//this.subsciptions.
if (!$element) {
$element = ctx.$container[0];
}
@ -71,17 +48,21 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
if (!MapClass) {
return;
}
this.map = new MapClass($element, { ...baseOptions, ...ctx.settings })
if(mapProvider !== "image-map")
this.map.createMarker({ lat: 0, lng: 0 }, { color: '#FD2785' })
else
this.map.createMarker({ x: 500, y: 500 }, { color: '#6D2785' });
this.map = new MapClass($element, { ...baseOptions, ...ctx.settings });
this.schema = providerSets[mapProvider]?.schema;
}
onInit() {
}
update() {
console.log(this.data,parseData(this.data) );
if (this.drawRoutes)
this.map.updatePolylines(parseArray(this.data));
this.map.updateMarkers(parseData(this.data));
}
onDataUpdated() {
}
@ -173,4 +154,31 @@ TbMapWidgetV2 = class TbMapWidgetV2 implements MapWidgetInterface {
onDestroy() {
}
}
const providerSets = {
'openstreet-map': {
MapClass: OpenStreetMap,
schema: openstreetMapSettingsSchema,
name: "Openstreet"
},
'tencent-map': {
MapClass: TencentMap,
schema: tencentMapSettingsSchema,
name: "Tencent"
},
'google-map': {
MapClass: GoogleMap,
schema: googleMapSettingsSchema,
name: "Openstreet"
},
'here': {
MapClass: HEREMap,
schema: hereMapSettingsSchema,
name: "HERE"
},
'image-map': {
MapClass: ImageMap,
schema: imageMapSettingsSchema
}
}

24
ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts

@ -1,4 +1,5 @@
import L from 'leaflet';
import _ from 'lodash';
export function createTooltip(target, settings, targetArgs?) {
var popup = L.popup();
@ -19,4 +20,27 @@ export function createTooltip(target, settings, targetArgs?) {
locationSettings: settings,
dsIndex: settings.dsIndex
};
}
export function parseArray(input: any[]): any[] {
let alliases: any = _(input).groupBy(el => el?.datasource?.aliasName).values().value();
return alliases.map(alliasArray =>
alliasArray[0].data.map((el, i) => {
const obj = { aliasName: alliasArray[0]?.datasource?.aliasName };
alliasArray.forEach(el => {
obj[el?.dataKey?.label] = el?.data[i][1]
});
return obj;
})
).flat();
}
export function parseData(input: any[]): any[] {
return _(input).groupBy(el => el?.datasource?.aliasName).values().value().map(alliasArray => {
const obj = { aliasName: alliasArray[0]?.datasource?.aliasName };
alliasArray.forEach(el => {
obj[el?.dataKey?.label] = el?.data[0][1]
});
return obj;
});
}

9
ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts

@ -7,13 +7,14 @@ import { aspectCache } from '@app/core/utils';
export class Marker {
leafletMarker: L.Marker;
// map: L.Map;
tooltipOffset;
tooltip;
location;
constructor(private map: L.Map, location: L.LatLngExpression, settings: MarkerSettings, onClickListener?, markerArgs?, onDragendListener?) {
//this.map = map;
this.location = location;
this.leafletMarker = L.marker(location, {
draggable: settings.draggable
});
@ -43,6 +44,10 @@ export class Marker {
}
updateMarkerPosition(position: L.LatLngExpression){
this.leafletMarker.setLatLng(position);
}
updateMarkerLabel(settings) {
this.leafletMarker.unbindTooltip();
if (settings.showLabel)
@ -56,7 +61,7 @@ export class Marker {
});
}
updateMarkerIcon( settings) {
updateMarkerIcon(settings) {
this.createMarkerIcon(settings, (iconInfo) => {
this.leafletMarker.setIcon(iconInfo.icon);
if (settings.showLabel) {

3
ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts

@ -2,10 +2,9 @@ import L from 'leaflet';
export class Polyline {
map: L.Map;
leafletPoly: L.Polyline;
constructor(locations, settings) {
constructor(private map: L.Map, locations, settings) {
this.leafletPoly = L.polyline(locations,
{
color: settings.color,

10
ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts

@ -101,13 +101,13 @@ export class ImageMap extends LeafletMap {
}
}
convertPosition(expression: { x, y }): L.LatLngExpression {
console.log("ImageMap -> expression", expression)
return this.pointToLatLng(expression.x, expression.y) as L.LatLngExpression;
convertPosition(expression): L.LatLng {
return this.pointToLatLng(
expression[this.options.xPosKeyName] * this.width,
expression[this.options.yPosKeyName] * this.height);
}
pointToLatLng(x, y) {
pointToLatLng(x, y): L.LatLng {
return L.CRS.Simple.pointToLatLng({ x, y } as L.PointExpression, maxZoom - 1);
}

1
ui-ngx/tsconfig.json

@ -33,6 +33,7 @@
},
"lib": [
"es2018",
"es2019",
"dom"
]
}

Loading…
Cancel
Save