def get_centermost_point(cluster: object) -> object: """ :param cluster: :return: :rtype: object """ centroid = (MultiPoint(cluster).centroid.x, MultiPoint(cluster).centroid.y) centermost_point = min(cluster, key=lambda point: great_circle(point, centroid).m) return tuple(centermost_point)
def aggregate(self,new_id=1): ## will hold the unioned geometry new_geometry = np.empty((1,1),dtype=object) ## get the masked geometries geoms = self.spatial.value.compressed() if self.spatial.geomtype == 'point': pts = MultiPoint([pt for pt in geoms.flat]) new_geometry[0,0] = Point(pts.centroid.x,pts.centroid.y) else: ## break out the MultiPolygon objects. inextricable geometry errors ## sometimes occur otherwise ugeom = [] for geom in geoms: if isinstance(geom,MultiPolygon): for poly in geom: ugeom.append(poly) else: ugeom.append(geom) ## execute the union new_geometry[0,0] = cascaded_union(ugeom) ## overwrite the original geometry self.spatial._value = new_geometry self.spatial._value_mask = np.array([[False]]) self.spatial._uid = np.ma.array([[new_id]],mask=False) ## aggregate the values self.raw_value = self.value.copy() self.value = self._union_sum_()
def split_to_lines(polygon): """Split a square-ish polygon into 4 lines. :param polygon: :type polygon: shapely.geometry.polygon.Polygon :return: """ breakpoints = [] vertices = polygon.exterior.coords for i in range(1, len(vertices) + 1): a = vertices[i - 1] try: b = vertices[i] except IndexError: break try: c = vertices[i + 1] except IndexError: c = vertices[1] angle = calculate_angle(a, b, c) if MIN_ANGLE < angle < MAX_ANGLE: logging.debug("Adding breakpoint: {}".format(angle)) breakpoints.append(b) if len(breakpoints) != 4: raise Exception( "Expecting 4 breakpoints for polygon, found {}!".format( len(breakpoints))) logging.debug(breakpoints) lines = split(asLineString(polygon.exterior.coords), MultiPoint(breakpoints)) return lines
def analiseCover(self, img): cover = {} polis = {} meshs = {} for r in range(len(self.steps)): cover[r] = [] polis[r] = None meshs[str(r)] = [] for x in range(self.wFrame[0], self.wFrame[2], 1): for y in range(self.wFrame[1], self.wFrame[3], 1): c = img.read_pixel(x, y) try: ci = self.steps.index(c) except: ci = -1 if ci >= 0: #print("c",c,' ci',ci) p = (x, y) for cc in range(0, ci + 1, 1): cover[cc].append(p) for r in range(len(self.steps)): if r >= 0: print("cover at ", r, ' pixels', len(cover[r])) polis[r] = MultiPoint(cover[r]) polis[r] = polis[r].buffer(1.0).buffer(-3.0).buffer(2.0) polis[r] = polis[r].simplify(0.75, preserve_topology=True) print("is valid multipoly", polis[r].is_valid) print("area", polis[r].area) try: print("geoms", len(polis[r].geoms)) haveGeoms = True except: haveGeoms = False print("no geoms but have exterior?") print(len(polis[r].exterior.coords)) if len(polis[r].exterior.coords): ta = [] for mp in list(polis[r].exterior.coords[:]): ta.append([int(mp[0]), int(mp[1])]) meshs[str(r)].append(ta) if haveGeoms: for g in polis[r].geoms: ta = [] for mp in list(g.exterior.coords[:]): ta.append([int(mp[0]), int(mp[1])]) meshs[str(r)].append(ta) #except: # print("no geoms so one poly ?") return cover, polis, meshs
def fix_geom_type(row, expected_geom_type): # ESRI mixes geom_types within a given file. GC2 doesn't accept geojson with mixed types. When expecting multi features this ensures all features in a file are represented as Multi. if 'Multi' not in str( (row.geometry).geom_type) and expected_geom_type == 'MultiPolygon': geom = MultiPolygon([wkt.loads(str(row.geometry))]) elif 'Multi' not in str( (row.geometry).geom_type) and expected_geom_type == 'MultiLineString': geom = MultiLineString([wkt.loads(str(row.geometry))]) elif 'Multi' not in str( (row.geometry).geom_type) and expected_geom_type == 'MultiPoint': geom = MultiPoint([wkt.loads(str(row.geometry))]) else: geom = row.geometry return geom
def get_centermost_point(cluster: np.ndarray) -> object: """ Get center most point of a cluster Args: cluster (np.ndarray): Returns: """ try: if cluster.shape[0] >= 3: points_project = reproject(cluster[:, 0], cluster[:, 1]) hull = ConvexHull(points_project) area = hull.area else: area = 1 except: area = 1 centroid = (MultiPoint(cluster).centroid.x, MultiPoint(cluster).centroid.y) centermost_point = min( cluster, key=lambda point: great_circle(point, centroid).m) return list(centermost_point) + [area]
def unwrap_point(self, geom): if isinstance(geom, MultiPoint): pts = [] for pt in geom: if pt.x < 180: n = Point(pt.x + 360, pt.y) else: n = pt pts.append(n) ret = MultiPoint(pts) else: if geom.x < 180: ret = Point(geom.x + 360, geom.y) else: ret = geom return (ret)
def union(coll): """ Union the object's geometries. new_id :: int :: the new geometry's unique identifier coll :: OcgCollection returns OcgCollection """ ## reset the geometry identifier coll.gid = Identifier(dtype=object) for ocg_variable in coll.variables.itervalues(): ## will hold the unioned geometry new_geometry = np.empty((1, 1), dtype=object) ## get the masked geometries geoms = ocg_variable.spatial.get_masked().compressed() if coll.geomtype == 'point': pts = MultiPoint([pt for pt in geoms.flat]) new_geometry[0, 0] = Point(pts.centroid.x, pts.centroid.y) else: ## break out the MultiPolygon objects. inextricable geometry errors ## sometimes occur otherwise ugeom = [] for geom in geoms: if isinstance(geom, MultiPolygon): for poly in geom: ugeom.append(poly) else: ugeom.append(geom) ## execute the union new_geometry[0, 0] = cascaded_union(ugeom) ## overwrite the original geometry ocg_variable.spatial.value = new_geometry ocg_variable.spatial.value_mask = np.array([[False]]) coll.gid.add(new_geometry[0, 0].wkb) ## aggregate the values ocg_variable.raw_value = ocg_variable.value.copy() ocg_variable.value = union_sum(ocg_variable.spatial.weights, ocg_variable.raw_value)
def aggregate(self,new_geom_id=1,clip_geom=None): ## will hold the unioned geometry new_geometry = np.ones((1,1),dtype=object) new_geometry = np.ma.array(new_geometry,mask=False) ## get the masked geometries geoms = self.spatial.vector.geom.compressed() ## store the raw weights self.spatial.vector.raw_weights = self.spatial.vector.weights.copy() ## break out the MultiPolygon objects. inextricable geometry errors ## sometimes occur otherwise if self.spatial.abstraction == 'polygon': ugeom = [] for geom in geoms: if isinstance(geom,MultiPolygon): for poly in geom: ugeom.append(poly) else: ugeom.append(geom) ## execute the union new_geometry[0,0] = cascaded_union(ugeom) elif self.spatial.abstraction == 'point': if geoms.shape[0] == 0: raise(EmptyData) else: ## for point aggregation, use the provided clip geometry if ## passed as opposed to the more confusing multipoint centroid. ## there may be a need to implement this later so the old code ## remains. if clip_geom is None: pts = MultiPoint([pt for pt in geoms.flat]) new_fill = Point(pts.centroid.x,pts.centroid.y) else: new_fill = clip_geom new_geometry[0,0] = new_fill else: raise(NotImplementedError) ## overwrite the original geometry self.spatial.vector._geom = new_geometry self.spatial.vector.uid = np.ma.array([[new_geom_id]],mask=False) ## aggregate the values self.raw_value = self.value.copy() self._value = self._get_aggregate_sum_() self.spatial.vector._weights = None
def test_multipoint_buffering_and_union(self): """Test subset behavior using MultiPoint geometries.""" pts = [Point(3.8, 28.57), Point(9.37, 33.90), Point(17.04, 27.08)] mp = MultiPoint(pts) rd = self.test_data.get_rd('cancm4_tas') coll = OcgOperations(dataset=rd, output_format=constants.OutputFormatName.OCGIS, snippet=True, geom=mp).execute() mu1 = coll.get_element(variable_name='tas').get_masked_value().sum() nc_path = OcgOperations(dataset=rd, output_format='nc', snippet=True, geom=mp).execute() with self.nc_scope(nc_path) as ds: var = ds.variables['tas'] mu2 = var[:].sum() self.assertEqual(mu1, mu2)
def _unwrap_point_(self, geom): """ :param geom: The target geometry to adjust. :type geom: :class:`shapely.geometry.base.BaseGeometry` :rtype: :class:`shapely.geometry.point.Point` """ if isinstance(geom, MultiPoint): pts = [] for pt in geom: if pt.x < self.center_axis: n = Point(pt.x + 360, pt.y) else: n = pt pts.append(n) ret = MultiPoint(pts) else: if geom.x < self.center_axis: ret = Point(geom.x + 360, geom.y) else: ret = geom return ret
def wrap(self, geom): """ :param geom: The target geometry to adjust. :type geom: :class:`shapely.geometry.base.BaseGeometry` :rtype: :class:`shapely.geometry.base.BaseGeometry` """ def _shift_(geom): try: coords = np.array(geom.exterior.coords) coords[:, 0] = coords[:, 0] - 360 ret = Polygon(coords) # Likely a MultiPolygon. except AttributeError: polygons = np.empty(len(geom), dtype=object) for ii, polygon in enumerate(geom): coords = np.array(polygon.exterior.coords) coords[:, 0] = coords[:, 0] - 360 polygons[ii] = Polygon(coords) ret = MultiPolygon(list(polygons)) return ret if isinstance(geom, (Polygon, MultiPolygon)): bounds = np.array(geom.bounds) # If the polygon column bounds are both greater than 180 degrees shift the coordinates of the entire # polygon. if np.all([bounds[0] > self.wrap_axis, bounds[2] > self.wrap_axis]): new_geom = _shift_(geom) # If a polygon crosses the 180 axis, then the polygon will need to be split with intersection and # recombined. elif bounds[1] <= self.wrap_axis < bounds[2]: left = [ poly for poly in iter_exploded_geometries( geom.intersection(self.left_clip)) ] right = [ poly for poly in iter_exploded_geometries( _shift_(geom.intersection(self.right_clip))) ] try: new_geom = MultiPolygon(left + right) except TypeError: left = [x for x in left if type(x) != LineString] right = [x for x in right if type(x) != LineString] new_geom = MultiPolygon(left + right) # Otherwise, the polygon coordinates are not affected by wrapping and the geometry may be passed through. else: new_geom = geom # Likely a point type object. else: if isinstance(geom, Point): if geom.x > 180: new_geom = Point(geom.x - 360, geom.y) else: new_geom = geom # Likely a MultiPoint. elif isinstance(geom, MultiPoint): points = [None] * len(geom) for ii, point in enumerate(geom): if point.x > 180: new_point = Point(point.x - 360, point.y) else: new_point = point points[ii] = new_point new_geom = MultiPoint(points) else: raise NotImplementedError(geom) return new_geom
def get_centermost_point(cluster): centroid = (MultiPoint(cluster).centroid.x, MultiPoint(cluster).centroid.y) centermost_point = min( cluster, key=lambda point: great_circle(point, centroid).m) return tuple(centermost_point)