Cesium 读取Geoserver发布的 WFS 服务数据,属性值提取和属性值编辑

Cesium版本 1.6.1(现在都170了,好快!!)

最近会更几篇博客,主要内容就是 Cesium 加载 Geoserver 发布的 WFS 服务,然后执行后续的增删改查等操作,这篇文章主要是实现对 WFS 服务数据的属性表内容的提取以及编辑和修改属性值操作。

实现内容:

① 加载 Geoserver 发布的 WFS 服务数据;

② 点选图层显示属性表(字段名和属性值);

③ 修改和编辑属性值,并更新 WFS 服务内容。

废话不多说,代码先上:

①加载 WFS 服务数据

geoserverUrl = 'http://localhost:8080/geoserver/CesiumTest_WFS';//geoserver服务地址WFS
//定义各参数
var param = {
    service: 'WFS',
    version: '1.0.0',
    request: 'GetFeature',
    typeName: 'WFS',
    outputFormat: 'application/json'
};
$.ajax({
    url: geoserverUrl + "/ows" + getParamString(param, geoserverUrl),
    cache: false,
    async: true,
    success: function (data) {
        var dataPromise = Cesium.GeoJsonDataSource.load(data);
        dataPromise.then(function (dataSource) {
            viewer.dataSources.add(dataSource);//加载服务数据
            viewer.flyTo(dataSource);
        })
    },
    error: function (data) {
        console.log("error");
    }
})

效果:

②点选图层显示属性表:

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var ellipsoid = viewer.scene.globe.ellipsoid;
handler.setInputAction(function (movement) {
    console.log('属性展示和编辑');
    //通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
    cartesian = viewer.camera.pickEllipsoid(movement.position, ellipsoid);
    if (cartesian) {
        //将笛卡尔坐标转换为地理坐标
        var cartographic = ellipsoid.cartesianToCartographic(cartesian);
        //将弧度转为度的十进制度表示
        var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
        var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
        var point = longitudeString + ',' + latitudeString;
        queryWFSByPoint(geoserverUrl, point, param.typeName, ShowAndEditWfsLayerAttributes);
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

function ShowAndEditWfsLayerAttributes(geoserverUrl, data) {
    console.log('data', data);
    var m_div = document.getElementById('propertiesDiv');
    if (m_div) {
        document.getElementById('MapContainer').removeChild(m_div);
    }
    if (data && data.features.length > 0) {
        //气泡窗口显示
        var properties = data.features[0].properties;
        var id = data.features[0].id;
        var geometry = data.features[0].geometry;
        var o_Div = document.createElement('div');//属性提示的 DIV 元素
        o_Div.id = 'propertiesDiv';
        document.getElementById('MapContainer').appendChild(o_Div);

        var content = '<p>' + id + '</p>';
        for (var key in properties) {
            var keyName = key;
            var keyValue = properties[key];
            content += '<span>' + keyName + ':</span><input type="text" id="' + keyName + '" value = "' + keyValue + '" /></br>';
        }
        content += '<button type="button" id="editBtn">编辑属性并保存</button>';
        $("#propertiesDiv").show();
        $("#propertiesDiv").empty();
        $("#propertiesDiv").append(content);
        $("#editBtn").click(function () {
            getAttributesList();
            if (id) {
                //记录构造polygon,为后续几何图形的编辑做准备
                var polygon = '';
                var data = geometry.coordinates[0][0];
                for (var i = 0; i < data.length; i++) {
                    var item = data[i];
                    polygon += item[0] + ',' + item[1] + ',' + item[2] + ' ';
                }
                polygon += data[0][0] + ',' + data[0][1] + ',' + data[0][2];

                var attributesList = getAttributesList();//获取字段名和字段值键值对//暂时数组形式记录
                var typename = id.substr(0, id.indexOf('.'));
            }
        });
    }
}
function getAttributesList() {
    var List = new Array();
    var texts = $('#propertiesDiv input[type=text]');
    for (let i = 0; i < texts.length; i++) {
        const element = texts[i];
        var cur_Attribute = new Array(element.id, element.value);
        List.push(cur_Attribute);
    }
    return List;
}

③编辑属性值

function EditWfsLayerAttributs(geoserverUrl, typeName, fid, polygon, attributesList, callback) {
    var content = '';
    content += '<?xml version="1.0" encoding="utf-8"?>';
    content += '<wfs:Transaction version="1.0.0" service="WFS" username="admin" password="476852678" xmlns:CesiumTest_WFS="http://CesiumTest_WFS" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml">';
    content += '<wfs:Update typeName="CesiumTest_WFS:' + typeName + '">';
    for (let i = 0; i < attributesList.length; i++) {
        const element = attributesList[i];
        content += '<wfs:Property> <wfs:Name>' + element[0] + '</wfs:Name> <wfs:Value>' + element[1] + '</wfs:Value> </wfs:Property>';
    }

    content += '<wfs:Property>';
    content += '<wfs:Name>the_geom</wfs:Name>';
    content += '<wfs:Value>';
    content += '<gml:MultiPolygon> <gml:polygonMember> <gml:Polygon> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>' + polygon + '</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </gml:polygonMember> </gml:MultiPolygon>'
    content += '</wfs:Value>';
    content += '</wfs:Property>';

    content += '<ogc:Filter> <ogc:FeatureId fid="' + fid + '" /> </ogc:Filter>'
    content += '</wfs:Update>';
    content += '</wfs:Transaction>';

    $.ajax({
        url: geoserverUrl + '/wfs',
        async: true,
        data: content,
        type: 'post',
        contentType: 'text/xml',
        success(result) {
            callback(result);
        },
        error(err) {
            console.log(err);
        }
    })
}

实现效果:

 完整JS块(代码可直接使用):

/*
 * @Author: Wang JianLei 
 * @Date: 2020-03-30 15:50:27 
 * @Last Modified by: Wang JianLei
 * @Last Modified time: 2020-06-03 10:16:17
 */
/**************************************************************
**********代码内容主要是加载各类矢量数据,包括在线和本地***********
**************************************************************/
$(function () {
    var RootURL = getWinURL(window.location.href);
    // 获取地址url
    function getWinURL(url) {
        var url_index = url.lastIndexOf("/");
        return url.substr(0, url_index);
    }

    var geojsonOptions = {
        clampToGround: true
    };//确保加入的图层贴地
    var geoserverUrl;
    $("#loadFeatureLayer").change(function () {
        var option = $(this).val();
        switch (option) {
            case "加载WFS(geoserver)":
                geoserverUrl = 'http://localhost:8080/geoserver/CesiumTest_WFS';//geoserver服务地址WFS
                //定义各参数
                var param = {
                    service: 'WFS',
                    version: '1.0.0',
                    request: 'GetFeature',
                    typeName: 'WFS',
                    outputFormat: 'application/json'
                };
                $.ajax({
                    url: geoserverUrl + "/ows" + getParamString(param, geoserverUrl),
                    cache: false,
                    async: true,
                    success: function (data) {
                        var dataPromise = Cesium.GeoJsonDataSource.load(data);
                        dataPromise.then(function (dataSource) {
                            viewer.dataSources.add(dataSource);//加载服务数据
                            viewer.flyTo(dataSource);

                            //创建 属性 编辑几何 新增 删除按钮
                            var WFS_ButtonDiv = document.createElement('div');
                            WFS_ButtonDiv.id = 'WFS_ButtonDiv';
                            WFS_ButtonDiv.style.position = 'absolute';
                            WFS_ButtonDiv.style.left = '20px';
                            WFS_ButtonDiv.style.bottom = '20px';
                            var content = '<button class="cesium-button">属性</button> <button class="cesium-button">编辑几何</button> <button class="cesium-button">新增</button> <button class="cesium-button">删除</button>';
                            WFS_ButtonDiv.innerHTML = content;
                            document.getElementById('MapContainer').appendChild(WFS_ButtonDiv);

                            var handler = null;
                            var flag = true;
                            $('#WFS_ButtonDiv button').click(function (e) {
                                var m_div = document.getElementById('propertiesDiv');
                                if (m_div) {
                                    document.getElementById('MapContainer').removeChild(m_div);
                                }
                                var value = this.innerText;
                                switch (value) {
                                    case '属性':
                                        if (handler != null) {
                                            handler.destroy();
                                        }
                                        handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
                                        var ellipsoid = viewer.scene.globe.ellipsoid;
                                        handler.setInputAction(function (movement) {
                                            console.log('属性展示和编辑');
                                            //通过指定的椭球或者地图对应的坐标系,将鼠标的二维坐标转换为对应椭球体三维坐标
                                            cartesian = viewer.camera.pickEllipsoid(movement.position, ellipsoid);
                                            if (cartesian) {
                                                //将笛卡尔坐标转换为地理坐标
                                                var cartographic = ellipsoid.cartesianToCartographic(cartesian);
                                                //将弧度转为度的十进制度表示
                                                var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
                                                var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
                                                var point = longitudeString + ',' + latitudeString;
                                                queryWFSByPoint(geoserverUrl, point, param.typeName, ShowAndEditWfsLayerAttributes);
                                            }
                                        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
                                        break;
                                    default:
                                        break;
                                }
                            });
                        })
                    },
                    error: function (data) {
                        console.log("error");
                    }
                });
                consoleLog(option);
                break;

            default:
                break;
        }
    });
})

function consoleLog(value) {
    console.log(value);
}

/*图层几何编辑
*****@method AddNewWfsLayer
*****@param geoserverUrl Geoserver发布的WFS服务地址
*****@param data 图层数据
*/
function EditWfsLayerGeomertry(geoserverUrl, data) {
    console.log('data', data);
    var m_div = document.getElementById('propertiesDiv');
    if (m_div) {
        document.getElementById('MapContainer').removeChild(m_div);
    }
    if (data && data.features.length > 0) {
        //气泡窗口显示
        var properties = data.features[0].properties;
        var id = data.features[0].id;
        var geometry = data.features[0].geometry;
        var o_Div = document.createElement('div');//属性提示的 DIV 元素
        o_Div.id = 'propertiesDiv';
        document.getElementById('MapContainer').appendChild(o_Div);

        var content = '<p>' + id + '</p>';
        for (var key in properties) {
            var keyName = key;
            var keyValue = properties[key];
            content += '<span>' + keyName + ':</span><input type="text" id="' + keyName + '" value = "' + keyValue + '" /></br>';
        }
        content += '<button type="button" id="editBtn">几何编辑保存</button>';
        $("#propertiesDiv").show();
        $("#propertiesDiv").empty();
        $("#propertiesDiv").append(content);
        $("#editBtn").click(function () {
            getAttributesList();
            if (id) {
                //记录构造polygon,为后续几何图形的编辑做准备
                var polygon = '';
                var pointsArray=new Array();
                var data = geometry.coordinates[0][0];
                for (var i = 0; i < data.length; i++) {
                    var item = data[i];
                    var C3=Cesium.Cartesian3.fromDegrees(item[0],item[1]);
                    let point = viewer.entities.add({
                        name: ' ',
                        position: cartesian,
                        point: {
                            color: Cesium.Color.WHITE,
                            pixelSize: 50,
                            outlineColor: Cesium.Color.BLACK,
                            outlineWidth: 1,
                            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                        }
                    });
                    polygon += item[0] + ',' + item[1] + ',' + item[2] + ' ';
                }
                polygon += data[0][0] + ',' + data[0][1] + ',' + data[0][2];

                var attributesList = getAttributesList();//获取字段名和字段值键值对//暂时数组形式记录
                var typename = id.substr(0, id.indexOf('.'));
                EditWfsLayerAttributs(geoserverUrl, typename, id, polygon, attributesList, refreshLayer);
            }
        });
    }
}



/*图层属性展示和编辑
*****@method ShowAndEditWfsLayerAttributes
*****@param geoserverUrl Geoserver发布的WFS服务地址
*****@param data 图层数据
*/
function ShowAndEditWfsLayerAttributes(geoserverUrl, data) {
    console.log('data', data);
    var m_div = document.getElementById('propertiesDiv');
    if (m_div) {
        document.getElementById('MapContainer').removeChild(m_div);
    }
    if (data && data.features.length > 0) {
        //气泡窗口显示
        var properties = data.features[0].properties;
        var id = data.features[0].id;
        var geometry = data.features[0].geometry;
        var o_Div = document.createElement('div');//属性提示的 DIV 元素
        o_Div.id = 'propertiesDiv';
        document.getElementById('MapContainer').appendChild(o_Div);

        var content = '<p>' + id + '</p>';
        for (var key in properties) {
            var keyName = key;
            var keyValue = properties[key];
            content += '<span>' + keyName + ':</span><input type="text" id="' + keyName + '" value = "' + keyValue + '" /></br>';
        }
        content += '<button type="button" id="editBtn">编辑属性并保存</button>';
        $("#propertiesDiv").show();
        $("#propertiesDiv").empty();
        $("#propertiesDiv").append(content);
        $("#editBtn").click(function () {
            getAttributesList();
            if (id) {
                //记录构造polygon,为后续几何图形的编辑做准备
                var polygon = '';
                var data = geometry.coordinates[0][0];
                for (var i = 0; i < data.length; i++) {
                    var item = data[i];
                    polygon += item[0] + ',' + item[1] + ',' + item[2] + ' ';
                }
                polygon += data[0][0] + ',' + data[0][1] + ',' + data[0][2];

                var attributesList = getAttributesList();//获取字段名和字段值键值对//暂时数组形式记录
                var typename = id.substr(0, id.indexOf('.'));
                EditWfsLayerAttributs(geoserverUrl, typename, id, polygon, attributesList, refreshLayer);
            }
        });
    }
}

function getAttributesList() {
    var List = new Array();
    var texts = $('#propertiesDiv input[type=text]');
    for (let i = 0; i < texts.length; i++) {
        const element = texts[i];
        var cur_Attribute = new Array(element.id, element.value);
        List.push(cur_Attribute);
    }
    return List;
}

/*图层编辑
*****@method EditWfsLayerAttributs
*****@param geoserverUrl Geoserver发布的WFS服务地址
*****@param typeName 图层名
*****@param fid 记录fid值
*****@param attributesList 记录当前图层所有的字段名和字段值【字段名,字段值】
*****@return callback
要注意,字段名不能有中文,绝对不能有
*/
function EditWfsLayerAttributs(geoserverUrl, typeName, fid, polygon, attributesList, callback) {
    var content = '';
    content += '<?xml version="1.0" encoding="utf-8"?>';
    content += '<wfs:Transaction version="1.0.0" service="WFS" username="admin" password="476852678" xmlns:CesiumTest_WFS="http://CesiumTest_WFS" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml">';
    content += '<wfs:Update typeName="CesiumTest_WFS:' + typeName + '">';
    for (let i = 0; i < attributesList.length; i++) {
        const element = attributesList[i];
        content += '<wfs:Property> <wfs:Name>' + element[0] + '</wfs:Name> <wfs:Value>' + element[1] + '</wfs:Value> </wfs:Property>';
    }

    content += '<wfs:Property>';
    content += '<wfs:Name>the_geom</wfs:Name>';
    content += '<wfs:Value>';
    content += '<gml:MultiPolygon> <gml:polygonMember> <gml:Polygon> <gml:outerBoundaryIs> <gml:LinearRing> <gml:coordinates>' + polygon + '</gml:coordinates> </gml:LinearRing> </gml:outerBoundaryIs> </gml:Polygon> </gml:polygonMember> </gml:MultiPolygon>'
    content += '</wfs:Value>';
    content += '</wfs:Property>';

    content += '<ogc:Filter> <ogc:FeatureId fid="' + fid + '" /> </ogc:Filter>'
    content += '</wfs:Update>';
    content += '</wfs:Transaction>';

    $.ajax({
        url: geoserverUrl + '/wfs',
        async: true,
        data: content,
        type: 'post',
        contentType: 'text/xml',
        success(result) {
            callback(result);
        },
        error(err) {
            console.log(err);
        }
    })
}

/*通过点选来选择并获取图层对象
***@method queryWFSByPoint
***@param geoserverUrl Geoserver发布的WFS服务地址
***@param point 查询的位置点
***@param typeName 图层名称
***@return 返回值是点选位置查询获取的的图层对象
*/
function queryWFSByPoint(geoserverUrl, point, typeName, callback) {
    var filter = '<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">';
    filter += '<Intersects>';
    filter += '<PropertyName>the_geom</PropertyName>';
    filter += '<gml:Point>';
    filter += '<gml:coordinates>' + point + '</gml:coordinates>';
    filter += '</gml:Point>';
    filter += '</Intersects>';
    filter += '</Filter>';
    var param = {
        service: 'WFS',
        version: '1.0.0',
        request: 'GetFeature',
        typeName: typeName,
        outputFormat: 'application/json',
        filter: filter
    };
    $.ajax({
        url: geoserverUrl + '/ows' + getParamString(param, geoserverUrl),
        async: true,
        type: 'GET',
        dataType: 'json',
        success(result) {
            callback(geoserverUrl, result);//返给回调函数ShowAndEditWfsLayer
        },
        error(err) {
            console.log(err);
        }
    })
}

//请求参数转化
function getParamString(obj, existingUrl, uppercase) {
    var params = [];
    for (var i in obj) {
        params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
    }
    return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
}

//编辑完成后的回调函数
function refreshLayer(data) {
    var m_div = document.getElementById('propertiesDiv');
    if (m_div) {
        document.getElementById('MapContainer').removeChild(m_div);
    }
}

效果展示:

简单总结:get Json 、Post XML,有任何问题可以评论区指出,后续有时间更新增删改查其他操作。溜溜球~~~~

 

好的,我明白了。关于您的问题,我可以回答:Cesium是一个基于WebGL的虚拟地球和地理信息系统(GIS)库,可以用来展示地球上的各种数据,包括矢量图、卫星影像、地形模型等等。而Geoserver是一个开源的地理信息系统服务器,可以提供各种地图服务,包括WFS服务。 通过将CesiumGeoserver结合起来,我们可以实现矢量图的编辑,具体步骤如下: 1. 首先,需要在Geoserver上创建一个WFS数据源,并发布一个WFS服务。这里不再赘述具体的步骤,可以参考Geoserver的官方文档。 2. 在Cesium中,可以使用Cesium的DataSource来加载WFS服务中的图层数据。具体步骤如下: ```js // 创建一个DataSource var dataSource = new Cesium.GeoJsonDataSource(); // 加载WFS服务中的数据 var promise = dataSource.load('http://localhost:8080/geoserver/wfs', { service: 'WFS', version: '2.0.0', request: 'GetFeature', typeName: 'myworkspace:mylayer', outputFormat: 'application/json' }); // 数据加载完成后,将数据源添加到场景中 promise.then(function() { viewer.dataSources.add(dataSource); }); ``` 3. 接下来,可以使用Cesium的Entity来表示每个要素,并添加一些编辑功能。例如,可以使用Cesium的PolylineGraphics来表示线要素,并添加编辑功能。 ```js // 创建一个线要素 var entity = dataSource.entities.add({ polyline: { positions: Cesium.Cartesian3.fromDegreesArray([ -110.0, 38.0, -105.0, 40.0 ]), width: 5, material: Cesium.Color.RED } }); // 添加编辑功能 entity.polyline.editable = true; entity.polyline.width = 10; entity.polyline.material = Cesium.Color.BLUE; ``` 4. 最后,可以监听Cesium编辑事件,将编辑结果保存回Geoserver中。 ```js // 监听编辑事件 dataSource.entities.collectionChanged.addEventListener(function(collection, added, removed, changed) { // 将编辑结果保存回Geoserver中 // ... }); ``` 以上是实现矢量图编辑的大致步骤,具体的实现可能会因为数据源的不同而有所差异。希望对您有所帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

总要学点什么

相信每一个技术人员的惺惺相惜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值