http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DifferenceFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DifferenceFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DifferenceFunction.java new file mode 100644 index 0000000..2b0d9c7 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DifferenceFunction.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for doing a difference of a geometry. Should be implemented + * directly in the database, as the in-memory implementation is non-functional. + * Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:difference(?geometryA, ?geometryB) </li> + * </ul> + * Its necesary enable postgis in your database with the next command "CREATE + * EXTENSION postgis;" Note that for performance reasons it might be preferrable + * to create a geometry index for your database. Please consult your database + * documentation on how to do this. + * + * @author Xavier Sumba ([email protected])) + */ +public class DifferenceFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.DIFFERENCE.toString())) { + FunctionRegistry.getInstance().add(new DifferenceFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.DIFFERENCE.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:difference(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:difference(?geom1, geof:buffer(?geometry, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_AsText(ST_Difference(%s , %s )) ", geom1, geom2); + } + } + throw new UnsupportedOperationException("Difference function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.GEOMETRY; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg + ) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +}
http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DistanceFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DistanceFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DistanceFunction.java new file mode 100644 index 0000000..0a300bb --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/DistanceFunction.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * Returns the shortest distance in units between any two Points of two + * geometries. Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:distance(?geometryA, ?geometryB, units:meter) </li> + * </ul> + * Its necesary enable postgis in your database with the next command "CREATE + * EXTENSION postgis;" Note that for performance reasons it might be preferrable + * to create a geometry index for your database. Please consult your database + * documentation on how to do this. + * + * @author Xavier Sumba ([email protected])) + */ +public class DistanceFunction implements NativeFunction { +// auto-register for SPARQL environment + + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.DISTANCE.toString())) { + FunctionRegistry.getInstance().add(new DistanceFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.DISTANCE.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 3) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:distance(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:distance(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + if (args[2].equalsIgnoreCase("'" + FN_GEOSPARQL.meter.toString() + "'") || args[2].equalsIgnoreCase("'" + FN_GEOSPARQL.metre.toString() + "'")) { + return String.format("ST_Distance( ST_Transform( %s ,26986), ST_Transform( %s ,26986))", geom1, geom2); + } + if (args[2].equalsIgnoreCase("'" + FN_GEOSPARQL.degree.toString() + "'")) { + return String.format("ST_Distance(%s, %s)", geom1, geom2); + } + if (args[2].equalsIgnoreCase("'" + FN_GEOSPARQL.radian.toString() + "'")) { + return String.format("RADIANS(ST_Distance(%s, %s))", geom1, geom2); + } + } + } + throw new UnsupportedOperationException("Distance function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.DOUBLE; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 3; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 3; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhContainsFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhContainsFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhContainsFunction.java new file mode 100644 index 0000000..908ecb3 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhContainsFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Contains Relate between two geometries. + * Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehContains(?geometryA, ?geometryB) </li> + * </ul> + * Contains Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhContainsFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_CONTAINS.toString())) { + FunctionRegistry.getInstance().add(new EhContainsFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_CONTAINS.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehContains(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehContains(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'T*TFF*FF*')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehContains function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoveredByFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoveredByFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoveredByFunction.java new file mode 100644 index 0000000..b5286d2 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoveredByFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the CoveredBy Relate between two geometries. + * Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehCoveredBy(?geometryA, ?geometryB) </li> + * </ul> + * CoveredBy Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 7" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhCoveredByFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_COVEREDBY.toString())) { + FunctionRegistry.getInstance().add(new EhCoveredByFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_COVEREDBY.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehCoveredBy(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehCoveredBy(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'TFF*TFT**')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehCoveredBy function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoversFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoversFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoversFunction.java new file mode 100644 index 0000000..ded7b95 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhCoversFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Covers Relate between two geometries. + * Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehCovers(?geometryA, ?geometryB) </li> + * </ul> + * Covers Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhCoversFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_COVERS.toString())) { + FunctionRegistry.getInstance().add(new EhCoversFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_COVERS.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehCovers(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehCovers(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'T*TFT*FF*')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehCovers function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhDisjointFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhDisjointFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhDisjointFunction.java new file mode 100644 index 0000000..b88a7fd --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhDisjointFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Disjoint between two geometries. Should be + * implemented directly in the database, as the in-memory implementation is + * non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehDisjoint(?geometryA, ?geometryB) </li> + * </ul> + * Disjoint is calculated with "DE-9IM Intersection Pattern": defined in "RCC8 + * Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhDisjointFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_DISJOINT.toString())) { + FunctionRegistry.getInstance().add(new EhDisjointFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_DISJOINT.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehDisjoint(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehDisjoint(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'FF*FF****')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehDisjoint function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhEqualsFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhEqualsFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhEqualsFunction.java new file mode 100644 index 0000000..0dfa466 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhEqualsFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the EhEquals between two geometries. Should be + * implemented directly in the database, as the in-memory implementation is + * non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehEquals(?geometryA, ?geometryB) </li> + * </ul> + * EhEquals is calculated with "DE-9IM Intersection Pattern": defined in "RCC8 + * Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhEqualsFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_EQUALS.toString())) { + FunctionRegistry.getInstance().add(new EhEqualsFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_EQUALS.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehEquals(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehEquals(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'TFFFTFFFT')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehEquals function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhInsideFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhInsideFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhInsideFunction.java new file mode 100644 index 0000000..b3845bd --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhInsideFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Inside Relate between two geometries. + * Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehInside(?geometryA, ?geometryB) </li> + * </ul> + * Inside Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhInsideFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_INSIDE.toString())) { + FunctionRegistry.getInstance().add(new EhInsideFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_INSIDE.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehInside(?geom, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehInside(?geom, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'TFF*FFT**')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehInside function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhMeetFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhMeetFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhMeetFunction.java new file mode 100644 index 0000000..e340048 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhMeetFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Meet Relate between two geometries. Should + * be implemented directly in the database, as the in-memory implementation is + * non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehMeet(?geometryA, ?geometryB) </li> + * </ul> + * Meet Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhMeetFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_MEET.toString())) { + FunctionRegistry.getInstance().add(new EhMeetFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_MEET.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehMeet(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehMeet(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'F***T****')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehMeet function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhOverlapFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhOverlapFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhOverlapFunction.java new file mode 100644 index 0000000..605e304 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EhOverlapFunction.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for analyze the Overlap Relate between two geometries. + * Should be implemented directly in the database, as the in-memory + * implementation is non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:ehOverlap(?geometryA, ?geometryB) </li> + * </ul> + * Overlap Relate is calculated with "DE-9IM Intersection Pattern": defined in + * "RCC8 Query Functions Table 6" from "DE-9IM Intersection Pattern" from OGC + * GEOSPARQL DOCUMENT ( + * https://portal.opengeospatial.org/files/?artifact_id=47664 ) + * + * @author Xavier Sumba ([email protected])) + */ +public class EhOverlapFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.EH_OVERLAP.toString())) { + FunctionRegistry.getInstance().add(new EhOverlapFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.EH_OVERLAP.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:ehOverlap(?geom, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:ehOverlap(?geom, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_Relate(%s, %s, 'T*T***T**')", geom1, geom2); + } + } + throw new UnsupportedOperationException("ehOverlap function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.BOOL; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EnvelopeFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EnvelopeFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EnvelopeFunction.java new file mode 100644 index 0000000..378dca9 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/EnvelopeFunction.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for doing an envelope of a geometry. Should be implemented + * directly in the database, as the in-memory implementation is non-functional. + * Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:envelope(?geometryA) </li> + * </ul> + * Its necesary enable postgis in your database with the next command "CREATE + * EXTENSION postgis;" Note that for performance reasons it might be preferrable + * to create a geometry index for your database. Please consult your database + * documentation on how to do this. + * + * @author Xavier Sumba ([email protected])) + */ +public class EnvelopeFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.ENVELOPE.toString())) { + FunctionRegistry.getInstance().add(new EnvelopeFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.ENVELOPE.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 1) { + String geom1 = args[0]; + String SRID_default = "4326"; + /* + * The following conditions is required to read WKT inserted directly into args[0] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:envelope("POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:envelope(geof:buffer(?geom, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + return String.format("ST_AsText(ST_Envelope(%s)) ", geom1); + } + } + throw new UnsupportedOperationException("Envelope function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.GEOMETRY; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 1; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 1; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/GetSRIDFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/GetSRIDFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/GetSRIDFunction.java new file mode 100644 index 0000000..34ac142 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/GetSRIDFunction.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * Returns the spatial reference system URI for geom.. Should be implemented + * directly in the database, as the in-memory implementation is non-functional. + * Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:getSRID(?geometryA) </li> + * </ul> + * Its necesary enable postgis in your database with the next command "CREATE + * EXTENSION postgis;" Note that for performance reasons it might be preferrable + * to create a geometry index for your database. Please consult your database + * documentation on how to do this. + * + * @author Xavier Sumba ([email protected])) + */ +public class GetSRIDFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.GETSRID.toString())) { + FunctionRegistry.getInstance().add(new GetSRIDFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.GETSRID.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 1) { + return String.format("ST_SRID(%s)", args[0]); + } + } + throw new UnsupportedOperationException("getSRID function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.INT; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 1; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 1; + } +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/df172223/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/IntersectionFunction.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/IntersectionFunction.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/IntersectionFunction.java new file mode 100644 index 0000000..f1ed703 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/functions/IntersectionFunction.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.functions; + +import org.apache.marmotta.kiwi.persistence.KiWiDialect; +import org.apache.marmotta.kiwi.persistence.pgsql.PostgreSQLDialect; +import org.apache.marmotta.kiwi.sparql.builder.ValueType; +import org.apache.marmotta.kiwi.sparql.function.NativeFunction; +import org.apache.marmotta.kiwi.vocabulary.FN_GEOSPARQL; +import org.openrdf.model.Value; +import org.openrdf.model.ValueFactory; +import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException; +import org.openrdf.query.algebra.evaluation.function.FunctionRegistry; + +/** + * A SPARQL function for doing a intersection between two geometries. Should be + * implemented directly in the database, as the in-memory implementation is + * non-functional. Only support by postgres - POSTGIS + * <p/> + * The function can be called either as: + * <ul> + * <li>geof:intersection(?geometryA, ?geometryB) </li> + * </ul> + * Its necesary enable postgis in your database with the next command "CREATE + * EXTENSION postgis;" Note that for performance reasons it might be preferrable + * to create a geometry index for your database. Please consult your database + * documentation on how to do this. + * + * @author Xavier Sumba ([email protected])) + */ +public class IntersectionFunction implements NativeFunction { + + // auto-register for SPARQL environment + static { + if (!FunctionRegistry.getInstance().has(FN_GEOSPARQL.INTERSECTION.toString())) { + FunctionRegistry.getInstance().add(new IntersectionFunction()); + } + } + + @Override + public Value evaluate(ValueFactory valueFactory, Value... args) throws ValueExprEvaluationException { + throw new UnsupportedOperationException("cannot evaluate in-memory, needs to be supported by the database"); + } + + @Override + public String getURI() { + return FN_GEOSPARQL.INTERSECTION.toString(); + } + + /** + * Return true if this function has available native support for the given + * dialect + * + * @param dialect + * @return + */ + @Override + public boolean isSupported(KiWiDialect dialect) { + return dialect instanceof PostgreSQLDialect; + } + + /** + * Return a string representing how this GeoSPARQL function is translated + * into SQL ( Postgis Function ) in the given dialect + * + * @param dialect + * @param args + * @return + */ + @Override + public String getNative(KiWiDialect dialect, String... args) { + if (dialect instanceof PostgreSQLDialect) { + if (args.length == 2) { + String geom1 = args[0]; + String geom2 = args[1]; + String SRID_default = "4326"; + /* + * The following condition is required to read WKT inserted directly into args[0] or args[1] and create a geometries with SRID + * POINT, MULTIPOINT, LINESTRING ... and MULTIPOLYGON conditions: + * example: geof:intersection(?geom1, "POLYGON(( -7 43, -2 43, -2 38, -7 38, -7 43))"^^geo:wktLiteral) + * st_AsText condition: It is to use the geometry that is the result of another function geosparql. + * example: geof:intersection(?geom1, geof:buffer(?geom2, 50, units:meter)) + */ + if (args[0].contains("POINT") || args[0].contains("MULTIPOINT") || args[0].contains("LINESTRING") || args[0].contains("MULTILINESTRING") || args[0].contains("POLYGON") || args[0].contains("MULTIPOLYGON") || args[0].contains("ST_AsText")) { + geom1 = String.format("ST_GeomFromText(%s,%s)", args[0], SRID_default); + } + if (args[1].contains("POINT") || args[1].contains("MULTIPOINT") || args[1].contains("LINESTRING") || args[1].contains("MULTILINESTRING") || args[1].contains("POLYGON") || args[1].contains("MULTIPOLYGON") || args[1].contains("ST_AsText")) { + geom2 = String.format("ST_GeomFromText(%s,%s)", args[1], SRID_default); + } + return String.format("ST_AsText(st_Intersection(%s , %s ) )", geom1, geom2); + } + } + throw new UnsupportedOperationException("Intersection function not supported by dialect " + dialect); + } + + /** + * Get the return type of the function. This is needed for SQL type casting + * inside KiWi. + * + * @return + */ + @Override + public ValueType getReturnType() { + return ValueType.GEOMETRY; + } + + /** + * Get the argument type of the function for the arg'th argument (starting + * to count at 0). This is needed for SQL type casting inside KiWi. + * + * @param arg + * @return + */ + @Override + public ValueType getArgumentType(int arg) { + return ValueType.GEOMETRY; + } + + /** + * Return the minimum number of arguments this function requires. + * + * @return + */ + @Override + public int getMinArgs() { + return 2; + } + + /** + * Return the maximum number of arguments this function can take + * + * @return + */ + @Override + public int getMaxArgs() { + return 2; + } +}
