Skip to content

Commit

Permalink
add new functions to analysis library, also adds python bindings to a…
Browse files Browse the repository at this point in the history
…nalysis library

git-svn-id: http://svn.osgeo.org/qgis/trunk@11976 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
cfarmer committed Nov 7, 2009
1 parent e4f8edd commit 4a7839c
Show file tree
Hide file tree
Showing 7 changed files with 673 additions and 522 deletions.
49 changes: 30 additions & 19 deletions python/CMakeLists.txt
Expand Up @@ -2,38 +2,45 @@ SUBDIRS(plugins)
IF (WIN32)
SET(BINDINGS_CORE_LIB ${CMAKE_CURRENT_BINARY_DIR}/core/core.pyd)
SET(BINDINGS_GUI_LIB ${CMAKE_CURRENT_BINARY_DIR}/gui/gui.pyd)
SET(BINDINGS_ANALYSIS_LIB ${CMAKE_CURRENT_BINARY_DIR}/analysis/analysis.pyd)
IF (NOT MSVC)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.dll)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.dll)
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.dll)
ELSE (NOT MSVC)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/${CMAKE_CFG_INTDIR}/qgis_core.lib)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/${CMAKE_CFG_INTDIR}/qgis_gui.lib)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/${CMAKE_CFG_INTDIR}/qgis_core.lib)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/${CMAKE_CFG_INTDIR}/qgis_gui.lib)
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/${CMAKE_CFG_INTDIR}/qgis_analysis.lib)
ENDIF (NOT MSVC)
ELSE (WIN32)
SET(BINDINGS_CORE_LIB ${CMAKE_CURRENT_BINARY_DIR}/core/core.so)
SET(BINDINGS_GUI_LIB ${CMAKE_CURRENT_BINARY_DIR}/gui/gui.so)
SET(BINDINGS_CORE_LIB ${CMAKE_CURRENT_BINARY_DIR}/core/core.so)
SET(BINDINGS_GUI_LIB ${CMAKE_CURRENT_BINARY_DIR}/gui/gui.so)
SET(BINDINGS_ANALYSIS_LIB ${CMAKE_CURRENT_BINARY_DIR}/analysis/analysis.so)
IF (APPLE)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.dylib)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.dylib)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.dylib)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.dylib)
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.dylib)
ELSE (APPLE)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.so)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.so)
SET(QGIS_CORE_LIB ${CMAKE_BINARY_DIR}/src/core/libqgis_core.so)
SET(QGIS_GUI_LIB ${CMAKE_BINARY_DIR}/src/gui/libqgis_gui.so)
SET(QGIS_ANALYSIS_LIB ${CMAKE_BINARY_DIR}/src/analysis/libqgis_analysis.so)
ENDIF (APPLE)
ENDIF (WIN32)

SET (BINDINGS_LIBS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB})

SET (BINDINGS_CORE_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/core/Makefile)
SET (BINDINGS_GUI_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/gui/Makefile)
SET (BINDINGS_LIBS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB} ${BINDINGS_ANALYSIS_LIB})
SET (BINDINGS_CORE_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/core/Makefile)
SET (BINDINGS_GUI_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/gui/Makefile)
SET (BINDINGS_ANALYSIS_MAKEFILE ${CMAKE_CURRENT_BINARY_DIR}/analysis/Makefile)

# 'python' target will force to build bindings libs for core and gui
ADD_CUSTOM_TARGET (python ALL DEPENDS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB})
ADD_CUSTOM_TARGET (python ALL DEPENDS ${BINDINGS_CORE_LIB} ${BINDINGS_GUI_LIB} ${BINDINGS_ANALYSIS_LIB})

# don't run python before the libs are built
ADD_DEPENDENCIES (python qgis_core qgis_gui)
ADD_DEPENDENCIES (python qgis_core qgis_gui qgis_analysis)

FILE(GLOB CORE_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/core/*.sip")
FILE(GLOB GUI_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gui/*.sip")
FILE(GLOB CORE_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/core/*.sip")
FILE(GLOB GUI_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gui/*.sip")
FILE(GLOB ANALYSIS_SIP_FILES "${CMAKE_CURRENT_SOURCE_DIR}/analysis/*.sip")

# Step 1: during configuration
# create file configure.py from configure.py.in
Expand All @@ -50,12 +57,12 @@ ENDIF (MSVC)
# run python configure.py
# it will run SIP utility to generate sources and will prepare makefiles
# should be run everytime core or gui library has been changed
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_CORE_MAKEFILE} ${BINDINGS_GUI_MAKEFILE} PRE_BUILD
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_CORE_MAKEFILE} ${BINDINGS_GUI_MAKEFILE} ${BINDINGS_ANALYSIS_MAKEFILE} PRE_BUILD
COMMAND ${PYTHON_EXECUTABLE}
ARGS ${CMAKE_CURRENT_BINARY_DIR}/configure.py ${CMAKE_CFG_INTDIR} ${EXPORT}
DEPENDS ${QGIS_CORE_LIB} ${QGIS_GUI_LIB}
DEPENDS ${QGIS_CORE_LIB} ${QGIS_GUI_LIB} ${QGIS_ANALYSIS_LIB}
${CMAKE_CURRENT_BINARY_DIR}/configure.py
${CORE_SIP_FILES} ${GUI_SIP_FILES})
${CORE_SIP_FILES} ${GUI_SIP_FILES} ${ANALYSIS_SIP_FILES})

# Step 3: run make in core and gui subdirs
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_CORE_LIB} PRE_LINK
Expand All @@ -66,6 +73,10 @@ ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_GUI_LIB} PRE_LINK
COMMAND ${SIP_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gui
DEPENDS ${BINDINGS_GUI_MAKEFILE})
ADD_CUSTOM_COMMAND(OUTPUT ${BINDINGS_ANALYSIS_LIB} PRE_LINK
COMMAND ${SIP_MAKE_PROGRAM}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/analysis
DEPENDS ${BINDINGS_ANALYSIS_MAKEFILE})

IF (BINDINGS_GLOBAL_INSTALL)

Expand Down
11 changes: 11 additions & 0 deletions python/analysis/analysis.sip
@@ -0,0 +1,11 @@

%Module qgis.analysis 0

%Import QtCore/QtCoremod.sip
%Import QtGui/QtGuimod.sip
%Import QtXml/QtXmlmod.sip

%Import core/core.sip

%Include qgsgeometryanalyzer.sip

67 changes: 67 additions & 0 deletions python/analysis/qgsgeometryanalyzer.sip
@@ -0,0 +1,67 @@
/** \ingroup analysis
* The QGis class provides vector geometry analysis functions
*/

class QgsGeometryAnalyzer
{
%TypeHeaderCode
#include <qgsgeometryanalyzer.h>
%End

public:

/**
* Simplify vector layer using (a modified) Douglas-Peucker algorithm
* and write it to a new shape file
*/
bool simplify( QgsVectorLayer* layer, const QString& shapefileName, double tolerance,
bool onlySelectedFeatures = false );

/**Calculate the true centroids, or 'center of mass' for a vector layer and
write it to a new shape file
*/
bool centroids( QgsVectorLayer* layer, const QString& shapefileName,
bool onlySelectedFeatures = false );

/**Create a polygon based on the extent of all (selected) features and write it to a new shape file
*/
bool extent( QgsVectorLayer* layer, const QString& shapefileName,
bool onlySelectedFeatures = false );

/**Create buffers for a vector layer and write it to a new shape file
*/
bool buffer( QgsVectorLayer* layer, const QString& shapefileName, double bufferDistance,
bool onlySelectedFeatures = false, bool dissolve = false,
int bufferDistanceField = -1 );

/**Create convex hull(s) of a vector layer and write it to a new shape file
*/
bool convexHull( QgsVectorLayer* layer, const QString& shapefileName,
bool onlySelectedFeatures = false,
int uniqueIdField = -1 );

/**Dissolve a vector layer and write it to a new shape file
*/
bool dissolve( QgsVectorLayer* layer, const QString& shapefileName,
bool onlySelectedFeatures = false,
int uniqueIdField = -1 );

private:

QList<double> simpleMeasure( QgsGeometry* geometry );
double perimeterMeasure( QgsGeometry* geometry, QgsDistanceArea& measure );
/**Helper function to simplify an individual feature*/
void simplifyFeature( QgsFeature& f, QgsVectorFileWriter* vfw, double tolerance );
/**Helper function to get the cetroid of an individual feature*/
void centroidFeature( QgsFeature& f, QgsVectorFileWriter* vfw );
/**Helper function to buffer an individual feature*/
void bufferFeature( QgsFeature& f, int nProcessedFeatures, QgsVectorFileWriter* vfw,
bool dissolve, QgsGeometry** dissolveGeometry,
double bufferDistance, int bufferDistanceField );
/**Helper function to get the convex hull of feature(s)*/
void convexFeature( QgsFeature& f, int nProcessedFeatures,
QgsGeometry** dissolveGeometry );
/**Helper function to dissolve feature(s)*/
void dissolveFeature( QgsFeature& f, int nProcessedFeatures,
QgsGeometry** dissolveGeometry );
};
38 changes: 35 additions & 3 deletions python/configure.py.in
Expand Up @@ -38,6 +38,8 @@ if not os.path.isdir("./core"):
os.mkdir("./core")
if not os.path.isdir("./gui"):
os.mkdir("./gui")
if not os.path.isdir("./analysis"):
os.mkdir("./analysis")

##########################################################################
# SIP -> *.CPP + *.H
Expand All @@ -46,6 +48,7 @@ if not os.path.isdir("./gui"):
# system.
build_file_core = build_path + "/python/core/core.sbf"
build_file_gui = build_path + "/python/gui/gui.sbf"
build_file_analysis = build_path + "/python/analysis/analysis.sbf"

# Get the SIP configuration information.
config = PyQt4.pyqtconfig.Configuration()
Expand All @@ -61,6 +64,7 @@ mod_dir = os.path.join(config.default_mod_dir, "qgis")
# directory where sip files will be installed
sip_dir_core = os.path.join(config.default_sip_dir, "qgis/core")
sip_dir_gui = os.path.join(config.default_sip_dir, "qgis/gui")
sip_dir_analysis = os.path.join(config.default_sip_dir, "qgis/analysis")

# Run SIP to generate the code.
print "Parsing SIP files for 'core' library..."
Expand All @@ -73,6 +77,11 @@ cmd = " ".join([config.sip_bin, "-c", "gui", "-b", build_file_gui, "-I", python_
print cmd
os.system(cmd)

print "Parsing SIP files for 'analysis' library..."
cmd = " ".join([config.sip_bin, "-c", "analysis", "-b", build_file_analysis, "-I", python_path, "-I", config.pyqt_sip_dir, qt_sip_flags, python_path + "/analysis/analysis.sip"])
print cmd
os.system(cmd)


##########################################################################
# MAKEFILES
Expand All @@ -83,12 +92,13 @@ print "Creating makefiles..."
# its configuration module.
installs = []

# directories relative to core (gui) directories
# directories relative to core (gui, analysis) directories
installs.append([[python_path + "__init__.py", python_path + "qgisconfig.py"], mod_dir])


installs_core = copy.copy(installs)
installs_gui = copy.copy(installs)
installs_analysis = copy.copy(installs)

# install all sip files
sips_core = glob.glob(python_path + "/core/*.sip")
Expand All @@ -98,6 +108,10 @@ for sip in sips_core:
sips_gui = glob.glob(python_path + "/gui/*.sip")
for sip in sips_gui:
installs_gui.append([os.path.basename(sip), sip_dir_gui])

sips_analysis = glob.glob(python_path + "/analysis/*.sip")
for sip in sips_analysis:
installs_analysis.append([os.path.basename(sip), sip_dir_analysis])


# Create the Makefile. The QtModuleMakefile class provided by the
Expand All @@ -120,9 +134,18 @@ makefile_gui = sipconfig.ModuleMakefile(
install_dir=mod_dir,
dir="gui",
universal=osx_universal)

makefile_analysis = sipconfig.ModuleMakefile(
configuration=config,
qt=qt_libs,
build_file=build_file_analysis,
installs=installs_analysis,
install_dir=mod_dir,
dir="analysis",
universal=osx_universal)

# common settings for both core and gui libs
for mk in [ makefile_core, makefile_gui ]:
# common settings for core, gui and analysis libs
for mk in [ makefile_core, makefile_gui, makefile_analysis ]:
mk.extra_lflags.extend( "@CMAKE_MODULE_LINKER_FLAGS@".strip(' ').split(' ') )
mk.extra_libs = ["qgis_core"]
mk.extra_lib_dirs = [build_path+"/src/core"+intdir]
Expand All @@ -145,9 +168,18 @@ makefile_gui.extra_include_dirs.append(build_path+"/src/ui")
makefile_gui.extra_include_dirs.append(src_path+"/src/plugins") # because of qgisplugin.h TODO: sort out
makefile_gui.extra_cxxflags.append("-DGUI_EXPORT="+export)

# more settings for analysis lib
makefile_analysis.extra_libs.append("qgis_analysis")
makefile_analysis.extra_lib_dirs.append(build_path+"/src/analysis/vector"+intdir)
makefile_analysis.extra_include_dirs.append(src_path+"/src/analysis/vector")
makefile_analysis.extra_include_dirs.append(build_path+"/src/analysis/vector")
makefile_analysis.extra_include_dirs.append(src_path+"/src/plugins") # because of qgisplugin.h TODO: sort out
makefile_analysis.extra_cxxflags.append("-DANALYSIS_EXPORT="+export)

# Generate the Makefile itself.
makefile_core.generate()
makefile_gui.generate()
makefile_analysis.generate()

##########################################################################
# QGIS CONFIG
Expand Down
1 change: 1 addition & 0 deletions python/qgisconfig.py.in
Expand Up @@ -34,6 +34,7 @@ class QgisModuleMakefile(pyqtconfig.QtModuleMakefile):
# Make sure our C++ library is linked.
self.extra_libs.append("qgis_core")
self.extra_libs.append("qgis_gui")
self.extra_libs.append("qgis_analysis")

# Let the super-class do what it needs to.
pyqtconfig.QtModuleMakefile.finalise(self)

0 comments on commit 4a7839c

Please sign in to comment.