[英]TypeScript + OpenLayers 7: Set and get feature id fails
我有一個帶有兩個自定義按鈕的 map: Draw Polygon和Remove Feature ,它允許我繪制和刪除繪制的多邊形。 此外,我為顯示其面積的多邊形創建了一個測量疊加層(見圖)。 為了識別多邊形和覆蓋之間的連接,我嘗試在它們上設置相同的 id,以便在刪除多邊形時可以找到並刪除覆蓋:
const featureId = feature.get('id')
const overlay = map.getOverlayById(featureId)
map.removeOverlay(overlay)
但是,當嘗試讀取多邊形的 id 時,它總是返回 undefined。 我還嘗試將 id 設置為屬性並獲取它,但這也失敗了。
為了更容易跟隨:
import Map from 'ol/Map'
import OSM from 'ol/source/OSM'
import Draw from 'ol/interaction/Draw';
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import View from 'ol/View'
import { Control } from 'ol/control'
import { Geometry } from 'ol/geom';
import { transform, useGeographic } from 'ol/proj';
import Feature, { FeatureLike } from 'ol/Feature';
import { Overlay } from 'ol';
import { getArea } from 'ol/sphere';
import { unByKey } from 'ol/Observable';
import { EventsKey } from 'ol/events';
import { Coordinate } from 'ol/coordinate';
/**
* Map component
*/
export default class MapComponent {
map: Map
featureLayer: FeatureLayer
constructor() {
useGeographic()
this.map = new Map({
controls: [],
layers: [
new TileLayer({
source: new OSM(),
})
],
view: new View({
center: [0, 0],
zoom: 2
}),
target: "map"
})
this.featureLayer = new FeatureLayer()
// Add Feature Layer
this.map.addLayer(this.featureLayer)
// Add Custom Controls to Draw- and Remove Polygon
this.map.addControl(new DrawPolygonButton(this, this.map))
this.map.addControl(new RemovePolygonButton(this, this.map))
}
public getFeatureLayer(): FeatureLayer {
return this.featureLayer
}
public getMap() {
return this.map
}
}
/**
* This is the layer we want to draw the polygon (feature) on
*/
class FeatureLayer extends VectorLayer<VectorSource<Geometry>> {
constructor() {
super({
source: new VectorSource(),
properties: {
title: 'featureLayer'
}
})
}
}
/**
* A button which starts the drawing process
*/
class DrawPolygonButton extends Control {
constructor(mapComponent: MapComponent, map: Map) {
const button = document.createElement('button')
button.innerHTML = 'Draw Polygon'
super({ element: button })
button.addEventListener('click', () => {
const featureLayerSource = mapComponent.getFeatureLayer()?.getSource()
if (featureLayerSource) {
new Polygon(map, featureLayerSource)
}
})
}
}
/**
* A button which should listen to clicking on the map, and if it hits a polygon on the
* FeatureLayer it should remove it
*/
class RemovePolygonButton extends Control {
constructor(mapComponent: MapComponent, map: Map) {
const button = document.createElement('button')
button.innerHTML = 'Remove Feature'
super({ element: button })
button.addEventListener('click', () => {
map.on('click', (evt: any) => {
try {
const featureLayerSource = mapComponent.getFeatureLayer()?.getSource()
const features: any[] = [] // It does find features
map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
features.push(feature);
})
for (const feature of features) {
console.log('Feature: ', feature) // Feature exist
console.log('Title: ', feature.get('title')) // undefined
console.log('ID: ', feature.get('id')) // undefined
console.log('ID: ', feature.getId()) // undefined
const featureId = feature.get('id')
const overlay = map.getOverlayById(featureId)
// Remove overlay
map.removeOverlay(overlay)
// Remove feature
featureLayerSource?.removeFeature(feature)
}
} catch (err) {
console.log('Error: ', err)
}
})
})
}
}
/**
* The Polygon will be added to the map
*/
class Polygon extends Draw {
id: string
sketch: Feature | undefined
measureTooltipElement: HTMLElement | undefined
measureTooltip: Overlay | undefined
constructor(map: Map, featureLayerSource: VectorSource) {
super({
type: 'Polygon',
source: featureLayerSource
})
this.id = 'randomid' // Creating id
// this.setId('randomId') This does not work: Property 'setId' does not exist on type 'Polygon'.ts(2339)
this.set('id', this.id) // Assigning id with set()
this.setProperties({ // Assigning id (and title) with setProperties()
'id': this.id,
'title': this.id
})
this.createMeasureTooltip(map)
let listener: EventsKey | EventsKey[] | undefined = undefined
this.on('drawstart', (event: any) => {
this.sketch = event.feature
if (!this.sketch) {
return
}
let tooltipCoord: Coordinate = event.coordinate;
// Show measurements while drawing
listener = this.sketch.getGeometry()?.on('change', (evt: any) => {
const geom = evt.target
const output = this.formatArea(geom)
tooltipCoord = geom.getInteriorPoint().getCoordinates()
if (this.measureTooltipElement && this.measureTooltip) {
this.measureTooltipElement.innerHTML = output
this.measureTooltip.setPosition(tooltipCoord)
}
})
})
this.on('drawend', () => {
map.removeInteraction(this)
if (this.measureTooltipElement && this.measureTooltip) {
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'
this.measureTooltip.setOffset([0, -7])
// unset sketch
this.sketch = undefined
// unset tooltip so that a new one can be created
this.measureTooltipElement = undefined
this.createMeasureTooltip(map)
if (listener) {
unByKey(listener)
}
}
// Create measure tooltip
this.createMeasureTooltip(map)
})
map.addInteraction(this);
}
private formatArea(polygon: any): string {
const area = getArea(polygon)
return area > 10000 ?
Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>' :
Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>'
}
private createMeasureTooltip(map: Map): void {
if (this.measureTooltipElement) {
this.measureTooltipElement?.parentNode?.removeChild(this.measureTooltipElement)
}
this.measureTooltipElement = document.createElement('div')
this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'
this.measureTooltip = new Overlay({
id: this.id, // Assigning overlay id
element: this.measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center',
stopEvent: false,
insertFirst: false,
})
map.addOverlay(this.measureTooltip)
}
}
您的代碼正在繪制交互上設置屬性,以設置您需要繪制的特征的屬性或 id
this.on('drawend', (event) => {
event.feature.setId('randomId')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.