source: trunk/webmap/html/js/webmap/map.js @ 15

Last change on this file since 15 was 15, checked in by wcaarls, 11 years ago

Imported webmap at revision 1169

File size: 6.3 KB
Line 
1var webmap = webmap || {};
2webmap.modules.map = {}; /// Namespace for map modules.
3
4/// Create a new webmap.
5/**
6 * \param container     A reference to the container element.
7 * \param canvas_width  The width of the canvas.
8 * \param canvas_height The width of the canvas.
9 */
10webmap.Map = function(container, canvas_width, canvas_height) {
11       
12        // Call parent constructor.
13        webmap.Extendable.call(this, webmap.modules.map);
14       
15        // Copy parameters.
16        this.container  = container;
17        this.canvas_width  = canvas_width;
18        this.canvas_height = canvas_height;
19       
20        this.selected = null;
21       
22        // Create the SVG root element.
23        this.root = document.createElementNS(webmap.svgns, "svg");
24        this.root.setAttribute("version",      1.1);
25        this.root.setAttribute("baseProfile", "tiny");
26        this.root.setAttribute("class",        "webmap");
27        this.root.setAttribute("width",        this.canvas_width);
28        this.root.setAttribute("height",       this.canvas_height);
29        this.root = this.container.appendChild(this.root);
30        this.root.webmap = this;
31       
32        // Create a reference point outside of the transformed group.
33        this.ref_rect = document.createElementNS(webmap.svgns, "rect");
34        this.ref_rect.setAttribute("id", "ref_rect");
35        this.ref_rect.setAttribute("x", 0);
36        this.ref_rect.setAttribute("y", 0);
37        this.ref_rect.width  = this.root.width;
38        this.ref_rect.height = this.root.height;
39        this.ref_rect.setAttribute("fill",   "none");
40        this.ref_rect.setAttribute("stroke", "none");
41        this.ref_rect = this.root.appendChild(this.ref_rect);
42       
43        // Create the world group
44        this.world = document.createElementNS(webmap.svgns, "g");
45        this.world.setAttribute("id", "world");
46        this.world = this.root.appendChild(this.world);
47       
48        // Create initial view and virtual map transform.
49        this.world_tf = this.root.createSVGMatrix().translate(this.canvas_width * 0.5, this.canvas_height * 0.5).scaleNonUniform(1, -1);
50        this.applyView();
51       
52        this.mouseClickListener = this.mouseClick.bind(this);
53        this.root.addEventListener("click", this.mouseClickListener, false);
54}
55
56webmap.extend(webmap.Extendable, webmap.Map);
57
58/// Get the bounding rectangle of the SVG viewport.
59/**
60 * Returned coordinates are relative to the parent viewport.
61 */
62webmap.Map.prototype.getBoundingRect = function() {
63        return this.ref_rect.getBoundingClientRect();
64}
65
66/// Add an image to the map.
67/**
68 * \param iri         The IRI identifying the image.
69 * \param angle       The rotation of the image in degrees.
70 * \param x           The X coordinate of the bottom left corner of the image.
71 * \param y           The Y coordinate of the bottom left corner of the image.
72 * \param width       The virtual width of the image.
73 * \param height      The virtual width of the image.
74 * \return The created image.
75 */
76webmap.Map.prototype.addImage = function(iri, x, y, width, height) {
77        var img = document.createElementNS(webmap.svgns, "image");
78        img.setAttributeNS(webmap.xlinkns, "href", iri);
79        img.setAttribute("width",  width);
80        img.setAttribute("height", height);
81        img.setAttribute("preserveAspectRatio", "none");
82        img.setAttribute("viewbox", "defer");
83        img.setAttribute("x",      0);
84        img.setAttribute("y",      0);
85       
86        var tf = this.root.createSVGMatrix()
87                .translate(x, y)
88                .translate(width * 0.5, height * 0.5)
89                .scaleNonUniform(1, -1) // Flip the Y axis to correct for the right handed coordinate system.
90                .translate(width * -0.5, height * -0.5)
91       
92        img.transform.baseVal.initialize(img.transform.baseVal.createSVGTransformFromMatrix(tf));
93        this.world.appendChild(img);
94        return img;
95}
96
97/// Remove an image from the map.
98/**
99 * \param img The image to remove, as returned from addImage().
100 */
101webmap.Map.prototype.removeImage = function(img) {
102        if (img.parentNode === this.world) this.world.removeChild(img);
103}
104
105/// Add a robot to the map.
106/**
107 * \param robot  The robot to add.
108 */
109webmap.Map.prototype.addRobot = function(robot) {
110        if (robot.map && robot.map !== this) {
111                robot.map.removeRobot(robot);
112        } else if (robot.map === this) {
113                return;
114        }
115       
116        robot.map = this;
117        this.world.appendChild(robot.svg);
118        this.notifyModules("onAddRobot", robot);
119}
120
121/// Remove a robot from the map.
122/**
123 * \param robot The robot to remove.
124 * \return True if the robot was on the map and has been removed, false otherwise.
125 */
126webmap.Map.prototype.removeRobot = function(robot) {
127        if (!robot.map || robot.map !== this) return false;
128       
129        if (robot.svg.parentNode) robot.svg.parentNode.removeChild(robot.svg);
130        this.notifyModules("onRemoveRobot", robot);
131        return true;
132}
133
134/// Change the selected robot.
135/**
136 * \param robot The robot to select.
137 */
138webmap.Map.prototype.setSelected = function(robot) {
139        if (this.selected) this.selected.setSelected(false);
140        this.selected = robot;
141        if (this.selected) this.selected.setSelected(true);
142       
143        /// Notify all interested modules.
144        this.notifyModules("onSelect");
145}
146
147/// Apply world transforms.
148/**
149 * Changing the view allows you to zoom in/out on parts of the map,
150 * and to rotate the map.
151 */
152webmap.Map.prototype.applyView = function() {
153        this.world.transform.baseVal.initialize(this.world.transform.baseVal.createSVGTransformFromMatrix(this.world_tf));
154}
155
156/// Translate the world.
157/**
158 * \param x The X offset to translate by.
159 * \param y The Y offset to translate by.
160 */
161webmap.Map.prototype.translate = function(x, y) {
162        this.world_tf = this.root.createSVGMatrix().translate(x, y).multiply(this.world_tf);
163        this.applyView();
164}
165
166/// Scale the world around a viewport point.
167/**
168 * \param factor The factor to scale by.
169 * \param x The X coordinate of the viewport point to use as center.
170 * \param y The Y coordinate of the viewport point to use as center.
171 */
172webmap.Map.prototype.scale = function(factor, x, y) {
173        if (x == undefined) x = this.map.canvas_width  * 0.5;
174        if (y == undefined) y = this.map.canvas_height * 0.5;
175        this.world_tf = this.root.createSVGMatrix().translate(x - x * factor, y - y * factor).scale(factor).multiply(this.world_tf);
176        this.applyView();
177}
178
179/// Rotate the world around a given point.
180/**
181 * \param angle The angle to rotate by.
182 * \param x The X coordinate of the viewport point to use as center.
183 * \param y The Y coordinate of the viewport point to use as center.
184 */
185webmap.Map.prototype.rotate = function(angle, x, y) {
186        this.world_tf = this.root.createSVGMatrix().translate(x, y).rotate(angle).translate(-x, -y).multiply(this.world_tf);
187        this.applyView();
188}
189
190
191/// Handle mouse clicks.
192webmap.Map.prototype.mouseClick = function(event) {
193        // Clear the selection.
194        this.setSelected(null);
195}
Note: See TracBrowser for help on using the repository browser.