private void initGeoCodings(Document dom) {
   final GeoCoding[] geoCodings = DimapProductHelpers.createGeoCoding(dom, product);
   if (geoCodings != null) {
     if (geoCodings.length == 1) {
       product.setGeoCoding(geoCodings[0]);
     } else if (geoCodings.length == product.getNumBands()) {
       for (int i = 0; i < geoCodings.length; i++) {
         final Band band = product.getBandAt(i);
         if (product.getSceneRasterWidth() == band.getRasterWidth()
             && product.getSceneRasterHeight() == band.getRasterHeight()) {
           product.setGeoCoding(geoCodings[i]);
         }
         band.setGeoCoding(geoCodings[i]);
       }
     }
   } else {
     final Band lonBand = product.getBand("longitude");
     final Band latBand = product.getBand("latitude");
     if (latBand != null && lonBand != null) {
       final GeoCoding geoCoding =
           GeoCodingFactory.createPixelGeoCoding(latBand, lonBand, null, 6);
       product.setGeoCoding(geoCoding);
     }
   }
 }
  @Override
  protected void addGeoCoding(final Product product) {

    TiePointGrid latGrid = product.getTiePointGrid(OperatorUtils.TPG_LATITUDE);
    TiePointGrid lonGrid = product.getTiePointGrid(OperatorUtils.TPG_LONGITUDE);
    if (latGrid != null && lonGrid != null) {
      setLatLongMetadata(product, latGrid, lonGrid);

      final TiePointGeoCoding tpGeoCoding = new TiePointGeoCoding(latGrid, lonGrid, Datum.WGS_84);
      product.setGeoCoding(tpGeoCoding);
      return;
    }

    final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
    final String acquisitionMode = absRoot.getAttributeString(AbstractMetadata.ACQUISITION_MODE);
    int numOfSubSwath;
    switch (acquisitionMode) {
      case "IW":
        numOfSubSwath = 3;
        break;
      case "EW":
        numOfSubSwath = 5;
        break;
      default:
        return;
    }

    String[] bandNames = product.getBandNames();
    Band firstSWBand = null, lastSWBand = null;
    boolean firstSWBandFound = false, lastSWBandFound = false;
    for (String bandName : bandNames) {
      if (!firstSWBandFound && bandName.contains(acquisitionMode + 1)) {
        firstSWBand = product.getBand(bandName);
        firstSWBandFound = true;
      }

      if (!lastSWBandFound && bandName.contains(acquisitionMode + numOfSubSwath)) {
        lastSWBand = product.getBand(bandName);
        lastSWBandFound = true;
      }
    }
    if (firstSWBand == null && lastSWBand == null) return;

    final GeoCoding firstSWBandGeoCoding = bandGeocodingMap.get(firstSWBand);
    final int firstSWBandHeight = firstSWBand.getRasterHeight();

    final GeoCoding lastSWBandGeoCoding = bandGeocodingMap.get(lastSWBand);
    final int lastSWBandWidth = lastSWBand.getRasterWidth();
    final int lastSWBandHeight = lastSWBand.getRasterHeight();

    final PixelPos ulPix = new PixelPos(0, 0);
    final PixelPos llPix = new PixelPos(0, firstSWBandHeight - 1);
    final GeoPos ulGeo = new GeoPos();
    final GeoPos llGeo = new GeoPos();
    firstSWBandGeoCoding.getGeoPos(ulPix, ulGeo);
    firstSWBandGeoCoding.getGeoPos(llPix, llGeo);

    final PixelPos urPix = new PixelPos(lastSWBandWidth - 1, 0);
    final PixelPos lrPix = new PixelPos(lastSWBandWidth - 1, lastSWBandHeight - 1);
    final GeoPos urGeo = new GeoPos();
    final GeoPos lrGeo = new GeoPos();
    lastSWBandGeoCoding.getGeoPos(urPix, urGeo);
    lastSWBandGeoCoding.getGeoPos(lrPix, lrGeo);

    final float[] latCorners = {
      (float) ulGeo.getLat(), (float) urGeo.getLat(), (float) llGeo.getLat(), (float) lrGeo.getLat()
    };
    final float[] lonCorners = {
      (float) ulGeo.getLon(), (float) urGeo.getLon(), (float) llGeo.getLon(), (float) lrGeo.getLon()
    };

    ReaderUtils.addGeoCoding(product, latCorners, lonCorners);

    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_lat, ulGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_near_long, ulGeo.getLon());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_lat, urGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.first_far_long, urGeo.getLon());

    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_lat, llGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_near_long, llGeo.getLon());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_lat, lrGeo.getLat());
    AbstractMetadata.setAttribute(absRoot, AbstractMetadata.last_far_long, lrGeo.getLon());

    // add band geocoding
    final Band[] bands = product.getBands();
    for (Band band : bands) {
      band.setGeoCoding(bandGeocodingMap.get(band));
    }
  }