
在 OpenLayers 项目中,ol.interaction.Draw 提供了一种便捷的方式来进行地图上的绘制和测量。通常,该交互直接添加到 ol.Map 对象上,并在地图元素上进行操作。然而,在某些场景下,我们可能需要在非 OpenLayers Map 容器(例如一个独立的 HTML 元素)上进行测量操作,并希望 OpenLayers Map 上的测量结果能够同步更新。本文将介绍如何实现这一目标,并解决一些常见问题。
首先,我们需要创建一个 ol.interaction.Draw 实例,并将其添加到 ol.Map 对象中。
import Draw from 'ol/interaction/Draw';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
// 创建一个用于绘制的 VectorSource 和 VectorLayer
const source = new VectorSource();
const vector = new VectorLayer({
source: source,
});
// 创建 Draw 交互
const draw = new Draw({
source: source,
type: 'Polygon', // 可以是 'Point', 'LineString', 'Polygon', 'Circle'
});
// 添加 Draw 交互到 Map 对象
const map = new ol.Map({
target: 'map',
layers: [
// ... 其他图层
vector
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
map.addInteraction(draw);当在非 OpenLayers Map 容器上发生点击事件时,我们需要将坐标添加到 ol.interaction.Draw 中。appendCoordinates() 方法可以实现这个功能。
// 假设 container 是一个非 OpenLayers Map 的 HTML 元素
$(container).on("click.ol", () => {
if (this.measureHandler.viewerClick === true) {
this.lastCoord = ol.proj.transform([this.measureHandler.clickCoords[0], this.measureHandler.clickCoords[1]], "EPSG:4326", "EPSG:3857");
if (measureType !== "Polygon") {
this.coords.push(this.lastCoord);
} else {
if (this.coords.length <= 1) {
this.coords.splice(0, 0, this.lastCoord);
this.coords.push(this.lastCoord);
} else {
this.coords.splice(this.coords.length - 1, 0, this.lastCoord);
}
}
this.draw.appendCoordinates([this.lastCoord]);
}
});为了实时更新测量结果,我们需要模拟 ol.Map 的 "pointermove" 事件。ol.interaction.Draw 内部有一个 handlePointerMove_() 方法,可以用来处理 pointermove 事件。我们需要创建一个 ol.MapBrowserEvent 对象,并将其传递给 handlePointerMove_() 方法。
$(container).on("mousemove.ol", (evt) => {
// ... 获取坐标逻辑 ...
const olEvt = {
map: this.map,
pixel: this.measureHandler.pixelObj,
coordinate: this.lastCoord,
originalEvent: {
pointerType: "mouse"
},
frameState: this.map.frameState
};
this.draw.handlePointerMove_(olEvt);
});appendCoordinates() 方法对于圆形几何可能无法正常工作。在这种情况下,我们需要在点击事件处理程序中添加额外的逻辑来处理圆形几何。
$(container).on("click.ol", () => {
// ... 其他逻辑 ...
if (measureType === "Circle") {
if (this.clickCount === 0) {
this.draw.appendCoordinates([this.lastCoord]);
this.clickCount++;
} else {
this.draw.finishDrawing();
this.clickCount = 0;
}
} else {
this.draw.appendCoordinates([this.lastCoord]);
this.clickCount++;
}
});this.measureHandler.containers.forEach((container, nr) => {
$(container).on("click.ol", () => {
if (this.measureHandler.viewerClick === true) {
this.lastCoord = ol.proj.transform([this.measureHandler.clickCoords[0], this.measureHandler.clickCoords[1]], "EPSG:4326", "EPSG:3857");
if (measureType !== "Polygon") {
this.coords.push(this.lastCoord);
} else {
if (this.coords.length <= 1) {
this.coords.splice(0, 0, this.lastCoord);
this.coords.push(this.lastCoord);
} else {
this.coords.splice(this.coords.length - 1, 0, this.lastCoord);
}
}
if (measureType === "Circle") {
if (this.measureHandler.activePlugins[nr] !== "Ortofoto" && this.measureHandler.activePlugins[nr] !== "Ukosne" && this.measureHandler.activePlugins[nr] !== "OSMPlugin") {
if (this.clickCount === 0) {
this.draw.appendCoordinates([this.lastCoord]);
this.clickCount++;
} else {
this.draw.finishDrawing();
this.clickCount = 0;
}
}
} else {
this.draw.appendCoordinates([this.lastCoord]);
this.clickCount++;
}
}
});
$(container).on("mousemove.ol", (evt) => {
this.maps[nr].removeLayer(this.drawLayer);
if (nr === 0) {
this.map2.removeLayer(this.drawLayer);
this.map2.addLayer(this.drawLayer);
} else {
this.map.removeLayer(this.drawLayer);
this.map.addLayer(this.drawLayer);
}
this.maps[nr].addInteraction(this.draw);
this.lastCoord = ol.proj.transform([this.measureHandler.moveCoords[0], this.measureHandler.moveCoords[1]], "EPSG:4326", "EPSG:3857");
if (measureType !== "Polygon") {
this.coords.pop();
this.coords.push(this.lastCoord);
} else {
if (this.coords.length <= 1) {
this.coords.pop();
this.coords.push(this.lastCoord);
} else {
this.coords.splice(this.coords.length - 2, 1, this.lastCoord);
}
}
if (nr === 0) {
olEvt = {
map: this.map2,
pixel: this.measureHandler.pixelObj,
coordinate: this.lastCoord,
originalEvent: {
pointerType: "mouse"
},
frameState: this.map2.frameState
};
} else {
olEvt = {
map: this.map,
pixel: this.measureHandler.pixelObj,
coordinate: this.lastCoord,
originalEvent: {
pointerType: "mouse"
},
frameState: this.map.frameState
};
}
this.draw.handlePointerMove_(olEvt);
});
$(container).on("dblclick.ol", () => {
this.draw.removeLastPoint();
this.draw.finishDrawing();
this.clickCount = 0;
});
});通过 appendCoordinates() 方法和模拟 pointermove 事件,我们可以在自定义事件处理程序中触发 OpenLayers Map 事件,实现非 OpenLayers Map 容器上的测量操作与 OpenLayers Map 上的测量结果同步更新。 这种方法扩展了 ol.interaction.Draw 的使用场景,使其能够更好地满足复杂的业务需求。
以上就是使用 OpenLayers 在自定义事件处理程序中触发 Map 事件的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号