czwartek, 24 stycznia 2013

Change Node/Link/Zone Numbers in Visum via COM + limit of Visum

I believe anyone who has created once Visum network out of big extrenal datasets (mainly GIS - .shp) came across problems with numbering duplicates. Here I will show you how to overcome those issues. There are two ways: one is scripting (snippet below), another is via Access database.

Case:
We have model of Kraków (city ca. 1mln inhabitants), we are creating regional model of Małopolska - Kraków is it's capital.
We have detailed GIS network from regional municipality, we have our own Kraków model with Visum network. We want to merge them together.
In most cases we will have problems with duplicate keys in database (i.e. "Node with ID 301 already defined in the network"). That's mainly due to very decent DB architecture behind visum data. Each network object belongs to specific table with well defined 'primary key' and 'foreign key' - which basically cannot have duplicates (http://en.wikipedia.org/wiki/Foreign_key).
It goes like this:
  • each node is identified by it's NO
  • each link is identified by its FromNodeNo and ToNodeNo (those are foreign keys, plus implicitly it has it's own primary key NO - I assume)
  • each turn has its FromNode, ViaNode and ToNode
If during import of any external objects those numbers will get confused we get rubbish results (either all network is mixed up, either it's not imported at all.

Toy-network example:

1. I created following network and exported it to .shp:


Network no 1


2. I created another network like this:
Network no 2
3. I tried to import network 1 into network 2:
a) result without setting "Offset parameter":
No network import at all.
b) when You set "Offset" to a number greater than max NodeNo, you will get something
first you get error for some links (which were already defined in network no 2)

and finally the resulting network will be as follows:
network 1 imported into network 2 (marked added links) all together network makes no sense
As we see there's a lot of confusion.

Solution:

there are two methods: one is scripting, another is via Access DB.


Scripting is easier and faster and can be automated, but it doesn't work for many objects (it works for nodes, doesn't work for links). See examples below(all scripts in python):

a) Bulk (didn't work with older versions of Visum) - much faster:

def get_Nodes(Attr):
       return Visum.Net.Nodes.GetMultiAttValues(Attr)


Nodes=get_Nodes("No")
Nodes=list(Nodes)
Nodes=[list(node) for node in Nodes]
for i,node in enumerate(Nodes):
       node[1]=i+100000000 #put max node no in your network here

# we need to do it twice: once we add big number to all elements and the we can give them ordered numbers starting from whatever
Visum.Net.Nodes.SetMultiAttValues("No",Nodes)

Nodes=get_Nodes("No")
Nodes=list(Nodes)
Nodes=[list(node) for node in Nodes]
for i,node in enumerate(Nodes):
         node[1]=i+1000000 #give your threshold here (nodes will start fron No=1000000

Visum.Net.Nodes.SetMultiAttValues("No",Nodes)


b) element by element - can be very slow:

Nodes=Visum.Net.Nodes.GetMultiAttValues("No")
Nodes=[node[1] for node in Nodes]
for node in Nodes:
       Visum.Net.Nodes.ItemByKey(node).SetAttValue("No",node+
100000000 )
       i+=1
for node in Nodes:
      Visum.Net.Nodes.ItemByKey(node+
100000000 ).SetAttValue("No",i)
      i+=1


2) Access DataBase:
I'm not ver familiar with Access so just a picture of what I do:
a) Export network into Access DB (can take a lot of time)
b) Open access file and edit tables
c) Change keys in tables (for links it's good to change name of "No" column into anything else and create additional column named No, then set this column as a key.
d) make the new column "Autoincrement" - so the number will be integers starting from 1
(for links it needs to be different, links have directed numbers so it shall be like this: 1 1 2 2 3 3 4 4 5 5 6 6 ... - I did it in excel and pasted.
e) you save the file and Import it into Visum

This way we merged four different shapefiles with overlapping numbers and two different Visum networks.
Everything is neatly numbered starting from one onwards.


PS. We came across another issue which seemed strange but we found very easy explanation. During import we got following message that node number exceeds: 2 147 483 648. Which happened to be max of LongInt datatype, so actually that's the limit of Visum :) You cannot go any further. Simply reduce umbers by means of the solutions above.

Hope it helps!




Brak komentarzy:

Prześlij komentarz