前言
最近在项目现场部署系统,用到了ArcGIS 的Sever进行发布服务并调用,本来想自己网上查一查解决的,但网上的帖子说得都不太清除,以至于最后还是要找公司开发请教。所以今天写这篇博文记录总结一下,也方便大家参考。
软件基础
ArcGIS Sever:用于服务的发布
ArcMap:用于修改图层的样式、数量以及注册数据源(数据所在文件夹或数据库)
这里推荐用10.2版本,原因是这个版本才有能白嫖的Sever。
发布服务
这步的教程网上比较多,写得也足够好,这里不再赘述,仅提供其他人的文章给大家参考:
发布地图服务(MapSever):https://zhuanlan.zhihu.com/p/98645457
发布要素服务(FeatureSever):https://blog.csdn.net/lovecarpenter/article/details/52462207
注意:地图服务是仅供查看的服务,只能修改图层的显示样式不能对图层本身进行增删改;而要素服务可以进行图层内部图形的增删改,但不能修改图层的显示样式,并且发布要素服务的数据必须是在数据库里,否则发布服务时会报错。
连接数据库
由于ArcGIS支持的数据库比较多,pgsql、oracle等都可以,这部分网上教程也比较多,可以尝试搜索。再此不赘述。这里提供一个连接pgsql的博文供大家参考:
https://www.cnblogs.com/esrichina/p/4389109.html
注意:如果后续想要对图层内容进行增删改,如给某shp图层加一个多边形,一定要在连接的数据库的基础上建立企业级地理数据库,否则你进行插入多边形等操作时,可能会发生程序返回插入成功,但实际图形并没有保存到图层的问题。
要素服务
由于地图服务仅供查看,因此大家把它配到自己的web应用中,能显示出来就行了,没什么需要讲的,所以这里着重讲一下如何调用要素服务对其中图层内容进行增删查改。
新增图形
可以到其图形界面下进行新增,服务地址一般形式:
http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/addFeatures
出来的是这个界面:
其中输入Features的格式一般为esrijson格式,如:
[{
"geometry": {"type":"polygon","rings":[[[112.9779052734375,22.573438264572395],[112.906494140625,22.28655503294358],[112.8680419921875,22.075459351546858],[113.25256347656249,21.993988560906033],[113.80462646484375,22.1823184841715],[113.51074218749999,22.59119025242291],[112.9779052734375,22.573438264572395]]]},
"attribute": {
"attr1": "11",//字符串类型
“attr2”:3//数字类型
}
}]
但这并没有什么实用价值。
一般我们希望我们的web应用可以调用这个接口,这里以js代码调用为例:
var formdata = new FormData()
var data = [{
"geometry": {"type":"polygon","rings":
[[[112.9779052734375,22.573438264572395],
[112.906494140625,22.28655503294358],
[112.8680419921875,22.075459351546858],
[113.25256347656249,21.993988560906033],
[113.80462646484375,22.1823184841715],
[113.51074218749999,22.59119025242291],
[112.9779052734375,22.573438264572395]]]},
"attribute": {
"attr1": "11",
"attr2":3
}
}]
formData.append("features", JSON.stringify(data))
formData.append("f", 'json')//告诉系统这是esrijson格式的数据
$.ajax({
url: 'http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/addFeatures',
type: 'post',
data: formData,
processData: false,
contentType: false,
success: function (data) {
console.log(data)
}
});
利用formdata对象拼接需要传入的参数,再利用$.ajax函数,传参到我们要素服务地址当中。新增成功会返回参数:
更新图形属性
地址一般格式为:http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/updateFeatures
更新属性只要提供如下参数即可,但还是那句话,这种方式没有实用价值:
[ { "attributes" : {
"OBJECTID" : 13,
"Road_Name" : "sss", }
} ]
在web应用中以js代码调用的方法:
var formData = new FormData();
var tempfeature=[{
"attributes" : {
"OBJECTID" : 13,
"attr1" : "666",//修改我们想改的属性值
}
}
];
var updatefeature=JSON.stringify(tempfeature);
formData.append("features", updatefeature);
formData.append("format", 'json');
$.ajax({
url:'http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/updateFeatures',
type: 'post',
data: formData,
processData: false,
contentType: false,
success: function (feature) {
console.log(feature)
}
});
同样也是用formdata拼接更新图形的参数,在利用$.ajax函数将参数传到服务地址。更新成功后:
但这个方法存在一个致命问题,就是如何得到我想修改的图形的objectid。这里可以根据图形的其他属性,比如现在我有一个宗地图层,宗地会有唯一的宗地代码,我们可以利用宗地代码来倒查objectid。而查询的方法可以是:
例示url:http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/query
这里只需要指定查询条件where就行假如查询字段是数字类型则传参"zddm = 33",假如是字符串类型则传参"zddm = ‘33’"。(注意数据格式选json)
也可以用js代码加$.ajax的方式:
let oid=[];
$.ajax({
url: 'http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/query',
data: {
"where": "zddm = 33",
"geometryType": "esriGeometryEnvelope",
"spatialRel": "esriSpatialRelIntersects",
"relationParam": "",
"outFields": "*",
"returnGeometry": true,
"maxAllowableOffset": "",
"geometryPrecision": "",
"f": "pjson"
},
type: 'GET',
contentType: 'application/json', // 不要设置Content-Type请求头
success: function (data) {
console.log("查询结果", data)
oid.push(JSON.parse(data));//data的键是字符串形式的,需要把其键解码成普通形式的{”key“:123}-----》{key:123},后者可以通过data[”key“]索引,但解码之前不行。
}
});
objectid=oid[0]["features"][0]["attributes"]["objectid"];//这是符合条件的第一个图形的objectid,假如返会结果有多个,可以修改["features"][0]为["features"][n]以获得其他值。
然后将查到的objectid反代会上述更新图形的参数中即可。
删除图形
例示url:http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/deleteFeatures
打开删除的服务地址后显示的界面:
这里只需要指定想删除的图形objectid即可,想获得对应objectid可以参考属性更新那里,采用通过某属性为条件进行查询获得。
利用js代码和$.ajax时,方法如下:
var formdata=new FormData();//需要以formdata格式处理好相关数据
formdata.append("objectIds", 7);//要删除的图形的objectid
formdata.append("geometryType","esriGeometryEnvelope");//默认设置
formdata.append("spatialRel","esriSpatialRelIntersects");//默认设置
formdata.append("f","pjson");//告诉系统,我们的参数格式是json格式,pjson据说是能解决跨域,具体我也不太懂,知道的可以告诉我。
$.ajax({
url: 'http://ip:6080/arcgis/rest/services/test/test1/FeatureServer/0/deleteFeatures',
type: 'post',
data:formdata,
processData: false,
contentType: false,
success: function (data) {
console.log(data)
}
});
删除成功后返回代码: