Thanks to Ryan Reich's Most Excellent PGFKeys tracing package (at How do I debug pgfkeys?), I found that the key node distance stores its value in the macro \tikz@node@distance. This means that it cannot be accessed via the "standard channels" for pgfkeys (namely \pgfkeyvalueof). Moreover, as the macro name has @s in it then it cannot be used as-is. So we have to define a wrapper to get the value of this macro.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
% This bit was how I found out what was going on
%\usepackage{trace-pgfkeys}
%\pgfkeystracelevel{verbose}
%\tikzset{node distance=3mm}
%\pgfkeystracelevel{silent}
\makeatletter
\def\getnodedistance{\tikz@node@distance}
\makeatother
\begin{document}
\begin{tikzpicture}[%
mystyle/.style={draw, node distance=3mm}
]
\node [mystyle] (n1) {1};
\node [mystyle, right=of n1] (n2) {2};
\node [mystyle, below] at ([yshift=-\getnodedistance]$(n1.south) !0.5! (n2.south)$) (n3)
{3};
\end{tikzpicture}
\end{document}
This method doesn't easily generalise, but that's because pgfkeys can do whatsoever they like with the values that they are passed, including storing them in arbitrary macros. Sometimes you are lucky and they store them in keys in which case \pgfkeysvalueof{full key name} is what you want here. If a general macro is used, then you have to use that macro to access it.
(An alternative method would be to add some code to the original key call to store the value in another macro which you could use. I'd use this if the key used the argument in some non-trivial way which made it hard to extract the original value.)
Note: since the assignment node distance=3mm is local, you need to ensure that the mystyle key is invoked before the \getnodedistance macro is called. That's why I shifted the [mystyle,below] part to before the coordinate calculation. If you wanted to be able to specify the 3mm earlier in the document, I'd do all this in another way: store the 3mm in a separate key and then have both node distance and the yshift access this key. Something like:
\tikzset{
my global node distance/.initial=3mm,
mystyle/.style={
draw,
node distance=\pgfkeysvalueof{/tikz/my global node distance}
}
}
...
\node [mystyle,below] at ([yshift=-\pgfkeysvalueof{/tikz/my global node distance]...
EDIT (by percusse) :
Here are two more ways to include the macro assignment in the style declaration
1) Provide a length macro name option to save the value of node distance directly to that macro name(in this case mynodedist).
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\makeatletter
\tikzset{ mystyle/.style={draw, node distance=3mm, save node distance to=mynodedist},
save node distance to/.code={\expandafter\newdimen\csname#1\endcsname%
\advance\csname#1\endcsname by \tikz@node@distance }
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node [mystyle] (n1) {1};
\node [mystyle, right=of n1] (n2) {2};
\node [mystyle, below] at ([yshift=-\mynodedist ]$(n1.south) !0.5! (n2.south)$) (n3) {3};
\end{tikzpicture}
\end{document}
2) You can do the regular style= and code= assignment of the same key set, for more disciplined key-value pairing which boils down to modifying only
\makeatletter
\tikzset{ mystyle/.style={draw, node distance=3mm},
mystyle/.add code={}{\def\mynodedist{\tikz@node@distance}}
}
\makeatother
calcandpositioning, but with more obscure libraries it can take longer to figure out and that makes it harder for people to know that they are answering the question well. – Andrew Stacey Mar 29 '12 at 11:52C-y C-x C-fwithout having to think. Then I can see the problem straight away and make a quick assessment on whether or not I'll be able to help. – Andrew Stacey Mar 29 '12 at 13:32