隨着計算機的快速發展,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服務使用的相關文章,還請大家多多關注哦!