def process(self): #================= self.__layer.process(self.__svg) if self.__layer.boundary_id is not None: self.__boundary_geometry = self.__layer.features_by_id.get( self.__layer.boundary_id).geometry if self.__base_layer: # Save a cleaned copy of the SVG in the map's output directory cleaner = SVGCleaner(self.__source_file, self.flatmap.map_properties) cleaner.clean() with open( os.path.join(settings.get('output'), self.flatmap.id, '{}.svg'.format(self.flatmap.id)), 'wb') as fp: cleaner.save(fp) if settings.get('backgroundTiles', False): cleaner = SVGCleaner(self.__source_file, self.flatmap.map_properties, all_layers=False) cleaner.clean() cleaned_svg = io.BytesIO() cleaner.save(cleaned_svg) cleaned_svg.seek(0) self.__raster_source = RasterSource('svg', cleaned_svg)
def __init__(self): database = os.path.join(settings.get('output'), 'labels.sqlite') if settings.get('refreshLabels', False): try: os.remove(database) except FileNotFoundError: pass new_db = not os.path.exists(database) self.__db = sqlite3.connect(database) self.__cursor = self.__db.cursor() if new_db: self.__cursor.execute( 'CREATE TABLE labels (entity text, label text)') self.__db.commit()
def process(self): #================= for n in range(len(self.__slides)): slide = self.__slides[n] slide_number = n + 1 slide_layer = PowerpointSlide(self, slide, slide_number) log('Slide {}, {}'.format(slide_number, slide_layer.id)) if settings.get('saveDrawML'): xml = open(os.path.join(settings.get('output'), self.flatmap.id, '{}.xml'.format(slide_layer.id)), 'w') xml.write(slide.element.xml) xml.close() slide_layer.process() self.add_layer(slide_layer)
def process(self): #================= boundary_geometry = None for contour in self.__mbf.findall(self.ns_tag('contour')): label = contour.get('name') association = contour.xpath('ns:property[@name="TraceAssociation"]/ns:s', namespaces={'ns': self.__ns}) anatomical_id = association[0].text if len(association) else None points = [] for point in contour.findall(self.ns_tag('point')): x = float(point.get('x')) y = float(point.get('y')) points.append(self.__um_to_world.transform_point((x, y))) if contour.get('closed'): if (points[0] != points[-1]).all(): points.append(points[-1]) geometry = shapely.geometry.Polygon((points)) else: geometry = shapely.geometry.LineString(points) properties = {'tile-layer': 'features'} if label is not None: properties['label'] = label if anatomical_id is not None: properties['models'] = anatomical_id feature = self.flatmap.new_feature(geometry, properties) self.__layer.add_feature(feature) if anatomical_id == self.__boundary_id: boundary_geometry = feature.geometry self.__layer.boundary_id = feature.feature_id if settings.get('backgroundTiles', False): self.__set_raster_source(boundary_geometry)
def __init__(self, path_id, route_graph, centreline_scaffold=None): self.__path_id = path_id self.__graph = route_graph self.__centreline_scaffold = centreline_scaffold self.__path_layout = settings.get('pathLayout', 'automatic') self.__node_set = { node for node, data in route_graph.nodes(data=True) if not data.get('exclude', False) } self.__source_nodes = { node for node, data in route_graph.nodes(data=True) if data.get('type') == 'source' } self.__target_nodes = { node for node, data in route_graph.nodes(data=True) if data.get('type') == 'target' } if self.__path_layout == 'automatic': ## The sheath scaffold is a network property and should be set ## from the `centreline_scaffold` parameter self.__sheath = Sheath(route_graph, path_id) self.__sheath.build(self.__source_nodes, self.__target_nodes) else: self.__sheath = None
def parse_markup(markup): properties = {'markup': markup} deprecated = [] try: parsed = SHAPE_MARKUP.parseString(markup, parseAll=True) for prop in parsed[1:]: if prop[0] in DEPRECATED_MARKUP: deprecated.append(prop[0]) if (FEATURE_FLAGS.matches(prop[0]) or SHAPE_FLAGS.matches(prop[0])): properties[prop[0]] = True elif prop[0] == 'details': properties[prop[0]] = prop[1] properties['maxzoom'] = int(prop[2]) - 1 else: properties[prop[0]] = prop[1] except ParseException: properties['error'] = 'Syntax error' if len(deprecated) and settings.get('showDeprecated', False): properties['warning'] = "Deprecated '{}'".format( "', '".join(deprecated)) if ('styling' in properties and ('id' in properties or 'class' in properties)): properties[ 'error'] = "'styling' element can't have an 'id' nor 'class'" return properties
def process(self): #================= for n in range(len(self.__slides)): slide = self.__slides[n] slide_number = n + 1 slide_layer = PowerpointSlide(self, slide, slide_number) log('Slide {}, {}'.format(slide_number, slide_layer.id)) if settings.get('saveDrawML'): xml = open(os.path.join(self.flatmap.map_directory, '{}.xml'.format(slide_layer.id)), 'w') xml.write(slide.element.xml) xml.close() slide_layer.process() for error in self.errors: log.warn(error) else: self.add_layer(slide_layer)
def entity_knowledge(self, entity): #================================== # Optionally refresh local connectivity knowledge from SciCrunch if (settings.get('cleanConnectivity', False) and (entity.startswith(APINATOMY_MODEL_PREFIX) or entity.split(':')[0] in CONNECTIVITY_ONTOLOGIES)): self.db.execute('delete from knowledge where entity=?', (entity, )) else: # Check local cache knowledge = self.__entity_knowledge.get(entity, {}) if len(knowledge): return knowledge # Now check our database row = self.db.execute('select knowledge from knowledge where entity=?', (entity, )).fetchone() if row is not None: knowledge = json.loads(row[0]) else: # Consult SciCrunch if we don't know about the entity knowledge = self.__scicrunch.get_knowledge(entity) if len(knowledge) > 0: # Save knowledge in our database self.db.execute('replace into knowledge values (?, ?)', (entity, json.dumps(knowledge))) # Save label and publications in their own tables if 'label' in knowledge: self.db.execute('replace into labels values (?, ?)', (entity, knowledge['label'])) if 'publications' in knowledge: self.update_publications(entity, knowledge.pop('publications', [])) # Use the entity's value as its label if none is defined if 'label' not in knowledge: knowledge['label'] = entity # Cache local knowledge self.__entity_knowledge[entity] = knowledge return knowledge
def create_geometry(self, feature_map): #====================================== self.__feature_map = feature_map for edge in self.__centreline_graph.edges( data='id'): # Returns triples: (node, node, id) for node_id in edge[0:2]: self.__set_node_properties( self.__centreline_graph.nodes[node_id], node_id) feature = self.__find_feature(edge[2]) if feature is not None: bezier_path = feature.get_property('bezier-path') if bezier_path is None: log.warn('Centreline {} has no Bezier path'.format( feature.id)) else: bezier_start = bezier_path.pointAtTime(0) start_point = shapely.geometry.Point( bezier_start.x, bezier_start.y) end_node_0 = self.__centreline_graph.nodes[edge[0]].get( 'geometry') end_node_1 = self.__centreline_graph.nodes[edge[1]].get( 'geometry') if end_node_0 is not None and end_node_1 is not None: self.__centreline_graph.edges[ edge[0:2]]['geometry'] = bezier_path if start_point.distance( end_node_0) < start_point.distance(end_node_1): self.__centreline_graph.edges[ edge[0:2]]['start-node'] = edge[0] else: self.__centreline_graph.edges[ edge[0:2]]['start-node'] = edge[1] if settings.get('pathLayout', 'automatic') == 'automatic': # Construct the centreline scaffold for the network ##self.__centreline_scaffold = Sheath(self.__id, self.__graph) pass
def __get_geometry(self, shape, properties, transform): #====================================================== ## ## Returns shape's geometry as `shapely` object. ## coordinates = [] bezier_segments = [] pptx_geometry = Geometry(shape) for path in pptx_geometry.path_list: bbox = (shape.width, shape.height) if path.w is None or path.h is None else ( path.w, path.h) T = transform @ DrawMLTransform(shape, bbox) moved = False first_point = None current_point = None closed = False for c in path.getchildren(): if c.tag == DML('arcTo'): (wR, hR) = ((pptx_geometry.attrib_value(c, 'wR'), pptx_geometry.attrib_value(c, 'hR'))) stAng = radians(pptx_geometry.attrib_value(c, 'stAng')) swAng = radians(pptx_geometry.attrib_value(c, 'swAng')) p1 = ellipse_point(wR, hR, stAng) p2 = ellipse_point(wR, hR, stAng + swAng) pt = (current_point[0] - p1[0] + p2[0], current_point[1] - p1[1] + p2[1]) large_arc_flag = 1 if swAng >= math.pi else 0 paths = bezier_paths_from_arc_endpoints( tuple2(wR, hR), 0, large_arc_flag, 1, tuple2(*current_point), tuple2(*pt), T) bezier_segments.extend(paths.asSegments()) coordinates.extend(bezier_sample(paths)) current_point = pt elif c.tag == DML('close'): if first_point is not None and current_point != first_point: coordinates.append(T.transform_point(first_point)) closed = True first_point = None # Close current pptx_geometry and start a new one... elif c.tag == DML('cubicBezTo'): coords = [BezierPoint(*T.transform_point(current_point))] for p in c.getchildren(): pt = pptx_geometry.point(p) coords.append(BezierPoint(*T.transform_point(pt))) current_point = pt bz = CubicBezier(*coords) bezier_segments.append(bz) coordinates.extend(bezier_sample(bz)) elif c.tag == DML('lnTo'): pt = pptx_geometry.point(c.pt) if moved: coordinates.append(T.transform_point(current_point)) moved = False coordinates.append(T.transform_point(pt)) current_point = pt elif c.tag == DML('moveTo'): pt = pptx_geometry.point(c.pt) if first_point is None: first_point = pt current_point = pt moved = True elif c.tag == DML('quadBezTo'): coords = [BezierPoint(*T.transform_point(current_point))] for p in c.getchildren(): pt = pptx_geometry.point(p) coords.append(BezierPoint(*T.transform_point(pt))) current_point = pt bz = QuadraticBezier(*coords) bezier_segments.append(bz) coordinates.extend(bezier_sample(bz)) else: print('Unknown path element: {}'.format(c.tag)) if settings.get('saveBeziers', False) and len(bezier_segments) > 0: properties['bezier-segments'] = [ repr(bz) for bz in bezier_segments ] if closed: geometry = shapely.geometry.Polygon(coordinates) else: geometry = shapely.geometry.LineString(coordinates) if properties.get('closed', False): # Return a polygon if flagged as `closed` coordinates.append(coordinates[0]) return shapely.geometry.Polygon(coordinates) return geometry
def __init__(self, *args, show=True, **kwargs): if show and settings.get('verbose', False): self.__progress_bar = tqdm.tqdm(*args, **kwargs) else: self.__progress_bar = None
def __get_geometry(self, element, properties, transform): #======================================================= ## ## Returns path element as a `shapely` object. ## coordinates = [] bezier_segments = [] moved = False first_point = None current_point = None closed = False T = transform @ SVGTransform(element.attrib.get('transform')) if element.tag == SVG_NS('path'): path_tokens = re.sub('.', SVGLayer.__path_matcher, element.attrib.get('d', '')).split() elif element.tag == SVG_NS('rect'): x = length_as_pixels(element.attrib.get('x', 0)) y = length_as_pixels(element.attrib.get('y', 0)) width = length_as_pixels(element.attrib.get('width', 0)) height = length_as_pixels(element.attrib.get('height', 0)) rx = length_as_pixels(element.attrib.get('rx')) ry = length_as_pixels(element.attrib.get('ry')) if width == 0 or height == 0: return None if rx is None and ry is None: rx = ry = 0 elif ry is None: ry = rx elif rx is None: rx = ry rx = min(rx, width / 2) ry = min(ry, height / 2) if rx == 0 and ry == 0: path_tokens = [ 'M', x, y, 'H', x + width, 'V', y + height, 'H', x, 'V', y, 'Z' ] else: path_tokens = [ 'M', x + rx, y, 'H', x + width - rx, 'A', rx, ry, 0, 0, 1, x + width, y + ry, 'V', y + height - ry, 'A', rx, ry, 0, 0, 1, x + width - rx, y + height, 'H', x + rx, 'A', rx, ry, 0, 0, 1, x, y + height - ry, 'V', y + ry, 'A', rx, ry, 0, 0, 1, x + rx, y, 'Z' ] elif element.tag == SVG_NS('line'): x1 = length_as_pixels(element.attrib.get('x1', 0)) y1 = length_as_pixels(element.attrib.get('y1', 0)) x2 = length_as_pixels(element.attrib.get('x2', 0)) y2 = length_as_pixels(element.attrib.get('y2', 0)) path_tokens = ['M', x1, y1, x2, y2] elif element.tag == SVG_NS('polyline'): points = element.attrib.get('points', '').replace(',', ' ').split() path_tokens = ['M'] + points elif element.tag == SVG_NS('polygon'): points = element.attrib.get('points', '').replace(',', ' ').split() path_tokens = ['M'] + points + ['Z'] elif element.tag == SVG_NS('circle'): cx = length_as_pixels(element.attrib.get('cx', 0)) cy = length_as_pixels(element.attrib.get('cy', 0)) r = length_as_pixels(element.attrib.get('r', 0)) if r == 0: return None path_tokens = [ 'M', cx + r, cy, 'A', r, r, 0, 0, 0, cx, cy - r, 'A', r, r, 0, 0, 0, cx - r, cy, 'A', r, r, 0, 0, 0, cx, cy + r, 'A', r, r, 0, 0, 0, cx + r, cy, 'Z' ] elif element.tag == SVG_NS('ellipse'): cx = length_as_pixels(element.attrib.get('cx', 0)) cy = length_as_pixels(element.attrib.get('cy', 0)) rx = length_as_pixels(element.attrib.get('rx', 0)) ry = length_as_pixels(element.attrib.get('ry', 0)) if rx == 0 or ry == 0: return None path_tokens = [ 'M', cx + rx, cy, 'A', rx, ry, 0, 0, 0, cx, cy - ry, 'A', rx, ry, 0, 0, 0, cx - rx, cy, 'A', rx, ry, 0, 0, 0, cx, cy + ry, 'A', rx, ry, 0, 0, 0, cx + rx, cy, 'Z' ] pos = 0 while pos < len(path_tokens): if isinstance(path_tokens[pos], str) and path_tokens[pos].isalpha(): cmd = path_tokens[pos] pos += 1 # Else repeat previous command with new coordinates # with `moveTo` becoming `lineTo` elif cmd == 'M': cmd = 'L' elif cmd == 'm': cmd = 'l' if cmd not in ['s', 'S']: second_cubic_control = None if cmd not in ['t', 'T']: second_quad_control = None if cmd in ['a', 'A']: params = [float(x) for x in path_tokens[pos:pos + 7]] pos += 7 pt = params[5:7] if cmd == 'a': pt[0] += current_point[0] pt[1] += current_point[1] phi = radians(params[2]) paths = bezier_paths_from_arc_endpoints( tuple2(*params[0:2]), phi, *params[3:5], tuple2(*current_point), tuple2(*pt), T) bezier_segments.extend(paths.asSegments()) coordinates.extend(bezier_sample(paths)) current_point = pt elif cmd in ['c', 'C', 's', 'S']: coords = [BezierPoint(*T.transform_point(current_point))] if cmd in ['c', 'C']: n_params = 6 else: n_params = 4 if second_cubic_control is None: coords.append( BezierPoint(*T.transform_point(current_point))) else: coords.append( BezierPoint(*T.transform_point( reflect_point(second_cubic_control, current_point)))) params = [float(x) for x in path_tokens[pos:pos + n_params]] pos += n_params for n in range(0, n_params, 2): pt = params[n:n + 2] if cmd.islower(): pt[0] += current_point[0] pt[1] += current_point[1] if n == (n_params - 4): second_cubic_control = pt coords.append(BezierPoint(*T.transform_point(pt))) bz = CubicBezier(*coords) bezier_segments.append(bz) coordinates.extend(bezier_sample(bz)) current_point = pt elif cmd in ['l', 'L', 'h', 'H', 'v', 'V']: if cmd in ['l', 'L']: params = [float(x) for x in path_tokens[pos:pos + 2]] pos += 2 pt = params[0:2] if cmd == 'l': pt[0] += current_point[0] pt[1] += current_point[1] else: param = float(path_tokens[pos]) pos += 1 if cmd == 'h': param += current_point[0] elif cmd == 'v': param += current_point[1] if cmd in ['h', 'H']: pt = [param, current_point[1]] else: pt = [current_point[0], param] if moved: coordinates.append(T.transform_point(current_point)) moved = False coordinates.append(T.transform_point(pt)) current_point = pt elif cmd in ['m', 'M']: params = [float(x) for x in path_tokens[pos:pos + 2]] pos += 2 pt = params[0:2] if first_point is None: # First `m` in a path is treated as `M` first_point = pt else: if cmd == 'm': pt[0] += current_point[0] pt[1] += current_point[1] current_point = pt moved = True elif cmd in ['q', 'Q', 't', 'T']: coords = [BezierPoint(*T.transform_point(current_point))] if cmd in ['q', 'Q']: n_params = 4 else: n_params = 2 if second_quad_control is None: coords.append( BezierPoint(*T.transform_point(current_point))) else: coords.append( BezierPoint(*T.transform_point( reflect_point(second_quad_control, current_point)))) params = [float(x) for x in path_tokens[pos:pos + n_params]] pos += n_params for n in range(0, n_params, 2): pt = params[n:n + 2] if cmd.islower(): pt[0] += current_point[0] pt[1] += current_point[1] if n == (n_params - 4): second_quad_control = pt coords.append(BezierPoint(*T.transform_point(pt))) bz = QuadraticBezier(*coords) bezier_segments.append(bz) coordinates.extend(bezier_sample(bz)) current_point = pt elif cmd in ['z', 'Z']: if first_point is not None and current_point != first_point: coordinates.append(T.transform_point(first_point)) closed = True first_point = None else: print('Unknown path command: {}'.format(cmd)) if settings.get('saveBeziers', False) and len(bezier_segments) > 0: properties['bezier-segments'] = [ repr(bz) for bz in bezier_segments ] if closed: geometry = shapely.geometry.Polygon(coordinates) else: geometry = shapely.geometry.LineString(coordinates) if properties.get('closed', False): # Return a polygon if flagged as `closed` coordinates.append(coordinates[0]) return shapely.geometry.Polygon(coordinates) return geometry