Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Neo4j Spatial: Indexing Football Stadiums Using the REST API

DZone's Guide to

Neo4j Spatial: Indexing Football Stadiums Using the REST API

· Cloud Zone
Free Resource

Learn how our document data model can map directly to how you program your app, and native database features like secondary indexes, geospatial and text search give you full access to your data. Brought to you in partnership with MongoDB.

Late last week my colleague Peter wrote up some documentation about creating spatial indexes in neo4j via HTTP, something I hadn’t realised was possible until then.

I previously wrote about indexing football stadiums using neo4j spatial but the annoying thing about the approach I described was that I was using neo4j in embedded mode which restricts you to using a JVM language.

The rest of my code is in Ruby so I thought I’d translate that code.

To recap, I’m parsing a CSV file of football stadiums that I downloaded from Chris Bell’s blog which looks like this:

Name,Team,Capacity,Latitude,Longitude
"Adams Park","Wycombe Wanderers",10284,51.6306,-0.800299
"Almondvale Stadium","Livingston",10122,55.8864,-3.52207
"Amex Stadium","Brighton and Hove Albion",22374,50.8609,-0.08014

The code to process the file and index the stadiums in neo4j is as follows (and is essentially a translation of the find_geometries_within_distance_using_cypher test):

require 'csv'
require 'httparty'
require 'json'
 
HTTParty.post("http://localhost:7474/db/data/ext/SpatialPlugin/graphdb/addSimplePointLayer", 
  :body => { :layer => 'geom', :lat => 'lat', :lon => 'lon' }.to_json,
  :headers => { 'Content-Type' => 'application/json' } )
 
HTTParty.post("http://localhost:7474/db/data/index/node", 		
  :body => { :name => 'geom', :config => { :provider => 'spatial', :geometry_type => 'point', :lat => 'lat', :lon => 'lon'  } }.to_json,
  :headers => { 'Content-Type' => 'application/json' } )
 
contents = CSV.read(File.join(File.dirname(__FILE__), 'data', 'stadiums.csv'))
contents.shift
contents.each do |row|
  name, team, capacity, lat, long = row
 
  node_id = HTTParty.post("http://localhost:7474/db/data/node", 		
    :body => { :lat => lat.to_f, :lon => long.to_f, :name => name, :team => team, :capacity => capacity }.to_json,
    :headers => { 'Content-Type' => 'application/json' } )['self'].split("/")[-1]
 
  HTTParty.post("http://localhost:7474/db/data/index/node/geom", 		
    :body => { :key => 'dummy', :value => 'dummy', :uri => "http://localhost:7474/db/data/node/#{node_id}"}.to_json,
    :headers => { 'Content-Type' => 'application/json' } )
end

One change from the previous version is that I’m not indexing the stadiums using point based geometry rather than wkt.

If we want to find the number of stadiums within 10 km of Centre Point in London we’d write the following query:

START node = node:geom('withinDistance:[51.521348,-0.128113, 10.0]') 
RETURN node.name, node.team;
==> +--------------------------------------------+
==> | node.name          | node.team             |
==> +--------------------------------------------+
==> | "Emirates Stadium" | "Arsenal"             |
==> | "Stamford Bridge"  | "Chelsea"             |
==> | "The Den"          | "Millwall"            |
==> | "Loftus Road"      | "Queens Park Rangers" |
==> | "Craven Cottage"   | "Fulham"              |
==> | "Brisbane Road"    | "Leyton Orient"       |
==> +--------------------------------------------+
==> 6 rows







Discover when your data grows or your application performance demands increase, MongoDB Atlas allows you to scale out your deployment with an automated sharding process that ensures zero application downtime. Brought to you in partnership with MongoDB.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}