Package org.codemap.tasks

Source Code of org.codemap.tasks.ComputeLabelingTask$LayoutAlgorithm

package org.codemap.tasks;

import java.util.ArrayList;
import java.util.Collection;

import org.codemap.CodemapCore;
import org.codemap.DefaultLabelScheme;
import org.codemap.Labeling;
import org.codemap.Location;
import org.codemap.MapInstance;
import org.codemap.layers.Label;
import org.codemap.layers.LabelOverlay;
import org.codemap.util.MapScheme;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

import ch.akuhn.util.Get;
import ch.akuhn.util.ProgressMonitor;
import ch.akuhn.values.Arguments;
import ch.akuhn.values.TaskValue;
import ch.akuhn.values.Value;

public class ComputeLabelingTask extends TaskValue<Labeling> {

    public ComputeLabelingTask(Value<MapInstance> mapInstance, Value<MapScheme<String>> labelScheme) {
        super("Label layout", mapInstance, labelScheme);
    }

    @Override
    protected Labeling computeValue(ProgressMonitor monitor, Arguments arguments) {
        MapInstance mapInstance = arguments.nextOrFail();
        MapScheme<String> labelScheme = arguments.nextOrFail();
        if (labelScheme == null) labelScheme = new DefaultLabelScheme();
        return computeValue(monitor, mapInstance, labelScheme);
    }

    private Labeling computeValue(ProgressMonitor monitor, MapInstance mapInstance, MapScheme<String> labelScheme) {
        Device device = Display.getDefault();
        Image image = new Image(device, 8, 8); // to get a GC
        GC gc = new GC(image);
        Iterable<Label> labels = makeLabels(monitor, gc, mapInstance, labelScheme);
        labels = new LayoutAlgorithm().layout(labels);
        gc.dispose();
        image.dispose();
        return new Labeling(labels);
    }

    private Iterable<Label> makeLabels(ProgressMonitor monitor, GC gc, MapInstance map, MapScheme<String> labelScheme) {
        Collection<Label> labels = new ArrayList<Label>();
        Font basefont = new Font(gc.getDevice(), LabelOverlay.ARIAL_NARROW, 12, SWT.NORMAL);
        for (Location each: map.locations()) {
            String text = labelScheme.forLocation(each.getPoint());
            if (text == null) continue;
            FontData[] fontData = basefont.getFontData();
            int height = (int) (Math.sqrt(each.getElevation()) * CodemapCore.colorScheme().getLabelHeightFactor());
            for (FontData fd: fontData) fd.setHeight(height);
            Font font = new Font(gc.getDevice(), fontData);
            gc.setFont(font);
            Point extent = gc.stringExtent(text);
            labels.add(new Label(each.px, each.py, extent, height, text, each));
            font.dispose();
        }
        basefont.dispose();
        return labels;
    }

    private class LayoutAlgorithm {

        Collection<Label> layout;

        public Iterable<Label> layout(Iterable<Label> labels) {
            layout = new ArrayList<Label>();
            for (Label each: Get.sorted(labels)) mayebAddToLayout(each);
            return layout;
        }

        private void mayebAddToLayout(Label label) {
            for (double[] each: ORIENTATION) {
                label.changeOrientation(each[0], each[1]);
                if (intersectsLabels(label)) continue;
                layout.add(label);
                return;
            }
        }

        private boolean intersectsLabels(Label label) {
            for (Label each: layout) if (label.intersects(each)) return true;
            return false;
        }
    }

    private static final double[][] ORIENTATION = new double[][] {
        {-.5d,-1d}, // north
        {-.5d,-.5d}, // center
        {-.5d,0d}, // south
        {-.25d,-1d},
        {-.25d,-.5d},
        {-.25d,0d},
        {-.75d,-1d},
        {-.75d,-.5d},
        {-.75d,0d},
        {0d,-.5d},
        {-1d,-.5d}};
}
TOP

Related Classes of org.codemap.tasks.ComputeLabelingTask$LayoutAlgorithm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.