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)
コード例 #2
0
	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"))
コード例 #3
0
 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)
コード例 #5
0
	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)
コード例 #6
0
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)
コード例 #7
0
    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)
コード例 #8
0
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)
コード例 #9
0
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)
コード例 #10
0
	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')
コード例 #11
0
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)
コード例 #12
0
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)
コード例 #13
0
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)
コード例 #14
0
	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()
コード例 #15
0
    print(font_families)
except:
    print("Not on a mac it seems")

#AveriaLibre-Regular, Asap-Regular, ArchitectsDaughter, AnonymousPro-Regular, AdventPro-Regular, CabinSketch-Regular, Condiment-Regular, Dosis-Regular, IMFePIrm28P, NanumGothic-Regular, Nunito-Regular, PoiretOne-Regular, Quicksand-Regular, Rokkitt-Regular, Sacramento-Regular, Simonetta-Regular, TerminalDosis-Regular, 

#fonts = [ "Rancho-Regular", "Yesteryear-Regular", "Oregano-Regular", "PrincessSofia-Regular", "Cookie-Regular", "Yellowtail-Regular", "Radley-Italic", "Amiri-BoldSlanted", "BerkshireSwash-Regular", "Courgette-Regular", "Allura-Regular", "DroidSerif-BoldItalic", "Satisfy-Regular", "BadScript-Regular", "Condiment-Regular", "Damion-Regular", "Engagement-Regular", "Fascinate-Regular", "Federo-Regular", "Fondamento-Regular", "Handlee-Regular", "Lobster", "MrDafoe-Regular", "MrsSheppards-Regular",  ]

#main = Fig()
#collection = []

counter = 1
font = "IMFePIrm28P"
font = "AveriaLibre-Regular"
for content in markers:
    g = SVG("g", fill_opacity="50%", transform="translate(175, 0)")
    
    parts = font.split('-')
    name = parts[0]
    #if using styling in font name, may need to split by camel case too:
    #name = re.sub("([a-z])([A-Z])","\g<1> \g<2>",name)
    #(or you can do that manually when it is needed)
    print(name)

    bold = False
    italic = False
    if len(parts) > 1:
        properties = parts[1]
        if re.search("Bold", properties):
            bold = True
コード例 #16
0
 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
コード例 #17
0
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)
コード例 #18
0
	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
コード例 #19
0
    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
コード例 #20
0
	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)
コード例 #21
0
w = 522
h = 800

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:none;')

yo = 10

for k in Color.NAMED_COLOR:
    c = Color.NewFromHtml(Color.NAMED_COLOR[k],
                          wref=Color.WHITE_REFERENCE['std_D50'])
    out = [k]
    out.append(c.html)
    r, g, b = c.rgb
    out.append([int(r * 255), int(g * 255), int(b * 255)])
    out.append(list(c.hsv))
    out.append(list(c.hsl))
    l, a, b = c.lab
    out.append([l / 100.0, a, b])
    #print 'colors.push( ' + str(out) +' );'
    print 'colors.' + k + ' = "' + c.html + '"'
    svg.append(Text(23, yo + 15, k, style='font-size:12px').SVG())
    svg.append(SVG('rect', 10, y=yo, width=20, height=20, fill=c.html))
    yo += 24

svg.firefox()
コード例 #22
-1
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)