928 lines
42 KiB
HTML
928 lines
42 KiB
HTML
<html>
|
|
<head>
|
|
<script src="../OLLoader.js"></script>
|
|
<script type="text/javascript">
|
|
|
|
var name = "Vector Layer";
|
|
|
|
function test_Layer_Vector_constructor(t) {
|
|
t.plan(5);
|
|
|
|
var options = {protocol: new OpenLayers.Protocol(),
|
|
strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]}
|
|
var layer = new OpenLayers.Layer.Vector(name, options);
|
|
|
|
t.ok(layer instanceof OpenLayers.Layer.Vector, "new OpenLayers.Layer.Vector returns correct object" );
|
|
t.eq(layer.name, name, "layer name is correctly set");
|
|
t.ok(layer.renderer.CLASS_NAME, "layer has a renderer");
|
|
|
|
t.ok((layer.name == layer.strategies[0].layer.name) &&
|
|
(layer.strategies[0].layer.name == layer.strategies[1].layer.name),
|
|
"setLayer was called on strategies");
|
|
|
|
options.renderers = [OpenLayers.Renderer.SVG, OpenLayers.Renderer.VML, OpenLayers.Renderer.Canvas];
|
|
layer.destroy();
|
|
layer = new OpenLayers.Layer.Vector(name, options);
|
|
t.ok(layer.renderer.CLASS_NAME, "layer has a renderer when providing a function");
|
|
layer.destroy();
|
|
}
|
|
|
|
function test_Layer_Vector_assignRenderer(t) {
|
|
t.plan(2);
|
|
|
|
// create a dummy class in the global name space
|
|
My = {
|
|
Custom: {
|
|
Renderer: {
|
|
Supported: OpenLayers.Class(OpenLayers.Renderer, {
|
|
supported: OpenLayers.Function.True,
|
|
CLASS_NAME: 'My.Custom.Renderer.Supported'
|
|
}),
|
|
NotSupported: OpenLayers.Class(OpenLayers.Renderer, {
|
|
supported: OpenLayers.Function.False,
|
|
CLASS_NAME: 'My.Custom.Renderer.NotSupported'
|
|
})
|
|
}
|
|
}
|
|
};
|
|
var layer = new OpenLayers.Layer.Vector('vector', {
|
|
renderers: [My.Custom.Renderer.NotSupported,
|
|
My.Custom.Renderer.Supported,
|
|
OpenLayers.Renderer.Canvas]
|
|
});
|
|
t.eq(layer.renderer.CLASS_NAME, 'My.Custom.Renderer.Supported',
|
|
'layer has a valid renderer');
|
|
|
|
var layer = new OpenLayers.Layer.Vector('vector', {
|
|
renderers: ['SVG', 'VML', 'Canvas', My.Custom.Renderer.Supported]
|
|
});
|
|
t.ok(layer.renderer.CLASS_NAME != 'My.Custom.Renderer.Supported',
|
|
'renderers can be strings as well');
|
|
}
|
|
|
|
function test_Layer_Vector_refresh(t) {
|
|
t.plan(4);
|
|
|
|
var obj = {"an": "object"};
|
|
|
|
var log;
|
|
var layer = new OpenLayers.Layer.Vector(name, {
|
|
eventListeners: {
|
|
refresh: function(o) {
|
|
log.obj = o;
|
|
}
|
|
}
|
|
});
|
|
inRange = false;
|
|
layer.calculateInRange = function() {
|
|
return inRange;
|
|
};
|
|
|
|
log = {};
|
|
inRange = false;
|
|
layer.visibility = false;
|
|
layer.refresh(obj);
|
|
t.eq(log.obj, undefined, "[false, false] refresh not triggered");
|
|
|
|
log = {};
|
|
inRange = true;
|
|
layer.visibility = false;
|
|
layer.refresh(obj);
|
|
t.eq(log.obj, undefined, "[true, false] refresh not triggered");
|
|
|
|
log = {};
|
|
inRange = false;
|
|
layer.visibility = true;
|
|
layer.refresh(obj);
|
|
t.eq(log.obj, undefined, "[false, true] refresh not triggered");
|
|
|
|
log = {};
|
|
inRange = true;
|
|
layer.visibility = true;
|
|
layer.refresh(obj);
|
|
t.ok(log.obj === obj, "[true, true] refresh triggered with correct arg");
|
|
}
|
|
|
|
function test_Layer_Vector_addFeatures(t) {
|
|
t.plan(8);
|
|
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
|
|
var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
|
|
var pointFeature = new OpenLayers.Feature.Vector(point);
|
|
|
|
layer.preFeatureInsert = function(feature) {
|
|
t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert with the right arg");
|
|
};
|
|
layer.onFeatureInsert = function(feature) {
|
|
t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert with the right arg");
|
|
};
|
|
layer.events.register('beforefeatureadded', null, function(obj) {
|
|
t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded with correct feature passed to callback");
|
|
});
|
|
layer.events.register('featureadded', null, function(obj) {
|
|
t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers featureadded with correct feature passed to callback");
|
|
});
|
|
layer.events.register('featuresadded', null, function(obj) {
|
|
t.ok(pointFeature == obj.features[0], "OpenLayers.Layer.Vector.addFeatures triggers featuresadded with correct features passed to callback");
|
|
});
|
|
|
|
layer.addFeatures([pointFeature]);
|
|
|
|
t.eq(layer.features.length, 1, "OpenLayers.Layer.Vector.addFeatures adds something to the array");
|
|
t.ok(layer.features[0] == pointFeature, "OpenLayers.Layer.Vector.addFeatures returns an array of features");
|
|
|
|
layer.preFeatureInsert = function(feature) {
|
|
t.fail("OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert while it must not");
|
|
};
|
|
layer.onFeatureInsert = function(feature) {
|
|
t.fail("OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert while it must not");
|
|
};
|
|
layer.events.register('beforefeatureadded', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded while it must not");
|
|
});
|
|
layer.events.register('featureadded', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.addFeatures triggers featureadded while it must not");
|
|
});
|
|
layer.events.register('featuresadded', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.addFeatures triggers featuresadded while it must not");
|
|
});
|
|
|
|
layer.addFeatures([pointFeature], {silent: true});
|
|
|
|
var extent = layer.getDataExtent();
|
|
t.eq(extent.toBBOX(), "-111.04,45.68,-111.04,45.68", "extent from getDataExtent is correct");
|
|
}
|
|
|
|
function test_Layer_Vector_getFeature(t) {
|
|
t.plan(13);
|
|
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-111.04, 45.68));
|
|
|
|
t.ok(layer.getFeatureById(feature.id) == null,
|
|
"OpenLayers.Layer.Vector.getFeatureById returns null while the layer is empty");
|
|
t.ok(layer.getFeatureByFid('my_fid') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureByFid returns null while the layer is empty");
|
|
|
|
layer.addFeatures([feature]);
|
|
|
|
t.ok(layer.getFeatureByFid('my_fid') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureByFid returns null on unset feature fid");
|
|
|
|
feature.fid = 'my_fid';
|
|
|
|
t.ok(layer.getFeatureById(feature.id) == feature,
|
|
"OpenLayers.Layer.Vector.getFeatureById returns the correct feature");
|
|
t.ok(layer.getFeatureByFid(feature.fid) == feature,
|
|
"OpenLayers.Layer.Vector.getFeatureByFid returns the correct feature");
|
|
t.ok(layer.getFeatureById('some_id_that_does_not_exist') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureById returns null on non-existing feature id");
|
|
t.ok(layer.getFeatureByFid('some_fid_that_does_not_exist') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureByFid returns null on non-existing feature fid");
|
|
t.ok(layer.getFeatureById(feature.fid) == null,
|
|
"OpenLayers.Layer.Vector.getFeatureById ignores the feature fid");
|
|
t.ok(layer.getFeatureByFid(feature.id) == null,
|
|
"OpenLayers.Layer.Vector.getFeatureByFid ignores the feature id");
|
|
|
|
t.ok(layer.getFeatureBy('id', feature.id) == feature,
|
|
"OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on existing feature id");
|
|
t.ok(layer.getFeatureBy('id', 'some_id_that_does_not_exist') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on non-existing feature id");
|
|
t.ok(layer.getFeatureBy('fid', feature.fid) == feature,
|
|
"OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on existing feature fid");
|
|
t.ok(layer.getFeatureBy('fid', 'some_fid_that_does_not_exist') == null,
|
|
"OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on non-existing feature fid");
|
|
}
|
|
|
|
function test_Layer_Vector_getFeaturesByAttribute(t) {
|
|
t.plan( 9 );
|
|
// setup layer
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
|
|
// feature_1
|
|
var geometry_1 = new OpenLayers.Geometry.Point(-28.63, 153.64);
|
|
var attributes_1 = {
|
|
humpty: 'dumpty',
|
|
clazz: 1
|
|
};
|
|
var feature_1 = new OpenLayers.Feature.Vector(geometry_1, attributes_1);
|
|
feature_1.fid = 'f_01'; // to identify later
|
|
|
|
// feature_2
|
|
var geometry_2 = new OpenLayers.Geometry.Point(-27.48, 153.05);
|
|
var attributes_2 = {
|
|
// this feature has attribute humpty === undefined
|
|
clazz: '1'
|
|
};
|
|
var feature_2 = new OpenLayers.Feature.Vector(geometry_2, attributes_2);
|
|
feature_2.fid = 'f_02'; // to identify later
|
|
|
|
// feature_3
|
|
var geometry_3 = new OpenLayers.Geometry.Point(-33.74, 150.3);
|
|
var attributes_3 = {
|
|
humpty: 'foobar',
|
|
clazz: 1
|
|
};
|
|
var feature_3 = new OpenLayers.Feature.Vector(geometry_3, attributes_3);
|
|
feature_3.fid = 'f_03'; // to identify later
|
|
|
|
// Tests
|
|
|
|
// don't find anything... no features added
|
|
// 1 test
|
|
t.ok(layer.getFeaturesByAttribute('humpty', 'dumpty').length === 0,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an empty array while the layer is empty");
|
|
|
|
layer.addFeatures([feature_1, feature_2, feature_3]);
|
|
|
|
// simple use case: find 1 feature with an attribute and matching value
|
|
// 2 tests
|
|
var dumptyResults = layer.getFeaturesByAttribute('humpty', 'dumpty');
|
|
t.ok(dumptyResults.length === 1,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'humpty' with value 'dumpty'");
|
|
t.ok(dumptyResults[0].fid === 'f_01',
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'humpty' set to 'dumpty'");
|
|
|
|
// simple use case: find 1 feature with an attribute and matching value
|
|
// and respect data types
|
|
// 2 tests
|
|
var strOneResults = layer.getFeaturesByAttribute('clazz', '1');
|
|
t.ok(strOneResults.length === 1,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'clazz' with value '1' (a string)");
|
|
t.ok(strOneResults[0].fid === 'f_02',
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'clazz' set to the string '1'");
|
|
|
|
// simple use case: find 2 features with an attribute and matching value
|
|
// and respect data types
|
|
// 2 tests
|
|
var numOneResults = layer.getFeaturesByAttribute('clazz', 1);
|
|
t.ok(numOneResults.length === 2,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with two features for attribute 'clazz' with value 1 (a number)");
|
|
var bothFound = !!((numOneResults[0].fid === 'f_01' && numOneResults[1].fid === 'f_03') || (numOneResults[0].fid === 'f_03' && numOneResults[1].fid === 'f_01'));
|
|
t.ok(bothFound,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct features with attribute 'clazz' set to the number 1");
|
|
|
|
// advanced use case: find the 1 feature, that has an attribute not set
|
|
var undefined;
|
|
var humptyNotSet = layer.getFeaturesByAttribute('humpty', undefined);
|
|
t.ok(humptyNotSet.length === 1,
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute can be used to find features that have certain attributes not set");
|
|
t.ok(humptyNotSet[0].fid === 'f_02',
|
|
"OpenLayers.Layer.Vector.getFeaturesByAttribute found the correct featuren that has a certain attribute not set");
|
|
}
|
|
|
|
function test_Layer_Vector_getDataExtent(t) {
|
|
t.plan(1);
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
|
|
var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
|
|
var pointFeature = new OpenLayers.Feature.Vector(point);
|
|
layer.addFeatures([pointFeature]);
|
|
var point = new OpenLayers.Geometry.Point(-111.04, 5.68);
|
|
var pointFeature = new OpenLayers.Feature.Vector(point);
|
|
layer.addFeatures([pointFeature]);
|
|
var extent = layer.getDataExtent();
|
|
t.ok(extent.toBBOX() != layer.features[0].geometry.getBounds().toBBOX(), "extent from getDataExtent doesn't clobber first feature");
|
|
}
|
|
|
|
function test_Layer_Vector_getDataExtentEmpty(t) {
|
|
t.plan(1);
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
layer.addFeatures([new OpenLayers.Feature.Vector(null), new OpenLayers.Feature.Vector(null)]);
|
|
var extent = layer.getDataExtent();
|
|
t.eq(extent, null, "We expect null to be returned if there are no features with a geometry");
|
|
}
|
|
|
|
function test_Layer_Vector_removeFeatures(t) {
|
|
t.plan(17);
|
|
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
var features, log;
|
|
|
|
var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68);
|
|
var pointFeature1 = new OpenLayers.Feature.Vector(point1);
|
|
var point2 = new OpenLayers.Geometry.Point(-111.14, 45.78);
|
|
var pointFeature2 = new OpenLayers.Feature.Vector(point2);
|
|
|
|
// 1 test
|
|
layer.addFeatures([pointFeature1, pointFeature2]);
|
|
features = layer.removeFeatures([pointFeature1]);
|
|
t.ok(layer.features.length == 1, "OpenLayers.Layer.Vector.removeFeatures removes a feature from the features array");
|
|
|
|
// 1 test
|
|
layer.addFeatures([pointFeature1.clone(), pointFeature2.clone()]);
|
|
layer.selectedFeatures.push(layer.features[0]);
|
|
layer.removeFeatures(layer.features[0]);
|
|
t.eq(layer.selectedFeatures, [], "Remove features removes selected features");
|
|
|
|
// 1 test
|
|
features = layer.removeFeatures(layer.features);
|
|
t.ok(layer.features.length == 0,
|
|
"OpenLayers.Layer.Vector.removeFeatures(layer.features) removes all feature from the features array");
|
|
|
|
// 4 tests
|
|
log = [];
|
|
layer.addFeatures([pointFeature1, pointFeature2]);
|
|
layer.events.register("featuresremoved", null, function(obj) {
|
|
log.push(obj);
|
|
});
|
|
layer.removeFeatures(layer.features);
|
|
t.eq(log.length, 1,
|
|
"\"featuresremoved\" triggered once [0]");
|
|
t.eq(log[0].features.length, 2,
|
|
"\"featuresremoved\" listener is passed two features [0]");
|
|
t.ok(log[0].features[0] == pointFeature1,
|
|
"\"featuresremoved\" listener is passed the correct feature at index 0 [0]");
|
|
t.ok(log[0].features[1] == pointFeature2,
|
|
"\"featuresremoved\" listener is passed the correct feature at index 1 [0]");
|
|
layer.events.remove("featuresremoved");
|
|
|
|
// 4 tests
|
|
log = [];
|
|
layer.addFeatures([
|
|
pointFeature1, pointFeature2,
|
|
pointFeature1.clone(), pointFeature2.clone()
|
|
]);
|
|
layer.selectedFeatures.push(pointFeature1);
|
|
layer.selectedFeatures.push(pointFeature2);
|
|
layer.events.register("featuresremoved", null, function(obj) {
|
|
log.push(obj);
|
|
});
|
|
layer.removeFeatures(layer.selectedFeatures);
|
|
t.eq(log.length, 1,
|
|
"\"featuresremoved\" triggered once [1]");
|
|
t.eq(log[0].features.length, 2,
|
|
"\"featuresremoved\" listener is passed two features [1]");
|
|
t.ok(log[0].features[0] == pointFeature1,
|
|
"\"featuresremoved\" listener is passed the correct feature at index 0 [1]");
|
|
t.ok(log[0].features[1] == pointFeature2,
|
|
"\"featuresremoved\" listener is passed the correct feature at index 1 [1]");
|
|
layer.events.remove("featuresremoved");
|
|
layer.removeFeatures(layer.features);
|
|
|
|
// 6 tests
|
|
layer.events.register('beforefeatureremoved', null, function(obj) {
|
|
t.ok(pointFeature1 == obj.feature,
|
|
"OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved with correct feature passed to callback");
|
|
});
|
|
layer.events.register('featureremoved', null, function(obj) {
|
|
t.ok(pointFeature1 == obj.feature,
|
|
"OpenLayers.Layer.Vector.removeFeatures triggers featureremoved with correct feature passed to callback");
|
|
});
|
|
layer.events.register('featuresremoved', null, function(obj) {
|
|
t.ok(pointFeature1 == obj.features[0],
|
|
"OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved with correct features passed to callback");
|
|
});
|
|
layer.addFeatures([pointFeature1]);
|
|
layer.removeFeatures([pointFeature1]);
|
|
layer.addFeatures([pointFeature1]);
|
|
layer.removeFeatures(layer.features);
|
|
|
|
// 0 test
|
|
layer.events.register('beforefeatureremoved', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved while it must not");
|
|
});
|
|
layer.events.register('featureremoved', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featureremoved while it must not");
|
|
});
|
|
layer.events.register('featuresremoved', null, function(obj) {
|
|
t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved while it must not");
|
|
});
|
|
layer.addFeatures([pointFeature1]);
|
|
layer.removeFeatures([pointFeature1], {silent: true});
|
|
}
|
|
|
|
function test_Layer_Vector_drawFeature(t) {
|
|
t.plan(7);
|
|
var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true});
|
|
var map = new OpenLayers.Map('map', {
|
|
maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100)
|
|
});
|
|
map.addLayer(layer);
|
|
var geometry = new OpenLayers.Geometry.Point(10, 10);
|
|
var feature = new OpenLayers.Feature.Vector(geometry);
|
|
|
|
var f, s;
|
|
|
|
// Bogus layer renderer needs some methods
|
|
// for functional tests.
|
|
layer.drawn = true;
|
|
layer.renderer = {
|
|
drawFeature: function(feature, style) {
|
|
f = feature;
|
|
s = style;
|
|
},
|
|
root: document.createElement("div"),
|
|
destroy: function() { },
|
|
eraseFeatures: function() {},
|
|
setExtent: function() {}
|
|
};
|
|
|
|
|
|
layer.drawFeature(feature);
|
|
t.ok(geometry.equals(f.geometry),
|
|
"calls layer.renderer.drawFeature() with feature.geometry");
|
|
|
|
feature.style = {foo: "bar"};
|
|
layer.drawFeature(feature);
|
|
t.eq(feature.style, s,
|
|
"calls layer.renderer.drawFeature() with feature.style");
|
|
|
|
feature.style = null;
|
|
layer.style = {foo: "bar"};
|
|
layer.drawFeature(feature);
|
|
t.eq(layer.style.foo, s.foo,
|
|
"given null feature style, uses layer style");
|
|
|
|
feature.style = {foo1: "bar1"};
|
|
layer.style = {foo2: "bar2"};
|
|
var customStyle = {foo: "bar"};
|
|
layer.drawFeature(feature, customStyle);
|
|
t.eq(customStyle.foo, s.foo,
|
|
"given a custom style, renders with that");
|
|
|
|
// the real renderer's drawFeature method is tested in Renderer.html
|
|
layer.renderer.drawFeature = function(feature) {
|
|
return(feature.geometry.getBounds().intersectsBounds(map.getExtent()));
|
|
}
|
|
// reset the drawn to null as if the layer had never been rendered
|
|
layer.drawn = null;
|
|
|
|
layer.drawFeature(feature);
|
|
t.ok(true, "Trying to draw a feature on an not drawn layer doesn't throw any error.");
|
|
|
|
layer.addFeatures([feature]);
|
|
|
|
map.setCenter(new OpenLayers.Bounds(0, 0, 0, 0), 6);
|
|
t.ok(layer.unrenderedFeatures[feature.id], "Did not render feature outside the viewport.");
|
|
map.panTo(new OpenLayers.LonLat(10, 10));
|
|
t.ok(!layer.unrenderedFeatures[feature.id], "Rendered feature inside the viewport.");
|
|
|
|
layer.features = [];
|
|
}
|
|
|
|
function test_deleted_state(t) {
|
|
t.plan(9);
|
|
|
|
var map = new OpenLayers.Map("map");
|
|
var layer = new OpenLayers.Layer.Vector();
|
|
map.addLayer(layer);
|
|
var feature = new OpenLayers.Feature.Vector(
|
|
new OpenLayers.Geometry.Point(10, 10)
|
|
);
|
|
var log;
|
|
layer.renderer = {
|
|
drawFeature: function(f, s) {
|
|
log = {
|
|
feature: f,
|
|
style: s
|
|
};
|
|
},
|
|
destroy: function() {}
|
|
};
|
|
|
|
// draw feature with no state
|
|
layer.drawn = true;
|
|
layer.drawFeature(feature);
|
|
t.ok(log.feature === feature, "[no state] drawFeature called with correct feature");
|
|
t.ok(log.style.display !== "none", "[no state] drawFeature called with style display not none");
|
|
|
|
// draw feature with delete style
|
|
feature.state = OpenLayers.State.DELETE;
|
|
layer.drawFeature(feature);
|
|
t.ok(log.feature === feature, "[delete] drawFeature called with correct feature");
|
|
t.eq(log.style.display, "none", "[delete] drawFeature called with style display none");
|
|
|
|
// undelete the feature and redraw
|
|
delete feature.state;
|
|
delete feature.renderIntent;
|
|
layer.drawFeature(feature);
|
|
t.ok(log.feature === feature, "[undelete] drawFeature called with correct feature");
|
|
t.ok(log.style.display !== "none", "[undelete] drawFeature called with style display not none");
|
|
|
|
// change deleted style
|
|
layer.styleMap.styles["delete"] = new OpenLayers.Style({fillOpacity: 0.1});
|
|
|
|
// draw feature with delete style
|
|
feature.state = OpenLayers.State.DELETE;
|
|
layer.drawFeature(feature);
|
|
t.ok(log.feature === feature, "[draw deleted] drawFeature called with correct feature");
|
|
t.ok(log.style.display !== "none", "[draw deleted] drawFeature called with style display not none");
|
|
t.eq(log.style.fillOpacity, 0.1,"[draw deleted] drawFeature called with correct fill opacity");
|
|
|
|
|
|
}
|
|
|
|
function test_Layer_Vector_eraseFeatures(t) {
|
|
t.plan(2);
|
|
var layer = new OpenLayers.Layer.Vector("Test Layer");
|
|
var map = new OpenLayers.Map('map');
|
|
map.addLayer(layer);
|
|
var geometry = new OpenLayers.Geometry.Point(10, 10);
|
|
var feature = new OpenLayers.Feature.Vector(geometry);
|
|
|
|
var f;
|
|
layer.renderer = {
|
|
eraseFeatures: function(features) {
|
|
f = features[0];
|
|
},
|
|
destroy: function() { }
|
|
};
|
|
|
|
layer.eraseFeatures([feature]);
|
|
t.ok(f, "calls layer.renderer.eraseFeatures");
|
|
t.ok(geometry.equals(f.geometry),
|
|
"calls layer.renderer.eraseFeatures() given an array of features");
|
|
}
|
|
|
|
function test_Layer_Vector_destroyFeatures (t) {
|
|
t.plan(8);
|
|
var layer = new OpenLayers.Layer.Vector(name);
|
|
var map = new OpenLayers.Map('map');
|
|
map.addLayer(layer);
|
|
var features = [], i;
|
|
for (i = 0; i < 5; i++) {
|
|
features.push(new OpenLayers.Feature.Vector(
|
|
new OpenLayers.Geometry.Point(0,0)));
|
|
}
|
|
layer.addFeatures(features);
|
|
t.eq(layer.features.length, 5, "addFeatures adds 5 features");
|
|
layer.selectedFeatures.push(features[0]);
|
|
layer.destroyFeatures();
|
|
t.eq(layer.features.length, 0, "destroyFeatures triggers removal");
|
|
t.eq(layer.selectedFeatures, [], "Destroy features removes selected features");
|
|
var allDestroyed = true;
|
|
for (i = 0; i < 5; i++) {
|
|
if(features[i].geometry) {
|
|
allDestroyed = false;
|
|
}
|
|
}
|
|
t.ok(allDestroyed, "destroyFeatures actually destroys features");
|
|
features = [];
|
|
for (i = 0; i < 5; i++) {
|
|
features.push(new OpenLayers.Feature.Vector(
|
|
new OpenLayers.Geometry.Point(0,0)));
|
|
}
|
|
layer.addFeatures(features);
|
|
layer.selectedFeatures.push(features[0]);
|
|
layer.selectedFeatures.push(features[1]);
|
|
layer.destroyFeatures([features[0], features[1]]);
|
|
t.eq(layer.features.length, 3, "destroyFeatures removes appropriate features");
|
|
t.eq(layer.selectedFeatures, [], "destroyFeatures removes appropriate selected features");
|
|
t.eq(features[0].geometry, null, "destroyFeatures destroys feature 0");
|
|
t.eq(features[1].geometry, null, "destroyFeatures destroys feature 1");
|
|
}
|
|
|
|
function test_Layer_Vector_destroy (t) {
|
|
t.plan(6);
|
|
|
|
var options = {protocol: new OpenLayers.Protocol(),
|
|
strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]}
|
|
var layer = new OpenLayers.Layer.Vector(name, options);
|
|
var map = new OpenLayers.Map('map');
|
|
map.addLayer(layer);
|
|
layer.destroy();
|
|
t.eq(layer.map, null, "layer.map is null after destroy");
|
|
t.ok(!layer.renderer, "layer.renderer is falsey");
|
|
var err;
|
|
try {
|
|
layer.getFeatureFromEvent({target: "map"});
|
|
} catch (ex) {
|
|
err = ex;
|
|
}
|
|
t.ok(err, "Error thrown when calling getFeatureFromEvent on destroyed layer");
|
|
|
|
t.eq(layer.protocol, null, "layer.protocol is null after destroy");
|
|
t.eq(layer.strategies, null, "layer.strategies is null after destroy");
|
|
|
|
// test that we can call layer.destroy a second time without trouble
|
|
try {
|
|
layer.destroy();
|
|
layer.destroy();
|
|
t.ok(true, "layer.destroy called twice without any issues");
|
|
} catch(err) {
|
|
t.fail("calling layer.destroy twice triggers exception: " + err + " in " + err.fileName + " line " + err.lineNumber);
|
|
}
|
|
|
|
}
|
|
|
|
function test_Layer_Vector_clone(t) {
|
|
t.plan(5);
|
|
var original = new OpenLayers.Layer.Vector(name, {dummyOption: "foo"});
|
|
original.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2), {foo: "bar"})]);
|
|
var clone = original.clone();
|
|
t.ok(clone instanceof OpenLayers.Layer.Vector, "clone is an instance of OpenLayers.Layer.Vector");
|
|
t.ok(clone.name, original.name, "clone has the same name as the original");
|
|
t.ok(clone.features[0] != original.features[0], "clone's feature does not equal the original's feature");
|
|
t.eq(clone.features[0].attributes.foo, original.features[0].attributes.foo, "clone's feature has the same attributes as the original's feature");
|
|
t.eq(clone.dummyOption, original.dummyOption, "clone's dummyOption equals the original's dummy option");
|
|
}
|
|
|
|
function test_Layer_Vector_externalGraphic(t) {
|
|
t.plan(11);
|
|
var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true});
|
|
var renderer = layer.renderer;
|
|
var map = new OpenLayers.Map('map');
|
|
map.addLayers([layer]);
|
|
|
|
var geometryX = 10;
|
|
var geometryY = 10;
|
|
var geometry = new OpenLayers.Geometry.Point(geometryX, geometryY);
|
|
var feature = new OpenLayers.Feature.Vector(geometry);
|
|
|
|
map.zoomToMaxExtent();
|
|
|
|
var customStyle1 = new Object({
|
|
externalGraphic: 'test.png',
|
|
pointRadius: 10
|
|
});
|
|
var customStyle2 = new Object({
|
|
externalGraphic: 'test.png',
|
|
graphicWidth: 12
|
|
});
|
|
var customStyle3 = new Object({
|
|
externalGraphic: 'test.png',
|
|
graphicHeight: 14
|
|
});
|
|
var customStyle4 = new Object({
|
|
externalGraphic: 'test.png',
|
|
graphicWidth: 24,
|
|
graphicHeight: 16
|
|
});
|
|
var customStyle5 = new Object({
|
|
externalGraphic: 'test.png',
|
|
graphicWidth: 24,
|
|
graphicOpacity: 1
|
|
});
|
|
var customStyle6 = new Object({
|
|
externalGraphic: 'test.png',
|
|
graphicWidth: 24,
|
|
graphicHeight: 16,
|
|
graphicXOffset: -24,
|
|
graphicYOffset: -16
|
|
});
|
|
|
|
var root = renderer.vectorRoot;
|
|
if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') {
|
|
feature.style = customStyle1;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
(2*customStyle1.pointRadius).toString(),
|
|
"given a pointRadius, width equals 2*pointRadius");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
(2*customStyle1.pointRadius).toString(),
|
|
"given a pointRadius, height equals 2*pointRadius");
|
|
feature.style = customStyle2;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
root.firstChild.getAttributeNS(null, 'height'),
|
|
"given a graphicWidth, width equals height");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
customStyle2.graphicWidth.toString(),
|
|
"width is set correctly");
|
|
feature.style = customStyle3;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
root.firstChild.getAttributeNS(null, 'width'),
|
|
"given a graphicHeight, height equals width");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
customStyle3.graphicHeight.toString(),
|
|
"height is set correctly");
|
|
feature.style = customStyle4;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
customStyle4.graphicHeight.toString(),
|
|
"given graphicHeight and graphicWidth, both are set: height");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
customStyle4.graphicWidth.toString(),
|
|
"given graphicHeight and graphicWidth, both are set: width");
|
|
feature.style = customStyle5;
|
|
layer.drawFeature(feature);
|
|
// we use startsWith here as some browsers (at least Safari 3 and FireFox 4)
|
|
// do not append a semi-colon to the opacity string
|
|
t.ok(OpenLayers.String.startsWith(
|
|
root.firstChild.getAttributeNS(null, 'style'),
|
|
"opacity: " + customStyle5.graphicOpacity.toString()),
|
|
"graphicOpacity correctly set");
|
|
feature.style = customStyle6;
|
|
layer.drawFeature(feature);
|
|
var x = geometryX / renderer.getResolution() + renderer.left;
|
|
var y = geometryY / renderer.getResolution() - renderer.top;
|
|
// SVG setStyle() gets x and y using getAttributeNS(), which returns
|
|
// a value with only 3 decimal digits. To mimic this we use toFixed(3) here
|
|
x = x.toFixed(3);
|
|
y = y.toFixed(3);
|
|
// toFixed() returns a string
|
|
x = parseFloat(x);
|
|
y = parseFloat(y);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'x'),
|
|
(x + customStyle6.graphicXOffset).toFixed().toString(),
|
|
"graphicXOffset correctly set");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'y'),
|
|
(-y + customStyle6.graphicYOffset).toFixed().toString(),
|
|
"graphicYOffset correctly set");
|
|
}
|
|
if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG2') {
|
|
feature.style = customStyle1;
|
|
layer.drawFeature(feature);
|
|
var resolution = map.getResolution();
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
(2*customStyle1.pointRadius*resolution).toString(),
|
|
"given a pointRadius, width equals 2*pointRadius");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
(2*customStyle1.pointRadius*resolution).toString(),
|
|
"given a pointRadius, height equals 2*pointRadius");
|
|
feature.style = customStyle2;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
root.firstChild.getAttributeNS(null, 'height'),
|
|
"given a graphicWidth, width equals height");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
(customStyle2.graphicWidth*resolution).toString(),
|
|
"width is set correctly");
|
|
feature.style = customStyle3;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
root.firstChild.getAttributeNS(null, 'width'),
|
|
"given a graphicHeight, height equals width");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
(customStyle3.graphicHeight*resolution).toString(),
|
|
"height is set correctly");
|
|
feature.style = customStyle4;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'height'),
|
|
(customStyle4.graphicHeight*resolution).toString(),
|
|
"given graphicHeight and graphicWidth, both are set: height");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'width'),
|
|
(customStyle4.graphicWidth*resolution).toString(),
|
|
"given graphicHeight and graphicWidth, both are set: width");
|
|
feature.style = customStyle5;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'style'),
|
|
'opacity: '+customStyle5.graphicOpacity.toString()+((OpenLayers.Util.getBrowserName() == "opera" || OpenLayers.Util.getBrowserName() == "safari") ? "" : ';'),
|
|
"graphicOpacity correctly set");
|
|
feature.style = customStyle6;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.getAttributeNS(null, 'x'),
|
|
(geometryX + customStyle6.graphicXOffset*resolution).toString(),
|
|
"graphicXOffset correctly set");
|
|
t.eq(root.firstChild.getAttributeNS(null, 'y'),
|
|
(-geometryY + customStyle6.graphicYOffset*resolution).toString(),
|
|
"graphicYOffset correctly set");
|
|
}
|
|
if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') {
|
|
feature.style = customStyle1;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.style.width,
|
|
(2*customStyle1.pointRadius).toString()+'px',
|
|
"given a pointRadius, width equals 2*pointRadius");
|
|
t.eq(root.firstChild.style.height,
|
|
(2*customStyle1.pointRadius).toString()+'px',
|
|
"given a pointRadius, height equals 2*pointRadius");
|
|
feature.style = customStyle2;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.style.width,
|
|
root.firstChild.style.height,
|
|
"given a graphicWidth, width equals height");
|
|
t.eq(root.firstChild.style.width,
|
|
customStyle2.graphicWidth.toString()+'px',
|
|
"width is set correctly");
|
|
feature.style = customStyle3;
|
|
layer.drawFeature(feature);
|
|
t.eq(root.firstChild.style.height,
|
|
root.firstChild.style.width,
|
|
"given a graphicHeight, height equals width");
|
|
t.eq(root.firstChild.style.height,
|
|
customStyle3.graphicHeight.toString()+'px',
|
|
"height is set correctly");
|
|
feature.style = customStyle4;
|
|
layer.drawFeature(feature);
|
|
var left = parseInt(root.firstChild.style.left);
|
|
var top = parseInt(root.firstChild.style.top);
|
|
t.eq(root.firstChild.style.height,
|
|
customStyle4.graphicHeight.toString()+'px',
|
|
"given graphicHeight and graphicWidth, both are set: height");
|
|
t.eq(root.firstChild.style.width,
|
|
customStyle4.graphicWidth.toString()+'px',
|
|
"given graphicHeight and graphicWidth, both are set: width");
|
|
feature.style = customStyle5;
|
|
layer.renderer.clear();
|
|
layer.drawFeature(feature);
|
|
var fill = root.firstChild.getElementsByTagName("v:fill")[0];
|
|
var opacity;
|
|
if(fill) {
|
|
opacity = fill.getAttribute('opacity');
|
|
}
|
|
if(opacity === undefined) {
|
|
fill = root.firstChild.getElementsByTagName("fill")[0];
|
|
opacity = fill.getAttribute('opacity');
|
|
}
|
|
t.eq(opacity,
|
|
customStyle5.graphicOpacity,
|
|
"graphicOpacity correctly set");
|
|
feature.style = customStyle6;
|
|
layer.drawFeature(feature);
|
|
var offsetLeft = parseInt(root.firstChild.style.left);
|
|
var offsetTop = parseInt(root.firstChild.style.top);
|
|
t.eq((offsetLeft-left)*2, customStyle6.graphicXOffset, "graphicXOffset correctly set");
|
|
t.eq((top-offsetTop)*2, customStyle6.graphicYOffset, "graphicYOffset correctly set");
|
|
|
|
}
|
|
}
|
|
|
|
function test_removeLayer_drawFeature(t) {
|
|
// test behaviour when features are redrawn while
|
|
// the layer has been removed from the map
|
|
|
|
t.plan(1);
|
|
|
|
// set up
|
|
|
|
var map, layer, feature;
|
|
|
|
map = new OpenLayers.Map("map");
|
|
map.addLayer(new OpenLayers.Layer("base", {isBaseLayer: true}));
|
|
|
|
layer = new OpenLayers.Layer.Vector("vector");
|
|
map.addLayer(layer);
|
|
|
|
map.zoomToMaxExtent();
|
|
|
|
feature = new OpenLayers.Feature.Vector(
|
|
new OpenLayers.Geometry.Point(1.0, 1.0));
|
|
layer.addFeatures(feature);
|
|
|
|
// test
|
|
|
|
map.removeLayer(layer);
|
|
layer.drawFeature(feature);
|
|
layer.drawFeature(feature);
|
|
map.addLayer(layer);
|
|
|
|
var count = 0, node;
|
|
while(node = document.getElementById(feature.geometry.id)) {
|
|
node.parentNode.removeChild(node);
|
|
count++;
|
|
}
|
|
|
|
t.eq(count, 1, "one geometry added, one geometry removed");
|
|
|
|
// tear down
|
|
|
|
map.destroy();
|
|
}
|
|
|
|
function test_vectorBeforeFeatureAddedVeto(t) {
|
|
t.plan( 4 );
|
|
|
|
var map = new OpenLayers.Map('map');
|
|
layer = new OpenLayers.Layer.Vector("");
|
|
map.addLayer(layer);
|
|
var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0));
|
|
layer.addFeatures([feature]);
|
|
|
|
var addedFeatures = [];
|
|
var beforefeatureadded_veto = function(evt) { return false; };
|
|
layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto);
|
|
layer.events.register("featuresadded", layer, function(evt) {
|
|
if (evt.features) {
|
|
for (var i = 0; i < evt.features.length; i++) {
|
|
addedFeatures.push(evt.features[i]);
|
|
}
|
|
}
|
|
});
|
|
|
|
var blankFeatures = [
|
|
new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)),
|
|
new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0))];
|
|
layer.addFeatures(blankFeatures);
|
|
|
|
t.eq(layer.features.length, 1,
|
|
"features not added to layer after beforefeatureadded veto");
|
|
t.eq(addedFeatures.length, 0,
|
|
"no features sent to featuresadded on feature veto");
|
|
|
|
addedFeatures = [];
|
|
|
|
layer.events.unregister("beforefeatureadded", layer, beforefeatureadded_veto);
|
|
beforefeatureadded_veto = function(evt) { return true; };
|
|
layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto);
|
|
|
|
layer.addFeatures(blankFeatures);
|
|
|
|
t.eq(layer.features.length, 3,
|
|
"features added to layer as expected");
|
|
t.eq(addedFeatures.length, 2,
|
|
"featuresadded event received expected number of features");
|
|
}
|
|
|
|
|
|
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="map" style="width:500px;height:550px"></div>
|
|
</body>
|
|
</html>
|