ngx-mapbox-gl:溢出div

时间:2019-03-16 02:04:53

标签: angular mapbox-gl

我试图在Angular 7应用程序中首次使用ngx-mapbox-gl,并且遇到了一些奇怪的问题。我希望它占据导航栏下面的窗口的100%。但是由于某种原因,它所占用的空间超过了窗口大小。请注意,我是如何丢失归因和mapbox徽标的?我只希望地图适合窗口,仅此而已。 enter image description here

以下是html组件:​​

  

<mgl-map
  [style]="mapStyle"
  [zoom]="_zoom"
  [center]="_center"
  (load)="loadMap($event)"
  (zoomEnd)="onZoom($event)"
>
  <mgl-control
      mglScale
      unit="imperial"
      position="top-right">
  </mgl-control>
  <p>some text</p>
</mgl-map>
</mat-card-content>
</mat-card>

和ts:

import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { Subscription } from 'rxjs';
import { AppSettings } from '../../shared/app-settings'
import { AppSettingsService } from '../../services/app-settings.service';

import { LngLat, Map } from 'mapbox-gl';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnChanges {
  private className: string;
  appSettings: AppSettings;
  appSettingsSub: Subscription;
  map: Map;
  mapStyle: string;
  _zoom: number;
  _center: LngLat;

  //refs
  _mapRef: Map;

  @Output()
  centerChange: EventEmitter<LngLat> =  new EventEmitter;

  @Input()
  set zoom(z: number) {
    console.log('in zoom event');
    this._zoom = z;
    if(this.index === 0) {
      this.zoomChange.emit(this._zoom);
    }
  }
  @Output()
  zoomChange : EventEmitter<number> = new EventEmitter;

  @Input()
  index: number;

  constructor(public appSettingsService: AppSettingsService) { }

  ngOnInit() {
    this.className = this.constructor.toString().match(/\w+/g)[1];
    this._zoom = 6;

    this.appSettingsSub =     this.appSettingsService.behaviorSubject.asObservable().subscribe(value => {
      this.appSettings = value;
      if ( this.appSettings.norCalMapCenter == true ) {
        this._center = new LngLat( -121.31209, 37.449904  );
      }
      else {
        this._center = new LngLat(  -116.363804, 33.749757  );
      }
      if (this.appSettings.theme === 'tracs-dark-theme') {
        this.mapStyle = 'mapbox://styles/mapbox/dark-v9';
      }
      else {
        this.mapStyle = 'mapbox://styles/mapbox/outdoors-v9';
      }
    });

  }
  ngOnChanges(changes) {
    if (!changes) {
      return;
    }
  }
  loadMap( map: Map) {
    this._mapRef = map;
    this._center = map.getCenter();
  }

  onZoom(e) {
    this._zoom = Math.round(this._mapRef.getZoom());
    console.log('zoom event zoom:', this._zoom);
  };
}

和CSS:

mgl-map {
  height: 100%;
  width: 100%;
}

此外,我无法在地图顶部显示文字。我有一个想在地图顶部显示的简单段落,但文本从未显示。要在地图顶部显示某些内容,是否需要对图层或z级进行处理?

2 个答案:

答案 0 :(得分:0)

如果像这样单独设置身高100%,则不代表您拥有的导航栏。

您需要执行以下操作: 高度:calc(100%-100px)

100像素是导航栏的高度。尝试该解决方案。

答案 1 :(得分:0)

要回答有关在地图顶部显示段落的第二个问题:

您不需要 来调整z-index,而是将段落位置设为绝对。我已经将地图包装在父div中。我已将父div设置为填充可用屏幕减去顶部工具栏的高度。然后,我只需将地图元素的高度和宽度都设置为100%。 map元素和段落元素都是父div的子元素。该地图将默认为position: relative,然后通过在段落上设置position: absolute,可以精确控制您希望将其放置在何处。

map.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { map, switchMap } from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { Directions } from 'src/app/shared/models/directions.model';
import { NavigationService } from '../navigation.service';
import { SubSink } from 'subsink';

@Component({
  selector: 'nav-to-taylor-park',
  templateUrl: './nav-to-taylor-park.component.html',
  styleUrls: ['./nav-to-taylor-park.component.scss']
})
export class NavToTaylorParkComponent implements OnInit, OnDestroy {

  private _subs: SubSink = new SubSink();

  isMobile$ = this._bpObserver.observe([Breakpoints.Handset, Breakpoints.TabletPortrait])
    .pipe(map(result => result.matches)
  );

  directions$: Observable<Directions>;

  private _profiles: any[] = [
    { name: 'driving', value: 'driving' },
    { name: 'traffic', value: 'driving-traffic' },
    { name: 'walking', value: 'walking '},
    { name: 'cycling', value: 'cycling' }
  ];

  private _selectedProfile: string = this._profiles[0].value;

  constructor(
    private _bpObserver: BreakpointObserver,
    private _route: ActivatedRoute,
    private _navService: NavigationService
  ) { }

  get profiles() {
    return this._profiles;
  }

  get selectedProfile() {
    return this._selectedProfile;
  }

  set selectedProfile(val: string) {
    this._selectedProfile = val;
  }

  ngOnInit() {
    this.directions$ = this._route.paramMap.pipe(
      switchMap(params => {
        return this._navService.getDrivingDirections(params.get('pts'), this._selectedProfile)
      })
    );

    this._subs.sink = this.directions$.subscribe(dirs => console.log('Dirs in Nav Comp: ', dirs), 
      error => console.log('Error in Directions Subscription', error)
    );

  }

  ngOnDestroy() {
    if (this._subs) this._subs.unsubscribe();
  }

}

map.html

<div [class]="(isMobile$ | async) ? 'jumbotron-fluid mobile mb-0' : 'jumbotron-fluid mb-0'">
  <mgl-map 
    [style]="'mapbox://styles/mapbox/navigation-guidance-day-v2'" 
    [zoom]="[10]"
    [center]="[-106.58305214873641, 38.89357626425448]"
    [pitch]="[45]"
    *ngIf="directions$ | async as nav">
    <mgl-control mglNavigation></mgl-control>
    <mgl-control mglFullscreen></mgl-control>
    <mgl-marker *ngFor="let pt of nav.waypoints"
      [lngLat]="pt.location">
      <div class="marker">{{ pt.name }}</div>
    </mgl-marker>
  </mgl-map>
  <div class="on-map">
    This should be on top of map...
  </div>
</div>

map.scss

<div [class]="(isMobile$ | async) ? 'jumbotron-fluid mobile mb-0' : 'jumbotron-fluid mb-0'">
  <mgl-map 
    [style]="'mapbox://styles/mapbox/navigation-guidance-day-v2'" 
    [zoom]="[10]"
    [center]="[-106.58305214873641, 38.89357626425448]"
    [pitch]="[45]"
    *ngIf="directions$ | async as nav">
    <mgl-control mglNavigation></mgl-control>
    <mgl-control mglFullscreen></mgl-control>
    <mgl-marker *ngFor="let pt of nav.waypoints"
      [lngLat]="pt.location">
      <div class="marker">{{ pt.name }}</div>
    </mgl-marker>
  </mgl-map>
  <div class="on-map">
    This should be on top of map...
  </div>
</div>

screenshot