diff --git a/libcdi b/libcdi
index 44f985e1c427d75c261d25e782e895224ccd5a31..c59834a769ba989e8b4f3b6b762ca09d340bfa7a 160000
--- a/libcdi
+++ b/libcdi
@@ -1 +1 @@
-Subproject commit 44f985e1c427d75c261d25e782e895224ccd5a31
+Subproject commit c59834a769ba989e8b4f3b6b762ca09d340bfa7a
diff --git a/src/Remapgrid.cc b/src/Remapgrid.cc
index 6cf2c4929b21fb50009da17dffffc99d20440701..0268337596ff4db42df4adfa8cf3c5b7422386d3 100644
--- a/src/Remapgrid.cc
+++ b/src/Remapgrid.cc
@@ -196,14 +196,12 @@ remap_set_fracmin(double fracMin, Field &field, const RemapGrid *tgtGrid)
 }
 
 static void
-remap_field(const RemapSwitches &remapSwitches, RemapType &remap, const Field &field1, Field &field2)
+remap_field(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap, const Field &field1, Field &field2)
 {
-  auto mapType = remapSwitches.mapType;
-  auto numNeighbors = remapSwitches.numNeighbors;
   // clang-format off
   if      (mapType == RemapMethod::BILINEAR) remap_bilinear(remap.search, field1, field2);
   else if (mapType == RemapMethod::BICUBIC)  remap_bicubic(remap.search, field1, field2);
-  else if (mapType == RemapMethod::KNN)      remap_knn(numNeighbors, remap.search, field1, field2);
+  else if (mapType == RemapMethod::KNN)      remap_knn(knnParams, remap.search, field1, field2);
   else if (mapType == RemapMethod::CONSERV)  remap_conserv(remap.vars.normOpt, remap.search, field1, field2);
   // clang-format on
 }
@@ -507,7 +505,13 @@ public:
         if (remapSwitches.mapType == RemapMethod::KNN)
           {
             if (numNeighbors) remapSwitches.numNeighbors = numNeighbors;
-            if (remapSwitches.numNeighbors == -1) remapSwitches.numNeighbors = 1;
+            if (remapSwitches.numNeighbors != -1)
+              {
+                knnParams.k = remapSwitches.numNeighbors;
+                knnParams.kMin = 1;
+                knnParams.extrapolate = remapExtrapolate;
+                knnParams.weighted = WeightingMethod::distanceWeighted;
+              }
           }
       }
 
@@ -610,7 +614,7 @@ public:
     // initialize some remapping variables
     remap_vars_init(mapType, remapOrder, remap.vars);
 
-    remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, remapSwitches.numNeighbors);
+    remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, knnParams.k);
 
     if (remap_genweights)
       {
@@ -620,7 +624,7 @@ public:
               cdo_abort("Second order remapping is not available for unstructured grids!");
           }
 
-        remap_gen_weights(remapSwitches, remap);
+        remap_gen_weights(remapSwitches.mapType, knnParams, remap);
       }
   }
 
@@ -699,7 +703,7 @@ public:
                     else
                       remap_field(field2, var.missval, gridsize2, remap.vars, field1, gradients);
                   }
-                else { remap_field(remapSwitches, remap, field1, field2); }
+                else { remap_field(remapSwitches.mapType, knnParams, remap, field1, field2); }
 
                 if (operfunc == REMAPCON || operfunc == REMAPYCON2)
                   {
diff --git a/src/Remapweights.cc b/src/Remapweights.cc
index 1978b9406d6630353057eab80a1626642554ad6a..532395258e00b049182582726521bfe4f8c9298e 100644
--- a/src/Remapweights.cc
+++ b/src/Remapweights.cc
@@ -96,6 +96,7 @@ public:
   };
   inline static RegisterEntry<Remapweights> registration = RegisterEntry<Remapweights>(module);
 
+  KnnParams knnParams;
   RemapSwitches remapSwitches;
   int numRemaps{ 0 };
   int numNeighbors{ 0 };
@@ -182,6 +183,13 @@ public:
 
     remapSwitches = remap_operfunc_to_maptype(operfunc);
     if (numNeighbors) remapSwitches.numNeighbors = numNeighbors;
+    if (remapSwitches.numNeighbors != -1)
+      {
+        knnParams.k = remapSwitches.numNeighbors;
+        knnParams.kMin = 1;
+        knnParams.extrapolate = remapExtrapolate;
+        knnParams.weighted = WeightingMethod::distanceWeighted;
+      }
 
     mapType = remapSwitches.mapType;
     remapOrder = remapSwitches.remapOrder;
@@ -275,14 +283,14 @@ public:
             // initialize some remapping variables
             remap_vars_init(mapType, remapOrder, remap.vars);
 
-            remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, remapSwitches.numNeighbors);
+            remap_print_info(operfunc, remap_genweights, remap.srcGrid, remap.tgtGrid, numMissVals1, knnParams.k);
 
             if (needGradients && remap.srcGrid.rank != 2 && remapOrder == 2)
               {
                 cdo_abort("Second order remapping is not available for unstructured grids!");
               }
 
-            remap_gen_weights(remapSwitches, remap);
+            remap_gen_weights(remapSwitches.mapType, knnParams, remap);
 
             std::string outFile = cdo_get_stream_name(1);
             if (remapDefaults.genMultiWeights) { outFile += string_format("%05d", numRemaps) + ".nc"; }
diff --git a/src/remap.h b/src/remap.h
index 95c3e99782d471eb7a452e9b4da926be9de44603..1392bc1e6c12928f4ac36a7cb4e12e695dad9dae 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -87,12 +87,12 @@ size_t remap_search_cells(RemapSearch &rsearch, bool isReg2dCell, GridCell &grid
 
 void remap_bilinear_weights(RemapSearch &rsearch, RemapVars &rv);
 void remap_bicubic_weights(RemapSearch &rsearch, RemapVars &rv);
-void remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv);
+void remap_knn_weights(const KnnParams &knnParams, RemapSearch &rsearch, RemapVars &rv);
 void remap_conserv_weights(RemapSearch &rsearch, RemapVars &rv);
 
 void remap_bilinear(RemapSearch &rsearch, const Field &field1, Field &field2);
 void remap_bicubic(RemapSearch &rsearch, const Field &field1, Field &field2);
-void remap_knn(size_t numNeighbors, RemapSearch &rsearch, const Field &field1, Field &field2);
+void remap_knn(const KnnParams &knnParams, RemapSearch &rsearch, const Field &field1, Field &field2);
 void remap_conserv(NormOpt normOpt, RemapSearch &rsearch, const Field &field1, Field &field2);
 
 namespace remap
diff --git a/src/remap_knn.cc b/src/remap_knn.cc
index 7a995d846a71681923bcd032457db95e1f8830dc..cc8ada829f7cdf2964f14af1e9a3755c21e8fca9 100644
--- a/src/remap_knn.cc
+++ b/src/remap_knn.cc
@@ -21,7 +21,7 @@
 // This routine computes the weights for a k-nearest-neighbor interpolation
 // -----------------------------------------------------------------------
 void
-remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv)
+remap_knn_weights(const KnnParams &knnParams, RemapSearch &rsearch, RemapVars &rv)
 {
   auto srcGrid = rsearch.srcGrid;
   auto tgtGrid = rsearch.tgtGrid;
@@ -35,11 +35,11 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv)
   auto tgtGridSize = tgtGrid->size;
 
   std::vector<WeightLinks> weightLinks(tgtGridSize);
-  weight_links_alloc(numNeighbors, tgtGridSize, weightLinks);
+  weight_links_alloc(knnParams.k, tgtGridSize, weightLinks);
 
   std::vector<KnnData> knnDataList;
   knnDataList.reserve(Threading::ompNumThreads);
-  for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(numNeighbors));
+  for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(knnParams));
 
   cdo::timer timer;
 
@@ -75,7 +75,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv)
       // Store the link
       store_weightlinks(0, numWeights, knnData.m_indices.data(), knnData.m_dist.data(), tgtCellIndex, weightLinks);
 
-      if (numNeighbors > 1 && numWeights > 0)
+      if (knnParams.k > 1 && numWeights > 0)
         {
           if (numLinksPerValue == -1)
             numLinksPerValue = numWeights;
@@ -86,7 +86,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv)
 
   weight_links_to_remap_links(0, tgtGridSize, weightLinks, rv);
 
-  if (numNeighbors == 1)
+  if (knnParams.k == 1)
     rv.numLinksPerValue = 1;
   else if (numLinksPerValue > 0)
     rv.numLinksPerValue = numLinksPerValue;
@@ -99,7 +99,7 @@ remap_knn_weights(size_t numNeighbors, RemapSearch &rsearch, RemapVars &rv)
 // -----------------------------------------------------------------------
 template <typename T1, typename T2>
 static void
-remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, size_t numMissVals, size_t numNeighbors,
+remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, size_t numMissVals, const KnnParams &knnParams,
           RemapSearch &rsearch)
 {
   T1 missval = srcMissval;
@@ -120,7 +120,7 @@ remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, s
 
   std::vector<KnnData> knnDataList;
   knnDataList.reserve(Threading::ompNumThreads);
-  for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(numNeighbors));
+  for (int i = 0; i < Threading::ompNumThreads; ++i) knnDataList.push_back(KnnData(knnParams));
 
   cdo::timer timer;
 
@@ -157,10 +157,10 @@ remap_knn(const Varray<T1> &srcArray, Varray<T2> &tgtArray, double srcMissval, s
 }  // remap_knn
 
 void
-remap_knn(size_t numNeighbors, RemapSearch &remapSearch, const Field &field1, Field &field2)
+remap_knn(const KnnParams &knnParams, RemapSearch &remapSearch, const Field &field1, Field &field2)
 {
   auto func = [&](const auto &v1, auto &v2, double missval, size_t numMissVals) {
-    remap_knn(v1, v2, missval, numMissVals, numNeighbors, remapSearch);
+    remap_knn(v1, v2, missval, numMissVals, knnParams, remapSearch);
   };
   field_operation2(func, field1, field2, field1.missval, field1.numMissVals);
 }
diff --git a/src/remap_utils.cc b/src/remap_utils.cc
index ec4b96458f47510b2c9cf426c80a2c82874b7c37..4bfcb6f802e7d14138c4446489bd1371f28e1889 100644
--- a/src/remap_utils.cc
+++ b/src/remap_utils.cc
@@ -254,14 +254,12 @@ remap_get_normOpt(void)
 }
 
 void
-remap_gen_weights(const RemapSwitches &remapSwitches, RemapType &remap)
+remap_gen_weights(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap)
 {
-  auto mapType = remapSwitches.mapType;
-  auto numNeighbors = remapSwitches.numNeighbors;
   // clang-format off
   if      (mapType == RemapMethod::BILINEAR) remap_bilinear_weights(remap.search, remap.vars);
   else if (mapType == RemapMethod::BICUBIC)  remap_bicubic_weights(remap.search, remap.vars);
-  else if (mapType == RemapMethod::KNN)      remap_knn_weights(numNeighbors, remap.search, remap.vars);
+  else if (mapType == RemapMethod::KNN)      remap_knn_weights(knnParams, remap.search, remap.vars);
   else if (mapType == RemapMethod::CONSERV)  remap_conserv_weights(remap.search, remap.vars);
   // clang-format on
 }
diff --git a/src/remap_utils.h b/src/remap_utils.h
index a34fd77eb4a23012a7c6072027200293e501ea68..2f46c11c18bc614dcf6b8ece510f8b5082553a8a 100644
--- a/src/remap_utils.h
+++ b/src/remap_utils.h
@@ -57,7 +57,7 @@ RemapSwitches remap_operfunc_to_maptype(int operfunc);
 
 NormOpt remap_get_normOpt(void);
 
-void remap_gen_weights(const RemapSwitches &remapSwitches, RemapType &remap);
+void remap_gen_weights(RemapMethod mapType, const KnnParams &knnParams, RemapType &remap);
 
 std::vector<bool> remap_set_grids(int vlistID, const VarList &varList);