/* Copyright (c) 2013-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Victor Olaya (Boundless) - initial implementation
*/
package org.locationtech.geogig.osm.internal;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.plumbing.ResolveFeatureType;
import org.locationtech.geogig.api.plumbing.RevObjectParse;
import org.locationtech.geogig.api.porcelain.AddOp;
import org.locationtech.geogig.api.porcelain.CommitOp;
import org.locationtech.geogig.storage.FieldType;
import org.locationtech.geogig.test.integration.RepositoryTestCase;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
public class OSMHookTest extends RepositoryTestCase {
@Rule
public ExpectedException exception = ExpectedException.none();
@Override
protected void setUpInternal() throws Exception {
repo.configDatabase().put("user.name", "groldan");
repo.configDatabase().put("user.email", "groldan@boundlessgeo.com");
}
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void testOSMHook() throws Exception {
// set the hook that will trigger an unmapping when something is imported to the busstops
// tree
CharSequence commitPreHookCode = "var diffs = geogig.getFeaturesToCommit(\"busstops\", false);\n"
+ "if (diffs.length > 0){\n"
+ "\tvar params = {\"path\" : \"busstops\"};\n"
+ "\tgeogig.run(\"org.locationtech.geogig.osm.internal.OSMUnmapOp\", params)\n}";
File hooksFolder = new File(geogig.getPlatform().pwd(), ".geogig/hooks");
File commitPreHookFile = new File(hooksFolder, "pre_commit.js");
Files.write(commitPreHookCode, commitPreHookFile, Charsets.UTF_8);
// Import
String filename = OSMImportOp.class.getResource("nodes.xml").getFile();
File file = new File(filename);
geogig.command(OSMImportOp.class).setDataSource(file.getAbsolutePath()).call();
// Map
Map<String, AttributeDefinition> fields = Maps.newHashMap();
Map<String, List<String>> mappings = Maps.newHashMap();
mappings.put("highway", Lists.newArrayList("bus_stop"));
fields.put("geom", new AttributeDefinition("geom", FieldType.POINT));
fields.put("name", new AttributeDefinition("name", FieldType.STRING));
MappingRule mappingRule = new MappingRule("busstops", mappings, null, fields, null);
List<MappingRule> mappingRules = Lists.newArrayList();
mappingRules.add(mappingRule);
Mapping mapping = new Mapping(mappingRules);
geogig.command(AddOp.class).call();
geogig.command(CommitOp.class).setMessage("msg").call();
geogig.command(OSMMapOp.class).setMapping(mapping).call();
Optional<RevFeature> revFeature = geogig.command(RevObjectParse.class)
.setRefSpec("HEAD:busstops/507464799").call(RevFeature.class);
assertTrue(revFeature.isPresent());
Optional<RevFeatureType> featureType = geogig.command(ResolveFeatureType.class)
.setRefSpec("HEAD:busstops/507464799").call();
assertTrue(featureType.isPresent());
ImmutableList<Optional<Object>> values = revFeature.get().getValues();
assertEquals(3, values.size());
String wkt = "POINT (7.1959361 50.739397)";
assertEquals(wkt, values.get(2).get().toString());
assertEquals(507464799l, values.get(0).get());
// Modify a node
GeometryFactory gf = new GeometryFactory();
SimpleFeatureBuilder fb = new SimpleFeatureBuilder((SimpleFeatureType) featureType.get()
.type());
fb.set("geom", gf.createPoint(new Coordinate(0, 1)));
fb.set("name", "newname");
fb.set("id", 507464799l);
SimpleFeature newFeature = fb.buildFeature("507464799");
geogig.getRepository().workingTree().insert("busstops", newFeature);
geogig.command(AddOp.class).call();
geogig.command(CommitOp.class).setMessage("msg").call(); // this should trigger the hook
// check that the unmapping has been triggered and the unmapped node has the changes we
// introduced
Optional<RevFeature> unmapped = geogig.command(RevObjectParse.class)
.setRefSpec("WORK_HEAD:node/507464799").call(RevFeature.class);
assertTrue(unmapped.isPresent());
values = unmapped.get().getValues();
assertEquals("POINT (0 1)", values.get(6).get().toString());
assertEquals(
"bus:yes|public_transport:platform|highway:bus_stop|VRS:ortsteil:Hoholz|name:newname|VRS:ref:68566|VRS:gemeinde:BONN",
values.get(3).get().toString());
// check that unchanged nodes keep their attributes
Optional<RevFeature> unchanged = geogig.command(RevObjectParse.class)
.setRefSpec("WORK_HEAD:node/1633594723").call(RevFeature.class);
values = unchanged.get().getValues();
assertEquals("14220478", values.get(4).get().toString());
assertEquals("1355097351000", values.get(2).get().toString());
assertEquals("2", values.get(1).get().toString());
}
}