org.geogit.osm.map.internal.OSMMapOp.java Source code

Java tutorial

Introduction

Here is the source code for org.geogit.osm.map.internal.OSMMapOp.java

Source

/* Copyright (c) 2013 OpenPlans. All rights reserved.
 * This code is licensed under the BSD New License, available at the root
 * application directory.
 */
package org.geogit.osm.map.internal;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Iterator;
import java.util.List;

import javax.annotation.Nullable;

import org.geogit.api.AbstractGeoGitOp;
import org.geogit.api.NodeRef;
import org.geogit.api.ObjectId;
import org.geogit.api.RevFeature;
import org.geogit.api.RevFeatureType;
import org.geogit.api.RevTree;
import org.geogit.api.plumbing.LsTreeOp;
import org.geogit.api.plumbing.LsTreeOp.Strategy;
import org.geogit.api.plumbing.RevObjectParse;
import org.geogit.api.plumbing.RevParse;
import org.geogit.osm.base.OSMUtils;
import org.geogit.osm.in.internal.FeatureMapFlusher;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.opengis.feature.Feature;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.PropertyDescriptor;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;

/**
 * Creates new data in a geogit repository, based on the current OSM data in the repository and a
 * mapping that defines the schema to use for creating new features and the destination trees.
 * 
 * The source data used is the working tree data in the "node" and "way" trees.
 * 
 */
public class OSMMapOp extends AbstractGeoGitOp<RevTree> {

    /**
     * The mapping to use
     */
    private Mapping mapping;

    /**
     * Sets the mapping to use
     * 
     * @param mapping the mapping to use
     * @return {@code this}
     */
    public OSMMapOp setMapping(Mapping mapping) {
        this.mapping = mapping;
        return this;
    }

    @Override
    public RevTree call() {

        checkNotNull(mapping);

        Iterator<Feature> nodes;
        if (mapping.canUseNodes()) {
            nodes = getFeatures("WORK_HEAD:node");
        } else {
            nodes = Iterators.emptyIterator();
        }
        Iterator<Feature> ways;
        if (mapping.canUseWays()) {
            ways = getFeatures("WORK_HEAD:way");
        } else {
            ways = Iterators.emptyIterator();
        }
        Iterator<Feature> iterator = Iterators.concat(nodes, ways);

        FeatureMapFlusher insertsByParent = new FeatureMapFlusher(getWorkTree());
        while (iterator.hasNext()) {
            Feature feature = iterator.next();
            Optional<MappedFeature> newFeature = mapping.map(feature);
            if (newFeature.isPresent()) {
                String path = newFeature.get().getPath();
                SimpleFeature sf = (SimpleFeature) newFeature.get().getFeature();
                insertsByParent.put(path, sf);
            }
        }
        insertsByParent.flushAll();

        return getWorkTree().getTree();

    }

    private Iterator<Feature> getFeatures(String ref) {
        Optional<ObjectId> id = command(RevParse.class).setRefSpec(ref).call();
        if (!id.isPresent()) {
            return Iterators.emptyIterator();
        }
        LsTreeOp op = command(LsTreeOp.class).setStrategy(Strategy.DEPTHFIRST_ONLY_FEATURES).setReference(ref);

        Iterator<NodeRef> iterator = op.call();

        Function<NodeRef, Feature> function = new Function<NodeRef, Feature>() {

            @Override
            @Nullable
            public Feature apply(@Nullable NodeRef ref) {
                RevFeature revFeature = command(RevObjectParse.class).setObjectId(ref.objectId())
                        .call(RevFeature.class).get();
                SimpleFeatureType featureType;
                if (ref.path().startsWith(OSMUtils.NODE_TYPE_NAME)) {
                    featureType = OSMUtils.nodeType();
                } else {
                    featureType = OSMUtils.wayType();
                }
                SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
                RevFeatureType revFeatureType = RevFeatureType.build(featureType);
                List<PropertyDescriptor> descriptors = revFeatureType.sortedDescriptors();
                ImmutableList<Optional<Object>> values = revFeature.getValues();
                for (int i = 0; i < descriptors.size(); i++) {
                    PropertyDescriptor descriptor = descriptors.get(i);
                    Optional<Object> value = values.get(i);
                    featureBuilder.set(descriptor.getName(), value.orNull());
                }
                SimpleFeature feature = featureBuilder.buildFeature(ref.name());
                return feature;
            }

        };
        return Iterators.transform(iterator, function);
    }
}