Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-04-01 Thread Martin Dobias
Hi all

On Mon, Apr 1, 2019 at 1:16 PM Raymond Nijssen  wrote:
>
> Last HF martin and I discussed the current geometry model and some of
> the flaws and weird things. Especially the set() and get() are not very
> logical function names to me.

Just to add more thoughts to this... There is obviously a lot of
confusion regarding geometry API in QGIS since the big refactoring.
Things like QgsGeometry vs QgsAbstractGeometry ... or QgsPoint vs
QgsPointXY. I would say some bits are fixable without too much effort
(e.g. add some missing convenience constructors), but most bits will
need to wait until QGIS 4.0 (e.g. getting rid of methods
accepting/returning QgsPointXY within geometry API).

One idea that I wanted to explore is whether we could avoid having
QgsGeometry in the Python API at all, so it would be a mapped type
like QVariant is in PyQt5. So for example, feat.geometry() would
return directly QgsPoint or QgsLineString. This would avoid the need
to extract the internal geometry object from QgsGeometry and vice
versa (wrap internal geometry object into QgsGeometry). I have not
tried it in practice yet though and it will definitely be an API
break, but if it works, it should simplify things a lot :-)

Cheers
Martin
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-04-01 Thread Raymond Nijssen

Thank you Nyall!

Sorry for replying so late but I suddenly went on a busy 2 week trip abroad.

Last HF martin and I discussed the current geometry model and some of 
the flaws and weird things. Especially the set() and get() are not very 
logical function names to me.


To find out about the model I tested it using a script in the qgis 
python console. I'm still using it often to figure how to create and 
convert geometries. Hope it helps others as well. Would be nice for the 
cookbook maybe.


Kind regards,
Raymond

#points

p1 = QgsGeometry().fromWkt('point(0 0)')
print(p1) # 
print(p1.asPoint()) # 
print(p1.centroid()) # 
print(p1.buffer(1, 1)) # 0))>

print(p1.get()) # 

p2 = QgsPoint(1,2)
print(p2) # 
p2g = QgsGeometry(p2)
print(p2g) # 
print(p2) # 
print(p2.centroid()) # 
print(QgsPointXY(p2.x(), p2.y())) # 
#print(QgsGeometry(p2)) #!!! Converts 
p2 in place ? !!!

g = QgsGeometry()
print(g)
g.set(p2)
print(g)

p3 = QgsPointXY(2, 0)
print(p3) # 
print(QgsGeometry.fromPointXY(p3)) # 
print(QgsPoint(p3.x(), p3.y())) # 

# lines

l1 = QgsGeometry().fromWkt('linestring((0 0, 1 1, 1 2))')
print(l1) # 
print(l1.buffer(1, 1).asPolygon())
print(l1.asPolyline()) # [, 1)>, ]
#print(QgsLineString(l1.asPolyline())) # TypeError: index 0 has type 
'QgsPointXY' but 'QgsPoint' is expected



p1 = QgsPointXY(100,100)
print(p1)
p2 = QgsPoint(200,200)


l1 = QgsLineString()
print(l1)
l1.addVertex(QgsPoint(p1.x(), p1.y()))
l1.addVertex(p2)
print(l1)

pg1 = QgsGeometry().fromWkt('polygon((0 0, 0 1, 1 1, 1 0, 0 0))')
print(pg1) # 

pg2 = pg1.get()
print(pg2) # 

g = QgsGeometry()
g.set(pg2)
print(g) # 






On 21-03-19 09:43, Nyall Dawson wrote:

On Thu, 21 Mar 2019 at 15:59, Raymond Nijssen  wrote:




  def toLines(geom):
  return QgsGeometry(geom.get().boundary())

(Using 
https://qgis.org/pyqgis/master/core/QgsAbstractGeometry.html#qgis.core.QgsAbstractGeometry.boundary
)

Nyall


Thanks Nyall, that works!


Great, thanks for the confirmation. And because I've got to do mapping
all day, I'm in a good mood, and you get a free PyQGIS lesson:

geom.get() : gives you the underlying fundamental geometry object
attached to the feature. QgsFeature.geometry() returns a QgsGeometry
object, which is more or less a "container" for geometries. It's got
some convenient methods which apply to ALL geometry types, but
sometimes you need to dig down to the actual geometry primitive. In
that case you use geometry.get(), and you get the fundamental
QgsPoint/QgsLineString/QgsPolygon/etc object. It's actually generally
preferable to call "geometry.constGet()", IF you are doing some
operation which doesn't alter the geometry in place (like you are
here). But that's a complex microoptimisation.

geom.get().boundary() gives you the topological boundary of the
primitive. For polygons this is their exterior + interior rings, for
lines it's their start and end point (unless it's a closed ring, in
which case you get a null geometry). Points have no boundary. Using
boundary() to convert polygons to lines is the most efficient method -
it's very heavily optimised, and works perfectly with curved geometry
types and maintains any Z or M values which may be present.

Lastly, you need to wrap the result back up into a QgsGeometry object
- hence QgsGeometry(boundary() ). This is because most of QGIS API
works with QgsGeometry objects (remember, they are like "containers"
holding a geometry), and NOT the fundamental geometry objects.

Done! A super-efficient, rock solid approach which will work with all
input geometry types. Win!

(for reference - this is what the polygons to lines algorithm actually
does in the background too)

Nyall











I will try tomorrow.

One last question, it seems to me like the old code is working again in
3.7. Can you confirm that?


Shouldn't be -- maybe you have a leftover .py file here?


Indeed. I did a clean install and it is not working in my 3.7 anymore.


Regards,
Raymond




___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-21 Thread Nyall Dawson
On Thu, 21 Mar 2019 at 15:59, Raymond Nijssen  wrote:
>
>
> >  def toLines(geom):
> >  return QgsGeometry(geom.get().boundary())
> >
> > (Using 
> > https://qgis.org/pyqgis/master/core/QgsAbstractGeometry.html#qgis.core.QgsAbstractGeometry.boundary
> > )
> >
> > Nyall
>
> Thanks Nyall, that works!

Great, thanks for the confirmation. And because I've got to do mapping
all day, I'm in a good mood, and you get a free PyQGIS lesson:

geom.get() : gives you the underlying fundamental geometry object
attached to the feature. QgsFeature.geometry() returns a QgsGeometry
object, which is more or less a "container" for geometries. It's got
some convenient methods which apply to ALL geometry types, but
sometimes you need to dig down to the actual geometry primitive. In
that case you use geometry.get(), and you get the fundamental
QgsPoint/QgsLineString/QgsPolygon/etc object. It's actually generally
preferable to call "geometry.constGet()", IF you are doing some
operation which doesn't alter the geometry in place (like you are
here). But that's a complex microoptimisation.

geom.get().boundary() gives you the topological boundary of the
primitive. For polygons this is their exterior + interior rings, for
lines it's their start and end point (unless it's a closed ring, in
which case you get a null geometry). Points have no boundary. Using
boundary() to convert polygons to lines is the most efficient method -
it's very heavily optimised, and works perfectly with curved geometry
types and maintains any Z or M values which may be present.

Lastly, you need to wrap the result back up into a QgsGeometry object
- hence QgsGeometry(boundary() ). This is because most of QGIS API
works with QgsGeometry objects (remember, they are like "containers"
holding a geometry), and NOT the fundamental geometry objects.

Done! A super-efficient, rock solid approach which will work with all
input geometry types. Win!

(for reference - this is what the polygons to lines algorithm actually
does in the background too)

Nyall




>
> >
> >
> >>
> >> I will try tomorrow.
> >>
> >> One last question, it seems to me like the old code is working again in
> >> 3.7. Can you confirm that?
> >
> > Shouldn't be -- maybe you have a leftover .py file here?
>
> Indeed. I did a clean install and it is not working in my 3.7 anymore.
>
>
> Regards,
> Raymond
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-20 Thread Raymond Nijssen



 def toLines(geom):
 return QgsGeometry(geom.get().boundary())

(Using 
https://qgis.org/pyqgis/master/core/QgsAbstractGeometry.html#qgis.core.QgsAbstractGeometry.boundary
)

Nyall


Thanks Nyall, that works!






I will try tomorrow.

One last question, it seems to me like the old code is working again in
3.7. Can you confirm that?


Shouldn't be -- maybe you have a leftover .py file here?


Indeed. I did a clean install and it is not working in my 3.7 anymore.


Regards,
Raymond
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-20 Thread Nyall Dawson
On Thu, 21 Mar 2019 at 12:17, Raymond Nijssen  wrote:
>
> Hi Nyall, thanks for your answer.
>
> Somewhere in the middle of a calculation process (not an algorithm) I'd
> like to add a polygon feature to a line layer. I'm using the function to
> turn the polygon into a line geometry.
>
>
>
> I'm using it like this and don't know I figured this out or decided on it:
>
> from processing.algs.qgis import PolygonsToLines
>
> toLines = PolygonsToLines.PolygonsToLines().convertToLines
>
>
> then later on many places in my code:
>
> geom = toLines(geom)
>
>
>
> I remember it took me a while to figure out that second line, but having
> my own short "alias" function toLines() is very convenient. But maybe I
> can create it in another way, holding the processing.run code.

I'd replace this with:

def toLines(geom):
return QgsGeometry(geom.get().boundary())

(Using 
https://qgis.org/pyqgis/master/core/QgsAbstractGeometry.html#qgis.core.QgsAbstractGeometry.boundary
)

Nyall


>
> I will try tomorrow.
>
> One last question, it seems to me like the old code is working again in
> 3.7. Can you confirm that?

Shouldn't be -- maybe you have a leftover .py file here?

>
> Kind regards,
> Raymond
>
>
>
> On 21-03-19 01:34, Nyall Dawson wrote:
> > On Thu, 21 Mar 2019 at 02:40, Raymond Nijssen  wrote:
> >>
> >> The folowing line works for me in 3.4.3 and 3.7 (built today) but not in
> >> 3.6.0
> >>
> >> from processing.algs.qgis import PolygonsToLines
> >
> > It was ported from Python -> c++, so is no longer importable like
> > this. What's your use case for importing direct rather than running
> > via processing.run?
> >
> > Nyall
> >
>
> --
> Terglobo
> Fahrenheitstraat 1
> 5223 BJ 's-Hertogenbosch
> The Netherlands
> +31 (0) 6 25 31 49 83
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-20 Thread Raymond Nijssen

Hi Nyall, thanks for your answer.

Somewhere in the middle of a calculation process (not an algorithm) I'd 
like to add a polygon feature to a line layer. I'm using the function to 
turn the polygon into a line geometry.




I'm using it like this and don't know I figured this out or decided on it:

from processing.algs.qgis import PolygonsToLines

toLines = PolygonsToLines.PolygonsToLines().convertToLines


then later on many places in my code:

geom = toLines(geom)



I remember it took me a while to figure out that second line, but having 
my own short "alias" function toLines() is very convenient. But maybe I 
can create it in another way, holding the processing.run code.


I will try tomorrow.

One last question, it seems to me like the old code is working again in 
3.7. Can you confirm that?


Kind regards,
Raymond



On 21-03-19 01:34, Nyall Dawson wrote:

On Thu, 21 Mar 2019 at 02:40, Raymond Nijssen  wrote:


The folowing line works for me in 3.4.3 and 3.7 (built today) but not in
3.6.0

from processing.algs.qgis import PolygonsToLines


It was ported from Python -> c++, so is no longer importable like
this. What's your use case for importing direct rather than running
via processing.run?

Nyall



--
Terglobo
Fahrenheitstraat 1
5223 BJ 's-Hertogenbosch
The Netherlands
+31 (0) 6 25 31 49 83
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Re: [QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-20 Thread Nyall Dawson
On Thu, 21 Mar 2019 at 02:40, Raymond Nijssen  wrote:
>
> The folowing line works for me in 3.4.3 and 3.7 (built today) but not in
> 3.6.0
>
> from processing.algs.qgis import PolygonsToLines

It was ported from Python -> c++, so is no longer importable like
this. What's your use case for importing direct rather than running
via processing.run?

Nyall
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

[QGIS-Developer] cannot import processing algorithm in 3.6

2019-03-20 Thread Raymond Nijssen
The folowing line works for me in 3.4.3 and 3.7 (built today) but not in 
3.6.0


from processing.algs.qgis import PolygonsToLines

Could anyone test in the python console and confirm?

Thanks!
Raymond



--
Terglobo
Fahrenheitstraat 1
5223 BJ 's-Hertogenbosch
The Netherlands
+31 (0) 6 25 31 49 83
___
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer