defra_ruby_area 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8d89480d54dc8d9b14ee66e19ed637eabe76f6882ab44b4c2b8a3f23953951a
4
- data.tar.gz: 41609ce1da6d6a4ec09e692d5a77509548edb756f27e3bf2f2681316c114adb2
3
+ metadata.gz: 23956bd4e1621ffa7cf04a30b4096e33e990e83b6738c79d6ef11956589df6dc
4
+ data.tar.gz: 87fbeb2e00e7c88eb2212c6ef6216c3bd4b615a88fc256a289fae8f25797f758
5
5
  SHA512:
6
- metadata.gz: 291c9a85168a3ebd8b7407c9d1ed2cb69a33ed6ebbc0f67e981ce0fcaa77283b75cde0a1dc861528892ec8fbbf701688ad71badf79a0a1d048691e00f7c4dfea
7
- data.tar.gz: 898852ee546a6ef9db708639d0f034cd4cbab2c45a5ddb56657a0719133f6a1cdb108ace33e4fda03ae32308ec8c4270623bb5bb4048bcbddfa3381df1ecfc4a
6
+ metadata.gz: fbc060baebb90675695021b2e23ba9d25e977eed08fa8269cb3b87c7cb8a6dc229cbf43dbbc8baabf3915fadd8e3e029a1e3df15af6807d40915db904fa3f8cd
7
+ data.tar.gz: e91c6dc5995437f46aaaaa0d2225278170d471b919881872c6f7afd330a351f48874f37eba0de11f5d113e7a75601aa5a11715ecf176006e073ad2af70abf6c2
data/README.md CHANGED
@@ -91,29 +91,38 @@ A [Web Feature Service (WFS)](https://en.m.wikipedia.org/wiki/Web_Feature_Servic
91
91
 
92
92
  Calls are made using url query params. For example behind the scenes `DefraRuby::Area::PublicFaceAreaService` is hitting the following URL
93
93
 
94
- `https://environment.data.gov.uk/spatialdata/administrative-boundaries-environment-agency-and-natural-england-public-face-areas/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&typeNames=ms:Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas&propertyName=long_name&SRSName=EPSG:27700&Filter=(<ogc:Filter><ogc:Intersects><ogc:PropertyName>SHAPE</ogc:PropertyName><gml:Point><gml:coordinates>408602.61,257535.31</gml:coordinates></gml:Point></ogc:Intersects></ogc:Filter>)`
95
-
96
- As you can see it uses XML within query, and will return the result in XML.
97
-
98
- ```xml
99
- <?xml version="1.0" encoding="utf-8" ?>
100
- <wfs:FeatureCollection xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:dataset-91d0fb43-209c-477f-91e3-74e756296268="https://environment.data.gov.uk/spatialdata/dataset-91d0fb43-209c-477f-91e3-74e756296268/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://environment.data.gov.uk/spatialdata/dataset-91d0fb43-209c-477f-91e3-74e756296268/wfs https://environment.data.gov.uk/geoservices/datasets/91d0fb43-209c-477f-91e3-74e756296268/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=dataset-91d0fb43-209c-477f-91e3-74e756296268%3AAdministrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd">
101
- <gml:boundedBy>
102
- <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#27700">
103
- <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">57821.0086,-17164.8096 680640.9677,669368.5003</gml:coordinates>
104
- </gml:Box>
105
- </gml:boundedBy>
106
- <gml:featureMember>
107
- <dataset-91d0fb43-209c-477f-91e3-74e756296268:Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas fid="Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas.1">
108
- <gml:boundedBy>
109
- <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#27700">
110
- <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">280034.5456,45980.9664 421821.4,182101.3994</gml:coordinates>
111
- </gml:Box>
112
- </gml:boundedBy>
113
- <dataset-91d0fb43-209c-477f-91e3-74e756296268:long_name>Wessex</dataset-91d0fb43-209c-477f-91e3-74e756296268:long_name>
114
- </dataset-91d0fb43-209c-477f-91e3-74e756296268:Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas>
115
- </gml:featureMember>
116
- </wfs:FeatureCollection>
94
+ `https://environment.data.gov.uk/spatialdata/administrative-boundaries-environment-agency-and-natural-england-public-face-areas/wfs?outputformat=json&SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&typeNames=ms:Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas&propertyName=identifier,long_name,code,short_name&SRSName=EPSG:27700&cql_filter=bbox(shape,408602.61,257535.31,408602.61,257535.31)`
95
+
96
+ As you can see output requested in JSON, and will return the result in JSON format.
97
+
98
+ ```json
99
+ {
100
+ "type": "FeatureCollection",
101
+ "features": [
102
+ {
103
+ "type": "Feature",
104
+ "id": "Administrative_Boundaries_Environment_Agency_and_Natural_England_Public_Face_Areas.23",
105
+ "geometry": null,
106
+ "properties": {
107
+ "identifier": 51,
108
+ "long_name": "West Midlands",
109
+ "short_name": "West Midlands",
110
+ "code": "WMD"
111
+ },
112
+ "bbox": [
113
+ 316114.5,
114
+ 187934.4,
115
+ 456472.5,
116
+ 369909.5
117
+ ]
118
+ }
119
+ ],
120
+ "totalFeatures": 1,
121
+ "numberMatched": 1,
122
+ "numberReturned": 1,
123
+ "timeStamp": "2023-11-30T11:06:46.945Z",
124
+ "crs": null
125
+ }
117
126
  ```
118
127
 
119
128
  ### Further reading
@@ -7,24 +7,30 @@ module DefraRuby
7
7
  class Area
8
8
  attr_reader :area_id, :area_name, :code, :long_name, :short_name
9
9
 
10
- def initialize(wfs_xml_element)
11
- @xml = wfs_xml_element
10
+ def initialize(area_record)
11
+ @area_record = area_record
12
12
 
13
- validate_xml
14
- parse_xml
13
+ validate_area_record
14
+ parse_area_record
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def validate_xml
20
- raise(ArgumentError, "wfs_xml_element is invalid") unless @xml.is_a?(Nokogiri::XML::Element)
19
+ def validate_area_record
20
+ unless @area_record && @area_record["properties"]&.keys&.sort == %w[
21
+ code identifier long_name short_name
22
+ ]
23
+ raise(ArgumentError,
24
+ "area_record is invalid")
25
+ end
21
26
  end
22
27
 
23
- def parse_xml
24
- @area_id = @xml.xpath("*[local-name()='identifier']").text.to_i
25
- @code = @xml.xpath("*[local-name()='code']").text
26
- @long_name = @xml.xpath("*[local-name()='long_name']").text
27
- @short_name = @xml.xpath("*[local-name()='short_name']").text
28
+ def parse_area_record
29
+ @area_id = @area_record.dig("properties", "identifier").to_i
30
+ @code = @area_record.dig("properties", "code")
31
+ @long_name = @area_record.dig("properties", "long_name")
32
+ @short_name = @area_record.dig("properties", "short_name")
33
+ # area_name is no longer part of the response, but we're keeping it for backwards compatibility
28
34
  @area_name = @long_name
29
35
  end
30
36
 
@@ -30,7 +30,8 @@ module DefraRuby
30
30
  url: url,
31
31
  timeout: DefraRuby::Area.configuration.timeout
32
32
  )
33
- areas = extract_areas(Nokogiri::XML(response))
33
+
34
+ areas = extract_areas(JSON.parse(response))
34
35
 
35
36
  raise NoMatchError unless areas.any?
36
37
 
@@ -38,10 +39,10 @@ module DefraRuby
38
39
  end
39
40
  end
40
41
 
41
- def extract_areas(xml_response)
42
+ def extract_areas(json_response)
42
43
  areas = []
43
- xml_response.xpath("//wfs:FeatureCollection/gml:featureMember").each do |parent|
44
- areas << Area.new(parent.first_element_child)
44
+ json_response["features"].each do |area_record|
45
+ areas << Area.new(area_record)
45
46
  end
46
47
 
47
48
  areas
@@ -69,10 +70,11 @@ module DefraRuby
69
70
  "SERVICE" => service,
70
71
  "VERSION" => version,
71
72
  "REQUEST" => request,
72
- "typeName" => type_name,
73
+ "typeNames" => type_name,
73
74
  "propertyName" => property_name,
74
75
  "SRSName" => srs_name,
75
- "Filter" => filter
76
+ "cql_filter" => filter,
77
+ "outputformat" => "json"
76
78
  }.map { |k, v| "#{k}=#{v}" }.join("&")
77
79
  end
78
80
 
@@ -98,7 +100,7 @@ module DefraRuby
98
100
  # suppport multiple versions hence you need to state the version in the
99
101
  # request.
100
102
  def version
101
- "1.0.0"
103
+ "2.0.0"
102
104
  end
103
105
 
104
106
  # Used to tell the WFS what kind of request you are making. In the case
@@ -157,40 +159,15 @@ module DefraRuby
157
159
  # WFS's use filters in GetFeature requests to return data that only
158
160
  # matches a certain criteria.
159
161
  #
160
- # https://docs.geoserver.org/latest/en/user/filter/function.html
161
- #
162
- # There are various formats you can use for doing those, though it will be
163
- # dependent on what the WFS supports. In our case we use XML-based Filter
164
- # Encoding language because
162
+ # https://docs.geoserver.org/latest/en/user/tutorials/cql/cql_tutorial.html
165
163
  #
166
- # * this was how the team that manage the WFS have always provided their
167
- # examples
168
- # * we know this format is supported by the WFS's we are interacting with
169
- #
170
- # The others are CQL and ECQL. https://docs.geoserver.org/latest/en/user/tutorials/cql/cql_tutorial.html
171
164
  #
172
165
  # Our filter is looking for the result where our coordinates intersect
173
- # with the feature property +SHAPE+, with +SHAPE+ being a
174
- # +MultiPolygonPropertyType+.
166
+ # with the bounding box
175
167
  #
176
- # http://xml.fmi.fi/namespace/meteorology/conceptual-model/meteorological-objects/2009/04/28/docindex647.html
168
+ # https://docs.geoserver.org/latest/en/user/tutorials/cql/cql_tutorial.html#geometric-filters
177
169
  def filter
178
- # The filter is done in this way purely for readability. It could just
179
- # as easily been a one line string statement, but we think this is
180
- # better.
181
- filter = <<-XML
182
- (
183
- <ogc:Filter>
184
- <ogc:Intersects>
185
- <ogc:PropertyName>SHAPE</ogc:PropertyName>
186
- <gml:Point>
187
- <gml:coordinates>#{easting},#{northing}</gml:coordinates>
188
- </gml:Point>
189
- </ogc:Intersects>
190
- </ogc:Filter>
191
- )
192
- XML
193
- filter.strip.squeeze(" ").gsub(/\s+/, "")
170
+ "bbox(shape,#{easting},#{northing},#{easting},#{northing})"
194
171
  end
195
172
 
196
173
  def implemented_in_subclass
@@ -2,6 +2,6 @@
2
2
 
3
3
  module DefraRuby
4
4
  module Area
5
- VERSION = "2.1.0"
5
+ VERSION = "2.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defra_ruby_area
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Defra
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-24 00:00:00.000000000 Z
11
+ date: 2023-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -67,7 +67,7 @@ licenses:
67
67
  metadata:
68
68
  rubygems_mfa_required: 'true'
69
69
  allowed_push_host: https://rubygems.org
70
- post_install_message:
70
+ post_install_message:
71
71
  rdoc_options: []
72
72
  require_paths:
73
73
  - lib
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  version: '0'
84
84
  requirements: []
85
85
  rubygems_version: 3.4.10
86
- signing_key:
86
+ signing_key:
87
87
  specification_version: 4
88
88
  summary: Defra ruby on rails EA administrative area lookup
89
89
  test_files: []