module NSWTopo::ArcGIS::Query
def base_query(**options)
def base_query(**options) case when @unique raise UniqueFieldError when @geometry raise "polgyon geometry required" unless @geometry.polygon? options[:geometry] = { rings: @geometry.reproject_to(projection).coordinates.map(&:reverse) }.to_json options[:geometryType] = "esriGeometryPolygon" options[:where] = join_clauses(*@where) if @where when @where options[:where] = join_clauses(*@where) else oid_field = @layer["fields"].find do |field| field["type"] == "esriFieldTypeOID" end&.fetch("name") options[:where] = oid_field ? "#{oid_field} IS NOT NULL" : "1=1" end options end
def count
def count @count ||= get_json("#{@id}/query", **base_query, returnCountOnly: true).dig("count") end
def pages(per_page)
def pages(per_page) objectids = get_json("#{@id}/query", **base_query, returnIdsOnly: true)["objectIds"] || [] @count = objectids.count return [GeoJSON::Collection.new(projection: projection, name: @name)].each if @count.zero? @fields ||= @layer["fields"].select do |field| Layer::FIELD_TYPES === field["type"] end.map do |field| field["name"] end Enumerator.new do |yielder| out_fields = [*@fields, *extra_field].join ?, while objectids.any? begin get_json "#{@id}/query", outFields: out_fields, objectIds: objectids.take(per_page).join(?,) rescue Connection::Error (per_page /= 2) > 0 ? retry : raise end.fetch("features", []).filter_map do |feature| next unless geometry = feature["geometry"] properties = feature.fetch("attributes", {}) case @geometry_type when "esriGeometryPoint" point = geometry.values_at "x", "y" next unless point.all? next GeoJSON::Point[point, properties] when "esriGeometryMultipoint" points = geometry["points"] next unless points&.any? next GeoJSON::MultiPoint[points.transpose.take(2).transpose, properties] when "esriGeometryPolyline" raise "ArcGIS curve geometries not supported" if geometry.key? "curvePaths" paths = geometry["paths"] next unless paths&.any? next GeoJSON::LineString[paths[0], properties] if @mixed && paths.one? next GeoJSON::MultiLineString[paths, properties] when "esriGeometryPolygon" raise "ArcGIS curve geometries not supported" if geometry.key? "curveRings" rings = geometry["rings"] next unless rings&.any? polys = GeoJSON::MultiLineString[rings.map(&:reverse), properties].to_multipolygon next @mixed && polys.one? ? polys.first : polys else raise "unsupported ArcGIS geometry type: #{@geometry_type}" end end.tap do |features| yielder << GeoJSON::Collection.new(projection: projection, features: features, name: @name) end objectids.shift per_page end end end