Skip to content

Commit

Permalink
most of the way there, but cypher still failing :(
Browse files Browse the repository at this point in the history
  • Loading branch information
maxdemarzi committed Jan 25, 2014
1 parent 02cca20 commit 0465e80
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 1 deletion.
32 changes: 32 additions & 0 deletions lib/neography/rest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,38 @@ def add_point_layer(layer, lat = nil, lon = nil)
@spatial.add_point_layer(layer, lat, lon)
end

def add_editable_layer(layer, format, node_property_name)
@spatial.add_editable_layer(layer, format, node_property_name)
end

def get_layer(layer)
@spatial.get_layer(layer)
end

def add_geometry_to_layer(layer, geometry)
@spatial.add_geometry_to_layer(layer, geometry)
end

def edit_geometry_from_layer(layer, geometry, node)
@spatial.edit_geometry_from_layer(layer, geometry, node)
end

def add_node_to_layer(layer, node)
@spatial.add_node_to_layer(layer, node)
end

def find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
@spatial.find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
end

def find_geometries_within_distance(layer, pointx, pointy, distance)
@spatial.find_geometries_within_distance(layer, pointx, pointy, distance)
end

def create_spatial_index(name, type = nil, lat = nil, lon = nil)
@spatial.create_spatial_index(name, type, lat, lon)
end

# clean database

# For testing (use a separate neo4j instance)
Expand Down
89 changes: 88 additions & 1 deletion lib/neography/rest/spatial.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Spatial
add_path :add_node_to_layer, "/ext/SpatialPlugin/graphdb/addNodeToLayer"
add_path :find_geometries_in_bbox, "/ext/SpatialPlugin/graphdb/findGeometriesInBBox"
add_path :find_geometries_within_distance,"/ext/SpatialPlugin/graphdb/findGeometriesWithinDistance"
add_path :create_index, "/index/node"

def initialize(connection)
@connection = connection
Expand All @@ -38,7 +39,7 @@ def add_point_layer(layer, lat, lon)
def add_editable_layer(layer, format = "WKT", node_property_name = "wkt")
options = {
:body => {
:layer => name,
:layer => layer,
:format => format,
:nodePropertyName => node_property_name
}.to_json,
Expand All @@ -48,6 +49,92 @@ def add_editable_layer(layer, format = "WKT", node_property_name = "wkt")
@connection.post(add_editable_layer_path, options)
end

def get_layer(layer)
options = {
:body => {
:layer => layer
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(get_layer_path, options)
end

def add_geometry_to_layer(layer, geometry)
options = {
:body => {
:layer => layer,
:geometry => geometry
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(add_geometry_to_layer_path, options)
end

def edit_geometry_from_layer(layer, geometry, node)
options = {
:body => {
:layer => layer,
:geometry => geometry,
:geometryNodeId => get_id(node)
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(edit_geometry_from_layer_path, options)
end

def add_node_to_layer(layer, node)
options = {
:body => {
:layer => layer,
:node => get_id(node)
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(add_node_to_layer_path, options)
end

def find_geometries_in_bbox(layer, minx, maxx, miny, maxy)
options = {
:body => {
:layer => layer,
:minx => minx,
:maxx => maxx,
:miny => miny,
:maxy => maxy
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(find_geometries_in_bbox_path, options)
end

def find_geometries_within_distance(layer, pointx, pointy, distance)
options = {
:body => {
:layer => layer,
:pointX => pointx,
:pointY => pointy,
:distanceInKm => distance
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(find_geometries_within_distance_path, options)
end

def create_spatial_index(name, type, lat, lon)
options = {
:body => {
:name => name,
:config => {
:provider => "spatial",
:geometry_type => type || "point",
:lat => lat || "lat",
:lon => lon || "lon"
}
}.to_json,
:headers => json_content_type.merge({'Accept' => 'application/json;charset=UTF-8'})
}
@connection.post(create_index_path, options)
end

end
end
Expand Down
135 changes: 135 additions & 0 deletions spec/integration/rest_spatial_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,142 @@
pl.first["data"]["layer"].should == "coffee_shops"
pl.first["data"]["geomencoder_config"].should == "longitude:latitude"
end
end

describe "add an editable layer" do
it "can add an editable layer" do
el = @neo.add_editable_layer("zipcodes", "WKT", "wkt")
el.should_not be_nil
el.first["data"]["layer"].should == "zipcodes"
el.first["data"]["geomencoder_config"].should == "wkt"
end
end

describe "get a spatial layer" do
it "can get a layer" do
sl = @neo.get_layer("restaurants")
sl.should_not be_nil
sl.first["data"]["layer"].should == "restaurants"
end
end

describe "create a spatial index" do
it "can create a spatial index" do
index = @neo.create_spatial_index("restaurants")
index["provider"].should == "spatial"
index["geometry_type"].should == "point"
index["lat"].should == "lat"
index["lon"].should == "lon"
end
end

describe "add geometry to spatial layer" do
it "can add a geometry" do
geometry = "LINESTRING (15.2 60.1, 15.3 60.1)"
geo = @neo.add_geometry_to_layer("zipcodes", geometry)
geo.should_not be_nil
geo.first["data"]["wkt"].should == geometry
end
end

describe "update geometry from spatial layer" do
it "can update a geometry" do
geometry = "LINESTRING (15.2 60.1, 15.3 60.1)"
geo = @neo.add_geometry_to_layer("zipcodes", geometry)
geo.should_not be_nil
geo.first["data"]["wkt"].should == geometry
geometry = "LINESTRING (14.7 60.1, 15.3 60.1)"
existing_geo = @neo.edit_geometry_from_layer("zipcodes", geometry, geo)
existing_geo.first["data"]["wkt"].should == geometry
existing_geo.first["self"].split('/').last.to_i.should == geo.first["self"].split('/').last.to_i
end
end

describe "add a node to a layer" do
it "can add a node to a simple point layer" do
properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
node = @neo.create_node(properties)
node.should_not be_nil
added = @neo.add_node_to_layer("restaurants", node)
added.first["data"]["lat"].should == properties[:lat]
added.first["data"]["lon"].should == properties[:lon]

added = @neo.add_node_to_index("restaurants", "dummy", "dummy", node)
added["data"]["lat"].should == properties[:lat]
added["data"]["lon"].should == properties[:lon]
end
end

describe "find geometries in a bounding box" do
it "can find a geometry in a bounding box" do
properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
node = @neo.find_geometries_in_bbox("restaurants", 87.5, 87.7, 41.7, 41.9)
node.should_not be_empty
node.first["data"]["lat"].should == properties[:lat]
node.first["data"]["lon"].should == properties[:lon]
node.first["data"]["name"].should == "Max's Restaurant"
end

it "can find a geometry in a bounding box using cypher" do
node = @neo.execute_query("start n = node:restaurants({bbox}) return n", {:bbox => "bbox:[87.5,87.7,41.7,41.9]"})
#node = @neo.execute_query("start n = node:restaurants({bbox}) return n", {:bbox => "bbox:[87.6278,41.8819,87.6278,41.8819]"})
node.should_not be_empty
puts node.inspect
node.first["data"]["lat"].should == properties[:lat]
node.first["data"]["lon"].should == properties[:lon]
node.first["data"]["name"].should == "Max's Restaurant"
end
end

describe "find geometries within distance" do
it "can find a geometry within distance" do
properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
node = @neo.find_geometries_within_distance("restaurants", 87.627, 41.881, 10)
node.should_not be_empty
node.first["data"]["lat"].should == properties[:lat]
node.first["data"]["lon"].should == properties[:lon]
node.first["data"]["name"].should == "Max's Restaurant"
end

it "can find a geometry within distance using cypher" do
properties = {:name => "Max's Restaurant", :lat => 41.8819, :lon => 87.6278}
node = @neo.execute_query("start n = node:restaurants({bbox}) return n", {:bbox => "withinDistance:[87.6278,41.8819,10.0]"})
node.should_not be_empty
puts node.inspect
node.first["data"]["lat"].should == properties[:lat]
node.first["data"]["lon"].should == properties[:lon]
node.first["data"]["name"].should == "Max's Restaurant"
end
end

describe "complete example" do
it "can do what the manual does" do
@neo.add_point_layer("geom", "lat", "lon")
node = @neo.create_node({:lat => 60.1, :lon => 15.2})
@neo.create_spatial_index("geom", "point", "lat", "lon")
@neo.add_node_to_layer("geom", node)

existing_node = @neo.find_geometries_in_bbox("geom", 15.0,15.3,60.0,60.3)
existing_node.first["data"]["lat"].should == 60.1
existing_node.first["data"]["lon"].should == 15.2

existing_node = @neo.find_geometries_within_distance("geom", 15.0, 60.0, 100.0)
existing_node.first["data"]["lat"].should == 60.1
existing_node.first["data"]["lon"].should == 15.2

added = @neo.add_node_to_index("geom", "dummy", "dummy", node)
existing_node = @neo.execute_query("start node = node:geom(\'bbox:[15.0,15.3,60.0,60.2]\') return node")
puts existing_node.inspect
existing_node.first["data"]["lat"].should == 60.1
existing_node.first["data"]["lon"].should == 15.2

existing_node = @neo.execute_query("start node = node:geom(\'withinDistance:[60.0,15.0, 100.0]\') return node")
puts existing_node.inspect
existing_node.first["data"]["lat"].should == 60.1
existing_node.first["data"]["lon"].should == 15.2

end
end


end

0 comments on commit 0465e80

Please sign in to comment.