Skip to content

Commit

Permalink
Merge branch 'master' into issue-2902-ept-update
Browse files Browse the repository at this point in the history
  • Loading branch information
connormanning committed Feb 11, 2020
2 parents 1ca20b6 + 8ce4403 commit cb1026c
Show file tree
Hide file tree
Showing 90 changed files with 1,280 additions and 6,419 deletions.
5 changes: 3 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*.las binary
*.laz binary

# Declare files that must never have CRLF line endings on checkout,
# otherwise tests will fail.
# Declare files that must never have CRLF line endings on checkout.
# Some tests depend on this configuration.
test/data/bpf/bundle1 text eol=lf
test/data/bpf/bundle2 text eol=lf
apps/pdal-config.in text eol=lf
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

cmake_minimum_required(VERSION 3.5)

project(PDAL VERSION 2.0.0 LANGUAGES CXX C)
project(PDAL VERSION 2.1.0 LANGUAGES CXX C)
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)

set(ROOT_DIR "${PROJECT_SOURCE_DIR}")
Expand Down
43 changes: 13 additions & 30 deletions apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,42 +68,25 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pdal.pc
DESTINATION "${PDAL_LIB_INSTALL_DIR}/pkgconfig/"
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)

if(UNIX OR APPLE)
# Autoconf compatibility variables to use the same script source.
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pdal-config.in"
"${CMAKE_CURRENT_SOURCE_DIR}/pdal-config" @ONLY)

file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/pdal-config"
DESTINATION
"${PDAL_OUTPUT_BIN_DIR}/"
FILE_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)

install(PROGRAMS "${PDAL_OUTPUT_BIN_DIR}/pdal-config"
DESTINATION
"${CMAKE_INSTALL_PREFIX}/bin"
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)

elseif(WIN32)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pdal-config.in"
"${PDAL_OUTPUT_BIN_DIR}/pdal-config" @ONLY
NEWLINE_STYLE UNIX)
install(PROGRAMS "${PDAL_OUTPUT_BIN_DIR}/pdal-config"
DESTINATION
"${CMAKE_INSTALL_PREFIX}/bin"
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)

if(WIN32)
# Autoconf compatibility variables to use the same script source.
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pdal-config-bat.in"
"${CMAKE_CURRENT_SOURCE_DIR}/pdal-config.bat" @ONLY)

file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/pdal-config.bat"
DESTINATION
"${PDAL_OUTPUT_BIN_DIR}/"
FILE_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)

"${PDAL_OUTPUT_BIN_DIR}/pdal-config.bat" @ONLY
NEWLINE_STYLE CRLF)
install(PROGRAMS "${PDAL_OUTPUT_BIN_DIR}/pdal-config.bat"
DESTINATION
"${CMAKE_INSTALL_PREFIX}/bin"
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)

endif()
2 changes: 2 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
jobs:
- template: ./scripts/azp/linux.yml
- template: ./scripts/azp/linux-conda.yml
- template: ./scripts/azp/win.yml
- template: ./scripts/azp/osx.yml
- template: ./scripts/azp/doc.yml
11 changes: 0 additions & 11 deletions cmake/sqlite.cmake

This file was deleted.

2 changes: 2 additions & 0 deletions doc/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Reference
.. [Dippe1985] Dippé, Mark AZ, and Erling Henry Wold. "Antialiasing through stochastic sampling." *ACM Siggraph Computer Graphics* 19.3 (1985): 69-78.
.. [Ester1996] Ester, Martin, et al. "A density-based algorithm for discovering clusters in large spatial databases with noise." Kdd. Vol. 96. No. 34. 1996.
.. [Fischer2010] Fischer, Kaspar, Bernd Gärtner, and Martin Kutz. “Fast Smallest-Enclosing-Ball Computation in High Dimensions.” 26473 (2010): 630–641. Web.
.. [Guinard2017] Guinard S., Landrieu L. "Weakly Supervised Segmented-Aided Classification of Urban Scenes From 3D LIDAR Point Clouds." Int. Arch. Photogramm. Remote Sens. Spatial Inf. Sci., XLII-1/W1, 151-157, 2017
Expand Down
51 changes: 51 additions & 0 deletions doc/stages/filters.dbscan.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.. _filters.dbscan:

===============================================================================
filters.dbscan
===============================================================================

The DBSCAN filter performs Density-Based Spatial Clustering of Applications
with Noise (DBSCAN) [Ester1996]_ and labels each point with its associated
cluster ID. Points that do not belong to a cluster are given a Cluster ID of
-1. The remaining clusters are labeled as integers starting from 0.

.. embed::

.. versionadded:: 2.1

Example
-------

.. code-block:: json
[
"input.las",
{
"type":"filters.dbscan",
"min_points":10,
"eps":2.0,
"dimensions":"X,Y,Z"
},
{
"type":"writers.bpf",
"filename":"output.bpf",
"output_dims":"X,Y,Z,ClusterID"
}
]
Options
-------

min_points
The minimum cluster size ``min_points`` should be greater than or equal to
the number of dimensions (e.g., X, Y, and Z) plus one. As a rule of thumb,
two times the number of dimensions is often used. [Default: 6]

eps
The epsilon parameter can be estimated from a k-distance graph (for k =
``min_points`` minus one). ``eps`` defines the Euclidean distance that will
be used when searching for neighbors. [Default: 1.0]

dimensions
Comma-separated string indicating dimensions to use for clustering. [Default: X,Y,Z]

21 changes: 15 additions & 6 deletions doc/stages/filters.python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ The function must have two `NumPy`_ arrays as arguments, ``ins`` and ``outs``.
The ``ins`` array represents the points before the ``filters.python``
filter and the ``outs`` array represents the points after filtering.

.. warning::

Make sure `NumPy`_ is installed in your `Python`_ environment.

.. code-block:: shell
$ python3 -c "import numpy; print(numpy.__version__)"
1.18.1
.. warning::

Each array contains all the :ref:`dimensions` of the incoming ``ins``
Expand Down Expand Up @@ -102,14 +111,14 @@ classified 1 or 2 to be dropped from the point stream.
def filter(ins,outs):
cls = ins['Classification']
keep_classes = [1,2]
keep_classes = [1, 2]
# Use the first test for our base array.
keep = np.equal(cls, keep_classes[0])
# For 1:n, test each predicate and join back
# to our existing predicate array
for k in range(1,len(keep_classes)):
for k in range(1, len(keep_classes)):
t = np.equal(cls, keep_classes[k])
keep = keep + t
Expand Down Expand Up @@ -164,9 +173,9 @@ for the in-scope :ref:`filters.python` :cpp:class:`pdal::Stage`.
.. code-block:: python
def myfunc(ins,outs):
print ('schema: ', schema)
print ('srs: ', spatialreference)
print ('metadata: ', metadata)
print('schema: ', schema)
print('srs: ', spatialreference)
print('metadata: ', metadata)
outs = ins
return True
Expand Down Expand Up @@ -207,7 +216,7 @@ basic Python function while substituting values as necessary.
"type":"filters.python",
"module":"anything",
"function":"filter",
"source":"arguments.py",
"script":"arguments.py",
"pdalargs":"{\"factor\":0.3048,\"an_argument\":42, \"another\": \"a string\"}"
},
"output.las"
Expand Down
5 changes: 5 additions & 0 deletions doc/stages/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ invalidate an existing KD-tree.
filters.colorinterp
filters.colorization
filters.covariancefeatures
filters.dbscan
filters.dem
filters.eigenvalues
filters.estimaterank
Expand Down Expand Up @@ -71,6 +72,10 @@ invalidate an existing KD-tree.
dimension ``ClusterID`` that indicates the cluster that a point belongs
to. Points not belonging to a cluster are given a cluster ID of 0.

:ref:`filters.dbscan`
Perform Density-Based Spatial Clustering of Applications with Noise
(DBSCAN) [Ester1996]_.

:ref:`filters.colorinterp`
Assign RGB colors based on a dimension and a ramp

Expand Down
149 changes: 149 additions & 0 deletions doc/stages/filters.transformation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,152 @@ _`matrix`
The matrix is assumed to be presented in row-major order.
Only matrices with sixteen elements are allowed.

Further details
---------------

A full tutorial about transformation matrices is beyond the scope of this
documentation. Instead, we will provide a few pointers to introduce core
concepts, especially as pertains to PDAL's handling of the ``matrix`` argument.

Transformations in a 3-dimensional coordinate system can be represented as an
affine transformation using homogeneous coordinates. This 4x4 matrix can
represent transformations describing operations like translation, rotation, and
scaling of coordinates.

The transformation filter's ``matrix`` argument is a space delimited, 16
element string. This string is simply a row-major representation of the 4x4
matrix (i.e., first four elements correspond to the top row of the
transformation matrix and so on).

In the event that readers are accustomed to an alternate representation of the
transformation matrix, we provide some simple examples in the form of pure
translations, rotations, and scaling, and show the corresponding ``matrix``
string.

Translation
...........

A pure translation by :math:`t_x`, :math:`t_y`, and :math:`t_z` in the X, Y,
and Z dimensions is represented by the following matrix.

.. math::
\begin{matrix}
1 & 0 & 0 & t_x \\
0 & 1 & 0 & t_y \\
0 & 0 & 1 & t_z \\
0 & 0 & 0 & 1
\end{matrix}
The JSON syntax required for such a translation is written as follows for :math:`t_x=7`, :math:`t_y=8`, and :math:`t_z=9`.

.. code-block:: json
[
{
"type":"filters.transformation",
"matrix":"1 0 0 7 0 1 0 8 0 0 1 9 0 0 0 1"
}
]
Scaling
.......

Scaling of coordinates is also possible using a transformation matrix. The
matrix shown below will scale the X coordinates by :math:`s_x`, the Y
coordinates by :math:`s_y`, and Z by :math:`s_z`.

.. math::
\begin{matrix}
s_x & 0 & 0 & 0 \\
0 & s_y & 0 & 0 \\
0 & 0 & s_z & 0 \\
0 & 0 & 0 & 1
\end{matrix}
We again provide an example JSON snippet to demonstrate the scaling
transformation. In the example, X and Y are not scaled at all (i.e.,
:math:`s_x=s_y=1`) and Z is magnified by a factor of 2 (:math:`s_z=2`).

.. code-block:: json
[
{
"type":"filters.transformation",
"matrix":"1 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1"
}
]
Rotation
........

A rotation of coordinates by :math:`\theta` radians counter-clockswise about
the z-axis is accomplished with the following matrix.

.. math::
\begin{matrix}
\cos{\theta} & -\sin{\theta} & 0 & 0 \\
\sin{\theta} & \cos{\theta} & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{matrix}
In JSON, a rotation of 90 degrees (:math:`\theta=1.57` radians) takes the form
shown below.

.. code-block:: json
[
{
"type":"filters.transformation",
"matrix":"0 0 -1 0 1 0 0 0 0 0 1 0 0 0 0 1"
}
]
Similarly, a rotation about the x-axis by :math:`\theta` radians is represented
as

.. math::
\begin{matrix}
1 & 0 & 0 & 0 \\
0 & \cos{\theta} & -\sin{\theta} & 0 \\
0 & \sin{\theta} & \cos{\theta} & 0 \\
0 & 0 & 0 & 1
\end{matrix}
which takes the following form in JSON for a rotation of 45 degrees (:math:`\theta=0.785` radians)

.. code-block:: json
[
{
"type":"filters.transformation",
"matrix":"1 0 0 0 0 0.707 -0.707 0 0 0.707 0.707 0 0 0 0 1"
}
]
Finally, a rotation by :math:`\theta` radians about the y-axis is accomplished
with the matrix

.. math::
\begin{matrix}
\cos{\theta} & 0 & \sin{\theta} & 0 \\
0 & 1 & 0 & 0 \\
-\sin{\theta} & 0 & \cos{\theta} & 0 \\
0 & 0 & 0 & 1
\end{matrix}
and the JSON string for a rotation of 10 degrees (:math:`\theta=0.175` radians) becomes

.. code-block:: json
[
{
"type":"filters.transformation",
"matrix":"0.985 0 0.174 0 0 1 0 0 -0.174 0 0.985 0 0 0 0 1"
}
]

0 comments on commit cb1026c

Please sign in to comment.