I'm working on a NetLogo project where I'm using the nw:load-graphml
function from the NW extension to load data from a GraphML file into my NetLogo model.
When I use nw:set-context turtles routes
and then call nw:load-graphml "orbis.graphml"
, my code works perfectly. Here is the code that works:
extensions [nw]
directed-link-breed [ routes route ]
routes-own [ days expense km route-type ]
turtles-own [ pots node-id x y modern province rank town-name ]
to setup
clear-all
nw:set-context turtles routes
nw:load-graphml "orbis.graphml"
ask turtles [
show x
]
reset-ticks
end
The variable x
is the x coordinate of a city in a network.
However, when I change the turtle breed to cities
and use nw:set-context cities routes
instead, I'm unable to retrieve x
values from the cities. This is the code that doesn't work:
extensions [nw]
breed [ cities city ]
directed-link-breed [ routes route ]
routes-own [ days expense km route-type ]
cities-own [ pots node-id x y modern province rank town-name ]
to setup
clear-all
nw:set-context cities routes
nw:load-graphml "orbis.graphml"
ask cities [
show x
]
reset-ticks
end
Here, when I ask cities to show x
, I get nothing.
My GraphML file contains nodes with x
attributes, as shown in this extract:
<node id="n0">
<data key="d0">1</data>
<data key="d1">50001</data>
<data key="d2">0</data>
<data key="d3">Raetia</data>
<data key="d4">Germany</data>
<data key="d5">10.909</data>
<data key="d6">60</data>
<data key="d7">47.909</data>
<data key="d8">1</data>
<data key="d9">Abodiacum</data>
<data key="d10">0</data>
</node>
My project is built on top of this project. Pressing download will get you the .nlogo
file and the orbis.graphml
file.
Can someone explain why the x
values are not showing up for the cities
breed, while they do for turtles? Why does the breed change cause this issue?
The Netlogo User Manual for the Nw extension mentions the following (emphasis mine):
The key idea is that
nw:load-graphml
will try to assign the attribute values defined in the GraphML file to NetLogo agent variables of the same names (this is not case sensitive). The first one it tries to set is breed if it is there, so the turtle or link will get the right breed and, hence, the right breed variables. The load expects the plural form of the breed for a turtle or link, it will not recognize the singular form.
This means that, if you want to use a particular breed for nodes and edges, then this breed must be defined in the GraphML file.
For the edges the breed is already defined (line 23):
<key attr.name="BREED" attr.type="string" for="edge" id="d20"/>
And each individual edge contains a key that specifies that this edge is part of the breed routes
:
<data key="d20">routes</data>
For nodes however, no breed is specified in the GraphML file. This means that NetLogo is unable to assign the nodes to the cities
nodeset. It is however not very difficult to modify the GraphML file to specify the breed for nodes as well. Add the following to the main graph specification:
<key attr.name="BREED" attr.type="string" for="node" id="dbreed"/>
Then add a data key to each node:
<node id="n0">
<data key="dbreed">cities</data>
<data key="d0">1</data>
<data key="d1">50001</data>
<data key="d2">0</data>
<data key="d3">Raetia</data>
<data key="d4">Germany</data>
<data key="d5">10.909</data>
<!-- more data here -->
</node>
Now of course you don't want to type the extra line manually for all 678 cities. You can do a regular expression search-and-replace to make this automatic. Replace all occurrences of the following:
(<node id="n\d+">)
with the matched string followed by a newline, a bit of indentation, and the extra line:
\1\n <data key="dbreed">cities</data>
The exact regular expression syntax may differ between text editors, but this is the general idea. Of course you can also do this properly with an XML editor but the regex version seems to work fine.
Result after modifying the GraphML file, with unchanged NetLogo code: