Package org.openstreetmap.josm.plugins.continuosDownload

Source Code of org.openstreetmap.josm.plugins.continuosDownload.DownloadStrategy

package org.openstreetmap.josm.plugins.continuosDownload;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.Future;

import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask;
import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.gui.layer.GpxLayer;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
import org.openstreetmap.josm.gui.progress.ProgressMonitor;

public abstract class DownloadStrategy {

    public void fetch(Bounds bbox) {
        this.fetch(bbox, OsmDataLayer.class);
        this.fetch(bbox, GpxLayer.class);
    }

    public void fetch(Bounds bbox, Class<?> klass) {
        Bounds extendedBox = extend(bbox, Main.pref.getDouble("plugin.continuos_download.extra_download", 0.1));
        Collection<Bounds> existing = getExisting(klass);
        if (existing.size() == 0)
            return;
        Collection<Bounds> toFetch = getBoxes(extendedBox, existing,
                Main.pref.getInteger("plugin.continuos_download.max_areas", 4));

        printDebug(extendedBox, toFetch);

        // Try to avoid downloading areas outside the view area unnecessary
        Collection<Bounds> t = toFetch;
        toFetch = new ArrayList<Bounds>(t.size());
        for (Bounds box : t) {
            if (box.intersects(bbox)) {
                toFetch.add(box);
            }
        }

        download(toFetch, klass);
    }

    private void printDebug(Bounds bbox, Collection<Bounds> toFetch) {
        double areaToDownload = 0;
        for (Bounds box : toFetch) {
            areaToDownload += box.getArea();
        }

        double areaDownloaded = 0;
        for (Bounds box : getExisting(OsmDataLayer.class)) {
            if (box.intersects(bbox))
                areaDownloaded += intersection(box, bbox).getArea();
        }

        double downloadP = (areaToDownload * 100) / (bbox.getArea());
        double downloadedP = (areaDownloaded * 100) / (bbox.getArea());

        System.out.printf("Getting %.1f%% of area, already have %.1f%%, overlap %.1f%%%n", downloadP, downloadedP,
                downloadP + downloadedP - 100);
    }

    private Bounds intersection(Bounds box1, Bounds box2) {
        double minX1 = box1.getMin().getX();
        double maxX1 = box1.getMax().getX();
        double minY1 = box1.getMin().getY();
        double maxY1 = box1.getMax().getY();

        double minX2 = box2.getMin().getX();
        double maxX2 = box2.getMax().getX();
        double minY2 = box2.getMin().getY();
        double maxY2 = box2.getMax().getY();

        double minX = Math.max(minX1, minX2);
        double maxX = Math.min(maxX1, maxX2);
        double minY = Math.max(minY1, minY2);
        double maxY = Math.min(maxY1, maxY2);

        return new Bounds(minY, minX, maxY, maxX);
    }

    private Collection<Bounds> getExisting(Class<?> klass) {
        if (klass.isAssignableFrom(OsmDataLayer.class)) {
            OsmDataLayer layer = Main.map.mapView.getEditLayer();
            if (layer == null) {
                Collection<Layer> layers = Main.map.mapView.getAllLayersAsList();
                for (Layer layer1 : layers) {
                    if (layer1 instanceof OsmDataLayer)
                        return ((OsmDataLayer) layer1).data.getDataSourceBounds();
                }
                return Collections.emptyList();
            } else {
                return layer.data.getDataSourceBounds();
            }
        } else if (klass.isAssignableFrom(GpxLayer.class)) {
            if (!Main.isDisplayingMapView())
                return null;
            boolean merge = Main.pref.getBoolean("download.gps.mergeWithLocal", false);
            Layer active = Main.map.mapView.getActiveLayer();
            if (active instanceof GpxLayer && (merge || ((GpxLayer) active).data.fromServer))
                return ((GpxLayer) active).data.getDataSourceBounds();
            for (GpxLayer l : Main.map.mapView.getLayersOfType(GpxLayer.class)) {
                if (merge || l.data.fromServer)
                    return l.data.getDataSourceBounds();
            }
            return Collections.emptyList();
        } else {
            throw new IllegalArgumentException();
        }
    }

    public abstract Collection<Bounds> getBoxes(Bounds bbox, Collection<Bounds> present, int maxAreas);

    private void download(Collection<Bounds> bboxes, Class<?> klass) {
        for (Bounds bbox : bboxes) {
            AbstractDownloadTask task = getDownloadTask(klass);
           
            ProgressMonitor monitor = null;
            if (Main.pref.getBoolean("plugin.continuos_download.quiet_download", false)) {
                monitor = NullProgressMonitor.INSTANCE;
            }

            Future<?> future = task.download(false, bbox, monitor);
            DownloadPlugin.worker.execute(new PostDownloadHandler(task, future));
        }
    }

    private AbstractDownloadTask getDownloadTask(Class<?> klass) {
        if (klass.isAssignableFrom(OsmDataLayer.class))
            return new DownloadOsmTask2();
        if (klass.isAssignableFrom(GpxLayer.class))
            return new DownloadGpsTask();
        throw new IllegalArgumentException();
    }

    static protected Bounds extend(Bounds bbox, double amount) {
        LatLon min = bbox.getMin();
        LatLon max = bbox.getMax();

        double dLat = Math.abs(max.lat() - min.lat()) * amount;
        double dLon = Math.abs(max.lon() - min.lon()) * amount;

        return new Bounds(min.lat() - dLat, min.lon() - dLon, max.lat() + dLat, max.lon() + dLon);
    }

}
TOP

Related Classes of org.openstreetmap.josm.plugins.continuosDownload.DownloadStrategy

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.