Bing Map V8 读取 GeoJson 查找质心并添加图钉
Bing Map V8 Read GeoJson Find Centroid and add pushpin
以下是我的 GeoJson 代码,用于在 bing 地图上读取文件和显示数据层。我想在 GeoJson 函数中为每个 polygon/Multipolygon 找到质心,并为每个质心添加图钉。
当我尝试使用 shapes[i].getCenter() 查找中心时,它抛出错误 "shapes[i].getCenter is not a function".
如何在从文件中读取 GeoJson 时找到质心并添加引脚?
我参考这个例子来寻找质心。
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() {
}
}
centroid
方法在 SpatialMath
模块中,因此首先您需要像使用 GeoJson
:
一样加载它
Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson', 'Microsoft.Maps.SpatialMath'], function () {...});
然后在回调函数中,可以使用Microsoft.Maps.SpatialMath.Geometry.centroid(shapes[i])
获取质心位置
以下是我的 GeoJson 代码,用于在 bing 地图上读取文件和显示数据层。我想在 GeoJson 函数中为每个 polygon/Multipolygon 找到质心,并为每个质心添加图钉。
当我尝试使用 shapes[i].getCenter() 查找中心时,它抛出错误 "shapes[i].getCenter is not a function".
如何在从文件中读取 GeoJson 时找到质心并添加引脚?
我参考这个例子来寻找质心。
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() {
}
}
centroid
方法在 SpatialMath
模块中,因此首先您需要像使用 GeoJson
:
Microsoft.Maps.loadModule(['Microsoft.Maps.GeoJson', 'Microsoft.Maps.SpatialMath'], function () {...});
然后在回调函数中,可以使用Microsoft.Maps.SpatialMath.Geometry.centroid(shapes[i])
获取质心位置