defra_ruby_area 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []