Skip to content

Commit a7de620

Browse files
authored
Merge pull request #28 from nens/improve-handling-multisurfaces
Improve handling multisurfaces
2 parents 03015e4 + 2a59a3d commit a7de620

File tree

51 files changed

+64
-2557
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+64
-2557
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ ArcGIS_plugin/bgt_inlooptool/rtree/lib/spatialindex_c-64.dll
1616
.vscode/settings.json
1717
.spyproject
1818
.bak
19+
plugin/bgtinlooptool/bgtinlooptool.zip

ArcGIS_plugin/bgt_inlooptool/bgt_inlooptool_ArcGIS.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -383,17 +383,17 @@ def execute(self, parameters, messages):
383383
tool = BGTInloopToolArcGIS()
384384
params = tool.getParameterInfo()
385385

386-
main_path = r"C:\Users\hsc\OneDrive - Tauw Group bv\ArcGIS\Projects\bgt_inlooptool\Vlaardingen"
386+
main_path = r"C:\Users\vdi\OneDrive - TAUW Group bv\Werkzaamheden\BGT inlooptool\Testdata"
387387
# bgt_file
388-
params[0].value = os.path.join(main_path, "bug1_bgt.zip")
388+
params[0].value = os.path.join(main_path, "bgt.zip")
389389
# pipe_file
390-
params[1].value = os.path.join(main_path, "gwsw_vlaardingen.gpkg")
390+
params[1].value = os.path.join(main_path, "getGeoPackage_6376353cadf9d220ccd567eb.gpkg")
391391
# bag_file
392-
params[2].value = os.path.join(main_path, "bag_Vlaardingen.gpkg")
392+
params[2].value = None #os.path.join(main_path, "bag_Vlaardingen.gpkg")
393393
# kolken_file
394394
params[3].value = None
395395
# area_file
396-
params[4].value = os.path.join(main_path, r"vlaardingen_bug_siebrand.gpkg\main.gebiedsgrens")
396+
params[4].value = os.path.join(main_path, r"polyoon_centrum.gdb\Polygoon_centrum")
397397
# output_location
398398
params[5].value = os.path.join(main_path, "output.gpkg")
399399

ArcGIS_plugin/bgt_inlooptool/cls_general_use.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ def __init__(self, logPrint=False, debug=False):
88
logPrint = False voor logging zonder print functie"""
99
import time
1010

11-
self.startTime = time.clock()
11+
self.startTime = time.perf_counter()
1212
self.logPrint = logPrint
1313
self.debug = debug
1414

1515
def StartAnalyse(self):
1616
"""Reinitialise internal clock"""
1717
import time
1818

19-
self.startTime = time.clock()
19+
self.startTime = time.perf_counter()
2020

2121
def Traceback(self):
2222
""" "Returns error messages in ArcPy object and prints them."""
@@ -52,7 +52,7 @@ def AddTimeMessage(self, strMessage, urg=0):
5252

5353
strTime = (
5454
"Elapsed time from start "
55-
+ str(round(time.clock() - self.startTime))
55+
+ str(round(time.perf_counter()- self.startTime))
5656
+ " seconds on "
5757
+ time.strftime("%H:%M:%S")
5858
+ "."

ArcGIS_plugin/bgt_inlooptool/core/inlooptool.py

+21-34
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
# System imports
22
import os
33
import sys
4-
from pathlib import Path
54

65
# Third-party imports
76
from osgeo import osr
87
from osgeo import gdal
98
from osgeo import ogr
109
from datetime import datetime
1110

12-
# Rtree installation
11+
# Rtree should be installed by the plugin for QGIS
12+
# For ArcGIS Pro the following is needed
13+
import sys
14+
from pathlib import Path
1315
from .rtree_installer import unpack_rtree
16+
if not str(Path(__file__).parent) in sys.path: # bgt_inlooptool\\core
17+
rtree_path = unpack_rtree()
18+
sys.path.append(str(rtree_path))
1419

15-
unpack_rtree()
16-
sys.path.append(str(Path(__file__).parent.parent))
1720
import rtree
1821

1922
# Local imports
@@ -744,60 +747,44 @@ def clean_surfaces(self):
744747
Multipolygons, multisurfaces, curved polygons are forced to polygon.
745748
746749
"""
747-
for stype in ALL_USED_SURFACE_TYPES:
748-
lyr = self.mem_database.GetLayerByName(stype)
749-
if (
750-
lyr is None
751-
): # this happens if this particular layer in the bgt input has no features
750+
for surface_type in ALL_USED_SURFACE_TYPES:
751+
layer = self.mem_database.GetLayerByName(surface_type)
752+
if layer is None: # this happens if this particular layer in the bgt input has no features
752753
continue
753-
lyr.ResetReading()
754+
layer.ResetReading()
754755
delete_fids = []
755-
for f in lyr:
756-
geom = f.GetGeometryRef()
756+
for feature in layer:
757+
geom = feature.GetGeometryRef()
757758
geom_type = geom.GetGeometryType()
758759
if geom_type == ogr.wkbPolygon:
759760
pass
760-
elif geom_type == ogr.wkbCurvePolygon:
761+
elif geom_type in [ogr.wkbCurvePolygon, ogr.wkbMultiSurface]:
761762
# print('Fixing Curve Polygon feature {}'.format(f.GetFID()))
762763
geom_linear = geom.GetLinearGeometry()
763-
f.SetGeometry(geom_linear)
764-
lyr.SetFeature(f)
765-
elif geom_type in [ogr.wkbMultiSurface, ogr.wkbMultiPolygon]:
766-
# print('Fixing MultiSurface or MultiPolygon feature {}'.format(f.GetFID()))
767-
geom_fixed = ogr.ForceToPolygon(geom)
768-
geom_fixed = geom_fixed.MakeValid()
769-
if geom_fixed.GetGeometryType() == ogr.wkbMultiPolygon:
770-
for subgeom in geom_fixed:
771-
if subgeom.GetGeometryType() == ogr.wkbPolygon:
772-
cf = f.Clone()
773-
cf.SetGeometry(subgeom)
774-
lyr.SetFeature(cf)
775-
else:
776-
f.SetGeometry(geom_fixed)
777-
lyr.SetFeature(f)
778-
764+
feature.SetGeometry(geom_linear)
765+
layer.SetFeature(feature)
779766
elif geom_type in (
780767
ogr.wkbLineString,
781768
ogr.wkbCompoundCurve,
782769
ogr.wkbCircularString,
783770
):
784771
# print('Deleting feature {} because it is a Linestring'.format(f.GetFID()))
785-
delete_fids.append(f.GetFID())
772+
delete_fids.append(feature.GetFID())
786773
else:
787774
print(
788775
"Warning: Fixing feature {fid} in {stype} failed! No procedure defined to clean up geometry "
789776
"type {geom_type}. Continuing anyway.".format(
790-
fid=f.GetFID(), stype=stype, geom_type=str(geom_type)
777+
fid=feature.GetFID(), stype=surface_type, geom_type=str(geom_type)
791778
)
792779
)
793780
continue
794781
for fid in delete_fids:
795-
lyr.DeleteFeature(fid)
782+
layer.DeleteFeature(fid)
796783
print(
797-
f"cleaned import of {stype} layer has {lyr.GetFeatureCount()} features"
784+
f"cleaned import of {surface_type} layer has {layer.GetFeatureCount()} features"
798785
)
799786

800-
lyr = None
787+
layer = None
801788

802789
def classify_pipes(self, delete=True):
803790
"""Assign pipe type based on GWSW pipe type. Optionally, delete pipes of type INTERNAL_PIPE_TYPE_IGNORE"""

ArcGIS_plugin/bgt_inlooptool/core/parameters.ini

-14
This file was deleted.

ArcGIS_plugin/bgt_inlooptool/core/rtree_installer.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,13 @@ def get_wheel_filename(
6666

6767

6868
def unpack_whl(whl_file, package_name, extract_dir):
69-
7069
package_dir = extract_dir / package_name
7170
if not package_dir.is_dir():
7271
with ZipFile(whl_file, "r") as zipObj:
7372
zipObj.extractall(extract_dir)
7473

7574

7675
def unpack_rtree():
77-
7876
plugin_path = Path(__file__).parent.parent
7977
search_path = Path(__file__).parent / "whls"
8078
wheel_fn = get_wheel_filename(
@@ -83,5 +81,5 @@ def unpack_rtree():
8381
python_tag_prefix="cp",
8482
abi_tag_suffix="m",
8583
)
86-
8784
unpack_whl(wheel_fn, package_name="rtree", extract_dir=plugin_path)
85+
return plugin_path

core/inlooptool.py

+21-34
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
# System imports
22
import os
33
import sys
4-
from pathlib import Path
54

65
# Third-party imports
76
from osgeo import osr
87
from osgeo import gdal
98
from osgeo import ogr
109
from datetime import datetime
1110

12-
# Rtree installation
11+
# Rtree should be installed by the plugin for QGIS
12+
# For ArcGIS Pro the following is needed
13+
import sys
14+
from pathlib import Path
1315
from .rtree_installer import unpack_rtree
16+
if not str(Path(__file__).parent) in sys.path: # bgt_inlooptool\\core
17+
rtree_path = unpack_rtree()
18+
sys.path.append(str(rtree_path))
1419

15-
unpack_rtree()
16-
sys.path.append(str(Path(__file__).parent.parent))
1720
import rtree
1821

1922
# Local imports
@@ -744,60 +747,44 @@ def clean_surfaces(self):
744747
Multipolygons, multisurfaces, curved polygons are forced to polygon.
745748
746749
"""
747-
for stype in ALL_USED_SURFACE_TYPES:
748-
lyr = self.mem_database.GetLayerByName(stype)
749-
if (
750-
lyr is None
751-
): # this happens if this particular layer in the bgt input has no features
750+
for surface_type in ALL_USED_SURFACE_TYPES:
751+
layer = self.mem_database.GetLayerByName(surface_type)
752+
if layer is None: # this happens if this particular layer in the bgt input has no features
752753
continue
753-
lyr.ResetReading()
754+
layer.ResetReading()
754755
delete_fids = []
755-
for f in lyr:
756-
geom = f.GetGeometryRef()
756+
for feature in layer:
757+
geom = feature.GetGeometryRef()
757758
geom_type = geom.GetGeometryType()
758759
if geom_type == ogr.wkbPolygon:
759760
pass
760-
elif geom_type == ogr.wkbCurvePolygon:
761+
elif geom_type in [ogr.wkbCurvePolygon, ogr.wkbMultiSurface]:
761762
# print('Fixing Curve Polygon feature {}'.format(f.GetFID()))
762763
geom_linear = geom.GetLinearGeometry()
763-
f.SetGeometry(geom_linear)
764-
lyr.SetFeature(f)
765-
elif geom_type in [ogr.wkbMultiSurface, ogr.wkbMultiPolygon]:
766-
# print('Fixing MultiSurface or MultiPolygon feature {}'.format(f.GetFID()))
767-
geom_fixed = ogr.ForceToPolygon(geom)
768-
geom_fixed = geom_fixed.MakeValid()
769-
if geom_fixed.GetGeometryType() == ogr.wkbMultiPolygon:
770-
for subgeom in geom_fixed:
771-
if subgeom.GetGeometryType() == ogr.wkbPolygon:
772-
cf = f.Clone()
773-
cf.SetGeometry(subgeom)
774-
lyr.SetFeature(cf)
775-
else:
776-
f.SetGeometry(geom_fixed)
777-
lyr.SetFeature(f)
778-
764+
feature.SetGeometry(geom_linear)
765+
layer.SetFeature(feature)
779766
elif geom_type in (
780767
ogr.wkbLineString,
781768
ogr.wkbCompoundCurve,
782769
ogr.wkbCircularString,
783770
):
784771
# print('Deleting feature {} because it is a Linestring'.format(f.GetFID()))
785-
delete_fids.append(f.GetFID())
772+
delete_fids.append(feature.GetFID())
786773
else:
787774
print(
788775
"Warning: Fixing feature {fid} in {stype} failed! No procedure defined to clean up geometry "
789776
"type {geom_type}. Continuing anyway.".format(
790-
fid=f.GetFID(), stype=stype, geom_type=str(geom_type)
777+
fid=feature.GetFID(), stype=surface_type, geom_type=str(geom_type)
791778
)
792779
)
793780
continue
794781
for fid in delete_fids:
795-
lyr.DeleteFeature(fid)
782+
layer.DeleteFeature(fid)
796783
print(
797-
f"cleaned import of {stype} layer has {lyr.GetFeatureCount()} features"
784+
f"cleaned import of {surface_type} layer has {layer.GetFeatureCount()} features"
798785
)
799786

800-
lyr = None
787+
layer = None
801788

802789
def classify_pipes(self, delete=True):
803790
"""Assign pipe type based on GWSW pipe type. Optionally, delete pipes of type INTERNAL_PIPE_TYPE_IGNORE"""

core/rtree_installer.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,13 @@ def get_wheel_filename(
6666

6767

6868
def unpack_whl(whl_file, package_name, extract_dir):
69-
7069
package_dir = extract_dir / package_name
7170
if not package_dir.is_dir():
7271
with ZipFile(whl_file, "r") as zipObj:
7372
zipObj.extractall(extract_dir)
7473

7574

7675
def unpack_rtree():
77-
7876
plugin_path = Path(__file__).parent.parent
7977
search_path = Path(__file__).parent / "whls"
8078
wheel_fn = get_wheel_filename(
@@ -83,5 +81,5 @@ def unpack_rtree():
8381
python_tag_prefix="cp",
8482
abi_tag_suffix="m",
8583
)
86-
8784
unpack_whl(wheel_fn, package_name="rtree", extract_dir=plugin_path)
85+
return plugin_path

plugin/bgtinlooptool/BGTInloopTool.py

+4-29
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
from core.inlooptool import *
5858
from core.constants import *
5959
from .ogr2qgis import *
60-
import rtree
6160

6261
MESSAGE_CATEGORY = "BGT Inlooptool"
6362
BGT_API_URL = "https://api.pdok.nl/lv/bgt/download/v1_0/full/custom"
@@ -226,6 +225,7 @@ def finished(self, result):
226225
level=Qgis.Critical,
227226
)
228227
else:
228+
print(str(self.exception))
229229
message = "Bepalen afwateringskenmerken BGT mislukt"
230230
if isinstance(self.exception, FileInputError):
231231
message += ": " + str(self.exception)
@@ -275,40 +275,15 @@ def __init__(self, iface):
275275

276276
# initialize plugin directory
277277
self.plugin_dir = os.path.dirname(__file__)
278-
# initialize locale
279-
locale = QSettings().value("locale/userLocale")[0:2]
280-
locale_path = os.path.join(
281-
self.plugin_dir, "i18n", "BGTInloopTool_{}.qm".format(locale)
282-
)
283-
284-
if os.path.exists(locale_path):
285-
self.translator = QTranslator()
286-
self.translator.load(locale_path)
287-
QCoreApplication.installTranslator(self.translator)
288278

289279
# Declare instance attributes
290280
self.actions = []
291-
self.menu = self.tr("&BGT Inlooptool")
281+
self.menu = "&BGT Inlooptool"
292282

293283
# Check if plugin was started the first time in current QGIS session
294284
# Must be set in initGui() to survive plugin reloads
295285
self.first_start = None
296286

297-
# noinspection PyMethodMayBeStatic
298-
def tr(self, message):
299-
"""Get the translation for a string using Qt translation API.
300-
301-
We implement this ourselves since we do not inherit QObject.
302-
303-
:param message: String for translation.
304-
:type message: str, QString
305-
306-
:returns: Translated version of message.
307-
:rtype: QString
308-
"""
309-
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
310-
return QCoreApplication.translate("BGTInloopTool", message)
311-
312287
def add_action(
313288
self,
314289
icon_path,
@@ -388,7 +363,7 @@ def initGui(self):
388363
icon_path = ":/plugins/BGTInloopTool/icon.png"
389364
self.add_action(
390365
icon_path,
391-
text=self.tr("BGT Inlooptool"),
366+
text="BGT Inlooptool",
392367
callback=self.run,
393368
parent=self.iface.mainWindow(),
394369
)
@@ -399,7 +374,7 @@ def initGui(self):
399374
def unload(self):
400375
"""Removes the plugin menu item and icon from QGIS GUI."""
401376
for action in self.actions:
402-
self.iface.removePluginMenu(self.tr("&BGT Inlooptool"), action)
377+
self.iface.removePluginMenu("&BGT Inlooptool", action)
403378
self.iface.removeToolBarIcon(action)
404379

405380
def validate_extent_layer(self, extent_layer):

0 commit comments

Comments
 (0)