Add support for a Canvas renderer. This renderer will allow for some new
capabilties in OpenLayers Vector drawing, including: * Vector support for iPhone, Safari 2.x series browsers * Improved performance of dragging the map with a large number of geometries. The Vector layer default renderer order is now SVG, VML, Canvas, so browsers with Canvas support and no SVG or VML will be able to draw vectors. The Canvas layer has a number of limitations: getFeatureFromEvent is much slower than the other types of layer, and any change to any feature requires a redraw of the entire canvas. Because Canvas is typically a pretty fast drawing implementation, the latter is less problematic than it might otherwise be. r=pagameba,fred, with glances from a couple other people. (Closes #1512) git-svn-id: http://svn.openlayers.org/trunk/openlayers@7862 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>WFS Reprojection + Canvas Renderer Example</title>
|
||||
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
<script src="../lib/OpenLayers.js"></script>
|
||||
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map;
|
||||
OpenLayers.ProxyHost = "/proxy/?url=";
|
||||
var map, layer, styleMap;
|
||||
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
|
||||
function init(){
|
||||
|
||||
map = new OpenLayers.Map('map', {
|
||||
@@ -20,9 +21,10 @@
|
||||
});
|
||||
|
||||
var g = new OpenLayers.Layer.Google("G", {sphericalMercator: true});
|
||||
map.addLayers([g]);
|
||||
|
||||
// prepare to style the data
|
||||
var styleMap = new OpenLayers.StyleMap({
|
||||
styleMap = new OpenLayers.StyleMap({
|
||||
strokeColor: "black",
|
||||
strokeWidth: 2,
|
||||
strokeOpacity: 0.5,
|
||||
@@ -42,7 +44,7 @@
|
||||
// create a wfs layer with a projection different than the map
|
||||
// (only if your wfs doens't support your map projection)
|
||||
var wfs = layer = new OpenLayers.Layer.WFS(
|
||||
"States",
|
||||
"States (SVG)",
|
||||
"http://sigma.openplans.org:8080/geoserver/ows",
|
||||
{typename: 'topp:states'},
|
||||
{
|
||||
@@ -54,8 +56,23 @@
|
||||
styleMap: styleMap
|
||||
}
|
||||
);
|
||||
map.addLayer(wfs);
|
||||
|
||||
map.addLayers([g, wfs]);
|
||||
var wfs = layer = new OpenLayers.Layer.WFS(
|
||||
"States (Canvas)",
|
||||
"http://sigma.openplans.org:8080/geoserver/ows",
|
||||
{typename: 'topp:states'},
|
||||
{
|
||||
typename: 'states',
|
||||
featureNS: 'http://www.openplans.org/topp',
|
||||
projection: new OpenLayers.Projection("EPSG:4326"),
|
||||
extractAttributes: true,
|
||||
ratio: 1.2,
|
||||
styleMap: styleMap,
|
||||
renderers: ['Canvas', 'SVG', 'VML']
|
||||
}
|
||||
);
|
||||
map.addLayer(wfs);
|
||||
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
||||
|
||||
// if you want to use Geographic coords, transform to ESPG:900913
|
||||
@@ -70,7 +87,7 @@
|
||||
</head>
|
||||
<body onload="init()">
|
||||
|
||||
<h1 id="title">WFS Reprojection Example</h1>
|
||||
<h1 id="title">WFS Reprojection + Canvas Renderer Example</h1>
|
||||
|
||||
<div id="tags">
|
||||
</div>
|
||||
@@ -86,6 +103,9 @@
|
||||
here is the 'projection' option on the WFS layer.</p>
|
||||
<p>Also shown is styleMap for the layer with unique value rules. Colors
|
||||
are assigned based on the STATE_FIPS attribute.</p>
|
||||
<p>Additionally, this map demonstrates the Canvas/SVG renderers in browsers
|
||||
which support both. See the two different layers in the
|
||||
LayerSwitcher.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
"OpenLayers/Renderer.js",
|
||||
"OpenLayers/Renderer/Elements.js",
|
||||
"OpenLayers/Renderer/SVG.js",
|
||||
"OpenLayers/Renderer/Canvas.js",
|
||||
"OpenLayers/Renderer/VML.js",
|
||||
"OpenLayers/Layer/Vector.js",
|
||||
"OpenLayers/Strategy.js",
|
||||
|
||||
@@ -145,7 +145,7 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
* the first renderer which returns true for the 'supported()'
|
||||
* method will be used, if not defined in the 'renderer' option.
|
||||
*/
|
||||
renderers: ['SVG', 'VML'],
|
||||
renderers: ['SVG', 'VML', 'Canvas'],
|
||||
|
||||
/**
|
||||
* Property: renderer
|
||||
@@ -381,6 +381,11 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
if (!this.drawn || zoomChanged) {
|
||||
this.drawn = true;
|
||||
for(var i=0, len=this.features.length; i<len; i++) {
|
||||
if (i != (this.features.length - 1)) {
|
||||
this.renderer.locked = true;
|
||||
} else {
|
||||
this.renderer.locked = false;
|
||||
}
|
||||
this.drawFeature(this.features[i]);
|
||||
}
|
||||
}
|
||||
@@ -402,6 +407,11 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
var notify = !options || !options.silent;
|
||||
|
||||
for (var i=0, len=features.length; i<len; i++) {
|
||||
if (i != (features.length - 1)) {
|
||||
this.renderer.locked = true;
|
||||
} else {
|
||||
this.renderer.locked = false;
|
||||
}
|
||||
var feature = features[i];
|
||||
|
||||
if (this.geometryType &&
|
||||
@@ -463,6 +473,20 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
|
||||
var notify = !options || !options.silent;
|
||||
|
||||
for (var i = features.length - 1; i >= 0; i--) {
|
||||
// We remain locked so long as we're not at 0
|
||||
// and the 'next' feature has a geometry. We do the geometry check
|
||||
// because if all the features after the current one are 'null', we
|
||||
// won't call eraseGeometry, so we break the 'renderer functions
|
||||
// will always be called with locked=false *last*' rule. The end result
|
||||
// is a possible gratiutious unlocking to save a loop through the rest
|
||||
// of the list checking the remaining features every time. So long as
|
||||
// null geoms are rare, this is probably okay.
|
||||
if (i != 0 && features[i-1].geometry) {
|
||||
this.renderer.locked = true;
|
||||
} else {
|
||||
this.renderer.locked = false;
|
||||
}
|
||||
|
||||
var feature = features[i];
|
||||
|
||||
if (notify) {
|
||||
|
||||
@@ -33,6 +33,17 @@ OpenLayers.Renderer = OpenLayers.Class({
|
||||
*/
|
||||
extent: null,
|
||||
|
||||
/**
|
||||
* Property: locked
|
||||
* {Boolean} If the renderer is currently in a state where many things
|
||||
* are changing, the 'locked' property is set to true. This means
|
||||
* that renderers can expect at least one more drawFeature event to be
|
||||
* called with the 'locked' property set to 'true': In some renderers,
|
||||
* this might make sense to use as a 'only update local information'
|
||||
* flag.
|
||||
*/
|
||||
locked: false,
|
||||
|
||||
/**
|
||||
* Property: size
|
||||
* {<OpenLayers.Size>}
|
||||
|
||||
425
lib/OpenLayers/Renderer/Canvas.js
Normal file
425
lib/OpenLayers/Renderer/Canvas.js
Normal file
@@ -0,0 +1,425 @@
|
||||
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
|
||||
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Renderer.Canvas
|
||||
* A renderer based on the 2D 'canvas' drawing element.element
|
||||
*
|
||||
*/
|
||||
OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
|
||||
|
||||
/**
|
||||
* Property: root
|
||||
* {DOMElement} root element of canvas.
|
||||
*/
|
||||
root: null,
|
||||
|
||||
/**
|
||||
* Property: canvas
|
||||
* {Canvas} The canvas context object.
|
||||
*/
|
||||
canvas: null,
|
||||
|
||||
/**
|
||||
* Property: features
|
||||
* {Object} Internal object of feature/style pairs for use in redrawing the layer.
|
||||
*/
|
||||
features: null,
|
||||
|
||||
/**
|
||||
* Property: geometryMap
|
||||
* {Object} Geometry -> Feature lookup table. Used by eraseGeometry to
|
||||
* lookup features to remove from our internal table (this.features)
|
||||
* when erasing geoms.
|
||||
*/
|
||||
geometryMap: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Renderer
|
||||
*
|
||||
* Parameters:
|
||||
* containerID - {<String>}
|
||||
*/
|
||||
initialize: function(containerID) {
|
||||
OpenLayers.Renderer.prototype.initialize.apply(this, arguments);
|
||||
this.root = document.createElement("canvas");
|
||||
this.container.appendChild(this.root);
|
||||
this.canvas = this.root.getContext("2d");
|
||||
this.features = {};
|
||||
this.geometryMap = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: eraseGeometry
|
||||
* Erase a geometry from the renderer. Because the Canvas renderer has
|
||||
* 'memory' of the features that it has drawn, we have to remove the
|
||||
* feature so it doesn't redraw.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
*/
|
||||
eraseGeometry: function(geometry) {
|
||||
this.eraseFeatures(this.features[this.geometryMap[geometry.id]][0]);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: supported
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} Whether or not the browser supports the renderer class
|
||||
*/
|
||||
supported: function() {
|
||||
var canvas = document.createElement("canvas");
|
||||
return !!canvas.getContext;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setExtent
|
||||
* Set the visible part of the layer.
|
||||
*
|
||||
* Resolution has probably changed, so we nullify the resolution
|
||||
* cache (this.resolution), then redraw.
|
||||
*
|
||||
* Parameters:
|
||||
* extent - {<OpenLayers.Bounds>}
|
||||
*/
|
||||
setExtent: function(extent) {
|
||||
this.extent = extent.clone();
|
||||
this.resolution = null;
|
||||
this.redraw();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setSize
|
||||
* Sets the size of the drawing surface.
|
||||
*
|
||||
* Once the size is updated, redraw the canvas.
|
||||
*
|
||||
* Parameters:
|
||||
* size - {<OpenLayers.Size>}
|
||||
*/
|
||||
setSize: function(size) {
|
||||
this.size = size.clone();
|
||||
this.root.style.width = size.w + "px";
|
||||
this.root.style.height = size.h + "px";
|
||||
this.root.width = size.w;
|
||||
this.root.height = size.h;
|
||||
this.resolution = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawFeature
|
||||
* Draw the feature. Stores the feature in the features list,
|
||||
* then redraws the layer.
|
||||
*
|
||||
* Parameters:
|
||||
* feature - {<OpenLayers.Feature.Vector>}
|
||||
* style - {<Object>}
|
||||
*/
|
||||
drawFeature: function(feature, style) {
|
||||
if(style == null) {
|
||||
style = feature.style;
|
||||
}
|
||||
style = OpenLayers.Util.extend({
|
||||
'fillColor': '#000000',
|
||||
'strokeColor': '#000000',
|
||||
'strokeWidth': 2,
|
||||
'fillOpacity': 1,
|
||||
'strokeOpacity': 1
|
||||
}, style);
|
||||
this.features[feature.id] = [feature, style];
|
||||
this.geometryMap[feature.geometry.id] = feature.id;
|
||||
this.redraw();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Method: drawGeometry
|
||||
* Used when looping (in redraw) over the features; draws
|
||||
* the canvas.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
* featureId - {<String>}
|
||||
*/
|
||||
drawGeometry: function(geometry, style) {
|
||||
var className = geometry.CLASS_NAME;
|
||||
if ((className == "OpenLayers.Geometry.Collection") ||
|
||||
(className == "OpenLayers.Geometry.MultiPoint") ||
|
||||
(className == "OpenLayers.Geometry.MultiLineString") ||
|
||||
(className == "OpenLayers.Geometry.MultiPolygon")) {
|
||||
for (var i = 0; i < geometry.components.length; i++) {
|
||||
this.drawGeometry(geometry.components[i], style);
|
||||
}
|
||||
return;
|
||||
};
|
||||
switch (geometry.CLASS_NAME) {
|
||||
case "OpenLayers.Geometry.Point":
|
||||
this.drawPoint(geometry, style);
|
||||
break;
|
||||
case "OpenLayers.Geometry.LineString":
|
||||
this.drawLineString(geometry, style);
|
||||
break;
|
||||
case "OpenLayers.Geometry.LinearRing":
|
||||
this.drawLinearRing(geometry, style);
|
||||
break;
|
||||
case "OpenLayers.Geometry.Polygon":
|
||||
this.drawPolygon(geometry, style);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawExternalGraphic
|
||||
* Called to draw External graphics.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*/
|
||||
drawExternalGraphic: function(pt, style) {
|
||||
var img = new Image();
|
||||
img.src = style.externalGraphic;
|
||||
|
||||
var width = style.graphicWidth || style.graphicHeight;
|
||||
var height = style.graphicHeight || style.graphicWidth;
|
||||
width = width ? width : style.pointRadius*2;
|
||||
height = height ? height : style.pointRadius*2;
|
||||
var xOffset = (style.graphicXOffset != undefined) ?
|
||||
style.graphicXOffset : -(0.5 * width);
|
||||
var yOffset = (style.graphicYOffset != undefined) ?
|
||||
style.graphicYOffset : -(0.5 * height);
|
||||
var opacity = style.graphicOpacity || style.fillOpacity;
|
||||
|
||||
var context = { img: img,
|
||||
x: (pt[0]+xOffset),
|
||||
y: (pt[1]+yOffset),
|
||||
width: width,
|
||||
height: height,
|
||||
canvas: this.canvas };
|
||||
|
||||
img.onload = OpenLayers.Function.bind( function() {
|
||||
this.canvas.drawImage(this.img, this.x,
|
||||
this.y, this.width, this.height);
|
||||
}, context);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: setCanvasStyle
|
||||
* Prepare the canvas for drawing by setting various global settings.
|
||||
*
|
||||
* Parameters:
|
||||
* type - {String} one of 'stroke', 'fill', or 'reset'
|
||||
* style - {Object} Symbolizer hash
|
||||
*/
|
||||
setCanvasStyle: function(type, style) {
|
||||
if (type == "fill") {
|
||||
this.canvas.globalAlpha = style['fillOpacity'];
|
||||
this.canvas.fillStyle = style['fillColor'];
|
||||
} else if (type == "stroke") {
|
||||
this.canvas.globalAlpha = style['strokeOpacity'];
|
||||
this.canvas.strokeStyle = style['strokeColor'];
|
||||
this.canvas.lineWidth = style['strokeWidth'];
|
||||
} else {
|
||||
this.canvas.globalAlpha = 0;
|
||||
this.canvas.lineWidth = 1;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawPoint
|
||||
* This method is only called by the renderer itself.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*/
|
||||
drawPoint: function(geometry, style) {
|
||||
var pt = this.getLocalXY(geometry);
|
||||
|
||||
if (style.externalGraphic) {
|
||||
this.drawExternalGraphic(pt, style);
|
||||
} else {
|
||||
this.setCanvasStyle("fill", style);
|
||||
this.canvas.beginPath();
|
||||
this.canvas.arc(pt[0], pt[1], 6, 0, Math.PI*2, true);
|
||||
this.canvas.fill();
|
||||
|
||||
this.setCanvasStyle("stroke", style);
|
||||
this.canvas.beginPath();
|
||||
this.canvas.arc(pt[0], pt[1], 6, 0, Math.PI*2, true);
|
||||
this.canvas.stroke();
|
||||
this.setCanvasStyle("reset");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawLineString
|
||||
* This method is only called by the renderer itself.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*/
|
||||
drawLineString: function(geometry, style) {
|
||||
this.setCanvasStyle("stroke", style);
|
||||
this.canvas.beginPath();
|
||||
var start = this.getLocalXY(geometry.components[0]);
|
||||
this.canvas.moveTo(start[0], start[1]);
|
||||
for(var i = 1; i < geometry.components.length; i++) {
|
||||
var pt = this.getLocalXY(geometry.components[i]);
|
||||
this.canvas.lineTo(pt[0], pt[1]);
|
||||
}
|
||||
this.canvas.stroke();
|
||||
this.setCanvasStyle("reset");
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawLinearRing
|
||||
* This method is only called by the renderer itself.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*/
|
||||
drawLinearRing: function(geometry, style) {
|
||||
this.setCanvasStyle("fill", style);
|
||||
this.canvas.beginPath();
|
||||
var start = this.getLocalXY(geometry.components[0]);
|
||||
this.canvas.moveTo(start[0], start[1]);
|
||||
for(var i = 1; i < geometry.components.length - 1 ; i++) {
|
||||
var pt = this.getLocalXY(geometry.components[i]);
|
||||
this.canvas.lineTo(pt[0], pt[1]);
|
||||
}
|
||||
this.canvas.fill();
|
||||
|
||||
var oldWidth = this.canvas.lineWidth;
|
||||
this.setCanvasStyle("stroke", style);
|
||||
this.canvas.beginPath();
|
||||
var start = this.getLocalXY(geometry.components[0]);
|
||||
this.canvas.moveTo(start[0], start[1]);
|
||||
for(var i = 1; i < geometry.components.length; i++) {
|
||||
var pt = this.getLocalXY(geometry.components[i]);
|
||||
this.canvas.lineTo(pt[0], pt[1]);
|
||||
}
|
||||
this.canvas.stroke();
|
||||
this.setCanvasStyle("reset");
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: drawPolygon
|
||||
* This method is only called by the renderer itself.
|
||||
*
|
||||
* Parameters:
|
||||
* geometry - {<OpenLayers.Geometry>}
|
||||
* style - {Object}
|
||||
*/
|
||||
drawPolygon: function(geometry, style) {
|
||||
this.drawLinearRing(geometry.components[0], style);
|
||||
for (var i = 1; i < geometry.components.length; i++) {
|
||||
this.drawLinearRing(geometry.components[i], {
|
||||
fillOpacity: 0,
|
||||
strokeWidth: 0,
|
||||
strokeOpacity: 0,
|
||||
strokeColor: '#000000',
|
||||
fillColor: '#000000'}
|
||||
); // inner rings are 'empty'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getLocalXY
|
||||
* transform geographic xy into pixel xy
|
||||
*
|
||||
* Parameters:
|
||||
* point - {<OpenLayers.Geometry.Point>}
|
||||
*/
|
||||
getLocalXY: function(point) {
|
||||
var resolution = this.getResolution();
|
||||
var extent = this.extent;
|
||||
var x = (point.x / resolution + (-extent.left / resolution));
|
||||
var y = ((extent.top / resolution) - point.y / resolution);
|
||||
return [x, y];
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: clear
|
||||
* Clear all vectors from the renderer.
|
||||
* virtual function.
|
||||
*/
|
||||
clear: function() {
|
||||
this.canvas.clearRect(0, 0, this.root.width, this.root.height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getFeatureIdFromEvent
|
||||
* Returns a feature id from an event on the renderer.
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*
|
||||
* Returns:
|
||||
* {String} A feature id or null.
|
||||
*/
|
||||
getFeatureIdFromEvent: function(evt) {
|
||||
var loc = this.map.getLonLatFromPixel(evt.xy);
|
||||
var resolution = this.getResolution();
|
||||
var bounds = new OpenLayers.Bounds(loc.lon - resolution * 5,
|
||||
loc.lat - resolution * 5,
|
||||
loc.lon + resolution * 5,
|
||||
loc.lat + resolution * 5);
|
||||
var geom = bounds.toGeometry();
|
||||
for (var feat in this.features) {
|
||||
if (!this.features.hasOwnProperty(feat)) { continue; }
|
||||
if (this.features[feat][0].geometry.intersects(geom)) {
|
||||
return feat;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: eraseFeatures
|
||||
* This is called by the layer to erase features; removes the feature from
|
||||
* the list, then redraws the layer.
|
||||
*
|
||||
* Parameters:
|
||||
* features - {Array(<OpenLayers.Feature.Vector>)}
|
||||
*/
|
||||
eraseFeatures: function(features) {
|
||||
if(!(features instanceof Array)) {
|
||||
features = [features];
|
||||
}
|
||||
for(var i=0; i<features.length; ++i) {
|
||||
delete this.features[features[i].id];
|
||||
}
|
||||
if (!this.locked) {
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: redraw
|
||||
* The real 'meat' of the function: any time things have changed,
|
||||
* redraw() can be called to loop over all the data and (you guessed
|
||||
* it) redraw it. Unlike Elements-based Renderers, we can't interact
|
||||
* with things once they're drawn, to remove them, for example, so
|
||||
* instead we have to just clear everything and draw from scratch.
|
||||
*/
|
||||
redraw: function() {
|
||||
if (!this.locked) {
|
||||
this.clear();
|
||||
for (var id in this.features) {
|
||||
if (!this.features.hasOwnProperty(id)) { continue; }
|
||||
if (!this.features[id][0].geometry) { continue; }
|
||||
this.drawGeometry(this.features[id][0].geometry, this.features[id][1]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Renderer.Canvas"
|
||||
});
|
||||
86
tests/Renderer/Canvas.html
Normal file
86
tests/Renderer/Canvas.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<html>
|
||||
<head>
|
||||
<script src="../../lib/OpenLayers.js"></script>
|
||||
<script type="text/javascript">
|
||||
var supported = OpenLayers.Renderer.Canvas.prototype.supported();
|
||||
function test_Renderer_Canvas_constructor(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
|
||||
t.ok(r instanceof OpenLayers.Renderer.Canvas, "new OpenLayers.Renderer.Canvas returns Renderer.Canvas object" );
|
||||
t.ok(r.container == el, "renderer container is correctly set");
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_setextent(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
|
||||
var extent = new OpenLayers.Bounds(1,2,3,4);
|
||||
r.resolution = 1;
|
||||
r.setExtent(extent);
|
||||
t.ok(r.extent.equals(extent), "extent is correctly set");
|
||||
t.eq(r.resolution, null, "resolution nullified");
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_setsize(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
var size = new OpenLayers.Size(1,2);
|
||||
r.resolution = 1;
|
||||
r.setSize(size);
|
||||
t.ok(r.size.equals(size), "size is correctly set");
|
||||
t.eq(r.resolution, null, "resolution nullified");
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_getresolution(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(2);
|
||||
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
var map = new OpenLayers.Map("map");
|
||||
r.map = map;
|
||||
var resolution = r.getResolution();
|
||||
t.eq(resolution, map.getResolution(), "resolution matches the map resolution");
|
||||
t.eq(r.resolution, resolution, "resolution is correctly set");
|
||||
}
|
||||
|
||||
function test_Renderer_Canvas_destroy(t) {
|
||||
if (!supported) { t.plan(0); return; }
|
||||
t.plan(5);
|
||||
|
||||
var el = document.body;
|
||||
el.id = "foo";
|
||||
var r = new OpenLayers.Renderer.Canvas(el.id);
|
||||
r.container = document.createElement("div");
|
||||
r.extent = new OpenLayers.Bounds(1,2,3,4);
|
||||
r.size = new OpenLayers.Size(1,2);
|
||||
r.resolution = 1;
|
||||
r.map = {};
|
||||
|
||||
r.destroy();
|
||||
|
||||
t.eq(r.container, null, "container nullified");
|
||||
t.eq(r.extent, null, "extent nullified");
|
||||
t.eq(r.size, null, "size nullified");
|
||||
t.eq(r.resolution, null, "resolution nullified");
|
||||
t.eq(r.map, null, "map nullified");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" style="width:500px;height:550px"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -114,6 +114,7 @@
|
||||
<li>Projection.html</li>
|
||||
<li>Protocol.html</li>
|
||||
<li>Renderer.html</li>
|
||||
<li>Renderer/Canvas.html</li>
|
||||
<li>Renderer/Elements.html</li>
|
||||
<li>Renderer/SVG.html</li>
|
||||
<li>Renderer/VML.html</li>
|
||||
|
||||
Reference in New Issue
Block a user