简体   繁体   English

Map 即将出现未定义 - OpenLayers

[英]Map is coming up as undefined - OpenLayers

I am experiencing a strange issue.我遇到了一个奇怪的问题。 I am receiving an error message that reads "ERROR TypeError: Cannot read properties of null (reading 'map_') on line 29".我收到一条错误消息,内容为“错误类型错误:无法在第 29 行读取 null 的属性(读取 'map_')”。 Even though I am able to loop the layers on the map to get the list of features on hover (line 23).即使我能够循环 map 上的层以获取 hover 上的功能列表(第 23 行)。 Please see my code below and let me know if you have any advice on what I can do to fix this.请在下面查看我的代码,如果您对我可以做些什么来解决这个问题有任何建议,请告诉我。

The way this is set up is, that my component is using a service that holds the information about the map and overlay.设置的方式是,我的组件正在使用一个服务,该服务包含有关 map 和覆盖的信息。 All I want to do is set the position of overlay on hover.我要做的就是在 hover 上设置覆盖的 position。

Component零件

import { Component, OnInit } from '@angular/core';
    import { Map } from 'ol';
    import { GeneralMapService } from 'src/app/services/general-map.service';
    
    @Component({
      selector: 'app-application-map',
      templateUrl: './application-map.component.html',
      styleUrls: ['./application-map.component.css']
    })
    
    export class WhereisMapComponent implements OnInit {

  map_: Map;
  overlay: any;

  constructor(private generalMap: GeneralMapService) {
    this.map_ = this.generalMap.map
    
    this.map_.on("pointermove", (e) => {
      
      const positionOfMouse = e.coordinate
      
      this.map_.forEachFeatureAtPixel(e.pixel, function (feature) {
        
        if (feature) {
          const { as_tr_name, ass_track, id, descriptio, media } = feature.getProperties();

          // I receive an error message here.
          console.log(this.map_.getView())
          this.map_.getView().mapOverlay.setPosition(positionOfMouse);
        }

      })

    })

    this.overlay = document.getElementById('informationOverlay')
    this.generalMap.mapOverlay.set("id", "informationOverlay")
    this.generalMap.mapOverlay.setElement(this.overlay)

  }

  ngOnInit(): void {
  }

  ngAfterViewInit() {
    this.map_.setTarget("map")  

  }

}

General Service一般事务

import { Injectable } from '@angular/core';
import { Map, Overlay, Tile, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import { Zoom, ZoomSlider, FullScreen } from 'ol/control';
import XYZ from 'ol/source/XYZ';
import BingMaps from 'ol/source/BingMaps';
import LayerGroup from 'ol/layer/Group';

import { mapDefaultCenter, mapeDefaultZoom } from '../shared/maptilerkey';
import { CreateLayerService } from './create-layer.service';
import { Fill, Stroke, Style } from 'ol/style';
import CircleStyle from 'ol/style/Circle';
import { OverlayService } from './overlay.service';

@Injectable({
  providedIn: 'root'
})
export class GeneralMapService {

  map: Map;
  zoomSlider: ZoomSlider = new ZoomSlider({
    className: "zoom-slider-dashboard"
  })
  mapLayers: LayerGroup = new LayerGroup({
    layers: []
  })
  mapOverlay: Overlay;

  constructor(private createLayers: CreateLayerService, overlayService: OverlayService) {

    const topographicLayer = new TileLayer({
      source: new XYZ({
        url: "https://api.maptiler.com/maps/topographique/{z}/{x}/{y}@2x.png?key=WYPadsIvfisd0PUHFJ6K"
      }),
      visible: false
    })
    topographicLayer.set('name', 'topographic');

    const openStreetMap = new TileLayer({
      source: new OSM(),
      visible: true
    })
    openStreetMap.set('name', 'openstreetmap');

    const bingMaps = new TileLayer({
      preload: Infinity,

      source: new BingMaps({
        key: 'AngczjEvgHNjwD8lTQe3DJ6CoFxavJfGTFCxxaGbS3bIgUW5_qn4k_m510RR53fe',
        imagerySet: "Aerial",
        hidpi: true,
        maxZoom: 19
      }),
      visible: false
    })
    bingMaps.set('name', 'bingmap');

    this.map = new Map({
      view: new View({
        center: mapDefaultCenter,
        zoom: mapeDefaultZoom,
        minZoom: 5,
        projection: "EPSG:3857",
        extent: [15766342.542104144, -5590291.031415702, 16739198.402589425, -4713511.626202316]
      }),
      controls: []
    })

    const mapLayerGroup = new LayerGroup({
      layers: [topographicLayer, openStreetMap, bingMaps]
    })

    this.map.setLayerGroup(mapLayerGroup)
    this.map.addControl(this.zoomSlider)

    // vector layer
    const walkPointStyle = new Style({
      image: new CircleStyle({
        radius: 6,
        fill: new Fill({
          color: '#44c4a1',
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 2,
        }),
      }),
    })

    const walkPoints = this.createLayers.createVectorLayer("/assets/data/walking-data.geojson", walkPointStyle)
    const builtMapLayers = [
      walkPoints
    ]

    this.map.getLayers().extend(builtMapLayers)

    // Overlay registration
    this.mapOverlay = overlayService.overlay
    this.map.addOverlay(this.mapOverlay)
    console.log("this.map", this.map.getOverlays())

  }

  ngAfterContentInit() {

  }

  returnMap() {
    return this.map;
  }

  setMap(updatedMap: Map) {
    this.map = updatedMap;
  }
}

Any sort of help would be appreciated!任何形式的帮助将不胜感激!

It looks like you need to store context somewhere and then try to use that context forEachFeatureAtPixel method.看起来您需要在某处存储上下文,然后尝试使用该上下文forEachFeatureAtPixel方法。

Let me show an example:让我举个例子:

let that = this;

this.map_.forEachFeatureAtPixel(e.pixel, function (feature) {
        
    if (feature) {
      // ... other code is omitted for the brevity
     
      console.log(that.map_.getView())
      that.map_.getView().mapOverlay.setPosition(positionOfMouse);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM