/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2015, Open Source Geospatial Foundation (OSGeo)
* (C) 2014-2015, Boundless
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.mongodb;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiPolygon;
/**
*
* @author tkunicki@boundlessgeo.com
*/
public class FeatureTypeDBObjectTest {
public FeatureTypeDBObjectTest() {
}
@Test
public void testRoundTripConversion() throws FileNotFoundException, IOException, FactoryException {
SimpleFeatureType original = buildDummyFeatureType("dummy");
DBObject dbo = FeatureTypeDBObject.convert(original);
// make sure we're dealing with proper BSON/JSON by round-tripping it
// through serialization...
StringBuilder jsonBuffer = new StringBuilder();
JSON.serialize(dbo, jsonBuffer);
String json = jsonBuffer.toString();
Object o = JSON.parse(json);
assertThat(o, is(instanceOf(DBObject.class)));
dbo = (DBObject)o;
SimpleFeatureType result = FeatureTypeDBObject.convert(dbo);
compareFeatureTypes(original, result, false);
}
@Test
public void crsFromGeoJSON() {
DBObject crsDBO = FeatureTypeDBObject.encodeCRSToGeoJSON(DefaultGeographicCRS.WGS84);
CoordinateReferenceSystem result = FeatureTypeDBObject.decodeCRSFromGeoJSON(crsDBO);
assertTrue(CRS.equalsIgnoreMetadata(DefaultGeographicCRS.WGS84, result));
}
static SimpleFeatureType buildDummyFeatureType(String typeName) throws FactoryException {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(typeName);
builder.userData("mapping", "geometry");
builder.userData("encoding", "GeoJSON");
builder.add("geometry", MultiPolygon.class, CRS.decode("EPSG:4269", true));
builder.userData("mapping", "child.prop1");
builder.add("propString", String.class);
builder.userData("mapping", "child.prop2");
builder.add("propBoolean", Boolean.class);
builder.userData("mapping", "child.prop3");
builder.add("propFloat", Float.class);
builder.userData("mapping", "child.prop4");
builder.add("propDouble", Double.class);
builder.userData("mapping", "child.prop5");
builder.add("propByte", Byte.class);
builder.userData("mapping", "child.prop6");
builder.add("propShort", Short.class);
builder.userData("mapping", "child.prop7");
builder.add("propInteger", Integer.class);
builder.userData("mapping", "child.prop8");
builder.add("propLong", Long.class);
builder.userData("mapping", "child.prop9");
builder.add("propDate", Date.class);
SimpleFeatureType original = builder.buildFeatureType();
original.getUserData().put("sample-key", "sample-value");
return original;
}
static void compareFeatureTypes(SimpleFeatureType left, SimpleFeatureType right, boolean strictGeometryClass) {
assertThat(right.getTypeName(), is(equalTo(left.getTypeName())));
// verify feature type user data persisted
Map<?,?> resultUserData = right.getUserData();
Map<?,?> originalUserData = left.getUserData();
assertThat(resultUserData.size(), is(equalTo(originalUserData.size())));
for (Map.Entry entry : resultUserData.entrySet()) {
assertThat(entry.getValue(), (Matcher)is(equalTo(originalUserData.get(entry.getKey()))));
}
// verify we persist and restore same number of attributes
assertThat(right.getAttributeCount(), is(equalTo(left.getAttributeCount())));
// verify we persist and restore geometry name
String rgdName = right.getGeometryDescriptor().getLocalName();
assertThat(rgdName, is(equalTo(left.getGeometryDescriptor().getLocalName())));
// verify we persist and restore CRS (this should always be WGS84 in the wild)
assertTrue("CRS are equal", CRS.equalsIgnoreMetadata(right.getCoordinateReferenceSystem(), left.getCoordinateReferenceSystem()));
if (strictGeometryClass) {
assertThat(right.getGeometryDescriptor().getType().getBinding().getSimpleName(),
is(equalTo(left.getGeometryDescriptor().getType().getBinding().getSimpleName())));
} else {
// NOTE! Geometry type is generalized when persisted...
assertThat(Geometry.class.isAssignableFrom(right.getGeometryDescriptor().getType().getBinding()), is(equalTo(true)));
assertThat(Geometry.class.isAssignableFrom(left.getGeometryDescriptor().getType().getBinding()), is(equalTo(true)));
}
for (AttributeDescriptor rad: right.getAttributeDescriptors()) {
String radName = rad.getLocalName();
AttributeDescriptor oad = left.getDescriptor(radName);
assertThat(rad.getMinOccurs(), is(equalTo(oad.getMinOccurs())));
assertThat(rad.getMaxOccurs(), is(equalTo(oad.getMaxOccurs())));
assertThat(rad.getDefaultValue(), is(equalTo(oad.getDefaultValue())));
if (!radName.equals(rgdName)) {
assertThat(rad.getType().getBinding().getSimpleName(), is(equalTo(oad.getType().getBinding().getSimpleName())));
}
Map<?,?> radUserData = rad.getUserData();
Map<?,?> oadUserData = oad.getUserData();
assertThat(radUserData.size(), is(equalTo(oadUserData.size())));
for (Map.Entry entry : radUserData.entrySet()) {
assertThat(entry.getValue(), (Matcher)is(equalTo(oadUserData.get(entry.getKey()))));
}
}
}
}