Skip to content

Commit

Permalink
Add spatial function st_isovist
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-f committed Sep 24, 2018
1 parent ff0a2bf commit eac6d78
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.h2.tools.RunScript;
import org.h2gis.api.Function;
import org.h2gis.api.ScalarFunction;
import org.h2gis.functions.spatial.earth.*;
import org.h2gis.functions.spatial.split.ST_LineIntersector;
import org.h2gis.functions.spatial.split.ST_Split;
import org.h2gis.functions.io.DriverManager;
Expand Down Expand Up @@ -112,9 +113,6 @@
import org.h2gis.functions.spatial.distance.ST_MaxDistance;
import org.h2gis.functions.spatial.distance.ST_ProjectPoint;
import org.h2gis.functions.spatial.distance.ST_ShortestLine;
import org.h2gis.functions.spatial.earth.ST_GeometryShadow;
import org.h2gis.functions.spatial.earth.ST_SunPosition;
import org.h2gis.functions.spatial.earth.ST_Svf;
import org.h2gis.functions.spatial.edit.ST_AddPoint;
import org.h2gis.functions.spatial.edit.ST_AddZ;
import org.h2gis.functions.spatial.edit.ST_CollectionExtract;
Expand Down Expand Up @@ -443,7 +441,8 @@ public static Function[] getBuiltInsFunctions() {
new ST_Svf(),
new JsonWrite(),
new ST_ShortestLine(),
new ST_OrientedEnvelope()};
new ST_OrientedEnvelope(),
new ST_Isovist()};
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* H2GIS is a library that brings spatial support to the H2 Database Engine
* <http://www.h2database.com>. H2GIS is developed by CNRS
* <http://www.cnrs.fr/>.
*
* This code is part of the H2GIS project. H2GIS is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation;
* version 3.0 of the License.
*
* H2GIS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details <http://www.gnu.org/licenses/>.
*
*
* For more information, please consult: <http://www.h2gis.org/>
* or contact directly: info_at_h2gis.org
*/
package org.h2gis.functions.spatial.earth;

import org.h2gis.api.*;
import org.h2gis.utilities.jts_utils.*;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.util.*;

import java.sql.*;

public class ST_Isovist extends DeterministicScalarFunction {
public ST_Isovist() {
addProperty(PROP_REMARKS, "ST_Isovist takes LINESTRING(S) or POLYGON(S) as input\n"
+ " and a maximum distance (spatial ref units). This function compute the visibility polygon" +
" obstructed by provided \"walls\". Provided segments will be enclosed by a circle" +
" defined by maximum distance parameter.");
}

@Override
public String getJavaStaticMethod() {
return "isovist";
}

/**
* This function compute the visibility polygon
* @param viewPoint Point instance, isovist location
* @param lineSegments Occlusion segments. Geometry collection or polygon or linestring
* @param maxDistance Maximum distance of view from viewPoint (spatial ref units)
* @return The visibility polygon
* @throws SQLException In case of wrong parameters
*/
public static Polygon isovist(Geometry viewPoint, Geometry lineSegments, double maxDistance) throws SQLException {
if(!(viewPoint instanceof Point) || viewPoint.isEmpty()) {
throw new SQLException("First parameter of ST_Isovist must be a Point");
}
if(maxDistance <= 0) {
throw new SQLException("Third parameter of ST_Isovist must be a valid distance superior than 0");
}
VisibilityAlgorithm visibilityAlgorithm = new VisibilityAlgorithm(maxDistance);
visibilityAlgorithm.addGeometry(lineSegments);
return visibilityAlgorithm.getIsoVist(viewPoint.getCoordinate(), true);
}

/**
* This function compute the visibility polygon
* @param viewPoint Point instance, isovist location
* @param lineSegments Occlusion segments. Geometry collection or polygon or linestring
* @param maxDistance Maximum distance of view from viewPoint (spatial ref units)
* @param radBegin Constraint view angle start in radian
* @param radEnd Constraint view angle end in radian
* @return The visibility polygon
* @throws SQLException In case of wrong parameters
*/
public static Geometry isovist(Geometry viewPoint, Geometry lineSegments, double maxDistance, double radBegin, double radEnd) throws SQLException {
Geometry isopoly = isovist(viewPoint, lineSegments, maxDistance);

// Intersects with view constrain
GeometricShapeFactory geometricShapeFactory = new GeometricShapeFactory();
geometricShapeFactory.setCentre(viewPoint.getCoordinate());
geometricShapeFactory.setWidth(maxDistance * 2);
geometricShapeFactory.setHeight(maxDistance * 2);
return geometricShapeFactory.createArcPolygon(radBegin, radEnd).intersection(isopoly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -951,4 +951,20 @@ public void test_ST_ShortestLine4() throws Exception {
Assert.assertTrue(rs.next());
assertGeometryEquals("LINESTRING (2 4, 2 4.9)", rs.getObject(1));
}

@Test
public void test_ST_Isovist() throws Exception {
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT ST_Isovist('POINT (1.8 2.4)'::GEOMETRY, 'MULTIPOLYGON(((1 2, 3 2, 2 3, 1 2)),((2 4, 5 2, 5 5, 2 4)),((1 1 0, 4 1 0, 4 4 5, 1 1 0)))'::GEOMETRY, 10) as result");
Assert.assertTrue(rs.next());
assertGeometryEquals("POLYGON ((2.5 2.5, 2 3, 1 2, 2 2, 2.5 2.5))", rs.getObject(1));
}

@Test
public void test_ST_IsovistConstraint() throws Exception {
Statement st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT ST_Isovist('POINT (2 2.5)'::GEOMETRY, 'MULTIPOLYGON(((1 2, 3 2, 2 3, 1 2)),((2 4, 5 2, 5 5, 2 4)),((1 1 0, 4 1 0, 4 4 5, 1 1 0)))'::GEOMETRY, 10, 0, PI() / 2) as result");
Assert.assertTrue(rs.next());
assertGeometryEquals("POLYGON ((2 2.5, 2 3, 2.5 2.5, 2 2.5))", rs.getObject(1));
}
}

0 comments on commit eac6d78

Please sign in to comment.