Implement pan to, fix zooming on map change
All checks were successful
FarmMaps.Develop/FarmMapsLib/develop This commit looks good
All checks were successful
FarmMaps.Develop/FarmMapsLib/develop This commit looks good
This commit is contained in:
parent
ac5efdb40f
commit
64c02614ba
@ -15,6 +15,6 @@
|
||||
"@ngrx/router-store": "^8.2",
|
||||
"@ngrx/store": "^8.2",
|
||||
"tassign": "^1.0.0",
|
||||
"@farmmaps/common": ">=0.0.1-prerelease.90 <0.0.1"
|
||||
"@farmmaps/common": ">=0.0.1-prerelease.102 <0.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ import { WidgetStatusComponent } from './components/widget-status/widget-status.
|
||||
import { ForChild} from './components/for-item/for-child.decorator';
|
||||
import {ForItemType } from './components/for-item/for-itemtype.decorator';
|
||||
import { ForSourceTask} from './components/for-item/for-sourcetask.decorator';
|
||||
import { PanToLocation} from './components/aol/pan-to-location/pan-to-location.component';
|
||||
|
||||
|
||||
export {
|
||||
@ -104,6 +105,7 @@ export {
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
AbstractFeatureListComponent,
|
||||
AbstractFeatureListFeatureComponent,
|
||||
AbstractSelectedItemComponent,
|
||||
@ -169,6 +171,7 @@ export {
|
||||
ItemWidgetListComponent,
|
||||
WidgetStatusComponent,
|
||||
GpsLocation,
|
||||
PanToLocation
|
||||
],
|
||||
entryComponents: [
|
||||
FeatureListComponent,
|
||||
@ -192,6 +195,7 @@ export {
|
||||
MetaDataModalComponent,
|
||||
MapComponent,
|
||||
GpsLocation,
|
||||
PanToLocation,
|
||||
FeatureListFeatureComponent,
|
||||
FeatureListFeatureCropfieldComponent,
|
||||
FeatureListFeatureCroppingschemeComponent,
|
||||
|
@ -0,0 +1,13 @@
|
||||
<div (click)="handleClick($event)" class="rounded-circle gps-location">
|
||||
<svg height="100%" width="100%" viewBox="0 0 96 96">
|
||||
<g
|
||||
id="XMLID_1_"><circle
|
||||
class="pan-to" [ngClass]="{'pan-to-centered':centered(),'pan-to-disabled':disabled()}"
|
||||
cx="48"
|
||||
cy="48"
|
||||
r="9.8000002"/><path
|
||||
class="pan-to" [ngClass]="{'pan-to-centered':centered(),'pan-to-disabled':disabled()}"
|
||||
d="M 80.5,44.8 H 73.8 C 72.3,33 63,23.7 51.3,22.2 v -6.7 h -6.5 v 6.7 C 33,23.7 23.7,33 22.2,44.8 h -6.7 v 6.5 h 6.7 C 23.7,63 33,72.3 44.8,73.8 v 6.7 h 6.5 V 73.8 C 63,72.3 72.3,63 73.8,51.3 h 6.7 z M 48,67.5 C 37.2,67.5 28.5,58.8 28.5,48 28.5,37.2 37.2,28.5 48,28.5 c 10.8,0 19.5,8.7 19.5,19.5 0,10.8 -8.7,19.5 -19.5,19.5 z"
|
||||
inkscape:connector-curvature="0"/></g>
|
||||
</svg>
|
||||
</div>
|
@ -0,0 +1,28 @@
|
||||
@import "../../../_theme.scss";
|
||||
@import "~bootstrap/scss/bootstrap.scss";
|
||||
|
||||
|
||||
.gps-location {
|
||||
display:block;
|
||||
width:2.5em;
|
||||
height:2.5em;
|
||||
background-color: white;
|
||||
background-size: contain;
|
||||
margin-top:0.5em;
|
||||
}
|
||||
|
||||
.center, .tolerance, .border {
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.pan-to {
|
||||
fill: #333333;
|
||||
}
|
||||
|
||||
.pan-to-centered {
|
||||
fill: theme-color()
|
||||
}
|
||||
|
||||
.pan-to-disabled {
|
||||
fill: #808080;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
import { Component, OnInit, Input, Host, OnChanges, SimpleChanges,ChangeDetectorRef } from '@angular/core';
|
||||
import { MapComponent } from 'ngx-openlayers';
|
||||
import {IMapState} from '../../../models/map.state'
|
||||
import {View} from 'ol';
|
||||
import { fromLonLat } from 'ol/proj';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-map-pan-to-location',
|
||||
templateUrl: './pan-to-location.component.html',
|
||||
styleUrls: ['./pan-to-location.component.scss']
|
||||
})
|
||||
export class PanToLocation implements OnInit,OnChanges{
|
||||
|
||||
view: View;
|
||||
map: MapComponent;
|
||||
@Input() position: Position;
|
||||
@Input() mapState: IMapState;
|
||||
@Input() animate: boolean;
|
||||
|
||||
constructor(@Host() map: MapComponent,private changeDetectorRef$: ChangeDetectorRef ) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.view = this.map.instance.getView();
|
||||
this.view.on('change:center', () => {
|
||||
this.changeDetectorRef$.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
// if (changes.position && this.instance) {
|
||||
// var p = changes.position.currentValue as Position;
|
||||
// this.instance.setPosition(fromLonLat([p.coords.longitude, p.coords.latitude]));
|
||||
// this.locationTolerance = p.coords.accuracy;
|
||||
// this.recalcLocationTolerance();
|
||||
// this.heading = p.coords.heading;
|
||||
// }
|
||||
}
|
||||
|
||||
p
|
||||
|
||||
public centered():boolean {
|
||||
if(this.position && this.mapState) {
|
||||
let center = this.view.getCenter();
|
||||
let newCenter = fromLonLat([this.position.coords.longitude,this.position.coords.latitude]);
|
||||
let x1 = newCenter[0].toFixed(0);
|
||||
let x2 = center[0].toFixed(0);
|
||||
let y1 = newCenter[1].toFixed(0);
|
||||
let y2 = center[1].toFixed(0);
|
||||
return x1==x2 && y1==y2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public disabled():boolean {
|
||||
return !this.position;
|
||||
}
|
||||
|
||||
handleClick(event:Event) {
|
||||
if(this.position) {
|
||||
let view = this.map.instance.getView();
|
||||
let newCenter = fromLonLat([this.position.coords.longitude,this.position.coords.latitude]);
|
||||
let extent = [newCenter[0]-500,newCenter[1]-500,newCenter[0]+500,newCenter[1]+500];
|
||||
var options = { padding: [0, 0, 0, 0],minResolution:1 };
|
||||
let size = this.map.instance.getSize();
|
||||
let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
||||
let threshold = 44 * rem;
|
||||
var left = 1 * rem;
|
||||
var right = 1 * rem;
|
||||
var bottom = Math.round(size[1] / 2);
|
||||
var top = 1 * rem;
|
||||
if (size[0] > threshold) {
|
||||
bottom = 1 * rem;
|
||||
left = 23 * rem;
|
||||
}
|
||||
//options.padding = [top, right, bottom, left];
|
||||
if (this.animate) options["duration"] = 2000;
|
||||
view.fit(extent, options);
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
@ -15,12 +15,14 @@ import {View} from 'ol';
|
||||
background-size: contain;
|
||||
background-image: url(data:image/png;base64,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);
|
||||
opacity: 1;
|
||||
margin-top:0.5em;
|
||||
}
|
||||
.compass-n {
|
||||
background-image: url(data:image/png;base64,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);
|
||||
transition: opacity 1s ease-out;
|
||||
transition-delay: 2s;
|
||||
transition: opacity 1s ease-out 2s,height 1s ease-out 3s,margin-top 1s ease-out 3s;
|
||||
opacity:0;
|
||||
height:0;
|
||||
margin-top:0;
|
||||
}
|
||||
`]
|
||||
})
|
||||
|
@ -1,58 +1,81 @@
|
||||
<aol-map #map (onMoveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" [ngClass]="{'panel-visible':(panelVisible|async)}" class="map">
|
||||
<div>
|
||||
<ng-container *ngIf="{
|
||||
mapState:mapState$|async,
|
||||
extent:extent$|async,
|
||||
baseLayers:baseLayers$|async,
|
||||
overlayLayers:overlayLayers$|async,
|
||||
selectedItemLayer:selectedItemLayer$|async,
|
||||
features:features$|async,
|
||||
position:position$|async,
|
||||
parentCode:parentCode$|async,
|
||||
panelVisible:panelVisible$|async,
|
||||
openedModalName:openedModalName$|async,
|
||||
panelCollapsed:panelCollapsed$|async,
|
||||
searchMinified:searchMinified$|async,
|
||||
selectedItem:selectedItem$|async,
|
||||
queryState:queryState$|async,
|
||||
menuVisible:menuVisible$|async,
|
||||
searchCollapsed:searchCollapsed$|async,
|
||||
clearEnabled:clearEnabled$|async,
|
||||
period:period$|async
|
||||
} as state">
|
||||
<aol-map #map (moveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" [ngClass]="{'panel-visible':state.panelVisible}" class="map">
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<aol-view [zoom]="(mapState|async).zoom" [rotation]="(mapState|async).rotation">
|
||||
<aol-coordinate [x]="(mapState|async).xCenter" [y]="(mapState|async).yCenter" [srid]="'EPSG:4326'"></aol-coordinate>
|
||||
<fm-map-zoom-to-extent [extent]="extent|async" [animate]="true"></fm-map-zoom-to-extent>
|
||||
</aol-view>
|
||||
<aol-interaction-default></aol-interaction-default>
|
||||
<aol-interaction-dragrotateandzoom></aol-interaction-dragrotateandzoom>
|
||||
<fm-map-item-layers [itemLayers]="baseLayers|async"></fm-map-item-layers>
|
||||
<fm-map-item-layers [itemLayers]="overlayLayers|async"></fm-map-item-layers>
|
||||
<fm-map-item-layers [itemLayer]="selectedItemLayer|async"></fm-map-item-layers>
|
||||
<aol-layer-vector>
|
||||
<fm-map-item-source-vector [features]="features|async" (onFeaturesSelected)="handleFeaturesSelected($event)" [selectedFeature]="selectedFeature|async" [selectedItem]="selectedItem|async"></fm-map-item-source-vector>
|
||||
</aol-layer-vector>
|
||||
<fm-map-gps-location [position]="position|async" [headingTolerance]="20" [showHeading]="true"></fm-map-gps-location>
|
||||
<div class="control-container">
|
||||
<!-- <switch2d3d></switch2d3d>-->
|
||||
<fm-map-rotation-reset></fm-map-rotation-reset>
|
||||
</div>
|
||||
<fm-map-file-drop-target [parentCode]="(parentCode | async)" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target>
|
||||
</aol-map>
|
||||
<fm-map-map-search #mapSearch [openedModalName]="openedModalName|async" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':(menuVisible|async)}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="searchCollapsed|async" [searchMinified]="(searchMinified | async)" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="queryState|async" [clearEnabled]="clearEnabled|async" [period]="period|async"></fm-map-map-search>
|
||||
<fm-side-panel [resizeable]="true" [visible]="(panelVisible|async)" [collapsed]="(panelCollapsed|async)" [collapsable]="false">
|
||||
<div class="panel-wrapper">
|
||||
<div class="panel-top bg-secondary" *ngIf="!(searchMinified | async)">
|
||||
</div>
|
||||
<div class="panel-bottom">
|
||||
|
||||
<div *ngIf="!(selectedItem|async)">
|
||||
<fm-map-feature-list-container [features]="(features | async)" [queryState]="(queryState|async)"></fm-map-feature-list-container>
|
||||
<aol-view [zoom]="state.mapState.zoom" [rotation]="state.mapState.rotation">
|
||||
<aol-coordinate [x]="state.mapState.xCenter" [y]="state.mapState.yCenter" [srid]="'EPSG:4326'"></aol-coordinate>
|
||||
<fm-map-zoom-to-extent [extent]="state.extent" [animate]="true"></fm-map-zoom-to-extent>
|
||||
</aol-view>
|
||||
<aol-interaction-default></aol-interaction-default>
|
||||
<aol-interaction-dragrotateandzoom></aol-interaction-dragrotateandzoom>
|
||||
<fm-map-item-layers [itemLayers]="state.baseLayers"></fm-map-item-layers>
|
||||
<fm-map-item-layers [itemLayers]="state.overlayLayers"></fm-map-item-layers>
|
||||
<fm-map-item-layers [itemLayer]="state.selectedItemLayer"></fm-map-item-layers>
|
||||
<aol-layer-vector>
|
||||
<fm-map-item-source-vector [features]="state.features" (onFeaturesSelected)="handleFeaturesSelected($event)" [selectedFeature]="state.selectedFeature" [selectedItem]="state.selectedItem"></fm-map-item-source-vector>
|
||||
</aol-layer-vector>
|
||||
<fm-map-gps-location [position]="state.position" [headingTolerance]="20" [showHeading]="true"></fm-map-gps-location>
|
||||
<div class="control-container">
|
||||
<!-- <switch2d3d></switch2d3d>-->
|
||||
<fm-map-pan-to-location [position]="state.position" [mapState]="state.mapState" [animate]="true"></fm-map-pan-to-location>
|
||||
<fm-map-rotation-reset></fm-map-rotation-reset>
|
||||
</div>
|
||||
<fm-map-file-drop-target [parentCode]="state.parentCode" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target>
|
||||
</aol-map>
|
||||
<fm-map-map-search #mapSearch [openedModalName]="state.openedModalName" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':state.menuVisible}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="state.searchCollapsed" [searchMinified]="state.searchMinified" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="state.queryState" [clearEnabled]="state.clearEnabled" [period]="state.period"></fm-map-map-search>
|
||||
<fm-side-panel [resizeable]="true" [visible]="state.panelVisible" [collapsed]="state.panelCollapsed" [collapsable]="false">
|
||||
<div class="panel-wrapper">
|
||||
<div class="panel-top bg-secondary" *ngIf="!(state.searchMinified)">
|
||||
</div>
|
||||
<div class="panel-bottom">
|
||||
|
||||
<div *ngIf="(selectedItem | async);let item">
|
||||
<fm-map-selected-item-container [item]="item"></fm-map-selected-item-container>
|
||||
</div>
|
||||
<div *ngIf="(features|async).length == 0" class="no-results m-2">
|
||||
<div *ngIf="(queryState|async)?.query">Cannot find <span>{{(queryState|async)?.query}}</span></div>
|
||||
<div *ngIf="(queryState|async)?.tags">Cannot find tag <span>{{(queryState|async)?.tags}}</span></div>
|
||||
<div *ngIf="!(state.selectedItem)">
|
||||
<fm-map-feature-list-container [features]="state.features" [queryState]="state.queryState"></fm-map-feature-list-container>
|
||||
</div>
|
||||
|
||||
<div *ngIf="state.selectedItem;let item">
|
||||
<fm-map-selected-item-container [item]="item"></fm-map-selected-item-container>
|
||||
</div>
|
||||
<div *ngIf="state.features.length == 0" class="no-results m-2">
|
||||
<div *ngIf="state.queryState.query">Cannot find <span>{{state.queryState?.query}}</span></div>
|
||||
<div *ngIf="state.queryState?.tags">Cannot find tag <span>{{state.queryState?.tags}}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fm-side-panel>
|
||||
<fm-side-panel [visible]="(menuVisible|async)" class="menu">
|
||||
<div class="container-fluid">
|
||||
<div class="body">
|
||||
<div class="d-flex flex-row">
|
||||
<div class="mt-2 mb-2 flex-grow-1 logo"><router-outlet name="side-panel-logo"></router-outlet></div>
|
||||
<div class="mt-2 mb-2 ml-2"><button type="button" class="btn btn-outline-secondary" (click)="handleToggleMenu($event)"><i class="fa fa-times" aria-hidden="true"></i></button></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column cards">
|
||||
<router-outlet name="side-panel-menu"></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fm-side-panel>
|
||||
</fm-side-panel>
|
||||
<fm-side-panel [visible]="state.menuVisible" class="menu">
|
||||
<div class="container-fluid">
|
||||
<div class="body">
|
||||
<div class="d-flex flex-row">
|
||||
<div class="mt-2 mb-2 flex-grow-1 logo"><router-outlet name="side-panel-logo"></router-outlet></div>
|
||||
<div class="mt-2 mb-2 ml-2"><button type="button" class="btn btn-outline-secondary" (click)="handleToggleMenu($event)"><i class="fa fa-times" aria-hidden="true"></i></button></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column cards">
|
||||
<router-outlet name="side-panel-menu"></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fm-side-panel>
|
||||
</ng-container>
|
||||
|
||||
|
||||
|
@ -40,39 +40,39 @@ import { tassign } from 'tassign';
|
||||
|
||||
export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
title: string = 'Map';
|
||||
public openedModalName: Observable<string>;
|
||||
public itemTypes: Observable<{ [id: string]: IItemType }>;
|
||||
public mapState: Observable<IMapState>;
|
||||
public features: Observable<Array<Feature>>;
|
||||
public overlayLayers: Observable<Array<IItemLayer>>;
|
||||
public selectedOverlayLayer: Observable<IItemLayer>;
|
||||
public selectedItemLayer: Observable<IItemLayer>;
|
||||
public baseLayers: Observable<Array<IItemLayer>>;
|
||||
public selectedBaseLayer: Observable<IItemLayer>;
|
||||
public projection: Observable<string>;
|
||||
public selectedFeatures: Subject<ISelectedFeatures> = new Subject<ISelectedFeatures>();
|
||||
public droppedFile: Subject<IDroppedFile> = new Subject<IDroppedFile>();
|
||||
public openedModalName$: Observable<string>;
|
||||
public itemTypes$: Observable<{ [id: string]: IItemType }>;
|
||||
public mapState$: Observable<IMapState>;
|
||||
public features$: Observable<Array<Feature>>;
|
||||
public overlayLayers$: Observable<Array<IItemLayer>>;
|
||||
public selectedOverlayLayer$: Observable<IItemLayer>;
|
||||
public selectedItemLayer$: Observable<IItemLayer>;
|
||||
public baseLayers$: Observable<Array<IItemLayer>>;
|
||||
public selectedBaseLayer$: Observable<IItemLayer>;
|
||||
public projection$: Observable<string>;
|
||||
public selectedFeatures$: Subject<ISelectedFeatures> = new Subject<ISelectedFeatures>();
|
||||
public droppedFile$: Subject<IDroppedFile> = new Subject<IDroppedFile>();
|
||||
private paramSub: Subscription;
|
||||
private itemTypeSub: Subscription;
|
||||
private mapStateSub: Subscription;
|
||||
private queryStateSub: Subscription;
|
||||
public parentCode: Observable<string>;
|
||||
public panelVisible: Observable<boolean>;
|
||||
public panelCollapsed: Observable<boolean>;
|
||||
public selectedFeature: Observable<Feature>;
|
||||
public selectedItem: Observable<IItem>;
|
||||
public queryState: Observable<IQueryState>;
|
||||
public period: Observable<IPeriodState>;
|
||||
public clearEnabled: Observable<boolean>;
|
||||
public searchCollapsed: Observable<boolean>;
|
||||
public searchMinified: Observable<boolean>;
|
||||
public menuVisible: Observable<boolean>;
|
||||
public query: Observable<IQueryState>;
|
||||
public position: Observable<Position>;
|
||||
public parentCode$: Observable<string>;
|
||||
public panelVisible$: Observable<boolean>;
|
||||
public panelCollapsed$: Observable<boolean>;
|
||||
public selectedFeature$: Observable<Feature>;
|
||||
public selectedItem$: Observable<IItem>;
|
||||
public queryState$: Observable<IQueryState>;
|
||||
public period$: Observable<IPeriodState>;
|
||||
public clearEnabled$: Observable<boolean>;
|
||||
public searchCollapsed$: Observable<boolean>;
|
||||
public searchMinified$: Observable<boolean>;
|
||||
public menuVisible$: Observable<boolean>;
|
||||
public query$: Observable<IQueryState>;
|
||||
public position$: Observable<Position>;
|
||||
public baseLayersCollapsed:boolean = true;
|
||||
public overlayLayersCollapsed: boolean = true;
|
||||
public extent: Observable<Extent>;
|
||||
@ViewChild('map', { static: true }) map;
|
||||
public extent$: Observable<Extent>;
|
||||
@ViewChild('map', { static: false }) map;
|
||||
|
||||
constructor(private store: Store<mapReducers.State | commonReducers.State>,
|
||||
private route: ActivatedRoute,
|
||||
@ -81,8 +81,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
private serializeService: StateSerializerService,
|
||||
public itemTypeService: ItemTypeService,
|
||||
private location: Location,
|
||||
private geolocationService: GeolocationService,
|
||||
private _ref: ChangeDetectorRef ) {
|
||||
private geolocationService: GeolocationService) {
|
||||
}
|
||||
|
||||
@HostListener('document:keyup', ['$event'])
|
||||
@ -118,36 +117,36 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
|
||||
ngOnInit() {
|
||||
this.store.dispatch(new mapActions.Init());
|
||||
this.selectedFeatures.next({x:0,y:0,features:[]});
|
||||
this.mapState = this.store.select(mapReducers.selectGetMapState);
|
||||
this.parentCode = this.store.select(mapReducers.selectGetParentCode);
|
||||
this.features = this.store.select(mapReducers.selectGetFeatures);
|
||||
this.overlayLayers = this.store.select(mapReducers.selectGetOverlayLayers);
|
||||
this.selectedOverlayLayer = this.store.select(mapReducers.selectGetSelectedOverlayLayer);
|
||||
this.baseLayers = this.store.select(mapReducers.selectGetBaseLayers);
|
||||
this.projection = this.store.select(mapReducers.selectGetProjection);
|
||||
this.selectedBaseLayer = this.store.select(mapReducers.selectGetSelectedBaseLayer);
|
||||
this.panelVisible = this.store.select(mapReducers.selectGetPanelVisible);
|
||||
this.panelCollapsed = this.store.select(mapReducers.selectGetPanelCollapsed);
|
||||
this.selectedFeature = this.store.select(mapReducers.selectGetSelectedFeature);
|
||||
this.selectedItem = this.store.select(mapReducers.selectGetSelectedItem);
|
||||
this.queryState = this.store.select(mapReducers.selectGetQueryState);
|
||||
this.clearEnabled = this.store.select(mapReducers.selectGetClearEnabled);
|
||||
this.searchCollapsed = this.store.select(mapReducers.selectGetSearchCollapsed);
|
||||
this.searchMinified = this.store.select(mapReducers.selectGetSearchMinified);
|
||||
this.menuVisible = this.store.select(mapReducers.selectGetMenuVisible);
|
||||
this.openedModalName = this.store.select(commonReducers.selectOpenedModalName);
|
||||
this.query = this.store.select(mapReducers.selectGetQuery);
|
||||
this.extent = this.store.select(mapReducers.selectGetExtent);
|
||||
this.selectedFeatures.next(null);
|
||||
this.selectedItemLayer = this.store.select(mapReducers.selectGetSelectedItemLayer);
|
||||
this.period = this.store.select(mapReducers.selectGetPeriod);
|
||||
this.position = this.geolocationService.getCurrentPosition();
|
||||
this.selectedFeatures$.next({x:0,y:0,features:[]});
|
||||
this.mapState$ = this.store.select(mapReducers.selectGetMapState);
|
||||
this.parentCode$ = this.store.select(mapReducers.selectGetParentCode);
|
||||
this.features$ = this.store.select(mapReducers.selectGetFeatures);
|
||||
this.overlayLayers$ = this.store.select(mapReducers.selectGetOverlayLayers);
|
||||
this.selectedOverlayLayer$ = this.store.select(mapReducers.selectGetSelectedOverlayLayer);
|
||||
this.baseLayers$ = this.store.select(mapReducers.selectGetBaseLayers);
|
||||
this.projection$ = this.store.select(mapReducers.selectGetProjection);
|
||||
this.selectedBaseLayer$ = this.store.select(mapReducers.selectGetSelectedBaseLayer);
|
||||
this.panelVisible$ = this.store.select(mapReducers.selectGetPanelVisible);
|
||||
this.panelCollapsed$ = this.store.select(mapReducers.selectGetPanelCollapsed);
|
||||
this.selectedFeature$ = this.store.select(mapReducers.selectGetSelectedFeature);
|
||||
this.selectedItem$ = this.store.select(mapReducers.selectGetSelectedItem);
|
||||
this.queryState$ = this.store.select(mapReducers.selectGetQueryState);
|
||||
this.clearEnabled$ = this.store.select(mapReducers.selectGetClearEnabled);
|
||||
this.searchCollapsed$ = this.store.select(mapReducers.selectGetSearchCollapsed);
|
||||
this.searchMinified$ = this.store.select(mapReducers.selectGetSearchMinified);
|
||||
this.menuVisible$ = this.store.select(mapReducers.selectGetMenuVisible);
|
||||
this.openedModalName$ = this.store.select(commonReducers.selectOpenedModalName);
|
||||
this.query$ = this.store.select(mapReducers.selectGetQuery);
|
||||
this.extent$ = this.store.select(mapReducers.selectGetExtent);
|
||||
this.selectedFeatures$.next(null);
|
||||
this.selectedItemLayer$ = this.store.select(mapReducers.selectGetSelectedItemLayer);
|
||||
this.period$ = this.store.select(mapReducers.selectGetPeriod);
|
||||
this.position$ = this.geolocationService.getCurrentPosition();
|
||||
|
||||
this.mapState.pipe(withLatestFrom(this.queryState)).subscribe((state) => {
|
||||
this.mapState$.pipe(withLatestFrom(this.queryState$)).subscribe((state) => {
|
||||
this.replaceUrl(state[0], state[1], true);
|
||||
});
|
||||
this.query.pipe(withLatestFrom(this.mapState)).subscribe((state) => {
|
||||
this.query$.pipe(withLatestFrom(this.mapState$)).subscribe((state) => {
|
||||
this.replaceUrl(state[1], state[0],false);
|
||||
});
|
||||
}
|
||||
@ -194,9 +193,9 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
}
|
||||
this.stateSetCount += 1;
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.map.instance.updateSize();
|
||||
}, 500);
|
||||
// setTimeout(() => {
|
||||
// this.map.instance.updateSize();
|
||||
// }, 500);
|
||||
}
|
||||
|
||||
handleSearchCollapse(event) {
|
||||
@ -245,7 +244,6 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
parts.push(mapState.baseLayerCode);
|
||||
parts.push( this.serializeService.serialize(queryState));
|
||||
this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent });
|
||||
this._ref.markForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,7 +257,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
|
||||
let mapState: IMapState = { xCenter: center[0], yCenter: center[1], zoom: zoom, rotation: rotation, baseLayerCode: null };
|
||||
let state = { mapState: mapState, extent: extent };
|
||||
let source = from([state]);
|
||||
source.pipe(withLatestFrom(this.selectedBaseLayer), withLatestFrom(this.queryState)).subscribe(([[state, baselayer], queryState]) => {
|
||||
source.pipe(withLatestFrom(this.selectedBaseLayer$), withLatestFrom(this.queryState$)).subscribe(([[state, baselayer], queryState]) => {
|
||||
if (mapState && baselayer && queryState) {
|
||||
let newMapState = tassign(state.mapState, { baseLayerCode: baselayer.item.code });
|
||||
this.replaceUrl(newMapState, tassign(queryState, { bbox: queryState.bboxFilter ? state.extent : queryState.bbox }));
|
||||
|
Loading…
Reference in New Issue
Block a user