Browse Source

Image map fixes and improvements. Fixed state chart subscription.

pull/2929/head
Igor Kulikov 6 years ago
parent
commit
b86c5e61e1
  1. 2
      ui-ngx/src/app/core/api/datasource-subcription.ts
  2. 8
      ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts
  3. 6
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts
  4. 67
      ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts
  5. 5
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts
  6. 5
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/here-map.ts
  7. 108
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts
  8. 5
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts
  9. 5
      ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/tencent-map.ts

2
ui-ngx/src/app/core/api/datasource-subcription.ts

@ -314,7 +314,7 @@ export class DatasourceSubscription {
}); });
stateDataReceived = true; stateDataReceived = true;
} else { } else {
firstStateData = data; firstStateData = subscriptionUpdate;
} }
} else { } else {
if (subsTw.aggregation.stateData && !stateDataReceived) { if (subsTw.aggregation.stateData && !stateDataReceived) {

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

@ -33,6 +33,7 @@ import { filter } from 'rxjs/operators';
import { Polyline } from './polyline'; import { Polyline } from './polyline';
import { Polygon } from './polygon'; import { Polygon } from './polygon';
import { createTooltip, safeExecute } from '@home/components/widget/lib/maps/maps-utils'; import { createTooltip, safeExecute } from '@home/components/widget/lib/maps/maps-utils';
import { WidgetContext } from '@home/models/widget-component.models';
export default abstract class LeafletMap { export default abstract class LeafletMap {
@ -49,7 +50,9 @@ export default abstract class LeafletMap {
points: FeatureGroup; points: FeatureGroup;
markersData: FormattedData[] = []; markersData: FormattedData[] = [];
protected constructor(public $container: HTMLElement, options: UnitedMapSettings) { protected constructor(public ctx: WidgetContext,
public $container: HTMLElement,
options: UnitedMapSettings) {
this.options = options; this.options = options;
} }
@ -341,9 +344,6 @@ export default abstract class LeafletMap {
}); });
} }
setImageAlias(alias: Observable<any>) {
}
// Polyline // Polyline
updatePolylines(polyData: FormattedData[][], data?: FormattedData) { updatePolylines(polyData: FormattedData[][], data?: FormattedData) {

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

@ -165,6 +165,12 @@ export interface HistorySelectSettings {
buttonColor: string; buttonColor: string;
} }
export interface MapImage {
imageUrl: string;
aspect: number;
update?: boolean;
}
export type TripAnimationSettings = { export type TripAnimationSettings = {
showPoints: boolean; showPoints: boolean;
pointColor: string; pointColor: string;

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

@ -17,26 +17,18 @@
import { defaultSettings, hereProviders, MapProviders, providerSets, UnitedMapSettings } from './map-models'; import { defaultSettings, hereProviders, MapProviders, providerSets, UnitedMapSettings } from './map-models';
import LeafletMap from './leaflet-map'; import LeafletMap from './leaflet-map';
import { import {
commonMapSettingsSchema, commonMapSettingsSchema,
mapPolygonSchema, mapPolygonSchema,
mapProviderSchema, mapProviderSchema,
markerClusteringSettingsSchema, markerClusteringSettingsSchema,
markerClusteringSettingsSchemaLeaflet, markerClusteringSettingsSchemaLeaflet,
routeMapSettingsSchema routeMapSettingsSchema
} from './schemes'; } from './schemes';
import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface';
import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils';
import { of, Subject } from 'rxjs';
import { WidgetContext } from '@app/modules/home/models/widget-component.models'; import { WidgetContext } from '@app/modules/home/models/widget-component.models';
import { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils'; import { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils';
import { import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models';
Datasource,
DatasourceType,
JsonSettingsSchema,
WidgetActionDescriptor,
widgetType,
DatasourceData
} from '@shared/models/widget.models';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models';
import { AttributeService } from '@core/http/attribute.service'; import { AttributeService } from '@core/http/attribute.service';
@ -76,8 +68,7 @@ export class MapWidgetController implements MapWidgetInterface {
return; return;
} }
parseWithTranslation.setTranslate(this.translate); parseWithTranslation.setTranslate(this.translate);
this.map = new MapClass($element, this.settings, this.ctx.$injector); this.map = new MapClass(this.ctx, $element, this.settings, this.ctx.$injector);
this.map.setImageAlias(this.subscribeForImageAttribute());
this.map.saveMarkerLocation = this.setMarkerLocation; this.map.saveMarkerLocation = this.setMarkerLocation;
if (this.settings.draggableMarker) { if (this.settings.draggableMarker) {
this.map.setDataSources(parseData(this.data)); this.map.setDataSources(parseData(this.data));
@ -263,48 +254,6 @@ export class MapWidgetController implements MapWidgetInterface {
this.map.onResize(); this.map.onResize();
} }
subscribeForImageAttribute() {
const imageEntityAlias = this.settings.imageEntityAlias;
const imageUrlAttribute = this.settings.imageUrlAttribute;
if (!imageEntityAlias || !imageUrlAttribute) {
return of(false);
}
const entityAliasId = this.ctx.aliasController.getEntityAliasId(imageEntityAlias);
if (!entityAliasId) {
return of(false);
}
const datasources = [
{
type: DatasourceType.entity,
name: imageEntityAlias,
aliasName: imageEntityAlias,
entityAliasId,
dataKeys: [
{
type: DataKeyType.attribute,
name: imageUrlAttribute,
label: imageUrlAttribute,
settings: {},
_hash: Math.random()
}
]
}
];
const result = new Subject();
const imageUrlSubscriptionOptions = {
datasources,
useDashboardTimewindow: false,
type: widgetType.latest,
callbacks: {
onDataUpdated: (subscription) => {
result.next(subscription?.data[0]?.data[0]);
}
}
};
this.ctx.subscriptionApi.createSubscription(imageUrlSubscriptionOptions, true).subscribe(() => { });
return result;
}
onDestroy() { onDestroy() {
} }
} }

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

@ -21,6 +21,7 @@ import { UnitedMapSettings } from '../map-models';
import 'leaflet.gridlayer.googlemutant'; import 'leaflet.gridlayer.googlemutant';
import { ResourcesService } from '@core/services/resources.service'; import { ResourcesService } from '@core/services/resources.service';
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { WidgetContext } from '@home/models/widget-component.models';
const gmGlobals: GmGlobal = {}; const gmGlobals: GmGlobal = {};
@ -31,8 +32,8 @@ interface GmGlobal {
export class GoogleMap extends LeafletMap { export class GoogleMap extends LeafletMap {
private resource: ResourcesService; private resource: ResourcesService;
constructor($container, options: UnitedMapSettings, private injector: Injector) { constructor(ctx: WidgetContext, $container, options: UnitedMapSettings, private injector: Injector) {
super($container, options); super(ctx, $container, options);
this.resource = injector.get(ResourcesService); this.resource = injector.get(ResourcesService);
this.loadGoogle(() => { this.loadGoogle(() => {
const map = L.map($container, {attributionControl: false}).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); const map = L.map($container, {attributionControl: false}).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);

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

@ -17,10 +17,11 @@
import L from 'leaflet'; import L from 'leaflet';
import LeafletMap from '../leaflet-map'; import LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models'; import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class HEREMap extends LeafletMap { export class HEREMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) { constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super($container, options); super(ctx, $container, options);
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
const tileLayer = (L.tileLayer as any).provider(options.mapProviderHere || 'HERE.normalDay', options.credentials); const tileLayer = (L.tileLayer as any).provider(options.mapProviderHere || 'HERE.normalDay', options.credentials);
tileLayer.addTo(map); tileLayer.addTo(map);

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

@ -14,12 +14,16 @@
/// limitations under the License. /// limitations under the License.
/// ///
import L, { LatLngLiteral, LatLngBounds, LatLngTuple } from 'leaflet'; import L, { LatLngBounds, LatLngLiteral, LatLngTuple } from 'leaflet';
import LeafletMap from '../leaflet-map'; import LeafletMap from '../leaflet-map';
import { UnitedMapSettings, PosFuncton } from '../map-models'; import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models';
import { Observable } from 'rxjs'; import { Observable, ReplaySubject } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators'; import { filter, map, mergeMap } from 'rxjs/operators';
import { aspectCache, calculateNewPointCoordinate, parseFunction } from '@home/components/widget/lib/maps/maps-utils'; import { aspectCache, calculateNewPointCoordinate, parseFunction } from '@home/components/widget/lib/maps/maps-utils';
import { WidgetContext } from '@home/models/widget-component.models';
import { DataSet, DatasourceType, widgetType } from '@shared/models/widget.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { WidgetSubscriptionOptions } from '@core/api/widget-api.models';
const maxZoom = 4;// ? const maxZoom = 4;// ?
@ -32,26 +36,96 @@ export class ImageMap extends LeafletMap {
imageUrl: string; imageUrl: string;
posFunction: PosFuncton; posFunction: PosFuncton;
constructor($container: HTMLElement, options: UnitedMapSettings) { constructor(ctx: WidgetContext, $container: HTMLElement, options: UnitedMapSettings) {
super($container, options); super(ctx, $container, options);
this.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as PosFuncton; this.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as PosFuncton;
this.imageUrl = options.mapUrl; this.mapImage(options).subscribe((mapImage) => {
aspectCache(this.imageUrl).subscribe(aspect => { this.imageUrl = mapImage.imageUrl;
this.aspect = aspect; this.aspect = mapImage.aspect;
if (mapImage.update) {
this.onResize(true);
} else {
this.onResize(); this.onResize();
super.setMap(this.map); super.setMap(this.map);
super.initSettings(options); super.initSettings(options);
}
}); });
} }
setImageAlias(alias: Observable<any>) { private mapImage(options: UnitedMapSettings): Observable<MapImage> {
alias.pipe(filter(result => result), map(el => el[1]), switchMap(res => { const imageEntityAlias = options.imageEntityAlias;
this.imageUrl = res; const imageUrlAttribute = options.imageUrlAttribute;
return aspectCache(res); if (!imageEntityAlias || !imageUrlAttribute) {
})).subscribe(aspect => { return this.imageFromUrl(options.mapUrl);
this.aspect = aspect; }
this.onResize(true); const entityAliasId = this.ctx.aliasController.getEntityAliasId(imageEntityAlias);
}); if (!entityAliasId) {
return this.imageFromUrl(options.mapUrl);
}
const datasources = [
{
type: DatasourceType.entity,
name: imageEntityAlias,
aliasName: imageEntityAlias,
entityAliasId,
dataKeys: [
{
type: DataKeyType.attribute,
name: imageUrlAttribute,
label: imageUrlAttribute,
settings: {},
_hash: Math.random()
}
]
}
];
const result = new ReplaySubject<[DataSet, boolean]>();
let isUpdate = false;
const imageUrlSubscriptionOptions: WidgetSubscriptionOptions = {
datasources,
useDashboardTimewindow: false,
type: widgetType.latest,
callbacks: {
onDataUpdated: (subscription) => {
result.next([subscription.data[0]?.data, isUpdate]);
isUpdate = true;
}
}
};
this.ctx.subscriptionApi.createSubscription(imageUrlSubscriptionOptions, true).subscribe(() => { });
return this.imageFromAlias(result);
}
private imageFromUrl(url: string): Observable<MapImage> {
return aspectCache(url).pipe(
map( aspect => {
const mapImage: MapImage = {
imageUrl: url,
aspect,
update: false
};
return mapImage;
}
));
}
private imageFromAlias(alias: Observable<[DataSet, boolean]>): Observable<MapImage> {
return alias.pipe(
filter(result => result[0].length > 0),
mergeMap(res => {
const mapImage: MapImage = {
imageUrl: res[0][0][1],
aspect: null,
update: res[1]
};
return aspectCache(mapImage.imageUrl).pipe(
map((aspect) => {
mapImage.aspect = aspect;
return mapImage;
}
));
})
);
} }
updateBounds(updateImage?: boolean, lastCenterPos?) { updateBounds(updateImage?: boolean, lastCenterPos?) {

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

@ -17,10 +17,11 @@
import L from 'leaflet'; import L from 'leaflet';
import LeafletMap from '../leaflet-map'; import LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models'; import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class OpenStreetMap extends LeafletMap { export class OpenStreetMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) { constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super($container, options); super(ctx, $container, options);
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
let tileLayer; let tileLayer;
if (options.useCustomProvider) if (options.useCustomProvider)

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

@ -18,10 +18,11 @@
import L from 'leaflet'; import L from 'leaflet';
import LeafletMap from '../leaflet-map'; import LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models'; import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class TencentMap extends LeafletMap { export class TencentMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) { constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super($container, options); super(ctx, $container, options);
const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0'; const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0';
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
const txLayer = L.tileLayer(txUrl, { const txLayer = L.tileLayer(txUrl, {

Loading…
Cancel
Save