Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -111,7 +112,7 @@ public static void main(String[] args) {
if (verbose) {
System.out.println("Handling collection " + id);
}
parser.readCollection(path, sourcesByType, id);
parser.readCollection(path, sourcesByType, id, Collections.emptyList());
} catch (Exception e) {
System.err.println("ERROR: " + e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import fi.nls.hakunapi.core.filter.Filter;
import fi.nls.hakunapi.core.param.GetFeatureParam;
Expand Down Expand Up @@ -57,4 +58,6 @@ public default CacheSettings getCacheSettings() {
return null;
}

public Optional<SRIDCode> getSrid(int srid);

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import fi.nls.hakunapi.core.filter.Filter;
import fi.nls.hakunapi.core.geom.HakunaGeometryDimension;
import fi.nls.hakunapi.core.param.GetFeatureParam;
import fi.nls.hakunapi.core.projection.ProjectionTransformerFactory;
import fi.nls.hakunapi.core.property.HakunaProperty;
Expand All @@ -32,6 +32,7 @@ public abstract class SimpleFeatureType implements FeatureType {
private List<Filter> staticFilters;
private ProjectionTransformerFactory transformerFactory;
private Map<String, Object> metadata;
private List<SRIDCode> knownSrids;

public abstract FeatureProducer getFeatureProducer();

Expand Down Expand Up @@ -201,5 +202,18 @@ public void setMetadata(Map<String, Object> metadata) {
public Map<String, Object> getMetadata() {
return metadata;
}

public Optional<SRIDCode> getSrid(int srid) {
if (knownSrids == null) {
return Optional.empty();
}
return knownSrids.stream()
.filter(x -> x.getSrid() == srid)
.findAny();
}

public void setKnownSrids(List<SRIDCode> knownSrids) {
this.knownSrids = knownSrids;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import fi.nls.hakunapi.core.PaginationStrategyCursor;
import fi.nls.hakunapi.core.PaginationStrategyHybrid;
import fi.nls.hakunapi.core.PaginationStrategyOffset;
import fi.nls.hakunapi.core.SRIDCode;
import fi.nls.hakunapi.core.SimpleFeatureType;
import fi.nls.hakunapi.core.SimpleSource;
import fi.nls.hakunapi.core.filter.Filter;
Expand Down Expand Up @@ -276,7 +277,7 @@ public String[] readCollectionIds() {
return collectionsIds;
}

public FeatureType readCollection(Path path, Map<String, SimpleSource> sourcesByType, String collectionId) throws Exception {
public FeatureType readCollection(Path path, Map<String, SimpleSource> sourcesByType, String collectionId, List<SRIDCode> knownSrids) throws Exception {
LOG.info("collection "+collectionId);
// Current prefix for properties
String p = "collections." + collectionId + ".";
Expand Down Expand Up @@ -304,6 +305,7 @@ public FeatureType readCollection(Path path, Map<String, SimpleSource> sourcesBy
ft.setMetadata(parseMetadata(p, path));
ft.setProjectionTransformerFactory(getProjection(p));
ft.setCacheSettings(parseCacheConfig(collectionId));
ft.setKnownSrids(knownSrids);

if (ft.getPaginationStrategy() == null) {
ft.setPaginationStrategy(getPaginationStrategy(p, ft));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package fi.nls.hakunapi.cql2.function.geometry;

import java.util.List;

import org.locationtech.jts.geom.Geometry;

import fi.nls.hakunapi.core.schemas.FunctionArgumentInfo.FunctionArgumentType;
import fi.nls.hakunapi.core.schemas.FunctionReturnsInfo.FunctionReturnsType;
import fi.nls.hakunapi.cql2.function.Function;
import fi.nls.hakunapi.cql2.model.function.FunctionCall;
import fi.nls.hakunapi.cql2.model.FilterContext;

public class Buffer extends Function {
public class Buffer extends Function<FilterContext> {

public Buffer() {
super("Buffer", null, null);
Expand All @@ -18,9 +20,15 @@ public Buffer() {
}

@Override
public Object visit(FunctionCall functionCall) {
Geometry geom = toGeometry(functionCall, "geom");
double radius_of_buffer = toNumber(functionCall, "radius_of_buffer").doubleValue();
public Object invoke(List<Object> args, FilterContext context) {
Geometry geom = getGeometryArg(args, "geom");
double radius_of_buffer = getNumberArg(args, "radius_of_buffer").doubleValue();
if (context != null) {
FilterContext fContext = (FilterContext) context;
if (fContext.filterSrid().isDegrees()) {
// TODO: Handle differently?
}
}
return geom.buffer(radius_of_buffer);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fi.nls.hakunapi.cql2.function.geometry;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -10,9 +11,9 @@
import fi.nls.hakunapi.core.schemas.FunctionArgumentInfo.FunctionArgumentType;
import fi.nls.hakunapi.core.schemas.FunctionReturnsInfo.FunctionReturnsType;
import fi.nls.hakunapi.cql2.function.Function;
import fi.nls.hakunapi.cql2.model.function.FunctionCall;
import fi.nls.hakunapi.cql2.model.FilterContext;

public class ST_Buffer extends Function {
public class ST_Buffer extends Function<FilterContext> {

/*
* reference: http://postgis.net/docs/manual-3.2/ST_Buffer.html
Expand All @@ -31,11 +32,10 @@ public ST_Buffer() {
}

@Override
public Object visit(FunctionCall functionCall) {

Geometry geom = toGeometry(functionCall, "geom");
double radius_of_buffer = toNumber(functionCall, "radius_of_buffer").doubleValue();
String buffer_style_parameters = toString(functionCall, "buffer_style_parameters");
public Object invoke(List<Object> args, FilterContext context) {
Geometry geom = getGeometryArg(args, "geom");
double radius_of_buffer = getNumberArg(args, "radius_of_buffer").doubleValue();
String buffer_style_parameters = getStringArg(args, "buffer_style_parameters");
String[] parts = buffer_style_parameters.split(" ");
final Map<String, String> kv = Stream.of(parts).filter(v -> !v.isEmpty()).map(elem -> elem.split("="))
.filter(v -> v.length != 0).collect(Collectors.toMap(e -> e[0], e -> e[1]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,16 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Polygon;

import fi.nls.hakunapi.cql2.function.Function;
import fi.nls.hakunapi.cql2.function.FunctionTable;
import fi.nls.hakunapi.cql2.model.function.FunctionCall;
import fi.nls.hakunapi.cql2.model.literal.NumberLiteral;
import fi.nls.hakunapi.cql2.model.literal.StringLiteral;
import fi.nls.hakunapi.cql2.model.spatial.SpatialLiteral;

public class TestGeometryFunctionsFactory {

Expand All @@ -31,15 +25,13 @@ public void testGeometryFunctionsBuffer() {
List<FunctionTable> functionTables = factory.createFunctionTables();

assertEquals(functionTables.size(), 1);
Function buffer = functionTables.get(0).getFunction("Buffer");
Function<?> buffer = functionTables.get(0).getFunction("Buffer");
assertNotNull(buffer);

LineString geomFrom = geomFactory
.createLineString(new Coordinate[] { new Coordinate(0, 0), new Coordinate(1, 1) });

FunctionCall functionCall = new FunctionCall("Buffer",
Arrays.asList(new SpatialLiteral(geomFrom), new NumberLiteral(1)));
Object rv = buffer.visit(functionCall);
Object rv = buffer.invoke(List.of(geomFrom, 1), null);

assertNotNull(rv);
assertTrue(rv instanceof Polygon);
Expand All @@ -53,15 +45,13 @@ public void testGeometryFunctionsSTBuffer() {
List<FunctionTable> functionTables = factory.createFunctionTables();

assertEquals(functionTables.size(), 1);
Function st_buffer = functionTables.get(0).getFunction("ST_Buffer");
Function<?> st_buffer = functionTables.get(0).getFunction("ST_Buffer");
assertNotNull(st_buffer);

LineString geomFrom = geomFactory
.createLineString(new Coordinate[] { new Coordinate(0, 0), new Coordinate(1, 1) });

FunctionCall functionCall = new FunctionCall("ST_Buffer",
Arrays.asList(new SpatialLiteral(geomFrom), new NumberLiteral(1), new StringLiteral("")));
Object rv = st_buffer.visit(functionCall);
Object rv = st_buffer.invoke(List.of(geomFrom, 1, ""), null);

assertNotNull(rv);
assertTrue(rv instanceof Polygon);
Expand All @@ -75,17 +65,13 @@ public void testGeometryFunctionsSTBufferMiter() {
List<FunctionTable> functionTables = factory.createFunctionTables();

assertEquals(functionTables.size(), 1);
Function st_buffer = functionTables.get(0).getFunction("ST_Buffer");
Function<?> st_buffer = functionTables.get(0).getFunction("ST_Buffer");
assertNotNull(st_buffer);

LineString geomFrom = geomFactory
.createLineString(new Coordinate[] { new Coordinate(0, 0), new Coordinate(1, 1) });

FunctionCall functionCall = new FunctionCall("ST_Buffer",
Arrays.asList(new SpatialLiteral(geomFrom), new NumberLiteral(1),
//
new StringLiteral("join=miter")));
Object rv = st_buffer.visit(functionCall);
Object rv = st_buffer.invoke(List.of(geomFrom, 1, "join=miter"), null);

assertNotNull(rv);
assertTrue(rv instanceof Polygon);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ public class CQL2Functions {
Map<String, FunctionTable> FUNCTION_TABLES = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

public void register() {
FunctionTableProvider.getFunctionTables().forEach(ft -> {
init(FunctionTableProvider.getFunctionTables());
}

public void init(List<FunctionTable> functionTables) {
functionTables.forEach(ft -> {
FUNCTION_TABLES.put(ft.getPackageName(), ft);
});
}
Expand All @@ -31,7 +35,7 @@ public Optional<Function> getAnyFunction(String functionName) {
.filter(Objects::nonNull).findFirst();
}

public static FunctionInfo fromFunc(Function func) {
public static FunctionInfo fromFunc(Function<?> func) {
final FunctionInfo funcInfo = new FunctionInfo(func.getName(), func.getDescription(), func.getMetadataUrl());
funcInfo.setArguments(func.getArguments());
funcInfo.setReturns(func.getReturns());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@
import fi.nls.hakunapi.core.schemas.FunctionArgumentInfo.FunctionArgumentType;
import fi.nls.hakunapi.core.schemas.FunctionReturnsInfo;
import fi.nls.hakunapi.core.schemas.FunctionReturnsInfo.FunctionReturnsType;
import fi.nls.hakunapi.cql2.model.function.FunctionCall;
import fi.nls.hakunapi.cql2.model.literal.NumberLiteral;
import fi.nls.hakunapi.cql2.model.literal.StringLiteral;
import fi.nls.hakunapi.cql2.model.spatial.SpatialLiteral;

public class Function {
public class Function<TContext> {

@FunctionalInterface
public interface FunctionImplementation {
Object visit(Function func, FunctionCall call);
public interface FunctionImplementation<TContext> {
Object invoke(Function<TContext> func, List<Object> args, TContext context);
}

protected String name;
Expand Down Expand Up @@ -54,14 +50,14 @@ public void setMetadataUrl(String metadataUrl) {
this.metadataUrl = metadataUrl;
}

public Function argument(String name, FunctionArgumentType type) {
public Function<TContext> argument(String name, FunctionArgumentType type) {
FunctionArgumentInfo funcArgInfo = new FunctionArgumentInfo(name, null, type);
argumentsPosName.put(name, arguments.size());
arguments.add(funcArgInfo);
return this;
}

public Function returns(FunctionReturnsType type) {
public Function<TContext> returns(FunctionReturnsType type) {
returns = new FunctionReturnsInfo(type);
return this;
}
Expand All @@ -74,7 +70,7 @@ public FunctionReturnsInfo getReturns() {
return returns;
}

public Object visit(FunctionCall functionCall) {
public Object invoke(List<Object> args, TContext context) {
throw new RuntimeException("Missing function implementation");
}

Expand All @@ -85,34 +81,37 @@ protected Function(String name, String description, String metadataUrl) {
this.metadataUrl = metadataUrl;
}

public static Function of(String name) {
return new Function(name, null, null);
public static <TContext> Function<TContext> of(String name) {
return new Function<>(name, null, null);
}

public static Function of(String name, String description, String metadataUrl) {
public static <TContext> Function<TContext> of(String name, String description, String metadataUrl) {

return new Function(name, description, metadataUrl);
return new Function<>(name, description, metadataUrl);
}

public static Function of(String name, final FunctionImplementation impl) {
public static <TContext> Function<TContext> of(String name, final FunctionImplementation<TContext> impl) {

return new Function(name, null, null) {
public Object visit(FunctionCall call) {
return impl.visit(this, call);
return new Function<>(name, null, null) {
public Object invoke(List<Object> args, TContext context) {
return impl.invoke(this, args, context);
}
};
}

protected Geometry toGeometry(FunctionCall call, String name) {
return ((SpatialLiteral) call.getArgs().get(argumentsPosName.get(name))).getGeometry();
protected Geometry getGeometryArg(List<Object> args, String name) {
int i = argumentsPosName.get(name);
return (Geometry) args.get(i);
}

protected Number toNumber(FunctionCall call, String name) {
return ((NumberLiteral) call.getArgs().get(argumentsPosName.get(name))).getValue();
protected Number getNumberArg(List<Object> args, String name) {
int i = argumentsPosName.get(name);
return (Number) args.get(i);
}

protected String toString(FunctionCall call, String name) {
return ((StringLiteral) call.getArgs().get(argumentsPosName.get(name))).getValue();
protected String getStringArg(List<Object> args, String name) {
int i = argumentsPosName.get(name);
return args.get(i).toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

public interface Expression {

default public Object accept(ExpressionVisitor visitor) {
return visitor.visit(this);
default public Object accept(ExpressionVisitor visitor, Object context) {
return visitor.visit(this, context);
}

default public boolean isCasei() {
Expand Down
Loading