【问题标题】:Bing Map V8 Read GeoJson Find Centroid and add pushpinBing Map V8 读取 GeoJson 查找质心并添加图钉
【发布时间】:2019-01-07 17:19:36
【问题描述】:

以下是我的 GeoJson 代码,用于读取文件并在 bing 地图上显示数据层。我想为 GeoJson 函数中的每个多边形/多多边形找到质心,并为每个质心添加图钉。

当我尝试使用 shape[i].getCenter() 查找中心时,它会抛出错误“shapes[i].getCenter 不是函数”。

从文件中读取 GeoJson 时如何找到质心并添加 pin ?

我指的是这个例子来寻找质心。

https://www.bing.com/api/maps/sdk/mapcontrol/isdk#getCentroid+JS

import { ViewContainerRef, Component, ElementRef, OnInit, ViewChild, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { MapService } from '../../services/map.service';
import { CookieService } from 'ngx-cookie';
import { Config } from '../../config/config';
import { CommonUtils } from './../../shared/CommonUtils';
import { fail, throws } from 'assert';
import { Toast, ToastsManager } from 'ng2-toastr/ng2-toastr';
import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks';
import { DeviceDetectorService } from 'ngx-device-detector';

declare const Microsoft: any;

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})

export class MapComponent implements OnInit, OnDestroy {
  map: any;
  infobox: any;
  dataLayer: any;
  heatGradientData: any;

  @ViewChild('mapElement') someInput: ElementRef;
  myMap = document.querySelector('#myMap');

  constructor(private mapService: MapService,
    private router: Router, private config: Config,
    private utils: CommonUtils,
    private cookieService: CookieService,
    public toastr: ToastsManager, vRef: ViewContainerRef,
    private deviceService: DeviceDetectorService,
    private zone: NgZone) {
    this.toastr.setRootViewContainerRef(vRef);
  }

  ngOnInit() {

    if (document.readyState != 'complete') {
      document.onreadystatechange = () => {
        if (document.readyState === 'complete') {
          this.loadMapView(this.config.getConstants('mapTypeRoad'));
        } else {
          this.ngOnInit();
        }
      }
    } else {
      if (document.readyState === 'complete') {
        this.loadMapView(this.config.getConstants('mapTypeRoad'));
      }
    }

  }

  loadMapView(type: String) {

    var location = new Microsoft.Maps.Location(53.32, -110.29);

    this.map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
      credentials: this.config.get('BingMapKey'),
      center: location,
      mapTypeId: type == this.config.getConstants('mapTypeSatellite') ? Microsoft.Maps.MapTypeId.aerial : Microsoft.Maps.MapTypeId.road,
      zoom: 4,
      liteMode: true,
      enableClickableLogo: false,
      showLogo: false,
      showTermsLink: false,
      showMapTypeSelector: false,
      showTrafficButton: true,
      enableSearchLogo: false,
      showCopyright: false
    });

    //Store some metadata with the pushpin
    this.infobox = new Microsoft.Maps.Infobox(this.map.getCenter(), {
      visible: false
    });

    this.infobox.setMap(this.map);

    // Load the Spatial Math module.
    Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson'], function () { });

    // Create a layer to load pushpins to.
    // this.dataLayer = new Microsoft.Maps.EntityCollection();

    //Create a layer to add the GeoJSON data to.
    this.dataLayer = new Microsoft.Maps.Layer();
    this.map.layers.insert(this.dataLayer);

    //Add click event to the layer.
    //Microsoft.Maps.Events.addHandler(this.dataLayer, 'click', this.showInfobox);

    this.ReadGeoJson();

  }

  ReadGeoJson() {

    var self = this;

    //Load the GeoJSON module and read the GeoJSON feed.
    Microsoft.Maps.loadModule('Microsoft.Maps.GeoJson', function () {
      Microsoft.Maps.GeoJson.readFromUrl('../../assets/US_County_Boundaries.js', function (shapes) {
        //Add shapes to the layer.
        for (var i = 0, len = shapes.length; i < len; i++) {

          //Create custom Pushpin using an SVG string.
          // var pin = new Microsoft.Maps.Pushpin(shapes[i].getCenter(), {
          //   icon: '<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30"><circle cx="15" cy="15" r="13" stroke="black" stroke-width="2" fill="{color}"/><text x="15" y="20" text-anchor="middle">{text}</text></svg>',
          //   color: 'yellow',
          //   text: '1',
          //   anchor: new Microsoft.Maps.Point(20, 20)
          // });

          // //Add the pushpin to the map.
          // self.map.entities.push(pin);
          Microsoft.Maps.Events.addHandler(shapes[i], 'click', showInfobox);
        }

        self.dataLayer.add(shapes);

        function showInfobox(e) {
          var shape = e.target;
          var loc = e.location; //Default to the location of the mouse event to show the infobox.

          //If the shape is a pushpin, use it's location to display the infobox.
          if (shape instanceof Microsoft.Maps.Pushpin) {
            loc = shape.getLocation();
          }
          //Display the infoboc
          self.infobox.setOptions({ location: loc, title: shape.metadata.NAME, visible: true });
        }
      });
    });
  }

  ngOnDestroy() {

  }

}

【问题讨论】:

    标签: angular bing-maps


    【解决方案1】:

    centroid 方法在SpatialMath 模块中,所以首先你需要像使用GeoJson 一样加载它:

    Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson', 'Microsoft.Maps.SpatialMath'], function () {...});

    然后在回调函数中,可以使用Microsoft.Maps.SpatialMath.Geometry.centroid(shapes[i])获取质心位置。

    【讨论】:

    • 感谢您的回复。我知道质心在空间模块中,但是如何在读取 GeoJSON 并在回调函数中获取质心后获取多边形?
    • 如前所述,首先需要加载模块,并在其回调中使用 readFromUrl 解析 GeoJson。现在,readFromUrl 返回一个形状列表作为它自己的回调的输入参数,所以在 readFromUrl 的回调中你可以循环遍历形状并调用 centroid 方法。请参阅上面的修改。
    • 谢谢 J S。它对我有用。我可以用同样的方式添加图钉吗?
    • 是的 - 获得质心位置后,只需使用它来创建图钉。或一通电话:new Microsoft.Maps.Pushpin(Microsoft.Maps.SpatialMath.Geometry.centroid(shapes[i]), {...})
    • 现在我可以在 for 循环中添加图钉,但添加图钉后我看不到多边形颜色。我只能看到图钉。如果我删除图钉,那么它会显示带有颜色的多边形。可能是什么问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多