]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Merge "Make vertices smaller on map UI & CSV import performance improvements"
authorJani Simomaa <jani.simomaa@semantum.fi>
Thu, 4 Apr 2019 19:05:09 +0000 (19:05 +0000)
committerGerrit Code Review <gerrit2@simantics>
Thu, 4 Apr 2019 19:05:09 +0000 (19:05 +0000)
org.simantics.district.feature/rootFiles/QGIS scripts/generateCSV.py
org.simantics.district.network/src/org/simantics/district/network/profile/ArrowLengthStyle.java

index 80c596b2c31733ec7eda00c734469d2eebca3dd1..e4d51508d98e75f7beaa47ee581c8dbe0555ea22 100644 (file)
@@ -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')
index 2e8c3458164770959409e9aa7fce6f87b2276532..0201f0b16b98bae9a2cae6e5bd0e750bcf16afb8 100644 (file)
@@ -20,7 +20,6 @@ import org.simantics.scenegraph.profile.common.ProfileVariables;
 public class ArrowLengthStyle extends ThrottledStyleBase<Double> {
 
        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<Double> {
                // 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);