GIS应用|快速开发REST数据服务

随着计算机的快速发展,GIS已经在各大领域得到应用,和我们的生活息息相关, 但是基于GIS几大厂商搭建服务,都会有一定的门槛,尤其是需要server,成本高,难度大,这里介绍一种在线GIS云平台,帮你快速解决服务端的问题,你只需要考虑自己客户端的业务层即可

SuperMap Online,可在线上传数据,发布多种REST服务,为您节省购买和部署SuperMap iServer的大量财力和时间成本,将数据和服务进行安全稳定的托管。

发布为REST数据服务的数据,可以通过少量代码开发来实现要素编辑即点、线、面数据的增删改查等功能。下面带领大家快速玩转REST数据服务!

要素编辑

(点击在线演示”可在线查看)

 

01上传数据,发布服务,在线安全托管

打开SuperMap Online并登录您的账号,依次点击“资源中心”-“数据”-“上传数据”。

上传数据

选择数据类型并进行上传。本示例使用的是SuperMap工作空间数据—“china.zip”。(示例数据百度云下载链接: https://pan.baidu.com/s/17gsAySUvb_nbsYWHQi4UHQ   提取码: h845 )。

选择数据并上传

云存储支持将上传的数据发布为地图、数据、三维、空间分析等多种类型的REST服务。本示例选择发布的服务类型为“REST数据服务”。

选择服务类型并发布

发布完成后的数据可以在“资源中心”-“数据”-“我的数据”查看。调用服务前需要开启数据共享。点击服务名称下对应服务地址,选择目标目录复制链接即可调用该REST数据服务,数据服务的子资源在 SuperMap iServer中是数据查询和操作的入口,提供了数据源集合和数据查询功能的资源信息。

修改数据权限,打开REST数据服务

选择目标目录

获取REST数据服务地址

REST数据服务也可以通过使用“密钥key”的方式来进行调用,搜索并打开SuperMap Online,在首页下方找到开发模块,更多服务调用方式等你发现!

SuperMap Online首页开发模块

02调用REST数据服务,实现数据修改功能

获取服务地址后,即可在网页中调用REST数据服务。示例中,底图调用的是REST地图服务,点击可查看REST地图服务使用方法哦

调用REST数据服务

通过简单代码编写,可以对REST数据服务进行编辑。如已知某点坐标,即可以直接在REST数据服务中添加该点。

新增点数据

REST数据服务也可以用于打造在线数据编辑平台,可以实现点、线、面要素的增删改查,修改后的结果可以同步到REST数据服务当中。

要素编辑

源码如下:

 

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css" rel="stylesheet" />
    <link href='https://iclient.supermap.io/dist/ol/iclient-ol.min.css' rel='stylesheet' />
    <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://iclient.supermap.io/dist/ol/iclient-ol.min.js"></script>
    <link href='https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' />
    <script type="text/javascript" src="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="https://iclient.supermap.io/examples/js/widgets.js"></script>
    <title>地物编辑</title>
    <style>
        .ol-zoom {
            bottom: .5em;
            font-size: 18px;
            top: unset;
        }
        
        .editPane {
            position: absolute;
            left: 15px;
            top: 8px;
            text-align: center;
            background: #FFF;
            z-index: 1000;
            border-radius: 4px;
        }
        
        .ol-popup {
            position: absolute;
            background-color: white;
            -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
            filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #cccccc;
            bottom: 12px;
            left: -50px;
            min-width: 120px;
        }
        
        .ol-popup:after,
        .ol-popup:before {
            top: 100%;
            border: solid transparent;
            content: " ";
            height: 0;
            width: 0;
            position: absolute;
            pointer-events: none;
        }
        
        .ol-popup:after {
            border-top-color: white;
            border-width: 10px;
            left: 48px;
            margin-left: -10px;
        }
        
        .ol-popup:before {
            border-top-color: #cccccc;
            border-width: 11px;
            left: 48px;
            margin-left: -11px;
        }
        
        .tooltip {
            position: relative;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 4px;
            color: white;
            padding: 4px 8px;
            opacity: 0.7;
            white-space: nowrap;
        }
        
        @media only screen and (max-width: 640px) {
            #msg_container {
                transform: translate(-35%, -20%);
            }
        }
    </style>
</head>

<body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%; position: absolute;top: 0;">
    <div id="map" style="width: 100%;height:100%"></div>
    <div id="popup" class="ol-popup">
        <div id="popup-content"></div>
    </div>
    <div>
        <div class="panel panel-primary editPane" id="editPane">
            <div class='panel-heading'>
                <h5 class='panel-title text-center'>编辑单个要素</h5>
            </div>
            <div class='panel-body content'>
                <input type='button' class='btn btn-default' value="添加地物" onclick='addMarker()' /> 
                <input type='button' class='btn btn-default' value="撤销添加" onclick='revocationMarker()' />
                <input type='button' class='btn btn-default' value="提交" onclick='commit()' /> 
                <input type='button' class='btn btn-default' value="修改" onclick='clearLayer(selectFeaturForUpdate)' /> 
                <input type='button' class='btn btn-default' value="清除" onclick='clearLayer(selectFeatureForDelete)' />
            </div>
        </div>
    </div>
    <div id="pointInfoModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="largerModal">
        <div class="modal-dialog modal-sm" role="document">
            <div class="modal-content">
                <div class="modal-header">输入新增点名字</div>
                <div class="modal-body">
                    <input type="text" class="form-control" id="point-info" autocomplete="off">
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal" onclick="revocationMarker()">取消</button>
                    <button type="button" class="btn btn-primary" onclick="setPointName()">确定</button>
                </div>
            </div>
        </div>
    </div>
    <div class="modal fade" id="updatePointModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog modal-sm">
            <div class="modal-content" style="width: 400px;">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">
                        ×
                    </button>
                    <h4 class="modal-title" id="myModalLabel">
                        要素信息
                    </h4>
                </div>
                <div class="modal-body">
                    <form class="form-horizontal" role="form">
                        <div class="form-group">
                            <label for="name" class="col-sm-3  control-label" style="width: 21%;">Name</label>
                            <div class="col-sm-9">
                                <input type="text" class="form-control" id="name" name="name" value="">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="x" class="col-sm-3 control-label" style="width: 21%;">X(m)</label>
                            <div class="col-sm-9">
                                <input type="text" class="form-control" name="x" value="" id="x">
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="y" class="col-sm-3 control-label" style="width: 21%;">Y(m)</label>
                            <div class="col-sm-9">
                                <input type="text" class="form-control" name="y" value="" id="y">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    <button type="submit" class="btn btn-primary" onclick="updateFeature()">修改</button>
                </div>
            </div>
        </div>
    </div>
    <div class="modal fade" id="confirmModel">
        <div class="modal-dialog">
            <div class="modal-content message_align" style="width: 400px;">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                            aria-hidden="true">×</span></button>
                    <h4 class="modal-title">确认信息</h4>
                </div>
                <div class="modal-body">
                    <p id="delcfmMsg">您确认要删除吗?</p>
                </div>
                <div class="modal-footer">
                    <input type="hidden" id="submitUrl" />
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                    <a onclick="deleteFeature()" class="btn btn-success" data-dismiss="modal">确定</a>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        var map, draw, pointFeature, vectorSource, resultLayer, addPointsSource, addPointsLayer,
            func, update, deletedId, helpTooltipElement, helpTooltip, isclearPoint,
            baseMap = "https://maptiles.supermapol.com/iserver/services/map_China/rest/maps/China_Dark",
            //替换为在online上发布的数据服务,需要设置为公开
            dataService = "https://www.supermapol.com/proxy/iserver/services/data_china_54y8bdc4/rest/data",
            editFeaturesService = new ol.supermap.FeatureService(dataService),
            container = document.getElementById('popup'),
            content = document.getElementById('popup-content'),
            pointName = document.getElementById('point-info'),
            overlay = new ol.Overlay(({
                element: container,
                autoPan: true,
                autoPanAnimation: {
                    duration: 250
                },
                offset: [0, -20]
            })),

            map = new ol.Map({
                target: 'map',
                controls: ol.control.defaults({
                        attributionOptions: {
                            collapsed: true
                        }
                    })
                    .extend([]),
                view: new ol.View({
                    center: [12962344.405822188, 4830679.745330002],
                    zoom: 5,
                    projection: 'EPSG:3857',
                    multiWorld: true
                }),
            });
        var layer = new ol.layer.Tile({
            source: new ol.source.TileSuperMapRest({
                url: baseMap
            }),
            projection: 'EPSG:3857'
        });
        map.addLayer(layer);

        createHelpTooltip();
        initFeature();
        loadLayer();

        //创建鼠标操作提示
        function createHelpTooltip() {
            if (helpTooltipElement) {
                helpTooltipElement.parentNode.removeChild(helpTooltipElement);
            }
            helpTooltipElement = document.createElement('div');
            helpTooltipElement.className = 'tooltip hidden';
            helpTooltip = new ol.Overlay({
                element: helpTooltipElement,
                offset: [15, 0],
                positioning: 'center-left'
            });
        }

        //查询数据,页面初始化显示
        function initFeature() {
            var getFeatureParams = new SuperMap.GetFeaturesBySQLParameters({
                //查询参数,根据自己的服务设置参数
                queryParameter: {
                    name: "CityA_P@China",
                    orderBy: "SMID desc"
                },
                datasetNames: ["China:CityA_P"],
                fromIndex: 0,
                toIndex: 30
            });
            editFeaturesService.getFeaturesBySQL(getFeatureParams, function(serviceResult) {
                var features = (new ol.format.GeoJSON()).readFeatures(serviceResult.result.features);
                for (var i = 0; i < features.length; i++) {
                    features[i].setStyle(new ol.style.Style({
                        image: new ol.style.Icon(({
                            anchor: [0.5, 0.9],
                            src: 'https://iclient.supermap.io/examples/img/markerbig_select.png'
                        }))
                    }));
                }

                //避免重复添加图层,只对一个图层进行数据更新操作:
                if (vectorSource.getFeatures().length > 0) {
                    vectorSource.clear();
                }
                vectorSource.addFeatures(features);
                map.on('pointermove', pointermoveLinstener);
            });
        }

        //添加图层
        function loadLayer() {
            //添加查询结果图层
            vectorSource = new ol.source.Vector({
                wrapX: false
            });
            resultLayer = new ol.layer.Vector({
                source: vectorSource,
            });

            //添加点图层
            addPointsSource = new ol.source.Vector({
                wrapX: false
            });
            addPointsLayer = new ol.layer.Vector({
                source: addPointsSource,
            });

            map.addLayer(addPointsLayer);
            map.addLayer(resultLayer);
        }

        //鼠标移动监听,移动到点上显示名字
        function pointermoveLinstener(e) {
            var select = false;
            map.forEachFeatureAtPixel(e.pixel, function(feature) {
                if (feature.getProperties().NAME) {
                    map.getTargetElement().style.cursor = 'pointer';
                    var contentHTML = feature.getProperties().NAME;
                    content.innerHTML = contentHTML;
                    overlay.setPosition(feature.getGeometry().getCoordinates());
                    map.addOverlay(overlay);
                    select = true
                }
            }, {
                hitTolerance: 10
            });
            if (!select) {
                map.getTargetElement().style.cursor = '';
                overlay.setPosition(undefined);
                map.removeOverlay(overlay);
            }
            if (isclearPoint) {
                helpTooltipElement.innerHTML = '选择要操作的要素';
                helpTooltip.setPosition(e.coordinate);
                helpTooltipElement.classList.remove('hidden');
                map.addOverlay(helpTooltip);
            } else {
                helpTooltip.setPosition(undefined);
                helpTooltipElement.classList.add('hidden');
            }
        }

        //添加标记点
        function addMarker() {
            if (isclearPoint) {
                closeSelectListener(func);
            }
            widgets.alert.clearAlert();
            if (!pointFeature) {
                ceateMarker()
            } else {
                addPointsSource.clear();
                ceateMarker()
            }
            //通过点击创建标记点
            function ceateMarker() {
                draw = new ol.interaction.Draw({
                    source: addPointsSource,
                    type: 'Point'
                });
                map.addInteraction(draw);
                draw.on("drawstart", function(e) {
                    pointFeature = e.feature;
                    pointFeature.setStyle(new ol.style.Style({
                        image: new ol.style.Circle({
                            fill: new ol.style.Fill({
                                color: [255, 0, 0, 0.5]
                            }),
                            stroke: new ol.style.Stroke({
                                color: 'red',
                                width: 2
                            }),
                            radius: 8
                        })
                    }));
                    addPointsSource.addFeature(pointFeature);
                    map.removeInteraction(draw);
                    $('#pointInfoModal').modal({
                        backdrop: 'static',
                        keyboard: false,
                        show: true
                    })
                    $('#pointInfoModal').on('shown.bs.modal', function() {
                        $("#pointInfoModal #point-info").focus();
                    });
                });

            }
        }

        //设置添加点的名字
        function setPointName() {
            pointFeature.setProperties({
                "NAME": pointName.value
            });
            $('#point-info').val("");
            $('#pointInfoModal').modal('hide');
        }

        //撤销添加,清除标绘点
        function revocationMarker() {
            if (pointFeature) {
                addPointsSource.clear();
                pointFeature = null;
            } else {
                widgets.alert.showAlert('没有可撤回的要素。', false);
            }

        }

        //提交新增点到数据服务
        function commit() {
            widgets.alert.clearAlert();
            if (pointFeature) {
                //新增点要素参数,根据自己的服务设置参数
                var addFeatureParams = new SuperMap.EditFeaturesParameters({
                    features: pointFeature,
                    dataSourceName: "China",
                    dataSetName: "CityA_P",
                    editType: "add",
                    returnContent: true
                });
                editFeaturesService.editFeatures(addFeatureParams, function(serviceResult) {
                    if (serviceResult.result.succeed) {
                        addPointsSource.clear();
                        vectorSource.clear();
                        pointFeature = null;
                        initFeature();
                        widgets.alert.showAlert('提交成功', true);
                    }
                });
            } else {
                widgets.alert.showAlert('没有可提交的新要素,请先添加新要素。', false);
            }
        }

        //地图点击事件,选择点进行修改或删除
        function clearLayer(method) {
            widgets.alert.clearAlert();
            isclearPoint = true;
            map.on('click', method);
            func = method;
        }

        //选择要素修改
        function selectFeaturForUpdate(e) {
            if (isclearPoint) {
                closeSelectListener(func);
            }
            update = null;
            widgets.alert.clearAlert();
            map.forEachFeatureAtPixel(e.pixel, function(feature) {
                //只修改选中第一个要素:
                if (!update) {
                    update = feature;
                    var coordinate = feature.getGeometry().getCoordinates();
                    var name = feature.getProperties().NAME;
                    $('#name').val(name);
                    $('#x').val(coordinate[0]);
                    $('#y').val(coordinate[1]);
                    $('#updatePointModal').modal({
                        backdrop: 'static',
                        keyboard: false,
                        show: true
                    })
                }
            }, {
                hitTolerance: 1
            });
        }

        //修改要素,更新数据服务
        function updateFeature() {
            $('#updatePointModal').modal('hide');
            var name = document.getElementById('name').value;
            var x = document.getElementById('x').value;
            var y = document.getElementById('y').value;
            update.getGeometry().setCoordinates([x, y]);
            update.setProperties({
                "NAME": name
            });
            //修改要素参数,根据自己的服务设置参数
            var updateParams = new SuperMap.EditFeaturesParameters({
                dataSourceName: "China",
                dataSetName: "CityA_P",
                features: update,
                editType: "update"
            });
            editFeaturesService.editFeatures(updateParams, function(serviceResult) {
                if (serviceResult.result.succeed) {
                    initFeature();
                    vectorSource.clear();
                    isclearPoint = false;
                    closeSelectListener(selectFeaturForUpdate);
                    widgets.alert.showAlert('更新成功', true);
                } else {
                    widgets.alert.showAlert('更新失败', false)
                }
            });
        }

        //选择要素删除
        function selectFeatureForDelete(e) {
            if (isclearPoint) {
                closeSelectListener(func);
            }
            deletedId = null;
            map.forEachFeatureAtPixel(e.pixel, function(feature) {
                //只删选中第一个要素:
                if (!deletedId) {
                    deletedId = feature.getId();
                    //避免示例数据被删除,只允许删除额外添加的点
                    if (deletedId > 269) {
                        $('#confirmModel').modal({
                            backdrop: 'static',
                            keyboard: false,
                            show: true
                        })
                    } else {
                        widgets.alert.showAlert('为保持示例数据完整性,请先添加一个点来进行删除操作', false)
                    }
                }
            }, {
                hitTolerance: 1
            });
        }

        //删除要素,更新数据服务
        function deleteFeature() {
            //删除要素参数,根据自己的服务设置参数
            var deleteParams = new SuperMap.EditFeaturesParameters({
                dataSourceName: "China",
                dataSetName: "CityA_P",
                IDs: [deletedId],
                editType: "delete"
            });

            editFeaturesService.editFeatures(deleteParams, function(serviceResult) {
                if (serviceResult.result.succeed) {
                    initFeature();
                    vectorSource.clear();
                    isclearPoint = false;
                    closeSelectListener(selectFeatureForDelete);
                    widgets.alert.showAlert('删除要素成功!', true);
                } else {
                    widgets.alert.showAlert('删除要素失败!', false)
                }
            });
        }

        //关闭地图点击事件,移除鼠标提示
        function closeSelectListener(method) {
            isclearPoint = false;
            map.un('click', method);
            helpTooltip.setPosition(undefined);
            map.removeOverlay(helpTooltip);
            helpTooltipElement.classList.add('hidden');
        }
    </script>
</body>

</html>

 

  

 

REST数据服务不仅可以通过简单开发实现数据编辑、查询等功能,也可以直接在云应用中通过“添加服务”的方式进行使用。本篇文章以REST数据服务为例,通过云存储还可以发布地图、三维、空间分析等多种类型的REST服务,点击可查看REST地图服务使用方法,后续会发布更多关于REST服务使用的相关文章,还请大家多多关注哦!

posted on 2021-10-19 14:49  追梦的远远  阅读(354)  评论(0编辑  收藏  举报

导航