OSMnx Difference between geometries_from_place tag highway and graph_from_place? - openstreetmap

I use OSMnx for my project and I need to retrieve information about roads.
I know I can use osmnx.graph_from_place(place, network_type="all") to get the graph of highways of a certain type from Open Street Map. However it does not provides lots of features, only 15.
I know I can use osmnx.geometries_from_place(place, tags={"highway"=True}) , it gives more features however it provides different result than the previous function (less rows).
Using 'Etterbeek, Brussels, Belgium' as place, with graph_from_place, I get 12636 rows in my dataframe but with geometries_from_place, I get 3636
So can anyone explain me what is the difference between the two functions and why they provide different results?
Code :
import osmnx as ox
place = 'Etterbeek, Brussels, Belgium'
etterbeek_all_highway_info = ox.geometries_from_place(place, tags={"highway":True})
len(etterbeek_all_highway_info) # 3636
street_graph = ox.graph_from_place(place, network_type='all', simplify=False)
nodes , streets = ox.graph_to_gdfs(street_graph)
len(streets["highway"]) #12636
Documentation :
https://osmnx.readthedocs.io/en/stable/osmnx.html#osmnx.graph.graph_from_place
https://osmnx.readthedocs.io/en/stable/osmnx.html#osmnx.geometries.geometries_from_place

Related

Adding POIs/amenities from geometries_from_polygon or geometries_from_place to graph via graph_from_gdfs

Does someone has a function handy that adds POIs retrieved with geometries_from_polygon (or geometries_from_place) as GDF to an existing graph via graph_from_gdfs?
Basically something simple like
G = ox.graph_from_place(query = "<query>", network_type='all', simplify=False, retain_all=True)
pois = ox.geometries.geometries_from_polygon(<geometry>, tags = {"amenity": [<amenity_tag>]})
> simple function that generates the nodes and edges from the pois GDF ?
G2 = ox.graph_from_gdfs(pois_nodes, pois_edges, <graph_attrs>)
> merge G and G2 ?
ox.save_graph_xml(<merged_G_and_G2>)
I think I can just iterate through the GDF and generate the nodes/edges myself, but I'm wondering if there isn't an easier/simpler way to do this, or even an existing function I'm missing?
I'm not looking into rendering that actual graph, I'm just looking for an easy way to generate a graph XML file that includes both, the street network and some POIs and I'm using OSMX to modify that data in some ways.

How can I search street or postal address on simplekml without using coordinates

I have a list of street addresses, weekly my database grows. For example 10 Hage Geingob Walvis Bay. I need to plot their positions on Google Mymaps (or alternatively Google Earth) using the kml file. I'm doing it via Python. I'll eventually have control over the labels, colors, titles, descriptions offering me some value.
However the code seems to only respond to coordinate (lat/long) input, using the "coords" command. When using "address" command it simply targets the 0,0 lat/long position in the ocean.
I would appreciate any help on how to use the a street address as the input directly into simplekml...as if I typed the street address directly into google maps or google earth.
As a workaround I have used geocode functions such as geopy and Nominatim ...to establish GPS coordinates and then feed that to simplekml ...but accuracy is terrible. Some addresses are accurate, some are miles off.
I'm not interested in setting up keys and API's in GoogleV3.
Code used as workaround
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="redacted")
location = geolocator.geocode(address)
print(location.address)
print((location.latitude, location.longitude))
import simplekml
kml = simplekml.Kml() # Create an instance of Kml
single_point = kml.newpoint(name=address, coords=[(location.longitude,location.latitude)])
kml.save("10 Hage Geingob.kml")```
When in my view it should be possible to do the following according to the simplkml documentation...
```street_address = '10 Hage Geingob Walvis Bay'
import simplekml
kml = simplekml.Kml()
kml.newpoint(name=street_address, address=street_address)
kml.save("10 Hage Geingob.kml")```
...but it doesn't work. Any help is much appreciated thank you. I am indeed a complete noob.
Thank you

Save and re-load a weighted graph from OSMnx for NetworKX

I am using OSMnx to get a graph and add a new edge attribute (w3) representing a custom weight for each edge. Then I can successfully find 2 different shortest paths between 2 points using NetworkX and 'length', 'w2'. Everything works fine, this is my code:
G = ox.graph_from_place(PLACE, network_type='all_private', retain_all = True, simplify=True,truncate_by_edge=False) ```
w3_dict = dict((zip(zip(lu, lv, lk),lw3)))
nx.set_edge_attributes(G, w3_dict, "w3")
route_1 = nx.shortest_path(G, node_start, node_stop, weight = 'length')
route_2 = nx.shortest_path(G, node_start, node_stop, weight = 'w3')
Now I would like to save G to disk and reopen it, to perform more navigation tasks later on. But after saving it with:
ox.save_graph_xml(G, filepath='DATA/network.osm')
and reopen it with:
G = ox.graph_from_xml('DATA/network.osm')
my custom attribute w3 has disappeared. I have followed the instructions in the docs but with no luck. It feels like I'm missing something really obvious but I don't understand what it is..
Use the ox.save_graphml and ox.load_graphml functions to save/load full-featured OSMnx/NetworkX graphs to/from disk for later use. The save xml function exists only to allow serialization to the .osm file format for applications that require it, and has many constraints to conform to that.
import networkx as nx
import osmnx as ox
ox.config(use_cache=True, log_console=True)
# get a graph, set 'w3' edge attribute
G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')
nx.set_edge_attributes(G, 100, 'w3')
# save graph to disk
ox.save_graphml(G, './data/graph.graphml')
# load graph from disk and confirm 'w3' edge attribute is there
G2 = ox.load_graphml('./data/graph.graphml')
nx.get_edge_attributes(G2, 'w3')

Plot a graph with ipycytoscape (and networkx)

Following the instructions of ipycitoscape I am not able to plot a graph using ipycitoscape.
according to: https://github.com/QuantStack/ipycytoscape/blob/master/examples/Test%20NetworkX%20methods.ipynb
this should work:
import networkx as nx
import ipycytoscape
G2 = nx.Graph()
G2.add_nodes_from([*'ABCDEF'])
G2.add_edges_from([('A','B'),('B','C'),('C','D'),('E','F')])
print(G2.nodes)
print(G2.edges)
cytoscapeobj = ipycytoscape.CytoscapeWidget()
cytoscapeobj.graph.add_graph_from_networkx(nx_graph)
G2 is a networkx graph example and it looks ok since print(G2) gives the networkx object back and G2.nodes and G2.edges can be printed.
The error:
ValueError: invalid literal for int() with base 10: 'A'
Why should a node be an integer?
More general what to do if the starting data point if a pandas dataframe with a million rows edges those being strings like ProcessA-ProcessB, processC-processD etc
Also having a look to the examples it is to be noted that the list of nodes is composed of a dictionary data for every node. that data including an "id" per node and also "Atribute". The surprise here is that the networkx Graph should have all those properties.
thanks
This problem was fixed. See attachment.
Please let me know if it's still happening. Feel free to open an issue: https://github.com/QuantStack/ipycytoscape/
I'm just playing around with ipycytoscape myself, so I could be way off-base, but, shouldn't the line be:
cytoscapeobj.graph.add_graph_from_networkx(G2) # your graph name goes here
Trying to generate a cytoscape object built on a graph that doesn't exist might trigger a ValueError because it can't find any nodes.

pygraphviz/networkx external label (xlabel)

I have a question regarding external labels in pygraphviz. Sadly, I haven't found anything regarding this on the internet.
I want to use networkx to create/parse a graph in tree structure and then use pygraphviz/pydot to draw it. I need external labels on top of the normal labels for the nodes because I want to display values for the nodes + the node name itself.
Let's say I have the following graph (very simplified example of what I'm doing later):
g = nx.Graph()
g.add_edges_from([('A','B'), ('A','C')])
p = nx.drawing.nx_pydot.to_pydot(g)
So I'm using the last line to generate a tree like hraph and I need external labels for B and C.
How to do it?
For pygraphviz you can pass through arbitrary graphviz attributes, so you can do:
dot.node('point', '', shape='point', xlabel='Label')