def draw_station(geom1, geom2, station, filename, length_factor=100., angle_factor=100., colors=dt_colors, dropafew=False): if station == 4: station_template = load_svg("station4_template.svg") else: station_template = load_svg("station_template.svg") if station == 1: x_scale_factor = 1/6. if station == 2: x_scale_factor = 1/7. if station == 3: x_scale_factor = 1/8.5 if station == 4: x_scale_factor = 1/10. y_scale_factor = 1/7. # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in station_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9mpz]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception wheel = m.group(1) if wheel == "m2": wheel = -2 elif wheel == "m1": wheel = -1 elif wheel == "z": wheel = 0 elif wheel == "p1": wheel = 1 elif wheel == "p2": wheel = 2 sector = int(m.group(2)) xdiff = x_scale_factor * length_factor * (geom1.dt[wheel, station, sector].x - geom2.dt[wheel, station, sector].x) * signConventions["DT", wheel, station, sector][0] ydiff = -y_scale_factor * length_factor * (geom1.dt[wheel, station, sector].y - geom2.dt[wheel, station, sector].y) * signConventions["DT", wheel, station, sector][1] phizdiff = -angle_factor * (geom1.dt[wheel, station, sector].phiz - geom2.dt[wheel, station, sector].phiz) * signConventions["DT", wheel, station, sector][2] sx = float(svgitem["x"]) + float(svgitem["width"])/2. sy = float(svgitem["y"]) + float(svgitem["height"])/2. svgitem["transform"] = "translate(%g,%g)" % (sx, sy) svgitem["x"] = -float(svgitem["width"])/2. svgitem["y"] = -float(svgitem["height"])/2. svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox = svgitem.clone() newBox["transform"] = "translate(%g,%g) rotate(%g) " % (sx + xdiff, sy + ydiff, phizdiff * 180./pi) newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors(wheel, station, sector) if (not dropafew) or ((wheel, station, sector) not in [(0, 3, 6), (0, 4, 3), (0, 1, 8), (0, 2, 8), (0, 2, 9), (-1, 4, 6), (-2, 1, 8), (2, 4, 8), (2, 3, 6), (2, 1, 5), (-2, 2, 10), (-2, 3, 10), (-2, 11, 4), (1, 7, 4), (2, 2, 4), (2, 4, 4), (2, 8, 4), (2, 11, 4)]): new_boxes.append(newBox) else: svgitem["style"] = "fill:none;stroke:none" for treeindex, svgitem in station_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "stationx": svgitem[0] = "Station %d" % station svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) station_template.save(filename)
def add_sea_layer(self, svg, globe, view, viewbox): from svgfig import SVG sea_pts = self.get_sea_points(globe, view) sea_polys = self.clip_polygons([Polygon('sea', sea_pts, mode='point')], viewbox) g = SVG('g', id='sea') svg.append(g) for sea in sea_polys: g.append(SVG('path', d=sea.svgPathString(useInt=False), style='fill:#d0ddf0', id="sea"))
def toSVG(self): from svgfig import SVG, canvas w = self.view.width h = self.view.height svg = canvas(width='%dpx' % w, height='%dpx' % h, viewBox='0 0 %d %d' % (w, h), enable_background='new 0 0 %d %d' % (w, h), style='stroke-width:0.7pt; stroke-linejoin: round; stroke:#444; fill:#eee;') g = SVG('g', id="gemeinden") for circle in self.circles: c = SVG('circle',cx=circle.x, cy=circle.y, r=circle.r) c['data-key'] = circle.id c['data-population'] = circle.value g.append(c) meta = SVG('metadata') views = SVG('views') view = SVG('view', padding="80", w=w, h=h) proj = self.globe.toXML() bbox = self.bbox bbox = SVG('bbox', x=round(bbox.left,2), y=round(bbox.top,2), w=round(bbox.width,2), h=round(bbox.height,2)) views.append(view) view.append(proj) view.append(bbox) meta.append(views) svg.append(meta) svg.append(g) svg.save('cartogram.svg')
def toSVG(self): from svgfig import SVG, canvas w = self.view.width h = self.view.height svg = canvas(width='%dpx' % w, height='%dpx' % h, viewBox='0 0 %d %d' % (w, h), enable_background='new 0 0 %d %d' % (w, h), style='stroke-width:0.7pt; stroke-linejoin: round; stroke:#444; fill:#eee;') g = SVG('g', id="states") for circle in self.circles: c = SVG('circle',cx=circle.x, cy=circle.y, r=circle.r) c['data-key'] = circle.id c['data-population'] = circle.value g.append(c) meta = SVG('metadata') views = SVG('views') view = SVG('view', padding="80", w=w, h=h) proj = self.globe.toXML() bbox = self.bbox bbox = SVG('bbox', x=round(bbox.left,2), y=round(bbox.top,2), w=round(bbox.width,2), h=round(bbox.height,2)) views.append(view) view.append(proj) view.append(bbox) meta.append(views) svg.append(meta) svg.append(g) svg.firefox()
def to_svg(self): from svgfig import SVG, canvas svg = self.svg g = SVG('g', id="cartogram", fill="red", fill_opacity="0.5") for circle in self.circles: c = SVG('circle',cx=circle.x, cy=circle.y, r=circle.r) c['data-'+self.attr] = circle.id c['data-'+self.key.lower()] = circle.value g.append(c) svg.append(g) svg.firefox()
def draw_wheel(geom1, geom2, wheel, filename, length_factor=100., angle_factor=100., colors=dt_colors, dropafew=False): wheel_template = load_svg("wheel_template.svg") # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in wheel_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception station, sector = int(m.group(1)), int(m.group(2)) xdiff = -length_factor * (geom1.dt[wheel, station, sector].x - geom2.dt[wheel, station, sector].x) * signConventions["DT", wheel, station, sector][0] zdiff = length_factor * (geom1.dt[wheel, station, sector].z - geom2.dt[wheel, station, sector].z) * signConventions["DT", wheel, station, sector][2] phiydiff = -angle_factor * (geom1.dt[wheel, station, sector].phiy - geom2.dt[wheel, station, sector].phiy) * signConventions["DT", wheel, station, sector][1] m = re.search("translate\(([0-9\.\-\+eE]+),\s([0-9\.\-\+eE]+)\)\srotate\(([0-9\.\-\+eE]+)\)",svgitem["transform"]) tx = float(m.group(1)) ty = float(m.group(2)) tr = float(m.group(3)) newBox = svgitem.clone() svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:5.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:5.0;stroke-opacity:1;stroke-dasharray:none" % colors(wheel, station, sector) newBox["id"] = newBox["id"] + "_moved" newBox["transform"] = "translate(%g,%g) rotate(%g)" % (tx - xdiff*cos(tr*pi/180.) + zdiff*sin(tr*pi/180.), ty - xdiff*sin(tr*pi/180.) - zdiff*cos(tr*pi/180.), tr - phiydiff*180./pi) if (not dropafew) or ((wheel, station, sector) not in [(0, 3, 6), (0, 4, 3), (0, 1, 8), (0, 2, 8), (0, 2, 9), (-1, 4, 6), (-2, 1, 8), (2, 4, 8), (2, 3, 6), (2, 1, 5), (-2, 2, 10), (-2, 3, 10), (-2, 11, 4), (1, 7, 4), (2, 2, 4), (2, 4, 4), (2, 8, 4), (2, 11, 4)]): new_boxes.append(newBox) else: svgitem["style"] = "fill:none;stroke:none" for treeindex, svgitem in wheel_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "wheelx": if wheel == 0: svgitem[0] = "Wheel 0" else: svgitem[0] = "Wheel %+d" % wheel svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) wheel_template.save(filename)
def draw_sector(geom1, geom2, sector, filename, length_factor=100., angle_factor=100., colors=dt_colors): if sector < 13: sector_template = load_svg("sector_template.svg") else: sector_template = load_svg("sector_template_station4.svg") # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in sector_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9])_([0-9])", svgitem["id"]) if m is None: raise Exception wheel, station = int(m.group(1))-2, int(m.group(2)) m = re.search("translate\(([0-9\.\-\+eE]+),([0-9\.\-\+eE]+)\)",svgitem["transform"]) tx = float(m.group(1)) ty = float(m.group(2)) ydiff = -length_factor * (geom2.dt[wheel, station, sector].y - geom1.dt[wheel, station, sector].y) * signConventions["DT", wheel, station, sector][1] zdiff = -length_factor * (geom2.dt[wheel, station, sector].z - geom1.dt[wheel, station, sector].z) * signConventions["DT", wheel, station, sector][2] phixdiff = angle_factor * (geom2.dt[wheel, station, sector].phix - geom1.dt[wheel, station, sector].phix) * signConventions["DT", wheel, station, sector][0] newBox = svgitem.clone() svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:5.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:5.0;stroke-opacity:1;stroke-dasharray:none" % colors(wheel, station, sector) newBox["id"] = newBox["id"] + "_moved" newBox["transform"] = "translate(%g,%g) rotate(%g)" % (tx + ydiff, ty - zdiff, phixdiff*180./pi) new_boxes.append(newBox) for treeindex, svgitem in sector_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "title": svgitem[0] = "Sector %d (length x%g, angle x%g)" % (sector,length_factor, angle_factor) sector_template.save(filename)
def add_map_layer(self, svg, polygons, layerId, filter=None, groupBy='oid', polycolor=None): """ add a layer to the map """ if filter != None: filtered = [] for poly in polygons: if filter(poly): filtered.append(poly) polygons = filtered from svgfig import SVG from types import FunctionType svgGroup = SVG('g', id=layerId) svg.append(svgGroup) if groupBy != None: polyGroups = self.group_polygons(polygons, groupBy) for group in polyGroups: path_str_arr = [] for poly in group: path_str_arr.append(poly.svgPathString(useInt=self.options.round_coordinates)) # todo: looks ugly svg_path = SVG('path', d=' '.join(path_str_arr)) poly = group[0] if type(polycolor) == FunctionType: svg_path['fill'] = polycolor(poly.data) for key in poly.data: svg_path['data-'+key] = poly.data[key] svgGroup.append(svg_path) else: for poly in polygons: svg_path = SVG('path', d=poly.svgPathString(useInt=options.round_coordinates)) if type(polycolor) == FunctionType: svg_path['fill'] = polycolor(poly.data) for key in poly.data: svg_path['data-'+key] = poly.data[key] svgGroup.append(svg_path)
def store_layers_svg(self, layers, layerOpts, layerFeatures, svg, opts): """ store features in svg """ from svgfig import SVG for id in layers: print id if len(layerFeatures[id]) == 0: continue # ignore empty layers g = SVG('g', id=id) for feat in layerFeatures[id]: fs = feat.to_svg(opts['export']['round'], layerOpts[id]['attributes']) if fs is not None: g.append(fs) if 'styles' in layerOpts[id]: for prop in layerOpts[id]['styles']: g[prop] = layerOpts[id]['styles'][prop] svg.append(g)
def draw_wheel(geom1, geom2, wheel, filename, length_factor=100., angle_factor=100., colors=dt_colors, template_dir='./'): wheel_template = load_svg(template_dir + "wheel_template.svg") # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in wheel_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception station, sector = int(m.group(1)), int(m.group(2)) xdiff = -length_factor * (geom1.dt[wheel, station, sector].x - geom2.dt[wheel, station, sector].x) * signConventions["DT", wheel, station, sector][0] zdiff = length_factor * (geom1.dt[wheel, station, sector].z - geom2.dt[wheel, station, sector].z) * signConventions["DT", wheel, station, sector][2] phiydiff = -angle_factor * (geom1.dt[wheel, station, sector].phiy - geom2.dt[wheel, station, sector].phiy) * signConventions["DT", wheel, station, sector][1] m = re.search("translate\(([0-9\.\-\+eE]+),\s([0-9\.\-\+eE]+)\)\srotate\(([0-9\.\-\+eE]+)\)",svgitem["transform"]) tx = float(m.group(1)) ty = float(m.group(2)) tr = float(m.group(3)) newBox = svgitem.clone() svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:5.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:5.0;stroke-opacity:1;stroke-dasharray:none" % colors(wheel, station, sector) newBox["id"] = newBox["id"] + "_moved" newBox["transform"] = "translate(%g,%g) rotate(%g)" % (tx - xdiff*cos(tr*pi/180.) + zdiff*sin(tr*pi/180.), ty - xdiff*sin(tr*pi/180.) - zdiff*cos(tr*pi/180.), tr - phiydiff*180./pi) new_boxes.append(newBox) for treeindex, svgitem in wheel_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "wheelx": if wheel == 0: svgitem[0] = "Wheel 0" else: svgitem[0] = "Wheel %+d" % wheel svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) wheel_template.save(filename)
def svg(self): svg = SVG("g",stroke_width="0.1pt") for an in self.lattice: gn=[self.lattice[i] for i in an.down] for ag in gn: svg.append(SVG("line",x1=an.x, y1=an.y+an.h/2, x2=ag.x, y2=ag.y+an.h/2)) for an in self.lattice: txt = ','.join([str(l) for l in an.intent if l]) node = SVG("g",font_size=an.h/2,text_anchor="middle",stroke_width="0.1pt") node.append(SVG("rect", x=an.x-an.w/2, y=an.y, width=an.w, height=an.h, fill="yellow")) node.append(SVG("text",txt, x=an.x, y=an.y+3*an.h/4, fill="black")) svg.append(node) return svg
def init_svg_canvas(self, opts, proj, view, bbox): """ prepare a blank new svg file """ from svgfig import canvas, SVG w = view.width h = view.height + 2 svg = canvas(width='%dpx' % w, height='%dpx' % h, viewBox='0 0 %d %d' % (w, h), enable_background='new 0 0 %d %d' % (w, h), style='stroke-width:0.7pt; stroke-linejoin: round; stroke:#000; fill:#f3f3f0;') css = 'path { fill-rule: evenodd; }\n#context path { fill: #eee; stroke: #bbb; } ' #if options.graticule: # css += '#graticule path { fill: none; stroke-width:0.25pt; } #graticule .equator { stroke-width: 0.5pt } ' svg.append(SVG('defs', SVG('style', css, type='text/css'))) meta = SVG('metadata') views = SVG('views') view = SVG('view', padding=str(opts['bounds']['padding']), w=w, h=h) proj_ = proj.toXML() bbox = SVG('bbox', x=round(bbox.left, 2), y=round(bbox.top, 2), w=round(bbox.width, 2), h=round(bbox.height, 2)) ll = [-180, -90, 180, 90] if opts['bounds']['mode'] == "bbox": ll = opts['bounds']['data'] llbbox = SVG('llbbox', lon0=ll[0], lon1=ll[2], lat0=ll[1], lat1=ll[3]) views.append(view) view.append(proj_) view.append(bbox) view.append(llbbox) meta.append(views) svg.append(meta) return svg
def init_svg_canvas(self, view, bbox, globe): """ prepare a blank new svg file """ from svgfig import canvas, SVG options = self.options w = view.width h = view.height+2 svg = canvas(width='%dpx' % w, height='%dpx' % h, viewBox='0 0 %d %d' % (w, h), enable_background='new 0 0 %d %d' % (w, h), style='stroke-width:0.7pt; stroke-linejoin: round; stroke:#444; fill:white;') css = 'path { fill-rule: evenodd; }\n#context path { fill: #eee; stroke: #bbb; } ' if options.graticule: css += '#graticule path { fill: none; stroke-width:0.25pt; } #graticule .equator { stroke-width: 0.5pt } ' svg.append(SVG('defs', SVG('style', css, type='text/css'))) meta = SVG('metadata') views = SVG('views') view = SVG('view', padding=str(options.out_padding), w=w, h=h) proj = globe.toXML() bbox = SVG('bbox', x=round(bbox.left,2), y=round(bbox.top,2), w=round(bbox.width,2), h=round(bbox.height,2)) ll = options.llbbox llbbox = SVG('llbbox', lon0=ll[0],lon1=ll[2],lat0=ll[1],lat1=ll[3]) views.append(view) view.append(proj) view.append(bbox) view.append(llbbox) meta.append(views) svg.append(meta) return svg
def draw_disk(geom1, geom2, endcap, station, filename, length_factor=1., angle_factor=100., colors=csc_colors): if station == 1: disk_template = load_svg("disk1_template.svg") if station in (2, 3): disk_template = load_svg("disk23_template.svg") if endcap == 1 and station == 4: disk_template = load_svg("diskp4_template.svg") if endcap == 2 and station == 4: disk_template = load_svg("diskm4_template.svg") scale_factor = 0.233 new_boxes = SVG("g") for treeindex, svgitem in disk_template: if isinstance( svgitem, SVG ) and "id" in svgitem.attr and svgitem["id"] == "fakecenter": fakecenter = pathtoPath(pathtoPath(svgitem).SVG()) sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(fakecenter.d): if di[0] in ("M", "L"): sumx += di[1] sumy += di[2] sum1 += 1. originx = sumx / sum1 originy = sumy / sum1 for treeindex, svgitem in disk_template: if isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "ME_": m = re.match("ME_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception ring, chamber = int(m.group(1)), int(m.group(2)) xdiff = scale_factor * length_factor * ( geom1.csc[endcap, station, ring, chamber].x - geom2.csc[endcap, station, ring, chamber].x ) * signConventions["CSC", endcap, station, ring, chamber][0] ydiff = -scale_factor * length_factor * ( geom1.csc[endcap, station, ring, chamber].y - geom2.csc[endcap, station, ring, chamber].y ) * signConventions["CSC", endcap, station, ring, chamber][1] phizdiff = -angle_factor * ( geom1.csc[endcap, station, ring, chamber].phiz - geom2.csc[endcap, station, ring, chamber].phiz ) * signConventions["CSC", endcap, station, ring, chamber][2] svgitem[ "style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox = pathtoPath(svgitem) # Inkscape outputs wrong SVG: paths are filled with movetos, rather than linetos; this fixes that first = True for i, di in enumerate(newBox.d): if not first and di[0] == "m": di = list(di) di[0] = "l" newBox.d[i] = tuple(di) first = False # convert to absolute coordinates newBox = pathtoPath(newBox.SVG()) # find the center of the object sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(newBox.d): if di[0] == "L": sumx += di[1] sumy += di[2] sum1 += 1. centerx = sumx / sum1 centery = sumy / sum1 phipos = atan2(centery - originy, centerx - originx) - pi / 2. for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) di[1] += cos(phipos) * xdiff - sin(phipos) * ydiff di[2] += sin(phipos) * xdiff + cos(phipos) * ydiff newBox.d[i] = tuple(di) centerx += cos(phipos) * xdiff - sin(phipos) * ydiff centery += sin(phipos) * xdiff + cos(phipos) * ydiff for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) dispx = cos(phizdiff) * ( di[1] - centerx) - sin(phizdiff) * (di[2] - centery) dispy = sin(phizdiff) * ( di[1] - centerx) + cos(phizdiff) * (di[2] - centery) di[1] = dispx + centerx di[2] = dispy + centery newBox.d[i] = tuple(di) newBox = newBox.SVG() newBox[ "style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors( endcap, station, ring, chamber) newBox["id"] = newBox["id"] + "_moved" new_boxes.append(newBox) for treeindex, svgitem in disk_template: if isinstance( svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem[ "id"] == "chambers": svgitem.append(new_boxes) elif isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "diskx": if endcap == 1: svgitem[0] = "Disk %+d" % station else: svgitem[0] = "Disk %+d" % (-station) svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) disk_template.save(filename)
style += "font-size:%spx;" % font_size if bold: style += "font-weight:bold;" else: style += "font-weight:normal;" if italic: style += "font-style:italic;" else: style += "font-style:normal;" style += "font-family:%s" % name #t1 = SVG("text", content, x=0, y=line_height, style=style) t1 = SVG("text", content, x=-128, y=300, style=style) counter += 1 g.append(t1) svg = canvas() width = 90 svg.attr['viewBox'] = "0 0 %s %s" % (width, line_height*counter) svg.attr['width'] = width svg.attr['height'] = line_height svg.sub.append(g) svg.save("%s.svg" % content) #this works: #g = SVG("g", *collection, fill_opacity="50%") #g.save("tmp.svg")
def draw_disk(geom1, geom2, endcap, station, filename, length_factor=1., angle_factor=100., colors=csc_colors, template_dir='./'): if station == 1: disk_template = load_svg(template_dir + "disk1_template.svg") if station in (2, 3): disk_template = load_svg(template_dir + "disk23_template.svg") if endcap == 1 and station == 4: disk_template = load_svg(template_dir + "diskp4_template.svg") if endcap == 2 and station == 4: disk_template = load_svg(template_dir + "diskm4_template.svg") scale_factor = 0.233 new_boxes = SVG("g") for treeindex, svgitem in disk_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "fakecenter": fakecenter = pathtoPath(pathtoPath(svgitem).SVG()) sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(fakecenter.d): if di[0] in ("M", "L"): sumx += di[1] sumy += di[2] sum1 += 1. originx = sumx/sum1 originy = sumy/sum1 for treeindex, svgitem in disk_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "ME_": m = re.match("ME_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception ring, chamber = int(m.group(1)), int(m.group(2)) xdiff = scale_factor * length_factor * (geom1.csc[endcap, station, ring, chamber].x - geom2.csc[endcap, station, ring, chamber].x) * signConventions["CSC", endcap, station, ring, chamber][0] ydiff = -scale_factor * length_factor * (geom1.csc[endcap, station, ring, chamber].y - geom2.csc[endcap, station, ring, chamber].y) * signConventions["CSC", endcap, station, ring, chamber][1] phizdiff = -angle_factor * (geom1.csc[endcap, station, ring, chamber].phiz - geom2.csc[endcap, station, ring, chamber].phiz) * signConventions["CSC", endcap, station, ring, chamber][2] svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox = pathtoPath(svgitem) # Inkscape outputs wrong SVG: paths are filled with movetos, rather than linetos; this fixes that first = True for i, di in enumerate(newBox.d): if not first and di[0] == "m": di = list(di) di[0] = "l" newBox.d[i] = tuple(di) first = False # convert to absolute coordinates newBox = pathtoPath(newBox.SVG()) # find the center of the object sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(newBox.d): if di[0] == "L": sumx += di[1] sumy += di[2] sum1 += 1. centerx = sumx/sum1 centery = sumy/sum1 phipos = atan2(centery - originy, centerx - originx) - pi/2. for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) di[1] += cos(phipos)*xdiff - sin(phipos)*ydiff di[2] += sin(phipos)*xdiff + cos(phipos)*ydiff newBox.d[i] = tuple(di) centerx += cos(phipos)*xdiff - sin(phipos)*ydiff centery += sin(phipos)*xdiff + cos(phipos)*ydiff for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) dispx = cos(phizdiff) * (di[1] - centerx) - sin(phizdiff) * (di[2] - centery) dispy = sin(phizdiff) * (di[1] - centerx) + cos(phizdiff) * (di[2] - centery) di[1] = dispx + centerx di[2] = dispy + centery newBox.d[i] = tuple(di) newBox = newBox.SVG() newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors(endcap, station, ring, chamber) newBox["id"] = newBox["id"] + "_moved" new_boxes.append(newBox) for treeindex, svgitem in disk_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "diskx": if endcap == 1: svgitem[0] = "Disk %+d" % station else: svgitem[0] = "Disk %+d" % (-station) svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) disk_template.save(filename)
def draw_disk(geom1, geom2, endcap, station, filename, length_factor=1., angle_factor=100., colors=csc_colors): if station == 1: disk_template = load_svg("disk1_template.svg") if station in (2, 3, 4): disk_template = load_svg("disk234_template.svg") scale_factor = 0.233 new_boxes = SVG("g") # center of the template originx = 339.74905 originy = 513.50318 for treeindex, svgitem in disk_template: if isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "ME_": m = re.match("ME_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception ring, chamber = int(m.group(1)), int(m.group(2)) xdiff = scale_factor * length_factor * ( geom2.csc[endcap, station, ring, chamber].x - geom1.csc[endcap, station, ring, chamber].x ) * signConventions["CSC", endcap, station, ring, chamber][0] ydiff = scale_factor * length_factor * ( geom2.csc[endcap, station, ring, chamber].y - geom1.csc[endcap, station, ring, chamber].y ) * signConventions["CSC", endcap, station, ring, chamber][1] phizdiff = -angle_factor * ( geom2.csc[endcap, station, ring, chamber].phiz - geom1.csc[endcap, station, ring, chamber].phiz ) * signConventions["CSC", endcap, station, ring, chamber][2] svgitem[ "style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" # copy chamber newBox = pathtoPath(svgitem) # find the center of the chamber sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(newBox.d): if di[0] == "L": sumx += di[1] sumy += di[2] sum1 += 1. centerx = sumx / sum1 centery = sumy / sum1 # global phi of the chamber phipos = atan2(originy - centery, centerx - originx) # global shifts of the chamber calculated from local shifts dx = -sin(phipos) * xdiff - cos(phipos) * ydiff dy = -cos(phipos) * xdiff + sin(phipos) * ydiff # shift the chamber along global X and Y for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) di[1] += dx di[2] += dy newBox.d[i] = tuple(di) # shift the center of the chamber along global X and Y centerx += dx centery += dy for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) # global shifts of the chamber calculated from local rotation dispx = cos(phizdiff) * ( di[1] - centerx) - sin(phizdiff) * (di[2] - centery) dispy = sin(phizdiff) * ( di[1] - centerx) + cos(phizdiff) * (di[2] - centery) # shift the chamber along global X and Y di[1] = dispx + centerx di[2] = dispy + centery newBox.d[i] = tuple(di) newBox = newBox.SVG() newBox[ "style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors( endcap, station, ring, chamber) newBox["id"] = newBox["id"] + "_moved" new_boxes.append(newBox) for treeindex, svgitem in disk_template: if isinstance( svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem[ "id"] == "chambers": svgitem.append(new_boxes) elif isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "diskx": if endcap == 1: svgitem[0] = "Disk %+d" % station else: svgitem[0] = "Disk %+d" % (-station) svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) disk_template.save(filename)
def draw_sector(geom1, geom2, sector, filename, length_factor=100., angle_factor=100., colors=dt_colors): if sector < 13: sector_template = load_svg("sector_template.svg") else: sector_template = load_svg("sector_template_station4.svg") # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in sector_template: if isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9])_([0-9])", svgitem["id"]) if m is None: raise Exception wheel, station = int(m.group(1)) - 2, int(m.group(2)) m = re.search("translate\(([0-9\.\-\+eE]+),([0-9\.\-\+eE]+)\)", svgitem["transform"]) tx = float(m.group(1)) ty = float(m.group(2)) ydiff = -length_factor * (geom2.dt[wheel, station, sector].y - geom1.dt[wheel, station, sector].y ) * signConventions["DT", wheel, station, sector][1] zdiff = -length_factor * (geom2.dt[wheel, station, sector].z - geom1.dt[wheel, station, sector].z ) * signConventions["DT", wheel, station, sector][2] phixdiff = angle_factor * (geom2.dt[wheel, station, sector].phix - geom1.dt[wheel, station, sector].phix ) * signConventions["DT", wheel, station, sector][0] newBox = svgitem.clone() svgitem[ "style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:5.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox[ "style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:5.0;stroke-opacity:1;stroke-dasharray:none" % colors( wheel, station, sector) newBox["id"] = newBox["id"] + "_moved" newBox["transform"] = "translate(%g,%g) rotate(%g)" % ( tx + ydiff, ty - zdiff, phixdiff * 180. / pi) new_boxes.append(newBox) for treeindex, svgitem in sector_template: if isinstance( svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem[ "id"] == "chambers": svgitem.append(new_boxes) elif isinstance( svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "title": svgitem[0] = "Sector %d (length x%g, angle x%g)" % ( sector, length_factor, angle_factor) sector_template.save(filename)
def add_graticule(self, svg, globe, view, viewbox): """ """ from clipping import Line from svgfig import SVG options = self.options lon0 = options.proj_opts['lon0'] llbbox = options.llbbox minLat = max(globe.minLat, options.llbbox[1]) maxLat = min(globe.maxLat, options.llbbox[3]) minLon = options.llbbox[0] maxLon = options.llbbox[2] #print minLon, maxLon, minLat, maxLat def xfrange(start, stop, step): while (step > 0 and start < stop) or (step < 0 and start > step): yield start start += step g = SVG('g', id='graticule', style="fill:none;stroke-width:0.25pt;") svg.append(g) for lat in xfrange(0,90, options.grat_step): lats = ([lat, -lat], [0])[lat == 0] for lat_ in lats: if lat_ < minLat or lat_ > maxLat: continue pts = [] lines = [] for lon in xfrange(0,361,1): lon_ = lon-180 if lon_ < minLon or lon_ > maxLon: continue if globe._visible(lon_, lat_): x,y = view.project(globe.project(lon_, lat_)) pts.append(Point(x,y)) else: if len(pts) > 1: line = Line(pts) pts = [] lines += line & viewbox if len(pts) > 1: line = Line(pts) pts = [] lines += line & viewbox for line in lines: path = SVG('path', d=line.svgPathString(), data_lat=lat_) if lat == 0: path['class'] = 'equator' g.append(path) for lon in xfrange(0,181, options.grat_step): lons = ([lon, -lon], [lon])[lon == 0 or lon == 180] for lon_ in lons: if lon_ < minLon or lon_ > maxLon: continue pts = [] lines = [] lat_range = xfrange(options.grat_step, 181-options.grat_step,1) if lon_ % 90 == 0: lat_range = xfrange(0, 181,1) for lat in lat_range: lat_ = lat-90 if lat_ < minLat or lat_ > maxLat: continue if globe._visible(lon_, lat_): x,y = view.project(globe.project(lon_, lat_)) pts.append(Point(x,y)) else: if len(pts) > 1: line = Line(pts) pts = [] lines += line & viewbox if len(pts) > 1: line = Line(pts) pts = [] lines += line & viewbox for line in lines: path = SVG('path', d=line.svgPathString(), data_lon=lon0 - lon_) g.append(path)
def draw_disk(geom1, geom2, endcap, station, filename, length_factor=1., angle_factor=100., colors=csc_colors): if station == 1: disk_template = load_svg("disk1_template.svg") if station in (2, 3, 4): disk_template = load_svg("disk234_template.svg") scale_factor = 0.233 new_boxes = SVG("g") # center of the template originx = 339.74905 originy = 513.50318 for treeindex, svgitem in disk_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "ME_": m = re.match("ME_([0-9]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception ring, chamber = int(m.group(1)), int(m.group(2)) xdiff = scale_factor * length_factor * (geom2.csc[endcap, station, ring, chamber].x - geom1.csc[endcap, station, ring, chamber].x) * signConventions["CSC", endcap, station, ring, chamber][0] ydiff = scale_factor * length_factor * (geom2.csc[endcap, station, ring, chamber].y - geom1.csc[endcap, station, ring, chamber].y) * signConventions["CSC", endcap, station, ring, chamber][1] phizdiff = -angle_factor * (geom2.csc[endcap, station, ring, chamber].phiz - geom1.csc[endcap, station, ring, chamber].phiz) * signConventions["CSC", endcap, station, ring, chamber][2] svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" # copy chamber newBox = pathtoPath(svgitem) # find the center of the chamber sumx = 0. sumy = 0. sum1 = 0. for i, di in enumerate(newBox.d): if di[0] == "L": sumx += di[1] sumy += di[2] sum1 += 1. centerx = sumx/sum1 centery = sumy/sum1 # global phi of the chamber phipos = atan2(originy-centery, centerx - originx) # global shifts of the chamber calculated from local shifts dx = -sin(phipos)*xdiff - cos(phipos)*ydiff dy = -cos(phipos)*xdiff + sin(phipos)*ydiff # shift the chamber along global X and Y for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) di[1] += dx di[2] += dy newBox.d[i] = tuple(di) # shift the center of the chamber along global X and Y centerx += dx centery += dy for i, di in enumerate(newBox.d): if di[0] in ("M", "L"): di = list(di) # global shifts of the chamber calculated from local rotation dispx = cos(phizdiff) * (di[1] - centerx) - sin(phizdiff) * (di[2] - centery) dispy = sin(phizdiff) * (di[1] - centerx) + cos(phizdiff) * (di[2] - centery) # shift the chamber along global X and Y di[1] = dispx + centerx di[2] = dispy + centery newBox.d[i] = tuple(di) newBox = newBox.SVG() newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors(endcap, station, ring, chamber) newBox["id"] = newBox["id"] + "_moved" new_boxes.append(newBox) for treeindex, svgitem in disk_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "diskx": if endcap == 1: svgitem[0] = "Disk %+d" % station else: svgitem[0] = "Disk %+d" % (-station) svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) disk_template.save(filename)
def draw_station(geom1, geom2, station, filename, length_factor=100., angle_factor=100., colors=dt_colors, template_dir='./'): if station == 4: station_template = load_svg(template_dir + "station4_template.svg") else: station_template = load_svg(template_dir + "station_template.svg") if station == 1: x_scale_factor = 1/6. if station == 2: x_scale_factor = 1/7. if station == 3: x_scale_factor = 1/8.5 if station == 4: x_scale_factor = 1/10. y_scale_factor = 1/7. # make a new group to put the moved chambers into new_boxes = SVG("g") # loop over the SVG tree, looking for our chambers (by id) for treeindex, svgitem in station_template: if isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"][:3] == "MB_": m = re.match("MB_([0-9mpz]+)_([0-9]+)", svgitem["id"]) if m is None: raise Exception wheel = m.group(1) if wheel == "m2": wheel = -2 elif wheel == "m1": wheel = -1 elif wheel == "z": wheel = 0 elif wheel == "p1": wheel = 1 elif wheel == "p2": wheel = 2 sector = int(m.group(2)) xdiff = x_scale_factor * length_factor * (geom1.dt[wheel, station, sector].x - geom2.dt[wheel, station, sector].x) * signConventions["DT", wheel, station, sector][0] ydiff = -y_scale_factor * length_factor * (geom1.dt[wheel, station, sector].y - geom2.dt[wheel, station, sector].y) * signConventions["DT", wheel, station, sector][1] phizdiff = -angle_factor * (geom1.dt[wheel, station, sector].phiz - geom2.dt[wheel, station, sector].phiz) * signConventions["DT", wheel, station, sector][2] sx = float(svgitem["x"]) + float(svgitem["width"])/2. sy = float(svgitem["y"]) + float(svgitem["height"])/2. svgitem["transform"] = "translate(%g,%g)" % (sx, sy) svgitem["x"] = -float(svgitem["width"])/2. svgitem["y"] = -float(svgitem["height"])/2. svgitem["style"] = "fill:#e1e1e1;fill-opacity:1;stroke:#000000;stroke-width:1.0;stroke-dasharray:1, 1;stroke-dashoffset:0" newBox = svgitem.clone() newBox["transform"] = "translate(%g,%g) rotate(%g) " % (sx + xdiff, sy + ydiff, phizdiff * 180./pi) newBox["style"] = "fill:%s;fill-opacity:0.5;stroke:#000000;stroke-width:1.0;stroke-opacity:1;stroke-dasharray:none" % colors(wheel, station, sector) new_boxes.append(newBox) for treeindex, svgitem in station_template: if isinstance(svgitem, SVG) and svgitem.t == "g" and "id" in svgitem.attr and svgitem["id"] == "chambers": svgitem.append(new_boxes) elif isinstance(svgitem, SVG) and "id" in svgitem.attr and svgitem["id"] == "stationx": svgitem[0] = "Station %d" % station svgitem[0] += " (length x%g, angle x%g)" % (length_factor, angle_factor) station_template.save(filename)