private static boolean canCreateGcpGeoCoding(final double[] tiePoints) {
    int numTiePoints = tiePoints.length / 6;

    if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL3.getTermCountP()) {
      return true;
    } else if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL2.getTermCountP()) {
      return true;
    } else if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL1.getTermCountP()) {
      return true;
    } else {
      return false;
    }
  }
  private static void applyGcpGeoCoding(
      final TiffFileInfo info, final double[] tiePoints, final Product product) {

    int numTiePoints = tiePoints.length / 6;

    final GcpGeoCoding.Method method;
    if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL3.getTermCountP()) {
      method = GcpGeoCoding.Method.POLYNOMIAL3;
    } else if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL2.getTermCountP()) {
      method = GcpGeoCoding.Method.POLYNOMIAL2;
    } else if (numTiePoints >= GcpGeoCoding.Method.POLYNOMIAL1.getTermCountP()) {
      method = GcpGeoCoding.Method.POLYNOMIAL1;
    } else {
      return; // not able to apply GCP geo coding; not enough tie points
    }

    final int width = product.getSceneRasterWidth();
    final int height = product.getSceneRasterHeight();

    final GcpDescriptor gcpDescriptor = GcpDescriptor.getInstance();
    final ProductNodeGroup<Placemark> gcpGroup = product.getGcpGroup();
    for (int i = 0; i < numTiePoints; i++) {
      final int offset = i * 6;

      final float x = (float) tiePoints[offset + 0];
      final float y = (float) tiePoints[offset + 1];
      final float lon = (float) tiePoints[offset + 3];
      final float lat = (float) tiePoints[offset + 4];

      if (Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(lon) || Double.isNaN(lat)) {
        continue;
      }
      final PixelPos pixelPos = new PixelPos(x, y);
      final GeoPos geoPos = new GeoPos(lat, lon);

      final Placemark gcp =
          Placemark.createPointPlacemark(
              gcpDescriptor, "gcp_" + i, "GCP_" + i, "", pixelPos, geoPos, product.getGeoCoding());
      gcpGroup.add(gcp);
    }

    final Placemark[] gcps = gcpGroup.toArray(new Placemark[gcpGroup.getNodeCount()]);
    final SortedMap<Integer, GeoKeyEntry> geoKeyEntries = info.getGeoKeyEntries();
    final Datum datum = getDatum(geoKeyEntries);
    product.setGeoCoding(new GcpGeoCoding(method, gcps, width, height, datum));
  }