A challenging horizontal/vertical centering problem

Picture mode!

The side of the square is 5em, because \unitlength is set to 1em (which will take into account the current font). Therefore 0.3 represents a distance of 0.3em, which is what you seem to want. Fix the size according to your taste.

\documentclass{article}
\usepackage{pict2e}

\newcommand{\compass}[1]{%
  \begingroup
  \setlength\unitlength{1em}%
  \linethickness{0.2ex}%
  \begin{picture}(5,5)
  % the frame
  \moveto(0,0)\lineto(0,5)\lineto(5,5)\lineto(5,0)\closepath\strokepath
  % the cardinal points
  \put(2.5,4.7){\makebox[0pt]{\raisebox{-\height}{N}}}
  \put(2.5,0.3){\makebox[0pt]{S}}
  \put(0.3,2.5){\makebox[0pt][l]{\raisebox{-0.5\height}{W}}}
  \put(4.7,2.5){\makebox[0pt][r]{\raisebox{-0.5\height}{E}}}
  % the center
  \put(2.5,2.5){\makebox(0,0){#1}}
  \end{picture}%
  \endgroup
}

\begin{document}

X\compass{1}X\qquad{\footnotesize X\compass{3}X}\qquad{\tiny X\compass{5}X}

\bigskip

{\Large X\compass{12}X}\qquad{\Huge X\compass{24}X}

\end{document}

enter image description here


The following is a wild mix between LaTeX stuff and stuff you'd do using plain TeX. Change the default value of the optional argument of \compass to change the overall size. The overall size is not equal to the optional argument, but to #1+.6em+.4ex in width, #1+.3em+.2ex in height and .3em+.2ex in depth.

\documentclass[border=2mm]{standalone}

% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}

\newcommand\compass[2][10ex]
  {{%
    \fboxrule=.2ex
    \fboxsep=.3em
    \fbox
      {%
        \vbox to #1{\hsize=#1
          \hbox to #1{\hss N\hss}%
          \vss
          \hbox to #1{\rlap{W}\hss \clap{#2}\hss \llap{E}}%
          \vss
          \hbox to #1{\hss S\hss}%
        }%
      }%
  }}

\begin{document}
\compass{1}
\end{document}

enter image description here

Vertically it only aligns the baselines of W x E so if x is recognizable smaller than W and E it would not look vertically centred.

Version that also vertically centres the middle line using $\vcenter{...}$ (and utilizing that the \xlap macros use a \hbox internally so the text is not typeset in math mode):

\documentclass[border=2mm]{standalone}

% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}

\newcommand\compass[2][10ex]
  {{%
    \fboxrule=.2ex
    \fboxsep=.3em
    \fbox
      {%
        \vbox to #1{\hsize=#1
          \hbox to #1{\hss N\hss}%
          \vss
          \hbox to #1{%
            $\vcenter{\rlap{W}}$\hss
            $\vcenter{\clap{#2}}$\hss
            $\vcenter{\llap{E}}$%
          }%
          \vss
          \hbox to #1{\hss S\hss}%
        }%
      }%
  }}

\begin{document}
\compass{\tiny1}
\end{document}

enter image description here

Version that gives the same distance from the centre of the W and E to the border. Unfortunately it doesn't look as good as I thought.

\documentclass[border=2mm]{standalone}

% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}

\newbox\myTestbox
\newdimen\myhoffset
\newcommand\compass[2][10ex]
  {{%
    \setbox\myTestbox\hbox{E}%
    \myhoffset=.5\wd\myTestbox
    \setbox\myTestbox\hbox{W}%
    \ifdim\myhoffset<.5\wd\myTestbox
      \myhoffset=.5\wd\myTestbox
    \fi
    \fboxrule=.2ex
    \fboxsep=.3em
    \fbox
      {%
        \vbox to #1{\hsize=#1
          \hbox to #1{\hss N\hss}%
          \vss
          \hbox to #1{%
            \hskip\myhoffset
            $\vcenter{\clap{W}}$\hss
            $\vcenter{\clap{#2}}$\hss
            $\vcenter{\clap{E}}$%
            \hskip\myhoffset
          }%
          \vss
          \hbox to #1{\hss S\hss}%
        }%
      }%
  }}

\begin{document}
\compass[8ex]{\tiny1}
\end{document}

enter image description here

As OP noted, the \vcenter code has a small vertical offset from the middle. Therefore here another version, this time using some \smashs and a calculated \raise amount for #2:

\documentclass[border=2mm]{standalone}

% this might already be defined depending on included packages
\providecommand\clap[1]{\hbox to 0pt{\hss #1\hss}}

\newdimen\myvoffset
\newbox\mytestboxA
\newbox\mytestboxB
\newcommand\compass[2][10ex]
  {{%
    \setbox\mytestboxA\hbox{WE}%
    \setbox\mytestboxB\hbox{#2}%
    \myvoffset=\dimexpr
      \ht\mytestboxA-\ht\mytestboxB+\dp\mytestboxB-\dp\mytestboxA\relax
    \myvoffset=.5\myvoffset
    \fboxrule=.2ex
    \fboxsep=.3em
    \fbox
      {%
        \vbox to #1{\hsize=#1
          \hbox to #1{\hss N\hss}%
          \vss
          \hbox to #1{%
            \smash{\rlap{W}}\hss
            \smash{\clap{\raise\myvoffset\hbox{#2}}}\hss
            \smash{\llap{E}}%
          }%
          \vss
          \hbox to #1{\hss S\hss}%
        }%
      }%
  }}

\begin{document}
\compass[2.5em]{\tiny1}
\end{document}

enter image description here


Just for completeness (as this is overkill for the problem) a TikZ based answer (you'll need \usepackage{tikz} in your preamble). The optional argument matches the size

\documentclass[tikz,border=2mm]{standalone}

\newcommand\compass[2][15ex]
  {%
    \begin{tikzpicture}[inner sep=0pt]
      \draw[line width=.2ex,use as bounding box] (0,0) rectangle (#1,#1);
      \node at (0.5*#1,0.5*#1) {#2};
      \node[anchor=north] at (0.5*#1,#1-0.3em) {N};
      \node[anchor=south] at (0.5*#1,0.3em) {S};
      \node[anchor=west] at (0.3em,0.5*#1) {W};
      \node[anchor=east] at (#1-0.3em,0.5*#1) {E};
    \end{tikzpicture}%
  }

\begin{document}
\compass{\tiny1}
\end{document}

enter image description here