cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Adding new spatial points to (already imported) open street map data.

James8
Node Link

Hi,

We have a OSM data uploaded for San Diego. We also have housing data for which we've found longitudes and latitudes and have uploaded as nodes with corresponding spatial points.

How would one join this housing data with the OSM? I spent a while on Google trying to figure this out, but couldn't find much. It seems that you have your housing (label) node for each specific house and that you should be able to essentially create something akin to a point of interest with each house which will join to the map through an edge and a node, where it will join to the nearest edge (road) given the house's spatial coordinates. I'm not sure how to do this.

Here is script used for OSM import:

UNWIND $rows AS row
CREATE (p:PointOfInterest {name: row.names.local})
CREATE (g:Geometry)
SET g.location = point({latitude: toFloat(row.point[1]), longitude: toFloat(row.point[0]) })
CREATE (g)<-[:HAS_GEOMETRY]-(p)
SET g:Point
CREATE (t:Tags)
SET t += row.original_tags_dict
CREATE (p)-[:HAS_TAGS]->(t)
WITH *
CALL apoc.create.addLabels(p, [row.class, row.subclass]) YIELD node
RETURN COUNT(*) AS total

2 REPLIES 2

William_Lyon
Graph Fellow

Are you thinking about importing the San Diego road network as well? That would allow you to model intersections and road segments in the graph. You could then identify the closest intersection to each point of interest or house/address, which would give you a fully connected graph. I've been playing around with data from Open Addresses for this. Here's the data model I'm using:

 

Point of interests, addresses, and road network data modelPoint of interests, addresses, and road network data model

After adding point of interest and address nodes, I looked for the closest intersection node to each point of interest and address node like this:

MATCH (p:Address) WHERE NOT EXISTS ((p)-[:NEAREST_INTERSECTION]->(:Intersection))
WITH p LIMIT 100000
CALL {
  WITH p
  MATCH (i:Intersection)
  USING INDEX i:Intersection(location)
  WHERE point.distance(i.location, p.location) < 2000

  WITH i
  ORDER BY point.distance(p.location, i.location) ASC 
  LIMIT 1
  RETURN i
}
WITH p, i

MERGE (p)-[r:NEAREST_INTERSECTION]->(i)
SET r.length = point.distance(p.location, i.location)
RETURN COUNT(p)

Then for routing between addresses/pois:

 

MATCH (a:Address)-[:NEAREST_INTERSECTION]->(source:Intersection)
WHERE a.full_address CONTAINS "410 E 5TH AVE SAN MATEO, CA"
MATCH 
  (poi:PointOfInterest)-[:NEAREST_INTERSECTION]->(dest:Intersection) 
WHERE poi.geometry_id = "w914450392@1"
CALL apoc.algo.dijkstra(source, dest, "ROAD_SEGMENT", "length") 
YIELD weight, path
WITH [ x in nodes(path) | {latitude: x.location.latitude, longitude: x.location.longitude}] AS route, weight AS totalDist
RETURN *

Perhaps a similar approach might be useful? The code is currently split between these two GitHub repos:

https://github.com/johnymontana/geospatial-graph-demos - Some examples of spatial search and routing with OSM data

https://github.com/johnymontana/neo4j-osmnx-experiments - Importing OSM and OpenAddresses data into Neo4j 

William_Lyon
Graph Fellow

Are you planning to add the road network from OpenStreetMap as well? I've been playing around with this recently. Here's the data model I'm using (includes both points of interest and addresses from Open Addresses)

data_model_addresses.png

 

The road network models intersections, so for a fully connected graph I wanted to find the closest intersection for each point of interest or address:

MATCH (p:Address) WHERE NOT EXISTS ((p)-[:NEAREST_INTERSECTION]->(:Intersection))
WITH p LIMIT 100000
CALL {
  WITH p
  MATCH (i:Intersection)
  USING INDEX i:Intersection(location)
  WHERE point.distance(i.location, p.location) < 2000

  WITH i
  ORDER BY point.distance(p.location, i.location) ASC 
  LIMIT 1
  RETURN i
}
WITH p, i

MERGE (p)-[r:NEAREST_INTERSECTION]->(i)
SET r.length = point.distance(p.location, i.location)
RETURN COUNT(p)

Then, we can route between and point of address or address like this:

MATCH (a:Address)-[:NEAREST_INTERSECTION]->(source:Intersection)
WHERE a.full_address CONTAINS "410 E 5TH AVE SAN MATEO, CA"
MATCH 
  (poi:PointOfInterest)-[:NEAREST_INTERSECTION]->(dest:Intersection) 
WHERE poi.geometry_id = "w914450392@1"
CALL apoc.algo.dijkstra(source, dest, "ROAD_SEGMENT", "length") 
YIELD weight, path
WITH [ x in nodes(path) | {latitude: x.location.latitude, longitude: x.location.longitude}] AS route, weight AS totalDist
RETURN *

The code is currently split across two repos:

https://github.com/johnymontana/geospatial-graph-demos

https://github.com/johnymontana/neo4j-osmnx-experiments