如何在Python中通过自定义几何查询ArcGIS REST地图服务数据?
ArcGIS Map Service 几何相交查询的正确实现方法
不行,不能把geometry_json直接加到Where子句里。ArcGIS Map Service的空间查询需要使用专门的API参数,而非普通的属性查询条件。下面是修改脚本实现几何相交查询的具体方法:
核心原理
ArcGIS REST API的query接口支持空间筛选,需要传入以下关键参数:
geometry: 自定义几何的JSON字符串geometryType: 几何类型(对应你的esriGeometryPolygon)spatialRel: 空间关系,这里用esriSpatialRelIntersects表示"相交"
修改后的完整脚本
import arcpy import urllib.request import json import urllib.parse # Setup arcpy.env.overwriteOutput = True baseURL = r"https://gisp.dfo-mpo.gc.ca/arcgis/rest/services/FGP/MSDI_Dynamic_Current_Layer/MapServer/0" fields = "*" outdata = r"out/path" # 自定义几何(你的多边形) geometry_json = { "geometryType" : "esriGeometryPolygon", "spatialReference" : { "wkid" : 4326, "latestWkid" : 4326 }, "features" : [{ "geometry":{ "curveRings":[ [[-123.77335021899995,49.353870065000081],{"a":[[-123.77335021899995,49.353870065000081],[-123.88831213030559,49.338864996255367],0,1]}]]}}] } # 提取实际几何对象并转成URL可用的JSON字符串 query_geometry = json.dumps(geometry_json["features"][0]["geometry"]) geometry_type = geometry_json["geometryType"] spatial_rel = "esriSpatialRelIntersects" # 获取服务单批次最大记录限制 urlstring = baseURL + "?f=json" j = urllib.request.urlopen(urlstring) js = json.load(j) maxrc = int(js["maxRecordCount"]) print ("单批次最大记录数: %s" % maxrc) # 获取与自定义几何相交的特征Object IDs urlstring = (f"{baseURL}/query?where=1=1" f"&geometry={urllib.parse.quote(query_geometry)}" f"&geometryType={geometry_type}" f"&spatialRel={spatial_rel}" f"&returnIdsOnly=true&f=json") j = urllib.request.urlopen(urlstring) js = json.load(j) idfield = js["objectIdFieldName"] idlist = js["objectIds"] if "objectIds" in js else [] if not idlist: print("没有找到与指定几何相交的记录") exit() idlist.sort() numrec = len(idlist) print ("符合条件的记录数: %s" % numrec) # 分批次获取特征数据 print ("正在获取记录...") fs = dict() for i in range(0, numrec, maxrc): torec = i + (maxrc - 1) if torec > numrec: torec = numrec - 1 fromid = idlist[i] toid = idlist[torec] where = "{} >= {} and {} <= {}".format(idfield, fromid, idfield, toid) print (" 正在获取: {}".format(where)) # 分块查询时同样带上空间参数,确保只返回符合条件的记录 urlstring = (f"{baseURL}/query?where={where}" f"&geometry={urllib.parse.quote(query_geometry)}" f"&geometryType={geometry_type}" f"&spatialRel={spatial_rel}" f"&returnGeometry=true&outFields={fields}&f=json") fs[i] = arcpy.FeatureSet() fs[i].load(urlstring) # 保存合并后的结果 print ("正在保存数据...") fslist = [] for key,value in fs.items(): fslist.append(value) arcpy.Merge_management(fslist, outdata) print ("完成!")
关键修改点说明
- 提取有效几何对象:从你的
geometry_json中取出内层的geometry对象(外层features结构是多余的,API直接接收几何对象) - URL编码处理:用
urllib.parse.quote对几何JSON字符串编码,避免URL解析出错 - 添加空间参数:在获取Object ID和分块获取特征的请求中,都加入空间查询参数,确保只筛选相交的记录
- 空结果判断:如果没有找到相交记录,直接终止脚本,避免后续无意义的执行
内容的提问来源于stack exchange,提问作者seak23
相关产品推荐
相关产品推荐

