def olson_transform(geojson, scale_values): """ Scale GeoJSON features. Inplace scaling transformation of each polygon of the geojson provided according to the "scale values" also provided. Parameters ---------- geojson: dict The geojson of polygon to transform (it might be useful to have choosen an appropriate projection as we want to deal with the area) scale_values: list The pre-computed scale values for olson transformation (1 = no transformation) Returns ------- Nothing """ if len(geojson["features"]) != len(scale_values): raise ValueError("Inconsistent number of features/values") for val, feature in zip(scale_values, geojson['features']): geom = shape(feature["geometry"]) feature['properties']['ref_area'] = geom.area if hasattr(geom, '__len__'): feature["geometry"] = mapping( MultiPolygon([scale(g, xfact=val, yfact=val) for g in geom])) else: feature["geometry"] = mapping(scale(geom, xfact=val, yfact=val)) geojson['features'].sort( key=lambda x: x['properties']['ref_area'], reverse=True)
def handle(self, *args, **options): minx = options['minx'] miny = options['miny'] maxx = options['maxx'] maxy = options['maxy'] if minx >= maxx: raise CommandError(_('minx has to be lower than maxx')) if miny >= maxy: raise CommandError(_('miny has to be lower than maxy')) width = maxx-minx height = maxy-miny model = {'areas': Area, 'obstacles': Obstacle}[options['type']] namespaces = {'svg': 'http://www.w3.org/2000/svg'} svg = ElementTree.fromstring(options['svgfile'].read()) svg_width = float(svg.attrib['width']) svg_height = float(svg.attrib['height']) for element in svg.findall('.//svg:clipPath/..', namespaces): for clippath in element.findall('./svg:clipPath', namespaces): element.remove(clippath) for element in svg.findall('.//svg:symbol/..', namespaces): for clippath in element.findall('./svg:symbol', namespaces): element.remove(clippath) if svg.findall('.//*[@transform]'): raise CommandError(_('svg contains transform attributes. Use inkscape apply transforms.')) if model.objects.filter(space=options['space'], import_tag=options['name']).exists(): raise CommandError(_('objects with this import tag already exist in this space.')) with MapUpdate.lock(): changed_geometries.reset() for path in svg.findall('.//svg:path', namespaces): for polygon in self.parse_svg_data(path.attrib['d']): if len(polygon) < 3: continue polygon = Polygon(polygon) polygon = scale(polygon, xfact=1, yfact=-1, origin=(0, svg_height/2)) polygon = scale(polygon, xfact=width / svg_width, yfact=height / svg_height, origin=(0, 0)) polygon = translate(polygon, xoff=minx, yoff=miny) obj = model(geometry=polygon, space=options['space'], import_tag=options['name']) obj.save() MapUpdate.objects.create(type='importsvg') logger = logging.getLogger('c3nav') logger.info('Imported, map update created.') logger.info('Next step: go into the shell and edit them using ' '%s.objects.filter(space_id=%r, import_tag=%r)' % (model.__name__, options['space'].pk, options['name']))
def map_to_polygon(shape,origin,position,rotation,size): geom_obj=Polygon(shape) geom_obj=affinity.translate(geom_obj, -origin[0],-origin[1],0) geom_obj=affinity.scale(geom_obj,size[0],size[1],origin=(0,0)) geom_obj=affinity.rotate(geom_obj,int(rotation*360),origin=(0,0)) geom_obj=affinity.translate(geom_obj, position[0],position[1],0) return geom_obj
def _do_inverse_transform(shape, rotation, mirrored, rotation_origin=(0,0), scale_origin=(0,0)): if shape is None or shape.is_empty: return shape r = shape r = affinity.scale(r, xfact=(-1 if mirrored else 1), origin=scale_origin) r = affinity.rotate(r, -rotation, origin=rotation_origin) return r;
def reinforcement_polygon(asf_file, diametrs_dop, elements, scale = 1.1): out = sha.scale(elements[0], xfact=scale , yfact=scale ) for i,d in enumerate(diametrs_dop): if d != 0: el = sha.scale(elements[i], xfact=scale , yfact=scale) out = out.union(el) if out.geom_type != 'Polygon': for i,el in enumerate(out): minx, miny, maxx, maxy = el.bounds a = sha.scale(sh.box(minx, miny, maxx, maxy), xfact=scale , yfact=scale) if i == 0: out = a else: out = out.union(a) out = out.intersection(asf_file.plate) return out
def get_circles_centers(bbox, radius=5000, polygons=None): """ Function calculates centers for circles, that would cover all the bounding box, or area inside polygons. Used to create points for collectors, where radius small enough to matter (Instagram, VKontakte). Args: bbox (List[float]): long-lat corners for bounding box, that should be covered. radius (int): radius of circles, that will cover bounding box, in meters. polygons (shapely.geometry.polygon): geo polygon to describe monitoring area more precisely, and exclude some surplus centers. """ from math import radians, cos from itertools import product lat = radians(max([abs(bbox[1]), abs(bbox[3])])) # Calculate the length of a degree of latitude and longitude in meters latlen = 111132.92 - (559.82 * cos(2 * lat)) + (1.175 * cos(4 * lat)) + (-0.0023 * cos(6 * lat)) longlen = (111412.84 * cos(lat)) - (93.5 * cos(3 * lat)) + (0.118 * cos(5 * lat)) radius_x = radius/longlen radius_y = radius/latlen x_marks = [x for x in drange(bbox[0], bbox[2], radius_x)] y_marks = [y for y in drange(bbox[1], bbox[3], radius_y)] centers = [x for x in product(x_marks[0::2], y_marks[0::2])] + [x for x in product(x_marks[1::2], y_marks[1::2])] if polygons: cleaned_centers = [] from shapely.geometry import Point from shapely.affinity import scale for center in centers: circle = scale(Point(center[0], center[1]).buffer(1), xfact=radius_x, yfact=radius_y) if polygons.intersects(circle): cleaned_centers.append(center) centers = cleaned_centers return centers
def calibrate_measurement_model(self, arg_model_params): x1, y1, x2, y2 = self.container.floor.polygon.bounds world_size = (x2 / float(self.container.scale), y2 / float(self.container.scale)) usable_area_poly = sa.scale(self.container.usable_area.polygon, 1 / float(self.container.scale), 1 / float(self.container.scale), origin=(0, 0, 0)) self.particle_filter_model_param = ParticleFilterModelParameters(arg_number_of_particles=arg_model_params.number_of_particles, arg_world_dimensions=world_size, arg_sensor_noise=arg_model_params.sensor_noise, arg_turn_noise=arg_model_params.turn_noise, arg_forward_noise=arg_model_params.forward_noise, arg_speed=arg_model_params.forward_speed, arg_turn=arg_model_params.iteration_turn, arg_world_usable_area=usable_area_poly.exterior.coords[:]) # Sensor Geometry needs to be translated to position relative to origin taken to be top left corner of room # on floor plan i.e. bounding box for usable area min_from_origin = min([np.sqrt(pow(j[0],2)+pow(j[1],2)) for j in usable_area_poly.exterior.coords[:]]) minx, miny = [i for i in usable_area_poly.exterior.coords[:] if np.sqrt(pow(i[0],2)+pow(i[1],2)) ==min_from_origin ][0] # self.sensor_properties = copy.deepcopy(self.sensor_properties) # for k, sensor_prop in self.sensor_properties.items(): self.sensor_properties[k].measurement_boundary_poly = usable_area_poly.intersection( self.sensor_properties[k].measurement_boundary_poly) self.sensor_properties[k].measurement_boundary = [ self.sensor_properties[k].measurement_boundary_poly.exterior.coords[:]] self.pir_model = ParticleFilter(self.particle_filter_model_param, self.sensor_properties.values())
def mirror_x(self, x = 0): ofigs = [] center=(x,0,0) for f in self.figs: tmp = affinity.scale(f, xfact=-1, yfact=1,origin=center) ofigs.append(tmp) self.figs = ofigs
def _add_slope(self, bounds, altitude1, altitude2, point1, point2, bottom=False): altitude_diff = altitude2-altitude1 altitude_middle = (altitude1+altitude2)/2 altitude_halfdiff = altitude_diff/2 altitude_base = altitude1 line = LineString([point1, point2]) minx, miny, maxx, maxy = bounds points_2d = [(minx-100, miny-100), (maxx+100, miny-100), (maxx+100, maxy+100), (minx-100, maxy+100)] points_3d = [] for i, (x, y) in enumerate(points_2d): point = Point((x, y)) pos = line.project(point) while pos <= 0 or pos >= line.length-1: line = scale(line, xfact=2, yfact=2, zfact=2) altitude_diff *= 2 altitude_halfdiff *= 2 altitude_base = altitude_middle-altitude_halfdiff pos = line.project(point) z = ((pos/line.length)*altitude_diff)+altitude_base points_3d.append((x, y, z/1000)) extrude = abs(altitude1-altitude2)/1000+100 if bottom: extrude = -extrude self._add_python( 'last_slope = add_polygon_3d(name=%(name)r, coords=%(coords)r, extrude=%(extrude)f)' % { 'name': 'tmpslope', 'coords': tuple(points_3d), 'extrude': extrude, } )
def on_create_alignment_holes(self): axis = self.mirror_axis.get_value() mode = self.axis_location.get_value() if mode == "point": px, py = self.point.get_value() else: selection_index = self.box_combo.currentIndex() bb_obj = self.app.collection.object_list[selection_index] # TODO: Direct access?? xmin, ymin, xmax, ymax = bb_obj.bounds() px = 0.5 * (xmin + xmax) py = 0.5 * (ymin + ymax) xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis] dia = self.drill_dia.get_value() tools = {"1": {"C": dia}} # holes = self.alignment_holes.get_value() holes = eval("[{}]".format(self.alignment_holes.text())) drills = [] for hole in holes: point = Point(hole) point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py)) drills.append({"point": point, "tool": "1"}) drills.append({"point": point_mirror, "tool": "1"}) def obj_init(obj_inst, app_inst): obj_inst.tools = tools obj_inst.drills = drills obj_inst.create_geometry() self.app.new_object("excellon", "Alignment Drills", obj_init)
def compute_voronoi(keypoints, intersection=None, geometry=False, s=30): # ADDED """ Creates a voronoi diagram for all edges in a graph, and assigns a given weight to each edge. This is based around voronoi polygons generated by scipy's voronoi method, to determine if an image has significant coverage. Parameters ---------- graph : object A networkx graph object clean_keys : list Of strings used to apply masks to omit correspondences s : int Offset for the corners of the image """ vor_keypoints = [] keypoints.apply(lambda x: vor_keypoints.append((x['x'], x['y'])), axis = 1) if intersection is None: keypoint_bounds = Polygon(vor_keypoints).bounds intersection = shapely.geometry.box(keypoint_bounds[0], keypoint_bounds[1], keypoint_bounds[2], keypoint_bounds[3]) scaled_coords = np.array(scale(intersection, s, s).exterior.coords) vor_keypoints = np.vstack((vor_keypoints, scaled_coords)) vor = Voronoi(vor_keypoints) # Might move the code below to its own method depending on feedback if geometry: voronoi_df = gpd.GeoDataFrame(data = keypoints, columns=['x', 'y', 'weight', 'geometry']) else: voronoi_df = gpd.GeoDataFrame(data = keypoints, columns=['x', 'y', 'weight']) i = 0 vor_points = np.asarray(vor.points) for region in vor.regions: region_point = vor_points[np.argwhere(vor.point_region==i)] if not -1 in region: polygon_points = [vor.vertices[i] for i in region] if len(polygon_points) != 0: polygon = Polygon(polygon_points) intersection_poly = polygon.intersection(intersection) voronoi_df.loc[(voronoi_df["x"] == region_point[0][0][0]) & (voronoi_df["y"] == region_point[0][0][1]), 'weight'] = intersection_poly.area if geometry: voronoi_df.loc[(voronoi_df["x"] == region_point[0][0][0]) & (voronoi_df["y"] == region_point[0][0][1]), 'geometry'] = intersection_poly i += 1 return voronoi_df
def ellipse(width, length): """Create ellipse when given width and length. """ circle = geo.Point(0, 0).buffer(1) stretched = aff.scale(circle, xfact=width/2, yfact=length/2) rotated = aff.rotate(stretched, -45) return rotated
def get_intersection(self, vertex_line, line, center): while not line.crosses(vertex_line): line = affinity.scale(line, xfact=2.0, yfact=2.0, origin=center) object_of_intersection = line.intersection(vertex_line) for coord in object_of_intersection.coords: if not self.almost_equals(center, coord): return geometry.Point(coord)
def coordinate_conversion(data, width, height): scaleX=ncol * pixelFormat / width * pixelSize scaleY=nrow * pixelFormat / height * pixelSize Xmap=map(int, data[:, 0].tolist()) Ymap=map(int, data[:, 1].tolist()) geom=Polygon(zip(Xmap, Ymap)) geom2=scale(geom, xfact=scaleX, yfact=scaleY, origin=((0, 0))) return geom2, scaleX, scaleY
def load_marker(z): sx, sy = W / 600, H / 800 s = min(sx, sy) polygon = loads(WKT) polygon = scale(polygon, s, s) polygon = polygon.buffer(0.125) g = GCode.from_geometry(polygon, G0Z, z) g = g.move(3, 4, 0.5, 0.5) return g
def to_shapely(self): """Convert a markings.Blotch to shapely Ellipse. Code from https://gis.stackexchange.com/questions/243459/drawing-ellipse-with-shapely/243462 """ circ = geom.Point(self.center).buffer(1) ell = affinity.scale(circ, self.data.radius_1, self.data.radius_2) ellr = affinity.rotate(ell, self.data.angle) return ellr
def fit_shape(shape, width, height, padding=0): width -= padding * 2 height -= padding * 2 x1, y1, x2, y2 = shape.bounds w, h = x2 - x1, y2 - y1 s = min(width / w, height / h) shape = translate(shape, -x1, -y1) shape = scale(shape, s, s, origin=(0, 0, 0)) shape = translate(shape, padding, padding) return shape
def package2svg(package): topCopper = package.get_geometry("Top") tPlace = package.get_geometry("tPlace", apply_width=False) tValues = package.get_geometry("tValues", apply_width=False) tNames = package.get_geometry("tNames", apply_width=False) holes = package.get_geometry("Holes") tStop = package.get_geometry(layer_query="tStop") topCopper = topCopper.difference(holes) mask = tStop results = [ polygon_as_svg(affinity.scale(topCopper, yfact=-1, origin=(0,0)), style="fill:#ffb600"), polygon_as_svg(affinity.scale(tPlace , yfact=-1, origin=(0,0)), style="stroke:white; stroke-width:0.05mm;stroke-linecap:round;fill:none"), polygon_as_svg(affinity.scale(tNames , yfact=-1, origin=(0,0)), style="stroke:white; stroke-width:0.05mm;stroke-linecap:round;fill:none"), polygon_as_svg(affinity.scale(tValues , yfact=-1, origin=(0,0)), style="stroke:white; stroke-width:0.05mm;stroke-linecap:round;fill:none") ] return map(lambda x: ET.fromstring("<g>{}</g>".format(x)),results)
def affine_trans(self,header): for elmt in header.elements: if elmt.element.is_empty: continue if elmt.active: if self.mirror: elmt.element=affinity.scale(elmt.element, xfact=1, yfact=-1,origin=self.center) if abs(self.rot_ang) > self.tiny_ang: elmt.element=affinity.rotate(elmt.element, self.rot_ang,origin=self.center) if abs(self.xoff) > 0.0 or abs(self.yoff) > 0.0: elmt.element=affinity.translate(elmt.element, xoff=self.xoff, yoff=self.yoff)
def print_to_pdf(shapley_list, filename, random_colours=True, **kwargs): scale = kwargs['scale'] pylab.rcParams['savefig.dpi'] = 254 x_min = [] x_max = [] y_min = [] y_max = [] for shape in shapley_list: bound = shape.bounds x_min.append(bound[0]) y_min.append(bound[1]) x_max.append(bound[2]) y_max.append(bound[3]) x_limits = [np.min(x_min), np.max(x_max)] y_limits = [np.min(y_min), np.max(y_max)] fig_width = np.ptp(x_limits) fig_height = np.ptp(y_limits) fig = plt.figure(figsize=(fig_width/2.54, fig_height/2.54)) fig.subplots_adjust(left=0, right=1, top=1, bottom=0) ax = fig.add_subplot(111) for shape in shapley_list: if random_colours: colours = np.append( np.random.uniform(size=3), 0.3) else: colours = [0, 0, 0, 0.3] scaled_shape = aff.scale( shape, xfact=scale, yfact=scale) patch = des.PolygonPatch( scaled_shape, fc=colours ) ax.add_patch(patch) ax.set_xlim(x_limits) ax.set_ylim(y_limits) plt.grid(True) plt.savefig("temp.png") subprocess.call([ "convert", "-units", "PixelsPerInch", "temp.png", "-density", "254", "temp.pdf" ]) os.rename("temp.pdf", filename) os.remove("temp.png")
def combined_body(car, obst, orientations): ''' Find combined body of car with (x,y) centre coords car_cent and obstacle with coords obst_cent. i.e if a measured/predicted obst_cent is within the CB then it is in collision with the car. obst_cent is tuple (not point object) of the center coordinates rel. to obst''' # Convex hull of copies of obst rotated about obst_cent bound = obstacle_bound(obst, orientations) bound_flip = affinity.scale(bound, xfact=-1, yfact=-1, origin=(0,0)) return minkowski_sum(car, bound_flip)
def test_scale(self): ls = load_wkt('LINESTRING(240 400 10, 240 300 30, 300 300 20)') # test defaults of 1.0 sls = affinity.scale(ls) self.assertTrue(sls.equals(ls)) # different scaling in different dimensions sls = affinity.scale(ls, 2, 3, 0.5) els = load_wkt('LINESTRING(210 500 5, 210 200 15, 330 200 10)') self.assertTrue(sls.equals(els)) # Do explicit 3D check of coordinate values for a, b in zip(sls.coords, els.coords): for ap, bp in zip(a, b): self.assertEqual(ap, bp) # retest with named parameters for the same result sls = affinity.scale(geom=ls, xfact=2, yfact=3, zfact=0.5, origin='center') self.assertTrue(sls.equals(els)) ## other `origin` parameters # around the centroid sls = affinity.scale(ls, 2, 3, 0.5, origin='centroid') els = load_wkt('LINESTRING(228.75 537.5, 228.75 237.5, 348.75 237.5)') self.assertTrue(sls.equals(els)) # around the second coordinate tuple sls = affinity.scale(ls, 2, 3, 0.5, origin=ls.coords[1]) els = load_wkt('LINESTRING(240 600, 240 300, 360 300)') self.assertTrue(sls.equals(els)) # around some other 3D Point of origin sls = affinity.scale(ls, 2, 3, 0.5, origin=Point(100, 200, 1000)) els = load_wkt('LINESTRING(380 800 505, 380 500 515, 500 500 510)') self.assertTrue(sls.equals(els)) # Do explicit 3D check of coordinate values for a, b in zip(sls.coords, els.coords): for ap, bp in zip(a, b): self.assertEqual(ap, bp)
def add_letter_to_axis(ax, let, x, y, height): """Add 'let' with position x,y and height height to matplotlib axis 'ax'. """ for polygon, color in zip(letters_polygons[let], colors[let]): new_polygon = affinity.scale( polygon, yfact=height, origin=(0, 0, 0)) new_polygon = affinity.translate( new_polygon, xoff=x, yoff=y) patch = PolygonPatch( new_polygon, edgecolor=color, facecolor=color) ax.add_patch(patch) return
def load_letters(letters): x = 0.0 s = 1.82748538 p = 0.125 polygons = [] for letter in letters: polygon = load_letter(letter) polygon = scale(polygon, s, s) x1, y1, x2, y2 = polygon.bounds polygon = translate(polygon, -x1, -y1) polygon = translate(polygon, x) x += (x2 - x1) + p polygons.append(polygon) print polygon.bounds return MultiPolygon(polygons)
def main2(): bit = 0.0625 s = 1.82748538 for letter in 'MEGAN': p = load_letter(letter) p = scale(p, s, s) p = p.buffer(bit / 2) g = GCode.from_geometry(p, G0Z, -bit) g = g.origin() depths = [-bit, -bit*2, -bit*3, -bit*4] gs = [g.depth(G0Z, d) for d in depths] g = reduce(operator.add, gs) g = HEADER + g + FOOTER im = g.render(0, 0, 6, 8, 96) im.write_to_png('megan-%s.png' % letter) g.save('megan-%s.nc' % letter)
def create_ellipse(x): a = x[0] b = x[1] width = x[2] length = x[3] theta = x[4] ellipse = af.scale(unit_circle, xfact = width/2, yfact = length/2) ellipse = af.translate(ellipse, xoff=a, yoff=b) ellipse = af.rotate(ellipse, theta) return ellipse
def _rescale_viewcone(self, robot_pose): """Rescale the viewcone based on intersecting map objects. Parameters ---------- robot_pose : array_like, optional The robot's currentl [x, y, theta]. """ scale = self.max_view_dist blocking_shapes = [] possible_elements = [] try: possible_elements += self.element_dict['static'] except: logging.debug('No static elements') try: possible_elements += self.element_dict['dynamic'] except: logging.debug('No dynamic elements') for element in possible_elements: if element.blocks_camera: blocking_shapes.append(element.shape) for shape in blocking_shapes: if self.viewcone.shape.intersects(shape): # <>TODO: Use shadows instead of rescaling viewcone # calculate shadows for all shapes touching viewcone # origin = self.viewcone.project(map_object.shape) # shadow = affinity.scale(...) #map portion invisible to the view # self.viewcone = self.viewcone.difference(shadow) distance = Point(self.view_pose[0:2]).distance(shape) scale_ = distance / self.max_view_dist * 1.3 # <>TODO: why the 1.3? if scale_ < scale: scale = scale_ self.viewcone.shape = affinity.scale(self.ideal_viewcone.shape, xfact=scale, yfact=scale, origin=self.view_pose[0:2])
def random_vertex(self, polygon, index = None): angle = random.uniform(0.0, 2*math.pi) center = polygon.centroid.coords[0] line = self.create_line_from_center(angle, center) while not line.crosses(polygon): line = affinity.scale(line, xfact=2.0, yfact=2.0, origin=center) for i in xrange(len(polygon.exterior.coords)-1): coord1 = polygon.exterior.coords[i] coord2 = polygon.exterior.coords[i+1] polygon_line = geometry.LineString([coord1, coord2]) if polygon_line.intersects(line): intersection = polygon_line.intersection(line).coords[0] if self.get_distance(intersection, coord1) < self.get_distance(intersection, coord2): return (polygon.exterior.coords[i], i) else: return (polygon.exterior.coords[i+1], i+1)
def scale(self, xfact=1.0, yfact=1.0, zfact=1.0, origin='center'): """ Scale the geometries of the GeoSeries along each (x, y, z) dimension. Parameters ---------- xfact, yfact, zfact : float, float, float Scaling factors for the x, y, and z dimensions respectively. origin : string, Point, or tuple The point of origin can be a keyword 'center' for the 2D bounding box center (default), 'centroid' for the geometry's 2D centroid, a Point object or a coordinate tuple (x, y, z). Note: Negative scale factors will mirror or reflect coordinates. See shapely manual for more information: http://toblerity.org/shapely/manual.html#affine-transformations """ return GeoSeries([affinity.scale(s, xfact, yfact, zfact, origin=origin) for s in self], index=self.index, crs=self.crs)
def shapely_ellipse(ellipseRaw): """Given raw ellipse values create a shapely ellipse.""" xPosition = ellipseRaw[0] yPosition = ellipseRaw[1] width = ellipseRaw[2] length = ellipseRaw[3] rotation = ellipseRaw[4] unitCircle = geo.Point(0, 0).buffer(1) stretched = aff.scale(unitCircle, xfact=width/2, yfact=length/2) translated = aff.translate( stretched, xoff=xPosition, yoff=yPosition) rotated = aff.rotate(translated, rotation) ellipse = rotated return ellipse
#remove cracks and prepare for kmeans md = int(esz*4)+1 if int(esz*4)%2==0 else int(esz*4) bl1 = int(esz*20) bl2 = int(esz*40) target = cv2.medianBlur(target,md if md<14 else 13) #smoothen cracks target = cv2.bilateralFilter(target,bl1 if bl1<31 else 31 ,bl2 if bl2<80 else 80,bl2 if bl2<80 else 80) #remove cracks print("filter vals: med",int(esz*5)+1 if int(esz*5)%2==0 else int(esz*5), "bil1", int(esz*25), "bil2,3", int(esz*40)) cv2.imwrite(os.path.basename(img_name)+'_inkm_step1_crackremoval.jpg',target) fposes = np.array([np.array([line[:2] for line in pose if line[2] > 0]) for pose in datum.poseKeypoints]) #filtered poses without zero lines mask = np.zeros((len(img),len(img[0]),1), np.uint8) kmout_mask = np.zeros((len(img),len(img[0]),1), np.uint8) for pose in fposes: #remove bodys convexhull = Polygon(pose).convex_hull #inpainting sconvexhull = affinity.scale(convexhull, xfact=1.7, yfact=1.4, origin=convexhull.centroid) cv2.drawContours(mask, [polyToArr(sconvexhull)], 0, 255, int(15*esz)) cv2.drawContours(mask, [polyToArr(sconvexhull)], 0, 255, -1) #kmeans check sconvexhull = affinity.scale(convexhull, xfact=1, yfact=0.7, origin=convexhull.centroid) cv2.drawContours(kmout_mask, [polyToArr(sconvexhull)], 0, 255, int(7*esz)) cv2.drawContours(kmout_mask, [polyToArr(sconvexhull)], 0, 255, -1) cv2.rectangle(mask, (0,0), (len(img[0]),len(img)), 255, int(40*esz)) #remove frames #shift kmeans mask pixels downwards 40px kmout_mask = cv2.warpAffine(kmout_mask, np.float32([ [1,0,0], [0,1,30] ]), (kmout_mask.shape[:2][1], kmout_mask.shape[:2][0])) #inpaint the image cv2.imwrite(os.path.basename(img_name)+'_inkm_step2_inpaintmask.jpg',mask) cv2.imwrite(os.path.basename(img_name)+'_inkm_step2_kmeansresmask.jpg',kmout_mask)
def resize_to_original(regions, factor): new_regions = [ scale(region, factor, factor, origin=(0, 0, 0)) for region in regions ] return new_regions
def main(args): """ Runs dataLayer processing scripts to turn raw dataLayer from (../raw) into cleaned dataLayer ready to be analyzed (saved in ../processed). """ ## Talk to Rune about how dataLayer is handle. If it should be part of the "big" project. ## set number_tiles:1764 config = TrainingConfig() config = update_config(args, config) logger = logging.getLogger(__name__) logger.info('making final dataLayer set from raw dataLayer') userTuple = [['pandagud', 'damp4ever'], ['pandagud2', 'damp4ever'], ['pandagud3', 'damp4ever'], ['au524478', 'Palantir1234']] current_user = random.choice(userTuple) api = SentinelAPI(current_user[0], current_user[1], 'https://scihub.copernicus.eu/dhus') # search by polygon, time, and SciHub query keywords path = r"C:\Users\panda\Downloads\LC80290292014132LGN00.geojson" footprint = geojson_to_wkt(read_geojson(path)) products = api.query(area=footprint, date=('20210101', '20210105'), platformname='Sentinel-2', order_by='+ingestiondate', limit=1) areas = api.to_geodataframe(products) geojson = api.to_geojson(products) api.download_all(products, into=r'C:\Users\panda\Sat_paper\Alfa') products = api.query(area=footprint, date=('20210401', '20210430'), producttype='GRD', platformname='Sentinel-1', sensoroperationalmode='IW', polarisationmode='VV VH', order_by='ingestiondate') firstproduct = next(iter(products)) online_product = '' for i in products: is_online = api.is_online(products.get(i).get('uuid')) if is_online: online_product = i break delete_list = [] for i in products: if i != online_product: delete_list.append(i) for i in delete_list: del products[i] ground_geojsons = read_geojson(path) products_geojsons = api.to_geojson(products) ground_polygon = ground_geojsons.get('features')[0].get('geometry').get( 'coordinates') ground_polygon = geometry.Polygon(ground_polygon[0][0]) import numpy as np titles = [] ids = [] for item in products_geojsons.get('features'): id = item.get('properties').get('id') item = item.get('properties').get('title') item = (item[17:25] + item[48:55]) titles.append(item) ids.append([item, id]) unique = list(set(titles)) union_list = [] for i, element in enumerate(unique): local_polygon = Polygon() for j in range(len(titles)): if titles[j] == element: item = products_geojsons.get('features')[j] item = item.get('geometry').get('coordinates') item = geometry.Polygon(item[0][0]) item = affinity.scale(item, xfact=1.01, yfact=1.01) polygons = [item, local_polygon] local_polygons = unary_union(polygons) local_polygon = item union_list.append([local_polygons, element]) for index, element in enumerate(union_list): wkt = element[0].wkt if ground_polygon.within(element[0]): found_id = element[1] break for i in ids: if found_id != i[0]: del products[i[1]] area_list = [] for index, item in enumerate(products_geojsons.get('features')): item = item.get('geometry').get('coordinates') item = geometry.Polygon(item[0][0]) local_intersection = item.intersection(ground_polygon) local_intersection = [local_intersection.area, index] area_list.append(local_intersection) area_list.sort(reverse=True) for index in range(len(area_list)): item = products_geojsons.get('features')[area_list[index][1]] id = item.get('properties').get('id') item = item.get('geometry').get('coordinates') item = geometry.Polygon(item[0][0]) if item.intersects(ground_polygon): local_intersection = ground_polygon.intersection(item) print(str(ground_polygon.area)) print(str(local_intersection.area)) # ground_polygon = ground_polygon.difference(local_intersection) ground_polygon = (ground_polygon.symmetric_difference( local_intersection)).difference(local_intersection) else: del products[id] import datetime from datetime import timedelta S2_geojson = read_geojson(path) start_S1_date = S2_geojson.get('features')[0].get('properties').get( 'ingestiondate') start_S1_date = start_S1_date.split('T')[0] start_S1_date = datetime.datetime.strptime(start_S1_date, '%Y-%m-%d').date() ## New end date for S1 end_S1_date = start_S1_date + timedelta(days=7) start_S1_date = start_S1_date - timedelta(days=7) start_S1_date_str = str(start_S1_date).replace('-', '') end_S1_date_str = str(end_S1_date).replace('-', '') ## COMBINE FOOTPRINT geom_in_geojson = [] geom_in_geojson.append( geojson.Feature(geometry=ground_polygon, properties={"MissingData": "Test"})) feature_collection = FeatureCollection(geom_in_geojson) pathToFile = r'C:\Users\panda\Sat_paper\missing.geojson' with open(pathToFile, 'w') as f: dump(feature_collection, f) print("Done")
def get_alpha_shape(points, bone_type, show_figure): # todo: a-value alpha_shape = None if bone_type == Bone.Type.RADIUS: alpha_shape = alphashape.alphashape(points, alpha_radius) else: alpha_shape = alphashape.alphashape(points, alpha_femur) if alpha_shape.geom_type == 'MultiPolygon': areas = [i.area for i in alpha_shape] # Get the area of the largest part max_area = areas.index(max(areas)) # Return the index of the largest area alpha_shape = alpha_shape[max_area] if show_figure: alpha_shape_pts = alpha_shape.exterior.coords.xy fig, ax = plt.subplots() ax.scatter(points[:, 0], points[:, 1], color='blue') ax.scatter(alpha_shape_pts[0], alpha_shape_pts[1], color='red') # ax.add_patch(PolygonPatch(alpha_shape, fill=False, color='green')) ax.set_aspect('equal') plt.show() (min_x, min_y, max_x, max_y) = alpha_shape.exterior.bounds x_length = max_x - min_x y_length = max_y - min_y if bone_type == Bone.Type.TIBIA or bone_type == Bone.Type.RADIUS: # radius and tibia: need bigger part on the left left_box = Polygon([(min_x, min_y), (min_x, max_y), (min_x + x_length / 8, max_y), (min_x + x_length / 10, min_y)]) left_bone = alpha_shape.intersection(left_box) right_box = Polygon([(max_x - x_length / 8, min_y), (max_x - x_length / 8, max_y), (max_x, max_y), (max_x, min_y)]) right_bone = alpha_shape.intersection(right_box) if left_bone.area < right_bone.area: alpha_shape = affinity.scale(alpha_shape, xfact=-1, yfact=1, origin=(0, 0)) elif bone_type == Bone.Type.FEMUR or bone_type == Bone.Type.HUMERUS: # both femur and humerus need put head to right-lower corner # femur and humerus: head on the left or right left_box = Polygon([(min_x, min_y), (min_x, max_y), (min_x + x_length / 10, max_y), (min_x + x_length / 10, min_y)]) left_bone = alpha_shape.intersection(left_box) right_box = Polygon([(max_x - x_length / 10, min_y), (max_x - x_length / 10, max_y), (max_x, max_y), (max_x, min_y)]) right_bone = alpha_shape.intersection(right_box) if left_bone.area < right_bone.area: alpha_shape = affinity.scale(alpha_shape, xfact=-1, yfact=1, origin=(0, 0)) # head on the upper or lower part center_box = Polygon([(min_x + x_length * 0.4, min_y), (min_x + x_length * 0.4, max_y), (max_x + x_length * 0.6, max_y), (max_x + x_length * 0.6, min_y)]) center_bone = alpha_shape.intersection(center_box) if (max_y - center_bone.centroid.y) > y_length / 2: alpha_shape = affinity.scale(alpha_shape, xfact=1, yfact=-1, origin=(0, 0)) if show_figure: fig, ax = plt.subplots() x, y = alpha_shape.exterior.xy ax.plot(x, y) ax.set_aspect('equal') plt.show() return alpha_shape
fig = pyplot.figure(1, figsize=SIZE, dpi=90) triangle = Polygon([(1, 1), (2, 3), (3, 1)]) xrange = [0, 5] yrange = [0, 4] # 1 ax = fig.add_subplot(121) patch = PolygonPatch(triangle, facecolor=GRAY, edgecolor=GRAY, alpha=0.5, zorder=1) triangle_a = affinity.scale(triangle, xfact=1.5, yfact=-1) patch_a = PolygonPatch(triangle_a, facecolor=BLUE, edgecolor=BLUE, alpha=0.5, zorder=2) ax.add_patch(patch) ax.add_patch(patch_a) add_origin(ax, triangle, 'center') ax.set_title("a) xfact=1.5, yfact=-1") ax.set_xlim(*xrange) ax.set_xticks(range(*xrange) + [xrange[-1]]) ax.set_ylim(*yrange)
def _get_transform_matrix( shape: BaseGeometry, params: _TargetTransformParams) -> TransformMatrix: """ previous optimization is toggled with a given geometry, this function will release this toggle :param shape: a shape which the transformation toggled with :param params: params that toggle with the shape :return: transformMatrix elements """ translated = translate(shape, xoff=params.x_offset, yoff=params.y_offset) scaled = scale(translated, xfact=params.scale, yfact=params.scale) scale_origin = interpret_origin(translated, "center", 2) rotate_origin = interpret_origin(scaled, "center", 2) p00 = Point(0, 0) p10 = Point(1, 0) p01 = Point(0, 1) p00_translated = translate(p00, xoff=params.x_offset, yoff=params.y_offset) p00_scaled = scale(p00_translated, xfact=params.scale, yfact=params.scale, origin=scale_origin) p00_rotated = rotate(p00_scaled, angle=params.angle, origin=rotate_origin) # type: Point p01_translated = translate(p01, xoff=params.x_offset, yoff=params.y_offset) p01_scaled = scale(p01_translated, xfact=params.scale, yfact=params.scale, origin=scale_origin) p01_rotated = rotate(p01_scaled, angle=params.angle, origin=rotate_origin) # type: Point p10_translated = translate(p10, xoff=params.x_offset, yoff=params.y_offset) p10_scaled = scale(p10_translated, xfact=params.scale, yfact=params.scale, origin=scale_origin) p10_rotated = rotate(p10_scaled, angle=params.angle, origin=rotate_origin) # type: Point c = p00_rotated.x f = p00_rotated.y a = p10_rotated.x - c d = p10_rotated.y - f b = p01_rotated.x - c e = p01_rotated.y - f return TransformMatrix(a, b, d, e, c, f)
def length_in_meters(way_or_geometry): if isinstance(way_or_geometry, numpy.ndarray): return affinity.scale(geometry.LineString(way_or_geometry), scalx, 1).length * GEO.lat_to_m else: return affinity.scale(way_or_geometry, scalx, 1).length * GEO.lat_to_m
def rasterize(shp, ext_outline=False, ext_fill=True, int_outline=False, int_fill=False, scale_factor=4): """Convert a vector shape to a raster. Assumes the shape has already been transformed in to a pixel based coordinate system. The algorithm checks for the intersection of each point in the shape with a pixel grid created by the bounds of the shape. Partial overlaps are estimated by scaling the image in X and Y by the scale factor, rasterizing the shape, and downscaling (using mean), back to the bounds of the original shape. Parameters ---------- shp: shapely.Polygon or Multipolygon The shape to rasterize ext_outline: boolean (default False) Include the outline of the shape in the raster ext_fill: boolean (default True) Fill the shape in the raster int_outline: booelan (default False) Include the outline of the interior shapes int_fill: boolean (default False): Fill the interior shapes scale_factor: int (default 4) The amount to scale the shape in X, Y before downscaling. The higher this number, the more precise the estimate of the overlap. Returns ------- np.ndarray representing the rasterized shape. """ sf = int(scale_factor) minx, miny, maxx, maxy = map(int, shp.bounds) if minx == maxx and miny == maxy: return np.array([[1.]]) elif maxy > miny and minx == maxx: n = maxy - miny + 1 return np.zeros([n, 1]) + 1. / n elif maxy == miny and minx < maxx: n = maxx - minx + 1 return np.zeros([1, n]) + 1. / n if ((maxx - minx + 1) + (maxy - miny + 1)) <= 2 * sf: sf = 1 shp = scale(shp, xfact=sf, yfact=sf) minx, miny, maxx, maxy = shp.bounds width = int(maxx - minx + 1) height = int(maxy - miny + 1) img = Image.new('L', (width, height), 0) _shp = shp.geoms if hasattr(shp, "geoms") else [shp] ext_outline = int(ext_outline) ext_fill = int(ext_fill) int_outline = int(int_outline) int_fill = int(int_fill) for pg in _shp: ext_pg = [(x - minx, y - miny) for x, y in pg.exterior.coords] ImageDraw.Draw(img).polygon(ext_pg, outline=ext_outline, fill=ext_fill) for s in pg.interiors: int_pg = [(x - minx, y - miny) for x, y in s.coords] ImageDraw.Draw(img).polygon(int_pg, outline=int_outline, fill=int_fill) return downscale_local_mean(np.array(img), (sf, sf))
for shp in shps: # Get geographic bounds xmin_s, ymin_s, xmax_s, ymax_s = shp.bounds if xmin_s < p_bounds[0]: p_bounds[0] = xmin_s if ymin_s < p_bounds[1]: p_bounds[1] = ymin_s if xmax_s > p_bounds[2]: p_bounds[2] = xmax_s if ymax_s > p_bounds[3]: p_bounds[3] = ymax_s # Adjust shape scale and position to match region shp_ = affinity.translate(shp, -xmin_s, -ymin_s) shp_ = affinity.scale(shp_, h_scale, v_scale, origin=(0, 0)) shp_ = affinity.translate(shp_, (xmin_s - translation[0]) * h_scale, (ymin_s - translation[1]) * v_scale) shp = shp_ path = list(shp.exterior.coords) interiors = [list(intr.coords) for intr in shp.interiors] if DEBUG: debug.polygon(path, outline='red', fill='red') region_paths.append(path) # Draw onto mask image maskDraw.polygon(path, outline=255, fill=255)
def arrangeArtefactsOfScroll(scroll, side): db = cnxpool.get_connection() cursor = db.cursor() query = """SELECT artefact_position.artefact_position_id, ST_ASWKT(artefact_shape.region_in_sqe_image), ST_X(ST_PointN(ST_ExteriorRing(ST_ENVELOPE(artefact_shape.region_in_sqe_image)), 1)) AS x, ST_Y(ST_PointN(ST_ExteriorRing(ST_ENVELOPE(artefact_shape.region_in_sqe_image)), 1)) AS y, ST_X(ST_PointN(ST_ExteriorRing(ST_ENVELOPE(artefact_shape.region_in_sqe_image)), 3)) AS width, ST_Y(ST_PointN(ST_ExteriorRing(ST_ENVELOPE(artefact_shape.region_in_sqe_image)), 3)) AS height, SQE_image.dpi FROM artefact_position JOIN artefact_position_owner USING (artefact_position_id) JOIN artefact_shape USING(artefact_id) JOIN SQE_image USING(sqe_image_id) JOIN image_catalog USING(image_catalog_id) WHERE artefact_position.scroll_id = '%s' AND image_catalog.catalog_side = '%s' """ cursor.execute(query % (scroll, side)) current_x = 0 max_x = 0 current_width = 0 current_y = 0 master_scale = 1215 for (art_id, poly, x, y, width, height, dpi) in cursor: print('\n') print('Art id: %s' % art_id) if current_y > 10000: current_width = max_x current_x = max_x current_y = 0 scale = master_scale / dpi wkt_poly = wkt.loads(poly) first_translate = affinity.translate(wkt_poly, xoff=-x, yoff=-y) scaled_poly = affinity.scale(first_translate, scale, scale, 1.0, geometry.Point(0, 0, 0)) translated_poly = affinity.translate(scaled_poly, current_x, current_y) # translated_poly = affinity.translate(first_translate, current_x, current_y) translated_wkt_poly = wkt.dumps(translated_poly) wkt_point = wkt.loads('POINT(0 0)') translate_point = affinity.translate(wkt_point, current_x, current_y) translated_wkt_point = wkt.dumps(translate_point) matrix = {"matrix": [[1, 0, current_x], [0, 1, current_y]]} print("Artefact is is %s" % art_id) print("Matrix is %s" % matrix) try: db2 = cnxpool.get_connection() cursor2 = db2.cursor() query2 = """UPDATE artefact_position SET transform_matrix = '%s' WHERE artefact_position_id = %s """ print(query2 % (json.dumps(matrix), int(art_id))) cursor2.execute(query2 % (json.dumps(matrix), int(art_id))) db2.commit() print("The last inserted id was: ", cursor2.lastrowid) cursor2.close() db2.close() except mysql.connector.Error as error: print(art_id) cursor.close() db.close() print('Current y: %s' % current_y) print('Original poly bounds: %s, %s, %s, %s' % wkt_poly.bounds) print('x: %s, y: %s' % (-x, -y)) print('Poly bound: %s, %s, %s, %s' % first_translate.bounds) print('Height %s' % (translated_poly.bounds[3] - translated_poly.bounds[1])) print('Y shift: %s' % translated_poly.bounds[3]) current_y = translated_poly.bounds[3] if translated_poly.bounds[2] > max_x: max_x = translated_poly.bounds[2] cursor.close() db.close()
def set_georeference(plain_geom, ds: DataSet, nrows=None): transform = ds.transform nrows = nrows or ds.array.shape[0] scaled_geom = shaff.scale(plain_geom, xfact=transform[1], yfact=abs(transform[5]), origin=(0, 0)) out_geom = shaff.translate(scaled_geom, transform[0], transform[3] + transform[5] * nrows) return out_geom
def __init__(self, part, footprint, module, circuit, ref=None, hide_value=True): self.position = Point(0, 0) self.rotation = 0 self._ref = ref self.circuit = circuit self.part = part # the skidl part self.footprint = footprint # the footprint name self.module = module # the pykicad footprint instance if ref: self.set_ident(ref) if hide_value: for t in self.module.texts: if t.type == 'value': t.hide = True # Collect a map of pads from the footprint object; these are # the pins of the device, but with the physical coords self._pads = {} self._pads_by_idx = {} for padidx, pad in enumerate(self.module.pads): pos = pad.at size = pad.size shape = pad.shape drillshape = None if shape == 'rect': padshape = box(pos[0] - size[0] / 2, pos[1] - size[0] / 2, pos[0] + size[0] / 2, pos[1] + size[0] / 2) elif shape in ('oval', 'circle'): padshape = scale( Point(*pos).buffer(1), size[0] / 2, size[1] / 2) if pad.drill and isinstance(pad.drill.size, int): drillshape = scale( Point(*pos).buffer(1), pad.drill.size / 2, pad.drill.size / 2) else: raise Exception("unhandled pad shape " + str(shape)) if len(pos) > 2: # apply its individual rotation padshape = rotate(padshape, 360 - pos[2], origin=pos[0:2]) if drillshape: drillshape = rotate(drillshape, 360 - pos[2], origin=pos[0:2]) self._pads_by_idx[padidx] = (pad, padshape, drillshape) if self.part: # stitch the pad and the pin together pin = None try: pin = self.part[pad.name] padname = pad.name except KeyError: pass if not pin: try: pin = self.part[padidx] padname = padidx except KeyError: pass # there are a number of HOLE pads that don't # have corresponing pins, so skip those if pin: pin.component = self else: padname = padidx if pad.name in self._pads else pad.name self._pads[padname] = padshape if self.part: if ref: self.part.ref = ref for pin in self.part.pins: if not hasattr(pin, 'component'): print('part', self.part.name, 'pin', pin.name, 'num', pin.num, 'has no matching pad')
def write_file(filename, wkt, **attr): from xml.etree import ElementTree as et # Create an SVG XML element # @ToDo: Allow customisation of height/width iheight = 74 height = str(iheight) iwidth = 74 width = str(iwidth) doc = et.Element("svg", width=width, height=height, version="1.1", xmlns="http://www.w3.org/2000/svg") # Convert WKT from shapely.wkt import loads as wkt_loads try: # Enable C-based speedups available from 1.2.10+ from shapely import speedups speedups.enable() except: current.log.info("S3GIS", "Upgrade Shapely for Performance enhancements") shape = wkt_loads(wkt) geom_type = shape.geom_type if geom_type not in ("MultiPolygon", "Polygon"): current.log.error("Unsupported Geometry", geom_type) return # Scale Points & invert Y axis from shapely import affinity bounds = shape.bounds # (minx, miny, maxx, maxy) swidth = abs(bounds[2] - bounds[0]) sheight = abs(bounds[3] - bounds[1]) width_multiplier = iwidth / swidth height_multiplier = iheight / sheight multiplier = min(width_multiplier, height_multiplier) * 0.9 # Padding shape = affinity.scale(shape, xfact=multiplier, yfact=-multiplier, origin="centroid") # Center Shape centroid = shape.centroid xoff = (iwidth / 2) - centroid.x yoff = (iheight / 2) - centroid.y shape = affinity.translate(shape, xoff=xoff, yoff=yoff) if geom_type == "MultiPolygon": polygons = shape.geoms elif geom_type == "Polygon": polygons = [shape] # @ToDo: #elif geom_type == "LineString": # _points = shape #elif geom_type == "Point": # _points = [shape] points = [] pappend = points.append for polygon in polygons: _points = polygon.exterior.coords for point in _points: pappend("%s,%s" % (point[0], point[1])) points = " ".join(points) # Wrap in Square for Icon # @ToDo: Anti-Aliased Rounded Corners # @ToDo: Make optional fill = "rgb(167, 192, 210)" stroke = "rgb(114, 129, 145)" et.SubElement(doc, "rect", width=width, height=height, fill=fill, stroke=stroke) # @ToDo: Allow customisation of options fill = "rgb(225, 225, 225)" stroke = "rgb(165, 165, 165)" et.SubElement(doc, "polygon", points=points, fill=fill, stroke=stroke) # @ToDo: Add Attributes from list_fields # Write out File path = os.path.join(current.request.folder, "static", "cache", "svg") if not os.path.exists(path): os.makedirs(path) filepath = os.path.join(path, filename) with open(filepath, "w") as f: # ElementTree 1.2 doesn't write the SVG file header errata, so do that manually f.write("<?xml version=\"1.0\" standalone=\"no\"?>\n") f.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n") f.write("\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n") f.write(et.tostring(doc)) return filepath
def checkClusteringPerRow(pageNd, dCellCndPerRow, dTextInCells, dClusterWithTL, dEdges): """ recompute clusters for the rows """ lNewPoly = [] lNewClusterWithTL = [] lNewClusterWithCC = [] lRowtodel = [] lTLtoBeAdded = [] for rowid, rowCells in dCellCndPerRow.items(): lNbClusterPerCol = [] lClusterPerCol = [] for cell in rowCells: if cell.wkt in dTextInCells.keys(): lIds = [tl.get('id') for tl in dTextInCells[cell.wkt]] lClusterCells = connected_components(dEdges, lIds, TH=0.5) lNbClusterPerCol.append(len(lClusterCells)) lClusterPerCol.append(lClusterCells) #print (len(rowCells),lIds,lClusterCells,lNbClusterPerCol) #else empty cell if len(lNbClusterPerCol) > 2: # print (lNbClusterPerCol) try: nbRows = mode(lNbClusterPerCol) except statistics.StatisticsError: nbRows = 2 if nbRows != 1: print('WARNING CUT ', rowid, "mode", nbRows) lRowtodel.append(rowid) dClusterCells = defaultdict(list) for colcluster in lClusterPerCol: if len(colcluster) == nbRows: # get tl instead of ids # take the first element only for comparing position colclustertxt = [] for cc in colcluster: colclustertxt.append([ tl for tl in dClusterWithTL[rowid] if tl.get('id') in cc ]) sortedC = sorted(colclustertxt, key=lambda x: ShapeLoader. node_to_Polygon(x[0]).centroid.y) for i, cc in enumerate(sortedC): dClusterCells[i].append(cc) else: for cc in colcluster: lTLtoBeAdded.extend([ tl for tl in dClusterWithTL[rowid] if tl.get('id') in cc ]) for i, lcc in dClusterCells.items(): # print (i,lcc) rect = ShapeLoader.contourObject([ x for cc in lcc for x in cc ]).envelope # minimal_rectangle? rect = scale(rect, xfact=2) lNewPoly.append(rect) lNewClusterWithCC.append(lcc) lNewClusterWithTL.append([x for cc in lcc for x in cc]) # lNewCluster.Append() # need also to create a cluster with list of ids!! rNd = etree.Element('LINE') rNd.set('points', ShapeLoader.getCoordsString(rect)) pageNd.append(rNd) # final check: if overlap between rectangle: top rectangle is the cut #return updated list of lCLusters return lRowtodel, lNewPoly, lNewClusterWithTL, lNewClusterWithCC, lTLtoBeAdded
def test_scale_empty(self): sls = affinity.scale(load_wkt('LINESTRING EMPTY')) els = load_wkt('LINESTRING EMPTY') self.assertTrue(sls.equals(els))
def svg_write(board, filename, style="top", formats=["svg"]): gml = board.layers["GML"].lines block = sg.Polygon(gml[-1], gml[:-1]) block = block.buffer(1).buffer(-1) for d, xys in board.holes.items(): if d > 0.1: hlist = so.unary_union([sg.Point(xy).buffer(d / 2) for xy in xys]) block = block.difference(hlist) block = sa.scale(block, SCALE_FACTOR, -SCALE_FACTOR, origin=(0, 0)) (x0, y0, x1, y1) = block.bounds block = sa.translate(block, -x0, -y0) x1 -= x0 y1 -= y0 args = { "stroke": "slategray", "fill_opacity": 1.0, "fill": "white", "stroke_width": 0.1 * SCALE_FACTOR, } dwg = svgwrite.Drawing(filename, size=("%fmm" % x1, "%fmm" % y1), viewBox=("0 0 %f %f" % (x1, y1))) li = [block.exterior] + list(block.interiors) for l in li: dwg.add(dwg.polyline(better_coords(l.coords), **args)) def renderlayer(layer, fill_colour="black", line_colour="black", fill_opacity=1.0): gto = board.layers[layer].preview() gto = sa.scale(gto, SCALE_FACTOR, -SCALE_FACTOR, origin=(0, 0)) gto = sa.translate(gto, -x0, -y0) args = { "fill": fill_colour, "fill_opacity": fill_opacity, "stroke": fill_colour, "stroke_opacity": 0, "stroke_width": 0, } def renderpoly(po): if type(po) == sg.MultiPolygon: [renderpoly(p) for p in po] return if len(po.interiors) == 0: dwg.add(dwg.polygon(better_coords(po.exterior.coords), **args)) else: bc = better_coords(po.exterior.coords) x0 = min([x for (x, y) in bc]) x1 = max([x for (x, y) in bc]) y0 = min([y for (x, y) in bc]) y1 = max([y for (x, y) in bc]) xm = (x0 + x1) / 2 eps = 0.0 renderpoly(po.intersection(sg.box(x0, y0, xm + eps, y1))) renderpoly(po.intersection(sg.box(xm - eps, y0, x1, y1))) if isinstance(gto, sg.Polygon): renderpoly(gto) else: [renderpoly(po) for po in gto] args = { "stroke": line_colour, "fill_opacity": 0.0, "stroke_opacity": fill_opacity, "stroke_width": 0.1, } if not isinstance(gto, sg.Polygon): for po in gto: li = [po.exterior] + list(po.interiors) for l in li: dwg.add(dwg.polyline(better_coords(l.coords), **args)) # make a temporary DRL layer to render representations of holes board.layers["DRL"] = Layer() for d, xys in board.holes.items(): dp = so.unary_union([sg.Point(xy).buffer(d / 2) for xy in xys]) board.layers["DRL"].add(dp) for d, xys in board.npth.items(): dp = so.unary_union([sg.Point(xy).buffer(d / 2) for xy in xys]) board.layers["DRL"].add(dp) if style not in SVG_STYLE: raise KeyError("Cannot find a style called %s in SVG_STYLE" % (style)) style = SVG_STYLE[style.lower()] for layer, fc, lc, op in style: if layer in board.layers: renderlayer(layer, fill_colour=fc, line_colour=lc, fill_opacity=op) if "svg" in formats: dwg.save() if "png" in formats: fn = filename.replace(".svg", ".png") svg2png(bytestring=dwg.tostring(), write_to=fn) if "pdf" in formats: fn = filename.replace(".svg", ".pdf") svg2pdf(bytestring=dwg.tostring(), write_to=fn)
def main(): scale_x=1.5 scale_y=1 btn = Button(window, text="Calculate", command=processOK,bg='yellow') canvas.bind("<Button-1>", click) for i in root.findall("./{http://www.opengis.net/indoorgml/1.0/core}primalSpaceFeatures/{http://www.opengis.net/indoorgml/1.0/core}PrimalSpaceFeatures/{http://www.opengis.net/indoorgml/1.0/core}cellSpaceMember/{http://www.opengis.net/indoorgml/1.0/core}CellSpace"): CS_gml_id=i.get('{http://www.opengis.net/gml/3.2}id') CS_name =i.find('{http://www.opengis.net/gml/3.2}name').text if i.find('{http://www.opengis.net/indoorgml/1.0/core}partialboundedBy')!=None: room_door[CS_gml_id]=i.find('{http://www.opengis.net/indoorgml/1.0/core}partialboundedBy').get('{http://www.w3.org/1999/xlink}href')[1:] list=[] list_set=[] for j in i.findall("./{http://www.opengis.net/indoorgml/1.0/core}cellSpaceGeometry/{http://www.opengis.net/indoorgml/1.0/core}Geometry2D/{http://www.opengis.net/gml/3.2}Polygon/{http://www.opengis.net/gml/3.2}exterior/{http://www.opengis.net/gml/3.2}LinearRing/{http://www.opengis.net/gml/3.2}pos"): words=j.text.split() list.append(str(float(words[0])*scale_x+20)) list.append(str(float(words[1])*scale_y+20)) FOR_MIN_MAX=((float(words[0])*scale_x+20),(float(words[1])*scale_y+20)) calc_min_max(FOR_MIN_MAX) input = (float(words[0])*scale_x+20,float(words[1])*scale_y+20) list_set.append(input) canvas.create_polygon(list, outline='black', fill='ivory3', width=2) # print(list) if CS_name.find("Corridor")!=-1: # print(list_set) corridor_line.append(LineString(list_set)) else: total_line.append(list) cellspace_accord[CS_gml_id]=list_set for i in root.findall("./{http://www.opengis.net/indoorgml/1.0/core}primalSpaceFeatures/{http://www.opengis.net/indoorgml/1.0/core}PrimalSpaceFeatures/{http://www.opengis.net/indoorgml/1.0/core}cellSpaceBoundaryMember/{http://www.opengis.net/indoorgml/1.0/core}CellSpaceBoundary"): gml_id=i.get('{http://www.opengis.net/gml/3.2}id') if gml_id.find("REVERSE")!= -1 : continue ##Reverse가 들어가 있을 경우 continue sum_x = 0 sum_y = 0 DOOR=[] for j in i.findall("{http://www.opengis.net/indoorgml/1.0/core}cellSpaceBoundaryGeometry/{http://www.opengis.net/indoorgml/1.0/core}geometry2D/{http://www.opengis.net/gml/3.2}LineString/{http://www.opengis.net/gml/3.2}pos"): words=j.text.split() DOOR.append([float(words[0])*scale_x+20,float(words[1])*scale_y+20]) sum_x+=float(words[0])*scale_x+20 sum_y+=float(words[1])*scale_y+20 total_door.append((sum_x/2,sum_y/2)) door_accord[gml_id]=(sum_x/2,sum_y/2) door_line.append(LineString([(DOOR[0][0], DOOR[0][1]),(DOOR[1][0], DOOR[1][1])])) canvas.create_line(DOOR[0][0], DOOR[0][1], DOOR[1][0], DOOR[1][1], width=10, fill="blue") ##Door에서 vertical 한 line 생성 DOOR_Linestring = LineString([(DOOR[0][0], DOOR[0][1]),(DOOR[1][0], DOOR[1][1])])##DOOR를 Linestring으로 변환 # print(DOOR[0][0], DOOR[0][1], DOOR[1][0], DOOR[1][1]) # for i in DOOR_Linestring.coords: # print (i) # print(DOOR_Linestring.coords[0],DOOR_Linestring.coords[1]) # print("------------------------------------------------------------------------------------------") Rotate_Linestring = affinity.rotate(DOOR_Linestring,90)##90도 수직 시킨 길이 Rotate_Linestring = affinity.scale(Rotate_Linestring, xfact = 100, yfact= 100)#100배씩 해줌 (Door 수직 한거 길이 100배) vertical_line.append(Rotate_Linestring) # canvas.create_line(Rotate_Linestring.coords[0][0], Rotate_Linestring.coords[0][1], Rotate_Linestring.coords[1][0], Rotate_Linestring.coords[1][1], width=3, fill="green") ##Door에서 vertical 한 line 생성 door_and_corner[gml_id] = (sum_x/2,sum_y/2) for key,value in room_door.items(): if(value.find("-REVERSE")!=-1): room_door[key]=value[0:value.find("-REVERSE")] # visibility() plt.show() canvas.pack() btn.pack() draw_vertical() window.mainloop()
y = 0 for country_id in countries3857: x += countries3857[country_id]['center'].x * population[country_id] y += countries3857[country_id]['center'].y * population[country_id] totals['center'] = Point([x / totals['population'], y / totals['population']]) # scale scale = math.sqrt(n) / math.sqrt(totals['area']) # continent continent = { 'center': Point(0, 0), 'scale': 1, 'n': n, 'area': n, 'polygon': affinity.translate(affinity.scale(totals['polygon'], xfact=scale, yfact=scale, origin=totals['center']), xoff=-1 * totals['center'].x, yoff=-1 * totals['center'].y) } # transformed centers and polygons for country_id in countries: # scale and move around [0,0]: raw_center = affinity.translate(affinity.scale(countries3857[country_id]['center'], xfact=scale, yfact=scale, origin=totals['center']), xoff=-1 * totals['center'].x, yoff=-1 * totals['center'].y) raw_polygon = affinity.translate(affinity.scale(countries3857[country_id]['polygon'], xfact=scale, yfact=scale, origin=totals['center']), xoff=-1 * totals['center'].x, yoff=-1 * totals['center'].y) countries[country_id]['center'] = affinity.scale(raw_center, xfact=countries[country_id]['scale'], yfact=countries[country_id]['scale'], origin=raw_center) countries[country_id]['polygon'] = affinity.scale(raw_polygon, xfact=countries[country_id]['scale'], yfact=countries[country_id]['scale'], origin=raw_center) countries[country_id]['area'] = countries[country_id]['polygon'].area fig = go.Figure() x, y = continent['polygon'].exterior.coords.xy
def scale_(x): origin = (0, 0) if translate else (xc, yc) return affinity.scale(x, scale, scale, origin=origin)
def mask_to_polygons(mask, img_id, epsilon=1, min_area=1., test=True): ''' Generate polygons from mask :param mask: :param epsilon: :param min_area: :return: ''' # find contours, cv2 switches the x-y coordiante of mask to y-x in contours # This matches the wkt data in train_wkt_v4, which is desirable for submission image, contours, hierarchy = cv2.findContours( ((mask == 1) * 255).astype(np.uint8), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_KCOS) # create approximate contours approx_contours = [ cv2.approxPolyDP(cnt, epsilon, True) for cnt in contours ] if not contours: return MultiPolygon() cnt_children = defaultdict(list) child_contours = set() assert hierarchy.shape[0] == 1 for idx, (_, _, _, parent_idx) in enumerate(hierarchy[0]): if parent_idx != -1: child_contours.add(idx) cnt_children[parent_idx].append(approx_contours[idx]) # create actual polygon filtering by area (remove artifacts) all_polygons = [] for idx, cnt in enumerate(approx_contours): if idx not in child_contours and cv2.contourArea(cnt) >= min_area: assert cnt.shape[1] == 1 poly = Polygon(shell=cnt[:, 0, :], holes=[ c[:, 0, :] for c in cnt_children.get(idx, []) if cv2.contourArea(c) >= min_area ]) all_polygons.append(poly) # approximating polygons might have created invalid ones, fix them all_polygons = MultiPolygon(all_polygons) if not all_polygons.is_valid: all_polygons = all_polygons.buffer(0) # Sometimes buffer() converts a simple Multipolygon to just a Polygon, # need to keep it a Multi throughout if all_polygons.type == 'Polygon': all_polygons = MultiPolygon([all_polygons]) id = test_IDs_dict[img_id] if test else train_IDs_dict[img_id] x_max = grid_sizes[grid_sizes.ImageId == id].Xmax.values[0] y_min = grid_sizes[grid_sizes.ImageId == id].Ymin.values[0] x_scaler, y_scaler = x_max / mask.shape[1], y_min / mask.shape[0] scaled_pred_polygons = scale(all_polygons, xfact=x_scaler, yfact=y_scaler, origin=(0., 0., 0.)) return scaled_pred_polygons
def get_geometry(self, layer_query=None, **options): if not self._layer_matches(layer_query, self.get_layer()): return shapes.LineString() if self.get_align() == "center": h_align = "center" v_align = "center" else: m = re.match("(\w+)-(\w+)", self.get_align()) v_align = m.group(1) h_align = m.group(2) lines = self.get_text().split("\n") stroke_width = self.get_ratio() / 100.0 yscale = (vectorFont.base_height - stroke_width) / vectorFont.base_height RenderedLine = collections.namedtuple("RenderedLine", ["width", "shape"]) rendered_lines = [] for l in lines: cursor = 0 text = shapes.LineString() for character in l: glyph_data = vectorFont.glyphs[character] if glyph_data.width == 0: xscale = 1 else: xscale = ((glyph_data.width - stroke_width / 2) / glyph_data.width + glyph_data.width) / 2 # emperical formula glyph = shapes.MultiLineString(glyph_data.lines) glyph = affinity.scale( glyph, # the width of the lines we use for drawing must fit within the line height. yfact=yscale, xfact=xscale, origin=(0, 0)) # Put the character at the cursor and move it down to accomodate the stroke thickness. emprical value glyph = affinity.translate(glyph, cursor + stroke_width / 2, -stroke_width / 2) text = text.union(glyph) effective_width = glyph_data.width cursor = cursor + effective_width + vectorFont.base_kerning width = cursor - vectorFont.base_kerning rendered_lines.append(RenderedLine(width, text)) max_width = max([x.width for x in rendered_lines]) baseline_skip = vectorFont.base_height + self.get_distance( ) / 100.0 * vectorFont.base_height text = shapes.LineString() v_cursor = 0 for l in rendered_lines: if h_align == "left": dx = 0 elif h_align == "center": dx = (max_width - l.width) / 2 - max_width / 2 elif h_align == "right": dx = (max_width - l.width) - max_width else: assert False, "illegal h_align: {}".format(h_align) text = text.union(affinity.translate(l.shape, dx, v_cursor)) v_cursor = v_cursor - baseline_skip height = -v_cursor - self.get_distance( ) / 100.0 * vectorFont.base_height if v_align == "top": dy = 0 elif v_align == "center": dy = height / 2 elif v_align == "bottom": dy = height else: assert False, "illegal v_align: {}".format(v_align) text = affinity.translate(text, 0, dy) text = affinity.scale(text, xfact=self.get_size(), yfact=self.get_size(), origin=(0, 0)) text = affinity.translate(text, self.get_x(), self.get_y()) text = self._apply_transform(text, rotation_origin=(self.get_x(), self.get_y()), scale_origin=(self.get_x(), self.get_y())) text = self._apply_width(text, width=stroke_width * self.get_size(), **options) return text
def scale_points(pts, xscale, yscale): poly = SPolygon(pts) poly = affinity.scale(poly, xscale, yscale) return list(poly.exterior.coords)
def poly_to_coords(self, poly, factor=20, expand=1): if expand != 1: poly = affinity.scale(poly, xfact=expand, yfact=expand) pts = poly.exterior.coords.xy points = [(factor*pts[0][i] + 100, factor*pts[1][i] + 100) for i in range(len(pts[0]))] return points
def polygon_computing(reg_file_1, reg_file_2, debug=False): """ ENTREE : chemins vers les fichiers des deux lignes a comparer ------------------------------------- Fonction de calcul du taux de recouvrement entre deux fauchees. """ #Recuperation des donnees en dataframe data1 = pandas.read_csv(reg_file_1, delim_whitespace=True, names=['p', 'b', 'x', 'y', 'z', 'o']) # data1 = data1.where(data1['o'] == 0) data2 = pandas.read_csv(reg_file_2, delim_whitespace=True, names=['p', 'b', 'x', 'y', 'z', 'o']) # data2 = data2.where(data2['o'] == 0) #Calcul de l'angle de rotation #L'angle de reference est pris sur la premiere ligne angle, std = get_angle(data1) # print(angle,std) X1 = data1['x'].values Y1 = data1['y'].values X2 = data2['x'].values Y2 = data2['y'].values #Creation du polygone convexe contourant l'ensemble des points de la ligne poly1 = Polygon(zip(X1, Y1)).convex_hull poly2 = Polygon(zip(X2, Y2)).convex_hull #Calcul de l'intersection des aires des deux polygones représentant nos fauchees inter = poly1.intersection(poly2) centroid = (inter.centroid.x, inter.centroid.y) #Rotation des polygones selon l'angle calcule par rapport au centroide de l'intersection poly1 = rotate(poly1, angle, origin=centroid, use_radians=True) poly2 = rotate(poly2, angle, origin=centroid, use_radians=True) #On a transforme par une rotation nos polygones, il faut refaire la zone d'intersection inter = poly1.intersection(poly2) #Creation d'un rectangle englobant l'intersection envelope = inter.envelope #Recuperation des coordonnees du polygone representant l'intersection rect = list(envelope.exterior.coords) #Recuperation des coordonnees du premier point du rectangle englobant l'intersection des aires larger_envelope = np.abs(rect[0][0]-rect[1][0]) larger_data = np.abs(max(data1['x'].max(),data2['x'].max())-min(data1['x'].min(),data2['x'].min())) #Determination de la zone a traiter #Correspond a la partie commune sur l'axe y des fauchees #Pour eviter de traiter endroits ou fauchee plus courte que l'autre, ce qui fausserait les resultats #Finalement, cette zone correspond a l'aire d'intersection allongee sur l'axe x, du debut de la ligne 1 a la fin de la ligne 2 envelope = scale(inter.envelope,larger_data/larger_envelope) res0 = inter.area/poly2.intersection(envelope).area*100 res1 = inter.area/poly1.intersection(envelope).area*100 rospy.loginfo("\tRecouvrement reg 1 sur reg 2 : %.3f"%(res0)) rospy.loginfo("\tRecouvrement reg 2 sur reg 1 : %.3f"%(res1)) if debug: ##################### # AFFICHAGE (debug) # ##################### convex_hull_x1, convex_hull_y1 = [z.tolist() for z in poly1.exterior.coords.xy] convex_hull_x2, convex_hull_y2= [z.tolist() for z in poly2.exterior.coords.xy] x3, y3 = [z.tolist() for z in inter.convex_hull.exterior.coords.xy] x4, y4 = [z.tolist() for z in poly1.intersection(envelope).convex_hull.exterior.coords.xy] x5, y5 = [z.tolist() for z in poly2.intersection(envelope).convex_hull.exterior.coords.xy] x6, y6 = [z.tolist() for z in envelope.convex_hull.exterior.coords.xy] plt.figure(2) plt.plot(X1, Y1, ".") plt.plot(X2, Y2, ".") plt.plot(convex_hull_x1, convex_hull_y1) plt.plot(convex_hull_x2, convex_hull_y2) plt.plot(x3, y3) plt.plot(x4, y4) plt.plot(x5, y5) plt.plot(x6, y6) plt.gca().set_aspect('equal', adjustable='box') plt.show() return res0, res1
def scale_to_plotter_units(self, geom): return scale(geom, self.scalar, self.scalar, origin=Point(0, 0))
def polygon_anlysis(image, mask, data, polygon, pfact, oxfact, oyfact): pts1 = data['shapes'][polygon]['points'] pts1 = np.array(pts1) x, y, w, h = cv2.boundingRect(pts1.astype(int)) if data['shapes'][polygon]['label'] == 'a': pts = data['shapes'][polygon]['points'] X = [] Y = [] for i in pts: X.append(i[0]) Y.append(i[1]) minx, maxx, miny, maxy = min(X), max(X), min(Y), max(Y) pts[0][0], pts[1][0], pts[2][0], pts[3][0] = minx, minx, maxx, maxx pts[0][1], pts[1][1], pts[2][1], pts[3][1] = miny, maxy, maxy, miny pts = [[pts[0][0] - pfact, pts[0][1] - pfact], [pts[1][0] - pfact, pts[1][1] + pfact], [pts[2][0] + pfact, pts[2][1] + pfact], [pts[3][0] + pfact, pts[3][1] - pfact]] pts = np.array(pts) x1, y1, w1, h1 = cv2.boundingRect(pts.astype(int)) croped = image[y1:y1 + h1, x1:x1 + w1].copy() # show_croped(croped) ret, thresh = cv2.threshold(croped, 169, 255, cv2.THRESH_BINARY) # if polygon == 2: # show_croped(croped) # show_croped(thresh) elif data['shapes'][polygon]['label'] == 'k': pts = data['shapes'][polygon]['points'] pts = [tuple(x) for x in pts] scaled = affinity.scale(Polygon(pts), oxfact, oyfact, origin='center') pts = scaled.exterior.coords[:] pts = [[int(j) for j in i] for i in pts] pts = np.array(pts) cv2.fillPoly(mask, [pts.astype(int)], (255, 255, 255)) # apply the mask masked_image = cv2.bitwise_and(image, mask) croped = masked_image[y:y + h, x:x + w].copy() # show_croped(croped) ret, thresh = cv2.threshold(croped, 190, 255, cv2.THRESH_BINARY) # ret, thresh = cv2.threshold(crop, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # show_croped(thresh) elif data['shapes'][polygon]['label'] == 'c': pts = data['shapes'][polygon]['points'] pts = [tuple(x) for x in pts] scaled = affinity.scale(Polygon(pts), xfact=1, yfact=1, origin='center') pts = scaled.exterior.coords[:] pts = [[int(j) for j in i] for i in pts] pts = np.array(pts) cv2.fillPoly(mask, [pts.astype(int)], (255, 255, 255)) # apply the mask masked_image = cv2.bitwise_and(image, mask) croped = masked_image[y:y + h, x:x + w].copy() # show_croped(croped) ret, thresh = cv2.threshold(croped, 183, 255, cv2.THRESH_BINARY) else: croped = image[y:y + h, x:x + w].copy() ret, thresh = cv2.threshold(croped, 150, 255, cv2.THRESH_BINARY) #get percentage of pixels of each color. Total_pixels = thresh.shape[0] * thresh.shape[1] white_pixels = cv2.countNonZero(thresh) # Nonzero pixels black_bixels = Total_pixels - white_pixels # Get percentage of white pixels per_white_pixels = white_pixels / Total_pixels * 100 #get percentage of black pixels per_black_pixels = black_bixels / Total_pixels * 100 return pts1, per_white_pixels, per_black_pixels
def transform_ellipse(long: float, lat: float, major: float, minor: float, orientation: float, srid: int) -> WKBElement: """ Takes the fundamental bits of a ellipse and converts it to a descritized ellipse (polygon) transformed to 4326. :param long: Longitude of the center of the ellipse. :type long: ``float`` :param lat: Latitude of the center of the ellipse. :type lat: ``float`` :param major: The major axis of the ellipse. :type major: ``float`` :param minor: The minor axis of the ellispe. :type minor: ``float`` :param orientation: The angular orientation of the ellipse. :type orientation: ``float`` :param srid: SRID of the center point. :type srid: ``int`` :return: A WKB representation of the ellipse. :rtype: :py:class:`WKBElement` """ # Source spatial reference. source = osr.SpatialReference() source.ImportFromEPSG(srid) # TODO - Need to handle different values for the incoming UOM # TODO - Must have a lookup table of some kind. # The target will depend on the value of uom, but we'll just assume # it's 9001/meters for now. target = osr.SpatialReference() # target.ImportFromEPSG(3857) target.ImportFromEPSG(getutmsrid(long, lat, srid)) # Set up the transform. transform = osr.CoordinateTransformation(source, target) # Create a geometry we can use with the transform. center = ogr.CreateGeometryFromWkt('POINT({0} {1})'.format(long, lat)) # Transform it and apply the buffer. center.Transform(transform) cir = center.Buffer(1) wkt_cir = cir.ExportToWkt() # load up a new Shapely Polygon from the WKT and convert it to a GeoAlchemy2 WKBElement # that we can use to query. circle = loads(wkt_cir) # Let create the ellipse along x and y: ell = affinity.scale(circle, major, minor) # xml.py parse method has already converted GML degree's to radians rotate_angle = calculate_orientation(orientation) if rotate_angle >= 0: # Let rotate the ellipse (clockwise, x axis pointing right): ellr = affinity.rotate(ell, rotate_angle, use_radians=True) else: # If one need to rotate it clockwise along an upward pointing x axis: ellr = affinity.rotate(ell, 90 - rotate_angle, use_radians=True) # According to the man, a positive value means a anti-clockwise angle, # and a negative one a clockwise angle. # Convert from shapely to org org_ellipse = ogr.CreateGeometryFromWkt(ellr.wkt) # Now transform it back to 4326 and extract the wkt reverse_transform = osr.CoordinateTransformation(target, source) org_ellipse.Transform(reverse_transform) wkt_ellipse = org_ellipse.ExportToWkt() # load up a new Shapely Polygon from the WKT and convert it to a GeoAlchemy2 WKBElement # that we can use to query. poly = loads(wkt_ellipse) wkb_ellipse = from_shape(poly, srid) return wkb_ellipse
def shape_model(coords): ax = plt.axes() ax.set_facecolor("white") plt.grid(True) points = list(zip(coords[::2],coords[1::2])) poly = Polygon(points) x,y = poly.exterior.xy plt.plot(x,y) x = (-(poly.centroid.x)) y = (-(poly.centroid.y)) poly2 = affinity.translate(poly, xoff= x, yoff= y) poly2_simple = Polygon(poly2.simplify(35)) x,y = poly2_simple.exterior.xy plt.plot(x,y) poly3= affinity.scale(poly2_simple, xfact= .5, yfact= .5) coords = list(poly3.exterior.coords) if len(coords) > 12: print('here0') poly3 = Polygon(poly3.simplify(40)) print(len(coords)) coords = coords[:-1] sides = len(coords) n = 0 angles = [] while n < sides: angles.append(angle(coords[n % sides], coords[(n + 1) % sides], coords[(n + 2) % sides])) n = n + 1 print((sides + 1)-len(points_to_be_deleted)) print(len(angles)) if sides > 6: print('here') anomalies = find_anomalies(angles) print(anomalies) for elem in anomalies: angles.remove(elem) else: print('here2') outliers = angle_outside_range(angles) angles = remove_max(angles, outliers) print(len(angles)) sides = len(angles) avg_angle = sum(angles)/sides inner_angle = (sides-2) * 180 / sides # if sides <= 8 and ((inner_angle + 10) > avg_angle > (inner_angle - 10)): # poly3 = regular_poly(sides) x,y = poly3.exterior.xy plt.plot(x,y) # plt.show() return poly3.exterior.coords
def create_ellipse(centre, a, b, angle): circle = Point(centre).buffer(1) ellipse = affinity.scale(circle, int(a), int(b)) ellipser = affinity.rotate(ellipse, angle) return ellipser
def main(event): logging.info(event) # Get data. uuid = event['campaign_uuid'] zoom_levels = event['zoom_levels'] # Remove previous data. remove_folder(uuid) client = {'obj': CLIENT, 'bucket': BUCKET, 'uuid': uuid} logging.info('Fetching file: {0}'.format(client['uuid'])) campaign_geojson = get_campaign(client) folder_path = join(PATH, uuid) create_folder(folder_path) features = [] campaign_aois = campaign_geojson['features'] logging.info('Campaign has {0} geometries'.format(len(campaign_aois))) for index, poly in enumerate(campaign_aois): # Fix right-hand rule. polygon = sp.Polygon(poly['geometry']['coordinates'][0]) polygon = sp.polygon.orient(polygon) # To get just a small number of tiles around. scaled_polygon = scale(polygon, 1.1, 1.1) try: index = poly['properties']['id'] except KeyError: pass # Create geojson. feature = gj.Feature(geometry=gj.Polygon( [list(polygon.exterior.coords)]), properties={ "id": index, "parent": None }) features.append(feature) event = { 'bbox': scaled_polygon.bounds, 'campaign_uuid': uuid, 'index': index, 'zoom_levels': zoom_levels } # Run lambda function that fetches tiles. spawn_fetch_tiles(event) # Save new geojson. tiles_file = 'tiles.geojson' logging.info('Saving hashes to {0}'.format(tiles_file)) feature_collection = gj.FeatureCollection(features) geojson_outfile = join(folder_path, '{0}'.format(tiles_file)) with open(geojson_outfile, 'w') as f: gj.dump(feature_collection, f) save_to_s3(client, uuid)