├── pstalgo ├── test │ ├── run.bat │ ├── run_x64.bat │ ├── tests │ │ ├── __init__.py │ │ ├── common.py │ │ ├── testcreatesegmentmap.py │ │ ├── testcallback.py │ │ ├── testcreatejunctions.py │ │ ├── testcreategraph.py │ │ ├── testcreatebufferpolygons.py │ │ └── graphs.py │ └── main.py ├── src │ ├── graph │ │ ├── SegmentGroupGraph.cpp │ │ ├── GraphColoring.cpp │ │ └── SimpleGraph.cpp │ ├── geometry │ │ ├── IsovistCalculator.cpp │ │ └── Polygon.cpp │ ├── Platform.h │ ├── PSTA.cpp │ ├── Platform.cpp │ ├── Progress.h │ ├── analyses │ │ ├── VisualConnectivity.cpp │ │ ├── Common.cpp │ │ ├── AngularChoice.cpp │ │ └── AngularChoiceAlgo.h │ ├── test │ │ └── CallbackTest.cpp │ ├── math │ │ └── Gaussian.cpp │ ├── system │ │ └── System.cpp │ ├── ProgressUtil.h │ ├── Raster.cpp │ ├── utils │ │ └── SimpleAlignedAllocator.cpp │ └── Debug.cpp ├── scripts │ ├── clean.bat │ ├── distr.bat │ └── deploy.bat ├── include │ └── pstalgo │ │ ├── utils │ │ ├── Concurrency.h │ │ ├── Macros.h │ │ ├── SimpleAlignedAllocator.h │ │ ├── DebugUtils.h │ │ ├── Perf.h │ │ ├── Span.h │ │ ├── Bit.h │ │ └── BitVector.h │ │ ├── gfx │ │ └── Blur.h │ │ ├── graph │ │ ├── GraphColoring.h │ │ ├── SimpleGraph.h │ │ └── SegmentGraph.h │ │ ├── math │ │ ├── Gaussian.h │ │ └── Integral.h │ │ ├── Types.h │ │ ├── geometry │ │ ├── ConvexHull.h │ │ ├── RegionPoints.h │ │ ├── SignedDistanceField.h │ │ └── Polygon.h │ │ ├── system │ │ └── System.h │ │ ├── Error.h │ │ ├── test │ │ └── CallbackTest.h │ │ ├── experimental │ │ ├── ShortestPathTraversal.h │ │ ├── FastSegmentBetweenness.h │ │ └── ArrayView.h │ │ ├── analyses │ │ ├── SegmentGroupIntegration.h │ │ ├── VisualConnectivity.h │ │ ├── Reach.h │ │ ├── RasterToPolygons.h │ │ ├── SegmentGrouping.h │ │ ├── NetworkIntegration.h │ │ ├── CreateJunctions.h │ │ ├── CreateBufferPolygons.h │ │ ├── ODBetweenness.h │ │ ├── AngularChoice.h │ │ ├── CreateSegmentMap.h │ │ ├── SegmentBetweenness.h │ │ └── AttractionDistance.h │ │ ├── pstalgo.h │ │ ├── Limits.h │ │ └── Debug.h ├── CMakeLists.txt ├── python │ └── pstalgo │ │ ├── log.py │ │ ├── callbacktest.py │ │ ├── raster.py │ │ ├── vector.py │ │ ├── segmentgroupintegration.py │ │ ├── fastsegmentbetweenness.py │ │ ├── reach.py │ │ ├── __init__.py │ │ └── segmentgrouping.py └── README.txt ├── .gitignore ├── pstqgis ├── src │ └── pst │ │ ├── icon.png │ │ ├── img │ │ └── isovist_tool.png │ │ ├── metadata.txt │ │ ├── ui │ │ ├── __init__.py │ │ ├── widgets │ │ │ ├── progressdialog.py │ │ │ ├── tabledataselectionwidget.py │ │ │ ├── __init__.py │ │ │ ├── widgetenableradiobutton.py │ │ │ ├── widgetenablecheckbox.py │ │ │ ├── multiselectionlistwidget.py │ │ │ └── colorpicker.py │ │ ├── wizard │ │ │ └── __init__.py │ │ ├── pages │ │ │ ├── __init__.py │ │ │ ├── finishpage.py │ │ │ └── readypage.py │ │ └── wizards │ │ │ ├── splitpolylineswiz.py │ │ │ ├── __init__.py │ │ │ ├── networkintegrationwiz.py │ │ │ └── segmentgroupingwiz.py │ │ ├── maptools │ │ ├── __init__.py │ │ └── isovist │ │ │ └── __init__.py │ │ ├── model │ │ ├── __init__.py │ │ └── settings.py │ │ ├── analyses │ │ ├── base.py │ │ └── __init__.py │ │ ├── utils.py │ │ └── __init__.py ├── scripts │ ├── clean.bat │ ├── package.bat │ └── deploy.bat ├── doc │ └── readme.txt └── README.txt └── README.txt /pstalgo/test/run.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | py -3 main.py 3 | pause -------------------------------------------------------------------------------- /pstalgo/test/run_x64.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | py -3-64 main.py 3 | pause -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/build/ 2 | **/bin/ 3 | *.pyc 4 | **/.vs/ 5 | *.vcxproj.user 6 | *.sln -------------------------------------------------------------------------------- /pstqgis/src/pst/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SMoG-Chalmers/PST/HEAD/pstqgis/src/pst/icon.png -------------------------------------------------------------------------------- /pstqgis/src/pst/img/isovist_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SMoG-Chalmers/PST/HEAD/pstqgis/src/pst/img/isovist_tool.png -------------------------------------------------------------------------------- /pstalgo/src/graph/SegmentGroupGraph.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SMoG-Chalmers/PST/HEAD/pstalgo/src/graph/SegmentGroupGraph.cpp -------------------------------------------------------------------------------- /pstalgo/src/geometry/IsovistCalculator.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SMoG-Chalmers/PST/HEAD/pstalgo/src/geometry/IsovistCalculator.cpp -------------------------------------------------------------------------------- /pstqgis/scripts/clean.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | PUSHD %~dp0.. 4 | 5 | rmdir deploy /s /q 6 | del *.zip 7 | for /f "delims=" %%i in ('dir /a:d /s /b __pycache__') do rd /s /q "%%i" 8 | del *.pyc /s /q 9 | 10 | POPD -------------------------------------------------------------------------------- /pstalgo/scripts/clean.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | PUSHD %~dp0.. 4 | 5 | for /f "delims=" %%i in ('dir /a:d /s /b build') do rd /s /q "%%i" 6 | for /f "delims=" %%i in ('dir /a:d /s /b __pycache__') do rd /s /q "%%i" 7 | del *.pyc /s /q 8 | 9 | POPD -------------------------------------------------------------------------------- /pstqgis/scripts/package.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | set pstqgis_dir=%~dp0.. 4 | set deploy_dir=%pstqgis_dir%\deploy 5 | 6 | del %pstqgis_dir%\pstqgis_*.zip 7 | 7z a %pstqgis_dir%\pstqgis_%DATE%.zip -tzip -r %deploy_dir%/*.* 8 | %DISTRIBUTION_ROOT%\zipchmod\bin\zipchmod32.exe %pstqgis_dir%\pstqgis_%DATE%.zip command 0100755 9 | 10 | pause -------------------------------------------------------------------------------- /pstalgo/scripts/distr.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | set pstalgo_dir=%~dp0.. 4 | 5 | IF "%DISTRIBUTION_ROOT%"=="" ( 6 | ECHO ERROR: Environment variable DISTRIBUTION_ROOT has not been set 7 | EXIT 8 | ) 9 | 10 | rd %DISTRIBUTION_ROOT%\pstalgo /s /q 11 | xcopy %pstalgo_dir%\bin\*.dll %DISTRIBUTION_ROOT%\pstalgo\bin\ /s /y 12 | xcopy %pstalgo_dir%\include\*.* %DISTRIBUTION_ROOT%\pstalgo\include\ /s /y 13 | xcopy %pstalgo_dir%\bin\*.lib %DISTRIBUTION_ROOT%\pstalgo\lib\ /s /y -------------------------------------------------------------------------------- /pstalgo/scripts/deploy.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | if "%1" EQU "" goto usage 4 | if "%2" NEQ "" goto usage 5 | 6 | set pstalgo_dir=%~dp0.. 7 | set target_dir=%1 8 | 9 | xcopy %pstalgo_dir%\bin\*32.dll %target_dir%\pstalgo\bin\ /y 10 | xcopy %pstalgo_dir%\bin\*64.dll %target_dir%\pstalgo\bin\ /y 11 | xcopy %pstalgo_dir%\bin\libpstalgo.dylib %target_dir%\pstalgo\bin\ /y 12 | xcopy %pstalgo_dir%\python\*.py %target_dir%\pstalgo\python\ /s /y 13 | 14 | goto:eof 15 | 16 | :usage 17 | ECHO Usage: deploy TARGET_FOLDER 18 | exit /B 1 -------------------------------------------------------------------------------- /pstqgis/scripts/deploy.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | set pstqgis_dir=%~dp0.. 4 | set deploy_dir=%pstqgis_dir%\deploy 5 | 6 | IF "%PSTALGO_PATH%" == "" ( 7 | set pstalgo_dir=%pstqgis_dir%\..\pstalgo 8 | ) ELSE ( 9 | set pstalgo_dir=%PSTALGO_PATH% 10 | ) 11 | 12 | rmdir %deploy_dir% /s /q 13 | mkdir %deploy_dir% 14 | mkdir %deploy_dir%\pst 15 | 16 | xcopy %pstqgis_dir%\src\pst\*.py %deploy_dir%\pst /sy 17 | xcopy %pstqgis_dir%\src\pst\*.png %deploy_dir%\pst /sy 18 | xcopy %pstqgis_dir%\src\pst\metadata.txt %deploy_dir%\pst /y 19 | copy %pstqgis_dir%\doc\readme.txt %deploy_dir%\pst /y 20 | 21 | CALL %pstalgo_dir%\scripts\deploy.bat %deploy_dir%\pst 22 | 23 | pause -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/Concurrency.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace psta 8 | { 9 | template 10 | void parallel_for(TIndex end_index, TLambda&& lmbd) 11 | { 12 | std::atomic common_index_counter(0); 13 | 14 | auto worker = [&]() 15 | { 16 | for (;;) 17 | { 18 | const auto index = common_index_counter++; 19 | if (index >= end_index) 20 | { 21 | break; 22 | } 23 | 24 | lmbd(index); 25 | } 26 | }; 27 | 28 | std::vector> workers; 29 | for (uint32_t i = 0; i < std::thread::hardware_concurrency() - 1; ++i) 30 | { 31 | workers.push_back(std::async(std::launch::async, worker)); 32 | } 33 | 34 | worker(); 35 | 36 | for (auto& w : workers) 37 | { 38 | w.wait(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /pstqgis/src/pst/metadata.txt: -------------------------------------------------------------------------------- 1 | [general] 2 | name=PST 3 | author=KTH School of Architecture, Chalmers Architecture and Spacescape AB (Alexander Ståhle, Lars Marcus, Daniel Koch, Martin Fitger, Anders Karlström, Tobias Nordström, Ann Legeby, Gianna Stavroulaki, Meta Berghauser Pont, Pablo Miranda). 4 | qgisMinimumVersion=3.0 5 | qgisMaximumVersion=3.99 6 | description=PST is a plugin application for the desktop software QGIS that combines space syntax with regular accessibility analysis in one tool. 7 | about=PST is a plugin application for the desktop software QGIS that combines space syntax with regular accessibility analysis in one tool. PST Documentation is available via KTH (https://www.arch.kth.se/forskning/urban-design/software) and Chalmers (https://www.smog.chalmers.se/PST.html). 8 | version=3.3.1 9 | experimental=False 10 | category=Vector 11 | supportsQt6=True -------------------------------------------------------------------------------- /pstalgo/test/tests/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | -------------------------------------------------------------------------------- /pstalgo/src/Platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | unsigned int GetTimeMSec(); -------------------------------------------------------------------------------- /pstqgis/src/pst/maptools/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .isovist import IsovistMapTool -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/progressdialog.py: -------------------------------------------------------------------------------- 1 | from qgis.PyQt.QtWidgets import ( 2 | QApplication, 3 | QDialog, 4 | QLabel, 5 | QProgressBar, 6 | QVBoxLayout, 7 | ) 8 | 9 | MAX_PROGRESS = 10000 10 | 11 | class ProgressDialog(QDialog): 12 | def __init__(self, title = "Progress", text = "", parent = None): 13 | QDialog.__init__(self, parent) 14 | self.setWindowTitle(title) 15 | 16 | self._app = QApplication.instance() 17 | 18 | vlayout = QVBoxLayout() 19 | 20 | self._label = QLabel(text, self) 21 | vlayout.addWidget(self._label) 22 | 23 | self._progressBar = QProgressBar(self) 24 | self._progressBar.setMinimum(0) 25 | self._progressBar.setMaximum(MAX_PROGRESS) 26 | vlayout.addWidget(self._progressBar) 27 | 28 | self.setLayout(vlayout) 29 | 30 | def setProgress(self, progress): 31 | self._progressBar.setValue(int(progress * MAX_PROGRESS + 0.5)) 32 | self._app.processEvents() 33 | 34 | def setText(self, text): 35 | self._label.setText(text) 36 | self._app.processEvents() -------------------------------------------------------------------------------- /pstqgis/src/pst/maptools/isovist/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .isovistmaptool import IsovistMapTool -------------------------------------------------------------------------------- /pstqgis/src/pst/model/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .model import GeometryType, QGISModel 23 | from .settings import Settings -------------------------------------------------------------------------------- /pstalgo/src/PSTA.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | PSTADllExport void PSTAFree(IPSTAlgo* algo) 25 | { 26 | delete algo; 27 | } 28 | -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/wizard/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .wizard import BasePage, BaseWiz, WizProp, WizPropBase, WizPropManual, WizPropFloat, WizPropRadio, WizPropCombo -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/gfx/Blur.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace psta 27 | { 28 | void GaussianBlur(Arr2dView& img, float sigma_range); 29 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/graph/GraphColoring.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | class CSimpleGraph; 25 | 26 | // Greedy algorithm that colors nodes in order of decreasing valency 27 | unsigned int ColorGraph(const CSimpleGraph& graph, unsigned int* out_colors); -------------------------------------------------------------------------------- /pstalgo/src/Platform.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | unsigned int GetTimeMSec() 25 | { 26 | auto t = std::chrono::steady_clock::now().time_since_epoch(); 27 | return (unsigned int)std::chrono::duration_cast(t).count(); 28 | } 29 | -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/tabledataselectionwidget.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .multiselectionlistwidget import MultiSelectionListWidget 23 | 24 | class TableDataSelectionWidget(MultiSelectionListWidget): 25 | def updateContents(self, model, table_name): 26 | self.setItems(model.columnNames(table_name)) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/math/Gaussian.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace psta 27 | { 28 | inline float GaussianFunc(float x) 29 | { 30 | return std::exp(-0.5f * (x * x)); 31 | } 32 | 33 | void GenerateGaussianKernel(float sigma_range, unsigned int num_values, float* ret_values); 34 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/Types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | typedef char int8; 25 | typedef unsigned char uint8; 26 | typedef short int16; 27 | typedef unsigned short uint16; 28 | typedef int int32; 29 | typedef unsigned int uint32; 30 | typedef long long int64; 31 | typedef unsigned long long uint64; -------------------------------------------------------------------------------- /pstalgo/src/Progress.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | class IProgressCallback 25 | { 26 | public: 27 | void operator=(const IProgressCallback& other) = delete; 28 | 29 | // progress = [0..1] 30 | virtual void ReportProgress(float progress) = 0; 31 | 32 | virtual void ReportStatus(const char* text) = 0; 33 | 34 | // Return TRUE = cancel, FALSE = continue 35 | virtual bool GetCancel() = 0; 36 | }; -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/Macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #define BIT(x) (1 << (x)) 25 | 26 | #define INFINITE_LOOP for(;;) 27 | 28 | #ifdef _MSC_VER 29 | #define ALLOW_NAMELESS_STRUCT_BEGIN __pragma(warning(push)) __pragma(warning(disable:4201)) 30 | #define ALLOW_NAMELESS_STRUCT_END __pragma(warning(pop)) 31 | #else 32 | #define ALLOW_NAMELESS_STRUCT_BEGIN 33 | #define ALLOW_NAMELESS_STRUCT_END 34 | #endif -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/math/Integral.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | namespace psta 25 | { 26 | template float IntegralApprox(TFunc&& F, float x0, float x1, unsigned int num_steps) 27 | { 28 | const float step = (x1 - x0) / num_steps; 29 | const float half_step = 0.5f * step; 30 | float sum = 0.0f; 31 | float x = x0 + half_step; 32 | for (unsigned int i = 0; i < num_steps; ++i, x += step) 33 | sum += F(x); 34 | return sum * step; 35 | } 36 | } -------------------------------------------------------------------------------- /pstalgo/test/tests/common.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | def IsRoughlyEqual(v0, v1, max_rel_diff=0.0001): 23 | if 0 == v0: 24 | return abs(v1-v0) <= max_rel_diff 25 | return abs((v1-v0)/v0) <= max_rel_diff 26 | 27 | def IsArrayRoughlyEqual(a0, a1, max_rel_diff=0.0001): 28 | if len(a0) != len(a1): 29 | raise Exception("Array lengths do not match, %d != %d" % (len(a0), len(a1))) 30 | for i in range(len(a0)): 31 | if not IsRoughlyEqual(a0[i], a1[i], max_rel_diff): 32 | return False 33 | return True -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/SimpleAlignedAllocator.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | class CSimpleAlignedAllocator 27 | { 28 | public: 29 | CSimpleAlignedAllocator(unsigned int block_size, unsigned int alignment_bits = 4); 30 | ~CSimpleAlignedAllocator(); 31 | void FreeAll(); 32 | void* Alloc(size_t size); 33 | private: 34 | unsigned int m_CurrentUsage; 35 | unsigned int m_BlockSize; 36 | unsigned int m_AlignmentBits; 37 | std::list m_Blocks; 38 | }; 39 | -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .multiselectionlistwidget import MultiSelectionListWidget 23 | from .propertysheet import PropertySheetWidget, PropertyStyle, PropertyState 24 | from .tabledataselectionwidget import TableDataSelectionWidget 25 | from .widgetenablecheckbox import WidgetEnableCheckBox 26 | from .widgetenableradiobutton import WidgetEnableRadioButton 27 | from .colorpicker import ColorPicker 28 | from .progressdialog import ProgressDialog -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/pages/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .columncopypage import ColumnCopyPage 23 | from .entrypointspage import EntryPointsPage 24 | from .finishpage import FinishPage 25 | from .graphinputpage import GraphInputPage 26 | from .networkinputpage import NetworkInputPage, NetworkTypeFlags 27 | from .progresspage import ProgressPage 28 | from .radiuspage import RadiusPage, AddRadiusProperties, RadiusWidget, RadiusType, RadiusTypePropName 29 | from .readypage import ReadyPage -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/geometry/ConvexHull.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | /** 28 | * Calculates convex hull of a set of points. 29 | * The supplied point array must not contain duplicates and must 30 | * be sorted by increasing x and increasing y. 31 | */ 32 | int ConvexHull(const float2* sorted_points, int count, float2* ret_hull); 33 | 34 | /** 35 | * Calculates area of a convex polygon. 36 | */ 37 | float ConvexPolyArea(const float2* points, unsigned int count); 38 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/system/System.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #if defined(__x86_64__) || defined(__ppc64__) || defined(__LP64__) || defined(_WIN64) 25 | #define PSTA_64 1 26 | #else 27 | #define PSTA_32 1 28 | #endif 29 | 30 | #ifdef WIN32 31 | #define PSTA_WIN 1 32 | #elif defined __GNUC__ 33 | #define PSTA_GCC 1 34 | #endif 35 | 36 | namespace psta 37 | { 38 | class CLowerThreadPrioInScope 39 | { 40 | public: 41 | CLowerThreadPrioInScope(); 42 | ~CLowerThreadPrioInScope(); 43 | private: 44 | int m_PrevPrio; 45 | }; 46 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/Error.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace psta 29 | { 30 | template 31 | inline TException FormatException(const char* fmt, ...) 32 | { 33 | char szMessage[1024]; 34 | va_list args; 35 | va_start(args, fmt); 36 | #ifdef _MSC_VER 37 | vsnprintf_s(szMessage, _TRUNCATE, fmt, args); 38 | #else 39 | vsnprintf(szMessage, sizeof(szMessage), fmt, args); 40 | #endif 41 | return TException(szMessage); 42 | } 43 | } -------------------------------------------------------------------------------- /pstalgo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(pstalgo) 3 | 4 | set(CMAKE_BUILD_TYPE Release) 5 | 6 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/../bin) 7 | 8 | # Mac: Set architectures to build for both x86_64 and arm64 9 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") 10 | 11 | # We need C++11 12 | include(CheckCXXCompilerFlag) 13 | CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14) 14 | CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) 15 | CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) 16 | if(COMPILER_SUPPORTS_CXX14) 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") 18 | elseif(COMPILER_SUPPORTS_CXX11) 19 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 20 | elseif(COMPILER_SUPPORTS_CXX0X) 21 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 22 | else() 23 | message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") 24 | endif() 25 | 26 | # Include files 27 | include_directories(include) 28 | 29 | # Source files 30 | file(GLOB_RECURSE SOURCES "src/*.cpp") 31 | 32 | # Generate the shared library from the sources 33 | add_library(pstalgo SHARED ${SOURCES}) 34 | 35 | # Set the location for library installation -- i.e., /usr/lib in this case 36 | # install(TARGETS testStudent DESTINATION /usr/lib) 37 | 38 | # Add PSTADLL_EXPORTS definition for Windows DLL exports 39 | target_compile_definitions(pstalgo PRIVATE PSTADLL_EXPORTS) 40 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/test/CallbackTest.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | struct SCallbackTestDesc 27 | { 28 | SCallbackTestDesc() : m_Version(VERSION) {} 29 | 30 | // Version 31 | static const unsigned int VERSION = 1; 32 | unsigned int m_Version; 33 | 34 | char* m_Status; 35 | float m_Progress; 36 | int m_ReturnValue; 37 | 38 | // Progress Callback 39 | FPSTAProgressCallback m_ProgressCallback; 40 | void* m_ProgressCallbackUser; 41 | }; 42 | 43 | PSTADllExport int PSTACallbackTest(const SCallbackTestDesc* desc); -------------------------------------------------------------------------------- /pstalgo/test/tests/testcreatesegmentmap.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import array 23 | import unittest 24 | import pstalgo 25 | 26 | class TestCreateSegmentMap(unittest.TestCase): 27 | 28 | def test_createsegmentmap(self): 29 | coords = array.array('d', [ 30 | 0, 0, 31 | 1, 0, 32 | ]) 33 | polys = array.array('i', [ 34 | 2, 35 | ]) 36 | (res, algo) = pstalgo.CreateSegmentMap(pstalgo.common.RoadNetworkType.AXIAL_OR_SEGMENT, coords, polys) # , tail=50, progress_callback=self._pstalgo.CreateAnalysisDelegateCallbackWrapper(delegate)) 37 | pstalgo.Free(algo) -------------------------------------------------------------------------------- /pstqgis/src/pst/analyses/base.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | 23 | # Delegate interface, dummy class 24 | from builtins import object 25 | class AnalysisDelegate(object): 26 | def setProgress(self, progress): 27 | pass 28 | def setStatus(self, text): 29 | pass 30 | def getCancel(self): 31 | return False 32 | 33 | 34 | class BaseAnalysis(object): 35 | def __init__(self): 36 | self._want_cancel = False 37 | self._error = None 38 | 39 | def run(self, delegate): 40 | pass 41 | 42 | 43 | class AnalysisException(Exception): 44 | def __init__(self, text): 45 | Exception.__init__(self, text) -------------------------------------------------------------------------------- /pstalgo/src/analyses/VisualConnectivity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include "../ProgressUtil.h" 25 | 26 | 27 | PSTADllExport psta_raster_handle_t PSTAVisualConnectivity(SVisualConnectivityDesc* desc) 28 | { 29 | try { 30 | VerifyStructVersion(*desc); 31 | 32 | CPSTAlgoProgressCallback progress(desc->m_ProgressCallback, desc->m_ProgressCallbackUser); 33 | 34 | 35 | return nullptr; 36 | } 37 | catch (const std::exception& e) { 38 | LOG_ERROR(e.what()); 39 | } 40 | catch (...) { 41 | LOG_ERROR("Unknown exception"); 42 | } 43 | return nullptr; 44 | } -------------------------------------------------------------------------------- /pstalgo/src/test/CallbackTest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "../ProgressUtil.h" 26 | 27 | PSTADllExport int PSTACallbackTest(const SCallbackTestDesc* desc) 28 | { 29 | ASSERT(desc); 30 | 31 | if (desc->VERSION != desc->m_Version) 32 | return -1; 33 | 34 | CPSTAlgoProgressCallback progress_callback(desc->m_ProgressCallback, desc->m_ProgressCallbackUser); 35 | 36 | progress_callback.ReportProgress(desc->m_Progress); 37 | progress_callback.ReportStatus(desc->m_Status); 38 | 39 | return progress_callback.GetCancel() ? 0 : desc->m_ReturnValue; 40 | } 41 | -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/widgetenableradiobutton.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtCore import Qt 23 | from qgis.PyQt.QtWidgets import QRadioButton 24 | 25 | class WidgetEnableRadioButton(QRadioButton): 26 | def __init__(self, text, widgets=[], parent=None): 27 | QRadioButton.__init__(self, text, parent) 28 | self._widgets = [] 29 | for w in widgets: 30 | self.addWidget(w) 31 | self.toggled.connect(self.onToggled) 32 | 33 | def addWidget(self, w): 34 | self._widgets.append(w) 35 | w.setEnabled(self.isChecked()) 36 | 37 | def onToggled(self, checked): 38 | for w in self._widgets: 39 | w.setEnabled(checked) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/DebugUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | template 26 | void TWriteVec(const char* path, std::vector& v) 27 | { 28 | FILE* f = fopen(path, "wb"); 29 | fwrite(v.data(), 1, sizeof(T) * v.size(), f); 30 | fclose(f); 31 | } 32 | 33 | template 34 | std::vector TReadVec(const char* path) 35 | { 36 | FILE* f = fopen(path, "rb"); 37 | fseek(f, 0, SEEK_END); 38 | size_t file_size = ftell(f); 39 | fseek(f, 0, SEEK_SET); 40 | std::vector v(file_size / sizeof(T)); 41 | const size_t nread = fread(v.data(), 1, file_size, f); 42 | ASSERT(nread == file_size); 43 | fclose(f); 44 | return v; 45 | } 46 | -------------------------------------------------------------------------------- /pstqgis/src/pst/utils.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | def lerp(a, b, t): 23 | return a + (b - a) * t 24 | 25 | def lerpIntegerTuple(a, b, t): 26 | return tuple(int(round(lerp(a[i], b[i], t))) for i in len(a)) 27 | 28 | def tupleFromHtmlColor(htmlColor): 29 | firstCharIndex = 1 if htmlColor[0] == '#' else 0 30 | colorCharCount = len(htmlColor) - firstCharIndex 31 | if colorCharCount == 3 or colorCharCount == 4: 32 | return tuple(int(htmlColor[firstCharIndex+i],16)*16 for i in range(colorCharCount)) 33 | elif colorCharCount == 6 or colorCharCount == 8: 34 | return tuple(int(htmlColor[firstCharIndex+(i*2):firstCharIndex+((i+1)*2)],16) for i in range(int(colorCharCount/2))) 35 | raise TypeError("Invalid HTML color format") -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/geometry/RegionPoints.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | size_t GeneratePointsAlongRegionEdge(const float2* points, unsigned int point_count, float interval, float2* buffer = nullptr, size_t max_count = 0); 28 | void GeneratePointsAlongRegionEdge(const float2* points, unsigned int point_count, float interval, std::vector& ret_points); 29 | 30 | size_t GeneratePointsAlongRegionEdge(const double2* points, unsigned int point_count, float interval, double2* buffer = nullptr, size_t max_count = 0); 31 | void GeneratePointsAlongRegionEdge(const double2* points, unsigned int point_count, float interval, std::vector& ret_points); -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/widgetenablecheckbox.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtCore import Qt 23 | from qgis.PyQt.QtWidgets import QCheckBox 24 | 25 | class WidgetEnableCheckBox(QCheckBox): 26 | def __init__(self, text, widgets=[], parent=None): 27 | QCheckBox.__init__(self, text, parent) 28 | self._widgets = [] 29 | for w in widgets: 30 | self.addWidget(w) 31 | self.stateChanged.connect(self.onStateChanged) 32 | 33 | def addWidget(self, w): 34 | self._widgets.append(w) 35 | w.setEnabled(Qt.CheckState.Checked == self.checkState()) 36 | 37 | def onStateChanged(self, state): 38 | enabled = (Qt.CheckState.Checked == state) 39 | for w in self._widgets: 40 | w.setEnabled(enabled) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/geometry/SignedDistanceField.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace psta 31 | { 32 | struct SPolygon 33 | { 34 | typedef std::vector ring_t; 35 | std::vector Rings; 36 | }; 37 | 38 | std::vector PolygonsFromSdfGrid(const Arr2dView& sdf, float range_min, float range_max = std::numeric_limits::max()); 39 | 40 | void AddLineSegmentToSdf(Arr2dView& sdf, const float2& p0, const float2& p1, float maxDistance); 41 | 42 | void AddLineSegmentToSdf2(Arr2dView& sdf, const float2& p0, const float2& p1, float maxDistance, float resolution, float strength); 43 | } -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/wizards/splitpolylineswiz.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from ..wizard import BaseWiz, BasePage, WizProp, WizPropFloat 23 | from ..pages import NetworkInputPage, ColumnCopyPage, ReadyPage, ProgressPage, FinishPage 24 | 25 | 26 | class SplitPolylinesWiz(BaseWiz): 27 | def __init__(self, parent, settings, model, task_factory): 28 | BaseWiz.__init__(self, parent, settings, model, "Split Polylines") 29 | self._task_factory = task_factory 30 | self.addPage(NetworkInputPage(point_src_available=False)) 31 | self.addPage(ColumnCopyPage()) 32 | self.addPage(ReadyPage()) 33 | self.addPage(ProgressPage()) 34 | self.addPage(FinishPage()) 35 | 36 | def createTask(self, props): 37 | """ Creates, initializes and returns a task object. """ 38 | return self._task_factory(props) -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/multiselectionlistwidget.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from builtins import range 23 | from qgis.PyQt.QtCore import Qt 24 | from qgis.PyQt.QtWidgets import QListWidget, QListWidgetItem 25 | 26 | class MultiSelectionListWidget(QListWidget): 27 | def __init__(self): 28 | QListWidget.__init__(self) 29 | 30 | def getSelectedItems(self): 31 | selection = [] 32 | for i in range(self.count()): 33 | item = self.item(i) 34 | if item.getCheckState() == Qt.CheckState.Checked: 35 | selection.append(item.text()) 36 | 37 | def setItems(self, items): 38 | self.clear() 39 | for name in items: 40 | item = QListWidgetItem(name) 41 | item.setFlags(item.flags() | Qt.ItemFlag.ItemIsUserCheckable) 42 | item.setCheckState(Qt.CheckState.Unchecked) 43 | self.addItem(item) -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/pages/finishpage.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtWidgets import QLabel, QVBoxLayout, QWizard, QWizardPage 23 | 24 | class FinishPage(QWizardPage): 25 | def __init__(self, title = "Analysis finished", sub_title = " "): 26 | QWizardPage.__init__(self) 27 | 28 | self.setTitle(title) 29 | self.setSubTitle(sub_title) 30 | 31 | self.createWidgets() 32 | 33 | self.setButtonText(QWizard.WizardButton.FinishButton, "Restart") 34 | self.setButtonText(QWizard.WizardButton.CancelButton, "Close") 35 | 36 | def createWidgets(self): 37 | vlayout = QVBoxLayout() 38 | vlayout.addWidget(QLabel("The analysis was performed successfully.")) 39 | vlayout.addStretch(1) 40 | vlayout.addWidget(QLabel("Click 'Restart' to do new analysis or 'Close' to close.")) 41 | self.setLayout(vlayout) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/graph/SimpleGraph.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | #include 27 | 28 | class CSimpleGraph 29 | { 30 | public: 31 | CSimpleGraph(); 32 | CSimpleGraph(const CSimpleGraph& other) = delete; 33 | CSimpleGraph(CSimpleGraph&& other); 34 | 35 | void operator=(CSimpleGraph&& other); 36 | 37 | void Reserve(uint32 node_count, uint32 edge_count); 38 | 39 | size_t NodeCount() const { return m_Nodes.size(); } 40 | 41 | void AddNode(const uint32* neighbours, uint32 neighbour_count); 42 | 43 | uint32 NeighbourCount(uint32 node_index) const; 44 | 45 | uint32 GetNeighbour(uint32 node_index, uint32 neighbour_index) const; 46 | 47 | private: 48 | struct SNode 49 | { 50 | uint32 m_NeighbourCount; 51 | uint32 m_FirstNeighbour; 52 | }; 53 | std::vector m_Nodes; 54 | std::vector m_Neighbours; 55 | }; 56 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/experimental/ShortestPathTraversal.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "DirectedMultiDistanceGraph.h" 27 | 28 | namespace psta 29 | { 30 | class IShortestPathTraversal 31 | { 32 | public: 33 | typedef CDirectedMultiDistanceGraph graph_t; 34 | typedef std::function dist_callback_t; 35 | 36 | virtual ~IShortestPathTraversal() {} 37 | virtual void Search(size_t origin_index, dist_callback_t& cb, const float* limits, float straight_line_distance_limit = std::numeric_limits::infinity()) = 0; 38 | virtual void SearchAccumulative(size_t origin_index, dist_callback_t& cb, const float* limits, float straight_line_distance_limit = std::numeric_limits::infinity()) = 0; 39 | }; 40 | 41 | std::unique_ptr CreateShortestPathTraversal(const CDirectedMultiDistanceGraph& graph); 42 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/SegmentGroupIntegration.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTASegmentGroupIntegrationDesc 29 | { 30 | SPSTASegmentGroupIntegrationDesc(); 31 | 32 | // Version 33 | static const unsigned int VERSION = 1; 34 | unsigned int m_Version; 35 | 36 | // Graph 37 | HPSTASegmentGroupGraph m_Graph; // Created with a call to PSTACreateSegmentGroupGraph 38 | 39 | // Radius 40 | SPSTARadii m_Radius; 41 | 42 | // Progress Callback 43 | FPSTAProgressCallback m_ProgressCallback; 44 | void* m_ProgressCallbackUser; 45 | 46 | // Output per group (optional) 47 | float* m_OutIntegration; 48 | unsigned int* m_OutNodeCount; // Number of reached nodes, INCLUDING origin node 49 | float* m_OutTotalDepth; 50 | }; 51 | 52 | PSTADllExport bool PSTASegmentGroupIntegration(const SPSTASegmentGroupIntegrationDesc* desc); -------------------------------------------------------------------------------- /pstalgo/test/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import sys, os, unittest 23 | 24 | def GetThisFilePath(): 25 | import inspect 26 | return os.path.abspath(inspect.stack()[0][1]) 27 | 28 | def ResolvePathRelativeToThisFile(rel_path): 29 | return os.path.abspath(os.path.join(os.path.dirname(GetThisFilePath()), rel_path)) 30 | 31 | # Import pstalgo 32 | sys.path.append(ResolvePathRelativeToThisFile("../python")) 33 | import pstalgo 34 | 35 | def MyLogCallback(error_level, domain, msg): 36 | print() 37 | print(pstalgo.FormatLogMessage(error_level, domain, msg)) 38 | 39 | if __name__ == '__main__': 40 | # It is important that we keep a reference to the callback handle, or callback object might get freed (causing crash)! 41 | callback_handle = pstalgo.RegisterLogCallback(MyLogCallback) 42 | 43 | testsuite = unittest.TestLoader().discover('.') 44 | unittest.TextTestRunner(verbosity=2).run(testsuite) 45 | 46 | pstalgo.UnregisterLogCallback(callback_handle) 47 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/VisualConnectivity.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "Common.h" 27 | 28 | 29 | struct SVisualConnectivityDesc 30 | { 31 | PSTA_DECL_STRUCT_NAME(SVisualConnectivityDesc) 32 | SVisualConnectivityDesc() : m_Version(VERSION) {} 33 | 34 | // Version 35 | static const unsigned int VERSION = 1; 36 | unsigned int m_Version; 37 | 38 | unsigned int m_PolygonCount; 39 | unsigned int* m_PointCountPerPolygon; 40 | double* m_PolygonPoints; 41 | 42 | double m_RangeMinX; 43 | double m_RangeMinY; 44 | double m_RangeMaxX; 45 | double m_RangeMaxY; 46 | float m_CellSize; 47 | float m_MaxViewDistance; 48 | 49 | // Progress Callback 50 | FPSTAProgressCallback m_ProgressCallback; 51 | void* m_ProgressCallbackUser; 52 | }; 53 | 54 | // NOTE: The handle must be freed with call to PSTAFree(). 55 | PSTADllExport psta_raster_handle_t PSTAVisualConnectivity(SVisualConnectivityDesc* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/Perf.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace psta 27 | { 28 | class CPerfTimer 29 | { 30 | public: 31 | typedef unsigned long long ticks_t; 32 | 33 | inline void Start() 34 | { 35 | m_Timestamp = CurrentTimestamp(); 36 | } 37 | 38 | inline ticks_t ReadAndRestart() 39 | { 40 | const auto last = m_Timestamp; 41 | m_Timestamp = CurrentTimestamp(); 42 | return m_Timestamp - last; 43 | } 44 | 45 | inline static float SecondsFromTicks(ticks_t ticks) 46 | { 47 | return SecondsPerTick() * ticks; 48 | } 49 | 50 | inline static float SecondsPerTick() 51 | { 52 | return (float)std::chrono::high_resolution_clock::duration::period::num / std::chrono::high_resolution_clock::duration::period::den; 53 | } 54 | 55 | inline static ticks_t CurrentTimestamp() 56 | { 57 | return (ticks_t)std::chrono::high_resolution_clock::now().time_since_epoch().count(); 58 | } 59 | 60 | private: 61 | ticks_t m_Timestamp; 62 | }; 63 | } -------------------------------------------------------------------------------- /pstalgo/src/math/Gaussian.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | namespace psta 26 | { 27 | void GenerateGaussianKernel(float sigma_range, unsigned int num_values, float* ret_values) 28 | { 29 | const unsigned int INTEGRAL_STEPS = 10; 30 | 31 | if (0 == num_values) 32 | return; 33 | 34 | const unsigned int radius = num_values - 1; 35 | 36 | const float step = sigma_range / (0.5f + radius); 37 | 38 | float x = 0.5f * step; 39 | ret_values[0] = 2.0f * IntegralApprox(GaussianFunc, 0.0f, x, INTEGRAL_STEPS); 40 | 41 | for (unsigned int i = 1; i < num_values; ++i, x += step) 42 | ret_values[i] = IntegralApprox(GaussianFunc, x, x + step, INTEGRAL_STEPS); 43 | 44 | // Normalize 45 | float sum = 0.5f * ret_values[0]; 46 | for (unsigned int i = 1; i < num_values; ++i) 47 | sum += ret_values[i]; 48 | const float normalize_multiplier = 0.5f / sum; 49 | for (unsigned int i = 0; i < num_values; ++i) 50 | ret_values[i] *= normalize_multiplier; 51 | } 52 | } -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/wizards/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .angularbetweennesswiz import AngularBetweennessWiz 23 | from .angularchoicewiz import AngularChoiceWiz 24 | from .angularintegrationwiz import AngularIntegrationWiz 25 | from .attractionbetweennesswiz import AttractionBetweennessWiz 26 | from .attractiondistancewiz import AttractionDistanceWiz 27 | from .attractionreachwiz import AttractionReachWiz 28 | from .compareresultswiz import CompareResultsWiz 29 | from .createsegmentmapwiz import CreateSegmentMapWiz 30 | from .createjunctionswiz import CreateJunctionsWiz 31 | from .isovistwiz import IsovistWiz 32 | from .networkbetweennesswiz import NetworkBetweennessWiz 33 | from .networkintegrationwiz import NetworkIntegrationWiz 34 | from .odbetweennesswiz import ODBetweennessWiz 35 | from .reachwiz import ReachWiz 36 | from .splitpolylineswiz import SplitPolylinesWiz 37 | 38 | # Experimental 39 | from .segmentgroupingwiz import SegmentGroupingWiz 40 | from .segmentgroupintegrationwiz import SegmentGroupIntegrationWiz -------------------------------------------------------------------------------- /pstalgo/test/tests/testcallback.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import unittest 23 | import pstalgo 24 | 25 | class TestCallback(unittest.TestCase): 26 | 27 | STATUS_TEXT = "Status test string" 28 | PROGRESS_VALUE = 0.5 29 | RETURN_VALUE = 123 30 | 31 | def callback1(self, status, progress): 32 | if status is not None: 33 | self.status = status 34 | else: 35 | self.progress = progress 36 | return False # 0 means continue 37 | 38 | def callback2(self, status, progress): 39 | return True # means cancel 40 | 41 | def test_callback(self): 42 | return_value = pstalgo.CallbackTest(self.STATUS_TEXT, self.PROGRESS_VALUE, self.RETURN_VALUE, self.callback1) 43 | self.assertEqual(self.status, self.STATUS_TEXT) 44 | self.assertEqual(self.progress, self.PROGRESS_VALUE) 45 | self.assertEqual(return_value, self.RETURN_VALUE) 46 | 47 | def test_cancel(self): 48 | return_value = pstalgo.CallbackTest(self.STATUS_TEXT, self.PROGRESS_VALUE, self.RETURN_VALUE, self.callback2) 49 | self.assertEqual(return_value, 0) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/Reach.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTAReachDesc 29 | { 30 | // Version 31 | static const unsigned int VERSION = 1; 32 | unsigned int m_Version = VERSION; 33 | 34 | // Graph 35 | HPSTAGraph m_Graph = nullptr; // Created with a call to PSTACreateGraph 36 | 37 | // Radius 38 | SPSTARadii m_Radius; 39 | 40 | // Origin points (optional) 41 | double2* m_OriginCoords = nullptr; 42 | unsigned int m_OriginCount = 0; 43 | 44 | // Progress Callback 45 | FPSTAProgressCallback m_ProgressCallback = nullptr; 46 | void* m_ProgressCallbackUser = nullptr; 47 | 48 | // Output 49 | // These can either be NULL or pointer to arrays of one element per origin (point or line) 50 | unsigned int* m_OutReachedCount = nullptr; // Number of reached lines, INCLUDING origin line 51 | float* m_OutReachedLength = nullptr; 52 | float* m_OutReachedArea = nullptr; // Square meters 53 | }; 54 | 55 | PSTADllExport bool PSTAReach(const SPSTAReachDesc* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/RasterToPolygons.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "Common.h" 27 | 28 | struct SRasterToPolygonsDesc 29 | { 30 | PSTA_DECL_STRUCT_NAME(SRasterToPolygonsDesc) 31 | 32 | SRasterToPolygonsDesc() : m_Version(VERSION) {} 33 | 34 | // Version 35 | static const unsigned int VERSION = 1; 36 | unsigned int m_Version; 37 | 38 | psta_raster_handle_t Raster; 39 | 40 | struct SRange 41 | { 42 | float Min; 43 | float Max; 44 | }; 45 | unsigned int RangeCount; 46 | const SRange* Ranges; 47 | 48 | unsigned int* OutPolygonCountPerRange; 49 | unsigned int* OutPolygonData; // ... , ... ... 50 | double* OutPolygonCoords; 51 | 52 | // Progress Callback 53 | FPSTAProgressCallback m_ProgressCallback; 54 | void* m_ProgressCallbackUser; 55 | }; 56 | 57 | // NOTE: The returned handle must be freed with call to PSTAFree(). 58 | PSTADllExport psta_handle_t PSTARasterToPolygons(SRasterToPolygonsDesc* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/SegmentGrouping.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTASegmentGroupingDesc 29 | { 30 | SPSTASegmentGroupingDesc(); 31 | 32 | // Version 33 | static const unsigned int VERSION = 1; 34 | unsigned int m_Version; 35 | 36 | // Graph 37 | HPSTASegmentGraph m_SegmentGraph; // Created with a call to PSTACreateGraph 38 | 39 | // Parameters 40 | float m_AngleThresholdDegrees; // [0..90] 41 | bool m_SplitGroupsAtJunctions; 42 | 43 | // Progress Callback 44 | FPSTAProgressCallback m_ProgressCallback; 45 | void* m_ProgressCallbackUser; 46 | 47 | unsigned int m_LineCount; // For verification of output array sizes 48 | 49 | // Output 50 | unsigned int* m_OutGroupIdPerLine; 51 | unsigned int m_OutGroupCount; // Will contain number of groups created on return 52 | unsigned int* m_OutColorPerLine; 53 | unsigned int m_OutColorCount; // Will contain number of colors used for coloring 54 | }; 55 | 56 | PSTADllExport bool PSTASegmentGrouping(SPSTASegmentGroupingDesc* desc); -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/widgets/colorpicker.py: -------------------------------------------------------------------------------- 1 | from qgis.PyQt import QtCore 2 | from qgis.PyQt.QtCore import Qt 3 | 4 | from qgis.PyQt.QtGui import ( 5 | QColor, 6 | QBrush, 7 | QPainter, 8 | ) 9 | 10 | from qgis.PyQt.QtWidgets import ( 11 | QFrame, 12 | QStyle, 13 | QStyleOptionFrame, 14 | QColorDialog, 15 | QLineEdit, 16 | ) 17 | 18 | 19 | class ColorPicker(QFrame): 20 | colorChanged = QtCore.pyqtSignal(QColor) 21 | colorSelected = QtCore.pyqtSignal(QColor) 22 | 23 | def __init__(self, parent, color): 24 | QFrame.__init__(self, parent) 25 | #self.setFrameShape(QFrame.Box) 26 | #self.setLineWidth(1) 27 | self.setCursor(Qt.PointingHandCursor) 28 | self.setColor(color) 29 | self.styleoption = QStyleOptionFrame() # QStyleOptionFrameV2 30 | editTemp = QLineEdit() 31 | editTemp.initStyleOption(self.styleoption) 32 | self._sizeHint = editTemp.sizeHint() 33 | 34 | def sizeHint(self): 35 | return self._sizeHint 36 | 37 | def color(self, color): 38 | return self._color 39 | 40 | def setColor(self, color): 41 | self._color = color 42 | self._brush = QBrush(color) 43 | self.repaint() 44 | 45 | def _selectColor(self): 46 | prevColor = self._color 47 | dialog = QColorDialog(self._color, self) 48 | dialog.currentColorChanged.connect(self.onColorChanged) 49 | dialog.colorSelected.connect(self.onColorChanged) 50 | if dialog.exec(): 51 | self.colorSelected.emit(self._color) 52 | else: 53 | self.setColor(prevColor) 54 | self.colorChanged.emit(prevColor) 55 | 56 | def mouseReleaseEvent(self, event): 57 | self._selectColor() 58 | 59 | def paintEvent(self, paintEvent): 60 | painter = QPainter(self) 61 | painter.setPen(Qt.PenStyle.NoPen) 62 | painter.setBrush(self._brush) 63 | # painter.drawRect(paintEvent.rect().adjusted(1,1,-1-1)) 64 | self.styleoption.rect = self.contentsRect() 65 | self.style().drawPrimitive(QStyle.PE_PanelLineEdit , self.styleoption, painter) 66 | 67 | @QtCore.pyqtSlot(QColor) 68 | def onColorChanged(self, color): 69 | self.setColor(color) 70 | self.colorChanged.emit(color) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/NetworkIntegration.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTANetworkIntegrationDesc 29 | { 30 | SPSTANetworkIntegrationDesc(); 31 | 32 | // Version 33 | static const unsigned int VERSION = 1; 34 | unsigned int m_Version; 35 | 36 | // Graph 37 | HPSTAGraph m_Graph; // Created with a call to PSTACreateGraph 38 | 39 | // Radius 40 | SPSTARadii m_Radius; 41 | 42 | // Progress Callback 43 | FPSTAProgressCallback m_ProgressCallback; 44 | void* m_ProgressCallbackUser; 45 | 46 | // Output per Junction (optional) 47 | double2* m_OutJunctionCoords; 48 | float* m_OutJunctionScores; 49 | unsigned int m_OutJunctionCount; 50 | 51 | // Output per Line (optional) 52 | float* m_OutLineIntegration; 53 | unsigned int* m_OutLineNodeCount; // Number of reached lines, INCLUDING origin line 54 | float* m_OutLineTotalDepth; 55 | }; 56 | 57 | float CalculateIntegrationScore(unsigned int N, float TD); 58 | 59 | PSTADllExport bool PSTANetworkIntegration(const SPSTANetworkIntegrationDesc* desc); -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/log.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from .common import _DLL 24 | 25 | class ErrorLevel: 26 | VERBOSE=0 27 | INFO=1 28 | WARNING=2 29 | ERROR=3 30 | 31 | ERROR_LEVEL_TEXT = [ 32 | "VERBOSE", 33 | "INFO", 34 | "WARNING", 35 | "ERROR", 36 | ] 37 | 38 | LOG_CALLBACK_TYPE = ctypes.CFUNCTYPE(None, ctypes.c_int, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p) 39 | 40 | def FormatLogMessage(error_level, domain, msg): 41 | if domain is None: 42 | return "%s: %s" % (ERROR_LEVEL_TEXT[error_level], msg) 43 | return "%s: (%s) %s" % (ERROR_LEVEL_TEXT[error_level], domain, msg) 44 | 45 | def RegisterLogCallback(pyfunc): 46 | def CallbackWrapper(error_level, domain, msg, user_data): 47 | pyfunc( 48 | error_level, 49 | None if domain is None else domain.decode("utf-8"), 50 | None if msg is None else msg.decode("utf-8")) 51 | cfunc = LOG_CALLBACK_TYPE(CallbackWrapper) 52 | handle = _DLL.PSTARegisterLogCallback(cfunc, ctypes.c_void_p()) 53 | if 0 == handle: 54 | raise Exception("PSTARegisterLogCallback failed.") 55 | return (cfunc, handle) 56 | 57 | def UnregisterLogCallback(handle): 58 | # Make the call 59 | fn = _DLL.PSTAUnregisterLogCallback 60 | fn(ctypes.c_int(handle[1])) -------------------------------------------------------------------------------- /pstalgo/src/geometry/Polygon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | // NOTE: Assumes polygon is not self-intersecting 25 | double2 PolygonCentroid(const double2* points, uint32 point_count, double& ret_area) 26 | { 27 | if (point_count < 3) 28 | { 29 | ret_area = 0; 30 | if (0 == point_count) 31 | return double2(0, 0); 32 | if (1 == point_count) 33 | return *points; 34 | return (points[0] + points[1]) * .5; 35 | } 36 | 37 | const auto p0_times_one_third = points[0] * (1.0 / 3); 38 | 39 | double poly_area_acc_times_two = 0; 40 | double2 poly_centroid_acc(0, 0); 41 | for (uint32 i = 2; i < point_count; ++i) 42 | { 43 | const auto v0 = points[i-1] - points[0]; 44 | const auto v1 = points[i] - points[i-1]; 45 | const auto v1_mid = (points[i] + points[i - 1]) * .5; 46 | const auto tri_area_times_two = crp(v0, v1); 47 | const auto tri_centroid = p0_times_one_third + (v1_mid * (2.0 / 3)); 48 | poly_area_acc_times_two += tri_area_times_two; 49 | poly_centroid_acc += tri_centroid * tri_area_times_two; 50 | } 51 | 52 | ret_area = poly_area_acc_times_two * .5; 53 | 54 | return (0.0 == poly_area_acc_times_two) ? points[0] : (poly_centroid_acc / poly_area_acc_times_two); 55 | } -------------------------------------------------------------------------------- /pstqgis/src/pst/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from __future__ import absolute_import 23 | 24 | # Load Metadata 25 | metadata = None 26 | def MetaData(): 27 | global metadata 28 | if metadata is None: 29 | import os, configparser 30 | my_dir = os.path.dirname(os.path.abspath(__file__)) 31 | metadata_path = os.path.join(my_dir, 'metadata.txt') 32 | with open(metadata_path, encoding="utf-8") as f: 33 | metadata_contents = f.read() 34 | metadata = configparser.ConfigParser() 35 | metadata.read_string(metadata_contents) 36 | return metadata 37 | 38 | APP_TITLE = MetaData()['general']['name'] 39 | 40 | def GetPSTAlgoPath(): 41 | import os 42 | path = os.environ.get('PSTALGO_PATH') 43 | if path is not None: 44 | return os.path.join(path, 'python') 45 | import inspect 46 | folder_of_this_file = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 47 | return os.path.join(folder_of_this_file, 'pstalgo', 'python') 48 | 49 | # Add PSTAlgo to sys path 50 | import sys 51 | PSTALGO_PATH = GetPSTAlgoPath() 52 | if PSTALGO_PATH not in sys.path: 53 | sys.path.append(PSTALGO_PATH) 54 | 55 | def classFactory(iface): 56 | from .main import PSTPlugin 57 | return PSTPlugin(iface) -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/callbacktest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from .common import _DLL, PSTALGO_PROGRESS_CALLBACK, CreateCallbackWrapper, DumpStructure 24 | 25 | class SCallbackTestDesc(ctypes.Structure) : 26 | _fields_ = [ 27 | ("m_Version", ctypes.c_uint), 28 | ("m_Status", ctypes.c_char_p), 29 | ("m_Progress", ctypes.c_float), 30 | ("m_ReturnValue", ctypes.c_int), 31 | ("m_ProgressCallback", PSTALGO_PROGRESS_CALLBACK), 32 | ("m_ProgressCallbackUser", ctypes.c_void_p) 33 | ] 34 | def __init__(self, *args): 35 | ctypes.Structure.__init__(self, *args) 36 | self.m_Version = 1 37 | 38 | def PSTACallbackTest(psta, desc): 39 | fn = psta.PSTACallbackTest 40 | fn.argtypes = [ctypes.POINTER(SCallbackTestDesc)] 41 | fn.restype = ctypes.c_int 42 | return fn(ctypes.byref(desc)) 43 | 44 | def CallbackTest(status, progress, return_value, progress_callback): 45 | desc = SCallbackTestDesc() 46 | desc.m_Status = ctypes.c_char_p(status.encode('utf-8')) # ctypes.create_string_buffer(status.encode('utf-8'))) 47 | desc.m_Progress = progress 48 | desc.m_ReturnValue = return_value 49 | desc.m_ProgressCallback = CreateCallbackWrapper(progress_callback) 50 | desc.m_ProgressCallbackUser = ctypes.c_void_p() 51 | return PSTACallbackTest(_DLL, desc) -------------------------------------------------------------------------------- /pstqgis/src/pst/analyses/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .angularchoiceanalysis import AngularChoiceAnalysis 23 | from .angularbetweennessanalysis import AngularBetweennessAnalysis 24 | from .angularintegrationanalysis import AngularIntegrationAnalysis 25 | from .attractionbetweennessanalysis import AttractionBetweennessAnalysis 26 | from .attractiondistanceanalysis import AttractionDistanceAnalysis 27 | from .attractionreachanalysis import AttractionReachAnalysis 28 | from .base import AnalysisException 29 | from .compareresultsanalysis import CompareResultsAnalysis 30 | from .createsegmentmapanalysis import CreateSegmentMapAnalysis 31 | from .createjunctionsanalysis import CreateJunctionsAnalysis 32 | from .isovistanalysis import IsovistAnalysis 33 | from .networkbetweennessanalysis import NetworkBetweennessAnalysis 34 | from .networkintegrationanalysis import NetworkIntegrationAnalysis 35 | from .odbetweennessanalysis import ODBetweennessAnalysis 36 | from .reachanalysis import ReachAnalysis 37 | from .splitpolylinesanalysis import SplitPolylinesAnalysis 38 | 39 | # Experimental 40 | from .segmentgroupinganalysis import SegmentGroupingAnalysis 41 | from .segmentgroupintegrationanalysis import SegmentGroupIntegrationAnalysis -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/raster.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from ctypes import byref, cdll, POINTER, Structure, c_double, c_float, c_int, c_uint, c_void_p, c_byte 24 | from .common import _DLL, PSTALGO_PROGRESS_CALLBACK, DOUBLE_PTR, CreateCallbackWrapper, UnpackArray, DumpStructure 25 | 26 | class RasterFormat: 27 | Undefined = 0 28 | Byte = 1 29 | Float = 2 30 | 31 | class SRasterData(Structure) : 32 | _fields_ = [ 33 | ("Version", c_uint), 34 | ("BBMinX", c_double), 35 | ("BBMinY", c_double), 36 | ("BBMaxX", c_double), 37 | ("BBMaxY", c_double), 38 | ("Width", c_uint), 39 | ("Height", c_uint), 40 | ("Pitch", c_uint), 41 | ("Format", c_byte), # RasterFormat 42 | ("Bits", c_void_p), 43 | ] 44 | def __init__(self, *args): 45 | Structure.__init__(self, *args) 46 | self.Version = 1 47 | 48 | def PSTAGetRasterData(psta, rasterHandle, rasterData): 49 | fn = psta.PSTAGetRasterData 50 | fn.argtypes = [c_void_p, POINTER(SRasterData)] 51 | fn.restype = c_int 52 | return fn(rasterHandle, byref(rasterData)) 53 | 54 | def GetRasterData(rasterHandle): 55 | rasterData = SRasterData() 56 | if 0 != PSTAGetRasterData(_DLL, rasterHandle, rasterData): 57 | raise Exception('PSTAGetRasterData failed') 58 | DumpStructure(rasterData) 59 | return rasterData -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/experimental/FastSegmentBetweenness.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "../analyses/Common.h" 26 | #include "../analyses/CreateGraph.h" 27 | 28 | struct SPSTAFastSegmentBetweennessDesc 29 | { 30 | // Version 31 | static const unsigned int VERSION = 2; 32 | unsigned int m_Version = VERSION; 33 | 34 | HPSTASegmentGraph m_Graph = nullptr; // Created with a call to PSTACreateSegmentGraph 35 | 36 | // Distance measurement 37 | unsigned char m_DistanceType = EPSTADistanceType_Angular; // enum EPSTADistanceType, only ANGULAR supported 38 | bool m_WeighByLength = false; // NOT YET SUPPORTED 39 | 40 | // Radius 41 | SPSTARadii m_Radius; // Only WALKING supported 42 | 43 | // Progress Callback 44 | FPSTAProgressCallback m_ProgressCallback = nullptr; 45 | void* m_ProgressCallbackUser = nullptr; 46 | 47 | // Output 48 | // These can either be NULL or pointer to arrays of one element per line 49 | float* m_OutBetweenness = nullptr; 50 | unsigned int* m_OutNodeCount = nullptr; // NOT YET SUPPORTED // Number of reached lines, INCLUDING origin line 51 | float* m_OutTotalDepth = nullptr; // NOT YET SUPPORTED 52 | }; 53 | 54 | PSTADllExport bool PSTAFastSegmentBetweenness(const SPSTAFastSegmentBetweennessDesc* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/CreateJunctions.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | struct SCreateJunctionsDesc 28 | { 29 | SCreateJunctionsDesc() : m_Version(VERSION) {} 30 | 31 | // Version 32 | static const unsigned int VERSION = 1; 33 | unsigned int m_Version; 34 | 35 | // Layer 0 36 | double2* m_Coords0; 37 | unsigned int* m_Lines0; // Can be NULL if m_Coords0 contains list of simple coordinate pairs 38 | unsigned int m_LineCount0; 39 | 40 | // Layer 1 41 | double2* m_Coords1; 42 | unsigned int* m_Lines1; // Can be NULL if m_Coords1 contains list of simple coordinate pairs 43 | unsigned int m_LineCount1; 44 | 45 | // Unlinks 46 | double2* m_UnlinkCoords; 47 | unsigned int m_UnlinkCount; 48 | 49 | // Progress Callback 50 | FPSTAProgressCallback m_ProgressCallback; 51 | void* m_ProgressCallbackUser; 52 | }; 53 | 54 | struct SCreateJunctionsRes 55 | { 56 | SCreateJunctionsRes() : m_Version(VERSION) {} 57 | 58 | // Version 59 | static const unsigned int VERSION = 1; 60 | unsigned int m_Version; 61 | 62 | // Junction points 63 | double* m_PointCoords; 64 | unsigned int m_PointCount; 65 | }; 66 | 67 | PSTADllExport IPSTAlgo* PSTACreateJunctions(const SCreateJunctionsDesc* desc, SCreateJunctionsRes* res); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/pstalgo.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #if defined(_MSC_VER) 25 | // Microsoft 26 | #ifdef PSTADLL_EXPORTS 27 | #define PSTADllExport extern "C" __declspec( dllexport ) 28 | #define PSTADllExportClass __declspec( dllexport ) 29 | #else 30 | #define PSTADllExport extern "C" __declspec( dllimport ) 31 | #define PSTADllExportClass __declspec( dllimport ) 32 | #endif 33 | #elif defined(__GNUC__) 34 | // GCC 35 | #define PSTADllExport extern "C" __attribute__((visibility("default"))) 36 | #define PSTADllExportClass __attribute__((visibility("default"))) 37 | #else 38 | #define PSTADllExport 39 | #define PSTADllExportClass 40 | #pragma warning Unknown dynamic link export semantics. 41 | #endif 42 | 43 | // Return 0 = continue, otherwise cancel 44 | typedef int(*FPSTAProgressCallback)(const char* text, float progress, void* user_data); 45 | 46 | class IPSTAlgo 47 | { 48 | public: 49 | virtual ~IPSTAlgo() {} 50 | 51 | void operator=(const IPSTAlgo&) = delete; 52 | }; 53 | 54 | typedef void* psta_handle_t; 55 | 56 | typedef int psta_result_t; 57 | 58 | #define PSTA_RESULT_OK 0 59 | #define PSTA_RESULT_ERROR 1 60 | 61 | PSTADllExport void PSTAFree(IPSTAlgo* algo); 62 | 63 | #define PSTA_DECL_STRUCT_NAME(T) inline static char* TypeName() { return #T; } 64 | #define PSTA_STRUCT_NAME(T) T::TypeName() -------------------------------------------------------------------------------- /pstalgo/src/graph/GraphColoring.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | unsigned int ColorGraph(const CSimpleGraph& graph, unsigned int* out_colors) 26 | { 27 | const uint32 NO_COLOR = (uint32)-1; 28 | 29 | for (uint32 i = 0; i < graph.NodeCount(); ++i) 30 | out_colors[i] = NO_COLOR; 31 | 32 | // Create ordering of nodes by (valency, index) 33 | std::vector order(graph.NodeCount()); 34 | for (uint32 i = 0; i < graph.NodeCount(); ++i) 35 | order[i] = i; 36 | std::sort(order.begin(), order.end(), [&](uint32 a, uint32 b) -> bool 37 | { 38 | const uint32 a_valency = graph.NeighbourCount(a); 39 | const uint32 b_valency = graph.NeighbourCount(b); 40 | return (a_valency == b_valency) ? (a < b) : (a_valency > b_valency); 41 | }); 42 | 43 | uint32 num_colors = 0; 44 | for (unsigned int i = 0; i < order.size(); ++i) 45 | { 46 | const auto node_index = order[i]; 47 | uint32 n, color = (uint32)-1; 48 | do 49 | { 50 | ++color; 51 | for (n = 0; n < graph.NeighbourCount(node_index); ++n) 52 | { 53 | if (color == out_colors[graph.GetNeighbour(node_index, n)]) 54 | break; 55 | } 56 | } while (graph.NeighbourCount(node_index) != n); 57 | out_colors[node_index] = color; 58 | if (color >= num_colors) 59 | num_colors = color + 1; 60 | } 61 | 62 | return num_colors; 63 | } -------------------------------------------------------------------------------- /pstalgo/src/graph/SimpleGraph.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | CSimpleGraph::CSimpleGraph() 25 | { 26 | } 27 | 28 | CSimpleGraph::CSimpleGraph(CSimpleGraph&& other) 29 | : m_Nodes(std::move(other.m_Nodes)) 30 | , m_Neighbours(std::move(other.m_Neighbours)) 31 | {} 32 | 33 | void CSimpleGraph::operator=(CSimpleGraph&& other) 34 | { 35 | if (&other == this) 36 | return; 37 | std::swap(m_Nodes, other.m_Nodes); 38 | std::swap(m_Neighbours, other.m_Neighbours); 39 | } 40 | 41 | void CSimpleGraph::Reserve(uint32 node_count, uint32 edge_count) 42 | { 43 | m_Nodes.reserve(node_count); 44 | m_Neighbours.reserve(edge_count * 2); 45 | } 46 | 47 | void CSimpleGraph::AddNode(const uint32* neighbours, uint32 neighbour_count) 48 | { 49 | m_Nodes.resize(m_Nodes.size() + 1); 50 | auto& node = m_Nodes.back(); 51 | node.m_NeighbourCount = neighbour_count; 52 | node.m_FirstNeighbour = (uint32)m_Neighbours.size(); 53 | for (uint32 i = 0; i < neighbour_count; ++i) 54 | m_Neighbours.push_back(neighbours[i]); 55 | } 56 | 57 | uint32 CSimpleGraph::NeighbourCount(uint32 node_index) const 58 | { 59 | return m_Nodes[node_index].m_NeighbourCount; 60 | } 61 | 62 | uint32 CSimpleGraph::GetNeighbour(uint32 node_index, uint32 neighbour_index) const 63 | { 64 | return m_Neighbours[m_Nodes[node_index].m_FirstNeighbour + neighbour_index]; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /pstalgo/src/system/System.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #ifdef WIN32 25 | #include 26 | #define INVALID_THREAD_PRIO THREAD_PRIORITY_ERROR_RETURN 27 | #else 28 | #define INVALID_THREAD_PRIO -1 29 | #endif 30 | 31 | namespace psta 32 | { 33 | CLowerThreadPrioInScope::CLowerThreadPrioInScope() 34 | : m_PrevPrio(INVALID_THREAD_PRIO) 35 | { 36 | #ifdef WIN32 37 | const auto current_thread = GetCurrentThread(); 38 | auto prio = GetThreadPriority(current_thread); 39 | auto new_prio = prio; 40 | switch (prio) 41 | { 42 | case THREAD_PRIORITY_BELOW_NORMAL: 43 | new_prio = THREAD_PRIORITY_LOWEST; 44 | break; 45 | case THREAD_PRIORITY_NORMAL: 46 | new_prio = THREAD_PRIORITY_BELOW_NORMAL; 47 | break; 48 | case THREAD_PRIORITY_ABOVE_NORMAL: 49 | new_prio = THREAD_PRIORITY_NORMAL; 50 | break; 51 | case THREAD_PRIORITY_HIGHEST: 52 | new_prio = THREAD_PRIORITY_ABOVE_NORMAL; 53 | break; 54 | default: 55 | // Leave priority unchanged 56 | return; 57 | } 58 | if (SetThreadPriority(current_thread, new_prio)) 59 | m_PrevPrio = prio; 60 | #endif 61 | } 62 | 63 | CLowerThreadPrioInScope::~CLowerThreadPrioInScope() 64 | { 65 | if (INVALID_THREAD_PRIO == m_PrevPrio) 66 | return; 67 | #ifdef WIN32 68 | SetThreadPriority(GetCurrentThread(), m_PrevPrio); 69 | #endif 70 | } 71 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/geometry/Polygon.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | double2 PolygonCentroid(const double2* points, uint32 point_count, double& ret_area); 29 | 30 | template 31 | bool TestPointInRing(const T& point, const psta::span& ring) 32 | { 33 | typedef decltype(point.x) scalar_t; 34 | 35 | if (ring.size() < 3) 36 | { 37 | return false; 38 | } 39 | int winding_count = 0; 40 | auto p0 = ring.back(); 41 | for (const auto& p1 : ring) 42 | { 43 | const int crossing_vertical_mask = (int)((p1.x - point.x) * (p0.x - point.x) >= (scalar_t)0) - 1; 44 | const auto cross_prod = crp(p0 - point, p1 - p0); 45 | const int direction = (cross_prod > 0) - (cross_prod < 0); 46 | winding_count += (int)(direction & crossing_vertical_mask); 47 | p0 = p1; 48 | } 49 | return winding_count != 0; 50 | } 51 | 52 | template 53 | bool TestPointInPolygon(const TVec2& point, psta::span> perimeter, psta::span>> holes = psta::span>>()) 54 | { 55 | if (!TestPointInRing(point, perimeter.data(), perimeter.size())) 56 | { 57 | return false; 58 | } 59 | 60 | for (const auto& hole : holes) 61 | { 62 | if (TestPointInRing(point, hole.data(), hole.size())) 63 | { 64 | return false; 65 | } 66 | } 67 | 68 | return true; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/CreateBufferPolygons.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "Common.h" 27 | 28 | struct SCompareResultsDesc 29 | { 30 | PSTA_DECL_STRUCT_NAME(SCompareResultsDesc) 31 | 32 | SCompareResultsDesc() : m_Version(VERSION) {} 33 | 34 | // Version 35 | static const unsigned int VERSION = 4; 36 | unsigned int m_Version; 37 | 38 | unsigned int LineCount1; 39 | double* LineCoords1; 40 | float* Values1; 41 | 42 | enum EMode : unsigned int 43 | { 44 | Normalized = 0, 45 | RelativePercent = 1, 46 | }; 47 | EMode Mode; 48 | 49 | float M; // Only applicable when Mode == RelativePercent 50 | 51 | unsigned int LineCount2; // Optional, must be zero if not used 52 | double* LineCoords2; // Optional, must be NULL if not used 53 | float* Values2; // Number of values from LineCount2 if two line sets are used, otherwise LineCount1. 54 | 55 | float BlurRadius; // Radius for 1 std dev. 56 | float Resolution; // Pixel size in meters 57 | 58 | psta_raster_handle_t OutRaster; 59 | float OutMin; 60 | float OutMax; 61 | 62 | // Progress Callback 63 | FPSTAProgressCallback m_ProgressCallback; 64 | void* m_ProgressCallbackUser; 65 | }; 66 | 67 | // NOTE: The returned handle must be freed with call to PSTAFree(). 68 | PSTADllExport psta_handle_t PSTACompareResults(SCompareResultsDesc* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/graph/SegmentGraph.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | class CSegmentGraph 29 | { 30 | public: 31 | // Represents an intersection of network segments - the "Edges" of the graph 32 | struct SIntersection 33 | { 34 | float2 m_Pos; 35 | unsigned int m_NumSegments; 36 | unsigned int m_Segments[1]; // Size will vary 0-N depending on allocation size of each SIntersection object 37 | }; 38 | 39 | // Represents a network segment - the "Nodes" of the graph 40 | struct SSegment 41 | { 42 | float2 m_Center; 43 | float m_Orientation; 44 | float m_Length; 45 | SIntersection* m_Intersections[2]; 46 | char m_Padding[8]; // TODO: Only if 32-bit! 47 | }; 48 | 49 | CSegmentGraph(); 50 | ~CSegmentGraph(); 51 | 52 | bool Create(const double2* line_coords, unsigned int line_coord_count, unsigned int* line_indices, unsigned int line_count); 53 | 54 | unsigned int GetSegmentCount() const { return (unsigned int)m_Segments.size(); } 55 | SSegment& GetSegment(unsigned int index) { return m_Segments[index]; } 56 | const SSegment& GetSegment(unsigned int index) const { return m_Segments[index]; } 57 | 58 | private: 59 | SIntersection* NewIntersection(unsigned int num_segments); 60 | 61 | std::vector m_Segments; 62 | CSimpleAlignedAllocator m_IntersectionAllocator; 63 | double2 m_WorldOrigin; 64 | }; -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | PST 2 | 3 | 4 | Overview 5 | -------- 6 | PST is a tool for performing space syntax and regular accessibility 7 | analyses. It currently consists of two main parts - a C++ and Python 8 | library called Pstalgo and a plugin for the desktop application QGIS. 9 | 10 | 11 | Pstalgo 12 | ------- 13 | Pstalgo is a C++ library that implements space syntax and regular 14 | accessibility analyses. There is also a Python interface for this library. 15 | For more information about Pstalgo please refer to the file 'README.txt' 16 | in the Pstalgo directory. 17 | 18 | 19 | PST for QGIS 20 | ------------ 21 | PST for QGIS is a plugin for the desktop application QGIS. It is written 22 | in Python and implements the user interface and all communication with 23 | QGIS. Pstqgis is dependant on the Pstalgo library. For more information 24 | about PST for QGIS please refer to the 'readme.txt' file in the pstqgis 25 | directory. 26 | 27 | 28 | License 29 | ------- 30 | Copyright 2019 Meta Berghauser Pont 31 | 32 | PST is free software: you can redistribute it and/or modify 33 | it under the terms of the GNU Lesser General Public License as published by 34 | the Free Software Foundation, either version 3 of the License, or 35 | (at your option) any later version. The GNU Lesser General Public License 36 | is intended to guarantee your freedom to share and change all versions 37 | of a program--to make sure it remains free software for all its users. 38 | 39 | PST is distributed in the hope that it will be useful, 40 | but WITHOUT ANY WARRANTY; without even the implied warranty of 41 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 42 | GNU Lesser General Public License for more details. 43 | 44 | You should have received a copy of the GNU Lesser General Public License 45 | along with PST. If not, see . 46 | 47 | 48 | Contact 49 | ------- 50 | Meta Berghauser Pont (copyright owner), meta.berghauserpont@chalmers.se 51 | Martin Fitger (programmer), martin.fitger@xmnsoftware.com 52 | 53 | 54 | Acknowledgements 55 | ---------------- 56 | PST is developed by KTH School of Architecture, Chalmers School of 57 | Architecture (SMoG) and Spacescape AB. Alexander Ståhle, Lars Marcus, 58 | Daniel Koch, Martin Fitger, Ann Legeby, Gianna Stavroulaki, 59 | Meta Berghauser Pont, Anders Karlström, Pablo Miranda Carranza, 60 | Tobias Nordström. -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/Limits.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | // DEPRECATED 30 | enum DistanceType { 31 | DIST_NONE = -1, 32 | DIST_STRAIGHT = 0, 33 | DIST_WALKING, 34 | DIST_LINES, 35 | DIST_ANGULAR, 36 | DIST_AXMETER, 37 | _DIST_COUNT 38 | }; 39 | 40 | // DEPRECATED 41 | struct LIMITS { 42 | enum { 43 | MASK_STRAIGHT = 0x01, 44 | MASK_WALKING = 0x02, 45 | MASK_TURNS = 0x04, 46 | MASK_ANGLE = 0x08, 47 | MASK_AXMETER = 0x10, 48 | }; 49 | unsigned int mask; 50 | float straightSqr; // NOTE: Stored as straight distance^2 for performance reasons 51 | float walking; 52 | int turns; 53 | float angle; 54 | float axmeter; 55 | public: 56 | LIMITS() : mask(0) {} 57 | public: 58 | bool set(struct DistanceSpec ds); 59 | std::string toString(); 60 | }; 61 | 62 | extern const char* DistanceTypeShortNames[_DIST_COUNT]; 63 | 64 | struct DistanceSpec { 65 | DistanceType type; 66 | float amount; 67 | const char* toString() const; 68 | }; 69 | 70 | class DistanceSet : public std::vector { 71 | public: 72 | bool addString(const char* pcszText, DistanceType distType); 73 | }; 74 | 75 | LIMITS LimitsFromSPSTARadii(const struct SPSTARadii& r); 76 | 77 | struct SPSTARadii PSTARadiiFromLimits(const LIMITS& lim); 78 | 79 | EPSTADistanceType EPSTADistanceTypeFromDistanceType(DistanceType distance_type); 80 | 81 | DistanceType DistanceTypeFromEPSTADistanceType(EPSTADistanceType distance_type); 82 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/ODBetweenness.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTAODBetweenness 29 | { 30 | // Version 31 | static const unsigned int VERSION = 1; 32 | unsigned int m_Version = VERSION; 33 | 34 | // Graph 35 | HPSTAGraph m_Graph = nullptr; // Created with a call to PSTACreateGraph 36 | 37 | // Origins 38 | const double2* m_OriginPoints = nullptr; 39 | const float* m_OriginWeights = nullptr; 40 | unsigned int m_OriginCount = 0; 41 | 42 | // Destinations (must match points in m_Graph member) 43 | const float* m_DestinationWeights = nullptr; 44 | unsigned int m_DestinationCount = 0; 45 | 46 | enum EDestinationMode 47 | { 48 | EDestinationMode_AllReachableDestinations = 0, 49 | EDestinationMode_ClosestDestinationOnly = 1, 50 | }; 51 | unsigned char m_DestinationMode = EDestinationMode_AllReachableDestinations; 52 | 53 | // Distance measurement 54 | unsigned char m_DistanceType = EPSTADistanceType_Walking; // enum EPSTADistanceType 55 | 56 | // Radius 57 | SPSTARadii m_Radius; 58 | 59 | // Progress Callback 60 | FPSTAProgressCallback m_ProgressCallback = nullptr; 61 | void* m_ProgressCallbackUser = nullptr; 62 | 63 | // Output 64 | // Pointer to array of one element per network element 65 | float* m_OutScores = nullptr; 66 | unsigned int m_OutputCount = 0; // For m_OutScores array size verification only 67 | }; 68 | 69 | PSTADllExport bool PSTAODBetweenness(const SPSTAODBetweenness* desc); -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/Span.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace psta 27 | { 28 | // TODO: Replace with std::span when available on all platforms 29 | 30 | template 31 | class span 32 | { 33 | public: 34 | span() {} 35 | span(T* elements, size_t size) : m_Data(elements), m_Size(size) {} 36 | span(T* begin, T* end) : m_Data(begin), m_Size(end - begin) {} 37 | 38 | inline bool empty() const { return 0 == m_Size; } 39 | 40 | inline size_t size() const { return m_Size; } 41 | 42 | inline T* data() { return m_Data; } 43 | inline const T* data() const { return m_Data; } 44 | 45 | inline T& back() { return m_Data[m_Size - 1]; } 46 | inline const T& back() const { return m_Data[m_Size - 1]; } 47 | 48 | inline T& operator[](size_t index) { return m_Data[index]; } 49 | inline const T& operator[](size_t index) const { return m_Data[index]; } 50 | 51 | T* begin() { return m_Data; } 52 | const T* begin() const { return m_Data; } 53 | 54 | T* end() { return m_Data + m_Size; } 55 | const T* end() const { return m_Data + m_Size; } 56 | 57 | protected: 58 | T* m_Data = nullptr; 59 | size_t m_Size = 0; 60 | }; 61 | 62 | template 63 | span make_span(T* data, size_t size) { return span(data, size); } 64 | 65 | template 66 | const span make_span(const T* data, size_t size) { return span(const_cast(data), size); } 67 | 68 | template 69 | const span make_span(const std::vector& v) { return make_span(const_cast(v.data()), v.size()); } 70 | } -------------------------------------------------------------------------------- /pstqgis/doc/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | PST is a plugin application for the desktop software QGIS that combines 3 | space syntax with regular accessibility analysis in one tool. 4 | 5 | 6 | Installation: 7 | 8 | 1. Start QGIS 3. 9 | 10 | 2. Click on "Plugins" / "Manage and Install Plugins..." to open the 11 | Plugin Manager dialog. 12 | 13 | 3. Select "Install from ZIP" in the left margin. 14 | 15 | 4. Click the "..."-button to the right of the "ZIP file"-field. 16 | 17 | 5. Browse to and select the PST ZIP-file. 18 | 19 | 6. Click the "Install Plugin"-button below the "ZIP file"-field (QGIS 20 | might show a warning here about installing plugins from untrusted 21 | sources). 22 | 23 | Alternatively, the plugin can be installed manually by unzipping the 24 | PST zip file into the following folder (NOTE: If the final "plugins" 25 | folder doesn't exist it has to be created first). 26 | 27 | Windows: 28 | C:\Users\{USERNAME}\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins 29 | 30 | where {USERNAME} is your user name (without {}-characters). 31 | 32 | Mac: 33 | ~/Library/Application Support/QGIS/QGIS3/profiles/default/python/plugins 34 | 35 | If done correctly you should end up with a folder called "pst" inside 36 | the "plugins" folder. 37 | 38 | 39 | Enabling the plugin: 40 | 41 | 1. Start QGIS 3. 42 | 43 | 2. Click on 'Plugins' / 'Manage and Install Plugins...' to open the 44 | Plugin Manager dialog. 45 | 46 | 3. Type in 'PST' in the search field. 47 | 48 | 4. Mark the checkbox of the PST plugin (if PST does not appear in the 49 | list make sure the installation above was done correctly). 50 | 51 | 5. PST will now appear in the 'Vector' menu. 52 | 53 | on Mac: 54 | 55 | 6. When you run the plugin for the first time you get the warning '"libpstalgo.dylib" cannot be opened because the developer cannot be verified'. 56 | 57 | 7. On your Mac, choose Apple menu  > System Preferences, click Security & Privacy, then click General. If the lock at the bottom left is locked, click it to unlock the preference pane. 58 | 59 | 8. Select the sources from which you’ll allow software to be installed: App Store and identified developers. 60 | 61 | 9. For the warning ‘“libpstalgo.dylib”’ was blocked from use because it is not from an identified developer’ click ‘Allow anyway’. 62 | 63 | 10. Restart QGIS. -------------------------------------------------------------------------------- /pstqgis/README.txt: -------------------------------------------------------------------------------- 1 | PST for QGIS 2 | 3 | 4 | Overview 5 | -------- 6 | PST for QGIS is a plugin for the desktop application QGIS. It is written 7 | in Python and implements the user interface and all communication with 8 | QGIS. PST for QGIS is dependant on the Pstalgo library for performing its 9 | analyses. 10 | 11 | 12 | Deployment 13 | ---------- 14 | There is a batch file called 'deploy.bat' that will assemble a plugin 15 | package that is ready to be used with QGIS. It will copy both Pstalgo 16 | binaries and necessary files from the pstqgis package into a subfolder 17 | 'deploy'. Please note that Pstalgo must be built before this is done (for 18 | instructions on how to build Pstalgo please refer to the 'readme.txt' file 19 | in the pstalgo directory). The contents of the generated 'deploy' folder 20 | can then be distributed/used as a regular QGIS plugin. Instructions for 21 | how to install the plugin will be available in a file 'readme.txt' in the 22 | generated 'deploy' directory. 23 | 24 | 25 | License 26 | ------- 27 | Copyright 2019 Meta Berghauser Pont 28 | 29 | PST for QGIS is part of PST. 30 | 31 | PST is free software: you can redistribute it and/or modify 32 | it under the terms of the GNU Lesser General Public License as published by 33 | the Free Software Foundation, either version 3 of the License, or 34 | (at your option) any later version. The GNU Lesser General Public License 35 | is intended to guarantee your freedom to share and change all versions 36 | of a program--to make sure it remains free software for all its users. 37 | 38 | PST is distributed in the hope that it will be useful, 39 | but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 41 | GNU Lesser General Public License for more details. 42 | 43 | You should have received a copy of the GNU Lesser General Public License 44 | along with PST. If not, see . 45 | 46 | 47 | Contact 48 | ------- 49 | Meta Berghauser Pont (copyright owner), meta.berghauserpont@chalmers.se 50 | Martin Fitger (programmer), martin.fitger@xmnsoftware.com 51 | 52 | 53 | Acknowledgements 54 | ---------------- 55 | PST is developed by KTH School of Architecture, Chalmers School of 56 | Architecture (SMoG) and Spacescape AB. Alexander Ståhle, Lars Marcus, 57 | Daniel Koch, Martin Fitger, Ann Legeby, Gianna Stavroulaki, 58 | Meta Berghauser Pont, Anders Karlström, Pablo Miranda Carranza, 59 | Tobias Nordström. -------------------------------------------------------------------------------- /pstalgo/test/tests/testcreatejunctions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import array 23 | import unittest 24 | import pstalgo 25 | 26 | class TestCreateJunctions(unittest.TestCase): 27 | 28 | def test_two_layers(self): 29 | coords0 = array.array('d', [0, 0, 2, 0]) 30 | lines0 = array.array('I', [0, 1]) 31 | coords1 = array.array('d', [1, 1, 1, -1]) 32 | lines1 = array.array('I', [0, 1]) 33 | (res, algo) = pstalgo.CreateJunctions(coords0, lines0, coords1, lines1, None, None) 34 | self.assertEqual(res.m_PointCount, 1) 35 | pstalgo.Free(algo) 36 | unlinks = array.array('d', [1, 0]) 37 | (res, algo) = pstalgo.CreateJunctions(coords0, lines0, coords1, lines1, unlinks, None) 38 | self.assertEqual(res.m_PointCount, 0) 39 | pstalgo.Free(algo) 40 | 41 | def test_one_layer_two_lines(self): 42 | coords0 = array.array('d', [-1, 0, 0, 0, 1, 0]) 43 | lines0 = array.array('I', [0, 1, 1, 2]) 44 | (res, algo) = pstalgo.CreateJunctions(coords0, lines0, None, None, None, None) 45 | self.assertEqual(res.m_PointCount, 0) # Two intersecting lines within same layer shouldn't qualify as a junction 46 | pstalgo.Free(algo) 47 | 48 | def test_one_layer_three_lines(self): 49 | coords0 = array.array('d', [-1, 0, 0, 0, 1, 0, 0, 1]) 50 | lines0 = array.array('I', [0, 1, 1, 2, 1, 3]) 51 | (res, algo) = pstalgo.CreateJunctions(coords0, lines0, None, None, None, None) 52 | self.assertEqual(res.m_PointCount, 1) # Three (or more) intersecting lines in same point within same layer qualifies as a junction 53 | pstalgo.Free(algo) -------------------------------------------------------------------------------- /pstalgo/src/ProgressUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include "Progress.h" 27 | 28 | class CPSTAlgoProgressCallback: public IProgressCallback 29 | { 30 | public: 31 | CPSTAlgoProgressCallback(FPSTAProgressCallback cbfunc, void* user_data, int min_progress_interval_ms = 100); 32 | 33 | // IProgressCallback Interface 34 | void ReportProgress(float progress) override; 35 | void ReportStatus(const char* text) override; 36 | bool GetCancel() override; 37 | 38 | private: 39 | bool TestFrequencyFilter(); 40 | void ResetFrequencyFilter(); 41 | 42 | FPSTAProgressCallback m_CBFunc; 43 | void* m_UserData; 44 | float m_Progress; 45 | bool m_Cancel; 46 | const unsigned int m_MinFilterIntervalMSec; 47 | unsigned int m_LastFilterTimestamp; 48 | }; 49 | 50 | 51 | class CPSTMultiTaskProgressCallback : public IProgressCallback 52 | { 53 | public: 54 | CPSTMultiTaskProgressCallback(IProgressCallback& parent_progress); 55 | 56 | void AddTask(unsigned int id, float weight, const char* text); 57 | 58 | void SetCurrentTask(unsigned int id); 59 | 60 | // IProgressCallback Interface 61 | void ReportProgress(float progress) override; 62 | void ReportStatus(const char* text) override; 63 | bool GetCancel() override; 64 | 65 | private: 66 | IProgressCallback& m_ParentProgress; 67 | float m_CurrTaskWeight; 68 | float m_FinishedWeight; 69 | float m_TotalWeightInv; 70 | 71 | struct STask 72 | { 73 | unsigned int m_Id; 74 | float m_Weight; 75 | const char* m_Text; 76 | }; 77 | std::vector m_Tasks; 78 | }; 79 | 80 | 81 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/AngularChoice.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTAAngularChoiceDesc 29 | { 30 | SPSTAAngularChoiceDesc(); 31 | 32 | // Version 33 | static const unsigned int VERSION = 2; 34 | unsigned int m_Version; 35 | 36 | // Graph 37 | HPSTASegmentGraph m_Graph; // Created with a call to PSTACreateSegmentGraph 38 | 39 | // Radius 40 | SPSTARadii m_Radius; 41 | 42 | // Settings 43 | bool m_WeighByLength; 44 | float m_AngleThreshold; 45 | unsigned int m_AnglePrecision; 46 | 47 | // Progress Callback 48 | FPSTAProgressCallback m_ProgressCallback; 49 | void* m_ProgressCallbackUser; 50 | 51 | // Output 52 | // These can either be NULL or pointer to arrays of one element per line 53 | float* m_OutChoice; 54 | unsigned int* m_OutNodeCount; // Number of reached lines, INCLUDING origin line 55 | float* m_OutTotalDepth; // SUM(depth) for reached nodes 56 | float* m_OutTotalDepthWeight; // SUM(depth*weight) for reached nodes 57 | }; 58 | 59 | PSTADllExport bool PSTAAngularChoice(const SPSTAAngularChoiceDesc* desc); 60 | 61 | // Normalization (Turner 2007) 62 | // N = number of reached nodes, including origin node 63 | PSTADllExport void PSTAAngularChoiceNormalize(const float* in_scores, const unsigned int* N, unsigned int count, float* out_normalized_score); 64 | 65 | // Syntax Normalization (NACH) 66 | // TD = total depth 67 | PSTADllExport void PSTAAngularChoiceSyntaxNormalize(const float* in_scores, const float* TD, unsigned int count, float* out_normalized_score); 68 | 69 | 70 | -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/CreateSegmentMap.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | 27 | struct SCreateSegmentMapDesc 28 | { 29 | SCreateSegmentMapDesc() : m_Version(VERSION) {} 30 | 31 | // Version 32 | static const unsigned int VERSION = 2; 33 | unsigned int m_Version; 34 | 35 | // Thresholds 36 | float m_Snap; 37 | float m_ExtrudeCut; 38 | float m_MinTail; 39 | float m_Min3NodeColinearDeviation; 40 | 41 | // Network Type 42 | unsigned char m_RoadNetworkType; // EPSTARoadNetworkType 43 | 44 | // Polylines 45 | double* m_PolyCoords; 46 | int* m_PolySections; 47 | unsigned int m_PolyCoordCount; 48 | unsigned int m_PolySectionCount; 49 | unsigned int m_PolyCount; 50 | 51 | // Unlinks. Only allowed if m_RoadNetworkType == EPSTARoadNetworkType_AxialOrSegment. 52 | double* m_UnlinkCoords; 53 | unsigned int m_UnlinkCount; 54 | 55 | // Progress Callback 56 | FPSTAProgressCallback m_ProgressCallback; 57 | void* m_ProgressCallbackUser; 58 | }; 59 | 60 | struct SCreateSegmentMapRes 61 | { 62 | SCreateSegmentMapRes() : m_Version(VERSION) {} 63 | 64 | // Version 65 | static const unsigned int VERSION = 2; 66 | unsigned int m_Version; 67 | 68 | // Segments 69 | double* m_SegmentCoords; 70 | unsigned int* m_Segments; // (P0, P1, Base) 71 | unsigned int m_SegmentCount; 72 | 73 | // Unlinks. Only available if m_RoadNetworkType == EPSTARoadNetworkType_RoadCenterLines. 74 | double* m_UnlinkCoords; 75 | unsigned int m_UnlinkCount; 76 | }; 77 | 78 | PSTADllExport IPSTAlgo* PSTACreateSegmentMap(const SCreateSegmentMapDesc* desc, SCreateSegmentMapRes* res); -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/vector.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | 24 | class Vector(object): 25 | def __init__(self, ctype, max_size, allocator, initial_size=0): 26 | self._ctype = ctype 27 | self._ptr = allocator.alloc(ctype, max_size) 28 | self._max_size = max_size 29 | self._size = 0 30 | self.resize(initial_size) 31 | 32 | def clear(self): 33 | self._size = 0 34 | 35 | def elemtype(self): 36 | return self._ctype 37 | 38 | def clone(self, allocator): 39 | v = Vector(self._ctype, self._max_size, allocator, self._size) 40 | for i in range(self._size): 41 | v._ptr[i] = _ptr[i] 42 | return v 43 | 44 | def append(self, value): 45 | assert(self._size < self._max_size) 46 | self._ptr[self._size] = value 47 | self._size += 1 48 | 49 | def resize(self, size): 50 | assert(size <= self._max_size) 51 | self._size = size 52 | 53 | # DEPRECATED! Use len() instead 54 | def size(self): 55 | return self._size 56 | 57 | # DEPRECATED! Use [] operator instead 58 | def at(self, index): 59 | assert(index < self._size) 60 | return self._ptr[index] 61 | 62 | # DEPRECATED! Use [] operator instead 63 | def set(self, index, value): 64 | assert(index < self._size) 65 | self._ptr[index] = value 66 | 67 | def values(self): 68 | def iter(): 69 | i = 0 70 | while i < self._size: 71 | yield self._ptr[i] 72 | i += 1 73 | return iter() 74 | 75 | def ptr(self): 76 | return self._ptr 77 | 78 | def __len__(self): 79 | return self._size 80 | 81 | def __getitem__(self, index): 82 | assert(index < self._size) 83 | return self._ptr[index] 84 | 85 | def __setitem__(self, index, value): 86 | assert(index < self._size) 87 | self._ptr[index] = value 88 | -------------------------------------------------------------------------------- /pstalgo/src/Raster.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | namespace psta 28 | { 29 | CRaster::CRaster() 30 | { 31 | m_BB.SetEmpty(); 32 | } 33 | 34 | CRaster::CRaster(uint32_t width, uint32_t height, RasterFormat format) 35 | : m_Width(width) 36 | , m_Height(height) 37 | , m_Pitch(width * RasterFormatPixelSize(format)) 38 | , m_Format(format) 39 | { 40 | m_Bits = malloc(m_Pitch * m_Height); 41 | m_BB.SetEmpty(); 42 | } 43 | 44 | CRaster::~CRaster() 45 | { 46 | free(m_Bits); 47 | } 48 | 49 | uint8_t RasterFormatPixelSize(RasterFormat format) 50 | { 51 | switch (format) 52 | { 53 | case RasterFormat_Byte: 54 | return 1; 55 | case RasterFormat_Float: 56 | return 4; 57 | } 58 | throw std::runtime_error("Unsupported raster data type"); 59 | } 60 | } 61 | 62 | PSTADllExport psta_result_t PSTAGetRasterData(psta_raster_handle_t handle, SRasterData* ret_data) 63 | { 64 | try { 65 | VerifyStructVersion(*ret_data); 66 | auto& raster = *(psta::CRaster*)handle; 67 | ret_data->BBMinX = raster.BB().m_Min.x; 68 | ret_data->BBMinY = raster.BB().m_Min.y; 69 | ret_data->BBMaxX = raster.BB().m_Max.x; 70 | ret_data->BBMaxY = raster.BB().m_Max.y; 71 | ret_data->Width = raster.Width(); 72 | ret_data->Height = raster.Height(); 73 | ret_data->Pitch = raster.Pitch(); 74 | ret_data->Format = raster.Format(); 75 | ret_data->Bits = raster.Data(); 76 | return PSTA_RESULT_OK; 77 | } 78 | catch (const std::exception& e) { 79 | LOG_ERROR(e.what()); 80 | } 81 | catch (...) { 82 | LOG_ERROR("Unknown exception"); 83 | } 84 | return PSTA_RESULT_ERROR; 85 | } -------------------------------------------------------------------------------- /pstalgo/test/tests/testcreategraph.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import array 23 | import unittest 24 | import pstalgo 25 | from .common import IsArrayRoughlyEqual 26 | 27 | class TestCreateGraph(unittest.TestCase): 28 | 29 | def test_creategraph(self): 30 | # | 31 | # --|-- 32 | # |__ 33 | line_coords = array.array('d', [0, 0, 2, 0, 1, 1, 1, -1, 2, -1]) 34 | line_indices = array.array('I', [0, 1, 2, 3, 3, 4]) 35 | unlinks = array.array('d', [1, 0]) 36 | points = array.array('d', [-1, 0]) 37 | 38 | graph_handle = pstalgo.CreateGraph(line_coords, line_indices, unlinks, points, None) 39 | self.assertIsNotNone(graph_handle) 40 | 41 | graph_info = pstalgo.GetGraphInfo(graph_handle) 42 | self.assertEqual(graph_info.m_LineCount, 3) 43 | self.assertEqual(graph_info.m_CrossingCount, 1) # One of the 2 crossings was unlinked 44 | self.assertEqual(graph_info.m_PointCount, 1) 45 | 46 | lengths = array.array('f', [0]) * 3 47 | pstalgo.GetGraphLineLengths(graph_handle, lengths) 48 | IsArrayRoughlyEqual(lengths, [2, 2, 1]) 49 | 50 | crossings = array.array('d', [0]) * 2 51 | pstalgo.GetGraphCrossingCoords(graph_handle, crossings) 52 | IsArrayRoughlyEqual(crossings, [1, -1]) 53 | 54 | pstalgo.FreeGraph(graph_handle) 55 | 56 | def test_createsegmentgraph(self): 57 | line_coords = array.array('d', [0, 0, 1, 0]) 58 | line_indices = array.array('I', [0, 1]) 59 | segment_graph_handle = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) 60 | self.assertIsNotNone(segment_graph_handle) 61 | pstalgo.FreeSegmentGraph(segment_graph_handle) -------------------------------------------------------------------------------- /pstalgo/src/analyses/Common.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | SPSTARadii::SPSTARadii() 28 | { 29 | Clear(); 30 | } 31 | 32 | void SPSTARadii::Clear() 33 | { 34 | memset(this, 0, sizeof(*this)); 35 | } 36 | 37 | float SPSTARadii::Get(EPSTADistanceType distance_type) const 38 | { 39 | if (!(m_Mask & EPSTADistanceMaskFromType(distance_type))) 40 | return std::numeric_limits::infinity(); 41 | switch (distance_type) 42 | { 43 | case EPSTADistanceType_Straight: 44 | return m_Straight; 45 | case EPSTADistanceType_Walking: 46 | return m_Walking; 47 | case EPSTADistanceType_Steps: 48 | return (float)m_Steps; 49 | case EPSTADistanceType_Angular: 50 | return m_Angular; 51 | case EPSTADistanceType_Axmeter: 52 | return m_Axmeter; 53 | 54 | // Unhandled 55 | case EPSTADistanceType_Undefined: 56 | default: 57 | break; 58 | } 59 | ASSERT(false && "Unsupported distance type!"); 60 | return std::numeric_limits::infinity(); 61 | } 62 | 63 | PSTADllExport void PSTAStandardNormalize(const float* in, unsigned int count, float* out) 64 | { 65 | using namespace std; 66 | 67 | if (0 == count) 68 | return; 69 | 70 | // Calculate min and max 71 | float low, high; 72 | low = high = in[0]; 73 | for (size_t i = 1; i < count; ++i) 74 | { 75 | low = min(low, in[i]); 76 | high = max(high, in[i]); 77 | } 78 | 79 | // Rescale to [0..1] range 80 | if (low < high) 81 | { 82 | const float s = 1.0f / (high - low); 83 | for (size_t i = 0; i < count; ++i) 84 | out[i] = (in[i] - low) * s; 85 | } 86 | else 87 | { 88 | for (size_t i = 0; i < count; ++i) 89 | out[i] = 1; 90 | } 91 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/experimental/ArrayView.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include "../Debug.h" 25 | 26 | namespace psta 27 | { 28 | template 29 | void enumerate(TCollection& collection, TLambda&& lambda) 30 | { 31 | size_t idx = 0; 32 | for (auto& element : collection) 33 | lambda(idx++, element); 34 | } 35 | 36 | template 37 | class array_view 38 | { 39 | public: 40 | array_view() : m_Begin(nullptr), m_End(nullptr) {} 41 | 42 | array_view(T* arr, size_t size) : m_Begin(arr), m_End(arr + size) {} 43 | 44 | operator bool() const { return !empty(); } 45 | 46 | bool empty() const { return m_End <= m_Begin; } 47 | 48 | size_t size() const { return m_End - m_Begin; } 49 | 50 | T& operator[](size_t idx) { ASSERT(idx < size()); return m_Begin[idx]; } 51 | const T& operator[](size_t idx) const { ASSERT(idx < size()); return m_Begin[idx]; } 52 | 53 | T* data() { return m_Begin; } 54 | const T* data() const { return m_Begin; } 55 | 56 | T* begin() { return m_Begin; } 57 | const T* begin() const { return m_Begin; } 58 | 59 | T* end() { return m_End; } 60 | const T* end() const { return m_End; } 61 | 62 | array_view sub_view(size_t first, size_t size) { return array_view(m_Begin + first, size); } 63 | const array_view sub_view(size_t first, size_t size) const { return array_view(m_Begin + first, size); } 64 | 65 | private: 66 | T* m_Begin; 67 | T* m_End; 68 | }; 69 | 70 | template 71 | array_view make_array_view(T* arr, size_t size) { return array_view(arr, size); } 72 | 73 | template 74 | array_view make_array_view(T (&arr)[TSize]) { return array_view(arr, TSize); } 75 | } -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/SegmentBetweenness.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTASegmentBetweennessDesc 29 | { 30 | // Version 31 | static const unsigned int VERSION = 1; 32 | unsigned int m_Version = VERSION; 33 | 34 | // Graph 35 | HPSTAGraph m_Graph = nullptr; // Created with a call to PSTACreateGraph 36 | 37 | // Distance measurement 38 | unsigned char m_DistanceType = EPSTADistanceType_Steps; // enum EPSTADistanceType 39 | 40 | // Radius 41 | SPSTARadii m_Radius; 42 | 43 | // Weights (optional) 44 | float* m_Weights = nullptr; // Per attraction point (if available), otherwise per segment 45 | 46 | // Attraction points (optional) 47 | double* m_AttractionPoints = nullptr; 48 | unsigned int m_AttractionPointCount = 0; 49 | 50 | // Progress Callback 51 | FPSTAProgressCallback m_ProgressCallback = nullptr; 52 | void* m_ProgressCallbackUser = nullptr; 53 | 54 | // Output 55 | // These can either be NULL or pointer to arrays of one element per line 56 | float* m_OutBetweenness = nullptr; 57 | unsigned int* m_OutNodeCount = nullptr; // Number of reached lines, INCLUDING origin line 58 | float* m_OutTotalDepth = nullptr; 59 | }; 60 | 61 | // N = number of nodes, INCLUDING origin node 62 | PSTADllExport void PSTABetweennessNormalize(const float* in_values, const unsigned int* node_counts, unsigned int count, float* out_normalized); 63 | 64 | PSTADllExport void PSTABetweennessSyntaxNormalize(const float* in_values, const float* total_depths, unsigned int count, float* out_normalized); 65 | 66 | PSTADllExport bool PSTASegmentBetweenness(const SPSTASegmentBetweennessDesc* desc); -------------------------------------------------------------------------------- /pstalgo/src/utils/SimpleAlignedAllocator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | // TODO: Move! 28 | inline void* aligned_malloc(size_t size, size_t align) 29 | { 30 | void *result; 31 | #ifdef _MSC_VER 32 | result = _aligned_malloc(size, align); 33 | #else 34 | if (posix_memalign(&result, align, size)) result = 0; 35 | #endif 36 | return result; 37 | } 38 | 39 | // TODO: Move! 40 | inline void aligned_free(void *ptr) 41 | { 42 | #ifdef _MSC_VER 43 | _aligned_free(ptr); 44 | #else 45 | free(ptr); 46 | #endif 47 | } 48 | 49 | CSimpleAlignedAllocator::CSimpleAlignedAllocator(unsigned int block_size, unsigned int alignment_bits) 50 | : m_CurrentUsage(0) 51 | , m_BlockSize(block_size) 52 | , m_AlignmentBits(alignment_bits) 53 | { 54 | } 55 | 56 | CSimpleAlignedAllocator::~CSimpleAlignedAllocator() 57 | { 58 | FreeAll(); 59 | } 60 | 61 | void CSimpleAlignedAllocator::FreeAll() 62 | { 63 | for (auto it = m_Blocks.begin(); m_Blocks.end() != it; ++it) 64 | aligned_free(*it); 65 | } 66 | 67 | void* CSimpleAlignedAllocator::Alloc(size_t size) 68 | { 69 | if (size > m_BlockSize) 70 | { 71 | ASSERT(false); 72 | return 0x0; 73 | } 74 | 75 | if ((m_CurrentUsage >> m_AlignmentBits) != ((m_CurrentUsage + size - 1) >> m_AlignmentBits)) 76 | { 77 | const unsigned int mask = (1 << m_AlignmentBits) - 1; 78 | m_CurrentUsage = (m_CurrentUsage + mask) & ~mask; 79 | } 80 | 81 | if (m_Blocks.empty() || (size > m_BlockSize - m_CurrentUsage)) 82 | { 83 | m_Blocks.push_back(aligned_malloc(m_BlockSize, 1 << m_AlignmentBits)); 84 | m_CurrentUsage = 0; 85 | } 86 | 87 | void* p = (char*)m_Blocks.back() + m_CurrentUsage; 88 | m_CurrentUsage += (unsigned int)size; 89 | 90 | return p; 91 | } 92 | -------------------------------------------------------------------------------- /pstalgo/src/analyses/AngularChoice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include "../ProgressUtil.h" 26 | #include "AngularChoiceAlgo.h" 27 | 28 | SPSTAAngularChoiceDesc::SPSTAAngularChoiceDesc() 29 | : m_Version(VERSION) 30 | , m_Graph(0) 31 | , m_WeighByLength(false) 32 | , m_AngleThreshold(0) 33 | , m_AnglePrecision(1) 34 | , m_ProgressCallback(nullptr) 35 | , m_ProgressCallbackUser(nullptr) 36 | , m_OutChoice(nullptr) 37 | , m_OutNodeCount(nullptr) 38 | , m_OutTotalDepth(nullptr) 39 | , m_OutTotalDepthWeight(nullptr) 40 | {} 41 | 42 | PSTADllExport bool PSTAAngularChoice(const SPSTAAngularChoiceDesc* desc) 43 | { 44 | CAngularChoiceAlgo algo; 45 | CPSTAlgoProgressCallback progress(desc->m_ProgressCallback, desc->m_ProgressCallbackUser); 46 | return algo.Run( 47 | *(CSegmentGraph*)desc->m_Graph, 48 | CAngularChoiceAlgo::EMode_AngularChoice, 49 | desc->m_Radius, 50 | desc->m_WeighByLength, 51 | desc->m_AngleThreshold, 52 | desc->m_AnglePrecision, 53 | desc->m_OutChoice, 54 | desc->m_OutNodeCount, 55 | desc->m_OutTotalDepth, 56 | nullptr, 57 | desc->m_OutTotalDepthWeight, 58 | progress); 59 | } 60 | 61 | PSTADllExport void PSTAAngularChoiceNormalize(const float* in_scores, const unsigned int* N, unsigned int count, float* out_normalized_score) 62 | { 63 | for (unsigned int i = 0; i < count; ++i) 64 | out_normalized_score[i] = (N[i] > 2) ? (in_scores[i] / ((float)(N[i] - 1) * (float)(N[i] - 2))) : in_scores[i]; 65 | } 66 | 67 | PSTADllExport void PSTAAngularChoiceSyntaxNormalize(const float* in_scores, const float* TD, unsigned int count, float* out_normalized_score) 68 | { 69 | using namespace std; 70 | for (unsigned int i = 0; i < count; ++i) 71 | out_normalized_score[i] = log10(in_scores[i] + 1.0f) / log10(2.0f + TD[i]); 72 | } -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/segmentgroupintegration.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from ctypes import byref, cdll, POINTER, Structure, c_double, c_float, c_int, c_uint, c_void_p 24 | from .common import _DLL, Radii, PSTALGO_PROGRESS_CALLBACK, CreateCallbackWrapper, UnpackArray, DumpStructure 25 | 26 | 27 | class SPSTASegmentGroupIntegration(Structure) : 28 | _fields_ = [ 29 | # Version 30 | ("m_Version", ctypes.c_uint), 31 | 32 | # Graph 33 | ("m_Graph", ctypes.c_void_p), 34 | 35 | # Radius 36 | ("m_Radius", Radii), 37 | 38 | # Progress Callback 39 | ("m_ProgressCallback", PSTALGO_PROGRESS_CALLBACK), 40 | ("m_ProgressCallbackUser", ctypes.c_void_p), 41 | 42 | # Output per group (optional) 43 | ("m_OutIntegration", ctypes.POINTER(ctypes.c_float)), 44 | ("m_OutNodeCount", ctypes.POINTER(ctypes.c_uint)), 45 | ("m_OutTotalDepth", ctypes.POINTER(ctypes.c_float)), 46 | ] 47 | def __init__(self, *args): 48 | Structure.__init__(self, *args) 49 | self.m_Version = 1 50 | 51 | 52 | def SegmentGroupIntegration(group_graph, radii, progress_callback = None, out_integration = None, out_node_counts = None, out_total_depths = None): 53 | desc = SPSTASegmentGroupIntegration() 54 | # Graph 55 | desc.m_Graph = group_graph 56 | # Radius 57 | desc.m_Radius = radii 58 | # Progress Callback 59 | desc.m_ProgressCallback = CreateCallbackWrapper(progress_callback) 60 | desc.m_ProgressCallbackUser = c_void_p() 61 | # Outputs per Line 62 | # TODO: Verify length of these 63 | desc.m_OutIntegration = UnpackArray(out_integration, 'f')[0] 64 | desc.m_OutNodeCount = UnpackArray(out_node_counts, 'I')[0] 65 | desc.m_OutTotalDepth = UnpackArray(out_total_depths, 'f')[0] 66 | # Make the call 67 | fn = _DLL.PSTASegmentGroupIntegration 68 | fn.restype = ctypes.c_bool 69 | if not fn(byref(desc)): 70 | raise Exception("PSTASegmentGroupIntegration failed.") -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/pages/readypage.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtWidgets import QHBoxLayout, QLabel, QPlainTextEdit, QPushButton, QVBoxLayout, QWizard, QWizardPage 23 | import json 24 | 25 | class ReadyPage(QWizardPage): 26 | def __init__(self, title = "Ready", sub_title = " "): 27 | QWizardPage.__init__(self) 28 | self.setTitle(title) 29 | self.setSubTitle(sub_title) 30 | self.setCommitPage(True) 31 | self.createWidgets() 32 | self.setButtonText(QWizard.WizardButton.CommitButton, "Start") 33 | 34 | def createWidgets(self): 35 | vlayout = QVBoxLayout() 36 | vlayout.addWidget(QLabel("PST now has all information necessary to start the analysis.")) 37 | vlayout.addStretch(1) 38 | self._propView = QPlainTextEdit() 39 | self._propView.setReadOnly(True) 40 | self._propView.setVisible(False) 41 | vlayout.addWidget(self._propView, 30) 42 | hlayout = QHBoxLayout() 43 | hlayout.addWidget(QLabel("Click 'Start' to start the analysis."), 1) 44 | self._toggleSettingsButton = QPushButton("Show settings") 45 | self._toggleSettingsButton.clicked.connect(self.onToggleShowSettings) 46 | hlayout.addWidget(self._toggleSettingsButton) 47 | vlayout.addLayout(hlayout) 48 | self.setLayout(vlayout) 49 | 50 | def initializePage(self): 51 | self.wizard().removeDeprecatedProperties() 52 | props = self.wizard().properties() 53 | text = json.dumps(props, sort_keys=True, indent=4, separators=(',', ': ')) 54 | self._propView.setPlainText(text) 55 | 56 | def validatePage(self): 57 | if not QWizardPage.validatePage(self): 58 | return False 59 | self.wizard().saveProperties() 60 | return True 61 | 62 | def onToggleShowSettings(self): 63 | visible = not self._propView.isVisible() 64 | self._propView.setVisible(visible) 65 | self._toggleSettingsButton.setText("Hide settings" if visible else "Show settings") -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/Bit.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | #ifdef _MSC_VER 27 | #include // for _BitScanReverse 28 | #if _MSC_VER <= 1800 29 | #define alignof __alignof 30 | #endif 31 | #endif 32 | 33 | #include 34 | 35 | namespace psta 36 | { 37 | // TODO: Replace with std::countr_zero in C++20 38 | 39 | // Returns zero-based index of most significant bit set in 'val' (i.e. val = 0x1000 --> 12) 40 | inline unsigned int bit_scan_reverse_32(unsigned long val) 41 | { 42 | #ifdef _MSC_VER 43 | unsigned long msb = 0; 44 | _BitScanReverse(&msb, val); 45 | return msb; 46 | #else 47 | return sizeof(val) * 8 - 1 - __builtin_clzl(val); 48 | #endif 49 | } 50 | 51 | inline unsigned int bit_scan_reverse(uint32_t val) { return bit_scan_reverse_32(val); } 52 | 53 | // Returns zero-based index of most significant bit set in 'val' (i.e. val = 0x1000 --> 12) 54 | #ifdef PSTA_64 55 | inline unsigned int bit_scan_reverse_64(unsigned long long val) 56 | { 57 | #ifdef _MSC_VER 58 | unsigned long msb = 0; 59 | _BitScanReverse64(&msb, val); 60 | return msb; 61 | #else 62 | return sizeof(val) * 8 - 1 - __builtin_clzll(val); 63 | #endif 64 | } 65 | 66 | inline unsigned int bit_scan_reverse(uint64_t val) { return bit_scan_reverse_64(val); } 67 | #endif 68 | 69 | 70 | template T align_up(T val, T alignment) 71 | { 72 | const auto align_mask = alignment - 1; 73 | return (val + align_mask) & ~align_mask; 74 | } 75 | 76 | template T* align_ptr_up(T* ptr, size_t alignment) 77 | { 78 | return (T*)align_up((size_t)ptr, alignment); 79 | } 80 | 81 | template T round_up_to_closest_power_of_two(T value) 82 | { 83 | if (!value) 84 | return 0; 85 | const T res = 1 << bit_scan_reverse(value); 86 | return (res < value) ? (res << 1) : res; 87 | } 88 | } -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/wizards/networkintegrationwiz.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtWidgets import QVBoxLayout 23 | from ..widgets import PropertySheetWidget 24 | from ..wizard import BaseWiz, BasePage, WizProp, WizPropFloat 25 | from ..pages import FinishPage, NetworkInputPage, NetworkTypeFlags, ProgressPage, ReadyPage, RadiusPage, RadiusType 26 | 27 | 28 | class NetworkIntegrationWiz(BaseWiz): 29 | def __init__(self, parent, settings, model, task_factory): 30 | BaseWiz.__init__(self, parent, settings, model, "Network Integration") 31 | self._task_factory = task_factory 32 | network_type_flags = NetworkTypeFlags.AXIAL 33 | self.addPage(NetworkInputPage(point_src_available=False, networkTypeFlags=network_type_flags)) 34 | self.addPage(RadiusPage(radius_types=[RadiusType.STEPS], network_type_flags=network_type_flags)) 35 | self.addPage(OutputPage()) 36 | self.addPage(ReadyPage()) 37 | self.addPage(ProgressPage()) 38 | self.addPage(FinishPage()) 39 | 40 | def createTask(self, props): 41 | """ Creates, initializes and returns a task object. """ 42 | return self._task_factory(props) 43 | 44 | 45 | class OutputPage(BasePage): 46 | def __init__(self): 47 | BasePage.__init__(self) 48 | self.setTitle("Output Settings") 49 | self.setSubTitle(" ") 50 | self.createWidgets() 51 | 52 | def createWidgets(self): 53 | prop_sheet = PropertySheetWidget(self) 54 | prop_sheet.setIndent(0) 55 | prop_sheet.addBoolProp("Output node count (N)", True, "output_N") 56 | prop_sheet.addBoolProp("Output total depth (TD)", True, "output_TD") 57 | prop_sheet.addBoolProp("Output mean depth (MD)", True, "output_MD") 58 | prop_sheet.newSection() 59 | prop_sheet.addBoolProp("Store avarage score at junctions", False, "output_at_junctions") 60 | vlayout = QVBoxLayout() 61 | vlayout.addWidget(prop_sheet) 62 | vlayout.addStretch(1) 63 | self.setLayout(vlayout) -------------------------------------------------------------------------------- /pstqgis/src/pst/model/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from builtins import range 23 | from builtins import object 24 | import os, sys, copy, json 25 | 26 | SETTINGS_DIR = 'pstqgis' 27 | SETTINGS_FILE = 'settings.json' 28 | 29 | def GetUserSettingsDir(app_name): 30 | import platform 31 | if 'Windows' == platform.system(): 32 | return os.path.join(os.getenv('APPDATA'), app_name) 33 | elif 'Darwin' == platform.system(): 34 | return os.path.expanduser('~/.' + app_name) # NOTE: We prepend a dot here to also make the folder hidden 35 | raise Exception("Unsupported plataform: %s" & platform.system()) 36 | 37 | class Settings(object): 38 | def __init__(self): 39 | self._props = {} 40 | 41 | def get(self, name): 42 | p = self._props 43 | for n in name.split('/'): 44 | p = p.get(n) 45 | if p is None: 46 | return None 47 | return copy.deepcopy(p) 48 | 49 | def set(self, name, prop): 50 | p = self._props 51 | nodes = name.split('/') 52 | for i in range(len(nodes)-1): 53 | n = nodes[i] 54 | t = p.get(n) 55 | if t is None: 56 | t = {} 57 | p[n] = t 58 | p = t 59 | p[nodes[-1]] = copy.deepcopy(prop) 60 | 61 | def save(self): 62 | settings_directory = GetUserSettingsDir(SETTINGS_DIR) 63 | if not os.path.exists(settings_directory): 64 | os.makedirs(settings_directory) 65 | settings_path = os.path.join(settings_directory, SETTINGS_FILE) 66 | with open(settings_path, 'w') as f: 67 | f.write(json.dumps(self._props, sort_keys=True, indent=4, separators=(',', ': '))) 68 | 69 | def load(self): 70 | self._props = {} 71 | settings_path = os.path.join(GetUserSettingsDir(SETTINGS_DIR), SETTINGS_FILE) 72 | if os.path.exists(settings_path): 73 | try: 74 | p = None 75 | with open(settings_path, 'r') as f: 76 | p = json.loads(f.read()) 77 | if type(p) == dict: 78 | self._props = p 79 | except: 80 | pass -------------------------------------------------------------------------------- /pstqgis/src/pst/ui/wizards/segmentgroupingwiz.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from qgis.PyQt.QtWidgets import QCheckBox, QVBoxLayout 23 | from ..wizard import BaseWiz, BasePage, WizProp 24 | from ..pages import FinishPage, NetworkInputPage, NetworkTypeFlags, ProgressPage, ReadyPage 25 | from ..widgets import PropertySheetWidget, WidgetEnableCheckBox 26 | 27 | 28 | class SegmentGroupingWiz(BaseWiz): 29 | def __init__(self, parent, settings, model, task_factory): 30 | BaseWiz.__init__(self, parent, settings, model, "Segment Grouping") 31 | self._task_factory = task_factory 32 | self.addPage(NetworkInputPage(point_src_available=False, networkTypeFlags=NetworkTypeFlags.SEGMENT)) 33 | self.addPage(OptionsPage()) 34 | self.addPage(ReadyPage()) 35 | self.addPage(ProgressPage()) 36 | self.addPage(FinishPage()) 37 | 38 | def createTask(self, props): 39 | """ Creates, initializes and returns a task object. """ 40 | return self._task_factory(props) 41 | 42 | 43 | class OptionsPage(BasePage): 44 | def __init__(self): 45 | BasePage.__init__(self) 46 | self.setTitle("Options") 47 | self.setSubTitle(" ") 48 | self.createWidgets() 49 | 50 | def createWidgets(self): 51 | prop_sheet = PropertySheetWidget(self) 52 | prop_sheet.newSection("Grouping") 53 | prop_sheet.addNumberProp("Angle threshold", 1, 2, "degrees", "angle_threshold") 54 | prop_sheet.addBoolProp("Split at junctions", False, "split_at_junctions") 55 | prop_sheet.newSection("Coloring") 56 | checkbox2 = QCheckBox("Apply generated colors to map") 57 | checkbox1 = WidgetEnableCheckBox("Generate minimal disjunct colors", [checkbox2]) 58 | prop_sheet.add(checkbox1) 59 | prop_sheet.add(checkbox2) 60 | self.regProp("generate_colors", WizProp(checkbox1, False)) 61 | self.regProp("apply_colors", WizProp(checkbox2, False)) 62 | vlayout = QVBoxLayout() 63 | vlayout.addWidget(prop_sheet) 64 | vlayout.addStretch(1) 65 | self.setLayout(vlayout) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/Debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include "pstalgo.h" 25 | 26 | #ifdef _MFC_VER 27 | #undef ASSERT 28 | #undef VERIFY 29 | #endif 30 | 31 | #ifdef _DEBUG 32 | #include 33 | #define ASSERT(x) assert(x) 34 | #define VERIFY(x) assert(x) 35 | #else 36 | #define ASSERT(x) 37 | #define VERIFY(x) x 38 | #endif 39 | 40 | #define LOG_VERBOSE(fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Verbose, 0x0, fmt, ##__VA_ARGS__) 41 | #define LOG_INFO(fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Info, 0x0, fmt, ##__VA_ARGS__) 42 | #define LOG_WARNING(fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Warning, 0x0, fmt, ##__VA_ARGS__) 43 | #define LOG_ERROR(fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Error, 0x0, fmt, ##__VA_ARGS__) 44 | 45 | #define LOG_VERBOSE_DOMAIN(domain, fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Verbose, domain, fmt, ##__VA_ARGS__) 46 | #define LOG_INFO_DOMAIN(domain, fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Info, domain, fmt, ##__VA_ARGS__) 47 | #define LOG_WARNING_DOMAIN(domain, fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Warning, domain, fmt, ##__VA_ARGS__) 48 | #define LOG_ERROR_DOMAIN(domain, fmt, ...) pstdbg::Log(pstdbg::EErrorLevel_Error, domain, fmt, ##__VA_ARGS__) 49 | 50 | namespace pstdbg 51 | { 52 | enum EErrorLevel : int 53 | { 54 | EErrorLevel_Verbose, 55 | EErrorLevel_Info, 56 | EErrorLevel_Warning, 57 | EErrorLevel_Error, 58 | }; 59 | 60 | typedef void(*FLogCallback)(EErrorLevel level, const char* domain, const char* msg, void* user_data); 61 | 62 | typedef unsigned int HLogCallback; 63 | 64 | HLogCallback RegisterLogCallback(FLogCallback func, void* user_data); 65 | 66 | void UnregisterLogCallback(HLogCallback handle); 67 | 68 | void Log(EErrorLevel level, const char* domain, const char* fmt, ...); 69 | } 70 | 71 | PSTADllExport pstdbg::HLogCallback PSTARegisterLogCallback(pstdbg::FLogCallback func, void* user_data); 72 | 73 | PSTADllExport void PSTAUnregisterLogCallback(pstdbg::HLogCallback handle); 74 | -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/fastsegmentbetweenness.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from ctypes import byref, cdll, POINTER, Structure, c_double, c_float, c_int, c_uint, c_void_p 24 | from .common import _DLL, PSTALGO_PROGRESS_CALLBACK, CreateCallbackWrapper, UnpackArray, DumpStructure, Radii 25 | 26 | class SPSTAFastSegmentBetweennessDesc(Structure) : 27 | _fields_ = [ 28 | ("m_Version", c_uint), 29 | 30 | # Graph 31 | ("m_Graph", c_void_p), 32 | 33 | # Distance type 34 | ("m_DistanceType", ctypes.c_ubyte), # DistanceType enum in common.py 35 | 36 | # Weight mode 37 | ("m_WeighByLength", ctypes.c_bool), 38 | 39 | # Radius (only WALKING supported) 40 | ("m_Radius", Radii), 41 | 42 | # Progress Callback 43 | ("m_ProgressCallback", PSTALGO_PROGRESS_CALLBACK), 44 | ("m_ProgressCallbackUser", c_void_p), 45 | 46 | # Outputs (optional) 47 | ("m_OutBetweenness", POINTER(c_float)), 48 | ("m_OutNodeCount", POINTER(c_uint)), 49 | ("m_OutTotalDepth", POINTER(c_float)), 50 | ] 51 | def __init__(self, *args): 52 | Structure.__init__(self, *args) 53 | self.m_Version = 2 54 | 55 | def FastSegmentBetweenness(graph_handle, distance_type, weigh_by_length, radius, progress_callback = None, out_betweenness = None, out_node_count = None, out_total_depth = None): 56 | desc = SPSTAFastSegmentBetweennessDesc() 57 | desc.m_Graph = graph_handle 58 | desc.m_DistanceType = distance_type 59 | desc.m_WeighByLength = weigh_by_length 60 | desc.m_Radius = radius 61 | desc.m_ProgressCallback = CreateCallbackWrapper(progress_callback) 62 | desc.m_ProgressCallbackUser = c_void_p() 63 | desc.m_OutBetweenness = UnpackArray(out_betweenness, 'f')[0] 64 | desc.m_OutNodeCount = UnpackArray(out_node_count, 'I')[0] 65 | desc.m_OutTotalDepth = UnpackArray(out_total_depth, 'f')[0] 66 | # Make the call 67 | fn = _DLL.PSTAFastSegmentBetweenness 68 | fn.restype = ctypes.c_bool 69 | if not fn(byref(desc)): 70 | raise Exception("PSTAFastSegmentBetweenness failed.") 71 | return True -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/reach.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from ctypes import byref, cdll, POINTER, Structure, c_double, c_float, c_int, c_uint, c_void_p 24 | from .common import _DLL, Radii, PSTALGO_PROGRESS_CALLBACK, CreateCallbackWrapper, UnpackArray, DumpStructure 25 | 26 | 27 | class SPSTAReachDesc(Structure) : 28 | _fields_ = [ 29 | # Version 30 | ("m_Version", c_uint), 31 | 32 | # Graph 33 | ("m_Graph", c_void_p), 34 | 35 | # Radius 36 | ("m_Radius", Radii), 37 | 38 | # Origin Points (optional) 39 | ("m_OriginPointCoords", POINTER(c_double)), 40 | ("m_OriginPointCount", c_uint), 41 | 42 | # Progress Callback 43 | ("m_ProgressCallback", PSTALGO_PROGRESS_CALLBACK), 44 | ("m_ProgressCallbackUser", c_void_p), 45 | 46 | # Outputs (optional) 47 | ("m_OutReachedCount", POINTER(c_uint)), 48 | ("m_OutReachedLength", POINTER(c_float)), 49 | ("m_OutReachedArea", POINTER(c_float)), 50 | ] 51 | def __init__(self, *args): 52 | Structure.__init__(self, *args) 53 | self.m_Version = 1 54 | 55 | 56 | def Reach(graph_handle, radius, origin_points = None, progress_callback = None, out_reached_count = None, out_reached_length = None, out_reached_area = None): 57 | desc = SPSTAReachDesc() 58 | # Graph 59 | desc.m_Graph = graph_handle 60 | # Radius 61 | desc.m_Radius = radius 62 | # Origin Poiints 63 | (desc.m_OriginPointCoords, n) = UnpackArray(origin_points, 'd') 64 | desc.m_OriginPointCount = int(n / 2); assert((n % 2) == 0) 65 | # Progress Callback 66 | desc.m_ProgressCallback = CreateCallbackWrapper(progress_callback) 67 | desc.m_ProgressCallbackUser = c_void_p() 68 | # Outputs 69 | # TODO: Verify length of these 70 | desc.m_OutReachedCount = UnpackArray(out_reached_count, 'I')[0] 71 | desc.m_OutReachedLength = UnpackArray(out_reached_length, 'f')[0] 72 | desc.m_OutReachedArea = UnpackArray(out_reached_area, 'f')[0] 73 | # Make the call 74 | fn = _DLL.PSTAReach 75 | fn.restype = ctypes.c_bool 76 | if not fn(byref(desc)): 77 | raise Exception("PSTAReach failed.") 78 | return True -------------------------------------------------------------------------------- /pstalgo/README.txt: -------------------------------------------------------------------------------- 1 | Pstalgo 2 | 3 | 4 | Overview 5 | -------- 6 | Pstalgo is a C++ library that implements space syntax and regular 7 | accessibility analyses. The library is also available to Python (via an 8 | interface that connects to the library dll via ctypes). 9 | 10 | 11 | Build Instructions 12 | ------------------ 13 | 14 | Visual C++ (Windows): 15 | There is a Microsoft Visual C++ 2017 project file in the 'vc' 16 | subdirectory that can be used for building the library on Windows. 17 | The project will generate intermediate files in the directory 'build', 18 | and output the built library files in the directory 'bin'. 19 | 20 | CMake (Only tested on Mac OS X): 21 | - Create an empty folder called 'build' 22 | > mkdir build 23 | - Change directory to the build folder 24 | > cd build 25 | - Run cmake to generate make file 26 | > cmake .. 27 | - Build with make 28 | > make 29 | The built library will be outputted to the folder 'bin' 30 | 31 | 32 | Testing 33 | ------- 34 | There is a set of unit tests in the subdirectory 'test' that can be run 35 | to verify that various aspects of Pstalgo works as expected. Note that 36 | the project must be built before running the tests. 37 | 38 | 39 | Deployment 40 | ---------- 41 | There is a batch file called 'deploy.bat' that will copy the built 42 | binaries and the python files to a separate directory. This is to 43 | facilitate distribution of the library. 44 | 45 | 46 | License 47 | ------- 48 | Copyright 2019 Meta Berghauser Pont 49 | 50 | The Pstalgo library is part of PST. 51 | 52 | PST is free software: you can redistribute it and/or modify 53 | it under the terms of the GNU Lesser General Public License as published by 54 | the Free Software Foundation, either version 3 of the License, or 55 | (at your option) any later version. The GNU Lesser General Public License 56 | is intended to guarantee your freedom to share and change all versions 57 | of a program--to make sure it remains free software for all its users. 58 | 59 | PST is distributed in the hope that it will be useful, 60 | but WITHOUT ANY WARRANTY; without even the implied warranty of 61 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 62 | GNU Lesser General Public License for more details. 63 | 64 | You should have received a copy of the GNU Lesser General Public License 65 | along with PST. If not, see . 66 | 67 | 68 | Contact 69 | ------- 70 | Meta Berghauser Pont (copyright owner), meta.berghauserpont@chalmers.se 71 | Martin Fitger (programmer), martin.fitger@xmnsoftware.com 72 | 73 | 74 | Acknowledgements 75 | ---------------- 76 | PST is developed by KTH School of Architecture, Chalmers School of 77 | Architecture (SMoG) and Spacescape AB. Alexander Ståhle, Lars Marcus, 78 | Daniel Koch, Martin Fitger, Ann Legeby, Gianna Stavroulaki, 79 | Meta Berghauser Pont, Anders Karlström, Pablo Miranda Carranza, 80 | Tobias Nordström. -------------------------------------------------------------------------------- /pstalgo/src/analyses/AngularChoiceAlgo.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | class CSegmentGraph; 29 | class IProgressCallback; 30 | 31 | class CAngularChoiceAlgo 32 | { 33 | public: 34 | enum EMode 35 | { 36 | EMode_AngularChoice, 37 | EMode_AngularIntegration, 38 | }; 39 | 40 | CAngularChoiceAlgo(); 41 | ~CAngularChoiceAlgo(); 42 | 43 | /** 44 | * ret_choice: Either choice or length-weighted choice values (depending on weigh_by_length). 45 | * ret_total_depths: Sum of either depth or depth*weight (depending on weigh_by_length) of each reached segment. 46 | * ret_total_weights: Sum of weights of all reached segments. NOTE: Weight of ORIGIN segment is NOT INCLUDED. Weight will be 1 or length depending on weigh_by_length. 47 | */ 48 | bool Run( 49 | CSegmentGraph& graph, 50 | EMode mode, 51 | const SPSTARadii& radii, 52 | bool weigh_by_length, 53 | float angle_threshold, 54 | unsigned int angle_precision, 55 | float* ret_choice, 56 | unsigned int* ret_node_counts, 57 | float* ret_total_depths, 58 | float* ret_total_weights, 59 | float* ret_total_depth_weights, 60 | IProgressCallback& progress); 61 | 62 | protected: 63 | 64 | bool IsWeighByLength() const { return m_WeighByLength; } 65 | 66 | CSegmentGraph& GetGraph() { return *m_Graph; } 67 | 68 | CSegmentGraph* m_Graph; 69 | EMode m_Mode; 70 | 71 | struct SRadius 72 | { 73 | float m_StraightLineSqr; 74 | float m_Walking; 75 | float m_Angle; 76 | unsigned int m_Steps; 77 | } m_Radius; 78 | 79 | bool m_WeighByLength; 80 | float m_AngleThresholdDegrees; 81 | unsigned int m_AnglePrecisionDegrees; 82 | 83 | // Per segment stats 84 | unsigned int* m_NodeCounts; 85 | float* m_TotalDepths; 86 | float* m_TotalWeights; 87 | float* m_TotalDepthWeights; // SUM(depth*weight) for each reached node 88 | 89 | class CWorker; 90 | 91 | std::vector> m_Workers; 92 | 93 | friend class CWorker; 94 | }; -------------------------------------------------------------------------------- /pstalgo/test/tests/testcreatebufferpolygons.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import array 23 | import unittest 24 | import pstalgo 25 | from .common import IsRoughlyEqual 26 | 27 | class TestCreateBufferPolygons(unittest.TestCase): 28 | 29 | def test_create_buffer_polygons(self): 30 | lineCoords = array.array('d', [ 31 | 0, 0, 32 | 2, 2, 33 | 0, 2, 34 | 2, 0, 35 | ]) 36 | values1 = array.array('f', [ 37 | 1, 38 | 2, 39 | ]) 40 | values2 = array.array('f', [ 41 | 3, 42 | 4, 43 | ]) 44 | ranges = [ 45 | (0, 1), 46 | (1, 2), 47 | ] 48 | (raster, compareMin, compareMax, handle1) = pstalgo.CompareResults( 49 | lineCoords1=lineCoords, 50 | values1=values1, 51 | lineCoords2=None, 52 | values2=values2) 53 | (polygonCountPerRange, polygonData, polygonCoords, handle2) = pstalgo.RasterToPolygons(raster, ranges) 54 | try: 55 | pass 56 | # dataPos = 0 57 | # coordPos = 0 58 | # for rangeIndex in range(len(ranges)): 59 | # print(f"Range #{rangeIndex}:") 60 | # for polygonIndex in range(polygonCountPerRange[rangeIndex]): 61 | # print(f" Polygon #{polygonIndex}:") 62 | # ringCount = polygonData[dataPos] 63 | # dataPos += 1 64 | # for ringIndex in range(ringCount): 65 | # pointCount = polygonData[dataPos] 66 | # dataPos += 1 67 | # coords = ["(%.2f %.2f)" % (polygonCoords[coordPos + pointIndex * 2], polygonCoords[coordPos + pointIndex * 2 + 1]) for pointIndex in range(pointCount)] 68 | # coordPos += pointCount * 2 69 | # print(f" Ring #{ringIndex}: " + ' '.join(coords)) 70 | finally: 71 | pstalgo.Free(handle1) 72 | pstalgo.Free(handle2) -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/analyses/AttractionDistance.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include "Common.h" 26 | #include "CreateGraph.h" 27 | 28 | struct SPSTAAttractionDistanceDesc 29 | { 30 | PSTA_DECL_STRUCT_NAME(SPSTAAttractionDistanceDesc) 31 | 32 | // Version 33 | static const unsigned int VERSION = 4; 34 | const unsigned int m_Version = VERSION; 35 | 36 | // Graph 37 | HPSTAGraph m_Graph = nullptr; // Created with a call to PSTACreateGraph 38 | 39 | unsigned char m_OriginType = EPSTAOriginType_Lines; // enum EOriginType 40 | 41 | // Distance measurement 42 | unsigned char m_DistanceType = EPSTADistanceType_Steps; // enum EPSTADistanceType 43 | 44 | // Radius 45 | SPSTARadii m_Radius; 46 | 47 | // Attraction points 48 | double2* m_AttractionPoints = nullptr; 49 | unsigned int m_AttractionPointCount = 0; 50 | 51 | // Attraction Polygons (optional) 52 | // If not NULL this means m_AttractionPoints should be treated as polygon 53 | // corners, and the actual attraction points will be generated at every 54 | // 'm_AttractionPolygonPointInterval' interval along polygon edges. 55 | unsigned int* m_PointsPerAttractionPolygon = nullptr; // Polygons will be closed automatically, start/end point should NOT be repeated 56 | unsigned int m_AttractionPolygonCount = 0; 57 | float m_AttractionPolygonPointInterval = 0; 58 | 59 | // Line weights (custom distance values) 60 | const float* m_LineWeights = nullptr; 61 | unsigned int m_LineWeightCount = 0; 62 | float m_WeightPerMeterForPointEdges = 0; 63 | 64 | // Progress Callback 65 | FPSTAProgressCallback m_ProgressCallback = nullptr; 66 | void* m_ProgressCallbackUser = nullptr; 67 | 68 | // Output arrays (one element per origin, where origin is specified by m_OriginType) 69 | float* m_OutMinDistance = nullptr; 70 | int* m_OutDestinationIndices = nullptr; // -1 if no destination was reachable 71 | unsigned int m_OutputCount = 0; // Element count for output arrays, for verification only 72 | }; 73 | 74 | PSTADllExport bool PSTAAttractionDistance(const SPSTAAttractionDistanceDesc* desc); -------------------------------------------------------------------------------- /pstalgo/src/Debug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #ifndef _MSC_VER 31 | #define vsnprintf_s vsnprintf 32 | #endif 33 | 34 | namespace pstdbg 35 | { 36 | struct SCallback 37 | { 38 | HLogCallback m_Handle; 39 | FLogCallback m_Func; 40 | void* m_UserData; 41 | }; 42 | 43 | HLogCallback g_CallbackCounter = 0; 44 | 45 | std::vector g_Callbacks; 46 | 47 | HLogCallback RegisterLogCallback(FLogCallback func, void* user_data) 48 | { 49 | ASSERT(func && "Tried to register a null function as log callback"); 50 | 51 | ++g_CallbackCounter; 52 | ASSERT((g_CallbackCounter != 0) && "Log callback handle counter overflowed!"); 53 | 54 | SCallback cb; 55 | cb.m_Handle = g_CallbackCounter; 56 | cb.m_Func = func; 57 | cb.m_UserData = user_data; 58 | 59 | g_Callbacks.push_back(cb); 60 | 61 | return g_CallbackCounter; 62 | } 63 | 64 | void UnregisterLogCallback(HLogCallback handle) 65 | { 66 | for (size_t i = 0; i < g_Callbacks.size(); ++i) 67 | { 68 | if (g_Callbacks[i].m_Handle == handle) 69 | { 70 | g_Callbacks.erase(g_Callbacks.begin() + i); 71 | return; 72 | } 73 | } 74 | ASSERT(!"Tried to unregister log callback that wasn't registered"); 75 | } 76 | 77 | void Log(EErrorLevel level, const char* domain, const char* fmt, ...) 78 | { 79 | char buf[4096]; 80 | va_list args; 81 | va_start (args, fmt); 82 | vsnprintf_s(buf, sizeof(buf), fmt, args); 83 | 84 | for (size_t i = 0; i < g_Callbacks.size(); ++i) 85 | { 86 | g_Callbacks[i].m_Func(level, domain, buf, g_Callbacks[i].m_UserData); 87 | } 88 | } 89 | } 90 | 91 | PSTADllExport pstdbg::HLogCallback PSTARegisterLogCallback(pstdbg::FLogCallback func, void* user_data) 92 | { 93 | return pstdbg::RegisterLogCallback(func, user_data); 94 | } 95 | 96 | PSTADllExport void PSTAUnregisterLogCallback(pstdbg::HLogCallback handle) 97 | { 98 | pstdbg::UnregisterLogCallback(handle); 99 | } 100 | -------------------------------------------------------------------------------- /pstalgo/test/tests/graphs.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import array 23 | import pstalgo 24 | 25 | def CreateChainGraph(line_count, line_length): 26 | line_coords = [] 27 | for x in range(line_count+1): 28 | line_coords.append(x*line_length) 29 | line_coords.append(0) 30 | line_indices = [] 31 | for i in range(line_count): 32 | line_indices.append(i) 33 | line_indices.append(i+1) 34 | line_coords = array.array('d', line_coords) 35 | line_indices = array.array('I', line_indices) 36 | graph_handle = pstalgo.CreateGraph(line_coords, line_indices, None, None, None) 37 | return graph_handle 38 | 39 | def CreateSquareGraph(line_length): 40 | line_coords = array.array('d', [0, 0, line_length, 0, line_length, line_length, 0, line_length]) 41 | line_indices = array.array('I', [0, 1, 1, 2, 2, 3, 3, 0]) 42 | graph_handle = pstalgo.CreateGraph(line_coords, line_indices, None, None, None) 43 | return graph_handle 44 | 45 | def CreateSegmentChainGraph(line_count, line_length): 46 | line_coords = [] 47 | for x in range(line_count+1): 48 | line_coords.append(x*line_length) 49 | line_coords.append(0) 50 | line_indices = [] 51 | for i in range(line_count): 52 | line_indices.append(i) 53 | line_indices.append(i+1) 54 | line_coords = array.array('d', line_coords) 55 | line_indices = array.array('I', line_indices) 56 | graph_handle = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) 57 | return graph_handle 58 | 59 | def CreateSegmentSquareGraph(line_length): 60 | line_coords = array.array('d', [0, 0, line_length, 0, line_length, line_length, 0, line_length]) 61 | line_indices = array.array('I', [0, 1, 1, 2, 2, 3, 3, 0]) 62 | graph_handle = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) 63 | return graph_handle 64 | 65 | def CreateCrosshairSegmentGraph(): 66 | # ___ 67 | # |_|_| 68 | # |_|_| 69 | # 70 | line_coords = array.array('d', [-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, 0, 0]) 71 | line_indices = array.array('I', [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0, 3, 8, 8, 7, 1, 8, 8, 5]) 72 | graph_handle = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) 73 | return graph_handle -------------------------------------------------------------------------------- /pstalgo/include/pstalgo/utils/BitVector.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | */ 21 | 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | 28 | 29 | /////////////////////////////////////////////////////////////////////////////// 30 | // 31 | // CBitVector 32 | // 33 | 34 | #ifdef PSTA_64 35 | template 36 | #else 37 | template 38 | #endif 39 | class bit_vector { 40 | 41 | // Data Members 42 | protected: 43 | std::vector m_bits; 44 | size_t m_Size = 0; 45 | const unsigned int WORD_BIT_COUNT = sizeof(TWord) * 8; 46 | 47 | // Operations 48 | public: 49 | inline bool empty() const { return 0 == m_Size; } 50 | inline size_t size() const { return m_Size; } 51 | inline void resize(size_t size) { m_Size = size; m_bits.resize((size + WORD_BIT_COUNT - 1) / WORD_BIT_COUNT); } 52 | inline void clearAll() { if (!m_bits.empty()) memset(&m_bits.front(), 0x00, m_bits.size() * sizeof(TWord)); } 53 | inline void setAll() { if (!m_bits.empty()) memset(&m_bits.front(), 0xFF, m_bits.size() * sizeof(TWord)); } 54 | inline bool get(size_t index) const { return (m_bits[index / WORD_BIT_COUNT] & ((TWord)1 << (index & (WORD_BIT_COUNT - 1)))) != 0; } 55 | inline void set(size_t index) { m_bits[index / WORD_BIT_COUNT] |= ((TWord)1 << (index & (WORD_BIT_COUNT - 1))); } 56 | inline void clear(size_t index) { m_bits[index / WORD_BIT_COUNT] &= ~((TWord)1 << (index & (WORD_BIT_COUNT - 1))); } 57 | 58 | template 59 | inline void forEachSetBit(TFunc&& fn) const 60 | { 61 | if (empty()) 62 | { 63 | return; 64 | } 65 | auto* at = m_bits.data(); 66 | auto* end = at + m_bits.size(); 67 | for (size_t base_index = 0; at < end; at++, base_index += WORD_BIT_COUNT) 68 | { 69 | auto w = *at; 70 | while (w) 71 | { 72 | const auto bit_index = psta::bit_scan_reverse(w); 73 | const auto index = base_index + bit_index; 74 | if (index >= m_Size) 75 | { 76 | return; 77 | } 78 | w ^= (TWord)1 << bit_index; 79 | fn(index); 80 | } 81 | } 82 | } 83 | }; 84 | 85 | typedef bit_vector CBitVector; -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | from .angularintegration import AngularIntegration, AngularIntegrationNormalize, AngularIntegrationNormalizeLengthWeight, AngularIntegrationSyntaxNormalize, AngularIntegrationSyntaxNormalizeLengthWeight, AngularIntegrationHillierNormalize, AngularIntegrationHillierNormalizeLengthWeight 23 | from .attractiondistance import AttractionDistance 24 | from .attractionreach import AttractionReach, AttractionScoreAccumulationMode, AttractionWeightFunction, AttractionDistributionFunc, AttractionCollectionFunc 25 | from .calculateisovists import CreateIsovistContext, CalculateIsovist, IsovistContextGeometry 26 | from .callbacktest import CallbackTest 27 | from .createbufferpolygons import CompareResults, CompareResultsMode, RasterToPolygons 28 | from .creategraph import CreateGraph, FreeGraph, GetGraphInfo, GetGraphLineLengths, GetGraphCrossingCoords, CreateSegmentGraph, FreeSegmentGraph, CreateSegmentGroupGraph, FreeSegmentGroupGraph 29 | from .createjunctions import CreateJunctions 30 | from .createsegmentmap import CreateSegmentMap 31 | from .log import ErrorLevel, FormatLogMessage, RegisterLogCallback, UnregisterLogCallback 32 | from .networkintegration import NetworkIntegration 33 | from .angularchoice import AngularChoice, AngularChoiceNormalize, AngularChoiceSyntaxNormalize 34 | from .odbetweenness import ODBetweenness, ODBDestinationMode 35 | from .raster import RasterFormat, GetRasterData 36 | from .reach import Reach 37 | from .segmentbetweenness import SegmentBetweenness, BetweennessNormalize, BetweennessSyntaxNormalize 38 | from .fastsegmentbetweenness import FastSegmentBetweenness 39 | from .segmentgrouping import SegmentGrouping 40 | from .segmentgroupintegration import SegmentGroupIntegration 41 | from .common import Free, DistanceType, Radii, StandardNormalize, OriginType, RoadNetworkType 42 | from .vector import Vector 43 | 44 | # TODO: Possibly move out of pstalgo module? This should probably be in an analysis module instead. 45 | def CreateAnalysisDelegateCallbackWrapper(delegate): 46 | def callback(status, progress): 47 | if status is not None: 48 | delegate.setStatus(status) 49 | delegate.setProgress(progress) 50 | return 1 if delegate.getCancel() else 0 51 | return callback -------------------------------------------------------------------------------- /pstalgo/python/pstalgo/segmentgrouping.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2019 Meta Berghauser Pont 3 | 4 | This file is part of PST. 5 | 6 | PST is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. The GNU Lesser General Public License 10 | is intended to guarantee your freedom to share and change all versions 11 | of a program--to make sure it remains free software for all its users. 12 | 13 | PST is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with PST. If not, see . 20 | """ 21 | 22 | import ctypes 23 | from ctypes import byref, cdll, POINTER, Structure, c_double, c_float, c_int, c_uint, c_void_p 24 | from .common import _DLL, PSTALGO_PROGRESS_CALLBACK, CreateCallbackWrapper, UnpackArray, DumpStructure 25 | 26 | 27 | class SPSTASegmentGroupingDesc(Structure) : 28 | _fields_ = [ 29 | # Version 30 | ("m_Version", ctypes.c_uint), 31 | 32 | # Graph 33 | ("m_SegmentGraph", ctypes.c_void_p), 34 | 35 | # Options 36 | ("m_AngleThresholdDegrees", ctypes.c_float), 37 | ("m_SplitGroupsAtJunctions", ctypes.c_bool), 38 | 39 | # Progress Callback 40 | ("m_ProgressCallback", PSTALGO_PROGRESS_CALLBACK), 41 | ("m_ProgressCallbackUser", ctypes.c_void_p), 42 | 43 | ("m_LineCount", ctypes.c_uint), 44 | 45 | # Output 46 | ("m_OutGroupIdPerLine", ctypes.POINTER(ctypes.c_uint)), 47 | ("m_OutGroupCount", ctypes.c_uint), 48 | ("m_OutColorPerLine", ctypes.POINTER(ctypes.c_uint)), 49 | ("m_OutColorCount", ctypes.c_uint), 50 | ] 51 | def __init__(self, *args): 52 | Structure.__init__(self, *args) 53 | self.m_Version = 1 54 | 55 | 56 | def SegmentGrouping(segment_graph, angle_threshold=1.0, split_at_junctions=False, out_group_id_per_line=None, out_color_per_line=None, progress_callback=None): 57 | desc = SPSTASegmentGroupingDesc() 58 | # Graph 59 | desc.m_SegmentGraph = segment_graph 60 | # Settings 61 | desc.m_AngleThresholdDegrees = float(angle_threshold) 62 | desc.m_SplitGroupsAtJunctions = split_at_junctions 63 | # Progress Callback 64 | desc.m_ProgressCallback = CreateCallbackWrapper(progress_callback) 65 | desc.m_ProgressCallbackUser = c_void_p() 66 | # Outputs 67 | (desc.m_OutGroupIdPerLine, n1) = UnpackArray(out_group_id_per_line, 'I') 68 | (desc.m_OutColorPerLine, n2) = UnpackArray(out_color_per_line, 'I') 69 | if out_group_id_per_line is not None: 70 | desc.m_LineCount = n1 71 | elif out_color_per_line is not None: 72 | desc.m_LineCount = n2 73 | else: 74 | desc.m_LineCount = 0 75 | # Make the call 76 | fn = _DLL.PSTASegmentGrouping 77 | fn.restype = ctypes.c_bool 78 | if not fn(ctypes.byref(desc)): 79 | raise Exception("PSTASegmentGrouping failed.") 80 | return (desc.m_OutGroupCount, desc.m_OutColorCount if desc.m_OutColorPerLine is not None else None) --------------------------------------------------------------------------------