Map/3.0 (#2542)
* add base map infrastructure * add leaflet css * add tencent map * add google maps support * added image map support * refactor schemes * here maps support && WIP on markers * add simple marker suppor * data update & polyline support * map bouds support * add some settings support * add map provider select to settings * labels support * WIP on trip animation widget * WIP on history control and route interpolation * trip-animation map provider & custom markers * comleted track marker & history controls * add license headers * label fix & tooltips support * WIP on polygons * marker dropping support * add polygon support * add label to trip animation * WIP on tooltips * lint anf typed leaflet AddMarker * some typing and poly improvements * add typing * add marker creation * update proxy * save position fix * add bounds padding * update map widget bendle && bugfixes * update marker placement widget * add licenses * reomove log * fix sizes Co-authored-by: Artem Halushko <ahalushko@thingboards.io> Co-authored-by: Adsumus <artemtv42@gmail.com>
This commit is contained in:
parent
4f15a29e81
commit
56a23ab82a
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -186,7 +186,7 @@ export default abstract class LeafletMap {
|
|||||||
if (this.convertPosition(data)) {
|
if (this.convertPosition(data)) {
|
||||||
if (data.rotationAngle) {
|
if (data.rotationAngle) {
|
||||||
this.options.icon = L.divIcon({
|
this.options.icon = L.divIcon({
|
||||||
html: `<div class="arrow" style="transform: rotate(${data.rotationAngle}deg)"><div>`
|
html: `<div class="arrow" style="transform: translate(-10px, -10px) rotate(${data.rotationAngle}deg);"><div>`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -210,8 +210,8 @@ export default abstract class LeafletMap {
|
|||||||
private createMarker(key, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings, setFocus = true) {
|
private createMarker(key, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings, setFocus = true) {
|
||||||
this.ready$.subscribe(() => {
|
this.ready$.subscribe(() => {
|
||||||
const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources, () => { }, this.dragMarker);
|
const newMarker = new Marker(this.map, this.convertPosition(data), settings, data, dataSources, () => { }, this.dragMarker);
|
||||||
if (setFocus)
|
if (setFocus && settings.fitMapBounds)
|
||||||
this.map.fitBounds(this.bounds.extend(newMarker.leafletMarker.getLatLng()));
|
this.map.fitBounds(this.bounds.extend(newMarker.leafletMarker.getLatLng()).pad(0.2));
|
||||||
this.markers.set(key, newMarker);
|
this.markers.set(key, newMarker);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ export default abstract class LeafletMap {
|
|||||||
this.ready$.subscribe(() => {
|
this.ready$.subscribe(() => {
|
||||||
this.poly = new Polyline(this.map,
|
this.poly = new Polyline(this.map,
|
||||||
data.map(el => this.convertPosition(el)).filter(el => !!el), data, dataSources, settings);
|
data.map(el => this.convertPosition(el)).filter(el => !!el), data, dataSources, settings);
|
||||||
const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds());
|
const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds().pad(0.2));
|
||||||
if (bounds.isValid()) {
|
if (bounds.isValid()) {
|
||||||
this.map.fitBounds(bounds);
|
this.map.fitBounds(bounds);
|
||||||
this.bounds = bounds;
|
this.bounds = bounds;
|
||||||
@ -270,6 +270,11 @@ export default abstract class LeafletMap {
|
|||||||
updatePolyline(data, dataSources, settings) {
|
updatePolyline(data, dataSources, settings) {
|
||||||
this.ready$.subscribe(() => {
|
this.ready$.subscribe(() => {
|
||||||
this.poly.updatePolyline(settings, data, dataSources);
|
this.poly.updatePolyline(settings, data, dataSources);
|
||||||
|
const bounds = this.bounds.extend(this.poly.leafletPoly.getBounds().pad(0.2));
|
||||||
|
if (bounds.isValid()) {
|
||||||
|
this.map.fitBounds(bounds);
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +299,7 @@ export default abstract class LeafletMap {
|
|||||||
createPolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) {
|
createPolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) {
|
||||||
this.ready$.subscribe(() => {
|
this.ready$.subscribe(() => {
|
||||||
this.polygon = new Polygon(this.map, data, dataSources, settings);
|
this.polygon = new Polygon(this.map, data, dataSources, settings);
|
||||||
const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds());
|
const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds().pad(0.2));
|
||||||
if (bounds.isValid()) {
|
if (bounds.isValid()) {
|
||||||
this.map.fitBounds(bounds);
|
this.map.fitBounds(bounds);
|
||||||
this.bounds = bounds;
|
this.bounds = bounds;
|
||||||
@ -305,6 +310,11 @@ export default abstract class LeafletMap {
|
|||||||
updatePolygon(data, dataSources, settings) {
|
updatePolygon(data, dataSources, settings) {
|
||||||
this.ready$.subscribe(() => {
|
this.ready$.subscribe(() => {
|
||||||
// this.polygon.updatePolygon(settings, data, dataSources);
|
// this.polygon.updatePolygon(settings, data, dataSources);
|
||||||
|
const bounds = this.bounds.extend(this.polygon.leafletPoly.getBounds().pad(0.2));
|
||||||
|
if (bounds.isValid()) {
|
||||||
|
this.map.fitBounds(bounds);
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,15 +1,15 @@
|
|||||||
///
|
///
|
||||||
/// Copyright © 2016-2020 The Thingsboard Authors
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
||||||
///
|
///
|
||||||
/// Licensed under the Apache License; Version 2.0 (the "License");
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
/// you may not use this file except in compliance with the License.
|
/// you may not use this file except in compliance with the License.
|
||||||
/// You may obtain a copy of the License at
|
/// You may obtain a copy of the License at
|
||||||
///
|
///
|
||||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
///
|
///
|
||||||
/// Unless required by applicable law or agreed to in writing; software
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
/// distributed under the License is distributed on an "AS IS" BASIS;
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND; either express or implied.
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
/// See the License for the specific language governing permissions and
|
/// See the License for the specific language governing permissions and
|
||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
@ -70,6 +70,7 @@ export type MarkerSettings = {
|
|||||||
markerImages?: string[];
|
markerImages?: string[];
|
||||||
useMarkerImage: boolean;
|
useMarkerImage: boolean;
|
||||||
markerImageSize: number;
|
markerImageSize: number;
|
||||||
|
fitMapBounds: boolean;
|
||||||
markerImage: {
|
markerImage: {
|
||||||
length: number
|
length: number
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,9 +46,7 @@ export class Polygon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updatePolygonColor(settings) {
|
updatePolygonColor(settings) {
|
||||||
console.log('Polygon -> updatePolygonColor -> settings', settings)
|
|
||||||
const style: L.PathOptions = {
|
const style: L.PathOptions = {
|
||||||
|
|
||||||
fill: true,
|
fill: true,
|
||||||
fillColor: settings.color,
|
fillColor: settings.color,
|
||||||
color: settings.color,
|
color: settings.color,
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export class Polyline {
|
|||||||
this.leafletPoly = L.polyline(locations,
|
this.leafletPoly = L.polyline(locations,
|
||||||
this.getPolyStyle(settings)
|
this.getPolyStyle(settings)
|
||||||
).addTo(this.map);
|
).addTo(this.map);
|
||||||
|
|
||||||
if (settings.usePolylineDecorator) {
|
if (settings.usePolylineDecorator) {
|
||||||
this.polylineDecorator = L.polylineDecorator(this.leafletPoly, this.getDecoratorSettings(settings)).addTo(this.map);
|
this.polylineDecorator = L.polylineDecorator(this.leafletPoly, this.getDecoratorSettings(settings)).addTo(this.map);
|
||||||
}
|
}
|
||||||
@ -61,10 +62,12 @@ export class Polyline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updatePolyline(settings, data, dataSources) {
|
updatePolyline(settings, data, dataSources) {
|
||||||
|
this.data = data;
|
||||||
|
this.dataSources = dataSources;
|
||||||
this.leafletPoly.setStyle(this.getPolyStyle(settings));
|
this.leafletPoly.setStyle(this.getPolyStyle(settings));
|
||||||
// this.setPolylineLatLngs(data);
|
// this.setPolylineLatLngs(data);
|
||||||
if(this.polylineDecorator)
|
if (this.polylineDecorator)
|
||||||
this.polylineDecorator.setPaths(this.leafletPoly);
|
this.polylineDecorator.setPaths(this.leafletPoly);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
|
getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
|
||||||
|
|||||||
@ -33,5 +33,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<tb-history-selector *ngIf="historicalData" [settings]="settings" [intervals]="intervals"
|
<tb-history-selector *ngIf="historicalData" [settings]="settings" [intervals]="intervals"
|
||||||
(onTimeUpdated)="timeUpdated($event)"></tb-history-selector>
|
(timeUpdated)="timeUpdated($event)"></tb-history-selector>
|
||||||
</div>
|
</div>
|
||||||
@ -55,8 +55,8 @@ export class HistorySelectorComponent implements OnInit, OnChanges {
|
|||||||
if (!this.interval)
|
if (!this.interval)
|
||||||
this.interval = interval(1000 / this.speed)
|
this.interval = interval(1000 / this.speed)
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(() => this.playing),
|
filter(() => this.playing)).subscribe(() => {
|
||||||
tap(() => this.index++)).subscribe(() => {
|
this.index++;
|
||||||
if (this.index < this.maxTimeIndex) {
|
if (this.index < this.maxTimeIndex) {
|
||||||
this.cd.detectChanges();
|
this.cd.detectChanges();
|
||||||
this.timeUpdated.emit(this.intervals[this.index]);
|
this.timeUpdated.emit(this.intervals[this.index]);
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import { parseTemplate } from '@app/core/utils';
|
|||||||
@Pipe({ name: 'tbParseTemplate' })
|
@Pipe({ name: 'tbParseTemplate' })
|
||||||
export class TbTemplatePipe implements PipeTransform {
|
export class TbTemplatePipe implements PipeTransform {
|
||||||
transform(template, data): string {
|
transform(template, data): string {
|
||||||
console.log('TbTemplatePipe -> transform -> template, data', template, data)
|
|
||||||
return parseTemplate(template, data);
|
return parseTemplate(template, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
ui-ngx/src/typings/add-marker.d.ts
vendored
16
ui-ngx/src/typings/add-marker.d.ts
vendored
@ -1,3 +1,19 @@
|
|||||||
|
///
|
||||||
|
/// Copyright © 2016-2020 The Thingsboard Authors
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
|
||||||
import * as L from 'leaflet'
|
import * as L from 'leaflet'
|
||||||
|
|
||||||
declare module 'leaflet' {
|
declare module 'leaflet' {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user