Skip to content
Merged
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
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:maxX. */
public class MaxXFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMaxX());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:maxY. */
public class MaxYFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMaxY());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:maxZ. */
public class MaxZFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMaxZ());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:minX. */
public class MinXFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMinX());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:minY. */
public class MinYFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMinY());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.geof.topological.filter_functions.geometry_property;

import org.apache.jena.datatypes.DatatypeFormatException;
import org.apache.jena.geosparql.implementation.GeometryWrapper;
import org.apache.jena.sparql.expr.ExprEvalException;
import org.apache.jena.sparql.expr.NodeValue;
import org.apache.jena.sparql.function.FunctionBase1;

/** Implements geof:minZ. */
public class MinZFF extends FunctionBase1 {

@Override
public NodeValue exec(NodeValue value) {
try {
GeometryWrapper geometry = GeometryWrapper.extract(value);
return NodeValue.makeDouble(geometry.getMinZ());
} catch (DatatypeFormatException | IllegalStateException ex) {
throw new ExprEvalException(ex.getMessage(), ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ public static int findCoordinateDimension(CoordinateSequenceDimensions dims) {
}

public static DimensionInfo find(Coordinate coordinate, Geometry geometry) {
CoordinateSequenceDimensions coordDims = CoordinateSequenceDimensions.find(coordinate);
// Empty geometries have no coordinate; use the existing XY default.
CoordinateSequenceDimensions coordDims = CoordinateSequenceDimensions.find(
coordinate == null ? XY_COORDINATE : coordinate);
return new DimensionInfo(coordDims, geometry.getDimension());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* 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
*
* https://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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.apache.jena.geosparql.implementation;

import java.util.function.DoubleBinaryOperator;

import org.locationtech.jts.geom.CoordinateSequence;
import org.locationtech.jts.geom.CoordinateSequenceFilter;
import org.locationtech.jts.geom.Geometry;

/**
* Finds coordinate extrema in the input geometry's SRS axis order.
* X and Y denote the first and second SRS dimensions, respectively.
*/
final class GeometryCoordinateExtrema {
private GeometryCoordinateExtrema() {
}

static double maxX(GeometryWrapper geometry) {
return extreme(geometry, 0, Math::max);
}

static double maxY(GeometryWrapper geometry) {
return extreme(geometry, 1, Math::max);
}

static double maxZ(GeometryWrapper geometry) {
return zExtreme(geometry, Math::max);
}

static double minX(GeometryWrapper geometry) {
return extreme(geometry, 0, Math::min);
}

static double minY(GeometryWrapper geometry) {
return extreme(geometry, 1, Math::min);
}

static double minZ(GeometryWrapper geometry) {
return zExtreme(geometry, Math::min);
}

private static double extreme(GeometryWrapper geometry, int ordinate,
DoubleBinaryOperator accumulator) {
return extreme(geometry.getParsingGeometry(), ordinate, accumulator, false);
}

private static double zExtreme(GeometryWrapper geometry, DoubleBinaryOperator accumulator) {
return extreme(geometry.getParsingGeometry(), 2, accumulator, true);
}

private static double extreme(Geometry geometry, int ordinate,
DoubleBinaryOperator accumulator, boolean skipNaN) {
ExtremaFilter filter = new ExtremaFilter(ordinate, accumulator, skipNaN);
geometry.apply(filter);
return filter.result();
}

private static final class ExtremaFilter implements CoordinateSequenceFilter {
private final int ordinate;
private final DoubleBinaryOperator accumulator;
private final boolean skipNaN;
private double result;
private boolean found;

private ExtremaFilter(int ordinate, DoubleBinaryOperator accumulator, boolean skipNaN) {
this.ordinate = ordinate;
this.accumulator = accumulator;
this.skipNaN = skipNaN;
}

@Override
public void filter(CoordinateSequence sequence, int index) {
if (skipNaN && !sequence.hasZ()) {
return;
}
double value = skipNaN ? sequence.getZ(index) : sequence.getOrdinate(index, ordinate);
if (Double.isInfinite(value) || (!skipNaN && Double.isNaN(value))) {
throw new IllegalStateException("Geometry has a non-finite ordinate at ordinate index " + ordinate);
}
if (skipNaN && Double.isNaN(value)) {
return;
}
result = found ? accumulator.applyAsDouble(result, value) : value;
found = true;
}

@Override
public boolean isDone() {
return false;
}

@Override
public boolean isGeometryChanged() {
return false;
}

private double result() {
if (!found) {
throw new IllegalStateException("Geometry has no eligible ordinate");
}
return result;
}
}
}
Loading
Loading