Java tutorial
/* 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); } }