Chapter 6: Static Data on the World-Wide Web
6.4 Scalable Vector Graphics (SVG)
Scalable Vector Graphics (SVG) let you draw many different geometric shapes in your documents.
The full specification of SVG 1.1.
Geometric Shapes
Geographic Data
Summary
Exercises
Geometric Shapes
SVG can display rectangles, circles, ellipses, and lines.
You can also draw more general polylines and polygons (sets of points that are connected and either open-ended or closed).
SVG statements can be placed anywhere in your HTML, using the <svg>
element to introduce them, and CSS to style them:
svg rect { fill: rgb(200,200,200); stroke: black; }
svg .central { fill: yellow; }
svg #offset { fill: green; opacity: 0.5; }
svg polyline { fill: none; stroke-width: 2; stroke: black; }
svg polygon { fill: cyan; stroke: black; stroke-width: 2; }
svg .point { fill: blue; }
<svg width="400" height="100">
<rect x="0" y="0" width="400" height="100" />
<circle class="central" cx="200" cy="50" r="40" />
<ellipse id="offset" cx="240" cy="70" rx="60" ry="20" />
<line x1="0" y1="0" x2="400" y2="100" style="stroke: red; stroke-width: 5;" />
<polyline points="350,25 375,50 360,60 390,80" />
<polygon points="20,75 60,50 100,75" />
<circle class="point" cx="350" cy="25" r="4" />
</svg>
It’s generally a good idea to always specify the size of the drawing area, or canvas, using the width
and height
attributes of the <svg>
element (or corresponding CSS properties); otherwise your browser could choose an unexpected one.
Similar to positioned elements, values are used to specify location relative to the upper left corner, to the right and downward.
Note that later elements are drawn on top of earlier ones.
Also note that the SVG styling nomenclature is based on common graphics terms and so different than that used for HTML elements, using the properties fill
and stroke
rather than background
and border
.
Points are not defined by themselves, but can be implemented as circles of small radius, as above, or as positioned images.
Polylines are straightforward to understand as a space-separated list of points, each of which are coordinate pairs x,y
.
Polygons are similar to polylines but are closed automatically after the last point.
Geographic Data
As noted above, SVG allows for vector data types that are commonly used in GIS, viz. points, polylines, and polygons.
Multipolygons are also very useful in GIS, for example to include different polygons as part of one feature, like mainland Massachusetts, Martha’s Vineyard, and Nantucket. The more general path element can be used for this purpose.
For example, in the New England-based Lambert Conformal projected coordinate system used in Dodge’s Figure 3 to the right, Massachusetts can be represented by a path whose points are defined by the map coordinates, here measured in meters:
<path data-STATE_NAME="Massachusetts" data-STATE_FIPS="25" data-STATE_ABBR="MA"
d="M 203431,80079.1 l -1680.77,1386.42 -420.676,3200.78 ... -4345.45,2563.74 z
M 262632,41315.7 l 3091.49,3857.82 1207.51,-5252.37 ... 89.6828,-5002.74 z
M 310529,28044 l 2112.92,1427.23 -1684.85,1382.71 ... 5549.37,3808.62 z"
/>
The path coordinates and instructions to draw them are listed in the attribute d
:
- The first instruction
M
says to move to an absolute position, e.g.(203431,80079.1)
- The instruction
l
continues with line segments to the next series of points, expressed as relative displacements, e.g.(-1680.77,1386.42)
... The instructionL
could be used instead to continue to an absolute position. - The instruction
z
closes each subpath. - Repeating the above sequentially produces a multipolygon with three polygons.
Attributes beginning with data-
are user-definable and usable with any HTML element. Here they provide data that might be in a layer’s attribute table.
The six New England states in this coordinate system extend from (0,0)
in Connecticut to (552797,710986)
in Maine. This establishes a viewbox with these initial coordinates, width, and height that we can map on to an SVG canvas with width 192 pixels and height 256 pixels:
<svg width="192" height="256" viewBox="0 0 552797 710986">
....
</svg>
By default this viewbox is scaled uniformly so that it fits within the canvas, and is centered.
Sets of instructions such those for the six New England states can be grouped together, allowing them to be collectively transformed through translation, rotation, scaling, etc.
<g fill="none" stroke="black" stroke-width="1000"
transform="translate(0,710986) scale(1, -1)">
....
</g>
Note that the stroke-width
is in the units of the viewbox.
Because of the difference between the geographic upward axis ↑ and the computer graphics downward axis ↓ , a transformation is necessary to apply a translation and a scaling acccording to the following formula:
The resulting code looks like:
<svg width="25%" height="33%" viewBox="0 0 552797 710986">
<g fill="none" stroke="black" stroke-width="1000"
transform="translate(0,710986) scale(1, -1)">
<path data-STATE_NAME="Maine" data-STATE_FIPS="23" data-STATE_ABBR="ME" d= ...
<path data-STATE_NAME="Vermont" data-STATE_FIPS="50" data-STATE_ABBR="VT" d= ...
<path data-STATE_NAME="New Hampshire" data-STATE_FIPS="33" data-STATE_ABBR="NH" d= ...
<path data-STATE_NAME="Massachusetts" data-STATE_FIPS="25" data-STATE_ABBR="MA" d= ...
<path data-STATE_NAME="Connecticut" data-STATE_FIPS="09" data-STATE_ABBR="CT" d= ...
<path data-STATE_NAME="Rhode Island" data-STATE_FIPS="44" data-STATE_ABBR="RI" d= ...
</g>
</svg>
With CSS positioning, this vector information can be overlayed on the tiles from the previous section:
div#nepm2 { position: relative; width: 756px; height: 960px; }
#nepm2 .tile11, #nepm2 .tile12, #nepm2 .tile13,
#nepm2 .tile21, #nepm2 .tile22, #nepm2 .tile23,
#nepm2 .tile31, #nepm2 .tile32, #nepm2 .tile33,
#nepm2 .tile41, #nepm2 .tile42, #nepm2 .tile43
{ position: absolute; z-index: 0; }
svg#neSVG { width: 756px; height: 960px;
position: absolute; z-index: 1; }
g#new_england_states { fill: none; stroke: red; stroke-width: 2000 }
The viewBox needs to be increased to compensate for the larger extent of this “basemap”; positioning it with GIS indicates that in this coordinate system it starts at (-59619, 82359) and has width=643486 and height=810982. The state group translation must also be adjusted to this new starting point, 810982:
<div id="nepm2" style="border: none;">
<svg id="neSVG" viewBox="-59619 82359 643486 810982">
<g id="new_england_states" transform="translate(0,810982) scale(1, -1)">
<path data-STATE_NAME="Maine" data-STATE_FIPS="23" ...
....
<path data-STATE_NAME="Rhode Island" data-STATE_FIPS="44" ...
</g>
</svg>
<img class="tile11" src= ... >
....
<img class="tile43" src= ... >
</div>
This is the basic process by which Web maps are created. But no doubt you are saying to yourself, “There has to be an easier way!” And there is, by programming the repetitious parts, which you will begin to learn about in the next chapter.
Summary
- SVG lets you define and position vector features on your Web page:
- Lines, polylines, rectangles, circles, ellipses, and polygons.
- Paths can be used to define multipolygons.
- Many additional vector geometries in are described in the full specification of SVG 1.1.
- Geographic data can be represented with SVG elements, though the coordinate systems must be transformed.
- You can define attributes for HTML elements by starting their names with
data-
. - Rand McNally is not careful with Massachusetts!
Exercises
In the Exercises at the end of Chapter 6.3, you updated your Web page gne.html
with styles stored in gne.css
. You also positioned a tiled image of 1871 Massachusetts, which is actually pretty close to a projection into Massachusetts State Plane Mainland. Now overlay vector data for Massachusetts towns to match, from this source:
This SVG file has two extra lines at its beginning that allow it to function as a standalone document displayable in your browser, but they aren’t necessary when the <svg>
element is inside of an HTML document, where you will copy it.
The <svg>
element should occupy the same space as the images, so it and the containing <div>
should have width: 1024px; height: 637px;
.
The coordinates are in meters but displaced from the usual Mass State Plane origin so that the data begins at (0, 0) and has a width=296973 and height=182137. The viewBox in this file includes a margin to position the map data over the image tiles: viewBox="-7331 8168 311006 193807"
.
When you are done, upload your two files gne.html
and gne.css
to the Week 6 assignment activity in Moodle.