mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-10-31 00:06:02 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| """
 | |
| ***************************************************************************
 | |
|     PointsFromLines.py
 | |
|     ---------------------
 | |
|     Date                 : August 2013
 | |
|     Copyright            : (C) 2013 by Alexander Bruy
 | |
|     Email                : alexander dot bruy at gmail dot com
 | |
| ***************************************************************************
 | |
| *                                                                         *
 | |
| *   This program is free software; you can redistribute it and/or modify  *
 | |
| *   it under the terms of the GNU General Public License as published by  *
 | |
| *   the Free Software Foundation; either version 2 of the License, or     *
 | |
| *   (at your option) any later version.                                   *
 | |
| *                                                                         *
 | |
| ***************************************************************************
 | |
| """
 | |
| 
 | |
| __author__ = 'Alexander Bruy'
 | |
| __date__ = 'August 2013'
 | |
| __copyright__ = '(C) 2013, Alexander Bruy'
 | |
| # This will get replaced with a git SHA1 when you do a git archive
 | |
| __revision__ = '$Format:%H$'
 | |
| 
 | |
| from PyQt4.QtCore import *
 | |
| from osgeo import gdal
 | |
| from qgis.core import *
 | |
| from processing.tools import vector, raster, dataobjects
 | |
| from processing.core.GeoAlgorithm import GeoAlgorithm
 | |
| from processing.parameters.ParameterRaster import ParameterRaster
 | |
| from processing.parameters.ParameterVector import ParameterVector
 | |
| from processing.outputs.OutputVector import OutputVector
 | |
| 
 | |
| class PointsFromLines(GeoAlgorithm):
 | |
| 
 | |
|     INPUT_RASTER = "INPUT_RASTER"
 | |
|     RASTER_BAND = "RASTER_BAND"
 | |
|     INPUT_VECTOR = "INPUT_VECTOR"
 | |
|     OUTPUT_LAYER = "OUTPUT_LAYER"
 | |
| 
 | |
|     def defineCharacteristics(self):
 | |
|         self.name = "Get raster values at line nodes"
 | |
|         self.group = "Vector analysis tools"
 | |
| 
 | |
|         self.addParameter(ParameterRaster(self.INPUT_RASTER, "Raster layer"))
 | |
|         self.addParameter(ParameterVector(self.INPUT_VECTOR, "Vector layer", [ParameterVector.VECTOR_TYPE_LINE]))
 | |
|         self.addOutput(OutputVector(self.OUTPUT_LAYER, "Output layer"))
 | |
| 
 | |
|     def processAlgorithm(self, progress):
 | |
|         layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_VECTOR))
 | |
| 
 | |
|         rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER))
 | |
| 
 | |
|         rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
 | |
|         geoTransform = rasterDS.GetGeoTransform()
 | |
|         rasterDS = None
 | |
| 
 | |
|         fields = QgsFields()
 | |
|         fields.append(QgsField("id", QVariant.Int, "", 10, 0))
 | |
|         fields.append(QgsField("line_id", QVariant.Int, "", 10, 0))
 | |
|         fields.append(QgsField("point_id", QVariant.Int, "", 10, 0))
 | |
| 
 | |
|         writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields.toList(), QGis.WKBPoint, layer.crs())
 | |
| 
 | |
|         outFeature = QgsFeature()
 | |
|         outFeature.setFields(fields)
 | |
| 
 | |
|         self.fid = 0
 | |
|         self.lineId = 0
 | |
|         self.pointId = 0
 | |
| 
 | |
|         current = 0
 | |
|         features = vector.features(layer)
 | |
|         total = 100.0 / len(features)
 | |
|         for f in features:
 | |
|             geom = f.geometry()
 | |
|             if geom.isMultipart():
 | |
|                 lines = geom.asMultiPolyline()
 | |
|                 for line in lines:
 | |
|                     for i in xrange(len(line) - 1):
 | |
|                         p1 = line[i]
 | |
|                         p2 = line[i + 1]
 | |
| 
 | |
|                         x1, y1 = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
 | |
|                         x2, y2 = raster.mapToPixel(p2.x(), p2.y(), geoTransform)
 | |
| 
 | |
|                         self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature)
 | |
|             else:
 | |
|                 points = geom.asPolyline()
 | |
|                 for i in xrange(len(points) - 1):
 | |
|                     p1 = points[i]
 | |
|                     p2 = points[i + 1]
 | |
| 
 | |
|                     x1, y1 = raster.mapToPixel(p1.x(), p1.y(), geoTransform)
 | |
|                     x2, y2 = raster.mapToPixel(p2.x(), p2.y(), geoTransform)
 | |
| 
 | |
|                     self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature)
 | |
| 
 | |
|             self.pointId = 0
 | |
|             self.lineId += 1
 | |
| 
 | |
|             current += 1
 | |
|             progress.setPercentage(int(current * total))
 | |
| 
 | |
|         del writer
 | |
| 
 | |
|     def buildLine(self, startX, startY, endX, endY, geoTransform, writer, feature):
 | |
|         point = QgsPoint()
 | |
|         if startX == endX:
 | |
|             if startY > endY:
 | |
|                 startY, endY = endY, startY
 | |
|             row = startX
 | |
|             for col in xrange(startY, endY + 1):
 | |
|                 self.createPoint(row, col, geoTransform, writer, feature)
 | |
|         elif startY == endY:
 | |
|             if startX > endX:
 | |
|                 startX, endX = endX, startX
 | |
|             col = startY
 | |
|             for row in xrange(startX, endX + 1):
 | |
|                 self.createPoint(row, col, geoTransform, writer, feature)
 | |
|         else:
 | |
|             width = endX - startX
 | |
|             height = endY - startY
 | |
| 
 | |
|             if width < 0:
 | |
|                 dx1 = -1
 | |
|                 dx2 = -1
 | |
|             else:
 | |
|                 dx1 = 1
 | |
|                 dx2 = 1
 | |
| 
 | |
|             if height < 0:
 | |
|                 dy1 = -1
 | |
|             else:
 | |
|                 dy1 = 1
 | |
|             dy2 = 0
 | |
| 
 | |
|             longest = abs(width)
 | |
|             shortest = abs(height)
 | |
|             if not longest > shortest:
 | |
|                 longest, shortest = shortest, longest
 | |
|                 if height < 0:
 | |
|                     dy2 = -1
 | |
|                 else:
 | |
|                     dy2 = 1
 | |
|                 dx2 = 0
 | |
| 
 | |
|             err = longest / 2
 | |
|             for i in xrange(longest + 1):
 | |
|                 self.createPoint(startX, startY, geoTransform, writer, feature)
 | |
| 
 | |
|                 err += shortest
 | |
|                 if not err < longest:
 | |
|                     err = err - longest
 | |
|                     startX += dx1
 | |
|                     startY += dy1
 | |
|                 else:
 | |
|                     startX += dx2
 | |
|                     startY += dy2
 | |
| 
 | |
|     def createPoint(self, pX, pY, geoTransform, writer, feature):
 | |
|         x, y = raster.pixelToMap(pX, pY, geoTransform)
 | |
| 
 | |
|         feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(x, y)))
 | |
|         feature["id"] = self.fid
 | |
|         feature["line_id"] = self.lineId
 | |
|         feature["point_id"] = self.pointId
 | |
| 
 | |
|         self.fid += 1
 | |
|         self.pointId +=1
 | |
| 
 | |
|         writer.addFeature(feature)
 |