Column

Scalable Vector Graphics

This is about how and when to use SVG (Scalable Vector Graphics). The graphics part of SVG is easiest to explain. SVG is a format for images, like JPEG, PNG, or TIFF. The SVG difference is that, instead of capturing the image with a camera or scanner, you define it with words.

This is where the word “vector” comes in. A vector consists of a distance and a direction. The simplest example of a vector is probably “from point A to point B.” Real estate lawyers will relate vectors to metes and bounds descriptions in surveys, e.g. “Commencing at the northwest corner of the lot, then north 30 degrees east 10 chains, three links to a post.” Another way is to specify two points with Cartesian coordinates, saying, for example, “from (1,2) to (7,-5)”. This is the basic method of SVG. For additional reading, see “Euclidean vector” (Wikipedia), “Metes and bounds” (Wikipedia), and “Cartesian coordinate system” (Wikipedia).

JPEG, PNG and TIFF are raster image formats. Since “raster” is from the Latin word “rastrum” meaning “rake”, it’s as if a slice of reality had been raked in by your scanner or camera. The general technique is to scrape a little bit of visual reality into a bitmap, i.e. a rectangular grid of picture elements (“pixels’.) The raw image formats used by the makers of scanners and cameras are notoriously unstandardized, but you can generally output from any of them to something that is usable elsewhere. In choosing an output format, there are various considerations, such as file size and loss of information.

For example, ordinary JPEG is “lossy”; PNG is not, which means file sizes tend to be larger. For additional reading, see “Rastrum” (Wiktionary), “Raster graphics” (Wikipedia), “Rendering (computer graphics) (Wikipedia), “Raw image format” (Wikipedia), “Lossy compression” (Wikipedia), “Lossless compression” (Wikipedia), “Bitmap” (Wikipedia), “Pixel” (Wikipedia), “Image File formats” (Wikipedia), “JPEG” (Wikipedia), “Portable Network Graphics” (Wikipedia), and “Tagged Image File Format” (Wikipedia).

Generally, when one wants to change the size of an image, one wants to change it while changing as little of anything else as is possible. That’s what we mean by “scalable”. Because vector images are made according to the written directions in the file, bigger and smaller versions will be equally crisp. It just depends on what your rendering agent (e.g. your browser) can do. Raster images are different because they depend not just on an abstract definition, but also on the amount of information originally scraped. Thus, when you resize them, you normally compromise them a little or a lot. Making a downsized raster image generally involves a loss of information. An upsized raster image tends to be fuzzy, because keeping it crisp would require an information gain.

You can read all about SVG at http://www.w3.org/Graphics/SVG/. It’s a W3C recommendation. The current recommendation is version 1.1, second edition (August 16, 2011). The first edition of 1.1 was dated January 14, 2003. Version 1.0 was dated September 4, 2001. It took a while for the browsers of the world to be able to handle SVG. That’s why I left it alone for a number of years. Now, however, it seems a pretty safe bet.

It’s a slightly different story on little machines, at least for now. SVG 1.1 Mobile (January 14, 2003) defined two subsets for devices with limited memory: SVG Tiny for cellphones, and SVG Basic for PDAs. The big memory saver in Tiny was the lack of a requirement to maintain a Document Object Model (DOM). In other words, no scripting. So SVG Tiny 1.2 (December 22, 2008) implements the SVG Micro DOM (uDOM). And the little machines keep getting more capable.

The hope is that SVG 2.0 will arrive in 2014, better integrated with CSS, HTML5 and WOFF. For additional reading, see “Scalable Vector Graphics” (Wikipedia), “HTML5″ (Wikipedia), “Cascading Style Sheets” (Wikipedia) and “Web Open Font Format” (Wikipedia).

So let’s see some SVG:
 
<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?>
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN”
        ”http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
<svg width=”1300″ height=”1000″ viewBox=”0 0 5200 4000″
        xmlns=”http://www.w3.org/2000/svg” version=”1.1″
        xmlns:xlink=”http://www.w3.org/1999/xlink”>
<title>A Certain Township</title>
<desc>Plan of A Certain Township</desc>
<g id=”a_certain_township” transform=”rotate(0.4 100 50)”>
        <!– original 2367 1641 ratio 0.69328 –>
        <image xlink:href=”a_certain_township.jpg” x=”100″ y=”50″ width=”4734″ height=”3282″ />
</g>
<g id=”lots_38_to_31″ transform=”translate(315 110) scale(2.8)”>
        <!– n 78 e 198.10, n 15.67 w 22, s 78 w 198.10, (s 15.67 e 20.50) –>
        <path d=”M 10 300 L 203.771 258.813 L 197.829 237.631 L 4.058 278.818 z”
        fill=”none” stroke=”red” stroke-width=”1″ />
</g>
</svg>

You’ll probably recognize that this is XML. So all you need to make SVG is a text editor.

The “standalone” attribute is apt to confuse. An SVG document can stand alone if its root element is “svg”, as here. But SVG need not stand alone. An XML document with, say, an “html” root element, can validly contain an svg fragment. Here, I have an svg root element, but I’ve said ‘standalone=”no”‘. Browsers tolerate that sort of thing. But an XML validator like http://validator.w3.org/ gets annoyed if I say ‘standalone=”yes”‘ and include an XLINK namespace, as I’ve done here. So I’ve said ‘standalone=”no”‘. (I included an XLINK namespace because I wanted to link to a JPEG. I’ll explain why later.)

The DTD is optional, unless you want (as I do) to use an external validator like the above, or a validating XML editor. As section 1.3 SVG Namespace, Public Identifier and System Identifier of the specification says: “While a DTD is provided in this specification, the use of DTDs for validating XML documents is known to be problematic. In particular, DTDs do not handle namespaces gracefully. It is not recommended that a DOCTYPE declaration be included in SVG documents.” Which is not the same as a recommendation that you NOT use one. For additional reading, see “Appendix G.2 Conforming SVG Document Fragments” (w3.org), “Appendix G.3 Conforming SVG Stand-Alone Files” (w3.org), Jesper Tverskov, “The standalone pseudo-attribute is only relevant if a DTD is used” (xmplease.com), and
“Document Type Definition” Wikipedia).

At the heart of SVG is the PATH element. Points are indicated by a pair of numbers, horizontal and vertical, reckoning from the top left corner of the document. (See the reference to Cartesian coordinates, above.) “10 300″ is an example. Thus, M, for “moveto”, indicates a starting point. The first L, for “lineto”, completes the specification of a vector. The next L, and the subsequent ones, extend the path. Z, for “closepath”, means extend the path back to the starting point. So my path in this example would be a little four-sided polygon. The stroke would be red, one pixel in width. No colour would be used to fill the inside of the polygon. Section 8.3.1 General information about path data of the specification uses a red triangle to illustrate.

Don’t like straight lines? Use a curve instead. SVG has three kinds: elliptical arcs, quadratic Bézier curves, and cubic Bézier curves.

Most of us will remember ellipses from high school geometry. To define the ellipse, you need a starting point, a horizontal x-radius, a vertical y-radius, and an x-axis rotation. To define a particular arc along that ellipse, you need a large-arc-flag (1 for large, 0 for small), a sweep-flag (1 for positive-angle, 0 for negative-angle), and an end-point. I can’t improve upon the illustration in Section 8.3.8 The elliptical arc curve commands.

We didn’t talk about Bézier curves when I took high school geometry. (Has that changed?) Of course, you need a start-point and an end-point. In the case of a quadratic Bézier curve, you indicate a single control-point which draws the connecting line towards itself like gravity. In the case of a cubic Bézier curve, there are two control-points to curve the connecting line. Again, I can’t improve upon the illustrations in section 8.3.7 The quadratic Bézier curve commands and section 8.3.6 The cubic Bézier curve commands of the specification. For additional reading, see “Bézier curve” (Wikipedia).

These are the essentials. Just for convenience, though, there are additional elements you can use for rectangles, circles, and so on. The G element is just for grouping. It helps with documentation, and with any scripting you might want to do.

If you’re thinking of using Javascript (or ECMAScript) and the Document Object Model (aka DOM) so that images can be redrawn dynamically on a website, you can. That’s one of the main advantages of having your images defined abstractly, rather than from scrapings. If this appeals to you, Section 8.5.1 Interface SVGPathSeg of the specification is a good place to start reading. For a simple example, and additional reading, see “Change svg path with javascript” stackoverflow.com, “Javascript” (Wikipedia),
“ECMAScript” (Wikipedia) and “Document Object Model” (Wikipedia).

OK. Back to my own example. Why did I want to include a JPEG image in an SVG image? As it happens, it’s just a temporary expedient, in order to let me “trace” that JPEG image to some extent. My example is from a work in progress.

One of my history projects involves land records. Crown grants and conveyances. I’m dealing with a bunch of 19th century metes and bounds descriptions, and I want to be able to make reasonably accurate illustrations, with internal documentation. (Things like “<!– comment –>” are comments.) In this case, the plan is to plot out all the descriptions in all the crown grants for a whole township.

I’ve wanted to keep the math as simple as possible. Therefore, the numbers in my point coordinates are directly based on the link and chain measurements from the original surveys. The image dimensions have been chosen accordingly. So far I’m just using a scientific calculator that does sines and cosines to get the x and y coordinates. I’ve thought of using Javascript to do the calculations but, as of right now, I don’t think that would actually simplify my life.

An added complication is that the descriptions sometimes follow the paths of roads, rivers and creeks, the meanderings of which were not explicitly described in the crown grants. That’s where the JPEG image comes in.

GeoGratis is a service of Natural Resources Canada: http://geogratis.cgdi.gc.ca/geogratis/en/index.html. You can get Landsat7 satellite images for free. You just have to be willing, at the appropriate moments, to say: “© Department of Natural Resources Canada. All rights reserved.” (Out of an abundance of caution, I thought it best not to use Google maps for this project, if I could avoid it.) For additional reading, see “Landsat 7″ (Wikipedia).

So I downloaded a satellite image and clipped out my township. As noted, I needed to to add a namespace for XLINK to my SVG file. I also had to rotate the image just a little, I think because of the difference between true north and magnetic north as it was in the early 1800s. Then I translated (i.e. shifted) and scaled the SVG drawings to make them a match (more or less) to the positions on the satellite image. The result is that I can trace the rivers and roads. And, once the tracing is complete, I can remove the JPEG. Or leave it in. At some point down the road, if I want to make an SVG image of just a few parcels, all I will have to do is copy a few paths to new files and scale everything accordingly.

I’m sure surveyors must have better tools for tasks like this. This method is free, though, and does what I need it to do, at least for now. In any event, figuring out how to do it has made it possible for me to give you a brief introduction to SVG.

Retweet information »

Comments are closed.