Load a network with an existing topology structure#

This documentation describes how to load data with a known topological (network) structure. The required structure is very simple: each edge has an initial (i.e. source) node and a final (i.e. target) node, the edges and nodes are defined by an identifier, and the geometry of the edges is a LineString type. It should be noted that directed graphs can be managed using the ‘orientation’ attribute of the edges, and a path cost can also be specified.

In tracklib, the static method readFromFile loads network data from a text file, and stores it in the Network structure:

tkl.NetworkReader.readFromFile(path:str,
                               formatfile:Union[str, NetworkFormat]="DEFAULT",
                               verbose=True) -> Network

Before to load network data, you need to create a NetworkFormat (option 1 or 2 described below) which describes metadata of the file. If this format is widely used, you can formalize it in a network_file_format (in tracklib/resources/ directory) and just call it as parameter (option 3 described below).

The network’s format must necessarily specify these parameters:

  • pos_edge_id: index of column containing the edge identifier

  • pos_source: index of column containing the node identifier

  • pos_target: index of the colmum containing the node identifier

  • pos_wkt: index of column containing geometry of edge in wkt format

  • srid: coordinate system of points (ENU, Geo or ECEF). Default srid is ENU.

You can specify also optional parameters:

  • pos_weight: the path cost, arbitrarily set to be proportional to the length of the WKT

  • pos_direction: the orientation of the edge. An integer arbitrarily set to: 0 to indicate two-way, 1 direct way and -1 indirect way

Parameters dedicated to reading the text file:

  • separator: the separating characters (can be multiple characters). Can be: c (comma), b (blankspace), s (semi-column)

  • header: the number of heading line in format

  • doublequote: true to manage double quote

  • encoding: the encoding like utf-8

As usual, let’s start by defining our environment#

The first task is only useful for the online notebook and import the local tracklib code source. It’s not necessary if tracklib is installed from PyPI.

[1]:
import os
import sys

# Import de tracklib
module_path = os.path.abspath(os.path.join('../../../../'))
if module_path not in sys.path:
    sys.path.append(module_path)

The following two imports are necessary for the tutorial:

[2]:
import matplotlib.pyplot as plt

# Import tracklib library
import tracklib as tkl

Loading network data from a CSV file#

In this short tutorial, the file used as an example is network-utgtrack-22245.csv, located in the data/network directory. It has a header line, and the parameters specified are in this order:

WKT,link_id,source,target,direction

Option 1: From a dictionary-type structure#

Although the file contains orientation data, we have decided not to load it here:

[3]:
# We define a network format
fmt_vtt = tkl.NetworkFormat({"pos_edge_id": 1,  "pos_source": 2, "pos_target": 3, "pos_wkt": 0, "srid": "GEO"})

# Then, we can load data
netpath = "../../../../data/network/network-utgtrack-22245.csv"
network = tkl.NetworkReader.readFromFile(netpath, fmt_vtt, verbose=False)
network.plot('k-', '', 'g-', 'r-', 1, plt)

# the direction is not loaded:
print (network.getEdgeId(25), network[25].orientation, round(network[25].weight, 2))
print (network.getEdgeId(29), network[29].orientation, round(network[29].weight, 2))
print (network.getEdgeId(30), network[30].orientation, round(network[30].weight, 2))
troncon_de_route.TRONROUT0000000002223246 0 33.07
troncon_de_route.TRONROUT0000000002223252 0 41.04
troncon_de_route.TRONROUT0000000002223253 0 137.37
../../_images/started_io_UG_IO_Network_7_1.png

Example 2: we load now the orientation data:

  • -1 : undirect way

  • 0 : two-way

  • 1 : direct way

[4]:
# We define a network format
fmt_vtt = tkl.NetworkFormat({"pos_edge_id": 1,  "pos_source": 2, "pos_target": 3, "pos_wkt": 0, "srid": "GEO", "pos_direction": 4})

# Then, we can load data
netpath = "../../../../data/network/network-utgtrack-22245.csv"
network = tkl.NetworkReader.readFromFile(netpath, fmt_vtt, False)
network.plot('k-', '', 'g-', 'r-', 1, plt)
plt.legend()

# the direction is loaded:
print (network.getEdgeId(25), network[25].orientation, round(network[25].weight, 2))
print (network.getEdgeId(29), network[29].orientation, round(network[29].weight, 2))
print (network.getEdgeId(30), network[30].orientation, round(network[30].weight, 2))
troncon_de_route.TRONROUT0000000002223246 1 33.07
troncon_de_route.TRONROUT0000000002223252 -1 41.04
troncon_de_route.TRONROUT0000000002223253 0 137.37
../../_images/started_io_UG_IO_Network_9_1.png

Option 2 : Field by field#

As above, but the fields are specified after creating the format.

[5]:
fmt_vtt = tkl.NetworkFormat()
fmt_vtt.pos_edge_id = 1
fmt_vtt.pos_source = 2
fmt_vtt.pos_target = 3
fmt_vtt.pos_wkt = 0
fmt_vtt.srid = 'GEO'
fmt_vtt.pos_direction = 4

# Then, we can load data
netpath = "../../../../data/network/network-utgtrack-22245.csv"
network = tkl.NetworkReader.readFromFile(netpath, fmt_vtt, False)
network.plot('k-', '', 'g-', 'r-', 0.5, plt)
plt.legend()
[5]:
<matplotlib.legend.Legend at 0x78afb22d0550>
../../_images/started_io_UG_IO_Network_11_1.png

Option 3: From a format defined as an external resource#

If this format is widely used, you can formalize it in a network_file_format and just call it as parameter.

  1. With the asString function, you can get the line in text format to store metadata format in the resources file:

[6]:
fmt_vtt = tkl.NetworkFormat()
fmt_vtt.pos_edge_id = 1
fmt_vtt.pos_source = 2
fmt_vtt.pos_target = 3
fmt_vtt.pos_wkt = 0
fmt_vtt.srid = 'GEO'
fmt_vtt.pos_direction = 4

print (fmt_vtt.asString())
UNDEFINED, 1, 2, 3, 0, -1, 4, c, 1, -1, UTF-8, GEO
  1. Then, let’s define a format call ‘VTT’ in the file network_file_format which corresponds to the network associated with mountain bike tracks. The file network_file_format is in tracklib/resources/ directory. All you have to do is replace the “UNDEFINED” in the previously calculated line and and copy it to the end of the file.

# Extract from file network_file_format:
# -----------------------------------------------------------------------------
DEFAULT, 0, 1, 2, 3, -1, 5, c, 1, True, UTF-8, GEO
IGN, 0, 1, 2, 4, -1, 3, c, 1, True, UTF-8, ENU
VERNIQUET, 0, 2, 3, 4, -1, 0, c, 1, True, UTF-8, ENU
VTT, 1, 2, 3, 0, -1, 4, c, 1, True, UTF-8, GEO
  1. Then, we can load data with the format name ‘VTT’:

[7]:
netpath = "../../../../data/network/network-utgtrack-22245.csv"
network = tkl.NetworkReader.readFromFile(netpath, 'VTT', False)

print ('nb edges=', len(network.EDGES))
print ('nb nodes=', len(network.NODES))

network.plot('k-', '', 'g-', 'r-', 0.5, plt)
plt.legend()
nb edges= 288
nb nodes= 216
[7]:
<matplotlib.legend.Legend at 0x78afb4414040>
../../_images/started_io_UG_IO_Network_16_2.png