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
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 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: