Skip to content

Commit f17e2c0

Browse files
committed
[processing] add Points from lines algorithm (still needs some improvements)
1 parent 00e2f1f commit f17e2c0

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

python/plugins/processing/algs/QGISAlgorithmProvider.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
from processing.algs.PointsDisplacement import PointsDisplacement
9090
from sextante.algs.ZonalStatistics import ZonalStatistics
9191
from sextante.algs.PointsFromPolygons import PointsFromPolygons
92+
from sextante.algs.PointsFromLines import PointsFromLines
9293

9394
#from processing.algs.VectorLayerHistogram import VectorLayerHistogram
9495
#from processing.algs.VectorLayerScatterplot import VectorLayerScatterplot
@@ -145,7 +146,8 @@ def __init__(self):
145146
# ------ vector ------
146147
PointsDisplacement(),
147148
ZonalStatistics(),
148-
PointsFromPolygons()
149+
PointsFromPolygons(),
150+
PointsFromLines()
149151
]
150152

151153
def initializeSettings(self):
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
***************************************************************************
5+
PointsFromLines.py
6+
---------------------
7+
Date : August 2013
8+
Copyright : (C) 2013 by Alexander Bruy
9+
Email : alexander dot bruy at gmail dot com
10+
***************************************************************************
11+
* *
12+
* This program is free software; you can redistribute it and/or modify *
13+
* it under the terms of the GNU General Public License as published by *
14+
* the Free Software Foundation; either version 2 of the License, or *
15+
* (at your option) any later version. *
16+
* *
17+
***************************************************************************
18+
"""
19+
20+
__author__ = 'Alexander Bruy'
21+
__date__ = 'August 2013'
22+
__copyright__ = '(C) 2013, Alexander Bruy'
23+
# This will get replaced with a git SHA1 when you do a git archive
24+
__revision__ = '$Format:%H$'
25+
26+
from PyQt4.QtCore import *
27+
28+
from osgeo import gdal
29+
30+
from qgis.core import *
31+
32+
from sextante.core.GeoAlgorithm import GeoAlgorithm
33+
from sextante.core.QGisLayers import QGisLayers
34+
35+
from sextante.parameters.ParameterRaster import ParameterRaster
36+
from sextante.parameters.ParameterVector import ParameterVector
37+
38+
from sextante.outputs.OutputVector import OutputVector
39+
40+
from sextante.algs import QGISUtils as utils
41+
42+
class PointsFromLines(GeoAlgorithm):
43+
44+
INPUT_RASTER = "INPUT_RASTER"
45+
RASTER_BAND = "RASTER_BAND"
46+
INPUT_VECTOR = "INPUT_VECTOR"
47+
OUTPUT_LAYER = "OUTPUT_LAYER"
48+
49+
def defineCharacteristics(self):
50+
self.name = "Points from lines"
51+
self.group = "Vector geometry tools"
52+
53+
self.addParameter(ParameterRaster(self.INPUT_RASTER, "Raster layer"))
54+
self.addParameter(ParameterVector(self.INPUT_VECTOR, "Vector layer", [ParameterVector.VECTOR_TYPE_LINE]))
55+
self.addOutput(OutputVector(self.OUTPUT_LAYER, "Output layer"))
56+
57+
def processAlgorithm(self, progress):
58+
layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT_VECTOR))
59+
60+
rasterPath = unicode(self.getParameterValue(self.INPUT_RASTER))
61+
62+
rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
63+
geoTransform = rasterDS.GetGeoTransform()
64+
rasterDS = None
65+
66+
fields = QgsFields()
67+
fields.append(QgsField("id", QVariant.Int, "", 10, 0))
68+
fields.append(QgsField("line_id", QVariant.Int, "", 10, 0))
69+
fields.append(QgsField("point_id", QVariant.Int, "", 10, 0))
70+
71+
writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields.toList(), QGis.WKBPoint, layer.crs())
72+
73+
outFeature = QgsFeature()
74+
outFeature.setFields(fields)
75+
76+
self.fid = 0
77+
self.lineId = 0
78+
self.pointId = 0
79+
80+
current = 0
81+
features = QGisLayers.features(layer)
82+
total = 100.0 / len(features)
83+
for f in features:
84+
geom = f.geometry()
85+
if geom.isMultipart():
86+
lines = geom.asMultiPolyline()
87+
for line in lines:
88+
for i in xrange(len(line) - 1):
89+
p1 = line[i]
90+
p2 = line[i + 1]
91+
92+
x1, y1 = utils.mapToPixel(p1.x(), p1.y(), geoTransform)
93+
x2, y2 = utils.mapToPixel(p2.x(), p2.y(), geoTransform)
94+
95+
self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature)
96+
else:
97+
points = geom.asPolyline()
98+
for i in xrange(len(points) - 1):
99+
p1 = points[i]
100+
p2 = points[i + 1]
101+
102+
x1, y1 = utils.mapToPixel(p1.x(), p1.y(), geoTransform)
103+
x2, y2 = utils.mapToPixel(p2.x(), p2.y(), geoTransform)
104+
105+
self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature)
106+
107+
self.pointId = 0
108+
self.lineId += 1
109+
110+
current += 1
111+
progress.setPercentage(int(current * total))
112+
113+
del writer
114+
115+
def buildLine(self, startX, startY, endX, endY, geoTransform, writer, feature):
116+
point = QgsPoint()
117+
118+
if startX == endX:
119+
if startY > endY:
120+
startY, endY = endY, startY
121+
row = startX
122+
for col in xrange(startY, endY + 1):
123+
self.createPoint(row, col, geoTransform, writer, feature)
124+
elif startY == endY:
125+
if startX > endX:
126+
startX, endX = endX, startX
127+
col = startY
128+
for row in xrange(startX, endX + 1):
129+
self.createPoint(row, col, geoTransform, writer, feature)
130+
else:
131+
width = endX - startX
132+
height = endY - startY
133+
134+
if width < 0:
135+
dx1 = -1
136+
dx2 = -1
137+
else:
138+
dx1 = 1
139+
dx2 = 1
140+
141+
if height < 0:
142+
dy1 = -1
143+
else:
144+
dy1 = 1
145+
dy2 = 0
146+
147+
longest = abs(width)
148+
shortest = abs(height)
149+
if not longest > shortest:
150+
longest, shortest = shortest, longest
151+
if height < 0:
152+
dy2 = -1
153+
else:
154+
dy2 = 1
155+
dx2 = 0
156+
157+
err = longest / 2
158+
for i in xrange(longest + 1):
159+
self.createPoint(startX, startY, geoTransform, writer, feature)
160+
161+
err += shortest
162+
if not err < longest:
163+
err = err - longest
164+
startX += dx1
165+
startY += dy1
166+
else:
167+
startX += dx2
168+
startY += dy2
169+
170+
def createPoint(self, pX, pY, geoTransform, writer, feature):
171+
x, y = utils.pixelToMap(pX, pY, geoTransform)
172+
173+
feature.setGeometry(QgsGeometry.fromPoint(QgsPoint(x, y)))
174+
feature["id"] = self.fid
175+
feature["line_id"] = self.lineId
176+
feature["point_id"] = self.pointId
177+
178+
self.fid += 1
179+
self.pointId +=1
180+
181+
writer.addFeature(feature)

0 commit comments

Comments
 (0)