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.out.cli; import static com.google.common.base.Preconditions.checkArgument; import java.io.File; import java.io.FileOutputStream; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; import org.geogit.api.Bounded; import org.geogit.api.GeoGIT; import org.geogit.api.NodeRef; import org.geogit.api.ObjectId; import org.geogit.api.RevFeature; import org.geogit.api.RevFeatureType; import org.geogit.api.plumbing.LsTreeOp; import org.geogit.api.plumbing.LsTreeOp.Strategy; import org.geogit.api.plumbing.ResolveTreeish; import org.geogit.api.plumbing.RevObjectParse; import org.geogit.api.plumbing.RevParse; import org.geogit.cli.AbstractCommand; import org.geogit.cli.CLICommand; import org.geogit.cli.GeogitCLI; import org.geogit.geotools.plumbing.ExportOp; import org.geogit.osm.base.EntityConverter; import org.geogit.osm.base.OSMUtils; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.PropertyDescriptor; import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer; import org.openstreetmap.osmosis.core.container.v0_6.WayContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; import org.openstreetmap.osmosis.core.domain.v0_6.Node; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.osmbinary.file.BlockOutputStream; import org.openstreetmap.osmosis.xml.common.CompressionMethod; import org.openstreetmap.osmosis.xml.v0_6.XmlWriter; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.vividsolutions.jts.geom.Envelope; import crosby.binary.osmosis.OsmosisSerializer; /** * Exports features from a feature type into a shapefile. * * @see ExportOp */ @Parameters(commandNames = "export", commandDescription = "Export to OSM format") public class OSMExport extends AbstractCommand implements CLICommand { @Parameter(description = "<file> [commitish]") public List<String> args; @Parameter(names = { "--overwrite", "-o" }, description = "Overwrite output file") public boolean overwrite; @Parameter(names = { "--bbox", "-b" }, description = "The bounding box to use as filter (S W N E).", arity = 4) private List<String> bbox; private GeoGIT geogit; /** * Executes the export command using the provided options. * * @param cli */ @Override protected void runInternal(GeogitCLI cli) throws Exception { if (cli.getGeogit() == null) { cli.getConsole().println("Not a geogit repository: " + cli.getPlatform().pwd()); return; } if (args.size() < 1 || args.size() > 2) { printUsage(); return; } checkArgument(bbox == null || bbox.size() == 4, "The specified bounding box is not correct"); geogit = cli.getGeogit(); String osmfile = args.get(0); String ref = "WORK_HEAD"; if (args.size() == 2) { ref = args.get(1); Optional<ObjectId> tree = geogit.command(ResolveTreeish.class).setTreeish(ref).call(); Preconditions.checkArgument(tree.isPresent(), "Invalid commit or reference: %s", ref); } File file = new File(osmfile); checkArgument(!file.exists() || overwrite, "The selected file already exists. Use -o to overwrite"); Iterator<EntityContainer> nodes = getFeatures(ref + ":node"); Iterator<EntityContainer> ways = getFeatures(ref + ":way"); Iterator<EntityContainer> iterator = Iterators.concat(nodes, ways); if (file.getName().endsWith(".pbf")) { BlockOutputStream output = new BlockOutputStream(new FileOutputStream(file)); OsmosisSerializer serializer = new OsmosisSerializer(output); while (iterator.hasNext()) { EntityContainer entity = iterator.next(); serializer.process(entity); } serializer.complete(); } else { XmlWriter writer = new XmlWriter(file, CompressionMethod.None); while (iterator.hasNext()) { EntityContainer entity = iterator.next(); writer.process(entity); } writer.complete(); } } private Iterator<EntityContainer> getFeatures(String ref) { Optional<ObjectId> id = geogit.command(RevParse.class).setRefSpec(ref).call(); if (!id.isPresent()) { return Iterators.emptyIterator(); } LsTreeOp op = geogit.command(LsTreeOp.class).setStrategy(Strategy.DEPTHFIRST_ONLY_FEATURES) .setReference(ref); if (bbox != null) { final Envelope env; try { env = new Envelope(Double.parseDouble(bbox.get(0)), Double.parseDouble(bbox.get(2)), Double.parseDouble(bbox.get(1)), Double.parseDouble(bbox.get(3))); } catch (NumberFormatException e) { throw new IllegalArgumentException("Wrong bbox definition"); } Predicate<Bounded> filter = new Predicate<Bounded>() { @Override public boolean apply(final Bounded bounded) { boolean intersects = bounded.intersects(env); return intersects; } }; op.setBoundsFilter(filter); } Iterator<NodeRef> iterator = op.call(); final EntityConverter converter = new EntityConverter(); Function<NodeRef, EntityContainer> function = new Function<NodeRef, EntityContainer>() { @Override @Nullable public EntityContainer apply(@Nullable NodeRef ref) { RevFeature revFeature = geogit.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()); Entity entity = converter.toEntity(feature); EntityContainer container; if (entity instanceof Node) { container = new NodeContainer((Node) entity); } else { container = new WayContainer((Way) entity); } return container; } }; return Iterators.transform(iterator, function); } }