arcserver.rb 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +12 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.lock +274 -0
  6. data/LICENSE +20 -20
  7. data/README.md +160 -0
  8. data/Rakefile +9 -62
  9. data/arcserver.rb.gemspec +35 -0
  10. data/lib/arcserver.rb +33 -7
  11. data/lib/arcserver/Identifiable.rb +10 -0
  12. data/lib/arcserver/Queryable.rb +10 -0
  13. data/lib/arcserver/feature_server.rb +19 -0
  14. data/lib/arcserver/geometry/geometry.rb +91 -0
  15. data/lib/arcserver/geometry_service.rb +18 -0
  16. data/lib/arcserver/gp_server.rb +20 -0
  17. data/lib/arcserver/graphics/feature.rb +23 -0
  18. data/lib/arcserver/graphics/feature_set.rb +26 -0
  19. data/lib/arcserver/map_server.rb +34 -40
  20. data/lib/arcserver/rest/feature_server.rb +30 -0
  21. data/lib/arcserver/rest/geometry_service.rb +54 -0
  22. data/lib/arcserver/rest/gp_server.rb +80 -0
  23. data/lib/arcserver/rest/identify.rb +66 -0
  24. data/lib/arcserver/rest/map_server.rb +230 -230
  25. data/lib/arcserver/rest/query.rb +68 -0
  26. data/lib/arcserver/url_helper.rb +31 -25
  27. data/lib/arcserver/util/legend_image.rb +0 -0
  28. data/lib/arcserver/version.rb +6 -6
  29. data/spec/custom_spec.rb +50 -0
  30. data/spec/factories/feature.rb +21 -0
  31. data/spec/feature_server_spec.rb +52 -0
  32. data/spec/feature_spec.rb +20 -0
  33. data/spec/geometry_service_spec.rb +31 -0
  34. data/spec/geometry_spec.rb +80 -0
  35. data/spec/gp_server_spec.rb +57 -0
  36. data/spec/identify_spec.rb +21 -0
  37. data/spec/query_spec.rb +38 -0
  38. data/spec/shared_context.rb +17 -0
  39. data/spec/spec_helper.rb +15 -0
  40. metadata +217 -158
  41. data/README.rdoc +0 -57
  42. data/lib/arcserver/soap/map_server.rb +0 -263
  43. data/test/functional/soap/map_server_test.rb +0 -193
  44. data/test/test_helper.rb +0 -25
  45. data/test/unit/map_server_test.rb +0 -61
  46. data/test/unit/url_helper_test.rb +0 -54
  47. data/test/unit/util/legend_image_test.rb +0 -69
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ module ArcServer
4
+ module REST
5
+ class Query
6
+
7
+ include HTTParty
8
+ format :json
9
+ # debug_output $stdout
10
+
11
+ def initialize(attr={})
12
+ defaults = {
13
+ where: "",
14
+ objectIds: "",
15
+ time: "",
16
+ geometry: nil,
17
+ geometryType: "esriGeometryEnvelope",
18
+ inSR: "",
19
+ spatialRel: "esriSpatialRelIntersects",
20
+ relationParam: "",
21
+ outFields: "*",
22
+ returnGeometry: true,
23
+ maxAllowableOffset: "",
24
+ geometryPrecision: "",
25
+ outSR: "",
26
+ gdbVersion: "",
27
+ returnIdsOnly: false,
28
+ returnCountOnly: false,
29
+ orderByFields: "",
30
+ groupByFieldsForStatistics: "",
31
+ outStatistics: "",
32
+ returnZ: false,
33
+ returnM: false,
34
+ f: "json"
35
+ }.merge(attr)
36
+ defaults.each { |k,v| instance_variable_set("@#{k}", v) }
37
+ end
38
+
39
+ def params
40
+ # sanitize_params
41
+ hash = Hash[instance_variables.map { |name| [name.to_s[1..-1].to_sym, instance_variable_get(name)] } ]
42
+ if hash[:geometry]
43
+ hash[:geometryType] = hash[:geometry].geometryType
44
+ hash[:geometry] = hash[:geometry].to_json
45
+ end
46
+ hash
47
+ end
48
+
49
+ # Utility method that sanitize che query parameters
50
+ # example:
51
+ # where clause want that single quotes are double
52
+ def sanitize_params
53
+ # @where[/\w*=\'(.*)\'/].gsub(/\'/, "''")
54
+ # @where.sub!(/\w*=\'(.*)\'/, { |s| puts s })
55
+ end
56
+
57
+ # Execute a query on a map layer
58
+ # You have to specify a layer avaible on the map server:
59
+ # http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/0
60
+ #
61
+ def execute(url)
62
+ response = self.class.get("#{url}/query", query: params)
63
+ Graphics::FeatureSet.new(response.with_indifferent_access)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -1,25 +1,31 @@
1
- # encoding: utf-8
2
-
3
- module ArcServer
4
- module UrlHelper
5
- def rest_service?(url)
6
- url.to_s.match(/ArcGIS\/rest\/.*/)
7
- end
8
-
9
- def soap_service?(url)
10
- url.to_s.match(/ArcGIS\/(?!rest\/).*/)
11
- end
12
-
13
- def map_server?(url)
14
- url.to_s.match(/\/MapServer$/)
15
- end
16
-
17
- def to_rest(url)
18
- rest_service?(url) ? url : url.sub('/ArcGIS/', '/ArcGIS/rest/')
19
- end
20
-
21
- def to_soap(url)
22
- soap_service?(url) ? url : url.sub('/ArcGIS/rest/', '/ArcGIS/')
23
- end
24
- end
25
- end
1
+ # encoding: utf-8
2
+
3
+ module ArcServer
4
+ module UrlHelper
5
+
6
+ def rest_service?(url)
7
+ url.to_s.match(/ArcGIS\/rest\/.*/)
8
+ end
9
+
10
+ def map_server?(url)
11
+ url.to_s.match(/\/MapServer$/)
12
+ end
13
+
14
+ def feature_server?(url)
15
+ url.to_s.match(/\/FeatureServer/)
16
+ end
17
+
18
+ def geometry_service?(url)
19
+ url.to_s.match(/\/GeometryServer$/)
20
+ end
21
+
22
+ def gp_server?(url)
23
+ url.to_s.match(/\/GPServer/)
24
+ end
25
+
26
+ def to_rest(url)
27
+ rest_service?(url) ? url : url.sub('/ArcGIS/', '/ArcGIS/rest/')
28
+ end
29
+
30
+ end
31
+ end
File without changes
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
2
- module ArcServer
3
- MAJOR = 0
4
- MINOR = 1
5
- PATCH = 4
6
- VERSION = [MAJOR, MINOR, PATCH].join('.')
1
+ # encoding: utf-8
2
+ module ArcServer
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 5
6
+ VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Custom Specs' do
6
+
7
+ it "should query with a point", broken: true do
8
+
9
+ map = ArcServer::MapServer.new("http://srvgists006.lugano.ch:6080/arcgis/rest/services/Territorio/OggettiLugano/MapServer")
10
+ feature_set = map.query('0', { where: "ID_SCHEDA=7", outFields: "*" })
11
+
12
+ oggetto = feature_set.features[0] # la prima feature del featureSet
13
+
14
+ basemap = ArcServer::MapServer.new("http://srvgispr001.lugano.ch:8399/arcgis/rest/services/Base/BaseMap2Dyn/MapServer")
15
+ fs = basemap.query('3', { geometryType: feature_set.geometryType, geometry: oggetto.geometry, outFields: "*", inSR: 21781, returnGeometry: true })
16
+ particella = fs.features[0]
17
+
18
+ # pr = ArcServer::MapServer.new("http://srvgispr001.lugano.ch:8399/arcgis/rest/services/PR/PR3Dyn/MapServer")
19
+ # varianti = pr.query('0', { outFields: "TIPO", inSR: 21781, geometryType: fs.geometryType, geometry: particella.geometry, returnGeometry: false })
20
+
21
+ # varianti.features.each do |v|
22
+ # puts v.attributes['TIPO']
23
+ # end
24
+
25
+ map_server = ArcServer::MapServer.new("http://srvgispr001.lugano.ch:8399/arcgis/rest/services/PR/PR3Dyn/MapServer")
26
+ results = map_server.identify({ geometryType: fs.geometryType, geometry: particella.geometry, tolerance: "10", mapExtent: "713286.65,88660.024,727694.27,108826.21", imageDisplay: "400,300,96", returnGeometry: false })
27
+
28
+ results.each do |i|
29
+ puts i
30
+ # puts "Layer ID: #{i.layerId}"
31
+ # puts i.feature.attributes
32
+ end
33
+
34
+ # puts fs.features[0].geometry
35
+
36
+ fs_gp = ArcServer::Graphics::FeatureSet.new({ features: [ fs.features[0] ] })
37
+ # puts fs_gp.to_json
38
+
39
+ gp = ArcServer::GPServer.new("http://srvgispr001.lugano.ch:8399/arcgis/rest/services/GisWeb/GPServer/GWClip")
40
+ params = { Feature_Set: fs_gp.to_json }
41
+
42
+ gp.submitJob(params) do |results|
43
+ results["zone_clipped"].features.each do |f|
44
+ puts f.attributes['ZONA'] if f.attributes['Shape_Area'] > 1
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,21 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :feature, class:Hash do
4
+ initialize_with {
5
+ geometry: {
6
+ x: 997986.50,
7
+ y: 5783631.06,
8
+ spatialReference: { wkid: 102100 }
9
+ },
10
+ attributes: {
11
+ status: 1,
12
+ req_id: "12345",
13
+ req_type: "Graffiti Complaint – Private Property",
14
+ req_date: "30.09.2013",
15
+ req_time: "14:00",
16
+ address: "via dei matti 1",
17
+ district: "Lugano"
18
+ }
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'FeatureServer' do
6
+
7
+ include_context "shared stuff"
8
+
9
+ it 'adds feature to FeatureServer' do
10
+
11
+ fs = ArcServer::FeatureServer.new("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer")
12
+ f = ArcServer::Graphics::Feature.new({ geometry: ArcServer::Geometry::Point.new({ x: 997986.50, y: 5783631.06, spatialReference: { wkid: 102100 }}), attributes: {status:1,req_id:"12345",req_type:"Graffiti Complaint – Private Property",req_date:"30.09.2013",req_time:"14:00",address:"via dei matti 1",district:"Lugano"} })
13
+
14
+ results = fs.applyEdits('0', [ f ], [ ], [ ])
15
+ results.should have_key(:addResults)
16
+ results[:addResults].should have(1).item
17
+ results[:addResults].each do |r|
18
+ r.should have_key(:objectId)
19
+ r.should have_key(:success)
20
+ r[:success].should be true
21
+ end
22
+
23
+ end
24
+
25
+ it 'updates feature on FeatureServer' do
26
+
27
+ fs = ArcServer::FeatureServer.new("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer")
28
+ f = query_for_random_feature
29
+
30
+ f.attributes[:address] = "The Avengers Tower"
31
+
32
+ results = fs.applyEdits('0', [ ], [ f ], [ ])
33
+ results.should have_key(:updateResults)
34
+ results[:updateResults].each do |r|
35
+ r.should have_key(:objectId)
36
+ r.should have_key(:success)
37
+ r[:success].should be true
38
+ end
39
+ end
40
+
41
+ it 'deletes features' do
42
+
43
+ feature_server = ArcServer::FeatureServer.new("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer")
44
+ feature_set = feature_server.query('0', { where: 'status=1', outFields: "*", inSR: 102100, outSR: 102100 })
45
+
46
+ deletes = feature_set.features[1..3].map { |f| f.attributes[:objectid] }.join(',')
47
+ results = feature_server.applyEdits('0', [ ], [ ], deletes)
48
+ results.should have_key(:deleteResults)
49
+
50
+ end
51
+
52
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Feature Specs' do
6
+
7
+ it "create a feature from JSON" do
8
+ json = '{ "geometry" : { "x" : -118.15, "y" : 33.80 }, "attributes" : { "OWNER" : "Joe Smith", "VALUE" : 94820.37, "APPROVED" : true, "LASTUPDATE" : 1227663551096 } }'
9
+ feature = ArcServer::Graphics::Feature.create(json)
10
+
11
+ feature.should be_kind_of(ArcServer::Graphics::Feature)
12
+ feature.geometry.should be_kind_of(ArcServer::Geometry::Point)
13
+ feature.geometry.x.should eq -118.15
14
+ feature.geometry.y.should eq 33.80
15
+ feature.attributes.should have_key("OWNER")
16
+ feature.attributes.should have_key("VALUE")
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'GeometryService' do
6
+
7
+ include_context "shared stuff"
8
+
9
+ before(:each) do
10
+ @gs = ArcServer::GeometryService.new("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer")
11
+ end
12
+
13
+ it 'projects geometries' do
14
+ projection = @gs.project({ inSR: 102100, outSR: 4326, geometries: { geometryType: "esriGeometryPoint", geometries: [ { x: -8926559.814803278, y: 2974164.2260772274 } ] } })
15
+ projection.should have(1).item
16
+ projection[0].should be_kind_of(ArcServer::Geometry::Point)
17
+ projection[0].x.should eq -80.18865116244909
18
+ projection[0].y.should eq 25.79865037102925
19
+ end
20
+
21
+ it 'buffers geometries' do
22
+ buffer = @gs.buffer({ inSR: 4326, outSR: 4326, bufferSR: 102113, distances: 1000, geometries: { geometryType: "esriGeometryPoint", geometries: [ { x: -117, y: 34 } ] } })
23
+ buffer[0].should be_kind_of(ArcServer::Geometry::Polygon)
24
+ end
25
+
26
+ it 'buffers geometries with class' do
27
+ buffer = @gs.buffer({ inSR: 4326, outSR: 4326, bufferSR: 102113, distances: 1000, geometries: { geometryType: "esriGeometryPoint", geometries: [ ArcServer::Geometry::Point.new({ x: -117, y: 34 }) ] } })
28
+ buffer[0].should be_kind_of(ArcServer::Geometry::Polygon)
29
+ end
30
+
31
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Geometry' do
6
+
7
+ include_context "shared stuff"
8
+
9
+ it 'creates feature with Geometry class' do
10
+
11
+ fs = ArcServer::FeatureServer.new("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/SanFrancisco/311Incidents/FeatureServer")
12
+ f = query_for_random_feature
13
+ f.geometry.should be_kind_of(ArcServer::Geometry::Point)
14
+
15
+ g = f.geometry
16
+ g.should respond_to(:extent)
17
+ g.should respond_to(:x)
18
+ g.should respond_to(:y)
19
+
20
+ end
21
+
22
+ it 'parse Point Geometry as JSON' do
23
+ json_geometry = '{"x" : -118.15, "y" : 33.80}'
24
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
25
+ geometry.should be_kind_of(ArcServer::Geometry::Point)
26
+
27
+ json_geometry = '{ "x" : -118.15, "y" : 33.80, "spatialReference" : {"wkid" : 4326} }'
28
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
29
+ geometry.should be_kind_of(ArcServer::Geometry::Point)
30
+
31
+ end
32
+
33
+ it 'parse Polyline Geometry as JSON' do
34
+ json_geometry = '{ "paths" : [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], [ [-97.06326,32.759], [-97.06298,32.755] ] ],"spatialReference" : {"wkid" : 4326 } }'
35
+
36
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
37
+ geometry.should be_kind_of(ArcServer::Geometry::Polyline)
38
+ end
39
+
40
+ it 'parse Polygon Geometry as JSON' do
41
+ json_geometry = '{ "rings" : [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], [ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ] ], "spatialReference" : {"wkid" : 4326} }'
42
+
43
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
44
+ geometry.should be_kind_of(ArcServer::Geometry::Polygon)
45
+ end
46
+
47
+ it 'parse Multipoint Geometry as JSON' do
48
+ json_geometry = '{ "points" : [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], "spatialReference" : {"wkid" : 4326}}'
49
+
50
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
51
+ geometry.should be_kind_of(ArcServer::Geometry::Multipoint)
52
+ end
53
+
54
+ it 'parse Envelope Geometry as JSON' do
55
+ json_geometry = '{ "xmin" : -109.55, "ymin" : 25.76, "xmax" : -86.39, "ymax" : 49.94, "spatialReference" : {"wkid" : 4326} }'
56
+
57
+ geometry = ArcServer::Geometry::Geometry.create json_geometry
58
+ geometry.should be_kind_of(ArcServer::Geometry::Envelope)
59
+ end
60
+
61
+ it "calculates the right extent" do
62
+
63
+ basemap = ArcServer::MapServer.new("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer")
64
+ fs = basemap.query('3', { where: "FEMALES>1", outFields: "*", returnGeometry: true })
65
+ feature = fs.features[0]
66
+ feature.geometry.should be_kind_of(ArcServer::Geometry::Polygon)
67
+ feature.geometry.extent.should have(4).item
68
+
69
+ end
70
+
71
+ it "don't explode without a geometry" do
72
+
73
+ basemap = ArcServer::MapServer.new("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer")
74
+ fs = basemap.query('3', { where: "FEMALES>1", outFields: "*", returnGeometry: false })
75
+ feature = fs.features[0]
76
+ feature.geometry.should be nil
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'GPServer' do
6
+
7
+ context 'when the GP is synchronous' do
8
+ it "sends a message in a bottle" do
9
+
10
+ gp = ArcServer::GPServer.new("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_Currents_World/GPServer/MessageInABottle")
11
+ feature = ArcServer::Graphics::Feature.new({ geometry: ArcServer::Geometry::Point.new({ x: -76.2890625, y: 35.859375, spatialReference: { wkid: 4326 } }) })
12
+ feature_set = ArcServer::Graphics::FeatureSet.new({ features: [ feature ] })
13
+
14
+ params = { Input_Point: feature_set.to_json, Days: 180 }
15
+ results = gp.execute(params)
16
+
17
+ results.should_not be nil
18
+ results.should have_at_least(1).items
19
+ results[0].should have_key 'paramName'
20
+ results[0].should have_key 'value'
21
+
22
+ end
23
+
24
+ it "executes export Web Map Task" do
25
+ gp = ArcServer::GPServer.new("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task")
26
+
27
+ webmap = '{"mapOptions":{"showAttribution":true,"extent":{"xmin":-9653813.186180541,"ymin":4553927.749172574,"xmax":-9427865.330569474,"ymax":4689068.415180817,"spatialReference":{"wkid":102100}},"spatialReference":{"wkid":102100},"scale":577790.5542889992},"operationalLayers":[{"id":"Ocean_Basemap_5301","title":"Ocean_Basemap_5301","opacity":1,"minScale":591657527.591555,"maxScale":9027.977411,"url":"http://services.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer"},{"id":"LOJIC_LandRecords_Louisville_3326","title":"LOJIC_LandRecords_Louisville_3326","opacity":0.24,"minScale":0,"maxScale":0,"url":"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/MapServer","visibleLayers":[0,2],"layers":[]},{"id":"map_graphics","minScale":0,"maxScale":0,"featureCollection":{"layers":[]}}],"exportOptions":{"outputSize":[800,1100],"dpi":96},"layoutOptions":{"titleText":"Louisville – Land Records, Portrait JPG","scaleBarOptions":{},"legendOptions":{"operationalLayers":[]}}}'
28
+
29
+ params = { Web_Map_as_JSON: webmap, Format: 'JPG', Layout_Template: 'MAP_ONLY' }
30
+ results = gp.execute(params)
31
+ results.should have_at_least(1).items
32
+ results[0].should have_key('paramName')
33
+ results[0]['value'].should have_key("url")
34
+ results[0]['value']['url'].should match /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6}):?(\d{1,6})*([\/\w \.-]*)*\/?$/
35
+ end
36
+
37
+ end
38
+
39
+ context 'when the GP is aynchronous' do
40
+
41
+ it "executes a Geo Processing Tool" do
42
+
43
+ gp = ArcServer::GPServer.new("http://sampleserver6.arcgisonline.com/arcgis/rest/services/911CallsHotspot/GPServer/911%20Calls%20Hotspot")
44
+ q = "(Date >= date '1998-01-01 12:00:00' and Date <= date '1998-01-07 12:00:00') AND (Day = 'SUN' OR Day= 'SAT' OR Day = 'FRI' OR Day ='MON' OR Day='TUE' OR Day='WED' OR Day ='THU')"
45
+ params = { Query: q }
46
+
47
+ gp.submitJob(params) do |results|
48
+ results.should have_key('Output_Features')
49
+ results.should have_key('Hotspot_Raster')
50
+ results['Hotspot_Raster'].should have_key('mapImage')
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end