@ -21,6 +21,7 @@ import { MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet.markerclu
import '@geoman-io/leaflet-geoman-free' ;
import '@geoman-io/leaflet-geoman-free' ;
import {
import {
CircleData ,
defaultSettings ,
defaultSettings ,
FormattedData ,
FormattedData ,
MapSettings ,
MapSettings ,
@ -36,7 +37,8 @@ import { Marker } from './markers';
import { Observable , of } from 'rxjs' ;
import { Observable , of } from 'rxjs' ;
import { Polyline } from './polyline' ;
import { Polyline } from './polyline' ;
import { Polygon } from './polygon' ;
import { Polygon } from './polygon' ;
import { createTooltip } from '@home/components/widget/lib/maps/maps-utils' ;
import { Circle } from './circle' ;
import { createTooltip , isCutPolygon , isJSON } from '@home/components/widget/lib/maps/maps-utils' ;
import {
import {
checkLngLat ,
checkLngLat ,
createLoadingDiv ,
createLoadingDiv ,
@ -45,19 +47,21 @@ import {
safeExecute
safeExecute
} from '@home/components/widget/lib/maps/common-maps-utils' ;
} from '@home/components/widget/lib/maps/common-maps-utils' ;
import { WidgetContext } from '@home/models/widget-component.models' ;
import { WidgetContext } from '@home/models/widget-component.models' ;
import { deepClone , isDefinedAndNotNull , isEmptyStr , isString } from '@core/utils' ;
import { deepClone , isDefinedAndNotNull , isNot EmptyStr , isString } from '@core/utils' ;
import { TranslateService } from '@ngx-translate/core' ;
import { TranslateService } from '@ngx-translate/core' ;
import {
import {
SelectEntityDialogComponent ,
SelectEntityDialogComponent ,
SelectEntityDialogData
SelectEntityDialogData
} from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component' ;
} from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component' ;
import { MatDialog } from '@angular/material/dialog' ;
import { MatDialog } from '@angular/material/dialog' ;
import ITooltipsterInstance = JQueryTooltipster . ITooltipsterInstance ;
export default abstract class LeafletMap {
export default abstract class LeafletMap {
markers : Map < string , Marker > = new Map ( ) ;
markers : Map < string , Marker > = new Map ( ) ;
polylines : Map < string , Polyline > = new Map ( ) ;
polylines : Map < string , Polyline > = new Map ( ) ;
polygons : Map < string , Polygon > = new Map ( ) ;
polygons : Map < string , Polygon > = new Map ( ) ;
circles : Map < string , Circle > = new Map ( ) ;
map : L.Map ;
map : L.Map ;
options : UnitedMapSettings ;
options : UnitedMapSettings ;
bounds : L.LatLngBounds ;
bounds : L.LatLngBounds ;
@ -66,22 +70,25 @@ export default abstract class LeafletMap {
points : FeatureGroup ;
points : FeatureGroup ;
markersData : FormattedData [ ] = [ ] ;
markersData : FormattedData [ ] = [ ] ;
polygonsData : FormattedData [ ] = [ ] ;
polygonsData : FormattedData [ ] = [ ] ;
circleData : FormattedData [ ] = [ ] ;
defaultMarkerIconInfo : MarkerIconInfo ;
defaultMarkerIconInfo : MarkerIconInfo ;
loadingDiv : JQuery < HTMLElement > ;
loadingDiv : JQuery < HTMLElement > ;
loading = false ;
loading = false ;
replaceInfoLabelMarker : Array < ReplaceInfo > = [ ] ;
replaceInfoLabelMarker : Array < ReplaceInfo > = [ ] ;
markerLabelText : string ;
markerLabelText : string ;
polygonLabelText : string ;
polygonLabelText : string ;
circleLabelText : string ;
replaceInfoLabelPolygon : Array < ReplaceInfo > = [ ] ;
replaceInfoLabelPolygon : Array < ReplaceInfo > = [ ] ;
replaceInfoTooltipMarker : Array < ReplaceInfo > = [ ] ;
replaceInfoTooltipMarker : Array < ReplaceInfo > = [ ] ;
replaceInfoTooltipCircle : Array < ReplaceInfo > = [ ] ;
markerTooltipText : string ;
markerTooltipText : string ;
drawRoutes : boolean ;
drawRoutes : boolean ;
showPolygon : boolean ;
showPolygon : boolean ;
updatePending = false ;
updatePending = false ;
editPolygons = false ;
editPolygons = false ;
editCircle = false ;
selectedEntity : FormattedData ;
selectedEntity : FormattedData ;
addMarkers : L.Marker [ ] = [ ] ;
ignoreUpdateBounds = false ;
addPolygons : L.Polygon [ ] = [ ] ;
// tslint:disable-next-line:no-string-literal
// tslint:disable-next-line:no-string-literal
southWest = new L . LatLng ( - Projection . SphericalMercator [ 'MAX_LATITUDE' ] , - 180 ) ;
southWest = new L . LatLng ( - Projection . SphericalMercator [ 'MAX_LATITUDE' ] , - 180 ) ;
// tslint:disable-next-line:no-string-literal
// tslint:disable-next-line:no-string-literal
@ -90,12 +97,14 @@ export default abstract class LeafletMap {
saveMarkerLocation : ( e : FormattedData , lat? : number , lng? : number ) = > Observable < any > ;
saveMarkerLocation : ( e : FormattedData , lat? : number , lng? : number ) = > Observable < any > ;
savePolygonLocation : ( e : FormattedData , coordinates? : Array < any > ) = > Observable < any > ;
savePolygonLocation : ( e : FormattedData , coordinates? : Array < any > ) = > Observable < any > ;
translateService : TranslateService ;
translateService : TranslateService ;
tooltipInstances : ITooltipsterInstance [ ] = [ ] ;
protected constructor ( public ctx : WidgetContext ,
protected constructor ( public ctx : WidgetContext ,
public $container : HTMLElement ,
public $container : HTMLElement ,
options : UnitedMapSettings ) {
options : UnitedMapSettings ) {
this . options = options ;
this . options = options ;
this . editPolygons = options . showPolygon && options . editablePolygon ;
this . editPolygons = options . showPolygon && options . editablePolygon ;
this . editCircle = options . showCircle && options . editableCircle ;
L . Icon . Default . imagePath = '/' ;
L . Icon . Default . imagePath = '/' ;
this . translateService = this . ctx . $injector . get ( TranslateService ) ;
this . translateService = this . ctx . $injector . get ( TranslateService ) ;
}
}
@ -151,6 +160,9 @@ export default abstract class LeafletMap {
case 'Marker' :
case 'Marker' :
entities = this . datasources . filter ( mData = > ! this . convertPosition ( mData ) ) ;
entities = this . datasources . filter ( mData = > ! this . convertPosition ( mData ) ) ;
break ;
break ;
case 'Circle' :
entities = this . datasources . filter ( mData = > ! this . isValidCircle ( mData ) ) ;
break ;
default :
default :
return of ( null ) ;
return of ( null ) ;
}
}
@ -181,6 +193,16 @@ export default abstract class LeafletMap {
// @ts-ignore
// @ts-ignore
this . map . pm . Draw . tbMarker . _hintMarker . setTooltipContent ( tooltipText ) ;
this . map . pm . Draw . tbMarker . _hintMarker . setTooltipContent ( tooltipText ) ;
break ;
break ;
case 'tbCircle' :
tooltipText = this . translateService . instant ( 'widgets.maps.tooltips.startCircle' , { entityName : data.entityName } ) ;
// @ts-ignore
this . map . pm . Draw . tbCircle . _hintMarker . setTooltipContent ( tooltipText ) ;
customTranslation = {
tooltips : {
finishCircle : this.translateService.instant ( 'widgets.maps.tooltips.finishCircle' , { entityName : data.entityName } )
}
} ;
break ;
case 'tbRectangle' :
case 'tbRectangle' :
tooltipText = this . translateService . instant ( 'widgets.maps.tooltips.firstVertex' , { entityName : data.entityName } ) ;
tooltipText = this . translateService . instant ( 'widgets.maps.tooltips.firstVertex' , { entityName : data.entityName } ) ;
// @ts-ignore
// @ts-ignore
@ -190,7 +212,6 @@ export default abstract class LeafletMap {
finishRect : this.translateService.instant ( 'widgets.maps.tooltips.finishRect' , { entityName : data.entityName } )
finishRect : this.translateService.instant ( 'widgets.maps.tooltips.finishRect' , { entityName : data.entityName } )
}
}
} ;
} ;
this . map . pm . setLang ( 'en' , customTranslation , 'en' ) ;
break ;
break ;
case 'tbPolygon' :
case 'tbPolygon' :
tooltipText = this . translateService . instant ( 'widgets.maps.tooltips.firstVertex' , { entityName : data.entityName } ) ;
tooltipText = this . translateService . instant ( 'widgets.maps.tooltips.firstVertex' , { entityName : data.entityName } ) ;
@ -202,9 +223,12 @@ export default abstract class LeafletMap {
finishPoly : this.translateService.instant ( 'widgets.maps.tooltips.finishPoly' , { entityName : data.entityName } )
finishPoly : this.translateService.instant ( 'widgets.maps.tooltips.finishPoly' , { entityName : data.entityName } )
}
}
} ;
} ;
this . map . pm . setLang ( 'en' , customTranslation ) ;
break ;
break ;
}
}
if ( customTranslation ) {
this . map . pm . setLang ( 'en' , customTranslation , 'en' ) ;
this . createdControlButtonTooltip ( ) ;
}
} else {
} else {
// @ts-ignore
// @ts-ignore
this . map . pm . Toolbar . toggleButton ( type , false ) ;
this . map . pm . Toolbar . toggleButton ( type , false ) ;
@ -265,6 +289,48 @@ export default abstract class LeafletMap {
} ) ;
} ) ;
}
}
// Customize edit circle
if ( this . editCircle && ! this . options . hideDrawControlButton ) {
const actions = [ {
text : L.PM.Utils.getTranslation ( 'actions.cancel' ) ,
onClick : ( ) = > this . toggleDrawMode ( 'tbCircle' )
} ] ;
this . map . pm . Toolbar . copyDrawControl ( 'Circle' , {
name : 'tbCircle' ,
afterClick : ( ) = > this . selectEntityWithoutLocation ( 'tbCircle' ) ,
disabled : true ,
actions
} ) ;
}
if ( this . editPolygons && ! this . options . hideEditControlButton ) {
this . map . pm . Toolbar . copyDrawControl ( 'cutPolygon' , {
name : 'tbCut' ,
title : this.translateService.instant ( 'widgets.maps.buttonTitles.cutButton' ) ,
block : 'edit' ,
onClick : ( ) = > {
this . map . pm . setLang ( 'en' , {
tooltips : {
firstVertex : this.translateService.instant ( 'widgets.maps.tooltips.firstVertex-cut' ) ,
continueLine : this.translateService.instant ( 'widgets.maps.tooltips.continueLine-cut' ) ,
finishPoly : this.translateService.instant ( 'widgets.maps.tooltips.finishPoly-cut' )
}
} , 'en' ) ;
this . createdControlButtonTooltip ( ) ;
} ,
// @ts-ignore
afterClick : ( e , ctx ) = > {
this . map . pm . Draw [ ctx . button . _button . jsClass ] . toggle ( {
snappable : this.options.snappable ,
cursorMarker : true ,
allowSelfIntersection : false ,
} ) ;
} ,
} ) ;
this . map . pm . Toolbar . changeControlOrder ( [ 'tbMarker' , 'tbRectangle' , 'tbPolygon' , 'tbCircle' , 'editMode' , 'dragMode' , 'tbCut' , 'removalMode' , 'rotateMode' ] ) ;
}
this . map . pm . setLang ( 'en' , this . translateService . instant ( 'widgets.maps' ) , 'en' ) ;
this . map . pm . setLang ( 'en' , this . translateService . instant ( 'widgets.maps' ) , 'en' ) ;
if ( ! this . options . hideAllControlButton ) {
if ( ! this . options . hideAllControlButton ) {
this . map . pm . addControls ( {
this . map . pm . addControls ( {
@ -277,8 +343,8 @@ export default abstract class LeafletMap {
drawPolyline : false ,
drawPolyline : false ,
drawPolygon : false ,
drawPolygon : false ,
dragMode : ! this . options . hideEditControlButton ,
dragMode : ! this . options . hideEditControlButton ,
editMode : this.editPolygons && ! this . options . hideEditControlButton ,
editMode : ( this . editPolygons || this . editCircle ) && ! this . options . hideEditControlButton ,
cutPolygon : this.editPolygons && ! this . options . hideEditControlButton ,
cutPolygon : false ,
removalMode : ! this . options . hideRemoveControlButton ,
removalMode : ! this . options . hideRemoveControlButton ,
rotateMode : this.editPolygons && ! this . options . hideEditControlButton
rotateMode : this.editPolygons && ! this . options . hideEditControlButton
} ) ;
} ) ;
@ -286,25 +352,38 @@ export default abstract class LeafletMap {
if ( this . options . initDragMode ) {
if ( this . options . initDragMode ) {
this . map . pm . enableGlobalDragMode ( ) ;
this . map . pm . enableGlobalDragMode ( ) ;
this . ignoreUpdateBounds = true ;
}
}
this . map . on ( 'pm:globaleditmodetoggled' , ( e ) = > this . ignoreUpdateBounds = e . enabled ) ;
this . map . on ( 'pm:globaldragmodetoggled' , ( e ) = > this . ignoreUpdateBounds = e . enabled ) ;
this . map . on ( 'pm:globalremovalmodetoggled' , ( e ) = > this . ignoreUpdateBounds = e . enabled ) ;
this . map . on ( 'pm:globalcutmodetoggled' , ( e ) = > this . ignoreUpdateBounds = e . enabled ) ;
this . map . on ( 'pm:globalrotatemodetoggled' , ( e ) = > this . ignoreUpdateBounds = e . enabled ) ;
this . map . on ( 'pm:create' , ( e ) = > {
this . map . on ( 'pm:create' , ( e ) = > {
if ( e . shape === 'tbMarker' ) {
switch ( e . shape ) {
// @ts-ignore
case 'tbMarker' :
this . saveLocation ( this . selectedEntity , this . convertToCustomFormat ( e . layer . getLatLng ( ) ) ) . subscribe ( ( ) = > {
} ) ;
} else if ( e . shape === 'tbRectangle' || e . shape === 'tbPolygon' ) {
let coordinates ;
if ( e . shape === 'tbRectangle' ) {
// @ts-ignore
// @ts-ignore
const bounds : L.LatLngBounds = e . layer . getBounds ( ) ;
this . saveLocation ( this . selectedEntity , this . convertToCustomFormat ( e . layer . getLatLng ( ) ) ) . subscribe ( ( ) = > { } ) ;
coordinates = [ bounds . getNorthWest ( ) , bounds . getSouthEast ( ) ] ;
break ;
} else {
case 'tbRectangle' :
case 'tbPolygon' :
let coordinates ;
if ( e . shape === 'tbRectangle' ) {
// @ts-ignore
const bounds : L.LatLngBounds = e . layer . getBounds ( ) ;
coordinates = [ bounds . getNorthWest ( ) , bounds . getSouthEast ( ) ] ;
} else {
// @ts-ignore
coordinates = e . layer . getLatLngs ( ) [ 0 ] ;
}
this . saveLocation ( this . selectedEntity , this . convertPolygonToCustomFormat ( coordinates ) ) . subscribe ( ( ) = > { } ) ;
break ;
case 'tbCircle' :
// @ts-ignore
// @ts-ignore
coordinates = e . layer . getLatLngs ( ) [ 0 ] ;
this . saveLocation ( this . selectedEntity , this . convertCircleToCustomFormat ( e . layer . getLatLng ( ) , e . layer . getRadius ( ) ) )
}
. subscribe ( ( ) = > { } ) ;
this . saveLocation ( this . selectedEntity , this . convertPolygonToCustomFormat ( coordinates ) ) . subscribe ( ( ) = > {
} ) ;
}
}
// @ts-ignore
// @ts-ignore
e . layer . _pmTempLayer = true ;
e . layer . _pmTempLayer = true ;
@ -342,6 +421,13 @@ export default abstract class LeafletMap {
result = iterator . next ( ) ;
result = iterator . next ( ) ;
}
}
this . saveLocation ( result . value . data , this . convertPolygonToCustomFormat ( null ) ) . subscribe ( ( ) = > { } ) ;
this . saveLocation ( result . value . data , this . convertPolygonToCustomFormat ( null ) ) . subscribe ( ( ) = > { } ) ;
} else if ( e . shape === 'Circle' ) {
const iterator = this . circles . values ( ) ;
let result = iterator . next ( ) ;
while ( ! result . done && e . layer !== result . value . leafletCircle ) {
result = iterator . next ( ) ;
}
this . saveLocation ( result . value . data , this . convertCircleToCustomFormat ( null , 0 ) ) . subscribe ( ( ) = > { } ) ;
}
}
} ) ;
} ) ;
}
}
@ -386,7 +472,7 @@ export default abstract class LeafletMap {
if ( this . options . disableScrollZooming ) {
if ( this . options . disableScrollZooming ) {
this . map . scrollWheelZoom . disable ( ) ;
this . map . scrollWheelZoom . disable ( ) ;
}
}
if ( this . options . draggableMarker || this . editPolygons ) {
if ( this . options . draggableMarker || this . editPolygons || this . editCircle ) {
map . pm . setGlobalOptions ( { snappable : false } as L . PM . GlobalOptions ) ;
map . pm . setGlobalOptions ( { snappable : false } as L . PM . GlobalOptions ) ;
map . pm . applyGlobalOptions ( ) ;
map . pm . applyGlobalOptions ( ) ;
this . addEditControl ( ) ;
this . addEditControl ( ) ;
@ -405,6 +491,12 @@ export default abstract class LeafletMap {
private createdControlButtonTooltip() {
private createdControlButtonTooltip() {
import ( 'tooltipster' ) . then ( ( ) = > {
import ( 'tooltipster' ) . then ( ( ) = > {
if ( $ . tooltipster ) {
this . tooltipInstances . forEach ( ( instance ) = > {
instance . destroy ( ) ;
} ) ;
this . tooltipInstances = [ ] ;
}
$ ( this . ctx . $container )
$ ( this . ctx . $container )
. find ( 'a[role="button"]:not(.leaflet-pm-action)' )
. find ( 'a[role="button"]:not(.leaflet-pm-action)' )
. each ( ( index , element ) = > {
. each ( ( index , element ) = > {
@ -416,7 +508,7 @@ export default abstract class LeafletMap {
title = element . title ;
title = element . title ;
$ ( element ) . removeAttr ( 'title' ) ;
$ ( element ) . removeAttr ( 'title' ) ;
}
}
$ ( element ) . tooltipster (
const tooltip = $ ( element ) . tooltipster (
{
{
content : title ,
content : title ,
theme : 'tooltipster-shadow' ,
theme : 'tooltipster-shadow' ,
@ -432,6 +524,7 @@ export default abstract class LeafletMap {
trackOrigin : true
trackOrigin : true
}
}
) ;
) ;
this . tooltipInstances . push ( tooltip . tooltipster ( 'instance' ) ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
}
@ -559,15 +652,18 @@ export default abstract class LeafletMap {
if ( showPolygon ) {
if ( showPolygon ) {
this . updatePolygons ( formattedData , false ) ;
this . updatePolygons ( formattedData , false ) ;
}
}
if ( this . options . showCircle ) {
this . updateCircle ( formattedData , false ) ;
}
this . updateMarkers ( formattedData , false ) ;
this . updateMarkers ( formattedData , false ) ;
this . updateBoundsInternal ( ) ;
this . updateBoundsInternal ( ) ;
if ( this . options . draggableMarker || this . editPolygons ) {
if ( this . options . draggableMarker || this . editPolygons || this . editCircle ) {
let foundEntityWithoutLocation = false ;
let foundEntityWithLocation = false ;
let foundEntityWithLocation = false ;
let foundEntityWithoutPolygon = false ;
let foundEntityWithPolygon = false ;
let foundEntityWithPolygon = false ;
let foundEntityWithCircle = false ;
if ( this . options . draggableMarker && ! this . options . hideDrawControlButton && ! this . options . hideAllControlButton ) {
if ( this . options . draggableMarker && ! this . options . hideDrawControlButton && ! this . options . hideAllControlButton ) {
let foundEntityWithoutLocation = false ;
for ( const mData of formattedData ) {
for ( const mData of formattedData ) {
const position = this . convertPosition ( mData ) ;
const position = this . convertPosition ( mData ) ;
if ( ! position ) {
if ( ! position ) {
@ -587,6 +683,7 @@ export default abstract class LeafletMap {
}
}
if ( this . editPolygons && ! this . options . hideDrawControlButton && ! this . options . hideAllControlButton ) {
if ( this . editPolygons && ! this . options . hideDrawControlButton && ! this . options . hideAllControlButton ) {
let foundEntityWithoutPolygon = false ;
for ( const pData of formattedData ) {
for ( const pData of formattedData ) {
const isValidPolygon = this . isValidPolygonPosition ( pData ) ;
const isValidPolygon = this . isValidPolygonPosition ( pData ) ;
if ( ! isValidPolygon ) {
if ( ! isValidPolygon ) {
@ -605,22 +702,47 @@ export default abstract class LeafletMap {
}
}
this . datasources = formattedData ;
this . datasources = formattedData ;
}
}
if ( this . editCircle && ! this . options . hideDrawControlButton && ! this . options . hideAllControlButton ) {
let foundEntityWithoutCircle = false ;
for ( const cData of formattedData ) {
const isValidCircle = this . isValidCircle ( cData ) ;
if ( ! isValidCircle ) {
foundEntityWithoutCircle = true ;
} else if ( isValidCircle ) {
foundEntityWithCircle = true ;
}
if ( foundEntityWithoutCircle && foundEntityWithCircle ) {
break ;
}
}
// @ts-ignore
if ( this . map . pm . Toolbar . getButtons ( ) . tbCircle . disable !== foundEntityWithoutCircle ) {
this . map . pm . Toolbar . setButtonDisabled ( 'tbCircle' , ! foundEntityWithoutCircle ) ;
}
this . datasources = formattedData ;
}
if ( ! this . options . hideRemoveControlButton && ! this . options . hideAllControlButton ) {
if ( ! this . options . hideRemoveControlButton && ! this . options . hideAllControlButton ) {
const disabledButton = ! foundEntityWithLocation && ! foundEntityWithPolygon ;
const disabledButton = ! foundEntityWithLocation && ! foundEntityWithPolygon && ! foundEntityWithCircle ;
if ( disabledButton && this . map . pm . globalRemovalModeEnabled ( ) ) {
if ( disabledButton && this . map . pm . globalRemovalModeEnabled ( ) ) {
this . map . pm . toggleGlobalRemovalMode ( ) ;
this . map . pm . toggleGlobalRemovalMode ( ) ;
}
}
this . map . pm . Toolbar . setButtonDisabled ( 'removalMode' , disabledButton ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'removalMode' , disabledButton ) ;
}
}
if ( ! this . options . hideEditControlButton && ! this . options . hideAllControlButton ) {
if ( ! this . options . hideEditControlButton && ! this . options . hideAllControlButton ) {
const disabledButton = ! foundEntityWithLocation && ! foundEntityWithPolygon ;
const disabledButton = ! foundEntityWithLocation && ! foundEntityWithPolygon && ! foundEntityWithCircle ;
// @ts-ignore
// @ts-ignore
if ( this . map . pm . Toolbar . getButtons ( ) . dragMode . disable !== disabledButton ) {
if ( this . map . pm . Toolbar . getButtons ( ) . dragMode . disable !== disabledButton ) {
this . map . pm . Toolbar . setButtonDisabled ( 'dragMode' , disabledButton ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'dragMode' , disabledButton ) ;
const foundEntityWithPoly = foundEntityWithPolygon || foundEntityWithCircle ;
// @ts-ignore
// @ts-ignore
if ( this . editPolygons && this . map . pm . Toolbar . getButtons ( ) . editMode . disable !== foundEntityWithPolygon ) {
if ( ( this . editPolygons || this . editCircle ) && this . map . pm . Toolbar . getButtons ( ) . editMode . disable !== foundEntityWithPoly ) {
this . map . pm . Toolbar . setButtonDisabled ( 'editMode' , ! foundEntityWithPolygon ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'editMode' , ! foundEntityWithPoly ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'cutPolygon' , ! foundEntityWithPolygon ) ;
}
// @ts-ignore
if ( this . editPolygons && this . map . pm . Toolbar . getButtons ( ) . tbCut . disable !== foundEntityWithPolygon ) {
this . map . pm . Toolbar . setButtonDisabled ( 'tbCut' , ! foundEntityWithPolygon ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'rotateMode' , ! foundEntityWithPolygon ) ;
this . map . pm . Toolbar . setButtonDisabled ( 'rotateMode' , ! foundEntityWithPolygon ) ;
}
}
}
}
@ -632,6 +754,9 @@ export default abstract class LeafletMap {
}
}
private updateBoundsInternal() {
private updateBoundsInternal() {
if ( this . ignoreUpdateBounds ) {
return ;
}
const bounds = new L . LatLngBounds ( null , null ) ;
const bounds = new L . LatLngBounds ( null , null ) ;
if ( this . drawRoutes ) {
if ( this . drawRoutes ) {
this . polylines . forEach ( ( polyline ) = > {
this . polylines . forEach ( ( polyline ) = > {
@ -643,6 +768,11 @@ export default abstract class LeafletMap {
bounds . extend ( polygon . leafletPoly . getBounds ( ) ) ;
bounds . extend ( polygon . leafletPoly . getBounds ( ) ) ;
} ) ;
} ) ;
}
}
if ( this . options . showCircle ) {
this . circles . forEach ( ( polygon ) = > {
bounds . extend ( polygon . leafletCircle . getBounds ( ) ) ;
} ) ;
}
if ( ( this . options as MarkerSettings ) . useClusterMarkers && this . markersCluster . getBounds ( ) . isValid ( ) ) {
if ( ( this . options as MarkerSettings ) . useClusterMarkers && this . markersCluster . getBounds ( ) . isValid ( ) ) {
bounds . extend ( this . markersCluster . getBounds ( ) ) ;
bounds . extend ( this . markersCluster . getBounds ( ) ) ;
} else {
} else {
@ -797,7 +927,8 @@ export default abstract class LeafletMap {
if ( ! this . options . pointTooltipOnRightPanel ) {
if ( ! this . options . pointTooltipOnRightPanel ) {
point . on ( 'click' , ( ) = > getTooltip ( pdata , dsData ) ) ;
point . on ( 'click' , ( ) = > getTooltip ( pdata , dsData ) ) ;
} else {
} else {
createTooltip ( point , this . options , pdata . $datasource , getTooltip ( pdata , dsData ) ) ;
createTooltip ( point , this . options , pdata . $datasource , this . options . autocloseTooltip ,
this . options . showTooltipAction , getTooltip ( pdata , dsData ) ) ;
}
}
this . points . addLayer ( point ) ;
this . points . addLayer ( point ) ;
}
}
@ -868,7 +999,8 @@ export default abstract class LeafletMap {
// Polygon
// Polygon
isValidPolygonPosition ( data : FormattedData ) : boolean {
isValidPolygonPosition ( data : FormattedData ) : boolean {
return data && isDefinedAndNotNull ( data [ this . options . polygonKeyName ] ) && ! isEmptyStr ( data [ this . options . polygonKeyName ] ) ;
return data && ( ( isNotEmptyStr ( data [ this . options . polygonKeyName ] ) && ! isJSON ( data [ this . options . polygonKeyName ] )
|| Array . isArray ( data [ this . options . polygonKeyName ] ) ) ) ;
}
}
updatePolygons ( polyData : FormattedData [ ] , updateBounds = true ) {
updatePolygons ( polyData : FormattedData [ ] , updateBounds = true ) {
@ -908,7 +1040,7 @@ export default abstract class LeafletMap {
if ( coordinates . length === 1 ) {
if ( coordinates . length === 1 ) {
coordinates = coordinates [ 0 ] ;
coordinates = coordinates [ 0 ] ;
}
}
if ( e . shape === 'Rectangle' && coordinates . length === 1 ) {
if ( e . shape === 'Rectangle' && ! isCutPolygon ( coordinates ) ) {
// @ts-ignore
// @ts-ignore
const bounds : L.LatLngBounds = e . layer . getBounds ( ) ;
const bounds : L.LatLngBounds = e . layer . getBounds ( ) ;
const boundsArray = [ bounds . getNorthWest ( ) , bounds . getNorthEast ( ) , bounds . getSouthWest ( ) , bounds . getSouthEast ( ) ] ;
const boundsArray = [ bounds . getNorthWest ( ) , bounds . getNorthEast ( ) , bounds . getSouthWest ( ) , bounds . getSouthEast ( ) ] ;
@ -951,5 +1083,88 @@ export default abstract class LeafletMap {
this . map . remove ( ) ;
this . map . remove ( ) ;
this . map = null ;
this . map = null ;
}
}
this . tooltipInstances . forEach ( ( instance ) = > {
instance . destroy ( ) ;
} ) ;
}
// Circle
isValidCircle ( data : FormattedData ) : boolean {
return data && isNotEmptyStr ( data [ this . options . circleKeyName ] ) && isJSON ( data [ this . options . circleKeyName ] ) ;
}
convertCircleToCustomFormat ( expression : L.LatLng , radius : number ) : { [ key : string ] : CircleData } {
let circleDara : CircleData = null ;
if ( expression ) {
const position = checkLngLat ( expression , this . southWest , this . northEast ) ;
circleDara = {
latitude : position.lat ,
longitude : position.lng ,
radius
} ;
}
return {
[ this . options . circleKeyName ] : circleDara
} ;
}
convertToCircleFormat ( circle : CircleData ) : CircleData {
const centerPoint = checkLngLat ( new L . LatLng ( circle . latitude , circle . longitude ) , this . southWest , this . northEast ) ;
circle . latitude = centerPoint . lat ;
circle . longitude = centerPoint . lng ;
return circle ;
}
dragCircleVertex = ( e ? , data = { } as FormattedData ) = > {
if ( e === undefined ) {
return ;
}
const center = e . layer . getLatLng ( ) ;
const radius = e . layer . getRadius ( ) ;
this . saveLocation ( data , this . convertCircleToCustomFormat ( center , radius ) ) . subscribe ( ( ) = > { } ) ;
}
updateCircle ( circlesData : FormattedData [ ] , updateBounds = true ) {
const toDelete = new Set ( Array . from ( this . circles . keys ( ) ) ) ;
const rawCircles = circlesData . filter ( cdata = > this . isValidCircle ( cdata ) ) ;
rawCircles . forEach ( data = > {
if ( this . circles . get ( data . entityName ) ) {
this . updatedCircle ( data , circlesData , updateBounds ) ;
} else {
this . createdCircle ( data , circlesData , updateBounds ) ;
}
toDelete . delete ( data . entityName ) ;
} ) ;
toDelete . forEach ( ( key ) = > {
this . removeCircle ( key ) ;
} ) ;
this . circleData = circlesData ;
}
updatedCircle ( data : FormattedData , dataSources : FormattedData [ ] , updateBounds = true ) {
const circle = this . circles . get ( data . entityName ) ;
const oldBounds = circle . leafletCircle . getBounds ( ) ;
circle . updateCircle ( data , dataSources ) ;
const newBounds = circle . leafletCircle . getBounds ( ) ;
if ( updateBounds && oldBounds . toBBoxString ( ) !== newBounds . toBBoxString ( ) ) {
this . fitBounds ( newBounds ) ;
}
}
createdCircle ( data : FormattedData , dataSources : FormattedData [ ] , updateBounds = true ) {
const circle = new Circle ( this , data , dataSources , this . options , this . dragCircleVertex ) ;
if ( updateBounds ) {
const bounds = circle . leafletCircle . getBounds ( ) ;
this . fitBounds ( bounds ) ;
}
this . circles . set ( data . entityName , circle ) ;
}
removeCircle ( name : string ) {
const circle = this . circles . get ( name ) ;
if ( circle ) {
this . map . removeLayer ( circle . leafletCircle ) ;
this . circles . delete ( name ) ;
}
}
}
}
}