Beispiel #1
0
    def testJSONExporter(self):
        """ test converting features to GeoJSON """
        fields = QgsFields()
        fields.append(QgsField("name", QVariant.String))
        fields.append(QgsField("cost", QVariant.Double))
        fields.append(QgsField("population", QVariant.Int))

        feature = QgsFeature(fields, 5)
        feature.setGeometry(QgsGeometry(QgsPointV2(5, 6)))
        feature.setAttributes(['Valsier Peninsula', 6.8, 198])

        exporter = QgsJSONExporter()

        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test with linestring for bbox inclusion
        l = QgsLineString()
        l.setPoints([QgsPointV2(5, 6), QgsPointV2(15, 16)])
        feature.setGeometry(QgsGeometry(QgsLineString(l)))

        expected = """{
   "type":"Feature",
   "id":5,
   "bbox":[5, 6, 15, 16],
   "geometry":
   {"type": "LineString", "coordinates": [ [5, 6], [15, 16]]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test that precision is respected
        feature.setGeometry(QgsGeometry(QgsPointV2(5.444444444, 6.333333333)))
        exporter.setPrecision(3)
        self.assertEqual(exporter.precision(), 3)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5.444, 6.333]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        feature.setGeometry(QgsGeometry(QgsPointV2(5, 6)))
        exporter.setPrecision(17)

        # test that attribute subset is respected
        exporter.setAttributes([0, 2])
        self.assertEqual(exporter.attributes(), [0, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setAttributes([1])
        self.assertEqual(exporter.attributes(), [1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "cost":6.8
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setAttributes([])

        # text excluding attributes

        exporter.setExcludedAttributes([1])
        self.assertEqual(exporter.excludedAttributes(), [1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setExcludedAttributes([1, 2])
        self.assertEqual(exporter.excludedAttributes(), [1, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula"
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setExcludedAttributes([0, 1, 2])
        self.assertEqual(exporter.excludedAttributes(), [0, 1, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test that excluded attributes take precedence over included

        exporter.setAttributes([1, 2])
        exporter.setExcludedAttributes([0, 1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setAttributes([])
        exporter.setExcludedAttributes([])

        # test excluding geometry
        exporter.setIncludeGeometry(False)
        self.assertEqual(exporter.includeGeometry(), False)
        feature.setGeometry(QgsGeometry(QgsLineString(l)))

        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setIncludeGeometry(True)

        feature.setGeometry(QgsGeometry(QgsPointV2(5, 6)))

        # test excluding attributes
        exporter.setIncludeAttributes(False)
        self.assertEqual(exporter.includeAttributes(), False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setIncludeGeometry(False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setIncludeAttributes(True)

        # test overriding ID
        expected = """{
   "type":"Feature",
   "id":29,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature, id=29), expected)

        # test injecting extra attributes
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198,
      "extra":"val1",
      "extra2":2
   }
}"""
        self.assertEqual(exporter.exportFeature(feature, extraProperties={"extra": "val1", "extra2": 2}), expected)

        exporter.setIncludeAttributes(False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "extra":"val1",
      "extra2":{"nested_map":5,
"nested_map2":"val"},
      "extra3":[1,2,3]
   }
}"""
        self.assertEqual(exporter.exportFeature(feature, extraProperties={"extra": "val1", "extra2": {"nested_map": 5, "nested_map2": "val"}, "extra3": [1, 2, 3]}), expected)
        exporter.setIncludeGeometry(True)
Beispiel #2
0
    def testJSONExporter(self):
        """ test converting features to GeoJSON """
        fields = QgsFields()
        fields.append(QgsField("name", QVariant.String))
        fields.append(QgsField("cost", QVariant.Double))
        fields.append(QgsField("population", QVariant.Int))

        feature = QgsFeature(fields, 5)
        feature.setGeometry(QgsGeometry(QgsPoint(5, 6)))
        feature.setAttributes(['Valsier Peninsula', 6.8, 198])

        exporter = QgsJsonExporter()

        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test with linestring for bbox inclusion
        l = QgsLineString()
        l.setPoints([QgsPoint(5, 6), QgsPoint(15, 16)])
        feature.setGeometry(QgsGeometry(QgsLineString(l)))

        expected = """{
   "type":"Feature",
   "id":5,
   "bbox":[5, 6, 15, 16],
   "geometry":
   {"type": "LineString", "coordinates": [ [5, 6], [15, 16]]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test that precision is respected
        feature.setGeometry(QgsGeometry(QgsPoint(5.444444444, 6.333333333)))
        exporter.setPrecision(3)
        self.assertEqual(exporter.precision(), 3)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5.444, 6.333]},
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        feature.setGeometry(QgsGeometry(QgsPoint(5, 6)))
        exporter.setPrecision(17)

        # test that attribute subset is respected
        exporter.setAttributes([0, 2])
        self.assertEqual(exporter.attributes(), [0, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setAttributes([1])
        self.assertEqual(exporter.attributes(), [1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "cost":6.8
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setAttributes([])

        # text excluding attributes

        exporter.setExcludedAttributes([1])
        self.assertEqual(exporter.excludedAttributes(), [1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula",
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setExcludedAttributes([1, 2])
        self.assertEqual(exporter.excludedAttributes(), [1, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "name":"Valsier Peninsula"
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setExcludedAttributes([0, 1, 2])
        self.assertEqual(exporter.excludedAttributes(), [0, 1, 2])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        # test that excluded attributes take precedence over included

        exporter.setAttributes([1, 2])
        exporter.setExcludedAttributes([0, 1])
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":{
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setAttributes([])
        exporter.setExcludedAttributes([])

        # test excluding geometry
        exporter.setIncludeGeometry(False)
        self.assertEqual(exporter.includeGeometry(), False)
        feature.setGeometry(QgsGeometry(QgsLineString(l)))

        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setIncludeGeometry(True)

        feature.setGeometry(QgsGeometry(QgsPoint(5, 6)))

        # test excluding attributes
        exporter.setIncludeAttributes(False)
        self.assertEqual(exporter.includeAttributes(), False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":
   {"type": "Point", "coordinates": [5, 6]},
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)

        exporter.setIncludeGeometry(False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":null
}"""
        self.assertEqual(exporter.exportFeature(feature), expected)
        exporter.setIncludeAttributes(True)

        # test overriding ID
        expected = """{
   "type":"Feature",
   "id":29,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198
   }
}"""
        self.assertEqual(exporter.exportFeature(feature, id=29), expected)

        # test injecting extra attributes
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "name":"Valsier Peninsula",
      "cost":6.8,
      "population":198,
      "extra":"val1",
      "extra2":2
   }
}"""
        self.assertEqual(
            exporter.exportFeature(feature,
                                   extraProperties={
                                       "extra": "val1",
                                       "extra2": 2
                                   }), expected)

        exporter.setIncludeAttributes(False)
        expected = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "extra":"val1",
      "extra2":{"nested_map":5,
"nested_map2":"val"},
      "extra3":[1,2,3]
   }
}"""
        expected2 = """{
   "type":"Feature",
   "id":5,
   "geometry":null,
   "properties":{
      "extra":"val1",
      "extra2":{"nested_map":5,"nested_map2":"val"},
      "extra3":[1,2,3]
   }
}"""
        exp_f = exporter.exportFeature(feature,
                                       extraProperties={
                                           "extra": "val1",
                                           "extra2": {
                                               "nested_map": 5,
                                               "nested_map2": "val"
                                           },
                                           "extra3": [1, 2, 3]
                                       })
        self.assertTrue(exp_f == expected or exp_f == expected2)
        exporter.setIncludeGeometry(True)
Beispiel #3
0
    def processAlgorithm(self, feedback):
        extent = self.getParameterValue(self.EXTENT).split(',')
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)
        hOverlay = self.getParameterValue(self.HOVERLAY)
        vOverlay = self.getParameterValue(self.VOVERLAY)
        crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

        bbox = QgsRectangle(float(extent[0]), float(extent[2]),
                            float(extent[1]), float(extent[3]))

        width = bbox.width()
        height = bbox.height()

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: {0}/{1}').format(
                    hSpacing, vSpacing))

        if hSpacing <= hOverlay or vSpacing <= vOverlay:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))

        if width < hSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr(
                    'Horizontal spacing is too small for the covered area'))

        if height < vSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Vertical spacing is too small for the covered area'))

        fields = [
            QgsField('left', QVariant.Double, '', 24, 16),
            QgsField('top', QVariant.Double, '', 24, 16),
            QgsField('right', QVariant.Double, '', 24, 16),
            QgsField('bottom', QVariant.Double, '', 24, 16),
            QgsField('id', QVariant.Int, '', 10, 0),
            QgsField('coord', QVariant.Double, '', 24, 15)
        ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QgsWkbTypes.LineString, crs)

        if hOverlay > 0:
            hSpace = [hSpacing - hOverlay, hOverlay]
        else:
            hSpace = [hSpacing, hSpacing]

        if vOverlay > 0:
            vSpace = [vSpacing - vOverlay, vOverlay]
        else:
            vSpace = [vSpacing, vSpacing]

        feat = QgsFeature()
        feat.initAttributes(len(fields))

        count = 0
        id = 1

        # latitude lines
        count_max = height / vSpacing
        count_update = count_max * 0.10
        y = bbox.yMaximum()
        while y >= bbox.yMinimum():
            pt1 = QgsPointV2(bbox.xMinimum(), y)
            pt2 = QgsPointV2(bbox.xMaximum(), y)
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([bbox.xMinimum(), y, bbox.xMaximum(), y, id, y])
            writer.addFeature(feat)
            y = y - vSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(int(count / count_max * 50))

        feedback.setProgress(50)

        # longitude lines
        # counters for progressbar - update every 5%
        count = 0
        count_max = width / hSpacing
        count_update = count_max * 0.10
        x = bbox.xMinimum()
        while x <= bbox.xMaximum():
            pt1 = QgsPointV2(x, bbox.yMaximum())
            pt2 = QgsPointV2(x, bbox.yMinimum())
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([x, bbox.yMaximum(), x, bbox.yMinimum(), id, x])
            writer.addFeature(feat)
            x = x + hSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(50 + int(count / count_max * 50))

        del writer
Beispiel #4
0
    def processAlgorithm(self, progress):
        extent = self.getParameterValue(self.EXTENT).split(",")
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)
        crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

        bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3]))

        width = bbox.width()
        height = bbox.height()

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(self.tr("Invalid grid spacing: %s/%s" % (hSpacing, vSpacing)))

        if width < hSpacing:
            raise GeoAlgorithmExecutionException(self.tr("Horizontal spacing is too small for the covered area"))

        if height < vSpacing:
            raise GeoAlgorithmExecutionException(self.tr("Vertical spacing is too small for the covered area"))

        fields = [
            QgsField("left", QVariant.Double, "", 24, 16),
            QgsField("top", QVariant.Double, "", 24, 16),
            QgsField("right", QVariant.Double, "", 24, 16),
            QgsField("bottom", QVariant.Double, "", 24, 16),
            QgsField("id", QVariant.Int, "", 10, 0),
            QgsField("coord", QVariant.Double, "", 24, 15),
        ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.LineString, crs)

        feat = QgsFeature()
        feat.initAttributes(len(fields))

        count = 0
        id = 1

        # latitude lines
        count_max = height / vSpacing
        count_update = count_max * 0.10
        y = bbox.yMaximum()
        while y >= bbox.yMinimum():
            pt1 = QgsPointV2(bbox.xMinimum(), y)
            pt2 = QgsPointV2(bbox.xMaximum(), y)
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([bbox.xMinimum(), y, bbox.xMaximum(), y, id, y])
            writer.addFeature(feat)
            y = y - vSpacing
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                progress.setPercentage(int(count / count_max * 50))

        progress.setPercentage(50)

        # longitude lines
        # counters for progressbar - update every 5%
        count = 0
        count_max = width / hSpacing
        count_update = count_max * 0.10
        x = bbox.xMinimum()
        while x <= bbox.xMaximum():
            pt1 = QgsPointV2(x, bbox.yMaximum())
            pt2 = QgsPointV2(x, bbox.yMinimum())
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([x, bbox.yMaximum(), x, bbox.yMinimum(), id, x])
            writer.addFeature(feat)
            x = x + hSpacing
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                progress.setPercentage(50 + int(count / count_max * 50))

        del writer
Beispiel #5
0
    def processAlgorithm(self, parameters, context, feedback):
        hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
        vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
        hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
        vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)

        crs = self.parameterAsCrs(parameters, self.CRS, context)
        bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)

        width = bbox.width()
        height = bbox.height()

        if hSpacing <= 0 or vSpacing <= 0:
            raise QgsProcessingException(
                self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))

        if hSpacing <= hOverlay or vSpacing <= vOverlay:
            raise QgsProcessingException(
                self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))

        if width < hSpacing:
            raise QgsProcessingException(
                self.tr('Horizontal spacing is too small for the covered area'))

        if height < vSpacing:
            raise QgsProcessingException(
                self.tr('Vertical spacing is too small for the covered area'))

        fields = QgsFields()
        fields.append(QgsField('left', QVariant.Double, '', 24, 16))
        fields.append(QgsField('top', QVariant.Double, '', 24, 16))
        fields.append(QgsField('right', QVariant.Double, '', 24, 16))
        fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('coord', QVariant.Double, '', 24, 15))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, QgsWkbTypes.LineString, crs)

        if hOverlay > 0:
            hSpace = [hSpacing - hOverlay, hOverlay]
        else:
            hSpace = [hSpacing, hSpacing]

        if vOverlay > 0:
            vSpace = [vSpacing - vOverlay, vOverlay]
        else:
            vSpace = [vSpacing, vSpacing]

        feat = QgsFeature()
        feat.initAttributes(len(fields))

        count = 0
        id = 1

        # latitude lines
        count_max = height / vSpacing
        count_update = count_max * 0.10
        y = bbox.yMaximum()
        while y >= bbox.yMinimum():
            if feedback.isCanceled():
                break

            pt1 = QgsPoint(bbox.xMinimum(), y)
            pt2 = QgsPoint(bbox.xMaximum(), y)
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([bbox.xMinimum(),
                                y,
                                bbox.xMaximum(),
                                y,
                                id,
                                y])
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            y = y - vSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(int(count / count_max * 50))

        feedback.setProgress(50)

        # longitude lines
        # counters for progressbar - update every 5%
        count = 0
        count_max = width / hSpacing
        count_update = count_max * 0.10
        x = bbox.xMinimum()
        while x <= bbox.xMaximum():
            if feedback.isCanceled():
                break

            pt1 = QgsPoint(x, bbox.yMaximum())
            pt2 = QgsPoint(x, bbox.yMinimum())
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([x,
                                bbox.yMaximum(),
                                x,
                                bbox.yMinimum(),
                                id,
                                x])
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            x = x + hSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(50 + int(count / count_max * 50))

        return {self.OUTPUT: dest_id}
Beispiel #6
0
    def processAlgorithm(self, parameters, context, feedback):
        hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
        vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
        hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
        vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)

        crs = self.parameterAsCrs(parameters, self.CRS, context)
        bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)

        width = bbox.width()
        height = bbox.height()

        if hSpacing <= 0 or vSpacing <= 0:
            raise QgsProcessingException(
                self.tr('Invalid grid spacing: {0}/{1}').format(
                    hSpacing, vSpacing))

        if hSpacing <= hOverlay or vSpacing <= vOverlay:
            raise QgsProcessingException(
                self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))

        if width < hSpacing:
            raise QgsProcessingException(
                self.tr(
                    'Horizontal spacing is too small for the covered area'))

        if height < vSpacing:
            raise QgsProcessingException(
                self.tr('Vertical spacing is too small for the covered area'))

        fields = QgsFields()
        fields.append(QgsField('left', QVariant.Double, '', 24, 16))
        fields.append(QgsField('top', QVariant.Double, '', 24, 16))
        fields.append(QgsField('right', QVariant.Double, '', 24, 16))
        fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('coord', QVariant.Double, '', 24, 15))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.LineString, crs)

        if hOverlay > 0:
            hSpace = [hSpacing - hOverlay, hOverlay]
        else:
            hSpace = [hSpacing, hSpacing]

        if vOverlay > 0:
            vSpace = [vSpacing - vOverlay, vOverlay]
        else:
            vSpace = [vSpacing, vSpacing]

        feat = QgsFeature()
        feat.initAttributes(len(fields))

        count = 0
        id = 1

        # latitude lines
        count_max = height / vSpacing
        count_update = count_max * 0.10
        y = bbox.yMaximum()
        while y >= bbox.yMinimum():
            if feedback.isCanceled():
                break

            pt1 = QgsPoint(bbox.xMinimum(), y)
            pt2 = QgsPoint(bbox.xMaximum(), y)
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([bbox.xMinimum(), y, bbox.xMaximum(), y, id, y])
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            y = y - vSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(int(count / count_max * 50))

        feedback.setProgress(50)

        # longitude lines
        # counters for progressbar - update every 5%
        count = 0
        count_max = width / hSpacing
        count_update = count_max * 0.10
        x = bbox.xMinimum()
        while x <= bbox.xMaximum():
            if feedback.isCanceled():
                break

            pt1 = QgsPoint(x, bbox.yMaximum())
            pt2 = QgsPoint(x, bbox.yMinimum())
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([x, bbox.yMaximum(), x, bbox.yMinimum(), id, x])
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            x = x + hSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(50 + int(count / count_max * 50))

        return {self.OUTPUT: dest_id}
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started

        if self.first_start == True:
            self.first_start = False
            self.dlg = SurvexImportDialog()
            self.dlg.selectedFile.clear()
            self.dlg.fileSelector.clicked.connect(self.select_3d_file)
            self.dlg.selectedGPKG.clear()
            self.dlg.GPKGSelector.clicked.connect(self.select_gpkg)
            self.dlg.CRSFromProject.setChecked(False)
            self.dlg.CRSFromFile.clicked.connect(self.crs_from_file)
            self.dlg.CRSFromFile.setChecked(False)
            self.dlg.CRSFromProject.clicked.connect(self.crs_from_project)
            self.dlg.ImportAll.clicked.connect(self.toggle_import_all)
            self.dlg.Legs.clicked.connect(self.all_checked)
            self.dlg.Stations.clicked.connect(self.all_checked)
            self.dlg.Polygons.clicked.connect(self.all_checked)
            self.dlg.Walls.clicked.connect(self.all_checked)
            self.dlg.XSections.clicked.connect(self.all_checked)
            self.dlg.Traverses.clicked.connect(self.all_checked)
            self.dlg.LegsSurface.clicked.connect(self.all_checked)
            self.dlg.LegsSplay.clicked.connect(self.all_checked)
            self.dlg.LegsDuplicate.clicked.connect(self.all_checked)
            self.dlg.StationsSurface.clicked.connect(self.all_checked)

        self.dlg.show()  # show the dialog

        result = self.dlg.exec_()  # Run the dialog event loop

        if result:  # The user pressed OK, and this is what happened next!

            survex_3d = self.dlg.selectedFile.text()
            gpkg_file = self.dlg.selectedGPKG.text()

            include_legs = self.dlg.Legs.isChecked()
            include_stations = self.dlg.Stations.isChecked()
            include_polygons = self.dlg.Polygons.isChecked()
            include_walls = self.dlg.Walls.isChecked()
            include_xsections = self.dlg.XSections.isChecked()
            include_traverses = self.dlg.Traverses.isChecked()

            exclude_surface_legs = not self.dlg.LegsSurface.isChecked()
            exclude_splay_legs = not self.dlg.LegsSplay.isChecked()
            exclude_duplicate_legs = not self.dlg.LegsDuplicate.isChecked()

            exclude_surface_stations = not self.dlg.StationsSurface.isChecked()

            use_clino_wgt = self.dlg.UseClinoWeights.isChecked()
            include_up_down = self.dlg.IncludeUpDown.isChecked()

            discard_features = not self.dlg.KeepFeatures.isChecked()

            if not os.path.exists(survex_3d):
                raise Exception("File '%s' doesn't exist" % survex_3d)

            if discard_features:
                self.leg_list = []
                self.station_list = []
                self.station_xyz = {}
                self.xsect_list = []

            # Read .3d file as binary, parse, and save data structures

            with open(survex_3d, 'rb') as fp:

                line = fp.readline().rstrip()  # File ID check

                if not line.startswith(b'Survex 3D Image File'):
                    raise IOError('Not a survex .3d file: ' + survex_3d)

                line = fp.readline().rstrip()  # File format version

                if not line.startswith(b'v'):
                    raise IOError('Unrecognised survex .3d version in ' +
                                  survex_3d)

                version = int(line[1:])
                if version < 8:
                    raise IOError('Survex .3d version >= 8 required in ' +
                                  survex_3d)

                line = fp.readline().rstrip(
                )  # Metadata (title and coordinate system)
                fields = line.split(b'\x00')

                previous_title = '' if discard_features else self.title

                if previous_title:
                    self.title = previous_title + ' + ' + fields[0].decode(
                        'ascii')
                else:
                    self.title = fields[0].decode('ascii')

                self.set_crs(
                    fields[1].decode('ascii') if len(fields) > 1 else None)

                line = fp.readline().rstrip(
                )  # Timestamp, unused in present application

                if not line.startswith(b'@'):
                    raise IOError('Unrecognised timestamp in ' + survex_3d)

                # timestamp = int(line[1:])

                flag = ord(fp.read(1))  # file-wide flag

                if flag & 0x80:  # abort if extended elevation
                    raise IOError("Can't deal with extended elevation in " +
                                  survex_3d)

                # All file-wide header data read in, now read byte-wise
                # according to .3d spec.  Note that all elements must
                # be processed, in order, otherwise we get out of sync.

                # We first define some baseline dates

                date0 = QDate(1900, 1, 1)
                date1 = QDate(1900, 1, 1)
                date2 = QDate(1900, 1, 1)

                label, style = '', 0xff  # initialise label and style

                legs = []  # will be used to capture leg data between MOVEs
                xsect = []  # will be used to capture XSECT data
                nlehv = None  # .. remains None if there isn't any error data...

                while True:  # start of byte-gobbling while loop

                    char = fp.read(1)

                    if not char:  # End of file (reached prematurely?)
                        raise IOError('Premature end of file in ' + survex_3d)

                    byte = ord(char)

                    if byte <= 0x05:  # STYLE
                        if byte == 0x00 and style == 0x00:  # this signals end of data
                            if legs:  # there may be a pending list of legs to save
                                self.leg_list.append((legs, nlehv))
                            break  # escape from byte-gobbling while loop
                        else:
                            style = byte

                    elif byte <= 0x0e:  # Reserved
                        continue

                    elif byte == 0x0f:  # MOVE
                        xyz = self.read_xyz(fp)
                        if legs:
                            self.leg_list.append((legs, nlehv))
                            legs = []

                    elif byte == 0x10:  # DATE (none)
                        date1 = date2 = date0

                    elif byte == 0x11:  # DATE (single date)
                        days = unpack('<H', fp.read(2))[0]
                        date1 = date2 = date0.addDays(days)

                    elif byte == 0x12:  # DATE (date range, short format)
                        days, extra = unpack('<HB', fp.read(3))
                        date1 = date0.addDays(days)
                        date2 = date0.addDays(days + extra + 1)

                    elif byte == 0x13:  # DATE (date range, long format)
                        days1, days2 = unpack('<HH', fp.read(4))
                        date1 = date0.addDays(days1)
                        date2 = date0.addDays(days2)

                    elif byte <= 0x1e:  # Reserved
                        continue

                    elif byte == 0x1f:  # Error info
                        nlehv = unpack('<iiiii', fp.read(20))

                    elif byte <= 0x2f:  # Reserved
                        continue

                    elif byte <= 0x33:  # XSECT
                        label = self.read_label(fp, label)
                        if byte & 0x02:
                            lrud = unpack('<iiii', fp.read(16))
                        else:
                            lrud = unpack('<hhhh', fp.read(8))
                        xsect.append((label, lrud))
                        if byte & 0x01:  # XSECT_END
                            self.xsect_list.append(xsect)
                            xsect = []

                    elif byte <= 0x3f:  # Reserved
                        continue

                    elif byte <= 0x7f:  # LINE
                        flag = byte & 0x3f
                        if not (flag & 0x20):
                            label = self.read_label(fp, label)
                        xyz_prev = xyz
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_legs and flag & 0x01: break
                            if exclude_duplicate_legs and flag & 0x02: break
                            if exclude_splay_legs and flag & 0x04: break
                            legs.append(((xyz_prev, xyz), label, style, date1,
                                         date2, flag))
                            break

                    elif byte <= 0xff:  # LABEL (or NODE)
                        flag = byte & 0x7f
                        label = self.read_label(fp, label)
                        xyz = self.read_xyz(fp)
                        while (True):  # code pattern to implement logic
                            if exclude_surface_stations and flag & 0x01 and not flag & 0x02:
                                break
                            self.station_list.append((xyz, label, flag))
                            break
                        self.station_xyz[label] = xyz

                # End of byte-gobbling while loop

            # file closes automatically, with open(survex_3d, 'rb') as fp:

            layers = []  # used to keep a list of the created layers

            if include_stations and self.station_list:  # station layer

                station_layer = self.add_layer('stations', 'PointZ')

                attrs = [
                    QgsField(self.station_attr[k], QVariant.Int)
                    for k in self.station_flags
                ]
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                station_layer.dataProvider().addAttributes(attrs)
                station_layer.updateFields()

                features = []

                for (xyz, label, flag) in self.station_list:
                    xyz = [0.01 * v for v in xyz]
                    attrs = [1 if flag & k else 0 for k in self.station_flags]
                    attrs.insert(0, round(xyz[2], 2))  # elevation
                    attrs.insert(0, label)
                    feat = QgsFeature()
                    geom = QgsGeometry(QgsPoint(*xyz))
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    features.append(feat)

                station_layer.dataProvider().addFeatures(features)
                layers.append(station_layer)

            if include_legs and self.leg_list:  # leg layer

                leg_layer = self.add_layer('legs', 'LineStringZ')

                attrs = [
                    QgsField(self.leg_attr[k], QVariant.Int)
                    for k in self.leg_flags
                ]
                if nlehv:
                    [
                        attrs.insert(0, QgsField(s, QVariant.Double))
                        for s in self.error_fields
                    ]
                    attrs.insert(0, QgsField('NLEGS', QVariant.Int))
                attrs.insert(0, QgsField('DATE2', QVariant.Date))
                attrs.insert(0, QgsField('DATE1', QVariant.Date))
                attrs.insert(0, QgsField('STYLE', QVariant.String))
                attrs.insert(0, QgsField('ELEVATION', QVariant.Double))
                attrs.insert(0, QgsField('NAME', QVariant.String))
                leg_layer.dataProvider().addAttributes(attrs)
                leg_layer.updateFields()

                features = []

                for legs, nlehv in self.leg_list:
                    for (xyz_pair, label, style, from_date, to_date,
                         flag) in legs:
                        elev = 0.5 * sum([0.01 * xyz[2] for xyz in xyz_pair])
                        points = []
                        for xyz in xyz_pair:
                            xyz = [0.01 * v for v in xyz]
                            points.append(QgsPoint(*xyz))
                        attrs = [1 if flag & k else 0 for k in self.leg_flags]
                        if nlehv:
                            [
                                attrs.insert(0, 0.01 * v)
                                for v in reversed(nlehv[1:5])
                            ]
                            attrs.insert(0, nlehv[0])
                        attrs.insert(0, to_date)
                        attrs.insert(0, from_date)
                        attrs.insert(0, self.style_type[style])
                        attrs.insert(0, round(elev, 2))
                        attrs.insert(0, label)
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        features.append(feat)

                leg_layer.dataProvider().addFeatures(features)
                layers.append(leg_layer)

            # Now do wall features if asked

            if (include_traverses or include_xsections or include_walls
                    or include_polygons) and self.xsect_list:

                trav_features = []
                wall_features = []
                xsect_features = []
                quad_features = []

                for xsect in self.xsect_list:

                    if len(xsect) < 2:  # if there's only one station ..
                        continue  # .. give up as we don't know which way to face

                    centerline = [
                    ]  # will contain the station position and LRUD data

                    for label, lrud in xsect:
                        xyz = self.station_xyz[
                            label]  # look up coordinates from label
                        lrud_or_zero = tuple([max(0, v) for v in lrud
                                              ])  # deal with missing data
                        centerline.append(
                            xyz + lrud_or_zero)  # and collect as 7-uple

                    direction = [
                    ]  # will contain the corresponding direction vectors

                    # The calculations below use integers for xyz and lrud, and
                    # conversion to metres is left to the end.  Then dh2 is an
                    # integer and the test for a plumb is safely dh2 = 0.

                    # The directions are unit vectors optionally weighted by
                    # cos(inclination) = dh/dl where dh^2 = dx^2 + dy^2 (note, no dz^2),
                    # and dl^2 = dh^2 + dz^2.  The normalisation is correspondingly
                    # either 1/dh, or 1/dh * dh/dl = 1/dl.

                    for i, xyzlrud in enumerate(centerline):
                        x, y, z = xyzlrud[0:3]
                        if i > 0:
                            dx, dy, dz = x - xp, y - yp, z - zp
                            dh2 = dx * dx + dy * dy  # integer horizontal displacement (mm^2)
                            norm = sqrt(dh2 + dz *
                                        dz) if use_clino_wgt else sqrt(dh2)
                            dx, dy = (dx / norm, dy /
                                      norm) if dh2 > 0 and norm > 0 else (0, 0)
                            direction.append((dx, dy))
                        xp, yp, zp = x, y, z

                    left_wall = []
                    right_wall = []
                    up_down = []

                    # We build the walls by walking through the list
                    # of stations and directions, with simple defaults
                    # for the start and end stations

                    for i, (x, y, z, l, r, u, d) in enumerate(centerline):
                        d1x, d1y = direction[i - 1] if i > 0 else (0, 0)
                        d2x, d2y = direction[i] if i + 1 < len(
                            centerline) else (0, 0)
                        dx, dy = d1x + d2x, d1y + d2y  # mean (sum of) direction vectors
                        norm = sqrt(dx * dx +
                                    dy * dy)  # normalise to unit vector
                        ex, ey = (dx / norm, dy / norm) if norm > 0 else (0, 0)
                        # Convert to metres when saving the points
                        left_wall.append((0.01 * (x - l * ey),
                                          0.01 * (y + l * ex), 0.01 * z))
                        right_wall.append((0.01 * (x + r * ey),
                                           0.01 * (y - r * ex), 0.01 * z))
                        up_down.append((0.01 * u, 0.01 * d))

                    # Mean elevation of centerline, used for elevation attribute

                    elev = 0.01 * sum([xyzlrud[2] for xyzlrud in centerline
                                       ]) / len(centerline)
                    attrs = [round(elev, 2)]

                    # Now create the feature sets - first the centerline traverse

                    points = []

                    for xyzlrud in centerline:
                        xyz = [0.01 * v for v in xyzlrud[0:3]
                               ]  # These were mm, convert to metres
                        points.append(QgsPoint(*xyz))

                    linestring = QgsLineString()
                    linestring.setPoints(points)
                    feat = QgsFeature()
                    geom = QgsGeometry(linestring)
                    feat.setGeometry(geom)
                    feat.setAttributes(attrs)
                    trav_features.append(feat)

                    # The walls as line strings

                    for wall in (left_wall, right_wall):

                        points = [QgsPoint(*xyz) for xyz in wall]
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        wall_features.append(feat)

                    # Slightly more elaborate, pair up points on left
                    # and right walls, and build a cross section as a
                    # 2-point line string, and a quadrilateral polygon
                    # with a closed 5-point line string for the
                    # exterior ring.  Note that QGIS polygons are
                    # supposed to have their points ordered clockwise.

                    for i, xyz_pair in enumerate(zip(left_wall, right_wall)):

                        elev = 0.01 * centerline[i][
                            2]  # elevation of station in centerline
                        attrs = [round(elev, 2)]
                        points = [QgsPoint(*xyz) for xyz in xyz_pair]
                        linestring = QgsLineString()
                        linestring.setPoints(points)
                        feat = QgsFeature()
                        geom = QgsGeometry(linestring)
                        feat.setGeometry(geom)
                        feat.setAttributes(attrs)
                        xsect_features.append(feat)

                        if i > 0:
                            elev = 0.5 * (prev_xyz_pair[0][2] + xyz_pair[0][2]
                                          )  # average elevation
                            attrs = [round(elev, 2)]
                            if include_up_down:  # average up / down
                                attrs += [
                                    0.5 * (v1 + v2)
                                    for (v1,
                                         v2) in zip(up_down[i - 1], up_down[i])
                                ]
                            points = [
                            ]  # will contain the exterior 5-point ring, as follows...
                            for xyz in tuple(
                                    reversed(prev_xyz_pair)) + xyz_pair + (
                                        prev_xyz_pair[1], ):
                                points.append(QgsPoint(*xyz))
                            linestring = QgsLineString()
                            linestring.setPoints(points)
                            polygon = QgsPolygon()
                            polygon.setExteriorRing(linestring)
                            feat = QgsFeature()
                            geom = QgsGeometry(polygon)
                            feat.setGeometry(geom)
                            feat.setAttributes(attrs)
                            quad_features.append(feat)

                        prev_xyz_pair = xyz_pair

                # End of processing xsect_list - now add features to requested layers

                attrs = [QgsField('ELEVATION',
                                  QVariant.Double)]  # common to all

                if include_traverses and trav_features:  # traverse layer
                    travs_layer = self.add_layer('traverses', 'LineStringZ')
                    travs_layer.dataProvider().addAttributes(attrs)
                    travs_layer.updateFields()
                    travs_layer.dataProvider().addFeatures(trav_features)
                    layers.append(travs_layer)

                if include_xsections and xsect_features:  # xsection layer
                    xsects_layer = self.add_layer('xsections', 'LineStringZ')
                    xsects_layer.dataProvider().addAttributes(attrs)
                    xsects_layer.updateFields()
                    xsects_layer.dataProvider().addFeatures(xsect_features)
                    layers.append(xsects_layer)

                if include_walls and wall_features:  # wall layer
                    walls_layer = self.add_layer('walls', 'LineStringZ')
                    walls_layer.dataProvider().addAttributes(attrs)
                    walls_layer.updateFields()
                    walls_layer.dataProvider().addFeatures(wall_features)
                    layers.append(walls_layer)

                if include_up_down:  # add fields if requested for polygons
                    attrs += [
                        QgsField(s, QVariant.Double)
                        for s in ('MEAN_UP', 'MEAN_DOWN')
                    ]

                if include_polygons and quad_features:  # polygon layer
                    quads_layer = self.add_layer('polygons', 'PolygonZ')
                    quads_layer.dataProvider().addAttributes(attrs)
                    quads_layer.updateFields()
                    quads_layer.dataProvider().addFeatures(quad_features)
                    layers.append(quads_layer)

            # All layers have been created, now update extents and add to QGIS registry

            if layers:
                [layer.updateExtents() for layer in layers]
                QgsProject.instance().addMapLayers(layers)

            # Write to GeoPackage if requested

            if gpkg_file:
                opts = [
                    QgsVectorFileWriter.CreateOrOverwriteFile,
                    QgsVectorFileWriter.CreateOrOverwriteLayer
                ]
                for i, layer in enumerate(layers):
                    options = QgsVectorFileWriter.SaveVectorOptions()
                    options.actionOnExistingFile = opts[int(
                        i > 0)]  # create file or layer
                    layer_name = layer.name()
                    match = search(
                        ' - ([a-z]*)',
                        layer_name)  # ie, extract 'legs', 'stations', etc
                    options.layerName = str(
                        match.group(1)) if match else layer_name
                    writer = QgsVectorFileWriter.writeAsVectorFormat(
                        layer, gpkg_file, options)
                    if writer:
                        msg = "'{}' -> {} in {}".format(
                            layer_name, options.layerName, gpkg_file)
                        QgsMessageLog.logMessage(msg,
                                                 tag='Import .3d',
                                                 level=Qgis.Info)
                    options, writer = None, None
Beispiel #8
0
    def read(self, params):

        self.inp_path = self.inp_path
        self.params = params

        statinfo = os.stat(self.inp_path)
        file_size = statinfo.st_size
        if file_size == 0:
            return None

        ref = read_epanet_file.InpReader(self.inp_path)

        # ref.LoadFile(self.inp_path)
        # ref.BinUpdateClass()
        links_count = ref.getBinLinkCount()

        # Get all Sections
        mixing = ref.getMixingSection()
        reactions = ref.getReactionsSection()
        sources = ref.getSourcesSection()
        rules = ref.getRulesSection()
        quality = ref.getQualitySection()
        curves = ref.getCurvesSection()
        patterns = ref.getPatternsSection()
        controls = ref.getControlsSection()
        emitters = ref.getEmittersSection()
        emitters_d = {}
        for emitter in emitters:
            emitters_d[emitter[0]] = emitter[1]

        status = ref.getStatusSection()
        demands = ref.getDemandsSection()
        energy = ref.getEnergySection()
        opt_reactions = ref.getReactionsOptionsSection()
        times = ref.getTimesSection()
        report = ref.getReportSection()
        options = ref.getOptionsSection()
        tags = ref.get_tags()
        tags_d = {}

        # Check for QEPANET section in inp file. If it's there, update layer attributes
        qepanet_junctions_elevcorr_od, qepanet_junctions_zone_end_od, \
            qepanet_junctions_pressure_od, qepanet_junctions_pressure_units_od = \
            self.read_qepanet_junctions()
        qepanet_tanks_od = self.read_qepanet_tanks()
        (qepanet_reservoirs_deltaz_od,
         qepanet_reservoirs_press_head_od) = self.read_qepanet_reservoirs()
        (qepanet_pipes_material_od, qepanet_pipes_edu_od,
         qepanet_pipes_zone_id_od, qepanet_pipes_velocity_od,
         qepanet_pipes_frictionloss_od, qepanet_pipes_length_units_od,
         qepanet_pipes_diameter_units_od, qepanet_pipes_velocity_units_od,
         qepanet_pipes_frictionloss_units_od) = self.read_qepanet_pipes()
        qepanet_vertices_od = self.read_qepanet_vertices()

        # Create layers and update
        if mixing:
            self.update_mixing(mixing)
        if reactions:
            self.update_reactions(reactions)
        if sources:
            self.update_sources(sources)
        if rules:
            self.update_rules(rules)
        if quality:
            self.update_quality(quality)
        if controls:
            self.update_controls(controls)
        if demands:
            self.update_demands(demands)
        if energy:
            self.update_energy(energy)
        if opt_reactions:
            self.update_opt_reactions(opt_reactions)
        if times:
            self.update_times(times)
        if report:
            self.update_report(report)
        if options:
            self.update_options(options)

        # Get all Section lengths
        all_sections = [
            len(energy),
            len(opt_reactions),
            len(demands),
            len(status),
            len(emitters),
            len(controls),
            len(patterns),
            len(curves[0]),
            len(quality),
            len(rules),
            len(sources),
            len(reactions),
            len(mixing),
            len(times),
            len(report),
            len(options),
            ref.getBinNodeCount(),
            ref.getBinLinkCount()
        ]
        ss = max(all_sections)

        if tags:
            for tag in tags:
                tags_d[tag.element_id] = tag.tag
            self.params.tag_names = set(tags_d.values())

        xy = ref.getBinNodeCoordinates()

        x = xy[0]
        y = xy[1]
        vertx = xy[2]
        verty = xy[3]
        vertxyFinal = []
        for i in range(len(vertx)):
            vertxy = []
            for u in range(len(vertx[i])):
                vertxy.append([float(vertx[i][u]), float(verty[i][u])])
            if vertxy != []:
                vertxyFinal.append(vertxy)

        # Get data of Junctions
        ndEle = ref.getBinNodeJunctionElevations()
        ndBaseD = ref.getBinNodeBaseDemands()

        ndID = ref.getBinNodeNameID()
        nodes_desc = ref.get_nodes_desc()

        ndPatID = ref.getBinNodeDemandPatternID()

        junctions_lay = None
        if ref.getBinNodeJunctionCount() > 0:

            junctions_lay = MemoryDS.create_junctions_lay(crs=params.crs)
            junctions_lay_dp = junctions_lay.dataProvider()

        # Get data of Pipes
        pipes_lay = None
        pumps_lay = None
        valves_lay = None

        if links_count > 0:

            # Pipes
            pipes_lay = MemoryDS.create_pipes_lay(crs=params.crs)
            pipes_lay_dp = pipes_lay.dataProvider()

            # Pumps
            pumps_lay = MemoryDS.create_pumps_lay(crs=params.crs)
            pumps_lay_dp = pumps_lay.dataProvider()

            # Valves
            valves_lay = MemoryDS.create_valves_lay(crs=params.crs)
            valves_lay_dp = valves_lay.dataProvider()

            pump_index = ref.getBinLinkPumpIndex()
            valve_index = ref.getBinLinkValveIndex()
            ndlConn = ref.getBinNodesConnectingLinksID()
            x1 = []
            x2 = []
            y1 = []
            y2 = []
            stat = ref.getBinLinkInitialStatus()

            kk = 0
            ch = 0
            linkID = ref.getBinLinkNameID()
            link_descs = ref.get_links_desc()
            linkLengths = ref.getBinLinkLength()
            linkDiameters = ref.getBinLinkDiameter()
            linkRough = ref.getBinLinkRoughnessCoeff()
            linkMinorloss = ref.getBinLinkMinorLossCoeff()

        # Write Tank Shapefile and get tank data
        tanks_lay = None
        if ref.getBinNodeTankCount() > 0:
            tanks_lay = MemoryDS.create_tanks_lay(crs=params.crs)
            tanks_lay_dp = tanks_lay.dataProvider()

            ndTankelevation = ref.getBinNodeTankElevations()
            initiallev = ref.getBinNodeTankInitialLevel()
            minimumlev = ref.getBinNodeTankMinimumWaterLevel()
            maximumlev = ref.getBinNodeTankMaximumWaterLevel()
            diameter = ref.getBinNodeTankDiameter()
            minimumvol = ref.getBinNodeTankMinimumWaterVolume()
            volumecurv = ref.getBinNodeTankVolumeCurveID()
            ndTankID = ref.getBinNodeTankNameID()

        reservoirs_lay = None
        if ref.getBinNodeReservoirCount() > 0:
            reservoirs_lay = MemoryDS.create_reservoirs_lay(crs=params.crs)
            reservoirs_lay_dp = reservoirs_lay.dataProvider()

            reservoirs_elev = ref.getBinNodeReservoirElevations()
            # posReservoirs.startEditing()

        vvLink = 68
        bbLink = 1

        vPos = 0
        pPos = 0
        pPosPower = 0
        pPosHead = 0
        pPosSpeed = 0
        pPosSpeedPattern = 0

        for i in range(ss):
            if i == ss / vvLink and vvLink > -1:
                vvLink = vvLink - 1
                bbLink = bbLink + 1

            if i < ref.getBinNodeJunctionCount():
                featJ = QgsFeature()
                point = QgsPointXY(float(x[i]), float(y[i]))

                delta_z = 0
                if qepanet_junctions_elevcorr_od:
                    delta_z = float(qepanet_junctions_elevcorr_od[ndID[i]])

                featJ.setGeometry(QgsGeometry.fromPointXY(point))

                # Emitter
                emitter_coeff = NULL
                if ndID[i] in emitters_d:
                    emitter_coeff = float(emitters_d[ndID[i]])

                # Tag
                tag = ''
                if ndID[i] in tags_d:
                    tag = tags_d[ndID[i]]

                zone_end = 0
                if ndID[i] in qepanet_junctions_zone_end_od:
                    zone_end = int(qepanet_junctions_zone_end_od[ndID[i]])

                pressure = 0
                if ndID[i] in qepanet_junctions_pressure_od:
                    pressure = float(qepanet_junctions_pressure_od[ndID[i]])

                pressure_units = 'meter'
                if ndID[i] in qepanet_junctions_pressure_units_od:
                    pressure_units = qepanet_junctions_pressure_units_od[
                        ndID[i]]

                featJ.setAttributes([
                    ndID[i], ndEle[i] - delta_z, delta_z, ndPatID[i],
                    ndBaseD[i], emitter_coeff, nodes_desc[i], tag, zone_end,
                    pressure, pressure_units
                ])
                junctions_lay_dp.addFeatures([featJ])
                self.params.nodes_sindex.addFeature(featJ)

            if i < links_count:
                if len(stat) == i:
                    ch = 1
                if ch == 1:
                    stat.append('OPEN')

                x1.append(x[ndID.index(ref.getBinLinkFromNode()[i])])
                y1.append(y[ndID.index(ref.getBinLinkFromNode()[i])])
                x2.append(x[ndID.index(ref.getBinLinkToNode()[i])])
                y2.append(y[ndID.index(ref.getBinLinkToNode()[i])])

                if i in pump_index:

                    # Pump
                    point1 = QgsPointXY(float(x1[i]), float(y1[i]))
                    point2 = QgsPointXY(float(x2[i]), float(y2[i]))

                    chPowerPump = ref.getBinLinkPumpPower()
                    cheadpump = ref.getBinLinkPumpCurveNameID()
                    pumpID = ref.getBinLinkPumpNameID()
                    patternsIDs = ref.getBinLinkPumpPatterns()
                    ppatt = ref.getBinLinkPumpPatternsPumpID()
                    linkID = ref.getBinLinkNameID()

                    Head = []
                    Flow = []
                    curve = []
                    power = []
                    pattern = []
                    pumpNameIDPower = ref.getBinLinkPumpNameIDPower()

                    param = None
                    head = None
                    power = None
                    speed = None

                    if pumpID[pPos] in pumpNameIDPower:
                        param = 'POWER'
                        power = float(chPowerPump[pPosPower])
                        pPosPower += 1
                    else:
                        param = 'HEAD'
                        if len(cheadpump) > pPosHead:
                            head = cheadpump[pPosHead]
                            pPosHead += 1
                        else:
                            head = NULL

                    if len(pumpNameIDPower) > 0:
                        for uu in range(0, len(pumpNameIDPower)):
                            if pumpNameIDPower[uu] == pumpID[pPos]:
                                power = float(chPowerPump[uu])
                    if len(patternsIDs) > 0:
                        for uu in range(0, len(ppatt)):
                            if ppatt[uu] == pumpID[pPos]:
                                pattern = patternsIDs[uu]

                    if ref.getBinCurveCount() > 0 and len(
                            pumpNameIDPower) == 0:
                        curveXY = ref.getBinCurvesXY()
                        curvesID = ref.getBinCurvesNameID()
                        for uu in range(0, len(curveXY)):
                            if curvesID[uu] == cheadpump[pPos]:
                                Head.append(str(curveXY[uu][0]))
                                Flow.append(str(curveXY[uu][1]))
                        curve = ref.getBinLinkPumpCurveNameID()[pPos]

                    if pumpID[pPos] in ref.getBinLinkPumpSpeedID():
                        speed = float(ref.getBinLinkPumpSpeed()[pPosSpeed])
                        pPosSpeed += 1

                    pump_pattern = None
                    if pumpID[pPos] in ppatt:
                        pump_pattern = ref.getBinLinkPumpPatterns(
                        )[pPosSpeedPattern]
                        pPosSpeedPattern += 1

                    pump_status = Pump.status_open
                    for statuss in status:
                        if statuss[0] == pumpID[pPos]:
                            if statuss[1].strip().upper(
                            ) == Pump.status_closed or statuss[1].strip(
                            ).upper() == Pump.status_open:
                                pump_status = statuss[1].strip().upper()
                                break

                    featPump = QgsFeature()
                    featPump.setGeometry(
                        QgsGeometry.fromPolylineXY([point1, point2]))

                    tag = ''
                    if linkID[i] in tags_d:
                        tag = tags_d[linkID[i]]

                    featPump.setAttributes([
                        linkID[i], param, head, power, speed, pump_pattern,
                        pump_status, link_descs[i], tag
                    ])
                    pumps_lay_dp.addFeatures([featPump])
                    self.params.nodes_sindex.addFeature(featPump)

                    pPos += 1

                elif i in valve_index:
                    # Valve
                    point1 = QgsPointXY(float(x1[i]), float(y1[i]))
                    point2 = QgsPointXY(float(x2[i]), float(y2[i]))

                    length = 0
                    diameter = 0
                    roughness = 0
                    minorloss = 0
                    featValve = QgsFeature()
                    featValve.setGeometry(
                        (QgsGeometry.fromPolylineXY([point1, point2])))

                    linkID = ref.getBinLinkValveNameID()
                    descs = ref.get_valves_desc()
                    linkType = ref.getBinLinkValveType()
                    linkDiameter = ref.getBinLinkValveDiameters()
                    linkInitSett = ref.getBinLinkValveSetting()
                    linkMinorloss = ref.getBinLinkValveMinorLoss()

                    valve_status = Valve.status_none
                    for statuss in status:
                        if statuss[0] == linkID[vPos]:
                            valve_status = statuss[1]
                            break

                    # Tag
                    tag = ''
                    if linkID[vPos] in tags_d:
                        tag = tags_d[linkID[vPos]]

                    featValve.setAttributes([
                        linkID[vPos], linkDiameter[vPos], linkType[vPos],
                        linkInitSett[vPos], linkMinorloss[vPos], valve_status,
                        descs[vPos], tag
                    ])
                    valves_lay_dp.addFeatures([featValve])
                    self.params.nodes_sindex.addFeature(featValve)

                    vPos += 1

                else:
                    # Pipe

                    # Last point
                    start_node_id = ndlConn[0][i]
                    end_node_id = ndlConn[1][i]

                    # Z
                    start_node_elev = 0
                    end_node_elev = 0
                    for j in range(ref.getBinNodeJunctionCount()):

                        delta_z = 0
                        if qepanet_junctions_elevcorr_od and ndID[
                                j] in qepanet_junctions_elevcorr_od:
                            delta_z = qepanet_junctions_elevcorr_od[ndID[j]]
                        if qepanet_reservoirs_deltaz_od and ndID[
                                j] in qepanet_reservoirs_deltaz_od:
                            delta_z = qepanet_reservoirs_deltaz_od[ndID[j]]
                        if qepanet_tanks_od and ndID[j] in qepanet_tanks_od:
                            delta_z = qepanet_tanks_od[ndID[j]]

                        if ndID[j] == start_node_id:
                            start_node_elev = ndEle[j] + delta_z

                        if ndID[j] == end_node_id:
                            end_node_elev = ndEle[j] + delta_z

                    point1 = QgsPoint(float(x1[i]), float(y1[i]),
                                      start_node_elev)
                    point2 = QgsPoint(float(x2[i]), float(y2[i]),
                                      end_node_elev)

                    if vertx[i]:
                        parts = [point1]
                        for mm in range(len(vertxyFinal[kk])):
                            a = vertxyFinal[kk][mm]

                            z = 0
                            if linkID[i] in qepanet_vertices_od:
                                z = qepanet_vertices_od[linkID[i]]

                            parts.append(QgsPoint(a[0], a[1], z))

                        parts.append(point2)
                        featPipe = QgsFeature()
                        linestring = QgsLineString()
                        linestring.setPoints(parts)
                        geom_3d = QgsGeometry(linestring)
                        featPipe.setGeometry(geom_3d)

                        kk += 1
                    else:
                        featPipe = QgsFeature()
                        # point1 = QgsPoint(float(x1[i]), float(y1[i]))
                        # point2 = QgsPoint(float(x2[i]), float(y2[i]))

                        linestring = QgsLineString()
                        linestring.setPoints([point1, point2])
                        geom_3d = QgsGeometry(linestring)
                        featPipe.setGeometry(geom_3d)

                        # featPipe.setGeometry(QgsGeometry.fromPolyline([point1, point2]))

                    material = None
                    if linkID[i] in qepanet_pipes_material_od:
                        material = qepanet_pipes_material_od[linkID[i]]

                    tag = ''
                    if linkID[i] in tags_d:
                        tag = tags_d[linkID[i]]

                    num_edu = 0
                    if linkID[i] in qepanet_pipes_edu_od:
                        num_edu = int(qepanet_pipes_edu_od[linkID[i]])

                    zone_id = 0
                    if linkID[i] in qepanet_pipes_zone_id_od:
                        zone_id = int(qepanet_pipes_zone_id_od[linkID[i]])

                    velocity = 0
                    if linkID[i] in qepanet_pipes_velocity_od:
                        velocity = float(qepanet_pipes_velocity_od[linkID[i]])

                    frictionloss = 0
                    if linkID[i] in qepanet_pipes_frictionloss_od:
                        frictionloss = float(
                            qepanet_pipes_frictionloss_od[linkID[i]])

                    length_units = 'meters'
                    if linkID[i] in qepanet_pipes_length_units_od:
                        length_units = qepanet_pipes_length_units_od[linkID[i]]

                    diameter_units = 'mm'
                    if linkID[i] in qepanet_pipes_diameter_units_od:
                        diameter_units = qepanet_pipes_diameter_units_od[
                            linkID[i]]

                    velocity_units = 'm/s'
                    if linkID[i] in qepanet_pipes_velocity_units_od:
                        velocity_units = qepanet_pipes_velocity_units_od[
                            linkID[i]]

                    frictionloss_units = 'm'
                    if linkID[i] in qepanet_pipes_frictionloss_units_od:
                        frictionloss_units = qepanet_pipes_frictionloss_units_od[
                            linkID[i]]

                    featPipe.setAttributes([
                        linkID[i], linkLengths[i], linkDiameters[i], stat[i],
                        linkRough[i], linkMinorloss[i], material,
                        link_descs[i], tag, num_edu, zone_id, velocity,
                        frictionloss, length_units, diameter_units,
                        velocity_units, frictionloss_units
                    ])
                    pipes_lay_dp.addFeatures([featPipe])
                    self.params.nodes_sindex.addFeature(featPipe)

            if i < ref.getBinNodeTankCount():
                p = ref.getBinNodeTankIndex()[i] - 1
                featTank = QgsFeature()
                point = QgsPointXY(float(x[p]), float(y[p]))
                featTank.setGeometry(QgsGeometry.fromPointXY(point))

                delta_z = 0
                if ndTankID[i] in qepanet_tanks_od:
                    delta_z = qepanet_tanks_od[ndTankID[i]]

                # Tag
                tag = ''
                if ndTankID[i] in tags_d:
                    tag = tags_d[ndTankID[i]]

                featTank.setAttributes([
                    ndTankID[i], ndTankelevation[i] - delta_z, delta_z,
                    initiallev[i], minimumlev[i], maximumlev[i], diameter[i],
                    minimumvol[i], volumecurv[i], nodes_desc[i], tag
                ])
                tanks_lay_dp.addFeatures([featTank])
                self.params.nodes_sindex.addFeature(featTank)

            if i < ref.getBinNodeReservoirCount():
                p = ref.getBinNodeReservoirIndex()[i] - 1

                feat_reserv = QgsFeature()
                point = QgsPointXY(float(x[p]), float(y[p]))
                feat_reserv.setGeometry(QgsGeometry.fromPointXY(point))

                delta_z = 0
                if ndID[p] in qepanet_reservoirs_deltaz_od:
                    delta_z = qepanet_reservoirs_deltaz_od[ndID[p]]

                pressure_head = 0
                if ndID[p] in qepanet_reservoirs_press_head_od:
                    pressure_head = qepanet_reservoirs_press_head_od[ndID[p]]

                # Tag
                tag = ''
                if ndID[p] in tags_d:
                    tag = tags_d[ndID[p]]

                feat_reserv.setAttributes([
                    ndID[p], reservoirs_elev[i] - delta_z - pressure_head,
                    delta_z, pressure_head, ndPatID[p], nodes_desc[i], tag
                ])
                reservoirs_lay_dp.addFeatures([feat_reserv])
                self.params.nodes_sindex.addFeature(feat_reserv)

        if curves:
            self.update_curves()
        if patterns:
            self.update_patterns()

        return {
            Junction.section_name: junctions_lay,
            Reservoir.section_name: reservoirs_lay,
            Tank.section_name: tanks_lay,
            Pipe.section_name: pipes_lay,
            Pump.section_name: pumps_lay,
            Valve.section_name: valves_lay
        }
Beispiel #9
0
    def processAlgorithm(self, parameters, context, feedback):
        extent = self.getParameterValue(self.EXTENT).split(',')
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)
        hOverlay = self.getParameterValue(self.HOVERLAY)
        vOverlay = self.getParameterValue(self.VOVERLAY)
        crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

        bbox = QgsRectangle(float(extent[0]), float(extent[2]),
                            float(extent[1]), float(extent[3]))

        width = bbox.width()
        height = bbox.height()

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))

        if hSpacing <= hOverlay or vSpacing <= vOverlay:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))

        if width < hSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Horizontal spacing is too small for the covered area'))

        if height < vSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Vertical spacing is too small for the covered area'))

        fields = QgsFields()
        fields.append(QgsField('left', QVariant.Double, '', 24, 16))
        fields.append(QgsField('top', QVariant.Double, '', 24, 16))
        fields.append(QgsField('right', QVariant.Double, '', 24, 16))
        fields.append(QgsField('bottom', QVariant.Double, '', 24, 16))
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        fields.append(QgsField('coord', QVariant.Double, '', 24, 15))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.LineString, crs, context)

        if hOverlay > 0:
            hSpace = [hSpacing - hOverlay, hOverlay]
        else:
            hSpace = [hSpacing, hSpacing]

        if vOverlay > 0:
            vSpace = [vSpacing - vOverlay, vOverlay]
        else:
            vSpace = [vSpacing, vSpacing]

        feat = QgsFeature()
        feat.initAttributes(len(fields))

        count = 0
        id = 1

        # latitude lines
        count_max = height / vSpacing
        count_update = count_max * 0.10
        y = bbox.yMaximum()
        while y >= bbox.yMinimum():
            pt1 = QgsPoint(bbox.xMinimum(), y)
            pt2 = QgsPoint(bbox.xMaximum(), y)
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([bbox.xMinimum(),
                                y,
                                bbox.xMaximum(),
                                y,
                                id,
                                y])
            writer.addFeature(feat, QgsFeatureSink.FastInsert)
            y = y - vSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(int(count / count_max * 50))

        feedback.setProgress(50)

        # longitude lines
        # counters for progressbar - update every 5%
        count = 0
        count_max = width / hSpacing
        count_update = count_max * 0.10
        x = bbox.xMinimum()
        while x <= bbox.xMaximum():
            pt1 = QgsPoint(x, bbox.yMaximum())
            pt2 = QgsPoint(x, bbox.yMinimum())
            line = QgsLineString()
            line.setPoints([pt1, pt2])
            feat.setGeometry(QgsGeometry(line))
            feat.setAttributes([x,
                                bbox.yMaximum(),
                                x,
                                bbox.yMinimum(),
                                id,
                                x])
            writer.addFeature(feat, QgsFeatureSink.FastInsert)
            x = x + hSpace[count % 2]
            id += 1
            count += 1
            if int(math.fmod(count, count_update)) == 0:
                feedback.setProgress(50 + int(count / count_max * 50))

        del writer