/*******************************************************************************
* Copyright (c) 2015 Voyager Search and MITRE
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License, Version 2.0 which
* accompanies this distribution and is available at
* http://www.apache.org/licenses/LICENSE-2.0.txt
******************************************************************************/
package org.locationtech.spatial4j.context;
import org.locationtech.spatial4j.context.jts.DatelineRule;
import org.locationtech.spatial4j.context.jts.JtsSpatialContext;
import org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory;
import org.locationtech.spatial4j.context.jts.ValidationRule;
import org.locationtech.spatial4j.distance.CartesianDistCalc;
import org.locationtech.spatial4j.distance.GeodesicSphereDistCalc;
import org.locationtech.spatial4j.io.ShapeIO;
import org.locationtech.spatial4j.io.WKTReader;
import org.locationtech.spatial4j.shape.impl.RectangleImpl;
import org.junit.After;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SpatialContextFactoryTest {
public static final String PROP = "SpatialContextFactory";
@After
public void tearDown() {
System.getProperties().remove(PROP);
}
private SpatialContext call(String... argsStr) {
Map<String,String> args = new HashMap<String,String>();
for (int i = 0; i < argsStr.length; i+=2) {
String key = argsStr[i];
String val = argsStr[i+1];
args.put(key,val);
}
return SpatialContextFactory.makeSpatialContext(args, getClass().getClassLoader());
}
@Test
public void testDefault() {
SpatialContext ctx = SpatialContext.GEO;
SpatialContext ctx2 = call();//default
assertEquals(ctx.getClass(), ctx2.getClass());
assertEquals(ctx.isGeo(), ctx2.isGeo());
assertEquals(ctx.getDistCalc(),ctx2.getDistCalc());
assertEquals(ctx.getWorldBounds(), ctx2.getWorldBounds());
}
@Test
public void testCustom() {
SpatialContext ctx = call("geo","false");
assertTrue(!ctx.isGeo());
assertEquals(new CartesianDistCalc(), ctx.getDistCalc());
ctx = call("geo","false",
"distCalculator","cartesian^2",
"worldBounds","ENVELOPE(-100, 75, 200, 0)");//xMin, xMax, yMax, yMin
assertEquals(new CartesianDistCalc(true),ctx.getDistCalc());
assertEquals(new RectangleImpl(-100, 75, 0, 200, ctx), ctx.getWorldBounds());
ctx = call("geo","true",
"distCalculator","lawOfCosines");
assertTrue(ctx.isGeo());
assertEquals(new GeodesicSphereDistCalc.LawOfCosines(),
ctx.getDistCalc());
}
@Test
public void testJtsContextFactory() {
JtsSpatialContext ctx = (JtsSpatialContext) call(
"spatialContextFactory", JtsSpatialContextFactory.class.getName(),
"geo", "true",
"normWrapLongitude", "true",
"precisionScale", "2.0",
"wktShapeParserClass", CustomWktShapeParser.class.getName(),
"datelineRule", "ccwRect",
"validationRule", "repairConvexHull",
"autoIndex", "true");
assertTrue(ctx.isNormWrapLongitude());
assertEquals(2.0, ctx.getGeometryFactory().getPrecisionModel().getScale(), 0.0);
assertTrue(CustomWktShapeParser.once);//cheap way to test it was created
assertEquals(DatelineRule.ccwRect,
ctx.getDatelineRule());
assertEquals(ValidationRule.repairConvexHull,
ctx.getValidationRule());
//ensure geo=false with worldbounds works -- fixes #72
ctx = (JtsSpatialContext) call(
"spatialContextFactory", JtsSpatialContextFactory.class.getName(),
"geo", "false",//set to false
"worldBounds", "ENVELOPE(-500,500,300,-300)",
"normWrapLongitude", "true",
"precisionScale", "2.0",
"wktShapeParserClass", CustomWktShapeParser.class.getName(),
"datelineRule", "ccwRect",
"validationRule", "repairConvexHull",
"autoIndex", "true");
assertEquals(300, ctx.getWorldBounds().getMaxY(), 0.0);
}
@Test
public void testFormatsConfig() {
JtsSpatialContext ctx = (JtsSpatialContext) call(
"spatialContextFactory", JtsSpatialContextFactory.class.getName(),
"readers", CustomWktShapeParser.class.getName());
assertTrue( ctx.getFormats().getReader(ShapeIO.WKT) instanceof CustomWktShapeParser );
}
@Test
public void testSystemPropertyLookup() {
System.setProperty(PROP,DSCF.class.getName());
assertTrue(!call().isGeo());//DSCF returns this
}
public static class DSCF extends SpatialContextFactory {
@Override
public SpatialContext newSpatialContext() {
geo = false;
return new SpatialContext(this);
}
}
public static class CustomWktShapeParser extends WKTReader {
static boolean once = false;//cheap way to test it was created
public CustomWktShapeParser(JtsSpatialContext ctx, JtsSpatialContextFactory factory) {
super(ctx, factory);
once = true;
}
}
}