openlayers 封装加载、修改本地geojson数据 - vue3

Geojson数据是矢量数据,主要是点、线、面数据集合

Geojson数据获取:DataV.GeoAtlas地理小工具系列

实现代码如下:

import {ref,toRaw} from 'vue';
import { Vector as VectorLayer } from 'ol/layer.js';
import { Vector as VectorSource } from 'ol/source.js';
import { Style, Fill, Stroke, Circle as CircleStyle  } from 'ol/style';
import {Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, Geometry} from 'ol/geom.js';
import { transform, fromLonLat, toLonLat } from 'ol/proj.js'
import Feature from 'ol/Feature.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import Select  from 'ol/interaction/Select.js';
import Overlay from 'ol/Overlay';
import pointData from "../../../static/datas/point.json";// 本地点数据
import lineData from "../../../static/datas/line.json";// 本地线数据
import polygonData from "../../../static/datas/polygon.json";// 本地面数据
import multiPointData from "../../../static/datas/multiPoint.json";// 本地multipoint数据
import multiLineData from "../../../static/datas/multiLine.json";// 本地multiLine数据
import multiPolygonData from "../../../static/datas/multiPolygon.json";// 本地multiPolygon数据
import ccsData from "../../../static/datas/ccs.json";

// 数据源
const vectorSource = ref(null);
// 创建图层
const vectorLayer = ref(null);

// 添加离线geojson数据-推荐
const addBaseGeoJsonLayer = (map) =>{
  removeGeoJsonLayer(map);

  // 使用 GeoJSON 格式读取数据
  const geojsonFormat = new GeoJSON();
  const features = geojsonFormat.readFeatures(pointData, {
    featureProjection: 'EPSG:3857' // 投影坐标系
  });

  // 创建一个矢量源并添加读取的特征
  const geoJsonSource = new VectorSource({
    features: features
  });

  // 创建一个矢量图层
   geoJsonLayer.value = new VectorLayer({
        name:"geojson图层",
        source:geoJsonSource,
        style: new Style({
            // 使用 CircleStyle 创建一个圆形的点
            image:new CircleStyle({
                // 点样式
                fill:new Fill({
                    //color:"red",// 颜色
                    color: 'rgba(255,0,0,0.4)',
                }),
                // 点周边样式
                stroke:new Stroke({
                    color: '#3399CC',
                    width: 1.25, 
                }),
                radius:7,// 半径
            }),
        }),
        zIndex: 20,
    });

    map.addLayer(geoJsonLayer.value);
}



// 遍历添加
export const addBaseGeoJson = (map) =>{
     // 删除图层
     map.removeLayer(vectorLayer.value);

    // 创建要素数据源
    vectorSource.value = new VectorSource();
    // 创建要素图层
    vectorLayer.value = new VectorLayer();

   
    // 遍历本地数据
    pointData.features.forEach(function(element){
        const feature = new Feature();
        // 要素名称/类型
        const featurName = element.type;
        feature.setGeometryName(featurName);

        // 要素属性信息
        const properties = element.properties;
        
        // 要素图层类型
        const geomType = element.geometry.type;
        console.log("geomType",geomType)
       
        
        if("Point" == geomType){// 点数据
             // 要素数据图形 
            const pointGeom = element.geometry.coordinates
       
            // 转换坐标
            //const transformedCoords = transform([pointGeom[0],pointGeom[1]],'EPSG:4326', 'EPSG:3857');
            const transformedCoords = fromLonLat([pointGeom[0],pointGeom[1]]);
            // 添加数据
            const pointGeometry = new Point(transformedCoords);
            feature.setGeometry(pointGeometry);
            // 设置样式
            feature.setStyle(
                new Style({
                    // 使用 CircleStyle 创建一个圆形的点
                    image:new CircleStyle({
                        // 点样式
                        fill:new Fill({
                            //color:"red",// 颜色
                            color: 'rgba(255,0,0,0.4)',
                        }),
                        // 点周边样式
                        stroke:new Stroke({
                            color: '#3399CC',
                            width: 1.25, 
                        }),
                        radius:7,// 半径
                    }),
                })
            );
        }else if("LineString" == geomType){// 线数据
             // 要素数据图形 
             const lineGeom = element.geometry.coordinates;
             // 转换坐标
             const transformedCoords = lineGeom.map((coord) => {
                return transform(coord, 'EPSG:4326','EPSG:3857');
              });
             // 创建线对象
             const lineGeometry = new LineString(transformedCoords);

             feature.setGeometry(lineGeometry);
             // 设置线特征样式(Style)
             feature.setStyle(
                new Style({
                    stroke:new Stroke({
                        color:"red",// 线的颜色
                        width:7// 线宽带
                    })
                })
             );
        }else if("Polygon" == geomType){// 面数据
            // 要素数据图形 
            const polygonGeom = element.geometry.coordinates;
            // 转换坐标
            const transformedCoords =  polygonGeom.map((item)=>{
                
                const coordResult = item.map((coord)=>{
                    //return fromLonLat(coord, 'EPSG:4326','EPSG:3857');
                    return fromLonLat(coord);
                });

                return coordResult;
            });
             
            // 创建面对象
            const polygonGeometry = new Polygon(transformedCoords);
      
            feature.setGeometry(polygonGeometry);

            // 设置多边形样式(Style)
            feature.setStyle(
                new Style({
                    stroke:new Stroke({
                        color:"yellow",// 多边形边界颜色
                        width:2// 多边形边界宽度
                    }),
                    fill:new Fill({
                        color:'rgba(0,0,255,0.5)'// 多边形填充颜色,这里设置为半透明颜色
                    })
                })
			);

        }else if("MultiPoint" == geomType){// 点集合
            // 要素数据图形 
            const multiPointGeom = element.geometry.coordinates;

            // 转换坐标
            const transformedCoords = multiPointGeom.map((coord) => {
                return transform(coord, 'EPSG:4326','EPSG:3857');
            });

            // 创建MultiPoint对象
            const MultiPointGeometry = new MultiPoint(transformedCoords);

            feature.setGeometry(MultiPointGeometry);

             // 设置样式
             feature.setStyle(
                new Style({
                    // 使用 CircleStyle 创建一个圆形的点
                    image:new CircleStyle({
                        // 点样式
                        fill:new Fill({
                            //color:"red",// 颜色
                            color: 'rgba(255,0,0,0.4)',
                        }),
                        // 点周边样式
                        stroke:new Stroke({
                            color: '#3399CC',
                            width: 1.25, 
                        }),
                        radius:7,// 半径
                    }),
                })
            );
        }else if("MultiLineString" == geomType){// 线集合
             // 要素数据图形 
             const multiLineGeom = element.geometry.coordinates;
             // 转换坐标
             const transformedCoords =  multiLineGeom.map((item)=>{
                const coordResult = item.map((coord)=>{
                    //return fromLonLat(coord, 'EPSG:4326','EPSG:3857');
                    return fromLonLat(coord);
                });
                return coordResult;
            });

            // 创建MultiLineString对象
            const MultiLineGeometry = new MultiLineString(transformedCoords);

            feature.setGeometry(MultiLineGeometry);
            // 设置多边形样式(Style)
            feature.setStyle(
                new Style({
                    stroke:new Stroke({
                        color:"green",// 多边形边界颜色
                        width:2// 多边形边界宽度
                    }),
                    fill:new Fill({
                        color:'rgba(0,0,255,0.5)'// 多边形填充颜色,这里设置为半透明颜色
                    })
                })
			);
        }else if("MultiPolygon" == geomType){// 面集合
            // 要素数据图形 
            const multiPolygonGeom = element.geometry.coordinates;
            
            // 转换坐标
            const transformedCoords =  multiPolygonGeom.map((parentItem)=>{
                const parentCoordResult = parentItem.map((parentCoord)=>{
                  const coordResult = parentCoord.map((coord)=>{
                        //return fromLonLat(coord, 'EPSG:4326','EPSG:3857');
                        return fromLonLat(coord);
                    });
                    return coordResult;
                });
                return parentCoordResult;
            });

            // 创建MultiPolygmon对象
            const multiPolygonGeometry = new MultiPolygon(transformedCoords);

            feature.setGeometry(multiPolygonGeometry);

            feature.setStyle(
                new Style({
                    fill: new Fill({
                        color: 'rgba(255, 0, 0, 1)'
                      }),
                    // 样式-边框
                    stroke: new Stroke({
                        color: '#0099ff',
                        width: 3
                      }),
                })
             );
        }
        
        // 点数据添加到数据源
        vectorSource.value.addFeature(feature);
        // 要素数据信息
        feature.setProperties(properties);
    });

    

    // 数据源添加到图层
    vectorLayer.value.setSource(vectorSource.value);
  
    // 将图层添加到地图上
    map.addLayer(vectorLayer.value);


    // 点选查看数据信息
    map.on('click', ev => {
        const pixel = ev.pixel   // 鼠标点击的位置,这个应该是像素
        const mousePoint = ev.coordinate  // 鼠标点击的坐标位置
        const feature = map.forEachFeatureAtPixel(pixel, (feature) => {
          return feature   // 查找出点击的哪个要素
        });

        if (feature) {  // 如果是点击了坐标点
          // 区域名称
          const properties = feature.getProperties();
          console.log("properties",properties);
        } else {
        
            console.log("没有要素数据");
        }
      })

     // 选中获取geojson数据
     /*if(vectorLayer.value != null){
        const featureLayer = toRaw(vectorLayer.value);

        // 创建选择交互
        const selectInteraction = new Select({
            layers:[featureLayer],
        });

        map.addInteraction(selectInteraction);

        // 监听选中要素的变化
        selectInteraction.on('select',(event) =>{
            // 获取被选中的要素
            const selectedFeatures = event.target.getFeatures();
            selectedFeatures.forEach(element => {
                //获取到选中要素的属性
                console.log("element",element.getProperties());
            });
        });
    }else{
        alert("没有要素图层!")
    }*/

}

使用方法:

在**.vue引入

import {addBaseGeoJson} from "../js/baseGeojson.js";// 引入js

// 使用
// 全图事件
const addJson = () => {
    addBaseGeoJson(map); 
}

注意:本地数据放置在根目录新建static/datas/下

point.json数据格式:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "点1",
        "region":"绿园区",
        "content":"信息点1"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [125.362488, 43.916037]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "点2",
        "region":"绿园区",
        "content":"信息点2"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [125.362488, 43.906037]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "点3",
        "region":"绿园区",
        "content":"信息点3"
      },
      "geometry": {
        "type": "Point",
        "coordinates": [125.363488, 43.936037]
      }
    }
  ]
}

line.json数据格式:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "线1",
        "region":"测试区1",
        "content":"信息线1"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
            [125.363488, 43.936037],
            [125.362488, 43.906037]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "线2",
       "region":"测试区2",
        "content":"信息线2"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
            [125.44,43.95],
            [125.44,43.96]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "线3",
        "region":"测试区1",
        "content":"信息线1"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [125.34,43.95],
          [125.54,43.96]
      ]
      }
    }
  ]
}

polygon.json数据格式:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "面1",
        "region":"测试区1",
        "content":"信息面1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
            [
              [125.323488, 43.86037],
              [124.332488, 42.706037],
              [125.342401, 43.607037]
            ]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "面2",
       "region":"测试区2",
        "content":"信息面2"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
            [
              [125.44,43.95],
              [125.46,43.96],
              [125.24,42.96]
            ]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "面3",
        "region":"测试区1",
        "content":"信息面1"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [125.34,43.95],
            [125.54,43.96],
            [125.64,43.90],
            [125.68,43.98]
          ]
      ]
      }
    }
  ]
}

multiPoint.json数据格式:

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": {
          "name": "multiPoint点1",
          "region":"绿园区",
          "content":"信息点1"
        },
        "geometry": {
          "type": "MultiPoint",
          "coordinates": [
            [125.362488, 43.916037],
            [125.352488, 43.936037]
          ]
        }
      },{
        "type": "Feature",
        "properties": {
          "name": "multiPoint点2",
          "region":"绿园区",
          "content":"信息点2"
        },
        "geometry": {
          "type": "MultiPoint",
          "coordinates": [
            [125.362488, 43.906037],
            [125.372488, 43.946037]
          ]
        }
      },{
        "type": "Feature",
        "properties": {
          "name": "multiPoint点3",
          "region":"绿园区",
          "content":"信息点3"
        },
        "geometry": {
          "type": "MultiPoint",
          "coordinates": [
            [125.563488, 43.976037],
            [125.373488, 43.946037]
          ]
        }
      }
    ]
  }

multiLine.json数据格式:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "multiLine线1",
        "region":"测试区1",
        "content":"信息线1"
      },
      "geometry": {
        "type": "MultiLineString",
        "coordinates": [
            [[125.363488, 43.936037], [125.362488, 43.906037]],
            [[125.263488, 43.736037], [125.242488, 43.706037]]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "multiLine线2",
       "region":"测试区2",
        "content":"信息线2"
      },
      "geometry": {
        "type": "MultiLineString",
        "coordinates": [
            [[125.49,43.92],[125.45,43.96]],
            [[125.45,43.91],[125.44,43.96]]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "multiLine线3",
        "region":"测试区1",
        "content":"信息线1"
      },
      "geometry": {
        "type": "MultiLineString",
        "coordinates": [
         [[125.38,43.95],[125.54,43.96]],
         [[125.34,43.92],[125.54,47.94]]
      ]
      }
    }
  ]
}

multiPolygon.json数据格式:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "multiPolygon面1",
        "region":"测试区1",
        "content":"信息面1"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
            [
                [
                  [125.323488, 43.86037],
                  [124.332488, 42.706037],
                  [125.342401, 43.607037]
                ]
            ],[
                [
                  [125.123488, 43.36037],
                  [124.132488, 42.306037],
                  [125.142401, 43.307037]
                ]
            ]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "multiPolygon面2",
       "region":"测试区2",
        "content":"信息面2"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
           [
              [
                [125.44,43.95],
                [125.46,43.96],
                [125.24,42.96]
              ]
           ],[
              [
                [125.46,43.95],
                [125.47,43.71],
                [125.28,42.56]
              ]
           ]
        ]
      }
    },{
      "type": "Feature",
      "properties": {
        "name": "multiPolygon面3",
        "region":"测试区1",
        "content":"信息面1"
      },
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
          [
              [
                [125.34,43.95],
                [125.54,43.96],
                [125.64,43.90],
                [125.68,43.98]
              ]
          ],[
              [
                [125.24,43.2],
                [125.34,43.94],
                [125.44,43.97],
                [125.58,43.99]
              ]
          ]
      ]
      }
    }
  ]
}

修改属性信息:

const updateInfoOne = () =>{
                
                const mySelect = new Select();
				this.map.addInteraction(mySelect);
				/* mySelect.on('select', function(evt) {
					// 打印出选中的要素属性信息
					//console.log("evt",JSON.stringify(evt.selected[0].values_.name));	
					// 获取选中要素信息集合
					//const selectedFeatures = mySelect.getFeatures().getArray();
					// 打印出选中的要素属性信息
					//console.log("selectedFeatures",JSON.stringify(selectedFeatures[0].values_.name));
					
					//方法1:修改离线*.josn信息方法
					const selectedFeature = evt.selected[0];
					selectedFeature.set('name', "lalala"); // 更新属性值,这里的'name'是示例属性名,根据实际情况修改。
					selectedFeature.set('region', "heiheihei");
					console.log("selectedFeature",JSON.stringify(selectedFeature));
					//方法2:修改离线*.json信息方法
					//const selectedFeatures = mySelect.getFeatures().getArray();
					//selectedFeatures[0].set('name', "还有谁"); // 更新属性值,这里的'name'是示例属性名,根据实际情况修改。
					//selectedFeatures[0].set('region',"朝阳区");
					// 该方法在离线json中报错
					//this.myVectorSource.changed(); // 通知源数据已更改,以便更新地图显示。
					//console.log("selectedFeatures",JSON.stringify(selectedFeatures));
					
				}); */

}               

const updateInfoTwo = () =>{

    	// 修改离线*.json属性信息
				mySelect.getFeatures().on('add', function(evt) {
				    const feature = evt.element;
				    // 显示属性编辑表单或对话框,这里仅为示例代码,实际实现需根据具体情况编写HTML和JavaScript代码来处理表单的显示和属性更新。
				    console.log('update before Selected feature:', JSON.stringify(feature));
					
					feature.set('name', "lalala"); // 更新属性值,这里的'name'是示例属性名,根据实际情况修改。
					feature.set('region', "heiheihei");
					// 该方法报错
					//this.myVectorSource.changed(); 
					
					console.log('update after Selected feature:',JSON.stringify(feature));
				});

}
                
			

加载 GeoJSON 文件可以通过多种方式实现,具体取决于所使用的库或框架。以下是基于 OpenLayersVue 的两种常见方法。 --- ### 使用 OpenLayers 加载 GeoJSON 数据 #### 方法一:从本地 JSON 对象加载 如果已经拥有 GeoJSON 数据作为 JavaScript 对象,则可以按照以下步骤操作: ```javascript // 导入必要的模块 import { Vector as VectorSource } from &#39;ol/source&#39;; import VectorLayer from &#39;ol/layer/Vector&#39;; import GeoJSON from &#39;ol/format/GeoJSON&#39;; // 假设 yourGeojsonData 是一个有效的 GeoJSON 对象 var vectorSource = new VectorSource({ features: (new GeoJSON()).readFeatures(yourGeojsonData) }); // 创建矢量图层并设置其源为上面定义的矢量源 var vectorLayer = new VectorLayer({ source: vectorSource, style: new Style({ stroke: new Stroke({ color: &#39;blue&#39;, width: 3 }), fill: new Fill({ color: &#39;rgba(0, 0, 255, 0.1)&#39; }) }) }); // 将矢量图层添加到地图中 map.addLayer(vectorLayer); ``` 此代码片段展示了如何通过 `ol.format.GeoJSON` 解析 GeoJSON 数据,并将其作为特性(features)传递给矢量源[^3]。 #### 方法二:从远程 URL 请求 GeoJSON 数据 当需要从服务器获取 GeoJSON 数据时,可按如下方式进行配置: ```javascript // 定义矢量源,指定 GeoJSON 格式以及数据所在的 URL var vectorSource = new VectorSource({ format: new GeoJSON(), url: &#39;path_to_your_geojson_file.json&#39; // 替换为您实际的 GeoJSON 文件路径 }); // 创建矢量图层并将矢量源绑定至该图层 var vectorLayer = new VectorLayer({ source: vectorSource, style: new Style({ stroke: new Stroke({ color: &#39;green&#39;, width: 2 }), fill: new Fill({ color: &#39;rgba(0, 128, 0, 0.1)&#39; }) }) }); // 向地图实例添加新创建的矢量图层 map.addLayer(vectorLayer); ``` 这种方法利用了 `url` 属性自动发起 HTTP GET 请求以下载 GeoJSON 数据[^3]。 --- ### 在 Vue.js 中集成 Leaflet 并加载 GeoJSON 数据 对于前端开发人员来说,在 Vue.js 应用程序中使用 Leaflet 可能更加直观。下面是一个简单的例子说明如何完成这一任务: ```html <template> <div id="map"></div> </template> <script> export default { name: "LeafletMap", mounted() { this.initMap(); }, methods: { initMap() { const L = require(&#39;leaflet&#39;); require(&#39;leaflet/dist/leaflet.css&#39;); // 初始化底图 const map = L.map(&#39;map&#39;).setView([39.9042, 116.4074], 13); L.tileLayer(&#39;https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png&#39;, {}).addTo(map); // 加载外部 GeoJSON 文件 fetch(&#39;path_to_your_geojson_file.json&#39;) // 修改为您的 GeoJSON 路径 .then(response => response.json()) .then(data => { L.geoJSON(data).addTo(map); // 将解析后的 GeoJSON 数据加入地图 }); } } }; </script> <style scoped> #map { height: 500px; width: 100%; } </style> ``` 这里的关键在于调用了浏览器内置的 Fetch API 来异步获取 GeoJSON 文件内容,并借助 Leaflet 提供的 `L.geoJSON()` 工具快速渲染这些地理要素[^4]。 --- ### Cesium 中加载 GeoJSON 数据 Cesium 支持直接加载 GeoJSON 文件并通过特定样式呈现出来。下面是基本流程的一个示例: ```javascript // 引入 cesium 模块 import * as Cesium from &#39;cesium&#39;; // 设置 viewer 实例 const viewer = new Cesium.Viewer(&#39;cesiumContainer&#39;, {}); // 动态加载 geojson 文件 viewer.dataSources.add(Cesium.GeoJsonDataSource.load( &#39;https://raw.githubusercontent.com/gregology/geometries/master/world-countries.geojson&#39; )).then(dataSource => { viewer.zoomTo(dataSource); // 自动缩放到合适范围 }); ``` 这段脚本演示了怎样运用 Cesium 的 `GeoJsonDataSource.load` 方法轻松导入在线托管的服务端资源[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值