-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Funders scraped and committed via a GitHub Action.
- Loading branch information
1 parent
a6b2138
commit cea81fa
Showing
17 changed files
with
129 additions
and
5 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
-170 Bytes
(99%)
content/community-blogs/analyzing-mobility-hotspots-with-movingpandas-carto.
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
content/community-blogs/bringing-qgis-maps-into-jupyter-notebooks.
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
-15 Bytes
(100%)
...exploring-a-hierarchical-graph-based-model-for-mobility-data-representation-and-analysis.
Binary file not shown.
Binary file modified
BIN
+47 Bytes
(100%)
content/community-blogs/mapping-neo4j-spatial-nodes-with-geopandas.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file added
BIN
+28.7 KB
content/community-blogs/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas.
Binary file not shown.
124 changes: 124 additions & 0 deletions
124
...unity-blogs/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
--- | ||
source: "blog" | ||
title: "anitagraser.com: Mapping relationships between Neo4j spatial nodes with GeoPandas" | ||
image: "mapping-relationships-between-neo4j-spatial-nodes-with-geopandas." | ||
date: "2023-12-09" | ||
link: "https://anitagraser.com/2023/12/09/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas/" | ||
draft: "true" | ||
showcase: "planet" | ||
--- | ||
|
||
<p>Previously, <a href="https://anitagraser.com/2023/12/03/mapping-neo4j-spatial-nodes-with-geopandas/">we mapped neo4j spatial nodes</a>. This time, we want to take it one step further and map relationships. </p> | ||
|
||
|
||
|
||
<p>A prime example, are the relationships between GTFS StopTime and Trip nodes. For example, this is the Cypher query to get all StopTime nodes of Trip 17:</p> | ||
|
||
|
||
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate"> | ||
MATCH | ||
(t:Trip {id: "17"}) | ||
<-[:BELONGS_TO]- | ||
(st:StopTime) | ||
RETURN st | ||
</pre></div> | ||
|
||
|
||
<figure class="wp-block-image size-large"><a href="https://underdark.files.wordpress.com/2023/12/image-5.png"><img width="1024" height="544" data-attachment-id="8684" data-permalink="https://anitagraser.com/2023/12/09/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas/image-5-8/" data-orig-file="https://underdark.files.wordpress.com/2023/12/image-5.png" data-orig-size="1214,645" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-5" data-image-description="" data-image-caption="" data-medium-file="https://underdark.files.wordpress.com/2023/12/image-5.png?w=300" data-large-file="https://underdark.files.wordpress.com/2023/12/image-5.png?w=545" src="https://underdark.files.wordpress.com/2023/12/image-5.png?w=1024" alt="" class="wp-image-8684" srcset="https://underdark.files.wordpress.com/2023/12/image-5.png?w=1024 1024w, https://underdark.files.wordpress.com/2023/12/image-5.png?w=150 150w, https://underdark.files.wordpress.com/2023/12/image-5.png?w=300 300w, https://underdark.files.wordpress.com/2023/12/image-5.png?w=768 768w, https://underdark.files.wordpress.com/2023/12/image-5.png 1214w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure> | ||
|
||
|
||
|
||
<p>To get the stop locations, we also need to get the stop nodes:</p> | ||
|
||
|
||
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: sql; title: ; notranslate"> | ||
MATCH | ||
(t:Trip {id: "17"}) | ||
<-[:BELONGS_TO]- | ||
(st:StopTime) | ||
-[:STOPS_AT]-> | ||
(s:Stop) | ||
RETURN st ,s | ||
</pre></div> | ||
|
||
|
||
<figure class="wp-block-image size-large"><a href="https://underdark.files.wordpress.com/2023/12/image-6.png"><img width="895" height="566" data-attachment-id="8687" data-permalink="https://anitagraser.com/2023/12/09/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas/image-6-8/" data-orig-file="https://underdark.files.wordpress.com/2023/12/image-6.png" data-orig-size="895,566" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-6" data-image-description="" data-image-caption="" data-medium-file="https://underdark.files.wordpress.com/2023/12/image-6.png?w=300" data-large-file="https://underdark.files.wordpress.com/2023/12/image-6.png?w=545" src="https://underdark.files.wordpress.com/2023/12/image-6.png?w=895" alt="" class="wp-image-8687" srcset="https://underdark.files.wordpress.com/2023/12/image-6.png 895w, https://underdark.files.wordpress.com/2023/12/image-6.png?w=150 150w, https://underdark.files.wordpress.com/2023/12/image-6.png?w=300 300w, https://underdark.files.wordpress.com/2023/12/image-6.png?w=768 768w" sizes="(max-width: 895px) 100vw, 895px" /></a></figure> | ||
|
||
|
||
|
||
<p>Adapting our code from the previous post, we can plot the stops: </p> | ||
|
||
|
||
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate"> | ||
from shapely.geometry import Point | ||
|
||
QUERY = """MATCH ( | ||
t:Trip {id: "17"}) | ||
<-[:BELONGS_TO]- | ||
(st:StopTime) | ||
-[:STOPS_AT]-> | ||
(s:Stop) | ||
RETURN st ,s | ||
ORDER BY st.stopSequence | ||
""" | ||
|
||
with driver.session(database="neo4j") as session: | ||
tx = session.begin_transaction() | ||
results = tx.run(QUERY) | ||
df = results.to_df(expand=True) | ||
gdf = gpd.GeoDataFrame( | ||
df[['s().prop.name']], crs=4326, | ||
geometry=df["s().prop.location"].apply(Point) | ||
) | ||
|
||
tx.close() | ||
m = gdf.explore() | ||
m | ||
</pre></div> | ||
|
||
|
||
<figure class="wp-block-image size-large"><a href="https://underdark.files.wordpress.com/2023/12/image-10.png"><img width="527" height="879" data-attachment-id="8696" data-permalink="https://anitagraser.com/2023/12/09/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas/image-10-6/" data-orig-file="https://underdark.files.wordpress.com/2023/12/image-10.png" data-orig-size="527,879" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-10" data-image-description="" data-image-caption="" data-medium-file="https://underdark.files.wordpress.com/2023/12/image-10.png?w=180" data-large-file="https://underdark.files.wordpress.com/2023/12/image-10.png?w=527" src="https://underdark.files.wordpress.com/2023/12/image-10.png?w=527" alt="" class="wp-image-8696" srcset="https://underdark.files.wordpress.com/2023/12/image-10.png 527w, https://underdark.files.wordpress.com/2023/12/image-10.png?w=90 90w, https://underdark.files.wordpress.com/2023/12/image-10.png?w=180 180w" sizes="(max-width: 527px) 100vw, 527px" /></a></figure> | ||
|
||
|
||
|
||
<p>Ordering by stop sequence is actually completely optional. Technically, we could use the sorted GeoDataFrame, and aggregate all the points into a linestring to plot the route. But I want to try something different: we’ll use the NEXT_STOP relationships to get a DataFrame of the start and end stops for each segment: </p> | ||
|
||
|
||
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: python; title: ; notranslate"> | ||
QUERY = """ | ||
MATCH (t:Trip {id: "17"}) | ||
<-[:BELONGS_TO]- | ||
(st1:StopTime) | ||
-[:NEXT_STOP]-> | ||
(st2:StopTime) | ||
MATCH (st1)-[:STOPS_AT]->(s1:Stop) | ||
MATCH (st2)-[:STOPS_AT]->(s2:Stop) | ||
RETURN st1, st2, s1, s2 | ||
""" | ||
|
||
from shapely.geometry import Point, LineString | ||
|
||
def make_line(row): | ||
s1 = Point(row["s1().prop.location"]) | ||
s2 = Point(row["s2().prop.location"]) | ||
return LineString([s1,s2]) | ||
|
||
with driver.session(database="neo4j") as session: | ||
tx = session.begin_transaction() | ||
results = tx.run(QUERY) | ||
df = results.to_df(expand=True) | ||
gdf = gpd.GeoDataFrame( | ||
df[['s1().prop.name']], crs=4326, | ||
geometry=df.apply(make_line, axis=1) | ||
) | ||
|
||
tx.close() | ||
gdf.explore(m=m) | ||
</pre></div> | ||
|
||
|
||
<figure class="wp-block-image size-large"><a href="https://underdark.files.wordpress.com/2023/12/image-11.png"><img loading="lazy" width="527" height="975" data-attachment-id="8698" data-permalink="https://anitagraser.com/2023/12/09/mapping-relationships-between-neo4j-spatial-nodes-with-geopandas/image-11-6/" data-orig-file="https://underdark.files.wordpress.com/2023/12/image-11.png" data-orig-size="527,975" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="image-11" data-image-description="" data-image-caption="" data-medium-file="https://underdark.files.wordpress.com/2023/12/image-11.png?w=162" data-large-file="https://underdark.files.wordpress.com/2023/12/image-11.png?w=527" src="https://underdark.files.wordpress.com/2023/12/image-11.png?w=527" alt="" class="wp-image-8698" srcset="https://underdark.files.wordpress.com/2023/12/image-11.png 527w, https://underdark.files.wordpress.com/2023/12/image-11.png?w=81 81w, https://underdark.files.wordpress.com/2023/12/image-11.png?w=162 162w" sizes="(max-width: 527px) 100vw, 527px" /></a></figure> | ||
|
||
|
||
|
||
<p>And here’s the notebook: <a href="https://github.com/anitagraser/QGIS-resources/blob/master/qgis3/notebooks/neo4j.ipynb">https://github.com/anitagraser/QGIS-resources/blob/master/qgis3/notebooks/neo4j.ipynb</a> </p> |
Binary file not shown.
Binary file not shown.
Binary file modified
BIN
+23 Bytes
(100%)
content/community-blogs/setting-up-a-graph-db-using-gtfs-data-neo4j.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
--- | ||
source: "blog" | ||
title: "maptiler.com: Vector basemaps in QGIS" | ||
title: "maptiler.com: Say hello to the new QGIS plugin" | ||
image: "www.maptiler.com." | ||
date: "2023-11-22" | ||
link: "https://www.maptiler.com/" | ||
draft: "true" | ||
showcase: "planet" | ||
--- | ||
|
||
The new version of the MapTiler plugin pushes our maps from MapTiler Cloud almost to perfection | ||
Open-source plugin for QGIS that loads fast vector maps. Change colors and fonts of the map to get unique look. |