You should take advantage of GeoDistance
listability.
In[2]:= level1$dists =
GeoDistance[level1, level1,
DistanceFunction -> "Center"]; // AbsoluteTiming
Out[2]= {0.91751, Null}
Also with the default option is fast:
In[3]:= level1$dists2 = GeoDistance[level1, level1]; // AbsoluteTiming
Out[3]= {1.34659, Null}
But for a list as long as level2
, you should do partition yourself and call GeoDistance
in groups. Instead of using Partition
, you can also use directly the natural partition of first administrative divisions, something like:
In[4]:= level2u = AdministrativeDivisionData[#, "Subdivisions"] & /@ level1;
In[5]:= level2$dist = Outer[GeoDistance, level2u, level2u, 1]; // AbsoluteTiming
Out[5]= {288.062, Null}