背景
目前有一個區的圖斑數據需要分鄉鎮展示,所以採用FeatureLayer 的 definitionExpression 構造SQL語句進行過濾,官方提供的示例:
1 // Set definition expression in constructor to only display trees with scientific name Ulmus pumila 2 const layer = new FeatureLayer({ 3 url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0", 4 definitionExpression: "Sci_Name = 'Ulmus pumila'" 5 });
// Set the definition expression directly on layer instance to only display trees taller than 50ft layer.definitionExpression = "HEIGHT > 50";
這個問題出來後,直接讓我懵逼了,總不能把十幾個鄉鎮的圖斑分別發佈出來然後加載吧,這樣子太麻煩了,當然這是最壞的打算。
“領導”的意思是讓後端來封裝一層,這個在其他純前端項目還好,sql語句放到後端,返回個json就好了。但這畢竟是GIS項目,人家都封裝好了,就需要個url,塞個json不合適吧....還說arcgis server發佈的就只能做demo,搞得我有點懷疑人生了
環境
Vue3.0
@arcgis/core
問題
利用definitionExpression 雖然方便,但是處於安全考慮,在正式環境下會被攔截。現場給的回覆是“URL(0141)::where=town%20%3D%20%27320509101000%27%20and%20xcdcqk%20%3C%3E%20%270%27”,被認定爲sql注入攻擊 攔截了
解決方案
其實這個只需要前端規避下在請求url裏面不要攜帶‘where’即可,所以就不要想着直接在定義featurelayer時過濾了,這樣子肯定還是會攜帶‘where’,所以考慮在featurelayer加載後再處理。
我的解決方案是利用layerview的filter來做篩選:
1 // display rain gauges where their water percent is over 30% 2 // and if the gauges are completely contained by the 10-mile 3 // buffer around the filter geometry 4 featureLayerView.filter = new FeatureFilter({ 5 where: "percentile >= 30", 6 geometry: filterPolygon, 7 spatialRelationship: "contains", 8 distance: 10, 9 units: "miles" 10 });
對比
原實際項目代碼:
1 let definitionExpression 2 if (townCode) { 3 definitionExpression = `town = '${townCode}' and xcdcqk <> '0'` 4 } else { 5 definitionExpression = "xcdcqk <> '0'" 6 } 7 8 const patchesLayer = new FeatureLayer({ 9 id: 'patchesLayer', 10 title: '圖斑', 11 url: patchesLayerUrl, 12 definitionExpression: definitionExpression, //直接在實例化FeatureLayer時設置 13 outFields: [ 14 'objectid_1', 15 'fwbh', 16 'lon', 17 'lat', 18 'needCheck', 19 'fwlb', 20 'fwmj', 21 'flloors', 22 'height' 23 ], 24 objectIdField: 'objectid_1', 25 editingEnabled: true, 26 renderer: pathchRender 27 }) 28 map.layers.add(patchesLayer)
請求效果圖,能看到查詢的url裏面攜帶‘where’:
改良後的項目代碼:
1 let definitionExpression 2 if (townCode) { 3 definitionExpression = `town = '${townCode}' and xcdcqk <> '0'` 4 } else { 5 definitionExpression = "xcdcqk <> '0'" 6 } 7 8 const patchesLayer = new FeatureLayer({ 9 id: 'patchesLayer', 10 title: '圖斑', 11 url: patchesLayerUrl, 12 // definitionExpression: definitionExpression, 13 outFields: [ 14 'objectid_1', 15 'fwbh', 16 'lon', 17 'lat', 18 'needCheck', 19 'fwlb', 20 'fwmj', 21 'flloors', 22 'height' 23 ], 24 objectIdField: 'objectid_1', 25 editingEnabled: true, 26 renderer: pathchRender 27 }) 28 map.layers.add(patchesLayer) 29 view.whenLayerView(patchesLayer).then((layerView) => { 30 patchLayerView = layerView 31 //用layerView過濾 32 patchLayerView.filter = { 33 where: definitionExpression 34 } 35 })
請求效果圖,可以看到請求的url中已經不再攜帶‘where’: