def create_random_shape(self): """ Creates a polygon whose shape is selected from 3 primitives (a unit cube, a unit equilateral triangle and a unit hexagon).That shape is then randomly transformed, by randomly skewing it by a random angle in [0,max_skew], rotating it by a random angle in [0,max_rot], scaling it by a random scale in [0,max_scale] and translating it by a random vector [x,y], where x is in [0,max_x] and y is in [0,max_y] Args: None Returns: pol (Polygon instance from shapely) created as described above """ chosen = np.random.choice(list(self.primitives.keys())) pol = Polygon(self.primitives[chosen]) rand_trans_x = self.max_x * np.random.random() rand_trans_y = self.max_y * np.random.random() pol = translate(pol, rand_trans_x, rand_trans_y) rand_scale = self.max_scale * np.random.random(2) pol = scale(pol, rand_scale[0], rand_scale[1]) rot = self.max_rot * np.random.random() pol = rotate(pol, rot) rand_skew = self.max_skew - 2.0 * self.max_skew * np.random.random(2) pol = skew(pol, rand_skew[0], rand_skew[1]) return pol
def skew(self, xs=0.0, ys=0.0, origin='center', use_radians=False): """ Shear/Skew the geometries of the GeoSeries by angles along x and y dimensions. Parameters ---------- xs, ys : float, float The shear angle(s) for the x and y axes respectively. These can be specified in either degrees (default) or radians by setting use_radians=True. origin : string, Point, or tuple (x, y) The point of origin can be a keyword 'center' for the bounding box center (default), 'centroid' for the geometry's centroid, a Point object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the shear angle(s) as degrees or radians See shapely manual for more information: http://toblerity.org/shapely/manual.html#affine-transformations """ return gpd.GeoSeries([ affinity.skew(s, xs, ys, origin=origin, use_radians=use_radians) for s in self.geometry ], index=self.index, crs=self.crs)
def skew(self, xs=0.0, ys=0.0, origin='center', use_radians=False): """Returns a ``GeoSeries`` with skewed geometries. The geometries are sheared by angles along the x and y dimensions. See http://shapely.readthedocs.io/en/latest/manual.html#shapely.affinity.skew for details. Parameters ---------- xs, ys : float, float The shear angle(s) for the x and y axes respectively. These can be specified in either degrees (default) or radians by setting use_radians=True. origin : string, Point, or tuple (x, y) The point of origin can be a keyword 'center' for the bounding box center (default), 'centroid' for the geometry's centroid, a Point object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the shear angle(s) as degrees or radians """ from .geoseries import GeoSeries return GeoSeries([ affinity.skew(s, xs, ys, origin=origin, use_radians=use_radians) for s in self.geometry ], index=self.index, crs=self.crs)
def test_skew_xs_ys_array(self): ls = load_wkt('LINESTRING(240 400 10, 240 300 30, 300 300 20)') els = load_wkt('LINESTRING (253.39745962155615 417.3205080756888, ' '226.60254037844385 317.3205080756888, ' '286.60254037844385 282.67949192431126)') # check with degrees xs_ys = numpy.array([15.0, -30.0]) sls = affinity.skew(ls, xs_ys[0:1], xs_ys[1:2]) self.assertEqual(xs_ys[0], 15.0) self.assertEqual(xs_ys[1], -30.0) self.assertTrue(sls.almost_equals(els)) # check with radians xs_ys = numpy.array([pi / 12, -pi / 6]) sls = affinity.skew(ls, xs_ys[0:1], xs_ys[1:2], use_radians=True) self.assertEqual(xs_ys[0], pi / 12) self.assertEqual(xs_ys[1], -pi / 6) self.assertTrue(sls.almost_equals(els))
def get_mesh(self): # get number of cells num_rows = len(self.submesh) - 1 # (u, v) pin_mesh = [] for j in range(num_rows - 1, -1, -1): for i in range(num_rows - 1, -1, -1): poly = geometry.Polygon([ (self.submesh[i + 1], self.submesh[j + 1] * sqrt(3) / 2), (self.submesh[i], self.submesh[j + 1] * sqrt(3) / 2), (self.submesh[i], self.submesh[j] * sqrt(3) / 2), (self.submesh[i + 1], self.submesh[j] * sqrt(3) / 2) ]) poly = affinity.skew(poly, xs=-30, origin=(0, 0)) poly = affinity.rotate(poly, angle=-150, origin=(0, 0), use_radians=False) pin_mesh.append(poly) # (w, u) for j in range(num_rows): for i in range(num_rows - 1, -1, -1): poly = geometry.Polygon([ (self.submesh[i + 1] * sqrt(3) / 2, self.submesh[j + 1]), (self.submesh[i] * sqrt(3) / 2, self.submesh[j + 1]), (self.submesh[i] * sqrt(3) / 2, self.submesh[j]), (self.submesh[i + 1] * sqrt(3) / 2, self.submesh[j]) ]) poly = affinity.scale(poly, xfact=-1, origin=(0, 0)) poly = affinity.skew(poly, ys=30, origin=(0, 0)) pin_mesh.append(poly) # (v, w) for j in range(num_rows): for i in range(num_rows): poly = geometry.Polygon([ (self.submesh[i + 1] * sqrt(3) / 2, self.submesh[j + 1]), (self.submesh[i] * sqrt(3) / 2, self.submesh[j + 1]), (self.submesh[i] * sqrt(3) / 2, self.submesh[j]), (self.submesh[i + 1] * sqrt(3) / 2, self.submesh[j]) ]) poly = affinity.skew(poly, ys=-30, origin=(0, 0), use_radians=False) pin_mesh.append(poly) return pin_mesh
def test_skew(self): ls = load_wkt('LINESTRING(240 400 10, 240 300 30, 300 300 20)') # test default shear angles of 0.0 sls = affinity.skew(ls) self.assertTrue(sls.equals(ls)) # different shearing in x- and y-directions sls = affinity.skew(ls, 15, -30) els = load_wkt('LINESTRING (253.39745962155615 417.3205080756888, ' '226.60254037844385 317.3205080756888, ' '286.60254037844385 282.67949192431126)') self.assertTrue(sls.almost_equals(els)) # retest with radians for the same result sls = affinity.skew(ls, pi / 12, -pi / 6, use_radians=True) self.assertTrue(sls.almost_equals(els)) # retest with named parameters for the same result sls = affinity.skew(geom=ls, xs=15, ys=-30, origin='center', use_radians=False) self.assertTrue(sls.almost_equals(els)) ## other `origin` parameters # around the centroid sls = affinity.skew(ls, 15, -30, origin='centroid') els = load_wkt('LINESTRING(258.42150697963973 406.49519052838332, ' '231.6265877365273980 306.4951905283833185, ' '291.6265877365274264 271.8541743770057337)') self.assertTrue(sls.almost_equals(els)) # around the second coordinate tuple sls = affinity.skew(ls, 15, -30, origin=ls.coords[1]) els = load_wkt('LINESTRING(266.7949192431123038 400, 240 300, ' '300 265.3589838486224153)') self.assertTrue(sls.almost_equals(els)) # around the absolute Point of origin sls = affinity.skew(ls, 15, -30, origin=Point(0, 0)) els = load_wkt('LINESTRING(347.179676972449101 261.435935394489832, ' '320.3847577293367976 161.4359353944898317, ' '380.3847577293367976 126.7949192431122754)') self.assertTrue(sls.almost_equals(els))
def skew(self, xs=0.0, ys=0.0, origin='center', use_radians=False): """ Shear/Skew the geometries of the GeoSeries by angles along x and y dimensions. Parameters ---------- xs, ys : float, float The shear angle(s) for the x and y axes respectively. These can be specified in either degrees (default) or radians by setting use_radians=True. origin : string, Point, or tuple (x, y) The point of origin can be a keyword 'center' for the bounding box center (default), 'centroid' for the geometry's centroid, a Point object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the shear angle(s) as degrees or radians See shapely manual for more information: http://toblerity.org/shapely/manual.html#affine-transformations """ return gpd.GeoSeries([affinity.skew(s, xs, ys, origin=origin, use_radians=use_radians) for s in self.geometry], index=self.index, crs=self.crs)
def skew(self, xs=0.0, ys=0.0, origin='center', use_radians=False): """Returns a ``GeoSeries`` with skewed geometries. The geometries are sheared by angles along the x and y dimensions. See http://shapely.readthedocs.io/en/latest/manual.html#shapely.affinity.skew for details. Parameters ---------- xs, ys : float, float The shear angle(s) for the x and y axes respectively. These can be specified in either degrees (default) or radians by setting use_radians=True. origin : string, Point, or tuple (x, y) The point of origin can be a keyword 'center' for the bounding box center (default), 'centroid' for the geometry's centroid, a Point object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the shear angle(s) as degrees or radians """ return gpd.GeoSeries([affinity.skew(s, xs, ys, origin=origin, use_radians=use_radians) for s in self.geometry], index=self.index, crs=self.crs)
def test_skew(self): ls = load_wkt('LINESTRING(240 400 10, 240 300 30, 300 300 20)') # test default shear angles of 0.0 sls = affinity.skew(ls) self.assertTrue(sls.equals(ls)) # different shearing in x- and y-directions sls = affinity.skew(ls, 15, -30) els = load_wkt('LINESTRING (253.39745962155615 417.3205080756888, ' '226.60254037844385 317.3205080756888, ' '286.60254037844385 282.67949192431126)') self.assertTrue(sls.almost_equals(els)) # retest with radians for the same result sls = affinity.skew(ls, pi/12, -pi/6, use_radians=True) self.assertTrue(sls.almost_equals(els)) # retest with named parameters for the same result sls = affinity.skew(geom=ls, xs=15, ys=-30, origin='center', use_radians=False) self.assertTrue(sls.almost_equals(els)) ## other `origin` parameters # around the centroid sls = affinity.skew(ls, 15, -30, origin='centroid') els = load_wkt('LINESTRING(258.42150697963973 406.49519052838332, ' '231.6265877365273980 306.4951905283833185, ' '291.6265877365274264 271.8541743770057337)') self.assertTrue(sls.almost_equals(els)) # around the second coordinate tuple sls = affinity.skew(ls, 15, -30, origin=ls.coords[1]) els = load_wkt('LINESTRING(266.7949192431123038 400, 240 300, ' '300 265.3589838486224153)') self.assertTrue(sls.almost_equals(els)) # around the absolute Point of origin sls = affinity.skew(ls, 15, -30, origin=Point(0, 0)) els = load_wkt('LINESTRING(347.179676972449101 261.435935394489832, ' '320.3847577293367976 161.4359353944898317, ' '380.3847577293367976 126.7949192431122754)') self.assertTrue(sls.almost_equals(els))
2.319 3.464, 2.441 3.383, 2.492 3.334, 2.536 3.279, 2.604 3.152, 2.644 3.002, 2.658 2.828, 2.651 2.712, 2.63 2.606, 2.594 2.51, 2.545 2.425, 2.482 2.352, 2.407 2.29, 2.319 2.241, 2.218 2.204), (1.347 3.282, 1.347 2.371, 1.784 2.371, 1.902 2.378, 2.004 2.4, 2.091 2.436, 2.163 2.487, 2.219 2.552, 2.259 2.63, 2.283 2.722, 2.291 2.828, 2.283 2.933, 2.259 3.025, 2.219 3.103, 2.163 3.167, 2.091 3.217, 2.004 3.253, 1.902 3.275, 1.784 3.282, 1.347 3.282))''') xrange = [0, 5] yrange = [0, 4] # 1 ax = fig.add_subplot(121) patch1a = PolygonPatch(R, facecolor=GRAY, edgecolor=GRAY, alpha=0.5, zorder=1) skewR = affinity.skew(R, xs=20, origin=(1, 1)) patch1b = PolygonPatch(skewR, facecolor=BLUE, edgecolor=BLUE, alpha=0.5, zorder=2) ax.add_patch(patch1a) ax.add_patch(patch1b) add_origin(ax, R, (1, 1)) ax.set_title("a) xs=20, origin(1, 1)") ax.set_xlim(*xrange) ax.set_xticks(range(*xrange) + [xrange[-1]]) ax.set_ylim(*yrange)
#%% def discretize(line: LineString, n): deltap = np.linspace(0, line.length, n) points = [] for delta in deltap: p = line.interpolate(delta) points.append(p) return points cover_d = LineString(discretize(cover, 50000)) cover_d_orig = LineString(discretize(cover_orig, 50000)) #%% cover_s = skew(cover_d, xs=0.5, ys=-7, origin=points[0]) ocover_s = skew(cover_d_orig, xs=0.5, ys=0.5, origin=points[0]) #%% rc = np.array(cover_s.coords[0]) - np.array(cover_s.coords[1]) orc = np.array(cover_s.coords[0]) - np.array(cover_s.coords[1]) ocover_sc = scale(ocover_s, 0.987, 0.987, origin=cover_s.coords[0]) cover_sc = scale(cover_s, 0.97, 0.95 * np.max(rc)/np.min(rc), origin=cover_s.coords[0]) #%% rg = np.random.default_rng(12345) points_diff = [] opoints_diff = [] for idx, p in enumerate(cover_sc.coords):
def getsvggeo(node): """ Extracts and flattens all geometry from an SVG node into a list of Shapely geometry. :param node: xml.etree.ElementTree.Element :return: List of Shapely geometry :rtype: list """ kind = re.search('(?:\{.*\})?(.*)$', node.tag).group(1) geo = [] # Recurse if len(node) > 0: for child in node: subgeo = getsvggeo(child) if subgeo is not None: geo += subgeo # Parse elif kind == 'path': log.debug("***PATH***") P = parse_path(node.get('d')) P = path2shapely(P) geo = [P] elif kind == 'rect': log.debug("***RECT***") R = svgrect2shapely(node) geo = [R] elif kind == 'circle': log.debug("***CIRCLE***") C = svgcircle2shapely(node) geo = [C] elif kind == 'ellipse': log.debug("***ELLIPSE***") E = svgellipse2shapely(node) geo = [E] elif kind == 'polygon': log.debug("***POLYGON***") poly = svgpolygon2shapely(node) geo = [poly] elif kind == 'line': log.debug("***LINE***") line = svgline2shapely(node) geo = [line] elif kind == 'polyline': log.debug("***POLYLINE***") pline = svgpolyline2shapely(node) geo = [pline] else: log.warning("Unknown kind: " + kind) geo = None # Transformations if 'transform' in node.attrib: trstr = node.get('transform') trlist = parse_svg_transform(trstr) #log.debug(trlist) # Transformations are applied in reverse order for tr in trlist[::-1]: if tr[0] == 'translate': geo = [translate(geoi, tr[1], tr[2]) for geoi in geo] elif tr[0] == 'scale': geo = [ scale(geoi, tr[0], tr[1], origin=(0, 0)) for geoi in geo ] elif tr[0] == 'rotate': geo = [ rotate(geoi, tr[1], origin=(tr[2], tr[3])) for geoi in geo ] elif tr[0] == 'skew': geo = [skew(geoi, tr[1], tr[2], origin=(0, 0)) for geoi in geo] elif tr[0] == 'matrix': geo = [affine_transform(geoi, tr[1:]) for geoi in geo] else: raise Exception('Unknown transformation: %s', tr) return geo
def test_skew_empty(self): sls = affinity.skew(load_wkt('LINESTRING EMPTY')) els = load_wkt('LINESTRING EMPTY') self.assertTrue(sls.equals(els))
def getsvggeo(node): """ Extracts and flattens all geometry from an SVG node into a list of Shapely geometry. :param node: xml.etree.ElementTree.Element :return: List of Shapely geometry :rtype: list """ kind = re.search('(?:\{.*\})?(.*)$', node.tag).group(1) geo = [] # Recurse if len(node) > 0: for child in node: subgeo = getsvggeo(child) if subgeo is not None: geo += subgeo # Parse elif kind == 'path': log.debug("***PATH***") P = parse_path(node.get('d')) P = path2shapely(P) geo = [P] elif kind == 'rect': log.debug("***RECT***") R = svgrect2shapely(node) geo = [R] elif kind == 'circle': log.debug("***CIRCLE***") C = svgcircle2shapely(node) geo = [C] elif kind == 'ellipse': log.debug("***ELLIPSE***") E = svgellipse2shapely(node) geo = [E] elif kind == 'polygon': log.debug("***POLYGON***") poly = svgpolygon2shapely(node) geo = [poly] elif kind == 'line': log.debug("***LINE***") line = svgline2shapely(node) geo = [line] elif kind == 'polyline': log.debug("***POLYLINE***") pline = svgpolyline2shapely(node) geo = [pline] else: log.warning("Unknown kind: " + kind) geo = None # Transformations if 'transform' in node.attrib: trstr = node.get('transform') trlist = parse_svg_transform(trstr) #log.debug(trlist) # Transformations are applied in reverse order for tr in trlist[::-1]: if tr[0] == 'translate': geo = [translate(geoi, tr[1], tr[2]) for geoi in geo] elif tr[0] == 'scale': geo = [scale(geoi, tr[0], tr[1], origin=(0, 0)) for geoi in geo] elif tr[0] == 'rotate': geo = [rotate(geoi, tr[1], origin=(tr[2], tr[3])) for geoi in geo] elif tr[0] == 'skew': geo = [skew(geoi, tr[1], tr[2], origin=(0, 0)) for geoi in geo] elif tr[0] == 'matrix': geo = [affine_transform(geoi, tr[1:]) for geoi in geo] else: raise Exception('Unknown transformation: %s', tr) return geo
2.112 1.948, 2.051 2.001, 1.986 2.038, 1.91 2.064, 1.823 2.08, 1.726 2.085, 1.347 2.085, 1.347 1, 1 1, 1 3.567, 1.784 3.567, 1.99 3.556, 2.168 3.521, 2.319 3.464, 2.441 3.383, 2.492 3.334, 2.536 3.279, 2.604 3.152, 2.644 3.002, 2.658 2.828, 2.651 2.712, 2.63 2.606, 2.594 2.51, 2.545 2.425, 2.482 2.352, 2.407 2.29, 2.319 2.241, 2.218 2.204), (1.347 3.282, 1.347 2.371, 1.784 2.371, 1.902 2.378, 2.004 2.4, 2.091 2.436, 2.163 2.487, 2.219 2.552, 2.259 2.63, 2.283 2.722, 2.291 2.828, 2.283 2.933, 2.259 3.025, 2.219 3.103, 2.163 3.167, 2.091 3.217, 2.004 3.253, 1.902 3.275, 1.784 3.282, 1.347 3.282))""" ) # 1 ax = fig.add_subplot(121) patch1a = PolygonPatch(R, facecolor=GRAY, edgecolor=GRAY, alpha=0.5, zorder=1) skewR = affinity.skew(R, xs=20, origin=(1, 1)) patch1b = PolygonPatch(skewR, facecolor=BLUE, edgecolor=BLUE, alpha=0.5, zorder=2) ax.add_patch(patch1a) ax.add_patch(patch1b) add_origin(ax, R, (1, 1)) ax.set_title("a) xs=20, origin(1, 1)") set_limits(ax, 0, 5, 0, 4) # 2 ax = fig.add_subplot(122) patch2a = PolygonPatch(R, facecolor=GRAY, edgecolor=GRAY, alpha=0.5, zorder=1) skewR = affinity.skew(R, ys=30)