uniapp 整合openlayers 编辑图形文件并上传到服务器

引入openlayer依赖

复制代码
import Map from 'ol/Map.js'  // OpenLayers的主要类,用于创建和管理地图  
import View from 'ol/View.js'  // OpenLayers的视图类,定义地图的视图属性 
import TileLayer from 'ol/layer/Tile.js'// OpenLayers的瓦片图层类   
import XYZ from 'ol/source/XYZ.js'
import olsourceOSM from 'ol/source/OSM.js'
import TileWMS from 'ol/source/TileWMS.js';
import Feature from 'ol/Feature.js'  // OpenLayers的要素类,表示地图上的一个对象或实体          
import Point from 'ol/geom/Point.js'  // OpenLayers的点几何类,用于表示点状的地理数据        
import { Vector as VectorLayer } from 'ol/layer.js'  // OpenLayers的矢量图层类,用于显示矢量数据        
import { Vector as VectorSource } from 'ol/source.js'  // OpenLayers的矢量数据源类,用于管理和提供矢量数据       
import { Circle as CircleStyle, Style, Stroke, Fill, Icon } from "ol/style.js"  // OpenLayers的样式类,用于定义图层的样式,包括圆形样式、基本样式、边框、填充和图标      
import { ScaleLine, defaults as defaultControls, MousePosition } from 'ol/control.js'// OpenLayers的控件类,包括默认的控件集合和特定的全屏、鼠标位置、比例尺控件
import { transform } from 'ol/proj.js'// OpenLayers的投影转换函数,用于经纬度坐标和投影坐标之间的转换
import LineString from 'ol/geom/LineString.js'  // OpenLayers的线几何类,用于表示线状的地理数据            
import Polygon from "ol/geom/Polygon.js"  // OpenLayers的多边形几何类,用于表示面状的地理数据
import ZoomSlider from 'ol/control/ZoomSlider.js';// 滑动放大缩小按钮
import FullScreen from 'ol/control/FullScreen.js';// 全屏按钮
import ZoomToExtent from 'ol/control/ZoomToExtent.js';// 范围 
import {GeoJSON, GML, WFS} from 'ol/format'; 
import {Select, Draw, Modify, Snap} from 'ol/interaction.js';
import Overlay from 'ol/Overlay';

1、创建编辑图层

复制代码
                        // 创建 VectorLayer 用于加载 GeoJSON
						layer =  new VectorLayer({
						  source: new VectorSource({
							url: data.url, // 替换为您的 GeoJSON 服务 URL
							format: new GeoJSON(),
						  }),
						  style: new Style({
							fill: new Fill({
							  color: '#ff00ff',
							}),
							// 样式-边框
							stroke: new Stroke({
							  color: '#6600ff',
							  width: 2,
							}),
							// 使用 CircleStyle 创建一个圆形的点
							image:new CircleStyle({
								// 点样式
								fill:new Fill({
									color: 'rgba(255,0,0,0.4)',
								}),
								// 点周边样式
								stroke:new Stroke({
									color: '#3399CC',
									width: 1.25, 
								}),
								radius:7,// 半径
							}),
						  }),
						  visible: true,
						  // 上传服务器所需
						  projection: data.wkid,
						  featureNS:data.featureNS,
						  featureType:data.featureType,
					      geometryName:data.geometryName,
						  wfsjdUrl:data.wfsjdUrl,
						  wkid:data.wkid,
						});
                    // 添加图层
					this.map.addLayer(layer); 

2、创建交互editLayer()方法

复制代码
editLayer(){
				const that = this;
				//console.log("selLayer",selLayer.get("wfsjdUrl"));
				// 创建选择交互
				const select = new Select({
					condition: function (event) {
					  return event.type === "click";
					},
				});
				that.map.addInteraction(select);
				
				// 根据选择状态动态设置修改交互
				select.on("select", function (event) {
					const selectedFeatures = event.selected;
				    const selectlayer = select.getLayer(selectedFeatures[0]);
					if(selectlayer == null){
						return;
					}
					
					if (selectedFeatures.length > 0) {
						that.modify = new Modify({
							features:select.getFeatures(),
							style:null,// 使用features的默认样式
						});
						that.map.addInteraction(that.modify);
						
						const snap = new Snap({
							source: selectlayer.getSource(),
						});
						that.map.addInteraction(snap);
						
						that.modify.on("modifyend",(e) =>{
							let feature = e.features.item(0).clone();
							feature.setId(e.features.item(0).getId());
							if(selectlayer.get("geometryName")!=null)
							{
							  feature.setGeometryName(selectlayer.get("geometryName")); 
							}
							// 坐标系转换:3857 -> 4326
							// const geometry = feature.getGeometry().clone();
							// geometry.transform('EPSG:3857', 'EPSG:4326');
							// feature.setGeometry(geometry);
							// let geomType = feature.getGeometry().getType().toLowerCase();
					
							// feature.getGeometry().applyTransform(function(flatCoordinates, flatCoordinates2, stride){
							//   for(let j = 0, jj = flatCoordinates.length; j < jj; j += stride){
							//     let y = flatCoordinates[j];
							//     let x = flatCoordinates[j + 1];
							//     flatCoordinates[j] = x;
							//     flatCoordinates[j + 1] = y;
							//   }
							// })
							// const featureN = new Feature();
							// featureN.setId('土地推介地块.32');
							// featureN.setGeometry(feature.values_.geometry)
						   that.editGeometry("update", feature, selectlayer);
						});
						
					}
				
				});
				
				// 双击地图
				that.map.on('dblclick', function (evt) {
					 // 移除监听modify
					 that.map.removeInteraction(modify);
				});
				
				
			},

3、编辑属性信息editGeometry()方法

复制代码
editGeometry(type, mofeature, layer){
				  const that = this;
				  const formatWFS = new WFS({
				    featureNS: layer.get("featureNS"),//  featureNS: http://jcdl
				    featureType: layer.get("featureType"),// featureType: ceshidk
				    // featurePrefix: 'jcdl', // 命名空间前缀
				    version: '1.0.0' // 指定为和示例代码一致的版本
				  });
				  
				  var formatGML = new GML({
				      featureNS: layer.get("featureNS"),//  featureNS: http://jcdl
				      featureType:  layer.get("featureType"),// featureType: ceshidk
				      // featurePrefix: 'jcdl', // 命名空间前缀
					  // projection:3857
				      srsName: 'EPSG:'+layer.get("projection"), // GeoServer 图层应使用 WGS84
				      gmlVersion: 1, // 强制使用 GML 3
				      
				  });
				
				   var node = '';
				   switch (type) {
				      case "insert":
				        node = formatWFS.writeTransaction([mofeature], [], [], formatGML);
				        break;
				      case "update":
				        node = formatWFS.writeTransaction([], [mofeature], [], formatGML);
				        break;
				      case "delete":
				        node = formatWFS.writeTransaction([], [], [mofeature], formatGML);
				        break;
				    }

				    const serializer = new XMLSerializer();
				    const transactionString = serializer.serializeToString(node);
				    const wfsjdUrl=layer.get("wfsjdUrl");
				    that.fetchFeatures(transactionString,wfsjdUrl);
				  
			},

4、上传编辑后的结果fetchFeatures()方法

复制代码
fetchFeatures(node,url){
				//url = http://192.168.1.20:8081/geoserver/wfs
				console.log("url",url)
				fetch(url, {
					method: 'POST',
					body: node,
					headers: { 
						'Content-Type': 'text/xml',
					}
				}).then((response) => {
				  return response.text().then((text) => {
					if (response.ok) {
					  console.log('保存成功,服务器响应:', text);
					} else {
					  console.error('保存失败,服务器响应:', text);
					}
				  });
				}).catch(function (error) {
					console.error('保存失败: ', error);
				});
				  
			},
相关推荐
崔庆才丨静觅25 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax