All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openstreetmap.atlas.checks.maproulette.data.Task Maven / Gradle / Ivy

package org.openstreetmap.atlas.checks.maproulette.data;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.codec.binary.StringUtils;
import org.openstreetmap.atlas.exception.CoreException;
import org.openstreetmap.atlas.geography.Location;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

/**
 * A task is a single unit of work in the MapRoulette Challenge
 *
 * @author cuthbertm
 * @author mgostintsev
 */
public class Task
{
    /**
     * A class holding a point and some description for that point
     */
    private class PointInformation
    {
        private final Location location;
        private final Optional description;

        PointInformation(final Location location, final Optional description)
        {
            this.location = location;
            this.description = description;
        }

        public Location getLocation()
        {
            return location;
        }

        public Optional getDescription()
        {
            return description;
        }
    }

    protected static final String FEATURE = "Feature";
    protected static final String POINT = "Point";
    protected static final String TASK_FEATURES = "features";
    protected static final String TASK_FEATURE_COORDINATES = "coordinates";
    protected static final String TASK_FEATURE_GEOMETRY = "geometry";
    protected static final String TASK_FEATURE_PROPERTIES = "properties";
    protected static final String TASK_GEOMETRIES = "geometries";
    protected static final String TASK_INSTRUCTION = "instruction";
    protected static final String TASK_NAME = "name";
    protected static final String TASK_PARENT_ID = "parent";
    protected static final String TASK_TYPE = "type";
    private static final String KEY_DESCRIPTION = "description";
    private String challengeName;
    private Optional geoJson = Optional.empty();
    private String instruction;
    private final Set points = new HashSet<>();
    private String projectName = "";
    private String taskIdentifier;

    public Task()
    {

    }

    /**
     * What defines a task as unique is its task identifier and its challenge name. So even if the
     * geometry or description or other member variables are different, it will be defined as equal
     * if those two values are equal
     *
     * @param obj
     *            The object to compare it against
     * @return whether it matches the supplied object
     */
    @Override
    public boolean equals(final Object obj)
    {
        return obj instanceof Task
                && StringUtils.equals(this.taskIdentifier, ((Task) obj).getTaskIdentifier())
                && StringUtils.equals(this.challengeName, ((Task) obj).getChallengeName());
    }

    public JsonObject generateTask(final long parentIdentifier)
    {
        final JsonObject task = new JsonObject();
        final JsonObject result = new JsonObject();
        result.addProperty(TASK_TYPE, "FeatureCollection");
        result.add(TASK_FEATURES, generateTaskFeatures(this.points, this.geoJson));
        task.add(TASK_INSTRUCTION, new JsonPrimitive(this.instruction));
        task.add(TASK_NAME, new JsonPrimitive(getTaskIdentifier()));
        task.add(TASK_PARENT_ID, new JsonPrimitive(parentIdentifier));
        task.add(TASK_GEOMETRIES, result);
        return task;
    }

    public String getChallengeName()
    {
        return this.challengeName;
    }

    public Optional getGeoJson()
    {
        return this.geoJson;
    }

    public String getInstruction()
    {
        return this.instruction;
    }

    public Set getPoints()
    {
        return this.points.parallelStream().map(PointInformation::getLocation)
                .collect(Collectors.toSet());
    }

    public String getProjectName()
    {
        return projectName;
    }

    public String getTaskIdentifier()
    {
        return this.taskIdentifier;
    }

    @Override
    public int hashCode()
    {
        return this.taskIdentifier.hashCode() + this.challengeName.hashCode();
    }

    public void setChallengeName(final String challengeName)
    {
        this.challengeName = challengeName;
    }

    public void setGeoJson(final Optional geoJson)
    {
        this.geoJson = geoJson;
    }

    public void setInstruction(final String instruction)
    {
        this.instruction = instruction;
    }

    public void setPoint(final Location point)
    {
        this.points.add(new PointInformation(point, Optional.empty()));
    }

    public void addPoint(final Location point, final String description)
    {
        this.points.add(new PointInformation(point, Optional.ofNullable(description)));
    }

    public void setPoints(final Set points)
    {
        this.points.addAll(
                points.parallelStream().map(point -> new PointInformation(point, Optional.empty()))
                        .collect(Collectors.toSet()));
    }

    public void setProjectName(final String projectName)
    {
        this.projectName = projectName;
    }

    public void setTaskIdentifier(final String taskIdentifier)
    {
        this.taskIdentifier = taskIdentifier;
    }

    protected JsonArray generateTaskFeatures(final Set source,
            final Optional geoJson)
    {
        final JsonArray features = new JsonArray();
        if (source.isEmpty() && !geoJson.isPresent())
        {
            throw new CoreException("Could not find any features for the task [{}].",
                    this.toString());
        }
        source.forEach(point ->
        {
            final JsonObject feature = new JsonObject();
            final JsonObject geometry = new JsonObject();
            final JsonArray coordinates = new JsonArray();
            coordinates.add(new JsonPrimitive(point.getLocation().getLongitude().asDegrees()));
            coordinates.add(new JsonPrimitive(point.getLocation().getLatitude().asDegrees()));
            geometry.add(TASK_TYPE, new JsonPrimitive(POINT));
            geometry.add(TASK_FEATURE_COORDINATES, coordinates);
            feature.add(TASK_FEATURE_GEOMETRY, geometry);
            feature.add(TASK_TYPE, new JsonPrimitive(FEATURE));
            final JsonObject pointInformation = new JsonObject();
            point.getDescription().ifPresent(description -> pointInformation.add(KEY_DESCRIPTION,
                    new JsonPrimitive(description)));
            feature.add(TASK_FEATURE_PROPERTIES, pointInformation);
            features.add(feature);
        });

        geoJson.ifPresent(json -> json.forEach(features::add));

        return features;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy