3

I am using following code to display geotiff file. Its only a small file 1,5MB but when I am moving map I have online white screen which gets loaded after I finish moving but it is a bit slow for me. I am scared how slow will it be with 1,2GB map. So is there a way to make this faster or to render map just as it is showed (not wait until user finishes moving)

Here is the code:

public class App
{
    private StyleFactory sf = CommonFactoryFinder.getStyleFactory();
    private FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
    private GridCoverage2DReader reader;

    private JMapFrame frame;
    public static void main( String[] args )
    {
        App me = new App();
        try {
            me.showMap();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public void showMap() throws IOException {
        File rasterFile = new File("C:/Users/Daniel/Desktop/release-1800-x64-gdal-1-11-1-mapserver-6-4-1/out.tif");
        AbstractGridFormat format = GridFormatFinder.findFormat(rasterFile);
        reader = format.getReader(rasterFile);

        Style rasterStyle = createRGBStyle();
        Layer rasterLayer = new GridReaderLayer(reader, rasterStyle);

        final MapContent map = new MapContent();
        map.setTitle("ImageLab");
        map.addLayer(rasterLayer);

        frame = new JMapFrame(map);
        frame.setSize(800, 600);
        frame.enableStatusBar(true);

        frame.enableToolBar(true);

        frame.setVisible(true);
    }
    public Style createRGBStyle() {
        GridCoverage2D cov = null;
        try {
            cov = reader.read(null);
        } catch (IOException giveUp) {
            throw new RuntimeException(giveUp);
        }
        // We need at least three bands to create an RGB style
        int numBands = cov.getNumSampleDimensions();
        if (numBands < 3) {
            return null;
        }
        // Get the names of the bands
        String[] sampleDimensionNames = new String[numBands];
        for (int i = 0; i < numBands; i++) {
            GridSampleDimension dim = cov.getSampleDimension(i);
            sampleDimensionNames[i] = dim.getDescription().toString();
        }
        final int RED = 0, GREEN = 1, BLUE = 2;
        int[] channelNum = { -1, -1, -1 };
        // We examine the band names looking for "red...", "green...", "blue...".
        // Note that the channel numbers we record are indexed from 1, not 0.
        for (int i = 0; i < numBands; i++) {
            String name = sampleDimensionNames[i].toLowerCase();
            if (name != null) {
                if (name.matches("red.*")) {
                    channelNum[RED] = i + 1;
                } else if (name.matches("green.*")) {
                    channelNum[GREEN] = i + 1;
                } else if (name.matches("blue.*")) {
                    channelNum[BLUE] = i + 1;
                }
            }
        }
        // If we didn't find named bands "red...", "green...", "blue..."
        // we fall back to using the first three bands in order
        if (channelNum[RED] < 0 || channelNum[GREEN] < 0 || channelNum[BLUE] < 0) {
            channelNum[RED] = 1;
            channelNum[GREEN] = 2;
            channelNum[BLUE] = 3;
        }
        // Now we create a RasterSymbolizer using the selected channels
        SelectedChannelType[] sct = new SelectedChannelType[cov.getNumSampleDimensions()];
        ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NORMALIZE);
        for (int i = 0; i < 3; i++) {
            sct[i] = sf.createSelectedChannelType(String.valueOf(channelNum[i]), ce);
        }
        RasterSymbolizer sym = sf.getDefaultRasterSymbolizer();
        ChannelSelection sel = sf.channelSelection(sct[RED], sct[GREEN], sct[BLUE]);
        sym.setChannelSelection(sel);

        return SLD.wrapSymbolizers(sym);
    }

}
2

This could be related to any number of factors, such as RAM, CPU etc on your machine. But the most likely is that your GeoTiff isn't optimised for speed. Have you added overviews? is your image tiled or does GeoTools have to read the whole image each time to draw a small subset.

I recommend you read the excellent GeoServer on Steroids talk from GeoSolutions which while aimed at GeoServer users is in fact an example of how to read rasters quickly using GeoTools.

  • well I have created geotiff by using gdal_translate and converted it from png + world file – horin Apr 28 '15 at 8:15
  • Make a GeoServer layer from your GeoTIFF for having something to compare with. If is is faster in the layer preview then you have something to optimize in your code. If you want to avoid white splash during panning then perhaps you could buffer the previous image ans show that until the new one is ready? – user30184 Apr 28 '15 at 8:45
  • as far as I can understand from presentation I need to prepare multiple geotiffs use image mosaic and put the in image pyramid to achieve fastest speed ... this is a bit hard task for me – horin Apr 28 '15 at 9:27
  • 1
    for a small(ish) GeoTiff (<4Gb) then internal tiles and overviews should be enough. – Ian Turton Apr 28 '15 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.