fr.amap.lidar.amapvox.voxelisation.postproc.MultiBandRaster.java Source code

Java tutorial

Introduction

Here is the source code for fr.amap.lidar.amapvox.voxelisation.postproc.MultiBandRaster.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.amap.lidar.amapvox.voxelisation.postproc;

import fr.amap.commons.raster.asc.Raster;
import fr.amap.commons.raster.multiband.BCommon;
import fr.amap.commons.raster.multiband.BHeader;
import fr.amap.commons.raster.multiband.BSQ;
import fr.amap.commons.util.Statistic;
import fr.amap.lidar.amapvox.commons.Voxel;
import fr.amap.lidar.amapvox.commons.VoxelSpaceInfos;
import fr.amap.lidar.amapvox.voxelisation.configuration.params.VoxelParameters;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger;

/**
 * Stores voxel space PAD values as a multi-band raster, which each z layer (relative to a DTM or not) is a raster band.
 * @author Julien Heurtebize
 */
public class MultiBandRaster {

    private final static Logger LOGGER = Logger.getLogger(MultiBandRaster.class);

    public static BSQ computeRaster(float startingHeight, float step, int bandNumber, int resolution,
            VoxelSpaceInfos infos, Voxel[][][] voxels, Raster dtm) {

        float[] altitudes = new float[bandNumber];
        for (int i = 0; i < bandNumber; i++) {
            altitudes[i] = startingHeight + (i * step);
        }

        float scale = (float) (resolution / infos.getResolution());

        int rasterXSize = (int) (Math.ceil(infos.getSplit().x / scale));
        int rasterYSize = (int) (Math.ceil(infos.getSplit().y / scale));

        BHeader header = new BHeader(rasterXSize, rasterYSize, altitudes.length, BCommon.NumberOfBits.N_BITS_32);
        header.setUlxmap(infos.getMinCorner().x + (resolution / 2.0f));
        header.setUlymap(infos.getMinCorner().y - (infos.getResolution() / 2.0f)
                + (infos.getSplit().y * infos.getResolution()));
        header.setXdim(resolution);
        header.setYdim(resolution);

        BSQ raster = new BSQ(null, header);

        Statistic[][][] padMean = new Statistic[rasterXSize][rasterYSize][altitudes.length];

        if (dtm != null) {

            if (altitudes.length > 0) {

                float altitudeMin = altitudes[0];

                for (int i = 0; i < infos.getSplit().x; i++) {
                    for (int j = infos.getSplit().y - 1; j >= 0; j--) {
                        for (int k = 0; k < infos.getSplit().z; k++) {

                            Voxel vox = voxels[i][j][k];

                            //on calcule l'indice de la couche auquel appartient le voxel
                            if (vox != null && vox.ground_distance > altitudeMin) {
                                int layer = (int) ((vox.ground_distance - altitudeMin) / step);

                                if (layer < altitudes.length) {

                                    int indiceI = (int) (i / scale);
                                    int indiceJ = (int) (j / scale);

                                    if (padMean[indiceI][indiceJ][layer] == null) {
                                        padMean[indiceI][indiceJ][layer] = new Statistic();
                                    }

                                    if (!Float.isNaN(vox.PadBVTotal)) {
                                        padMean[indiceI][indiceJ][layer].addValue(vox.PadBVTotal);
                                    }
                                }
                            }
                        }
                    }
                }

                long l = 4294967295L;

                try {
                    //on crit la moyenne
                    for (int i = 0; i < rasterXSize; i++) {
                        for (int j = rasterYSize - 1, j2 = 0; j >= 0; j--, j2++) {
                            for (int k = 0; k < altitudes.length; k++) {

                                if (padMean[i][j][k] != null) {

                                    double meanPAD = padMean[i][j][k].getMean();
                                    //float value = (meanOfPAD-0)/(MAX_PAD-0);

                                    long value = (long) ((meanPAD / (double) infos.getMaxPAD()) * (l));
                                    String binaryString = Long.toBinaryString(value);
                                    byte[] bval = new BigInteger(binaryString, 2).toByteArray();
                                    ArrayUtils.reverse(bval);
                                    byte b0 = 0x0, b1 = 0x0, b2 = 0x0, b3 = 0x0;
                                    if (bval.length > 0) {
                                        b0 = bval[0];
                                    }
                                    if (bval.length > 1) {
                                        b1 = bval[1];
                                    }
                                    if (bval.length > 2) {
                                        b2 = bval[2];
                                    }
                                    if (bval.length > 3) {
                                        b3 = bval[3];
                                    }
                                    raster.setPixel(i, j2, k, b0, b1, b2, b3);

                                }
                            }
                        }
                    }

                } catch (Exception ex) {
                    LOGGER.error(ex);
                }
            }

        }

        return raster;
    }

    public static void writeRaster(File outputFile, BSQ raster) throws IOException {

        raster.setOutputFile(outputFile);

        raster.writeImage();
        raster.writeHeader();
    }
}