Subversion Repositories display

Rev

Rev 370 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2014 Steve Ratcliffe
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 or
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package test.svg;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * Holds the SVG document.
 *
 * Various elements are saved as fields, so that information can be added later.
 *
 * @author Steve Ratcliffe
 */

public class SvgDoc {
        private static final String SODIPODI = "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";

        private Document doc; // The whole document

        private Element defs; // Definitions, eg markers.

        // Layers for drawing to
        private Element routing; // The layer used to draw the route network
        private Element roads;   // For roads
        private Element info;    // For information boxes
    private Element spokes;  // Lines from node to its center.
    private Element marked;  // Routing info for the marked nodes.

    // Offsets to translate the whole diagram by, so that it is all on the page.
        private int topOffset;
        private int leftOffset;

    /**
         * Create the document outline.  Various elements are saved and added to by the
         * rest of the program.
         */

        public void createDoc() {
                doc = DocumentHelper.createDocument();

                Element svg = doc.addElement("svg", "http://www.w3.org/2000/svg")
                                .addAttribute("xmlns", "http://www.w3.org/2000/svg")
                                .addAttribute("xmlns:inkscape", "http://www.inkscape.org/namespaces/inkscape")
                                .addAttribute("xmlns:sodipodi", SODIPODI)
                                .addAttribute("version", "1.1")
                                .addAttribute("id", "svg2");

                // Definitions for the whole document
                defs = svg.addElement("defs").addAttribute("id", "defs1");
                addMarkers();

                // Information for inkscape.
                svg.addElement("sodipodi:namedview", SODIPODI)
                                .addAttribute("id", "base")
                                .addAttribute("pagecolor", "#ffffff")
                                .addAttribute("inkscape:window-width", "1060")
                                .addAttribute("inkscape:window-height", "700")
                ;

                // Add the layers
                spokes = svg.addElement("g")
                                .addAttribute("inkscape:label", "center spokes")
                .addAttribute("style", "display:none")
                                .addAttribute("inkscape:groupmode", "layer");

        roads = svg.addElement("g")
                                .addAttribute("inkscape:label", "roads")
                                .addAttribute("opacity", "0.4")
                                .addAttribute("inkscape:groupmode", "layer");

                marked = svg.addElement("g")
                                .addAttribute("inkscape:label", "marked")
                                .addAttribute("z-index", "10")
                                .addAttribute("inkscape:groupmode", "layer");

                routing = svg.addElement("g")
                                .addAttribute("inkscape:label", "routing")
                                .addAttribute("inkscape:groupmode", "layer");

                info = svg.addElement("g")
                                .addAttribute("inkscape:label", "info")
                                .addAttribute("inkscape:groupmode", "layer");
        }

        private void addMarkers() {
                defs.addElement("marker")
                                .addAttribute("inkscape:stockid", "Arrow2Send")
                                .addAttribute("orient", "auto")
                                .addAttribute("refX", "0.0")
                                .addAttribute("refY", "0.0")
                                .addAttribute("id", "Arrow2Send")
                                .addAttribute("style", "overflow:visible;")
                        .addElement("path")
                                .addAttribute("style", "fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;")
                                .addAttribute("d", "M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z ")
                                .addAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)")
                ;

                defs.addElement("marker")
                                .addAttribute("inkscape:stockid", "DiamondSend")
                                .addAttribute("orient", "auto")
                                .addAttribute("refX", "0.0")
                                .addAttribute("refY", "0.0")
                                .addAttribute("id", "DiamondSend")
                                .addAttribute("style", "overflow:visible;")
                        .addElement("path")
                                .addAttribute("style", "fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt")
                                .addAttribute("d", "M 0,-7.0710768 L -7.0710894,0 L 0,7.0710589 L 7.0710462,0 L 0,-7.0710768 z")
                                .addAttribute("transform", "scale(0.2) translate(-6,0)")
                                ;
                defs.addElement("marker")
                                .addAttribute("inkscape:stockid", "DotM")
                                .addAttribute("orient", "auto")
                                .addAttribute("refX", "0.0")
                                .addAttribute("refY", "0.0")
                                .addAttribute("id", "DotM")
                                .addAttribute("style", "overflow:visible;")
                        .addElement("path")
                                .addAttribute("style", "fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt")
                                .addAttribute("d", "M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 " +
                                                "-12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z")
                                .addAttribute("transform", "scale(0.4) translate(7.4, 1)")
                                ;
        }

        public Document getDoc() {
                return doc;
        }

        public Element getRouting() {
                return routing;
        }

        public Element getRoads() {
                return roads;
        }

        public Element getInfo() {
                return info;
        }

    public Element getSpokes() {
        return spokes;
    }

    public void setTransform(int leftOffset, int topOffset) {
                int MARGIN = 30;
                String translate = String.format("translate(%d,%d)", MARGIN - leftOffset, MARGIN - topOffset);
                spokes.addAttribute("transform", translate);
                routing.addAttribute("transform", translate);
                roads.addAttribute("transform", translate);
                info.addAttribute("transform", translate);
                marked.addAttribute("transform", translate);
        }

        public int getLeftOffset() {
                return leftOffset;
        }

        public int getTopOffset() {
                return topOffset;
        }

        public XY coord(int lat, int lon) {
                XY co = new XY(lat, lon);
                if (co.getXi() < leftOffset)
                        leftOffset = co.getXi();
                if (co.getYi() < topOffset)
                        topOffset = co.getYi();
                return co;
        }

        public Element getMarked() {
                return marked;
        }
}