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;
} else {
firstStateData = data;
firstStateData = subscriptionUpdate;
}
} else {
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 { Polygon } from './polygon';
import { createTooltip, safeExecute } from '@home/components/widget/lib/maps/maps-utils';
import { WidgetContext } from '@home/models/widget-component.models';
export default abstract class LeafletMap {
@ -49,7 +50,9 @@ export default abstract class LeafletMap {
points: FeatureGroup;
markersData: FormattedData[] = [];
protected constructor(public $container: HTMLElement, options: UnitedMapSettings) {
protected constructor(public ctx: WidgetContext,
public $container: HTMLElement,
options: UnitedMapSettings) {
this.options = options;
}
@ -341,9 +344,6 @@ export default abstract class LeafletMap {
});
}
setImageAlias(alias: Observable<any>) {
}
// Polyline
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;
}
export interface MapImage {
imageUrl: string;
aspect: number;
update?: boolean;
}
export type TripAnimationSettings = {
showPoints: boolean;
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 LeafletMap from './leaflet-map';
import {
commonMapSettingsSchema,
mapPolygonSchema,
mapProviderSchema,
markerClusteringSettingsSchema,
markerClusteringSettingsSchemaLeaflet,
routeMapSettingsSchema
commonMapSettingsSchema,
mapPolygonSchema,
mapProviderSchema,
markerClusteringSettingsSchema,
markerClusteringSettingsSchemaLeaflet,
routeMapSettingsSchema
} from './schemes';
import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface';
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 { getDefCenterPosition, parseArray, parseData, parseFunction, parseWithTranslation } from './maps-utils';
import {
Datasource,
DatasourceType,
JsonSettingsSchema,
WidgetActionDescriptor,
widgetType,
DatasourceData
} from '@shared/models/widget.models';
import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models';
import { EntityId } from '@shared/models/id/entity-id';
import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models';
import { AttributeService } from '@core/http/attribute.service';
@ -76,8 +68,7 @@ export class MapWidgetController implements MapWidgetInterface {
return;
}
parseWithTranslation.setTranslate(this.translate);
this.map = new MapClass($element, this.settings, this.ctx.$injector);
this.map.setImageAlias(this.subscribeForImageAttribute());
this.map = new MapClass(this.ctx, $element, this.settings, this.ctx.$injector);
this.map.saveMarkerLocation = this.setMarkerLocation;
if (this.settings.draggableMarker) {
this.map.setDataSources(parseData(this.data));
@ -263,48 +254,6 @@ export class MapWidgetController implements MapWidgetInterface {
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() {
}
}

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 { ResourcesService } from '@core/services/resources.service';
import { Injector } from '@angular/core';
import { WidgetContext } from '@home/models/widget-component.models';
const gmGlobals: GmGlobal = {};
@ -31,8 +32,8 @@ interface GmGlobal {
export class GoogleMap extends LeafletMap {
private resource: ResourcesService;
constructor($container, options: UnitedMapSettings, private injector: Injector) {
super($container, options);
constructor(ctx: WidgetContext, $container, options: UnitedMapSettings, private injector: Injector) {
super(ctx, $container, options);
this.resource = injector.get(ResourcesService);
this.loadGoogle(() => {
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 LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class HEREMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) {
super($container, options);
constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super(ctx, $container, options);
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
const tileLayer = (L.tileLayer as any).provider(options.mapProviderHere || 'HERE.normalDay', options.credentials);
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.
///
import L, { LatLngLiteral, LatLngBounds, LatLngTuple } from 'leaflet';
import L, { LatLngBounds, LatLngLiteral, LatLngTuple } from 'leaflet';
import LeafletMap from '../leaflet-map';
import { UnitedMapSettings, PosFuncton } from '../map-models';
import { Observable } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';
import { MapImage, PosFuncton, UnitedMapSettings } from '../map-models';
import { Observable, ReplaySubject } from 'rxjs';
import { filter, map, mergeMap } from 'rxjs/operators';
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;// ?
@ -32,26 +36,96 @@ export class ImageMap extends LeafletMap {
imageUrl: string;
posFunction: PosFuncton;
constructor($container: HTMLElement, options: UnitedMapSettings) {
super($container, options);
constructor(ctx: WidgetContext, $container: HTMLElement, options: UnitedMapSettings) {
super(ctx, $container, options);
this.posFunction = parseFunction(options.posFunction, ['origXPos', 'origYPos']) as PosFuncton;
this.imageUrl = options.mapUrl;
aspectCache(this.imageUrl).subscribe(aspect => {
this.aspect = aspect;
this.mapImage(options).subscribe((mapImage) => {
this.imageUrl = mapImage.imageUrl;
this.aspect = mapImage.aspect;
if (mapImage.update) {
this.onResize(true);
} else {
this.onResize();
super.setMap(this.map);
super.initSettings(options);
}
});
}
setImageAlias(alias: Observable<any>) {
alias.pipe(filter(result => result), map(el => el[1]), switchMap(res => {
this.imageUrl = res;
return aspectCache(res);
})).subscribe(aspect => {
this.aspect = aspect;
this.onResize(true);
});
private mapImage(options: UnitedMapSettings): Observable<MapImage> {
const imageEntityAlias = options.imageEntityAlias;
const imageUrlAttribute = options.imageUrlAttribute;
if (!imageEntityAlias || !imageUrlAttribute) {
return this.imageFromUrl(options.mapUrl);
}
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?) {

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

@ -17,10 +17,11 @@
import L from 'leaflet';
import LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class OpenStreetMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) {
super($container, options);
constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super(ctx, $container, options);
const map = L.map($container).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
let tileLayer;
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 LeafletMap from '../leaflet-map';
import { UnitedMapSettings } from '../map-models';
import { WidgetContext } from '@home/models/widget-component.models';
export class TencentMap extends LeafletMap {
constructor($container, options: UnitedMapSettings) {
super($container, options);
constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) {
super(ctx, $container, options);
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 txLayer = L.tileLayer(txUrl, {

Loading…
Cancel
Save