Converting from "matrix" data into "coordinate" data

The reshaping can be done in several ways. Below are given three using SparseArray, "SSparseMatrix.m", and "DataReshape.m". (The first one is/was the accepted answer.)

I do these kind of transformations often while using sparse matrices (with named rows and columns) and Dataset objects. So, this answer is a good place to mention the related packages.

Data generation

First generating the data (simpler than in the question):

datafunction = MultinormalDistribution[{0, 0}, {{2, 1/2}, {1/2, 1}}];

data1 = N[Table[PDF[datafunction][{x, y}], {x, -4, 4, 1}, {y, -2, 2, 1}]];

MatrixForm[data1]

First answer (no-packages)

Make index-to-value associations corresponding to the ranges used to make data1:

aX = AssociationThread[Range[Length[#]], #] &@Range[-4, 4, 1];
aY = AssociationThread[Range[Length[#]], #] &@Range[-2, 2, 1];

Convert to a sparse array, take the corresponding rules, and map the {x,y} indexes to the actual x's and y's.

arules = Most[ArrayRules[SparseArray[data1]]];
data2 = Map[{aX[#[[1, 1]]], aY[#[[1, 2]]], #[[2]]} &, arules]

Plot (note the axes ticks):

ListContourPlot[data2]

enter image description here

Alternative answer using "SSparseMatrix.m"

This answer is just a package-based version of the previous one.

Import["https://raw.githubusercontent.com/antononcube/\
MathematicaForPrediction/master/SSparseMatrix.m"]

smat1 = ToSSparseMatrix[SparseArray[data1], 
  "RowNames" -> Map[ToString, Range[-4, 4, 1]], 
  "ColumnNames" -> Map[ToString, Range[-2, 2, 1]]]

data2a = SSparseMatrixToTriplets[smat1];
data2a = data2a /. x_String :> ToExpression[x];

data2a == data2  
(* True *)

Alternative answer with "DataReshape.m"

The package "DataReshape.m" was made because I have to often convert tabular data (Dataset objects) from "wide form" to "long form" and vice versa. (For R there are at least two dedicated packages from RStudio for doing these kind of transformations.)

Import["https://raw.githubusercontent.com/antononcube/\
MathematicaForPrediction/master/DataReshape.m"]

ds1 = Dataset[
   AssociationThread[Range[-4, 4, 1], 
    AssociationThread[Range[-2, 2, 1], #] & /@ data1]];

?ToLongForm

(* ToLongForm[ds_Dataset, idColumns_, valueColumns_] converts the \
dataset ds into long form. The resulting dataset has the columns \
idColumns and the columns "Variable" and "Value" derived from \
valueColumns. *)

data2b = Normal[ToLongForm[ds1][Values]];

data2b == data2
(* True *)

An alternative approach based on Rescaleing the "NonzeroPositions" of SparseArray[data1]:

xrange = {-4, 4};
yrange = {-2, 2};
sa = SparseArray[data1];
nzp = sa["NonzeroPositions"];
nzv = sa["NonzeroValues"];
data2b = Join[Transpose[Rescale[#, MinMax@#, #2] & @@@
     Thread[ {Transpose@nzp, {xrange, yrange}}]], List /@ nzv, 2];

data2b == data2 (* from Anton's answer *)

True