Attempts to allocate memory for at least the specified number of geometries.
If the number of geometries is known in advance, calling this function
prior to adding geometries will prevent reallocations and memory fragmentation.
* Add measurement tool bar.
* Add class for measure line.
* Get coordinate of clicked point.
* Add clicked point to string line.
* Store clicekd points to layer.
* Try to render the measurement line.
* Render the measurement line (with some problems).
* Store points in vector.
* Make identify and measure tool exlusive to each other.
* Add measurement dialog.
* Fix only one action must active.
* Some code suggestion from Martin.
* Revert code to show the line.
* Show segment length and the total.
* Implement close dialog means restart 3d measurement.
* Add new button.
* Add unit combo box.
* Fix shadowing private member of class.
* Add slot to combo box unit changes.
* Hide ellipsoid and cartesian radio button.
* Add measure line for QgsPoint.
* Add unit changes feature.
* Add help (pointed to 2D measurement tool).
* Add finish measurement using right click.
* Remove keypress event, it does not make sense.
* Add remove-last-point with middle button.
* Add crsChanged event.
* Remove confusing tooltip.
* Add pan (camera control) action tool for clear state of 3d map tool.
* Change 3D identify tool cursor.
* Fix distance 2D to 3D.
* Remove unclear method.
* Add unit test for measureLine3D.
* Add 3D measurement setting.
* Add header.
* Make extra 3D renderers refresh the scene when they are updated
+ update the 3D renderer every time the measurement line layer is modified
* Set Altitude clamping to absolute.
* Remove options for 3D measurement line.
* Remove help button in 3D measurement dialog.
* Merge duplicate code for handle clicked position.
* Use color for 3d measure line from 2d one.
* Remove unneeded reimplementation method.
* Remove 2D canvas reference.
* Unify update measurement layer.
Use local variable for feature and line
* Create measurement layer once.
* Use data provider to change the geometry.
* Add length3D for QgsLineString.
* Simplify distance calculation and presentation. Remove QgsDistanceArea measurement.
* Descaled z value based on the terrain vertical scale.
* Remove line when tool is deactivated.
* Enable changing the line color from setting, but after re-activation.
* Update color of measurement line after saving option.
* Remove debug message.
* Remove 3D length calculation from distancearea.
* Handle 2D case for length3D, more unit test, and docstring.
* Fix typos.
* Addressing Martin's and Nyall's review.
* Remove setMeasurement to avoid confussion.
... you are too slow and QJson API is so ugly.
Now using this wonderful json lib:
https://github.com/nlohmann/json
Results in release mode (QJson tests are not shown but
QJson was even slower than string concat).
PASS : TestQgsJsonUtils::testExportAttributesJson(Use json)
RESULT : TestQgsJsonUtils::testExportAttributesJson():"Use json":
0.0022 msecs per iteration (total: 75, iterations: 32768)
PASS : TestQgsJsonUtils::testExportAttributesJson(Use old string concat)
RESULT : TestQgsJsonUtils::testExportAttributesJson():"Use old string concat":
0.0032 msecs per iteration (total: 54, iterations: 16384)
PASS : TestQgsJsonUtils::testExportFeatureJson(Use json)
RESULT : TestQgsJsonUtils::testExportFeatureJson():"Use json":
0.011 msecs per iteration (total: 96, iterations: 8192)
PASS : TestQgsJsonUtils::testExportFeatureJson(Use old string concat)
RESULT : TestQgsJsonUtils::testExportFeatureJson():"Use old string concat":
0.015 msecs per iteration (total: 64, iterations: 4096)
PASS : TestQgsJsonUtils::testExportGeomToJson(Use json)
RESULT : TestQgsJsonUtils::testExportGeomToJson():"Use json":
0.76 msecs per iteration (total: 98, iterations: 128)
PASS : TestQgsJsonUtils::testExportGeomToJson(Use old string concat)
RESULT : TestQgsJsonUtils::testExportGeomToJson():"Use old string concat":
0.85 msecs per iteration (total: 55, iterations: 64)
PASS : TestQgsJsonUtils::cleanupTestCase()
For non-point geometry subclasses (points are always valid!) we
now cache the results of a geometry validity check. Subsequent
checks utilise the cached result wherever possible.
Because QgsGeometry/QgsFeature objects are implicitly shared, this
means that we avoid a *lot* of duplicate validity checks as
features and geometries are thrown around during processing model
execution.
For the c++ api dox this expands to "\c nullptr" (the
\c directive indicates a code literal value), and for sipify/Python
it expands to ``None`` (`` is sphinx annotation for literal values)
Makes for nicer dox for both c++ and Python!
When a new QgsAbstractGeometry is set on a geometry object, the previous child is deleted.
If the previous object was constructed by Python, it's wrapper will still be alive for
as long as the QgsGeometry is alive. If a new QgsAbstractGeometry is constructed at the same
memory address as the old one, the wrapper will be reused with wrong type (and other)
information, leading to all kind of weird issues.
See also https://www.riverbankcomputing.com/pipermail/pyqt/2019-January/041251.html
qgswkbptr.h is included indirectly by a large number of source files.
So this commit does the following:
- remove #include "qgsapplication.h" from qgswkbptr.h, and copy-paste the swap_endian
function where it's used.
- add the missing #include "qgsapplication.h" in other files
The rationale for this change is:
- qgswkbptr.h doesn't really needs QgsApplication, since it only used swap_endian.
We don't need to add a fake dependency on QgsApplication on every (indirect) "includers"
of qgswkbptr.h
- qgsapplication.h depends on qgsconfig.h which itself changes quite often (on every git op
at least). Before this change, a 'git commit' would trigger a rebuild of about 3500 files.
With this change we're down to ~700.
and asMultiPolygon()
- raise ValueError when these methods are called with null geometries
- raise TypeError when these methods are called with incompatible
geometry types, instead of silently returning empty lists
is called on non-single-polygon geometries
Previously we would just return an empty list when geometries of invalid
type were used, but this is dangerous and we are safer to explicitly
raise errors preventing use of asPolygon() with incompatible geometry types.
Also avoid massive long __repr__ strings for complex geometries,
as these can flood the Python console (and first aid plugin),
and aren't useful for debugging anyway.
Refs #14640
is called on non-single-line geometries
Previously we would just return an empty list when geometries of invalid
type were used, but this is dangerous and we are safer to explicitly
raise errors preventing use of asPolyline() with incompatible geometry types.
is called on non-single-point geometries
Previously we would just return QgsPointXY(0,0) when geometries of invalid
type were used, but this is dangerous and we are safer to explicitly
raise errors preventing use of asPoint() with incompatible geometry types.
Iterates over the geometries in the collection, allowing this type
of code:
gc = QgsGeometryCollection()
gc.fromWkt('GeometryCollection( Point(1 2), Point(11 12), LineString(33 34, 44 45))')
for part in gc:
print(part.asWkt())
- Calling removeGeometry with an invalid index will now raise an IndexError
- Calling collection[0] will return the first geometry in the collection,
collection[1] the second, etc. And negative indices return from the end
of the collection, so collection[-1] returns the last geometry in the collection.
- Geometries can be deleted by calling `del collection[1]` (deletes the
second geometry from the collection). Also supports negative indices
to count from the end of the collection.
- len(QgsCurve) returns number of points in curve
- raise IndexErrors when calling pointN, xAt, yAt, zAt, mAt, setXAt, setYAt,
setMAt, setZAt with invalid vertex indices
- Add [] getter for retrieving specific vertices, eg. ls[0] returns QgsPoint(...)
- Add [] setter for setting specific (existing) vertices, e.g. ls[1] = QgsPoint(1,2)
- Add del support for removing vertices, e.g. del ls[1] removes the second vertex
This allows easy iteration over all the parts of a geometry,
regardless of the geometry's type. E.g.
geometry = QgsGeometry.fromWkt( 'MultiPoint( 0 0, 1 1, 2 2)' )
for part in geometry.parts():
print(part.asWkt())
geometry = QgsGeometry.fromWkt( 'LineString( 0 0, 10 10 )' )
for part in geometry.parts():
print(part.asWkt())
There are two iterators available. QgsGeometry.parts() gives
a non-const iterator, allowing the parts to be modified in place:
geometry = QgsGeometry.fromWkt( 'MultiPoint( 0 0, 1 1, 2 2)' )
for part in geometry.parts():
part.transform(ct)
For a const iteration, calling .const_parts() gives a const
iterator, which cannot edit the parts but avoids a potentially expensive
QgsGeometry detach and clone
geometry = QgsGeometry.fromWkt( 'MultiPoint( 0 0, 1 1, 2 2)' )
for part in geometry.const_parts():
print(part.x())