Source code for catatom2osm.geo.geometry

import logging

from qgis.core import QgsFeature, QgsGeometry, QgsPointXY

from catatom2osm.config import app_name
from catatom2osm.geo.types import WKBMultiPolygon, WKBPolygon
from catatom2osm.report import instance as report

log = logging.getLogger(app_name)


[docs]class Geometry(object): """Methods for QGIS 2-3 compatibility and geometry utilities."""
[docs] @staticmethod def fromPointXY(point): try: return QgsGeometry.fromPointXY(QgsPointXY(point)) except (AttributeError, NameError): return QgsGeometry.fromPoint(point)
[docs] @staticmethod def fromMultiPointXY(mp): try: return QgsGeometry.fromMultiPointXY([QgsPointXY(p) for p in mp]) except AttributeError: return QgsGeometry.fromMultiPoint(mp)
[docs] @staticmethod def fromPolygonXY(polygon): try: return QgsGeometry.fromPolygonXY( [[QgsPointXY(p) for p in r] for r in polygon] ) except AttributeError: return QgsGeometry.fromPolygon(polygon)
[docs] @staticmethod def fromMultiPolygonXY(mp): try: return QgsGeometry.fromMultiPolygonXY( [[[QgsPointXY(p) for p in r] for r in t] for t in mp] ) except AttributeError: return QgsGeometry.fromMultiPolygon(mp)
[docs] @staticmethod def get_multipolygon(feature_or_geometry): """Return feature geometry always as a multipolygon.""" if isinstance(feature_or_geometry, QgsFeature): geom = feature_or_geometry.geometry() else: geom = feature_or_geometry if geom.wkbType() == WKBPolygon: return [geom.asPolygon()] return geom.asMultiPolygon()
[docs] @staticmethod def get_outer_rings(feature_or_geometry): """Return feature geometry as a multipolygon without inner rings.""" mp = Geometry.get_multipolygon(feature_or_geometry) return [[t[0]] for t in mp]
[docs] @staticmethod def get_vertices_list(feature): """Return list of all distinct vertices in feature geometry.""" return [ point for part in Geometry.get_multipolygon(feature) for ring in part for point in ring[0:-1] ]
[docs] @staticmethod def get_outer_vertices(feature): """Return list of distinct vertices in feature geometry outer rings.""" return [ point for part in Geometry.get_multipolygon(feature) for point in part[0][0:-1] ]
[docs] @staticmethod def merge_adjacent_polygons(feature): """ Merge adjacent polygons in a feature geometry. Returns true if geometry is changed. """ if feature.geometry().wkbType() != WKBMultiPolygon: return False mp = Geometry.get_multipolygon(feature) if len(mp) < 2: return False else: geom = None for p in mp: g = Geometry.fromPolygonXY(p) ng = g if geom is None else geom.combine(g) if ng.isGeosValid(): geom = ng if geom is not None: feature.setGeometry(geom) return geom.isGeosValid()
[docs] @staticmethod def merge_adjacent_features(group): """Combine all geometries in group of features.""" geom = False for p in group: g = p.geometry() if g.isGeosValid(): geom = geom.combine(g) if geom else g else: msg = _("The geometry of zone '%s' is not valid") % p["label"] log.warning(msg) report.warnings.append(msg) return geom
[docs] @staticmethod def is_valid(geom): return geom.isGeosValid() and len(Geometry.get_multipolygon(geom)) > 0