From: Jani Simomaa Date: Thu, 4 Apr 2019 19:05:09 +0000 (+0000) Subject: Merge "Make vertices smaller on map UI & CSV import performance improvements" X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=bbe939348eedaeeee3b1031059e2aca42e6137c3;hp=83f7b8f97f2ded1e48ed58d404f76d61625ae17b;p=simantics%2Fdistrict.git Merge "Make vertices smaller on map UI & CSV import performance improvements" --- diff --git a/org.simantics.district.feature/rootFiles/QGIS scripts/generateCSV.py b/org.simantics.district.feature/rootFiles/QGIS scripts/generateCSV.py index 80c596b2..e4d51508 100644 --- a/org.simantics.district.feature/rootFiles/QGIS scripts/generateCSV.py +++ b/org.simantics.district.feature/rootFiles/QGIS scripts/generateCSV.py @@ -23,9 +23,11 @@ from qgis.core import (QgsProcessing, QgsProcessingParameterDistance, QgsVectorDataProvider, QgsFields, - QgsField) + QgsField, + QgsUnitTypes) import processing - +import re +from operator import itemgetter class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): """ @@ -48,11 +50,15 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): PIPE = 'PIPE' SPAN = 'SPAN' TOLERANCE = 'TOLERANCE' + MINIMUM_LENGTH = 'MINIMUM_LENGTH' OUTPUT = 'OUTPUT' # Constants for feature field names FATHER_ID = 'FatherId' LINESTRING = 'LineString' + + # RegExp for DN values in + DN_PATTERN = re.compile(r"DN(\d+)(-.*)?") def tr(self, string): """ @@ -129,14 +135,23 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): ) ) - self.addParameter( - QgsProcessingParameterDistance( - self.TOLERANCE, - self.tr('Location tolerance'), - 0.0, - minValue = 0.0 - ) + tol = QgsProcessingParameterDistance( + self.TOLERANCE, + self.tr('Location tolerance'), + 0.001, + minValue = 0.0 + ) + tol.setDefaultUnit(QgsUnitTypes.DistanceMeters) + self.addParameter( tol ) + + dist = QgsProcessingParameterDistance( + self.MINIMUM_LENGTH, + self.tr('Minimum span length'), + 0.25, + minValue = 0.0 ) + dist.setDefaultUnit(QgsUnitTypes.DistanceMeters) + self.addParameter( dist ) self.addParameter( QgsProcessingParameterFeatureSink( @@ -172,6 +187,14 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): context ) + minLength = self.parameterAsDouble( + parameters, + self.MINIMUM_LENGTH, + context + ) + + feedback.pushInfo('Tolerance: {} m\nMinimum span length: {} m'.format(eps, minLength)) + sourceFields = span.fields() sourceNames = sourceFields.names() outputFields = QgsFields(sourceFields) @@ -183,6 +206,8 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): if not ('z2' in sourceNames): outputFields.append(QgsField('z2', QVariant.Double)) if not ('Length' in sourceNames): outputFields.append(QgsField('Length', QVariant.Double)) if not ('LineString' in sourceNames): outputFields.append(QgsField('LineString', QVariant.String)) + if not ('DimensionDN' in sourceNames): outputFields.append(QgsField('DimensionDN', QVariant.Int)) + if not ('PipeStruct' in sourceNames): outputFields.append(QgsField('PipeStruct', QVariant.String)) (output, outputId) = self.parameterAsSink( parameters, @@ -210,6 +235,9 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): # Dictionary from span feature ids to lists of lists of QgsPoint objects strings = dict() + # Dictionary for the PipeStruct field values + types = dict() + spanFeatures = span.getFeatures() pipeFeatures = pipe.getFeatures() @@ -222,10 +250,12 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): fatherID = feature[self.FATHER_ID] # Length - length = geometry.length() + myLength = feature['Length'] + if myLength == None: + myLength = geometry.length() oldLength = lengths.get(fatherID, 0.0) - lengths[fatherID] = oldLength + length + lengths[fatherID] = oldLength + myLength # Segment points pointList = strings.get(fatherID, []) @@ -241,6 +271,14 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): pointList.append(mylist) strings[fatherID] = pointList + # Store the value of PipeStruct + t = feature['PipeStruct'] + tt = types.get(fatherID, {}) + types[fatherID] = tt + c = tt.get(t, 0) + c += myLength + tt[t] = c + # Update the progress bar feedback.setProgress(int(counter * total)) @@ -262,17 +300,21 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): #feedback.pushInfo(str(id)) # Length - length = lengths.get(id, None) + myLength = feature['Length'] + + # Ignore short stumps + if myLength <= minLength: + continue # Vertices + mypoints = list(feature.geometry().vertices()) mylist = strings.get(id, None) if mylist == None: feedback.pushInfo('No points for feature {}'.format(id)) - continue + mylist = [mypoints] #feedback.pushInfo('Points: {}'.format("|".join(map(lambda x: ";".join(('{} {}'.format(p.x(), p.y()) for p in x)), mylist)))) - mypoints = list(feature.geometry().vertices()) head = feature.geometry().vertices().next() resultList = [head] @@ -283,21 +325,32 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): mylist = list(map(lambda x: list(reversed(x)), mylist)) i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None) if i == None: - feedback.pushInfo('No matching start vertex for feature {}'.format(id)) - continue + feedback.pushInfo('Warning: No matching start vertex for feature {}'.format(id)) + mylist = [mypoints] + i = 0 + + vertices = mylist.pop(i) while i != None: - vertices = mylist.pop(i) tail = vertices[-1] resultList.extend(vertices[1:]) + if tail.distance(mypoints[-1]) <= eps: + break + i = next((i for i, x in enumerate(mylist) if tail.distance(x[0]) <= eps), None) + if i != None: + vertices = mylist.pop(i) + else: + i = next((i for i, x in enumerate(mylist) if tail.distance(x[-1]) <= eps), None) + if i != None: + vertices = list(reversed(mylist.pop(i))) # feedback.pushInfo(str(resultList)) # Convert to string result = ";".join(('{} {}'.format(p.x(), p.y()) for p in resultList)) - feedback.pushInfo('Feature {}: {}'.format(id, result)) + # feedback.pushInfo('Feature {}: {}'.format(id, result)) outputFeature = QgsFeature() outputFeature.setFields(outputFields) @@ -311,9 +364,24 @@ class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm): outputFeature['x2'] = feature['x2'] outputFeature['y2'] = feature['y2'] outputFeature['z2'] = feature['z2'] - outputFeature['Length'] = feature['length'] # length + outputFeature['Length'] = feature['Length'] # myLength outputFeature['LineString'] = result + # Handle pipe type codes + mytypes = list(types.get(id, {}).items()) + if len(mytypes) == 0: + feedback.pushInfo('No type codes for feature {}'.format(id)) + else: + if len(mytypes) > 1: + mytypes.sort(key = itemgetter(1)) + feedback.pushInfo('No unique type code for feature {}: {}'.format(id, mytypes)) + outputFeature['PipeStruct'] = mytypes[-1][0] + + label = feature['Label'] + m = self.DN_PATTERN.fullmatch(label) + if m: + outputFeature['DimensionDN'] = int(m.group(1)) + output.addFeature(outputFeature) feedback.pushInfo('Loop done') diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java index 2e8c3458..0201f0b1 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java @@ -20,7 +20,6 @@ import org.simantics.scenegraph.profile.common.ProfileVariables; public class ArrowLengthStyle extends ThrottledStyleBase { private static final Double PENDING = Double.NaN; - private static final Double ONE = 1.0; @Override public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { @@ -33,18 +32,13 @@ public class ArrowLengthStyle extends ThrottledStyleBase { // Prevent PendingVariableExceptions from coming through boolean wasSynchronous = graph.setSynchronous(true); try { - Double length = ONE; if (ds.arrowLengthProperty.isPresent()) { - length = Simantics.applySCLRead(graph, ds.arrowLengthProperty.get(), groupItem); - // System.out.println("read thickness: " + thickness + " : " + ds.arrowLengthProperty); - if (length == null) { - length = ONE; - } else { - length = length * ds.arrowLengthGain + ds.arrowLengthBias; - } + Double length = Simantics.applySCLRead(graph, ds.arrowLengthProperty.get(), groupItem); + return length != null ? length * ds.arrowLengthGain + ds.arrowLengthBias : null; + } + else { + return null; } - - return length; } finally { graph.setSynchronous(wasSynchronous);