Merge pull request #218 from openlayers/vector
Vector work. p=@tschaub,@ahocevar; r=@twpayne,@marcjansen,@bartvde
This commit is contained in:
@@ -39,7 +39,9 @@
|
||||
"disambiguate-properties": true,
|
||||
|
||||
"externs": [
|
||||
"//json.js",
|
||||
"externs/bingmaps.js",
|
||||
"externs/geojson.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js"
|
||||
],
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
"id": "ol-simple",
|
||||
|
||||
"externs": [
|
||||
"//json.js",
|
||||
"externs/bingmaps.js",
|
||||
"externs/geojson.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js"
|
||||
],
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
"disambiguate-properties": false,
|
||||
|
||||
"externs": [
|
||||
"//json.js",
|
||||
"externs/bingmaps.js",
|
||||
"externs/geojson.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js"
|
||||
],
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
"css-output-file": "build/ol.css",
|
||||
|
||||
"externs": [
|
||||
"//json.js",
|
||||
"build/src/external/externs/types.js",
|
||||
"externs/bingmaps.js",
|
||||
"externs/geojson.js",
|
||||
"externs/proj4js.js",
|
||||
"externs/tilejson.js"
|
||||
],
|
||||
|
||||
52
examples/style-rules.html
Normal file
52
examples/style-rules.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="examples.css" type="text/css">
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Style with rules example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="example-list.html">OpenLayers 3 Examples</a>
|
||||
<ul class="nav pull-right">
|
||||
<li><a href="https://github.com/openlayers/ol3"><i class="icon-github"></i></a></li>
|
||||
<li><a href="https://twitter.com/openlayers"><i class="icon-twitter"></i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span4">
|
||||
<h4 id="title">Style with rules example</h4>
|
||||
<p id="shortdesc">Draws features with rule based styles.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="style-rules.js" target="_blank">style-rules.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">vector, geojson, style</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="loader.js?id=style-rules" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
136
examples/style-rules.js
Normal file
136
examples/style-rules.js
Normal file
@@ -0,0 +1,136 @@
|
||||
goog.require('ol.Collection');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.control.defaults');
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.parser.GeoJSON');
|
||||
goog.require('ol.projection');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Line');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
var style = new ol.style.Style({rules: [
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'outer';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeColor: new ol.Expression('color'),
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
}),
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('where') == 'inner';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 4,
|
||||
opacity: 1
|
||||
}),
|
||||
new ol.style.Line({
|
||||
strokeColor: new ol.Expression('color'),
|
||||
strokeWidth: 2,
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
})
|
||||
]});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
style: style,
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.projection.get('EPSG:3857')
|
||||
})
|
||||
});
|
||||
|
||||
vector.parseFeatures({
|
||||
'type': 'FeatureCollection',
|
||||
'features': [{
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#BADA55',
|
||||
'where': 'inner'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, -10000000], [10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#BADA55',
|
||||
'where': 'inner'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, 10000000], [10000000, -10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, -10000000], [-10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[-10000000, 10000000], [10000000, 10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[10000000, 10000000], [10000000, -10000000]]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'color': '#013',
|
||||
'where': 'outer'
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [[10000000, -10000000], [-10000000, -10000000]]
|
||||
}
|
||||
}]
|
||||
}, new ol.parser.GeoJSON(), ol.projection.get('EPSG:3857'));
|
||||
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [vector],
|
||||
controls: ol.control.defaults({
|
||||
attribution: false
|
||||
}),
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: new ol.Coordinate(0, 0),
|
||||
zoom: 1
|
||||
})
|
||||
});
|
||||
52
examples/vector-layer.html
Normal file
52
examples/vector-layer.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css">
|
||||
<link rel="stylesheet" href="examples.css" type="text/css">
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap-responsive.min.css" type="text/css">
|
||||
<title>Vector layer example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="brand" href="example-list.html">OpenLayers 3 Examples</a>
|
||||
<ul class="nav pull-right">
|
||||
<li><a href="https://github.com/openlayers/ol3"><i class="icon-github"></i></a></li>
|
||||
<li><a href="https://twitter.com/openlayers"><i class="icon-twitter"></i></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
|
||||
<div class="span4">
|
||||
<h4 id="title">Vector layer example</h4>
|
||||
<p id="shortdesc">Example of a vector layer.</p>
|
||||
<div id="docs">
|
||||
<p>See the <a href="vector-layer.js" target="_blank">vector-layer.js source</a> to see how this is done.</p>
|
||||
</div>
|
||||
<div id="tags">vector, geojson, style</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="loader.js?id=vector-layer" type="text/javascript"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
71
examples/vector-layer.js
Normal file
71
examples/vector-layer.js
Normal file
@@ -0,0 +1,71 @@
|
||||
goog.require('ol.Collection');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.RendererHint');
|
||||
goog.require('ol.View2D');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.parser.GeoJSON');
|
||||
goog.require('ol.projection');
|
||||
goog.require('ol.source.MapQuestOpenAerial');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Polygon');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
var map;
|
||||
|
||||
var raster = new ol.layer.TileLayer({
|
||||
source: new ol.source.MapQuestOpenAerial()
|
||||
});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.projection.get('EPSG:4326')
|
||||
}),
|
||||
style: new ol.style.Style({rules: [
|
||||
new ol.style.Rule({
|
||||
symbolizers: [
|
||||
new ol.style.Polygon({
|
||||
strokeStyle: '#696969',
|
||||
strokeWidth: 1,
|
||||
opacity: 1.5
|
||||
})
|
||||
]
|
||||
})
|
||||
]})
|
||||
});
|
||||
|
||||
var geojson = new ol.parser.GeoJSON();
|
||||
var url = '../test/spec/ol/parser/geojson/countries.json';
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
|
||||
/**
|
||||
* onload handler for the XHR request.
|
||||
*/
|
||||
xhr.onload = function() {
|
||||
if (xhr.status == 200) {
|
||||
// this is silly to have to tell the layer the destination projection
|
||||
var projection = map.getView().getProjection();
|
||||
vector.parseFeatures(xhr.responseText, geojson, projection);
|
||||
} else {
|
||||
throw new Error('Data loading failed: ' + xhr.status);
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
|
||||
map = new ol.Map({
|
||||
layers: new ol.Collection([raster, vector]),
|
||||
renderer: ol.RendererHint.CANVAS,
|
||||
target: 'map',
|
||||
view: new ol.View2D({
|
||||
center: new ol.Coordinate(0, 0),
|
||||
zoom: 1
|
||||
})
|
||||
});
|
||||
@@ -10,13 +10,27 @@
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
var GeoJSONCRS = function() {};
|
||||
var GeoJSONObject = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
GeoJSONCRS.prototype.type;
|
||||
GeoJSONObject.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* @type {!GeoJSONCRS|undefined}
|
||||
*/
|
||||
GeoJSONObject.prototype.crs;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {GeoJSONObject}
|
||||
*/
|
||||
var GeoJSONCRS = function() {};
|
||||
|
||||
|
||||
/**
|
||||
@@ -28,18 +42,14 @@ GeoJSONCRS.prototype.properties;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {GeoJSONObject}
|
||||
*/
|
||||
var GeoJSONGeometry = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
GeoJSONGeometry.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* @type {!Array.<number>|!Array.<!Array.<number>>}
|
||||
* @type {!Array.<number>|!Array.<!Array.<number>>|
|
||||
* !Array.<!Array.<!Array.<number>>>}
|
||||
*/
|
||||
GeoJSONGeometry.prototype.coordinates;
|
||||
|
||||
@@ -47,14 +57,23 @@ GeoJSONGeometry.prototype.coordinates;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {GeoJSONObject}
|
||||
*/
|
||||
var GeoJSONFeature = function() {};
|
||||
var GeoJSONGeometryCollection = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @type {!Array.<GeoJSONGeometry>}
|
||||
*/
|
||||
GeoJSONFeature.prototype.type;
|
||||
GeoJSONGeometryCollection.prototype.geometries;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {GeoJSONObject}
|
||||
*/
|
||||
var GeoJSONFeature = function() {};
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,16 +91,11 @@ GeoJSONFeature.prototype.properties;
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {GeoJSONObject}
|
||||
*/
|
||||
var GeoJSONFeatureCollection = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
GeoJSONFeatureCollection.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* @type {!Array.<GeoJSONFeature>}
|
||||
*/
|
||||
@@ -92,15 +106,3 @@ GeoJSONFeatureCollection.prototype.features;
|
||||
* @type {!Array.<number>|undefined}
|
||||
*/
|
||||
GeoJSONFeatureCollection.prototype.bbox;
|
||||
|
||||
|
||||
/**
|
||||
* @type {!GeoJSONCRS|undefined}
|
||||
*/
|
||||
GeoJSONFeatureCollection.prototype.crs;
|
||||
|
||||
|
||||
/**
|
||||
* @type {!Object.<string, *>}
|
||||
*/
|
||||
GeoJSONFeatureCollection.prototype.properties;
|
||||
|
||||
@@ -120,6 +120,11 @@
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.resolutions Array.<number>|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.url string|undefined
|
||||
|
||||
@exportObjectLiteral ol.source.SourceOptions
|
||||
@exportObjectLiteralProperty ol.source.SourceOptions.attributions Array.<ol.Attribution>|undefined
|
||||
@exportObjectLiteralProperty ol.source.SourceOptions.extent ol.Extent|undefined
|
||||
@exportObjectLiteralProperty ol.source.SourceOptions.projection ol.Projection|undefined
|
||||
|
||||
@exportObjectLiteral ol.source.StamenOptions
|
||||
@exportObjectLiteralProperty ol.source.StamenOptions.layer string
|
||||
@exportObjectLiteralProperty ol.source.StamenOptions.minZoom number|undefined
|
||||
@@ -150,6 +155,39 @@
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.url string|undefined
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.urls Array.<string>|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.IconOptions
|
||||
@exportObjectLiteralProperty ol.style.IconOptions.url string|ol.Expression
|
||||
@exportObjectLiteralProperty ol.style.IconOptions.width number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.IconOptions.height number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.IconOptions.opacity number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.IconOptions.rotation number|ol.Expression|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.LineOptions
|
||||
@exportObjectLiteralProperty ol.style.LineOptions.strokeColor string|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.LineOptions.strokeWidth number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.LineOptions.opacity number|ol.Expression|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.PolygonOptions
|
||||
@exportObjectLiteralProperty ol.style.PolygonOptions.fillColor string|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.PolygonOptions.strokeColor string|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.PolygonOptions.strokeWidth number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.PolygonOptions.opacity number|ol.Expression|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.RuleOptions
|
||||
@exportObjectLiteralProperty ol.style.RuleOptions.filter ol.filter.Filter|undefined
|
||||
@exportObjectLiteralProperty ol.style.RuleOptions.symbolizers Array.<ol.style.Symbolizer>|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.ShapeOptions
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.type ol.style.ShapeType|undefined
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.size number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.fillColor string|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.strokeColor string|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.strokeWidth number|ol.Expression|undefined
|
||||
@exportObjectLiteralProperty ol.style.ShapeOptions.opacity number|ol.Expression|undefined
|
||||
|
||||
@exportObjectLiteral ol.style.StyleOptions
|
||||
@exportObjectLiteralProperty ol.style.StyleOptions.rules Array.<ol.style.Rule>
|
||||
|
||||
@exportObjectLiteral ol.source.WMTSOptions
|
||||
@exportObjectLiteralProperty ol.source.WMTSOptions.attributions Array.<ol.Attribution>|undefined
|
||||
@exportObjectLiteralProperty ol.source.WMTSOptions.crossOrigin string|null|undefined
|
||||
|
||||
70
src/ol/expression.js
Normal file
70
src/ol/expression.js
Normal file
@@ -0,0 +1,70 @@
|
||||
goog.provide('ol.Expression');
|
||||
goog.provide('ol.ExpressionLiteral');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {string} source Expression to be evaluated.
|
||||
*/
|
||||
ol.Expression = function(source) {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.source_ = source;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate the expression and return the result.
|
||||
*
|
||||
* @param {Object=} opt_thisArg Object to use as this when evaluating the
|
||||
* expression. If not provided, the global object will be used.
|
||||
* @param {Object=} opt_scope Evaluation scope. All properties of this object
|
||||
* will be available as variables when evaluating the expression. If not
|
||||
* provided, the global object will be used.
|
||||
* @return {*} Result of the expression.
|
||||
*/
|
||||
ol.Expression.prototype.evaluate = function(opt_thisArg, opt_scope) {
|
||||
var thisArg = goog.isDef(opt_thisArg) ? opt_thisArg : goog.global,
|
||||
scope = goog.isDef(opt_scope) ? opt_scope : goog.global,
|
||||
names = [],
|
||||
values = [];
|
||||
|
||||
for (var name in scope) {
|
||||
names.push(name);
|
||||
values.push(scope[name]);
|
||||
}
|
||||
|
||||
var evaluator = new Function(names.join(','), 'return ' + this.source_);
|
||||
return evaluator.apply(thisArg, values);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.Expression}
|
||||
* @param {*} value Literal value.
|
||||
*/
|
||||
ol.ExpressionLiteral = function(value) {
|
||||
|
||||
/**
|
||||
* @type {*}
|
||||
* @private
|
||||
*/
|
||||
this.value_ = value;
|
||||
|
||||
};
|
||||
goog.inherits(ol.ExpressionLiteral, ol.Expression);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.ExpressionLiteral.prototype.evaluate = function(opt_thisArg, opt_scope) {
|
||||
return this.value_;
|
||||
};
|
||||
7
src/ol/feature.exports
Normal file
7
src/ol/feature.exports
Normal file
@@ -0,0 +1,7 @@
|
||||
@exportSymbol ol.Feature
|
||||
@exportProperty ol.Feature.prototype.get
|
||||
@exportProperty ol.Feature.prototype.getAttributes
|
||||
@exportProperty ol.Feature.prototype.getGeometry
|
||||
@exportProperty ol.Feature.prototype.set
|
||||
@exportProperty ol.Feature.prototype.setGeometry
|
||||
@exportProperty ol.Feature.prototype.setSymbolizers
|
||||
112
src/ol/feature.js
Normal file
112
src/ol/feature.js
Normal file
@@ -0,0 +1,112 @@
|
||||
goog.provide('ol.Feature');
|
||||
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.geom.Geometry');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
* @param {Object=} opt_values Attributes.
|
||||
*/
|
||||
ol.Feature = function(opt_values) {
|
||||
|
||||
goog.base(this, opt_values);
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.geometryName_;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.style.Symbolizer>}
|
||||
* @private
|
||||
*/
|
||||
this.symbolizers_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.Feature, ol.Object);
|
||||
|
||||
|
||||
/**
|
||||
* @return {Object} Attributes object.
|
||||
*/
|
||||
ol.Feature.prototype.getAttributes = function() {
|
||||
var keys = this.getKeys(),
|
||||
len = keys.length,
|
||||
attributes = {},
|
||||
i, key;
|
||||
for (i = 0; i < len; ++ i) {
|
||||
key = keys[i];
|
||||
attributes[key] = this.get(key);
|
||||
}
|
||||
return attributes;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.Geometry} The geometry (or null if none).
|
||||
*/
|
||||
ol.Feature.prototype.getGeometry = function() {
|
||||
return goog.isDef(this.geometryName_) ?
|
||||
/** @type {ol.geom.Geometry} */ (this.get(this.geometryName_)) :
|
||||
null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.style.SymbolizerLiteral>} Symbolizer literals.
|
||||
*/
|
||||
ol.Feature.prototype.getSymbolizerLiterals = function() {
|
||||
var symbolizerLiterals = null;
|
||||
if (!goog.isNull(this.symbolizers_)) {
|
||||
var numSymbolizers = this.symbolizers_.length;
|
||||
symbolizerLiterals = new Array(numSymbolizers);
|
||||
for (var i = 0; i < numSymbolizers; ++i) {
|
||||
symbolizerLiterals[i] = this.symbolizers_[i].createLiteral(this);
|
||||
}
|
||||
}
|
||||
return symbolizerLiterals;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param {string} key Key.
|
||||
* @param {*} value Value.
|
||||
*/
|
||||
ol.Feature.prototype.set = function(key, value) {
|
||||
if (!goog.isDef(this.geometryName_) && (value instanceof ol.geom.Geometry)) {
|
||||
this.geometryName_ = key;
|
||||
}
|
||||
goog.base(this, 'set', key, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.Geometry} geometry The geometry.
|
||||
*/
|
||||
ol.Feature.prototype.setGeometry = function(geometry) {
|
||||
if (!goog.isDef(this.geometryName_)) {
|
||||
this.geometryName_ = ol.Feature.DEFAULT_GEOMETRY;
|
||||
}
|
||||
this.set(this.geometryName_, geometry);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.style.Symbolizer>} symbolizers Symbolizers for this
|
||||
* features. If set, these take precedence over layer style.
|
||||
*/
|
||||
ol.Feature.prototype.setSymbolizers = function(symbolizers) {
|
||||
this.symbolizers_ = symbolizers;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.Feature.DEFAULT_GEOMETRY = 'geometry';
|
||||
39
src/ol/filter/extentfilter.js
Normal file
39
src/ol/filter/extentfilter.js
Normal file
@@ -0,0 +1,39 @@
|
||||
goog.provide('ol.filter.Extent');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.filter.Filter');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.filter.Filter}
|
||||
* @param {ol.Extent} extent The extent.
|
||||
*/
|
||||
ol.filter.Extent = function(extent) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.extent_ = extent;
|
||||
|
||||
};
|
||||
goog.inherits(ol.filter.Extent, ol.filter.Filter);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent} The filter extent.
|
||||
*/
|
||||
ol.filter.Extent.prototype.getExtent = function() {
|
||||
return this.extent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.filter.Extent.prototype.applies = function(feature) {
|
||||
return feature.getGeometry().getBounds().intersects(this.extent_);
|
||||
};
|
||||
7
src/ol/filter/filter.exports
Normal file
7
src/ol/filter/filter.exports
Normal file
@@ -0,0 +1,7 @@
|
||||
@exportSymbol ol.filter.Filter
|
||||
@exportSymbol ol.filter.Geometry
|
||||
@exportSymbol ol.filter.Logical
|
||||
|
||||
@exportSymbol ol.filter.LogicalOperator
|
||||
@exportProperty ol.filter.LogicalOperator.AND
|
||||
@exportProperty ol.filter.LogicalOperator.OR
|
||||
24
src/ol/filter/filter.js
Normal file
24
src/ol/filter/filter.js
Normal file
@@ -0,0 +1,24 @@
|
||||
goog.provide('ol.filter.Filter');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {function(this:ol.filter.Filter, ol.Feature)=} opt_filterFunction
|
||||
* Filter function. Should return true if the passed feature passes the
|
||||
* filter, false otherwise.
|
||||
*/
|
||||
ol.filter.Filter = function(opt_filterFunction) {
|
||||
if (goog.isDef(opt_filterFunction)) {
|
||||
this.applies = opt_filterFunction;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature to evaluate the filter against.
|
||||
* @return {boolean} The provided feature passes this filter.
|
||||
*/
|
||||
ol.filter.Filter.prototype.applies = goog.abstractMethod;
|
||||
42
src/ol/filter/geometryfilter.js
Normal file
42
src/ol/filter/geometryfilter.js
Normal file
@@ -0,0 +1,42 @@
|
||||
goog.provide('ol.filter.Geometry');
|
||||
goog.provide('ol.filter.GeometryType');
|
||||
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.filter.Filter}
|
||||
* @param {ol.geom.GeometryType} type The geometry type.
|
||||
*/
|
||||
ol.filter.Geometry = function(type) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {ol.geom.GeometryType}
|
||||
* @private
|
||||
*/
|
||||
this.type_ = type;
|
||||
|
||||
};
|
||||
goog.inherits(ol.filter.Geometry, ol.filter.Filter);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.filter.Geometry.prototype.applies = function(feature) {
|
||||
var geometry = feature.getGeometry();
|
||||
return goog.isNull(geometry) ? false : geometry.getType() === this.type_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.GeometryType} The geometry type.
|
||||
*/
|
||||
ol.filter.Geometry.prototype.getType = function() {
|
||||
return this.type_;
|
||||
};
|
||||
|
||||
63
src/ol/filter/logicalfilter.js
Normal file
63
src/ol/filter/logicalfilter.js
Normal file
@@ -0,0 +1,63 @@
|
||||
goog.provide('ol.filter.Logical');
|
||||
goog.provide('ol.filter.LogicalOperator');
|
||||
|
||||
goog.require('ol.filter.Filter');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.filter.Filter}
|
||||
* @param {Array.<ol.filter.Filter>} filters Filters to and-combine.
|
||||
* @param {!ol.filter.LogicalOperator} operator Operator.
|
||||
*/
|
||||
ol.filter.Logical = function(filters, operator) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.filter.Filter>}
|
||||
* @private
|
||||
*/
|
||||
this.filters_ = filters;
|
||||
|
||||
/**
|
||||
* @type {!ol.filter.LogicalOperator}
|
||||
*/
|
||||
this.operator = operator;
|
||||
|
||||
};
|
||||
goog.inherits(ol.filter.Logical, ol.filter.Filter);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.filter.Logical.prototype.applies = function(feature) {
|
||||
var filters = this.filters_,
|
||||
i = 0, ii = filters.length,
|
||||
operator = this.operator,
|
||||
start = operator(true, false),
|
||||
result = start;
|
||||
while (result === start && i < ii) {
|
||||
result = operator(result, filters[i].applies(feature));
|
||||
++i;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.filter.Filter>} The filter's filters.
|
||||
*/
|
||||
ol.filter.Logical.prototype.getFilters = function() {
|
||||
return this.filters_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {!Function}
|
||||
*/
|
||||
ol.filter.LogicalOperator = {
|
||||
AND: /** @return {boolean} result. */ function(a, b) { return a && b; },
|
||||
OR: /** @return {boolean} result. */ function(a, b) { return a || b; }
|
||||
};
|
||||
79
src/ol/geom/abstractcollection.js
Normal file
79
src/ol/geom/abstractcollection.js
Normal file
@@ -0,0 +1,79 @@
|
||||
goog.provide('ol.geom.AbstractCollection');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A collection of geometries. This constructor is not to be used directly.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
*/
|
||||
ol.geom.AbstractCollection = function() {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Geometry>}
|
||||
*/
|
||||
this.components = null;
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @protected
|
||||
*/
|
||||
this.bounds = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.AbstractCollection, ol.geom.Geometry);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.getBounds = function() {
|
||||
if (goog.isNull(this.bounds)) {
|
||||
var minX,
|
||||
minY = minX = Number.POSITIVE_INFINITY,
|
||||
maxX,
|
||||
maxY = maxX = Number.NEGATIVE_INFINITY,
|
||||
components = this.components,
|
||||
len = components.length,
|
||||
bounds, i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
bounds = components[i].getBounds();
|
||||
minX = Math.min(bounds.minX, minX);
|
||||
minY = Math.min(bounds.minY, minY);
|
||||
maxX = Math.max(bounds.maxX, maxX);
|
||||
maxY = Math.max(bounds.maxY, maxY);
|
||||
}
|
||||
this.bounds = new ol.Extent(minX, minY, maxX, maxY);
|
||||
}
|
||||
return this.bounds;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.getCoordinates = function() {
|
||||
var count = this.components.length;
|
||||
var coordinates = new Array(count);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
coordinates[i] = this.components[i].getCoordinates();
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.getType = goog.abstractMethod;
|
||||
14
src/ol/geom/base.js
Normal file
14
src/ol/geom/base.js
Normal file
@@ -0,0 +1,14 @@
|
||||
goog.provide('ol.geom.Vertex');
|
||||
goog.provide('ol.geom.VertexArray');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Array.<number>}
|
||||
*/
|
||||
ol.geom.Vertex;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Array.<ol.geom.Vertex>}
|
||||
*/
|
||||
ol.geom.VertexArray;
|
||||
1
src/ol/geom/expression.exports
Normal file
1
src/ol/geom/expression.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.Expression
|
||||
6
src/ol/geom/geometry.exports
Normal file
6
src/ol/geom/geometry.exports
Normal file
@@ -0,0 +1,6 @@
|
||||
@exportSymbol ol.geom.Point
|
||||
@exportSymbol ol.geom.LineString
|
||||
@exportSymbol ol.geom.Polygon
|
||||
@exportSymbol ol.geom.MultiPoint
|
||||
@exportSymbol ol.geom.MultiLineString
|
||||
@exportSymbol ol.geom.MultiPolygon
|
||||
71
src/ol/geom/geometry.js
Normal file
71
src/ol/geom/geometry.js
Normal file
@@ -0,0 +1,71 @@
|
||||
goog.provide('ol.geom.Geometry');
|
||||
goog.provide('ol.geom.GeometryType');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.geom.Geometry = function() {
|
||||
|
||||
/**
|
||||
* @type {ol.geom.SharedVertices}
|
||||
* @protected
|
||||
*/
|
||||
this.vertices = null;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The dimension of this geometry (2 or 3).
|
||||
* @type {number}
|
||||
*/
|
||||
ol.geom.Geometry.prototype.dimension;
|
||||
|
||||
|
||||
/**
|
||||
* Get the rectangular 2D envelope for this geoemtry.
|
||||
* @return {ol.Extent} The bounding rectangular envelope.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getBounds = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array} The GeoJSON style coordinates array for the geometry.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getCoordinates = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Get the shared vertices for this geometry.
|
||||
* @return {ol.geom.SharedVertices} The shared vertices.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getSharedVertices = function() {
|
||||
return this.vertices;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the geometry type.
|
||||
* @return {ol.geom.GeometryType} The geometry type.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getType = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.geom.GeometryType = {
|
||||
POINT: 'point',
|
||||
LINESTRING: 'linestring',
|
||||
LINEARRING: 'linearring',
|
||||
POLYGON: 'polygon',
|
||||
MULTIPOINT: 'multipoint',
|
||||
MULTILINESTRING: 'multilinestring',
|
||||
MULTIPOLYGON: 'multipolygon',
|
||||
GEOMETRYCOLLECTION: 'geometrycollection'
|
||||
};
|
||||
48
src/ol/geom/geometrycollection.js
Normal file
48
src/ol/geom/geometrycollection.js
Normal file
@@ -0,0 +1,48 @@
|
||||
goog.provide('ol.geom.GeometryCollection');
|
||||
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A mixed collection of geometries. Used one of the fixed type multi-part
|
||||
* constructors for collections of the same type.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<ol.geom.Geometry>} geometries Array of geometries.
|
||||
*/
|
||||
ol.geom.GeometryCollection = function(geometries) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Geometry>}
|
||||
*/
|
||||
this.components = geometries;
|
||||
|
||||
var dimension = 0;
|
||||
for (var i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
if (goog.isDef(dimension)) {
|
||||
dimension = geometries[i].dimension;
|
||||
} else {
|
||||
goog.asserts.assert(dimension == geometries[i].dimension);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = dimension;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.GeometryCollection, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.GeometryCollection.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.GEOMETRYCOLLECTION;
|
||||
};
|
||||
35
src/ol/geom/linearring.js
Normal file
35
src/ol/geom/linearring.js
Normal file
@@ -0,0 +1,35 @@
|
||||
goog.provide('ol.geom.LinearRing');
|
||||
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.LineString}
|
||||
* @param {ol.geom.VertexArray} coordinates Vertex array (e.g.
|
||||
* [[x0, y0], [x1, y1]]).
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.LinearRing = function(coordinates, opt_shared) {
|
||||
goog.base(this, coordinates, opt_shared);
|
||||
|
||||
/**
|
||||
* We're intentionally not enforcing that rings be closed right now. This
|
||||
* will allow proper rendering of data from tiled vector sources that leave
|
||||
* open rings.
|
||||
*/
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.LinearRing, ol.geom.LineString);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LinearRing.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.LINEARRING;
|
||||
};
|
||||
149
src/ol/geom/linestring.js
Normal file
149
src/ol/geom/linestring.js
Normal file
@@ -0,0 +1,149 @@
|
||||
goog.provide('ol.geom.LineString');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {ol.geom.VertexArray} coordinates Vertex array (e.g.
|
||||
* [[x0, y0], [x1, y1]]).
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.LineString = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0]));
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
dimension = coordinates[0].length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.geom.SharedVertices}
|
||||
*/
|
||||
this.vertices = vertices;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.sharedId_ = vertices.add(coordinates);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
goog.asserts.assert(this.dimension >= 2);
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.bounds_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.LineString, ol.geom.Geometry);
|
||||
|
||||
|
||||
/**
|
||||
* Get a vertex coordinate value for the given dimension.
|
||||
* @param {number} index Vertex index.
|
||||
* @param {number} dim Coordinate dimension.
|
||||
* @return {number} The vertex coordinate value.
|
||||
*/
|
||||
ol.geom.LineString.prototype.get = function(index, dim) {
|
||||
return this.vertices.get(this.sharedId_, index, dim);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.geom.VertexArray} Coordinates array.
|
||||
*/
|
||||
ol.geom.LineString.prototype.getCoordinates = function() {
|
||||
var count = this.getCount();
|
||||
var coordinates = new Array(count);
|
||||
var vertex;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
vertex = new Array(this.dimension);
|
||||
for (var j = 0; j < this.dimension; ++j) {
|
||||
vertex[j] = this.get(i, j);
|
||||
}
|
||||
coordinates[i] = vertex;
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the count of vertices in this linestring.
|
||||
* @return {number} The vertex count.
|
||||
*/
|
||||
ol.geom.LineString.prototype.getCount = function() {
|
||||
return this.vertices.getCount(this.sharedId_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LineString.prototype.getBounds = function() {
|
||||
if (goog.isNull(this.bounds_)) {
|
||||
var dimension = this.dimension,
|
||||
vertices = this.vertices,
|
||||
id = this.sharedId_,
|
||||
count = vertices.getCount(id),
|
||||
start = vertices.getStart(id),
|
||||
end = start + (count * dimension),
|
||||
coordinates = vertices.coordinates,
|
||||
minX, maxX,
|
||||
minY, maxY,
|
||||
x, y, i;
|
||||
|
||||
minX = maxX = coordinates[start];
|
||||
minY = maxY = coordinates[start + 1];
|
||||
for (i = start + dimension; i < end; i += dimension) {
|
||||
x = coordinates[i];
|
||||
y = coordinates[i + 1];
|
||||
if (x < minX) {
|
||||
minX = x;
|
||||
} else if (x > maxX) {
|
||||
maxX = x;
|
||||
}
|
||||
if (y < minY) {
|
||||
minY = y;
|
||||
} else if (y > maxY) {
|
||||
maxY = y;
|
||||
}
|
||||
}
|
||||
this.bounds_ = new ol.Extent(minX, minY, maxX, maxY);
|
||||
}
|
||||
return this.bounds_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LineString.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.LINESTRING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the identifier used to mark this line in the shared vertices structure.
|
||||
* @return {number} The identifier.
|
||||
*/
|
||||
ol.geom.LineString.prototype.getSharedId = function() {
|
||||
return this.sharedId_;
|
||||
};
|
||||
72
src/ol/geom/multilinestring.js
Normal file
72
src/ol/geom/multilinestring.js
Normal file
@@ -0,0 +1,72 @@
|
||||
goog.provide('ol.geom.MultiLineString');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<ol.geom.VertexArray>} coordinates Coordinates array.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.MultiLineString = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0]));
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
// try to get dimension from first vertex in first line
|
||||
dimension = coordinates[0][0].length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LineString>}
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
this.components[i] = new ol.geom.LineString(coordinates[i], vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiLineString, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiLineString.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.MULTILINESTRING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a multi-linestring geometry from an array of linestring geometries.
|
||||
*
|
||||
* @param {Array.<ol.geom.LineString>} geometries Array of geometries.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
* @return {ol.geom.MultiLineString} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiLineString.fromParts = function(geometries, opt_shared) {
|
||||
var count = geometries.length;
|
||||
var coordinates = new Array(count);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
coordinates[i] = geometries[i].getCoordinates();
|
||||
}
|
||||
return new ol.geom.MultiLineString(coordinates, opt_shared);
|
||||
};
|
||||
77
src/ol/geom/multipoint.js
Normal file
77
src/ol/geom/multipoint.js
Normal file
@@ -0,0 +1,77 @@
|
||||
goog.provide('ol.geom.MultiPoint');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {ol.geom.VertexArray} coordinates Coordinates array.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.MultiPoint = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0]));
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
// try to get dimension from first vertex
|
||||
dimension = coordinates[0].length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.geom.SharedVertices}
|
||||
*/
|
||||
this.vertices = vertices;
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Point>}
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
this.components[i] = new ol.geom.Point(coordinates[i], vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiPoint, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiPoint.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.MULTIPOINT;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a multi-point geometry from an array of point geometries.
|
||||
*
|
||||
* @param {Array.<ol.geom.Point>} geometries Array of geometries.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
* @return {ol.geom.MultiPoint} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiPoint.fromParts = function(geometries, opt_shared) {
|
||||
var count = geometries.length;
|
||||
var coordinates = new Array(count);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
coordinates[i] = geometries[i].getCoordinates();
|
||||
}
|
||||
return new ol.geom.MultiPoint(coordinates, opt_shared);
|
||||
};
|
||||
73
src/ol/geom/multipolygon.js
Normal file
73
src/ol/geom/multipolygon.js
Normal file
@@ -0,0 +1,73 @@
|
||||
goog.provide('ol.geom.MultiPolygon');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<Array.<ol.geom.VertexArray>>} coordinates Coordinates
|
||||
* array.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.MultiPolygon = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0][0]));
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
// try to get dimension from first vertex in first ring of the first poly
|
||||
dimension = coordinates[0][0][0].length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Polygon>}
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
this.components[i] = new ol.geom.Polygon(coordinates[i], vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiPolygon, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiPolygon.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.MULTIPOLYGON;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a multi-polygon geometry from an array of polygon geometries.
|
||||
*
|
||||
* @param {Array.<ol.geom.Polygon>} geometries Array of geometries.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
* @return {ol.geom.MultiPolygon} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiPolygon.fromParts = function(geometries, opt_shared) {
|
||||
var count = geometries.length;
|
||||
var coordinates = new Array(count);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
coordinates[i] = geometries[i].getCoordinates();
|
||||
}
|
||||
return new ol.geom.MultiPolygon(coordinates, opt_shared);
|
||||
};
|
||||
105
src/ol/geom/point.js
Normal file
105
src/ol/geom/point.js
Normal file
@@ -0,0 +1,105 @@
|
||||
goog.provide('ol.geom.Point');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.Vertex');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {ol.geom.Vertex} coordinates Coordinates array (e.g. [x, y]).
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.Point = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
dimension = coordinates.length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.geom.SharedVertices}
|
||||
*/
|
||||
this.vertices = vertices;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.sharedId_ = vertices.add([coordinates]);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
goog.asserts.assert(this.dimension >= 2);
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.bounds_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.Point, ol.geom.Geometry);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} dim Coordinate dimension.
|
||||
* @return {number} The coordinate value.
|
||||
*/
|
||||
ol.geom.Point.prototype.get = function(dim) {
|
||||
return this.vertices.get(this.sharedId_, 0, dim);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Point.prototype.getBounds = function() {
|
||||
if (goog.isNull(this.bounds_)) {
|
||||
var x = this.get(0),
|
||||
y = this.get(1);
|
||||
this.bounds_ = new ol.Extent(x, y, x, y);
|
||||
}
|
||||
return this.bounds_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.geom.Vertex} Coordinates array.
|
||||
*/
|
||||
ol.geom.Point.prototype.getCoordinates = function() {
|
||||
var coordinates = new Array(this.dimension);
|
||||
for (var i = 0; i < this.dimension; ++i) {
|
||||
coordinates[i] = this.get(i);
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Point.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.POINT;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the identifier used to mark this point in the shared vertices structure.
|
||||
* @return {number} The identifier.
|
||||
*/
|
||||
ol.geom.Point.prototype.getSharedId = function() {
|
||||
return this.sharedId_;
|
||||
};
|
||||
90
src/ol/geom/polygon.js
Normal file
90
src/ol/geom/polygon.js
Normal file
@@ -0,0 +1,90 @@
|
||||
goog.provide('ol.geom.Polygon');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LinearRing');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {Array.<ol.geom.VertexArray>} coordinates Array of rings. First
|
||||
* is outer, any remaining are inner.
|
||||
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
|
||||
*/
|
||||
ol.geom.Polygon = function(coordinates, opt_shared) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0]));
|
||||
|
||||
var vertices = opt_shared,
|
||||
dimension;
|
||||
|
||||
if (!goog.isDef(vertices)) {
|
||||
// try to get dimension from first vertex in first ring
|
||||
dimension = coordinates[0][0].length;
|
||||
vertices = new ol.geom.SharedVertices({dimension: dimension});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.geom.SharedVertices}
|
||||
*/
|
||||
this.vertices = vertices;
|
||||
|
||||
var numRings = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LinearRing>}
|
||||
*/
|
||||
this.rings = new Array(numRings);
|
||||
for (var i = 0; i < numRings; ++i) {
|
||||
this.rings[i] = new ol.geom.LinearRing(coordinates[i], vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dimension = vertices.getDimension();
|
||||
goog.asserts.assert(this.dimension >= 2);
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.bounds_ = null;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.Polygon, ol.geom.Geometry);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getBounds = function() {
|
||||
return this.rings[0].getBounds();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.geom.VertexArray>} Coordinates array.
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getCoordinates = function() {
|
||||
var count = this.rings.length;
|
||||
var coordinates = new Array(count);
|
||||
for (var i = 0; i < count; ++i) {
|
||||
coordinates[i] = this.rings[i].getCoordinates();
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.POLYGON;
|
||||
};
|
||||
163
src/ol/geom/sharedvertices.js
Normal file
163
src/ol/geom/sharedvertices.js
Normal file
@@ -0,0 +1,163 @@
|
||||
goog.provide('ol.geom.SharedVertices');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('ol.geom.Vertex');
|
||||
goog.require('ol.geom.VertexArray');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{dimension: (number),
|
||||
* offset: (ol.geom.Vertex|undefined)}}
|
||||
*/
|
||||
ol.geom.SharedVerticesOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provides methods for dealing with shared, flattened arrays of vertices.
|
||||
*
|
||||
* @constructor
|
||||
* @param {ol.geom.SharedVerticesOptions=} opt_options Shared vertices options.
|
||||
*/
|
||||
ol.geom.SharedVertices = function(opt_options) {
|
||||
var options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.coordinates = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.starts_ = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.counts_ = [];
|
||||
|
||||
/**
|
||||
* Number of dimensions per vertex. Default is 2.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.dimension_ = options.dimension || 2;
|
||||
|
||||
/**
|
||||
* Vertex offset.
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.offset_ = options.offset || null;
|
||||
goog.asserts.assert(goog.isNull(this.offset_) ||
|
||||
this.offset_.length === this.dimension_);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a vertex array to the shared coordinate array.
|
||||
* @param {ol.geom.VertexArray} vertices Array of vertices.
|
||||
* @return {number} Index used to reference the added vertex array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.add = function(vertices) {
|
||||
var start = this.coordinates.length;
|
||||
var offset = this.offset_;
|
||||
var dimension = this.dimension_;
|
||||
var count = vertices.length;
|
||||
var vertex, index;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
vertex = vertices[i];
|
||||
goog.asserts.assert(vertex.length == dimension);
|
||||
if (!offset) {
|
||||
Array.prototype.push.apply(this.coordinates, vertex);
|
||||
} else {
|
||||
index = start + (i * dimension);
|
||||
for (var j = 0; j < dimension; ++j) {
|
||||
this.coordinates[index + j] = vertex[j] - offset[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
var length = this.starts_.push(start);
|
||||
this.counts_.push(count);
|
||||
return length - 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} id The vertex array identifier (returned by add).
|
||||
* @param {number} index The vertex index.
|
||||
* @param {number} dim The coordinate dimension.
|
||||
* @return {number} The coordinate value.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.get = function(id, index, dim) {
|
||||
goog.asserts.assert(id < this.starts_.length);
|
||||
goog.asserts.assert(dim <= this.dimension_);
|
||||
goog.asserts.assert(index < this.counts_[id]);
|
||||
var start = this.starts_[id];
|
||||
var value = this.coordinates[start + (index * this.dimension_) + dim];
|
||||
if (this.offset_) {
|
||||
value += this.offset_[dim];
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} id The vertex array identifier (returned by add).
|
||||
* @return {number} The number of vertices in the referenced array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getCount = function(id) {
|
||||
goog.asserts.assert(id < this.counts_.length);
|
||||
return this.counts_[id];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the array of counts. The index returned by the add method can be used
|
||||
* to look up the number of vertices.
|
||||
*
|
||||
* @return {Array.<number>} The counts array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getCounts = function() {
|
||||
return this.counts_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The dimension of each vertex in the array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getDimension = function() {
|
||||
return this.dimension_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} The offset array for vertex coordinates (or null).
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getOffset = function() {
|
||||
return this.offset_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} id The vertex array identifier (returned by add).
|
||||
* @return {number} The start index in the shared vertices array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getStart = function(id) {
|
||||
goog.asserts.assert(id < this.starts_.length);
|
||||
return this.starts_[id];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the array of start indexes.
|
||||
* @return {Array.<number>} The starts array.
|
||||
*/
|
||||
ol.geom.SharedVertices.prototype.getStarts = function() {
|
||||
return this.starts_;
|
||||
};
|
||||
|
||||
3
src/ol/layer/vectorlayer.exports
Normal file
3
src/ol/layer/vectorlayer.exports
Normal file
@@ -0,0 +1,3 @@
|
||||
@exportClass ol.layer.Vector ol.layer.LayerOptions
|
||||
|
||||
@exportProperty ol.layer.Vector.prototype.parseFeatures
|
||||
360
src/ol/layer/vectorlayer.js
Normal file
360
src/ol/layer/vectorlayer.js
Normal file
@@ -0,0 +1,360 @@
|
||||
goog.provide('ol.layer.Vector');
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.projection');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.structs.RTree');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.layer.FeatureCache = function() {
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.idLookup_;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, ol.Feature>}
|
||||
* @private
|
||||
*/
|
||||
this.geometryTypeIndex_;
|
||||
|
||||
/**
|
||||
* @type {ol.structs.RTree}
|
||||
* @private
|
||||
*/
|
||||
this.rTree_;
|
||||
|
||||
this.clear();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clear the cache.
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.clear = function() {
|
||||
this.idLookup_ = {};
|
||||
var geometryTypeIndex = {};
|
||||
for (var key in ol.geom.GeometryType) {
|
||||
geometryTypeIndex[ol.geom.GeometryType[key]] = {};
|
||||
}
|
||||
this.geometryTypeIndex_ = geometryTypeIndex;
|
||||
this.rTree_ = new ol.structs.RTree();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add a feature to the cache.
|
||||
* @param {ol.Feature} feature Feature to be cached.
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.add = function(feature) {
|
||||
var id = goog.getUid(feature).toString(),
|
||||
geometry = feature.getGeometry();
|
||||
|
||||
this.idLookup_[id] = feature;
|
||||
|
||||
// index by geometry type and bounding box
|
||||
if (!goog.isNull(geometry)) {
|
||||
var geometryType = geometry.getType();
|
||||
this.geometryTypeIndex_[geometryType][id] = feature;
|
||||
this.rTree_.put(geometry.getBounds(),
|
||||
feature, geometryType);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Object.<string, ol.Feature>} Object of features, keyed by id.
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.getFeaturesObject = function(opt_filter) {
|
||||
var i, features;
|
||||
if (!goog.isDef(opt_filter)) {
|
||||
features = this.idLookup_;
|
||||
} else {
|
||||
if (opt_filter instanceof ol.filter.Geometry) {
|
||||
features = this.geometryTypeIndex_[opt_filter.getType()];
|
||||
} else if (opt_filter instanceof ol.filter.Extent) {
|
||||
features = this.rTree_.find(opt_filter.getExtent());
|
||||
} else if (opt_filter instanceof ol.filter.Logical &&
|
||||
opt_filter.operator === ol.filter.LogicalOperator.AND) {
|
||||
var filters = opt_filter.getFilters();
|
||||
if (filters.length === 2) {
|
||||
var filter, geometryFilter, extentFilter;
|
||||
for (i = 0; i <= 1; ++i) {
|
||||
filter = filters[i];
|
||||
if (filter instanceof ol.filter.Geometry) {
|
||||
geometryFilter = filter;
|
||||
} else if (filter instanceof ol.filter.Extent) {
|
||||
extentFilter = filter;
|
||||
}
|
||||
}
|
||||
if (extentFilter && geometryFilter) {
|
||||
features = this.rTree_.find(
|
||||
extentFilter.getExtent(), geometryFilter.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!goog.isDef(features)) {
|
||||
// TODO: support fast lane for other filter types
|
||||
var candidates = this.idLookup_,
|
||||
feature;
|
||||
features = {};
|
||||
for (i in candidates) {
|
||||
feature = candidates[i];
|
||||
if (opt_filter.applies(feature) === true) {
|
||||
features[i] = feature;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Geometry} filter Geometry type filter.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.getFeaturesByGeometryType_ = function(filter) {
|
||||
return goog.object.getValues(this.geometryTypeIndex_[filter.getType()]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get features by ids.
|
||||
* @param {Array.<string>} ids Array of (internal) identifiers.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.layer.FeatureCache.prototype.getFeaturesByIds_ = function(ids) {
|
||||
var len = ids.length,
|
||||
features = new Array(len),
|
||||
i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
features[i] = this.idLookup_[ids[i]];
|
||||
}
|
||||
return features;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.layer.Layer}
|
||||
* @param {ol.layer.LayerOptions} layerOptions Layer options.
|
||||
*/
|
||||
ol.layer.Vector = function(layerOptions) {
|
||||
goog.base(this, layerOptions);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.style.Style}
|
||||
*/
|
||||
this.style_ = goog.isDef(layerOptions.style) ? layerOptions.style : null;
|
||||
|
||||
/**
|
||||
* @type {ol.layer.FeatureCache}
|
||||
* @private
|
||||
*/
|
||||
this.featureCache_ = new ol.layer.FeatureCache();
|
||||
|
||||
/**
|
||||
* TODO: this means we need to know dimension at construction
|
||||
* @type {ol.geom.SharedVertices}
|
||||
* @private
|
||||
*/
|
||||
this.pointVertices_ = new ol.geom.SharedVertices();
|
||||
|
||||
/**
|
||||
* TODO: this means we need to know dimension at construction
|
||||
* @type {ol.geom.SharedVertices}
|
||||
* @private
|
||||
*/
|
||||
this.lineVertices_ = new ol.geom.SharedVertices();
|
||||
|
||||
/**
|
||||
* TODO: this means we need to know dimension at construction
|
||||
* @type {ol.geom.SharedVertices}
|
||||
* @private
|
||||
*/
|
||||
this.polygonVertices_ = new ol.geom.SharedVertices();
|
||||
|
||||
};
|
||||
goog.inherits(ol.layer.Vector, ol.layer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.addFeatures = function(features) {
|
||||
for (var i = 0, ii = features.length; i < ii; ++i) {
|
||||
this.featureCache_.add(features[i]);
|
||||
}
|
||||
// TODO: events for real - listeners want features and extent here
|
||||
this.dispatchEvent(goog.events.EventType.CHANGE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.source.Vector} Source.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getVectorSource = function() {
|
||||
return /** @type {ol.source.Vector} */ (this.getSource());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getFeatures = function(opt_filter) {
|
||||
return goog.object.getValues(
|
||||
this.featureCache_.getFeaturesObject(opt_filter));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.filter.Filter=} opt_filter Optional filter.
|
||||
* @return {Object.<string, ol.Feature>} Features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getFeaturesObject = function(opt_filter) {
|
||||
return this.featureCache_.getFeaturesObject(opt_filter);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.SharedVertices} Shared line vertices.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getLineVertices = function() {
|
||||
return this.lineVertices_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.SharedVertices} Shared point vertices.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getPointVertices = function() {
|
||||
return this.pointVertices_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.geom.SharedVertices} Shared polygon vertices.
|
||||
*/
|
||||
ol.layer.Vector.prototype.getPolygonVertices = function() {
|
||||
return this.polygonVertices_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object.<string, ol.Feature>} features Features.
|
||||
* @return {Array.<Array>} symbolizers for features.
|
||||
*/
|
||||
ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral =
|
||||
function(features) {
|
||||
var uniqueLiterals = {},
|
||||
featuresBySymbolizer = [],
|
||||
style = this.style_,
|
||||
i, j, l, feature, literals, numLiterals, literal, uniqueLiteral, key;
|
||||
for (i in features) {
|
||||
feature = features[i];
|
||||
literals = feature.getSymbolizerLiterals();
|
||||
if (goog.isNull(literals)) {
|
||||
literals = goog.isNull(style) ?
|
||||
ol.style.Style.applyDefaultStyle(feature) :
|
||||
style.apply(feature);
|
||||
}
|
||||
numLiterals = literals.length;
|
||||
for (j = 0; j < numLiterals; ++j) {
|
||||
literal = literals[j];
|
||||
for (l in uniqueLiterals) {
|
||||
uniqueLiteral = featuresBySymbolizer[uniqueLiterals[l]][1];
|
||||
if (literal.equals(uniqueLiteral)) {
|
||||
literal = uniqueLiteral;
|
||||
break;
|
||||
}
|
||||
}
|
||||
key = goog.getUid(literal);
|
||||
if (!goog.object.containsKey(uniqueLiterals, key)) {
|
||||
uniqueLiterals[key] = featuresBySymbolizer.length;
|
||||
featuresBySymbolizer.push([[], literal]);
|
||||
}
|
||||
featuresBySymbolizer[uniqueLiterals[key]][0].push(feature);
|
||||
}
|
||||
}
|
||||
return featuresBySymbolizer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object|Element|Document|string} data Feature data.
|
||||
* @param {ol.parser.Parser} parser Feature parser.
|
||||
* @param {ol.Projection} projection This sucks. The layer should be a view in
|
||||
* one projection.
|
||||
*/
|
||||
ol.layer.Vector.prototype.parseFeatures = function(data, parser, projection) {
|
||||
var features;
|
||||
|
||||
var lookup = {
|
||||
'point': this.pointVertices_,
|
||||
'linestring': this.lineVertices_,
|
||||
'polygon': this.polygonVertices_,
|
||||
'multipoint': this.pointVertices_,
|
||||
'multilinstring': this.lineVertices_,
|
||||
'multipolygon': this.polygonVertices_
|
||||
};
|
||||
|
||||
var callback = function(feature, type) {
|
||||
return lookup[type];
|
||||
};
|
||||
if (typeof data === 'string') {
|
||||
goog.asserts.assert(typeof parser.readFeaturesFromString === 'function',
|
||||
'Expected a parser with readFeaturesFromString method.');
|
||||
features = parser.readFeaturesFromString(data, {callback: callback});
|
||||
} else if (typeof data === 'object') {
|
||||
goog.asserts.assert(typeof parser.readFeaturesFromObject === 'function',
|
||||
'Expected a parser with a readFeaturesFromObject method.');
|
||||
features = parser.readFeaturesFromObject(data, {callback: callback});
|
||||
} else {
|
||||
// TODO: parse more data types
|
||||
throw new Error('Data type not supported: ' + data);
|
||||
}
|
||||
var sourceProjection = this.getSource().getProjection();
|
||||
var transform = ol.projection.getTransform(sourceProjection, projection);
|
||||
|
||||
transform(
|
||||
this.pointVertices_.coordinates,
|
||||
this.pointVertices_.coordinates,
|
||||
this.pointVertices_.getDimension());
|
||||
|
||||
transform(
|
||||
this.lineVertices_.coordinates,
|
||||
this.lineVertices_.coordinates,
|
||||
this.lineVertices_.getDimension());
|
||||
|
||||
transform(
|
||||
this.polygonVertices_.coordinates,
|
||||
this.polygonVertices_.coordinates,
|
||||
this.polygonVertices_.getDimension());
|
||||
|
||||
this.addFeatures(features);
|
||||
};
|
||||
|
||||
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
66
src/ol/parser/featureparser.js
Normal file
66
src/ol/parser/featureparser.js
Normal file
@@ -0,0 +1,66 @@
|
||||
goog.provide('ol.parser.DomFeatureParser');
|
||||
goog.provide('ol.parser.ObjectFeatureParser');
|
||||
goog.provide('ol.parser.ReadFeaturesOptions');
|
||||
goog.provide('ol.parser.StringFeatureParser');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
ol.parser.DomFeatureParser = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Element|Document} node Document or element node.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.parser.DomFeatureParser.prototype.readFeaturesFromNode =
|
||||
goog.abstractMethod;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
ol.parser.ObjectFeatureParser = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object} obj Object representing features.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.parser.ObjectFeatureParser.prototype.readFeaturesFromObject =
|
||||
goog.abstractMethod;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
ol.parser.StringFeatureParser = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} data String data.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Feature reading options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.parser.StringFeatureParser.prototype.readFeaturesFromString =
|
||||
goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(ol.Feature, ol.geom.GeometryType):ol.geom.SharedVertices}
|
||||
*/
|
||||
ol.parser.ReadFeaturesCallback;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{callback: ol.parser.ReadFeaturesCallback}}
|
||||
*/
|
||||
ol.parser.ReadFeaturesOptions;
|
||||
3
src/ol/parser/geojson.exports
Normal file
3
src/ol/parser/geojson.exports
Normal file
@@ -0,0 +1,3 @@
|
||||
@exportSymbol ol.parser.GeoJSON
|
||||
|
||||
@exportProperty ol.parser.GeoJSON.prototype.read
|
||||
285
src/ol/parser/geojson.js
Normal file
285
src/ol/parser/geojson.js
Normal file
@@ -0,0 +1,285 @@
|
||||
goog.provide('ol.parser.GeoJSON');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.MultiLineString');
|
||||
goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.parser.Parser');
|
||||
goog.require('ol.parser.ReadFeaturesOptions');
|
||||
goog.require('ol.parser.StringFeatureParser');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {ol.parser.StringFeatureParser}
|
||||
* @extends {ol.parser.Parser}
|
||||
*/
|
||||
ol.parser.GeoJSON = function() {};
|
||||
goog.inherits(ol.parser.GeoJSON, ol.parser.Parser);
|
||||
|
||||
|
||||
/**
|
||||
* Parse a GeoJSON string.
|
||||
* @param {string} str GeoJSON string.
|
||||
* @return {ol.Feature|Array.<ol.Feature>|
|
||||
* ol.geom.Geometry|Array.<ol.geom.Geometry>} Parsed geometry or array
|
||||
* of geometries.
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.read = function(str) {
|
||||
var json = /** @type {GeoJSONObject} */ (JSON.parse(str));
|
||||
return this.parse_(json);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse a GeoJSON feature collection.
|
||||
* @param {string} str GeoJSON feature collection.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Reader options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.readFeaturesFromString =
|
||||
function(str, opt_options) {
|
||||
var json = /** @type {GeoJSONFeatureCollection} */ (JSON.parse(str));
|
||||
return this.parseFeatureCollection_(json, opt_options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse a GeoJSON feature collection from decoded JSON.
|
||||
* @param {GeoJSONFeatureCollection} object GeoJSON feature collection decoded
|
||||
* from JSON.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Reader options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.readFeaturesFromObject =
|
||||
function(object, opt_options) {
|
||||
return this.parseFeatureCollection_(object, opt_options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONObject} json GeoJSON object.
|
||||
* @return {ol.Feature|Array.<ol.Feature>|
|
||||
* ol.geom.Geometry|Array.<ol.geom.Geometry>} Parsed geometry or array
|
||||
* of geometries.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parse_ = function(json) {
|
||||
var result;
|
||||
switch (json.type) {
|
||||
case 'FeatureCollection':
|
||||
result = this.parseFeatureCollection_(
|
||||
/** @type {GeoJSONFeatureCollection} */ (json));
|
||||
break;
|
||||
case 'Feature':
|
||||
result = this.parseFeature_(
|
||||
/** @type {GeoJSONFeature} */ (json));
|
||||
break;
|
||||
case 'GeometryCollection':
|
||||
result = this.parseGeometryCollection_(
|
||||
/** @type {GeoJSONGeometryCollection} */ (json));
|
||||
break;
|
||||
case 'Point':
|
||||
result = this.parsePoint_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
case 'LineString':
|
||||
result = this.parseLineString_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
case 'Polygon':
|
||||
result = this.parsePolygon_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
case 'MultiPoint':
|
||||
result = this.parseMultiPoint_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
case 'MultiLineString':
|
||||
result = this.parseMultiLineString_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
case 'MultiPolygon':
|
||||
result = this.parseMultiPolygon_(
|
||||
/** @type {GeoJSONGeometry} */ (json));
|
||||
break;
|
||||
default:
|
||||
throw new Error('GeoJSON parsing not implemented for type: ' + json.type);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONFeature} json GeoJSON feature.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Read options.
|
||||
* @return {ol.Feature} Parsed feature.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseFeature_ = function(json, opt_options) {
|
||||
var geomJson = json.geometry,
|
||||
geometry = null,
|
||||
options = opt_options || {};
|
||||
var feature = new ol.Feature(json.properties);
|
||||
if (geomJson) {
|
||||
var type = geomJson.type;
|
||||
var callback = options.callback;
|
||||
var sharedVertices;
|
||||
if (callback) {
|
||||
goog.asserts.assert(type in ol.parser.GeoJSON.GeometryType,
|
||||
'Bad geometry type: ' + type);
|
||||
sharedVertices = callback(feature, ol.parser.GeoJSON.GeometryType[type]);
|
||||
}
|
||||
switch (type) {
|
||||
case 'Point':
|
||||
geometry = this.parsePoint_(geomJson, sharedVertices);
|
||||
break;
|
||||
case 'LineString':
|
||||
geometry = this.parseLineString_(geomJson, sharedVertices);
|
||||
break;
|
||||
case 'Polygon':
|
||||
geometry = this.parsePolygon_(geomJson, sharedVertices);
|
||||
break;
|
||||
case 'MultiPoint':
|
||||
geometry = this.parseMultiPoint_(geomJson, sharedVertices);
|
||||
break;
|
||||
case 'MultiLineString':
|
||||
geometry = this.parseMultiLineString_(geomJson, sharedVertices);
|
||||
break;
|
||||
case 'MultiPolygon':
|
||||
geometry = this.parseMultiPolygon_(geomJson, sharedVertices);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Bad geometry type: ' + type);
|
||||
}
|
||||
feature.setGeometry(geometry);
|
||||
}
|
||||
return feature;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONFeatureCollection} json GeoJSON feature collection.
|
||||
* @param {ol.parser.ReadFeaturesOptions=} opt_options Read options.
|
||||
* @return {Array.<ol.Feature>} Parsed array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseFeatureCollection_ = function(
|
||||
json, opt_options) {
|
||||
var features = json.features,
|
||||
len = features.length,
|
||||
result = new Array(len),
|
||||
i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
result[i] = this.parseFeature_(
|
||||
/** @type {GeoJSONFeature} */ (features[i]), opt_options);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometryCollection} json GeoJSON geometry collection.
|
||||
* @return {Array.<ol.geom.Geometry>} Parsed array of geometries.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseGeometryCollection_ = function(json) {
|
||||
var geometries = json.geometries,
|
||||
len = geometries.length,
|
||||
result = new Array(len),
|
||||
i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
result[i] = this.parse_(/** @type {GeoJSONGeometry} */ (geometries[i]));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON linestring.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.LineString} Parsed linestring.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseLineString_ = function(json, opt_vertices) {
|
||||
return new ol.geom.LineString(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON multi-linestring.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.MultiLineString} Parsed multi-linestring.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseMultiLineString_ = function(
|
||||
json, opt_vertices) {
|
||||
return new ol.geom.MultiLineString(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON multi-point.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.MultiPoint} Parsed multi-point.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseMultiPoint_ = function(json, opt_vertices) {
|
||||
return new ol.geom.MultiPoint(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON multi-polygon.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.MultiPolygon} Parsed multi-polygon.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parseMultiPolygon_ = function(json, opt_vertices) {
|
||||
return new ol.geom.MultiPolygon(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON point.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.Point} Parsed point.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parsePoint_ = function(json, opt_vertices) {
|
||||
return new ol.geom.Point(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {GeoJSONGeometry} json GeoJSON polygon.
|
||||
* @param {ol.geom.SharedVertices=} opt_vertices Shared vertices.
|
||||
* @return {ol.geom.Polygon} Parsed polygon.
|
||||
* @private
|
||||
*/
|
||||
ol.parser.GeoJSON.prototype.parsePolygon_ = function(json, opt_vertices) {
|
||||
return new ol.geom.Polygon(json.coordinates, opt_vertices);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {ol.geom.GeometryType}
|
||||
*/
|
||||
ol.parser.GeoJSON.GeometryType = {
|
||||
'Point': ol.geom.GeometryType.POINT,
|
||||
'LineString': ol.geom.GeometryType.LINESTRING,
|
||||
'Polygon': ol.geom.GeometryType.POLYGON,
|
||||
'MultiPoint': ol.geom.GeometryType.MULTIPOINT,
|
||||
'MultiLineString': ol.geom.GeometryType.MULTILINESTRING,
|
||||
'MultiPolygon': ol.geom.GeometryType.MULTIPOLYGON,
|
||||
'GeometryCollection': ol.geom.GeometryType.GEOMETRYCOLLECTION
|
||||
};
|
||||
8
src/ol/parser/parser.js
Normal file
8
src/ol/parser/parser.js
Normal file
@@ -0,0 +1,8 @@
|
||||
goog.provide('ol.parser.Parser');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.parser.Parser = function() {};
|
||||
@@ -1,9 +1,12 @@
|
||||
goog.provide('ol.parser.XML');
|
||||
|
||||
goog.require('ol.parser.Parser');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.parser.Parser}
|
||||
*/
|
||||
ol.parser.XML = function() {
|
||||
this.regExes = {
|
||||
@@ -13,6 +16,7 @@ ol.parser.XML = function() {
|
||||
trimComma: (/\s*,\s*/g)
|
||||
};
|
||||
};
|
||||
goog.inherits(ol.parser.XML, ol.parser.Parser);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,9 +10,11 @@ goog.require('ol');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.ImageLayer');
|
||||
goog.require('ol.renderer.canvas.TileLayer');
|
||||
goog.require('ol.renderer.canvas.VectorLayer');
|
||||
|
||||
|
||||
|
||||
@@ -66,6 +68,8 @@ ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) {
|
||||
return new ol.renderer.canvas.ImageLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.TileLayer) {
|
||||
return new ol.renderer.canvas.TileLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.Vector) {
|
||||
return new ol.renderer.canvas.VectorLayer(this, layer);
|
||||
} else {
|
||||
goog.asserts.assert(false);
|
||||
return null;
|
||||
@@ -111,6 +115,8 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
|
||||
context.globalAlpha = 1;
|
||||
context.fillRect(0, 0, size.width, size.height);
|
||||
|
||||
this.calculateMatrices2D(frameState);
|
||||
|
||||
goog.array.forEach(frameState.layersArray, function(layer) {
|
||||
|
||||
var layerState = frameState.layerStates[goog.getUid(layer)];
|
||||
@@ -145,6 +151,4 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
|
||||
this.renderedVisible_ = true;
|
||||
}
|
||||
|
||||
this.calculateMatrices2D(frameState);
|
||||
|
||||
};
|
||||
|
||||
404
src/ol/renderer/canvas/canvasvectorlayerrenderer.js
Normal file
404
src/ol/renderer/canvas/canvasvectorlayerrenderer.js
Normal file
@@ -0,0 +1,404 @@
|
||||
goog.provide('ol.renderer.canvas.VectorLayer');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.TileCache');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
goog.require('ol.renderer.canvas.VectorRenderer');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.canvas.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.Vector} layer Vector layer.
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) {
|
||||
|
||||
goog.base(this, mapRenderer, layer);
|
||||
|
||||
/**
|
||||
* Final canvas made available to the map renderer.
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.canvas_ = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context_ = /** @type {CanvasRenderingContext2D} */
|
||||
this.canvas_.getContext('2d');
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* Interim canvas for drawing newly visible features.
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.sketchCanvas_ = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.sketchTransform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileCache}
|
||||
*/
|
||||
this.tileCache_ = new ol.TileCache(
|
||||
ol.renderer.canvas.VectorLayer.TILECACHE_SIZE);
|
||||
// TODO: this is far too coarse, we want extent of added features
|
||||
goog.events.listenOnce(layer, goog.events.EventType.CHANGE,
|
||||
this.handleLayerChange_, false, this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.tileArchetype_ = null;
|
||||
|
||||
/**
|
||||
* Geometry filters in rendering order.
|
||||
* @private
|
||||
* @type {Array.<ol.filter.Geometry>}
|
||||
* TODO: these will go away shortly (in favor of one call per symbolizer type)
|
||||
*/
|
||||
this.geometryFilters_ = [
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.POINT),
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.MULTIPOINT),
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.LINESTRING),
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.MULTILINESTRING),
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.POLYGON),
|
||||
new ol.filter.Geometry(ol.geom.GeometryType.MULTIPOLYGON)
|
||||
];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.renderedResolution_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.renderedExtent_ = null;
|
||||
|
||||
/**
|
||||
* Flag to be set internally when we know something has changed that suggests
|
||||
* we need to re-render.
|
||||
* TODO: discuss setting this for all layers when something changes before
|
||||
* calling map.render().
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.dirty_ = false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.pendingCachePrune_ = false;
|
||||
|
||||
/**
|
||||
* Grid used for internal generation of canvas tiles. This is created
|
||||
* lazily so we have access to the view projection.
|
||||
*
|
||||
* @private
|
||||
* @type {ol.tilegrid.TileGrid}
|
||||
*/
|
||||
this.tileGrid_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {function()}
|
||||
*/
|
||||
this.requestMapRenderFrame_ = goog.bind(function() {
|
||||
this.dirty_ = true;
|
||||
mapRenderer.getMap().requestRenderFrame();
|
||||
}, this);
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.VectorLayer, ol.renderer.canvas.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* Get rid cached tiles. If the optional extent is provided, only tiles that
|
||||
* intersect that extent will be removed.
|
||||
* @param {ol.Extent=} opt_extent extent Expire tiles within this extent only.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.expireTiles_ = function(opt_extent) {
|
||||
if (goog.isDef(opt_extent)) {
|
||||
// TODO: implement this
|
||||
}
|
||||
this.tileCache_.clear();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.getImage = function() {
|
||||
return this.canvas_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.Vector} Vector layer.
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.getVectorLayer = function() {
|
||||
return /** @type {ol.layer.Vector} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.getTransform = function() {
|
||||
return this.transform_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.events.Event} event Layer change event.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.handleLayerChange_ = function(event) {
|
||||
// TODO: get rid of this in favor of vector specific events
|
||||
this.expireTiles_();
|
||||
this.requestMapRenderFrame_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
// TODO: consider bailing out here if rendered center and resolution
|
||||
// have not changed. Requires that other change listeners set a dirty flag.
|
||||
|
||||
var view2DState = frameState.view2DState,
|
||||
resolution = view2DState.resolution,
|
||||
extent = frameState.extent,
|
||||
layer = this.getVectorLayer(),
|
||||
tileGrid = this.tileGrid_;
|
||||
|
||||
if (goog.isNull(tileGrid)) {
|
||||
// lazy tile grid creation to match the view projection
|
||||
tileGrid = ol.tilegrid.createForProjection(
|
||||
view2DState.projection,
|
||||
22, // should be no harm in going big here - ideally, it would be ∞
|
||||
new ol.Size(512, 512));
|
||||
this.tileGrid_ = tileGrid;
|
||||
}
|
||||
|
||||
// set up transform for the layer canvas to be drawn to the map canvas
|
||||
var z = tileGrid.getZForResolution(resolution),
|
||||
tileResolution = tileGrid.getResolution(z),
|
||||
tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
extent, tileResolution),
|
||||
tileRangeExtent = tileGrid.getTileRangeExtent(z, tileRange),
|
||||
tileSize = tileGrid.getTileSize(z),
|
||||
sketchOrigin = tileRangeExtent.getTopLeft(),
|
||||
transform = this.transform_;
|
||||
|
||||
goog.vec.Mat4.makeIdentity(transform);
|
||||
goog.vec.Mat4.translate(transform,
|
||||
frameState.size.width / 2,
|
||||
frameState.size.height / 2,
|
||||
0);
|
||||
goog.vec.Mat4.scale(transform,
|
||||
tileResolution / resolution, tileResolution / resolution, 1);
|
||||
goog.vec.Mat4.rotateZ(transform, view2DState.rotation);
|
||||
goog.vec.Mat4.translate(transform,
|
||||
(sketchOrigin.x - view2DState.center.x) / tileResolution,
|
||||
(view2DState.center.y - sketchOrigin.y) / tileResolution,
|
||||
0);
|
||||
|
||||
/**
|
||||
* Fastest path out of here. This method is called many many times while
|
||||
* there is nothing to do (e.g. while waiting for tiles from every other
|
||||
* layer to load.) Do not put anything above here that is more expensive than
|
||||
* necessary. And look for ways to get here faster.
|
||||
*/
|
||||
if (!this.dirty_ && this.renderedResolution_ === tileResolution &&
|
||||
// TODO: extent.equals()
|
||||
this.renderedExtent_.toString() === tileRangeExtent.toString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (goog.isNull(this.tileArchetype_)) {
|
||||
this.tileArchetype_ = /** @type {HTMLCanvasElement} */
|
||||
goog.dom.createElement(goog.dom.TagName.CANVAS);
|
||||
this.tileArchetype_.width = tileSize.width;
|
||||
this.tileArchetype_.height = tileSize.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the sketch canvas. This covers the currently visible tile range
|
||||
* and will have rendered all newly visible features.
|
||||
*/
|
||||
var sketchCanvas = this.sketchCanvas_;
|
||||
var sketchSize = new ol.Size(
|
||||
tileSize.width * tileRange.getWidth(),
|
||||
tileSize.height * tileRange.getHeight());
|
||||
|
||||
// transform for map coords to sketch canvas pixel coords
|
||||
var sketchTransform = this.sketchTransform_;
|
||||
var halfWidth = sketchSize.width / 2;
|
||||
var halfHeight = sketchSize.height / 2;
|
||||
goog.vec.Mat4.makeIdentity(sketchTransform);
|
||||
goog.vec.Mat4.translate(sketchTransform,
|
||||
halfWidth,
|
||||
halfHeight,
|
||||
0);
|
||||
goog.vec.Mat4.scale(sketchTransform,
|
||||
1 / tileResolution,
|
||||
-1 / tileResolution,
|
||||
1);
|
||||
goog.vec.Mat4.translate(sketchTransform,
|
||||
-(sketchOrigin.x + halfWidth * tileResolution),
|
||||
-(sketchOrigin.y - halfHeight * tileResolution),
|
||||
0);
|
||||
|
||||
// clear/resize sketch canvas
|
||||
sketchCanvas.width = sketchSize.width;
|
||||
sketchCanvas.height = sketchSize.height;
|
||||
|
||||
var sketchCanvasRenderer = new ol.renderer.canvas.VectorRenderer(
|
||||
sketchCanvas, sketchTransform, undefined, this.requestMapRenderFrame_);
|
||||
|
||||
// clear/resize final canvas
|
||||
var finalCanvas = this.canvas_;
|
||||
finalCanvas.width = sketchSize.width;
|
||||
finalCanvas.height = sketchSize.height;
|
||||
var finalContext = this.context_;
|
||||
|
||||
var featuresToRender = {};
|
||||
var tilesToRender = {};
|
||||
var tilesOnSketchCanvas = {};
|
||||
// TODO make gutter configurable?
|
||||
var tileGutter = 15 * tileResolution;
|
||||
var tile, tileCoord, key, tileState, x, y;
|
||||
// render features by geometry type
|
||||
var filters = this.geometryFilters_,
|
||||
numFilters = filters.length,
|
||||
deferred = false,
|
||||
i, geomFilter, tileExtent, extentFilter, type,
|
||||
groups, group, j, numGroups;
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
tileCoord = new ol.TileCoord(z, x, y);
|
||||
key = tileCoord.toString();
|
||||
if (this.tileCache_.containsKey(key)) {
|
||||
tilesToRender[key] = tileCoord;
|
||||
} else if (!frameState.viewHints[ol.ViewHint.ANIMATING]) {
|
||||
tileExtent = tileGrid.getTileCoordExtent(tileCoord);
|
||||
tileExtent.minX -= tileGutter;
|
||||
tileExtent.minY -= tileGutter;
|
||||
tileExtent.maxX += tileGutter;
|
||||
tileExtent.maxY += tileGutter;
|
||||
extentFilter = new ol.filter.Extent(tileExtent);
|
||||
for (i = 0; i < numFilters; ++i) {
|
||||
geomFilter = filters[i];
|
||||
type = geomFilter.getType();
|
||||
if (!goog.isDef(featuresToRender[type])) {
|
||||
featuresToRender[type] = {};
|
||||
}
|
||||
goog.object.extend(featuresToRender[type],
|
||||
layer.getFeaturesObject(new ol.filter.Logical(
|
||||
[geomFilter, extentFilter], ol.filter.LogicalOperator.AND)));
|
||||
}
|
||||
tilesOnSketchCanvas[key] = tileCoord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (type in featuresToRender) {
|
||||
groups = layer.groupFeaturesBySymbolizerLiteral(featuresToRender[type]);
|
||||
numGroups = groups.length;
|
||||
for (j = 0; j < numGroups; ++j) {
|
||||
group = groups[j];
|
||||
deferred = sketchCanvasRenderer.renderFeaturesByGeometryType(
|
||||
/** @type {ol.geom.GeometryType} */ (type),
|
||||
group[0], group[1]);
|
||||
if (deferred) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!deferred) {
|
||||
goog.object.extend(tilesToRender, tilesOnSketchCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
this.dirty_ = true;
|
||||
for (key in tilesToRender) {
|
||||
tileCoord = tilesToRender[key];
|
||||
if (this.tileCache_.containsKey(key)) {
|
||||
tile = /** @type {HTMLCanvasElement} */ (this.tileCache_.get(key));
|
||||
} else {
|
||||
tile = /** @type {HTMLCanvasElement} */
|
||||
this.tileArchetype_.cloneNode(false);
|
||||
tile.getContext('2d').drawImage(sketchCanvas,
|
||||
(tileRange.minX - tileCoord.x) * tileSize.width,
|
||||
(tileCoord.y - tileRange.maxY) * tileSize.height);
|
||||
this.tileCache_.set(key, tile);
|
||||
}
|
||||
finalContext.drawImage(tile,
|
||||
tileSize.width * (tileCoord.x - tileRange.minX),
|
||||
tileSize.height * (tileRange.maxY - tileCoord.y));
|
||||
this.dirty_ = false;
|
||||
}
|
||||
|
||||
this.renderedResolution_ = tileResolution;
|
||||
this.renderedExtent_ = tileRangeExtent;
|
||||
if (!this.pendingCachePrune_) {
|
||||
this.pendingCachePrune_ = true;
|
||||
frameState.postRenderFunctions.push(goog.bind(this.pruneTileCache_, this));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get rid of tiles that exceed the cache capacity.
|
||||
* TODO: add a method to the cache to handle this
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.prototype.pruneTileCache_ = function() {
|
||||
while (this.tileCache_.canExpireCache()) {
|
||||
this.tileCache_.pop();
|
||||
}
|
||||
this.pendingCachePrune_ = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
ol.renderer.canvas.VectorLayer.TILECACHE_SIZE = 128;
|
||||
441
src/ol/renderer/canvas/canvasvectorrenderer.js
Normal file
441
src/ol/renderer/canvas/canvasvectorrenderer.js
Normal file
@@ -0,0 +1,441 @@
|
||||
goog.provide('ol.renderer.canvas.VectorRenderer');
|
||||
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.net.ImageLoader');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Pixel');
|
||||
goog.require('ol.canvas');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.MultiLineString');
|
||||
goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.style.IconLiteral');
|
||||
goog.require('ol.style.LineLiteral');
|
||||
goog.require('ol.style.PointLiteral');
|
||||
goog.require('ol.style.PolygonLiteral');
|
||||
goog.require('ol.style.ShapeLiteral');
|
||||
goog.require('ol.style.ShapeType');
|
||||
goog.require('ol.style.SymbolizerLiteral');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {HTMLCanvasElement} canvas Target canvas.
|
||||
* @param {goog.vec.Mat4.Number} transform Transform.
|
||||
* @param {ol.Pixel=} opt_offset Pixel offset for top-left corner. This is
|
||||
* provided as an optional argument as a convenience in cases where the
|
||||
* transform applies to a separate canvas.
|
||||
* @param {function()=} opt_iconLoadedCallback Callback for deferred rendering
|
||||
* when images need to be loaded before rendering.
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer =
|
||||
function(canvas, transform, opt_offset, opt_iconLoadedCallback) {
|
||||
|
||||
var context = /** @type {CanvasRenderingContext2D} */
|
||||
(canvas.getContext('2d')),
|
||||
dx = goog.isDef(opt_offset) ? opt_offset.x : 0,
|
||||
dy = goog.isDef(opt_offset) ? opt_offset.y : 0;
|
||||
|
||||
/**
|
||||
* @type {goog.vec.Mat4.Number}
|
||||
* @private
|
||||
*/
|
||||
this.transform_ = transform;
|
||||
context.setTransform(
|
||||
goog.vec.Mat4.getElement(transform, 0, 0),
|
||||
goog.vec.Mat4.getElement(transform, 1, 0),
|
||||
goog.vec.Mat4.getElement(transform, 0, 1),
|
||||
goog.vec.Mat4.getElement(transform, 1, 1),
|
||||
goog.vec.Mat4.getElement(transform, 0, 3) + dx,
|
||||
goog.vec.Mat4.getElement(transform, 1, 3) + dy);
|
||||
|
||||
var vec = [1, 0, 0];
|
||||
goog.vec.Mat4.multVec3NoTranslate(transform, vec, vec);
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.inverseScale_ = 1 / Math.sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
|
||||
|
||||
/**
|
||||
* @type {CanvasRenderingContext2D}
|
||||
* @private
|
||||
*/
|
||||
this.context_ = context;
|
||||
|
||||
/**
|
||||
* @type {function()|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.iconLoadedCallback_ = opt_iconLoadedCallback;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.GeometryType} type Geometry type.
|
||||
* @param {Array.<ol.Feature>} features Array of features.
|
||||
* @param {ol.style.SymbolizerLiteral} symbolizer Symbolizer.
|
||||
* @return {boolean} true if deferred, false if rendered.
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.prototype.renderFeaturesByGeometryType =
|
||||
function(type, features, symbolizer) {
|
||||
var deferred = false;
|
||||
switch (type) {
|
||||
case ol.geom.GeometryType.POINT:
|
||||
case ol.geom.GeometryType.MULTIPOINT:
|
||||
goog.asserts.assert(symbolizer instanceof ol.style.PointLiteral,
|
||||
'Expected point symbolizer: ' + symbolizer);
|
||||
deferred = this.renderPointFeatures_(
|
||||
features, /** @type {ol.style.PointLiteral} */ (symbolizer));
|
||||
break;
|
||||
case ol.geom.GeometryType.LINESTRING:
|
||||
case ol.geom.GeometryType.MULTILINESTRING:
|
||||
goog.asserts.assert(symbolizer instanceof ol.style.LineLiteral,
|
||||
'Expected line symbolizer: ' + symbolizer);
|
||||
this.renderLineStringFeatures_(
|
||||
features, /** @type {ol.style.LineLiteral} */ (symbolizer));
|
||||
break;
|
||||
case ol.geom.GeometryType.POLYGON:
|
||||
case ol.geom.GeometryType.MULTIPOLYGON:
|
||||
goog.asserts.assert(symbolizer instanceof ol.style.PolygonLiteral,
|
||||
'Expected polygon symbolizer: ' + symbolizer);
|
||||
this.renderPolygonFeatures_(
|
||||
features, /** @type {ol.style.PolygonLiteral} */ (symbolizer));
|
||||
break;
|
||||
default:
|
||||
throw new Error('Rendering not implemented for geometry type: ' + type);
|
||||
}
|
||||
return deferred;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of line features.
|
||||
* @param {ol.style.LineLiteral} symbolizer Line symbolizer.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.prototype.renderLineStringFeatures_ =
|
||||
function(features, symbolizer) {
|
||||
|
||||
var context = this.context_,
|
||||
i, ii, geometry, components, j, jj, line, dim, k, kk, x, y;
|
||||
|
||||
context.globalAlpha = symbolizer.opacity;
|
||||
context.strokeStyle = symbolizer.strokeColor;
|
||||
context.lineWidth = symbolizer.strokeWidth * this.inverseScale_;
|
||||
context.lineCap = 'round'; // TODO: accept this as a symbolizer property
|
||||
context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
|
||||
context.beginPath();
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
geometry = features[i].getGeometry();
|
||||
if (geometry instanceof ol.geom.LineString) {
|
||||
components = [geometry];
|
||||
} else {
|
||||
goog.asserts.assert(geometry instanceof ol.geom.MultiLineString,
|
||||
'Expected MultiLineString');
|
||||
components = geometry.components;
|
||||
}
|
||||
for (j = 0, jj = components.length; j < jj; ++j) {
|
||||
line = components[j];
|
||||
dim = line.dimension;
|
||||
for (k = 0, kk = line.getCount(); k < kk; ++k) {
|
||||
x = line.get(k, 0);
|
||||
y = line.get(k, 1);
|
||||
if (k === 0) {
|
||||
context.moveTo(x, y);
|
||||
} else {
|
||||
context.lineTo(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.stroke();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of point features.
|
||||
* @param {ol.style.PointLiteral} symbolizer Point symbolizer.
|
||||
* @return {boolean} true if deferred, false if rendered.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.prototype.renderPointFeatures_ =
|
||||
function(features, symbolizer) {
|
||||
|
||||
var context = this.context_,
|
||||
content, alpha, i, ii, geometry, components, j, jj, point, vec;
|
||||
|
||||
if (symbolizer instanceof ol.style.ShapeLiteral) {
|
||||
content = ol.renderer.canvas.VectorRenderer.renderShape(symbolizer);
|
||||
alpha = 1;
|
||||
} else if (symbolizer instanceof ol.style.IconLiteral) {
|
||||
content = ol.renderer.canvas.VectorRenderer.renderIcon(
|
||||
symbolizer, this.iconLoadedCallback_);
|
||||
alpha = symbolizer.opacity;
|
||||
} else {
|
||||
throw new Error('Unsupported symbolizer: ' + symbolizer);
|
||||
}
|
||||
|
||||
if (goog.isNull(content)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var midWidth = content.width / 2;
|
||||
var midHeight = content.height / 2;
|
||||
context.save();
|
||||
context.setTransform(1, 0, 0, 1, -midWidth, -midHeight);
|
||||
context.globalAlpha = alpha;
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
geometry = features[i].getGeometry();
|
||||
if (geometry instanceof ol.geom.Point) {
|
||||
components = [geometry];
|
||||
} else {
|
||||
goog.asserts.assert(geometry instanceof ol.geom.MultiPoint,
|
||||
'Expected MultiPoint');
|
||||
components = geometry.components;
|
||||
}
|
||||
for (j = 0, jj = components.length; j < jj; ++j) {
|
||||
point = components[j];
|
||||
vec = goog.vec.Mat4.multVec3(
|
||||
this.transform_, [point.get(0), point.get(1), 0], []);
|
||||
context.drawImage(content, vec[0], vec[1], content.width, content.height);
|
||||
}
|
||||
}
|
||||
context.restore();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<ol.Feature>} features Array of polygon features.
|
||||
* @param {ol.style.PolygonLiteral} symbolizer Polygon symbolizer.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
|
||||
function(features, symbolizer) {
|
||||
var context = this.context_,
|
||||
strokeColor = symbolizer.strokeColor,
|
||||
fillColor = symbolizer.fillColor,
|
||||
i, ii, geometry, components, j, jj, poly,
|
||||
rings, numRings, ring, dim, k, kk, x, y;
|
||||
|
||||
context.globalAlpha = symbolizer.opacity;
|
||||
if (strokeColor) {
|
||||
context.strokeStyle = symbolizer.strokeColor;
|
||||
context.lineWidth = symbolizer.strokeWidth * this.inverseScale_;
|
||||
context.lineCap = 'round'; // TODO: accept this as a symbolizer property
|
||||
context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
|
||||
}
|
||||
if (fillColor) {
|
||||
context.fillStyle = fillColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Four scenarios covered here:
|
||||
* 1) stroke only, no holes - only need to have a single path
|
||||
* 2) fill only, no holes - only need to have a single path
|
||||
* 3) fill and stroke, no holes
|
||||
* 4) holes - render polygon to sketch canvas first
|
||||
*/
|
||||
context.beginPath();
|
||||
for (i = 0, ii = features.length; i < ii; ++i) {
|
||||
geometry = features[i].getGeometry();
|
||||
if (geometry instanceof ol.geom.Polygon) {
|
||||
components = [geometry];
|
||||
} else {
|
||||
goog.asserts.assert(geometry instanceof ol.geom.MultiPolygon,
|
||||
'Expected MultiPolygon');
|
||||
components = geometry.components;
|
||||
}
|
||||
for (j = 0, jj = components.length; j < jj; ++j) {
|
||||
poly = components[j];
|
||||
dim = poly.dimension;
|
||||
rings = poly.rings;
|
||||
numRings = rings.length;
|
||||
if (numRings > 0) {
|
||||
// TODO: scenario 4
|
||||
ring = rings[0];
|
||||
for (k = 0, kk = ring.getCount(); k < kk; ++k) {
|
||||
x = ring.get(k, 0);
|
||||
y = ring.get(k, 1);
|
||||
if (k === 0) {
|
||||
context.moveTo(x, y);
|
||||
} else {
|
||||
context.lineTo(x, y);
|
||||
}
|
||||
}
|
||||
if (fillColor && strokeColor) {
|
||||
// scenario 3 - fill and stroke each time
|
||||
context.fill();
|
||||
context.stroke();
|
||||
if (i < ii - 1 || j < jj - 1) {
|
||||
context.beginPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(fillColor && strokeColor)) {
|
||||
if (fillColor) {
|
||||
// scenario 2 - fill all at once
|
||||
context.fill();
|
||||
} else {
|
||||
// scenario 1 - stroke all at once
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.style.ShapeLiteral} circle Shape symbolizer.
|
||||
* @return {!HTMLCanvasElement} Canvas element.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.renderCircle_ = function(circle) {
|
||||
var strokeWidth = circle.strokeWidth || 0,
|
||||
size = circle.size + (2 * strokeWidth) + 1,
|
||||
mid = size / 2,
|
||||
canvas = /** @type {HTMLCanvasElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.CANVAS)),
|
||||
context = /** @type {CanvasRenderingContext2D} */
|
||||
(canvas.getContext('2d')),
|
||||
fillColor = circle.fillColor,
|
||||
strokeColor = circle.strokeColor,
|
||||
twoPi = Math.PI * 2;
|
||||
|
||||
canvas.height = size;
|
||||
canvas.width = size;
|
||||
|
||||
context.globalAlpha = circle.opacity;
|
||||
|
||||
if (fillColor) {
|
||||
context.fillStyle = fillColor;
|
||||
}
|
||||
if (strokeColor) {
|
||||
context.lineWidth = strokeWidth;
|
||||
context.strokeStyle = strokeColor;
|
||||
context.lineCap = 'round'; // TODO: accept this as a symbolizer property
|
||||
context.lineJoin = 'round'; // TODO: accept this as a symbolizer property
|
||||
}
|
||||
|
||||
context.beginPath();
|
||||
context.arc(mid, mid, circle.size / 2, 0, twoPi, true);
|
||||
|
||||
if (fillColor) {
|
||||
context.fill();
|
||||
}
|
||||
if (strokeColor) {
|
||||
context.stroke();
|
||||
}
|
||||
return canvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.style.ShapeLiteral} shape Shape symbolizer.
|
||||
* @return {!HTMLCanvasElement} Canvas element.
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.renderShape = function(shape) {
|
||||
var canvas;
|
||||
if (shape.type === ol.style.ShapeType.CIRCLE) {
|
||||
canvas = ol.renderer.canvas.VectorRenderer.renderCircle_(shape);
|
||||
} else {
|
||||
throw new Error('Unsupported shape type: ' + shape);
|
||||
}
|
||||
return canvas;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.style.IconLiteral} icon Icon literal.
|
||||
* @param {function()=} opt_callback Callback which will be called when
|
||||
* the icon is loaded and rendering will work without deferring.
|
||||
* @return {HTMLImageElement} image element of null if deferred.
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.renderIcon = function(icon, opt_callback) {
|
||||
var url = icon.url;
|
||||
var image = ol.renderer.canvas.VectorRenderer.icons_[url];
|
||||
var deferred = false;
|
||||
if (!goog.isDef(image)) {
|
||||
deferred = true;
|
||||
image = /** @type {HTMLImageElement} */
|
||||
(goog.dom.createElement(goog.dom.TagName.IMG));
|
||||
goog.events.listenOnce(image, goog.events.EventType.ERROR,
|
||||
goog.bind(ol.renderer.canvas.VectorRenderer.handleIconError_, null,
|
||||
opt_callback),
|
||||
false, ol.renderer.canvas.VectorRenderer.renderIcon);
|
||||
goog.events.listenOnce(image, goog.events.EventType.LOAD,
|
||||
goog.bind(ol.renderer.canvas.VectorRenderer.handleIconLoad_, null,
|
||||
opt_callback),
|
||||
false, ol.renderer.canvas.VectorRenderer.renderIcon);
|
||||
image.setAttribute('src', url);
|
||||
ol.renderer.canvas.VectorRenderer.icons_[url] = image;
|
||||
} else if (!goog.isNull(image)) {
|
||||
var width = icon.width,
|
||||
height = icon.height;
|
||||
if (goog.isDef(width) && goog.isDef(height)) {
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
} else if (goog.isDef(width)) {
|
||||
image.height = width / image.width * image.height;
|
||||
image.width = width;
|
||||
} else if (goog.isDef(height)) {
|
||||
image.width = height / image.height * image.width;
|
||||
image.height = height;
|
||||
}
|
||||
}
|
||||
return deferred ? null : image;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object.<string, HTMLImageElement>}
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.icons_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()=} opt_callback Callback.
|
||||
* @param {Event=} opt_event Event.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.handleIconError_ =
|
||||
function(opt_callback, opt_event) {
|
||||
if (goog.isDef(opt_event)) {
|
||||
var url = opt_event.target.getAttribute('src');
|
||||
ol.renderer.canvas.VectorRenderer.icons_[url] = null;
|
||||
ol.renderer.canvas.VectorRenderer.handleIconLoad_(opt_callback, opt_event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()=} opt_callback Callback.
|
||||
* @param {Event=} opt_event Event.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorRenderer.handleIconLoad_ =
|
||||
function(opt_callback, opt_event) {
|
||||
if (goog.isDef(opt_event)) {
|
||||
var url = opt_event.target.getAttribute('src');
|
||||
ol.renderer.canvas.VectorRenderer.icons_[url] =
|
||||
/** @type {HTMLImageElement} */ (opt_event.target);
|
||||
}
|
||||
if (goog.isDef(opt_callback)) {
|
||||
opt_callback();
|
||||
}
|
||||
};
|
||||
|
||||
1
src/ol/source/vectorsource.exports
Normal file
1
src/ol/source/vectorsource.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportClass ol.source.Vector ol.source.SourceOptions
|
||||
25
src/ol/source/vectorsource.js
Normal file
25
src/ol/source/vectorsource.js
Normal file
@@ -0,0 +1,25 @@
|
||||
goog.provide('ol.source.Vector');
|
||||
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.source.Source');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.Source}
|
||||
* @param {ol.source.SourceOptions} options Source options.
|
||||
*/
|
||||
ol.source.Vector = function(options) {
|
||||
goog.base(this, options);
|
||||
};
|
||||
goog.inherits(ol.source.Vector, ol.source.Source);
|
||||
213
src/ol/structs/rtree.js
Normal file
213
src/ol/structs/rtree.js
Normal file
@@ -0,0 +1,213 @@
|
||||
goog.provide('ol.structs.RTree');
|
||||
|
||||
goog.require('ol.Rectangle');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @constructor
|
||||
* @param {number} minX Minimum X.
|
||||
* @param {number} minY Minimum Y.
|
||||
* @param {number} maxX Maximum X.
|
||||
* @param {number} maxY Maximum Y.
|
||||
* @param {ol.structs.RTreeNode_} parent Parent node.
|
||||
* @param {number} level Level in the tree hierarchy.
|
||||
* @extends {ol.Rectangle}
|
||||
*/
|
||||
ol.structs.RTreeNode_ = function(minX, minY, maxX, maxY, parent, level) {
|
||||
|
||||
goog.base(this, minX, minY, maxX, maxY);
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
this.object;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.objectId;
|
||||
|
||||
/**
|
||||
* @type {ol.structs.RTreeNode_}
|
||||
*/
|
||||
this.parent = parent;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.level = level;
|
||||
|
||||
/**
|
||||
* @type {Object.<string, boolean>}
|
||||
*/
|
||||
this.types = {};
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.structs.RTreeNode_>}
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
};
|
||||
goog.inherits(ol.structs.RTreeNode_, ol.Rectangle);
|
||||
|
||||
|
||||
/**
|
||||
* Find all objects intersected by a rectangle.
|
||||
* @param {ol.Rectangle} bounds Bounding box.
|
||||
* @param {Object.<string, Object>} results Target object for results.
|
||||
* @param {string=} opt_type Type for another indexing dimension.
|
||||
*/
|
||||
ol.structs.RTreeNode_.prototype.find = function(bounds, results, opt_type) {
|
||||
if (this.intersects(bounds) &&
|
||||
(!goog.isDef(opt_type) || this.types[opt_type] === true)) {
|
||||
var numChildren = this.children.length;
|
||||
if (numChildren === 0) {
|
||||
if (goog.isDef(this.object)) {
|
||||
results[this.objectId] = this.object;
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < numChildren; ++i) {
|
||||
this.children[i].find(bounds, results, opt_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find the appropriate node for insertion.
|
||||
* @param {ol.Rectangle} bounds Bounding box.
|
||||
* @return {ol.structs.RTreeNode_|undefined} Matching node.
|
||||
*/
|
||||
ol.structs.RTreeNode_.prototype.get = function(bounds) {
|
||||
if (this.intersects(bounds)) {
|
||||
var numChildren = this.children.length;
|
||||
if (numChildren === 0) {
|
||||
return goog.isNull(this.parent) ? this : this.parent;
|
||||
}
|
||||
var node;
|
||||
for (var i = 0; i < numChildren; ++i) {
|
||||
node = this.children[i].get(bounds);
|
||||
if (goog.isDef(node)) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update boxes up to the root to ensure correct bounding
|
||||
* @param {ol.Rectangle} bounds Bounding box.
|
||||
*/
|
||||
ol.structs.RTreeNode_.prototype.update = function(bounds) {
|
||||
this.extend(bounds);
|
||||
if (!goog.isNull(this.parent)) {
|
||||
this.parent.update(bounds);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Divide @this node's children in half and create two new boxes containing
|
||||
* the split items. The top left will be the topmost leftmost child and the
|
||||
* bottom right will be the rightmost bottommost child.
|
||||
*/
|
||||
ol.structs.RTreeNode_.prototype.divide = function() {
|
||||
var numChildren = this.children.length;
|
||||
if (numChildren === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var half = Math.ceil(numChildren / 2),
|
||||
child, node;
|
||||
|
||||
for (var i = 0; i < numChildren; ++i) {
|
||||
child = this.children[i];
|
||||
if (i % half === 0) {
|
||||
node = new ol.structs.RTreeNode_(child.minX, child.minY,
|
||||
child.maxX, child.maxY, this, this.level + 1);
|
||||
goog.object.extend(this.types, node.types);
|
||||
this.children.push(node);
|
||||
}
|
||||
child.parent = /** @type {ol.structs.RTreeNode_} */ node;
|
||||
goog.object.extend(node.types, child.types);
|
||||
node.children.push(child);
|
||||
node.extend(child);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.structs.RTree = function() {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.structs.RTreeNode_}
|
||||
*/
|
||||
this.root_ = new ol.structs.RTreeNode_(
|
||||
Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY,
|
||||
Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, null, 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Rectangle} bounds Bounding box.
|
||||
* @param {string=} opt_type Type for another indexing dimension.
|
||||
* @return {Object.<string, Object>} Results for the passed bounding box.
|
||||
*/
|
||||
ol.structs.RTree.prototype.find = function(bounds, opt_type) {
|
||||
var results = /** @type {Object.<string, Object>} */ {};
|
||||
this.root_.find(bounds, results, opt_type);
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Rectangle} bounds Bounding box.
|
||||
* @param {Object} object Object to store with the passed bounds.
|
||||
* @param {string=} opt_type Type for another indexing dimension.
|
||||
*/
|
||||
ol.structs.RTree.prototype.put = function(bounds, object, opt_type) {
|
||||
var found = this.root_.get(bounds);
|
||||
if (found) {
|
||||
var node = new ol.structs.RTreeNode_(
|
||||
bounds.minX, bounds.minY, bounds.maxX, bounds.maxY,
|
||||
found, found.level + 1);
|
||||
node.object = object;
|
||||
node.objectId = goog.getUid(object).toString();
|
||||
|
||||
found.children.push(node);
|
||||
found.update(bounds);
|
||||
|
||||
if (goog.isDef(opt_type)) {
|
||||
node.types[opt_type] = true;
|
||||
found.types[opt_type] = true;
|
||||
}
|
||||
|
||||
if (found.children.length >= ol.structs.RTree.MAX_OBJECTS &&
|
||||
found.level < ol.structs.RTree.MAX_SUB_DIVISIONS) {
|
||||
found.divide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
ol.structs.RTree.MAX_SUB_DIVISIONS = 6;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
ol.structs.RTree.MAX_OBJECTS = 6;
|
||||
|
||||
9
src/ol/style.exports
Normal file
9
src/ol/style.exports
Normal file
@@ -0,0 +1,9 @@
|
||||
@exportClass ol.style.Icon ol.style.IconOptions
|
||||
@exportClass ol.style.Line ol.style.LineOptions
|
||||
@exportClass ol.style.Polygon ol.style.PolygonOptions
|
||||
@exportClass ol.style.Rule ol.style.RuleOptions
|
||||
@exportClass ol.style.Shape ol.style.ShapeOptions
|
||||
@exportClass ol.style.Style ol.style.StyleOptions
|
||||
@exportSymbol ol.style.IconType
|
||||
@exportSymbol ol.style.ShapeType
|
||||
@exportProperty ol.style.ShapeType.CIRCLE
|
||||
160
src/ol/style/icon.js
Normal file
160
src/ol/style/icon.js
Normal file
@@ -0,0 +1,160 @@
|
||||
goog.provide('ol.style.Icon');
|
||||
goog.provide('ol.style.IconLiteral');
|
||||
goog.provide('ol.style.IconType');
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.ExpressionLiteral');
|
||||
goog.require('ol.style.Point');
|
||||
goog.require('ol.style.PointLiteral');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{url: (string),
|
||||
* width: (number|undefined),
|
||||
* height: (number|undefined),
|
||||
* opacity: (number),
|
||||
* rotation: (number)}}
|
||||
*/
|
||||
ol.style.IconLiteralOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.PointLiteral}
|
||||
* @param {ol.style.IconLiteralOptions} config Symbolizer properties.
|
||||
*/
|
||||
ol.style.IconLiteral = function(config) {
|
||||
|
||||
/** @type {string} */
|
||||
this.url = config.url;
|
||||
|
||||
/** @type {number|undefined} */
|
||||
this.width = config.width;
|
||||
|
||||
/** @type {number|undefined} */
|
||||
this.height = config.height;
|
||||
|
||||
/** @type {number} */
|
||||
this.opacity = config.opacity;
|
||||
|
||||
/** @type {number} */
|
||||
this.rotation = config.rotation;
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.IconLiteral, ol.style.PointLiteral);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.style.IconLiteral.prototype.equals = function(iconLiteral) {
|
||||
return this.url == iconLiteral.type &&
|
||||
this.width == iconLiteral.width &&
|
||||
this.height == iconLiteral.height &&
|
||||
this.opacity == iconLiteral.opacity &&
|
||||
this.rotation == iconLiteral.rotation;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.Point}
|
||||
* @param {ol.style.IconOptions} options Symbolizer properties.
|
||||
*/
|
||||
ol.style.Icon = function(options) {
|
||||
|
||||
goog.asserts.assert(options.url, 'url must be set');
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.url_ = (options.url instanceof ol.Expression) ?
|
||||
options.url : new ol.ExpressionLiteral(options.url);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.width_ = !goog.isDef(options.width) ?
|
||||
null :
|
||||
(options.width instanceof ol.Expression) ?
|
||||
options.width : new ol.ExpressionLiteral(options.width);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.height_ = !goog.isDef(options.height) ?
|
||||
null :
|
||||
(options.height instanceof ol.Expression) ?
|
||||
options.height : new ol.ExpressionLiteral(options.height);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.opacity_ = !goog.isDef(options.opacity) ?
|
||||
new ol.ExpressionLiteral(ol.style.IconDefaults.opacity) :
|
||||
(options.opacity instanceof ol.Expression) ?
|
||||
options.opacity : new ol.ExpressionLiteral(options.opacity);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.rotation_ = !goog.isDef(options.rotation) ?
|
||||
new ol.ExpressionLiteral(ol.style.IconDefaults.rotation) :
|
||||
(options.rotation instanceof ol.Expression) ?
|
||||
options.rotation : new ol.ExpressionLiteral(options.rotation);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.style.IconLiteral} Literal shape symbolizer.
|
||||
*/
|
||||
ol.style.Icon.prototype.createLiteral = function(feature) {
|
||||
var attrs = feature.getAttributes();
|
||||
|
||||
var url = /** @type {string} */ (this.url_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(goog.isString(url) && url != '#', 'url must be a string');
|
||||
|
||||
var width = /** @type {number|undefined} */ (goog.isNull(this.width_) ?
|
||||
undefined : this.width_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(width) || goog.isNumber(width),
|
||||
'width must be undefined or a number');
|
||||
|
||||
var height = /** @type {number|undefined} */ (goog.isNull(this.height_) ?
|
||||
undefined : this.height_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(height) || goog.isNumber(height),
|
||||
'height must be undefined or a number');
|
||||
|
||||
var opacity = /** {@type {number} */ (this.opacity_.evaluate(feature, attrs));
|
||||
goog.asserts.assertNumber(opacity, 'opacity must be a number');
|
||||
|
||||
var rotation =
|
||||
/** {@type {number} */ (this.opacity_.evaluate(feature, attrs));
|
||||
goog.asserts.assertNumber(rotation, 'rotation must be a number');
|
||||
|
||||
return new ol.style.IconLiteral({
|
||||
url: url,
|
||||
width: width,
|
||||
height: height,
|
||||
opacity: opacity,
|
||||
rotation: rotation
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {ol.style.IconLiteral}
|
||||
*/
|
||||
ol.style.IconDefaults = new ol.style.IconLiteral({
|
||||
url: '#',
|
||||
opacity: 1,
|
||||
rotation: 0
|
||||
});
|
||||
128
src/ol/style/line.js
Normal file
128
src/ol/style/line.js
Normal file
@@ -0,0 +1,128 @@
|
||||
goog.provide('ol.style.Line');
|
||||
goog.provide('ol.style.LineLiteral');
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.ExpressionLiteral');
|
||||
goog.require('ol.style.Symbolizer');
|
||||
goog.require('ol.style.SymbolizerLiteral');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{strokeColor: (string),
|
||||
* strokeWidth: (number),
|
||||
* opacity: (number)}}
|
||||
*/
|
||||
ol.style.LineLiteralOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.SymbolizerLiteral}
|
||||
* @param {ol.style.LineLiteralOptions} config Symbolizer properties.
|
||||
*/
|
||||
ol.style.LineLiteral = function(config) {
|
||||
goog.base(this);
|
||||
|
||||
goog.asserts.assertString(config.strokeColor, 'strokeColor must be a string');
|
||||
/** @type {string} */
|
||||
this.strokeColor = config.strokeColor;
|
||||
|
||||
goog.asserts.assertNumber(config.strokeWidth, 'strokeWidth must be a number');
|
||||
/** @type {number} */
|
||||
this.strokeWidth = config.strokeWidth;
|
||||
|
||||
goog.asserts.assertNumber(config.opacity, 'opacity must be a number');
|
||||
/** @type {number} */
|
||||
this.opacity = config.opacity;
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.LineLiteral, ol.style.SymbolizerLiteral);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.style.LineLiteral.prototype.equals = function(lineLiteral) {
|
||||
return this.strokeColor == lineLiteral.strokeColor &&
|
||||
this.strokeWidth == lineLiteral.strokeWidth &&
|
||||
this.opacity == lineLiteral.opacity;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.Symbolizer}
|
||||
* @param {ol.style.LineOptions} options Symbolizer properties.
|
||||
*/
|
||||
ol.style.Line = function(options) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeColor_ = !goog.isDef(options.strokeColor) ?
|
||||
new ol.ExpressionLiteral(ol.style.LineDefaults.strokeColor) :
|
||||
(options.strokeColor instanceof ol.Expression) ?
|
||||
options.strokeColor : new ol.ExpressionLiteral(options.strokeColor);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeWidth_ = !goog.isDef(options.strokeWidth) ?
|
||||
new ol.ExpressionLiteral(ol.style.LineDefaults.strokeWidth) :
|
||||
(options.strokeWidth instanceof ol.Expression) ?
|
||||
options.strokeWidth : new ol.ExpressionLiteral(options.strokeWidth);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.opacity_ = !goog.isDef(options.opacity) ?
|
||||
new ol.ExpressionLiteral(ol.style.LineDefaults.opacity) :
|
||||
(options.opacity instanceof ol.Expression) ?
|
||||
options.opacity : new ol.ExpressionLiteral(options.opacity);
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.Line, ol.style.Symbolizer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.style.LineLiteral} Literal line symbolizer.
|
||||
*/
|
||||
ol.style.Line.prototype.createLiteral = function(opt_feature) {
|
||||
var attrs,
|
||||
feature = opt_feature;
|
||||
if (goog.isDef(feature)) {
|
||||
attrs = feature.getAttributes();
|
||||
}
|
||||
|
||||
var strokeColor = this.strokeColor_.evaluate(feature, attrs);
|
||||
goog.asserts.assertString(strokeColor, 'strokeColor must be a string');
|
||||
|
||||
var strokeWidth = this.strokeWidth_.evaluate(feature, attrs);
|
||||
goog.asserts.assertNumber(strokeWidth, 'strokeWidth must be a number');
|
||||
|
||||
var opacity = this.opacity_.evaluate(feature, attrs);
|
||||
goog.asserts.assertNumber(opacity, 'opacity must be a number');
|
||||
|
||||
return new ol.style.LineLiteral({
|
||||
strokeColor: strokeColor,
|
||||
strokeWidth: strokeWidth,
|
||||
opacity: opacity
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {ol.style.LineLiteral}
|
||||
*/
|
||||
ol.style.LineDefaults = new ol.style.LineLiteral({
|
||||
strokeColor: '#696969',
|
||||
strokeWidth: 1.5,
|
||||
opacity: 0.75
|
||||
});
|
||||
33
src/ol/style/point.js
Normal file
33
src/ol/style/point.js
Normal file
@@ -0,0 +1,33 @@
|
||||
goog.provide('ol.style.Point');
|
||||
goog.provide('ol.style.PointLiteral');
|
||||
|
||||
goog.require('ol.style.Symbolizer');
|
||||
goog.require('ol.style.SymbolizerLiteral');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.SymbolizerLiteral}
|
||||
*/
|
||||
ol.style.PointLiteral = function() {
|
||||
goog.base(this);
|
||||
};
|
||||
goog.inherits(ol.style.PointLiteral, ol.style.SymbolizerLiteral);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.Symbolizer}
|
||||
*/
|
||||
ol.style.Point = function() {
|
||||
goog.base(this);
|
||||
};
|
||||
goog.inherits(ol.style.Point, ol.style.Symbolizer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.style.Point.prototype.createLiteral = goog.abstractMethod;
|
||||
189
src/ol/style/polygon.js
Normal file
189
src/ol/style/polygon.js
Normal file
@@ -0,0 +1,189 @@
|
||||
goog.provide('ol.style.Polygon');
|
||||
goog.provide('ol.style.PolygonLiteral');
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.ExpressionLiteral');
|
||||
goog.require('ol.style.Symbolizer');
|
||||
goog.require('ol.style.SymbolizerLiteral');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{fillColor: (string|undefined),
|
||||
* strokeColor: (string|undefined),
|
||||
* strokeWidth: (number|undefined),
|
||||
* opacity: (number)}}
|
||||
*/
|
||||
ol.style.PolygonLiteralOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.SymbolizerLiteral}
|
||||
* @param {ol.style.PolygonLiteralOptions} config Symbolizer properties.
|
||||
*/
|
||||
ol.style.PolygonLiteral = function(config) {
|
||||
goog.base(this);
|
||||
|
||||
/** @type {string|undefined} */
|
||||
this.fillColor = config.fillColor;
|
||||
if (goog.isDef(config.fillColor)) {
|
||||
goog.asserts.assertString(config.fillColor, 'fillColor must be a string');
|
||||
}
|
||||
|
||||
/** @type {string|undefined} */
|
||||
this.strokeColor = config.strokeColor;
|
||||
if (goog.isDef(this.strokeColor)) {
|
||||
goog.asserts.assertString(
|
||||
this.strokeColor, 'strokeColor must be a string');
|
||||
}
|
||||
|
||||
/** @type {number|undefined} */
|
||||
this.strokeWidth = config.strokeWidth;
|
||||
if (goog.isDef(this.strokeWidth)) {
|
||||
goog.asserts.assertNumber(
|
||||
this.strokeWidth, 'strokeWidth must be a number');
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isDef(this.fillColor) ||
|
||||
(goog.isDef(this.strokeColor) && goog.isDef(this.strokeWidth)),
|
||||
'Either fillColor or strokeColor and strokeWidth must be set');
|
||||
|
||||
goog.asserts.assertNumber(config.opacity, 'opacity must be a number');
|
||||
/** @type {number} */
|
||||
this.opacity = config.opacity;
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.PolygonLiteral, ol.style.SymbolizerLiteral);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.style.PolygonLiteral.prototype.equals = function(polygonLiteral) {
|
||||
return this.fillColor == polygonLiteral.fillColor &&
|
||||
this.strokeColor == polygonLiteral.strokeColor &&
|
||||
this.strokeWidth == polygonLiteral.strokeWidth &&
|
||||
this.opacity == polygonLiteral.opacity;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.Symbolizer}
|
||||
* @param {ol.style.PolygonOptions} options Symbolizer properties.
|
||||
*/
|
||||
ol.style.Polygon = function(options) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.fillColor_ = !goog.isDefAndNotNull(options.fillColor) ?
|
||||
null :
|
||||
(options.fillColor instanceof ol.Expression) ?
|
||||
options.fillColor : new ol.ExpressionLiteral(options.fillColor);
|
||||
|
||||
// stroke handling - if any stroke property is supplied, use defaults
|
||||
var strokeColor = null,
|
||||
strokeWidth = null;
|
||||
|
||||
if (goog.isDefAndNotNull(options.strokeColor) ||
|
||||
goog.isDefAndNotNull(options.strokeWidth)) {
|
||||
|
||||
strokeColor = !goog.isDefAndNotNull(options.strokeColor) ?
|
||||
new ol.ExpressionLiteral(ol.style.PolygonDefaults.strokeColor) :
|
||||
(options.strokeColor instanceof ol.Expression) ?
|
||||
options.strokeColor : new ol.ExpressionLiteral(options.strokeColor);
|
||||
|
||||
strokeWidth = !goog.isDef(options.strokeWidth) ?
|
||||
new ol.ExpressionLiteral(ol.style.PolygonDefaults.strokeWidth) :
|
||||
(options.strokeWidth instanceof ol.Expression) ?
|
||||
options.strokeWidth : new ol.ExpressionLiteral(options.strokeWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeColor_ = strokeColor;
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeWidth_ = strokeWidth;
|
||||
|
||||
// one of stroke or fill can be null, both null is user error
|
||||
goog.asserts.assert(!goog.isNull(this.fillColor_) ||
|
||||
!(goog.isNull(this.strokeColor_) && goog.isNull(this.strokeWidth_)),
|
||||
'Stroke or fill properties must be provided');
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.opacity_ = !goog.isDef(options.opacity) ?
|
||||
new ol.ExpressionLiteral(ol.style.PolygonDefaults.opacity) :
|
||||
(options.opacity instanceof ol.Expression) ?
|
||||
options.opacity : new ol.ExpressionLiteral(options.opacity);
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.Polygon, ol.style.Symbolizer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.style.PolygonLiteral} Literal shape symbolizer.
|
||||
*/
|
||||
ol.style.Polygon.prototype.createLiteral = function(opt_feature) {
|
||||
var attrs,
|
||||
feature = opt_feature;
|
||||
if (goog.isDef(feature)) {
|
||||
attrs = feature.getAttributes();
|
||||
}
|
||||
|
||||
var fillColor = goog.isNull(this.fillColor_) ?
|
||||
undefined :
|
||||
/** @type {string} */ (this.fillColor_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(fillColor) || goog.isString(fillColor));
|
||||
|
||||
var strokeColor = goog.isNull(this.strokeColor_) ?
|
||||
undefined :
|
||||
/** @type {string} */ (this.strokeColor_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(strokeColor) || goog.isString(strokeColor));
|
||||
|
||||
var strokeWidth = goog.isNull(this.strokeWidth_) ?
|
||||
undefined :
|
||||
/** @type {number} */ (this.strokeWidth_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(strokeWidth) || goog.isNumber(strokeWidth));
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isDef(fillColor) ||
|
||||
(goog.isDef(strokeColor) && goog.isDef(strokeWidth)),
|
||||
'either fill style or strokeColor and strokeWidth must be defined');
|
||||
|
||||
var opacity = this.opacity_.evaluate(feature, attrs);
|
||||
goog.asserts.assertNumber(opacity, 'opacity must be a number');
|
||||
|
||||
return new ol.style.PolygonLiteral({
|
||||
fillColor: fillColor,
|
||||
strokeColor: strokeColor,
|
||||
strokeWidth: strokeWidth,
|
||||
opacity: opacity
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {ol.style.PolygonLiteral}
|
||||
*/
|
||||
ol.style.PolygonDefaults = new ol.style.PolygonLiteral({
|
||||
fillColor: '#ffffff',
|
||||
strokeColor: '#696969',
|
||||
strokeWidth: 1.5,
|
||||
opacity: 0.75
|
||||
});
|
||||
46
src/ol/style/rule.js
Normal file
46
src/ol/style/rule.js
Normal file
@@ -0,0 +1,46 @@
|
||||
goog.provide('ol.style.Rule');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.style.Symbolizer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {ol.style.RuleOptions} options Rule options.
|
||||
*/
|
||||
ol.style.Rule = function(options) {
|
||||
|
||||
/**
|
||||
* @type {ol.filter.Filter}
|
||||
* @private
|
||||
*/
|
||||
this.filter_ = goog.isDef(options.filter) ? options.filter : null;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.style.Symbolizer>}
|
||||
* @private
|
||||
*/
|
||||
this.symbolizers_ = goog.isDef(options.symbolizers) ?
|
||||
options.symbolizers : [];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @return {boolean} Does the rule apply to the feature?
|
||||
*/
|
||||
ol.style.Rule.prototype.applies = function(feature) {
|
||||
return goog.isNull(this.filter_) ? true : this.filter_.applies(feature);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.style.Symbolizer>} Symbolizers.
|
||||
*/
|
||||
ol.style.Rule.prototype.getSymbolizers = function() {
|
||||
return this.symbolizers_;
|
||||
};
|
||||
|
||||
230
src/ol/style/shape.js
Normal file
230
src/ol/style/shape.js
Normal file
@@ -0,0 +1,230 @@
|
||||
goog.provide('ol.style.Shape');
|
||||
goog.provide('ol.style.ShapeLiteral');
|
||||
goog.provide('ol.style.ShapeType');
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.ExpressionLiteral');
|
||||
goog.require('ol.style.Point');
|
||||
goog.require('ol.style.PointLiteral');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.style.ShapeType = {
|
||||
CIRCLE: 'circle'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{type: (ol.style.ShapeType),
|
||||
* size: (number),
|
||||
* fillColor: (string|undefined),
|
||||
* strokeColor: (string|undefined),
|
||||
* strokeWidth: (number|undefined),
|
||||
* opacity: (number)}}
|
||||
*/
|
||||
ol.style.ShapeLiteralOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.PointLiteral}
|
||||
* @param {ol.style.ShapeLiteralOptions} config Symbolizer properties.
|
||||
*/
|
||||
ol.style.ShapeLiteral = function(config) {
|
||||
|
||||
goog.asserts.assertString(config.type, 'type must be a string');
|
||||
/** @type {ol.style.ShapeType} */
|
||||
this.type = config.type;
|
||||
|
||||
goog.asserts.assertNumber(config.size, 'size must be a number');
|
||||
/** @type {number} */
|
||||
this.size = config.size;
|
||||
|
||||
/** @type {string|undefined} */
|
||||
this.fillColor = config.fillColor;
|
||||
if (goog.isDef(config.fillColor)) {
|
||||
goog.asserts.assertString(config.fillColor, 'fillColor must be a string');
|
||||
}
|
||||
|
||||
/** @type {string|undefined} */
|
||||
this.strokeColor = config.strokeColor;
|
||||
if (goog.isDef(this.strokeColor)) {
|
||||
goog.asserts.assertString(
|
||||
this.strokeColor, 'strokeColor must be a string');
|
||||
}
|
||||
|
||||
/** @type {number|undefined} */
|
||||
this.strokeWidth = config.strokeWidth;
|
||||
if (goog.isDef(this.strokeWidth)) {
|
||||
goog.asserts.assertNumber(
|
||||
this.strokeWidth, 'strokeWidth must be a number');
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isDef(this.fillColor) ||
|
||||
(goog.isDef(this.strokeColor) && goog.isDef(this.strokeWidth)),
|
||||
'Either fillColor or strokeColor and strokeWidth must be set');
|
||||
|
||||
goog.asserts.assertNumber(config.opacity, 'opacity must be a number');
|
||||
/** @type {number} */
|
||||
this.opacity = config.opacity;
|
||||
|
||||
};
|
||||
goog.inherits(ol.style.ShapeLiteral, ol.style.PointLiteral);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.style.ShapeLiteral.prototype.equals = function(shapeLiteral) {
|
||||
return this.type == shapeLiteral.type &&
|
||||
this.size == shapeLiteral.size &&
|
||||
this.fillColor == shapeLiteral.fillColor &&
|
||||
this.strokeColor == shapeLiteral.strokeColor &&
|
||||
this.strokeWidth == shapeLiteral.strokeWidth &&
|
||||
this.opacity == shapeLiteral.opacity;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.style.Point}
|
||||
* @param {ol.style.ShapeOptions} options Symbolizer properties.
|
||||
*/
|
||||
ol.style.Shape = function(options) {
|
||||
|
||||
/**
|
||||
* @type {ol.style.ShapeType}
|
||||
* @private
|
||||
*/
|
||||
this.type_ = /** @type {ol.style.ShapeType} */ (goog.isDef(options.type) ?
|
||||
options.type : ol.style.ShapeDefaults.type);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.size_ = !goog.isDef(options.size) ?
|
||||
new ol.ExpressionLiteral(ol.style.ShapeDefaults.size) :
|
||||
(options.size instanceof ol.Expression) ?
|
||||
options.size : new ol.ExpressionLiteral(options.size);
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.fillColor_ = !goog.isDefAndNotNull(options.fillColor) ?
|
||||
null :
|
||||
(options.fillColor instanceof ol.Expression) ?
|
||||
options.fillColor : new ol.ExpressionLiteral(options.fillColor);
|
||||
|
||||
// stroke handling - if any stroke property is supplied, use defaults
|
||||
var strokeColor = null,
|
||||
strokeWidth = null;
|
||||
|
||||
if (goog.isDefAndNotNull(options.strokeColor) ||
|
||||
goog.isDefAndNotNull(options.strokeWidth)) {
|
||||
|
||||
strokeColor = !goog.isDefAndNotNull(options.strokeColor) ?
|
||||
new ol.ExpressionLiteral(ol.style.ShapeDefaults.strokeColor) :
|
||||
(options.strokeColor instanceof ol.Expression) ?
|
||||
options.strokeColor : new ol.ExpressionLiteral(options.strokeColor);
|
||||
|
||||
strokeWidth = !goog.isDef(options.strokeWidth) ?
|
||||
new ol.ExpressionLiteral(ol.style.ShapeDefaults.strokeWidth) :
|
||||
(options.strokeWidth instanceof ol.Expression) ?
|
||||
options.strokeWidth : new ol.ExpressionLiteral(options.strokeWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeColor_ = strokeColor;
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.strokeWidth_ = strokeWidth;
|
||||
|
||||
// one of stroke or fill can be null, both null is user error
|
||||
goog.asserts.assert(!goog.isNull(this.fillColor_) ||
|
||||
!(goog.isNull(this.strokeColor_) && goog.isNull(this.strokeWidth_)),
|
||||
'Stroke or fill properties must be provided');
|
||||
|
||||
/**
|
||||
* @type {ol.Expression}
|
||||
* @private
|
||||
*/
|
||||
this.opacity_ = !goog.isDef(options.opacity) ?
|
||||
new ol.ExpressionLiteral(ol.style.ShapeDefaults.opacity) :
|
||||
(options.opacity instanceof ol.Expression) ?
|
||||
options.opacity : new ol.ExpressionLiteral(options.opacity);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.style.ShapeLiteral} Literal shape symbolizer.
|
||||
*/
|
||||
ol.style.Shape.prototype.createLiteral = function(opt_feature) {
|
||||
var attrs,
|
||||
feature = opt_feature;
|
||||
if (goog.isDef(feature)) {
|
||||
attrs = feature.getAttributes();
|
||||
}
|
||||
|
||||
var size = this.size_.evaluate(feature, attrs);
|
||||
goog.asserts.assertNumber(size, 'size must be a number');
|
||||
|
||||
var fillColor = goog.isNull(this.fillColor_) ?
|
||||
undefined :
|
||||
/** @type {string} */ (this.fillColor_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(fillColor) || goog.isString(fillColor));
|
||||
|
||||
var strokeColor = goog.isNull(this.strokeColor_) ?
|
||||
undefined :
|
||||
/** @type {string} */ (this.strokeColor_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(strokeColor) || goog.isString(strokeColor));
|
||||
|
||||
var strokeWidth = goog.isNull(this.strokeWidth_) ?
|
||||
undefined :
|
||||
/** @type {number} */ (this.strokeWidth_.evaluate(feature, attrs));
|
||||
goog.asserts.assert(!goog.isDef(strokeWidth) || goog.isNumber(strokeWidth));
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isDef(fillColor) ||
|
||||
(goog.isDef(strokeColor) && goog.isDef(strokeWidth)),
|
||||
'either fill style or strokeColor and strokeWidth must be defined');
|
||||
|
||||
var opacity = this.opacity_.evaluate(feature, attrs);
|
||||
goog.asserts.assertNumber(opacity, 'opacity must be a number');
|
||||
|
||||
return new ol.style.ShapeLiteral({
|
||||
type: this.type_,
|
||||
size: size,
|
||||
fillColor: fillColor,
|
||||
strokeColor: strokeColor,
|
||||
strokeWidth: strokeWidth,
|
||||
opacity: opacity
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {ol.style.ShapeLiteral}
|
||||
*/
|
||||
ol.style.ShapeDefaults = new ol.style.ShapeLiteral({
|
||||
type: ol.style.ShapeType.CIRCLE,
|
||||
size: 5,
|
||||
fillColor: '#ffffff',
|
||||
strokeColor: '#696969',
|
||||
strokeWidth: 1.5,
|
||||
opacity: 0.75
|
||||
});
|
||||
70
src/ol/style/style.js
Normal file
70
src/ol/style/style.js
Normal file
@@ -0,0 +1,70 @@
|
||||
goog.provide('ol.style.Style');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.SymbolizerLiteral');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {ol.style.StyleOptions} options Style options.
|
||||
*/
|
||||
ol.style.Style = function(options) {
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.style.Rule>}
|
||||
* @private
|
||||
*/
|
||||
this.rules_ = goog.isDef(options.rules) ? options.rules : [];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @return {Array.<ol.style.SymbolizerLiteral>} Symbolizer literals for the
|
||||
* feature.
|
||||
*/
|
||||
ol.style.Style.prototype.apply = function(feature) {
|
||||
var rules = this.rules_,
|
||||
literals = [],
|
||||
rule, symbolizers;
|
||||
for (var i = 0, ii = rules.length; i < ii; ++i) {
|
||||
rule = rules[i];
|
||||
if (rule.applies(feature)) {
|
||||
symbolizers = rule.getSymbolizers();
|
||||
for (var j = 0, jj = symbolizers.length; j < jj; ++j) {
|
||||
literals.push(symbolizers[j].createLiteral(feature));
|
||||
}
|
||||
}
|
||||
}
|
||||
return literals;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature.
|
||||
* @return {Array.<ol.style.SymbolizerLiteral>} Default symbolizer literals for
|
||||
* the feature.
|
||||
*/
|
||||
ol.style.Style.applyDefaultStyle = function(feature) {
|
||||
var geometry = feature.getGeometry(),
|
||||
symbolizerLiterals = [];
|
||||
if (!goog.isNull(geometry)) {
|
||||
var type = geometry.getType();
|
||||
if (type === ol.geom.GeometryType.POINT ||
|
||||
type === ol.geom.GeometryType.MULTIPOINT) {
|
||||
symbolizerLiterals.push(ol.style.ShapeDefaults);
|
||||
} else if (type === ol.geom.GeometryType.LINESTRING ||
|
||||
type === ol.geom.GeometryType.MULTILINESTRING) {
|
||||
symbolizerLiterals.push(ol.style.LineDefaults);
|
||||
} else if (type === ol.geom.GeometryType.LINEARRING ||
|
||||
type === ol.geom.GeometryType.POLYGON ||
|
||||
type === ol.geom.GeometryType.MULTIPOLYGON) {
|
||||
symbolizerLiterals.push(ol.style.PolygonDefaults);
|
||||
}
|
||||
}
|
||||
return symbolizerLiterals;
|
||||
};
|
||||
33
src/ol/style/symbolizer.js
Normal file
33
src/ol/style/symbolizer.js
Normal file
@@ -0,0 +1,33 @@
|
||||
goog.provide('ol.style.Symbolizer');
|
||||
goog.provide('ol.style.SymbolizerLiteral');
|
||||
|
||||
goog.require('ol.Feature');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.style.SymbolizerLiteral = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.style.SymbolizerLiteral} symbolizerLiteral Symbolizer literal to
|
||||
* compare to.
|
||||
* @return {boolean} Is the passed symbolizer literal equal to this instance?
|
||||
*/
|
||||
ol.style.SymbolizerLiteral.prototype.equals = goog.abstractMethod;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
ol.style.Symbolizer = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature=} opt_feature Feature for evaluating expressions.
|
||||
* @return {ol.style.SymbolizerLiteral} Literal symbolizer.
|
||||
*/
|
||||
ol.style.Symbolizer.prototype.createLiteral = goog.abstractMethod;
|
||||
@@ -1,11 +1,77 @@
|
||||
beforeEach(function() {
|
||||
var parent = this.getMatchersClass_();
|
||||
this.addMatchers({
|
||||
toBeA: function(type) {
|
||||
return this.actual instanceof type;
|
||||
},
|
||||
toRoughlyEqual: function(other, tol) {
|
||||
return Math.abs(this.actual - other) <= tol;
|
||||
}
|
||||
});
|
||||
var parent = this.getMatchersClass_();
|
||||
this.addMatchers({
|
||||
toBeA: function(type) {
|
||||
return this.actual instanceof type;
|
||||
},
|
||||
toRoughlyEqual: function(other, tol) {
|
||||
return Math.abs(this.actual - other) <= tol;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// helper functions for async testing
|
||||
(function(global) {
|
||||
|
||||
function afterLoad(type, path, next) {
|
||||
var done, error, data;
|
||||
runs(function() {
|
||||
goog.net.XhrIo.send(path, function(event) {
|
||||
var xhr = event.target;
|
||||
if (xhr.isSuccess()) {
|
||||
if (type === 'xml') {
|
||||
data = xhr.getResponseXml();
|
||||
} else if (type === 'json') {
|
||||
data = xhr.getResponseJson();
|
||||
} else {
|
||||
data = xhr.getResponseText();
|
||||
}
|
||||
} else {
|
||||
error = new Error(path + ' loading failed: ' + xhr.getStatus());
|
||||
}
|
||||
done = true;
|
||||
});
|
||||
});
|
||||
waitsFor(function() {
|
||||
return done;
|
||||
});
|
||||
runs(function() {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
next(data);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} path Relative path to file (e.g. 'spec/ol/foo.json').
|
||||
* @param {function(Object)} next Function to call with response object on
|
||||
* success. On failure, an error is thrown with the reason.
|
||||
*/
|
||||
global.afterLoadJson = function(path, next) {
|
||||
afterLoad('json', path, next);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} path Relative path to file (e.g. 'spec/ol/foo.txt').
|
||||
* @param {function(string)} next Function to call with response text on
|
||||
* success. On failure, an error is thrown with the reason.
|
||||
*/
|
||||
global.afterLoadText = function(path, next) {
|
||||
afterLoad('text', path, next);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} path Relative path to file (e.g. 'spec/ol/foo.xml').
|
||||
* @param {function(Document)} next Function to call with response xml on
|
||||
* success. On failure, an error is thrown with the reason.
|
||||
*/
|
||||
global.afterLoadXml = function(path, next) {
|
||||
afterLoad('xml', path, next);
|
||||
};
|
||||
|
||||
})(this);
|
||||
|
||||
|
||||
78
test/spec/ol/expression.test.js
Normal file
78
test/spec/ol/expression.test.js
Normal file
@@ -0,0 +1,78 @@
|
||||
goog.provide('ol.test.Expression');
|
||||
|
||||
describe('ol.Expression', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
it('creates an expression', function() {
|
||||
var exp = new ol.Expression('foo');
|
||||
expect(exp).toBeA(ol.Expression);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#evaluate()', function() {
|
||||
|
||||
it('evaluates and returns the result', function() {
|
||||
// test cases here with unique values only (lack of messages in expect)
|
||||
var cases = [{
|
||||
source: '42', result: 42
|
||||
}, {
|
||||
source: '10 + 10', result: 20
|
||||
}, {
|
||||
source: '"a" + "b"', result: 'ab'
|
||||
}, {
|
||||
source: 'Math.floor(Math.PI)', result: 3
|
||||
}, {
|
||||
source: 'ol', result: ol
|
||||
}, {
|
||||
source: 'this', result: goog.global
|
||||
}];
|
||||
|
||||
var c, exp;
|
||||
for (var i = 0, ii = cases.length; i < ii; ++i) {
|
||||
c = cases[i];
|
||||
exp = new ol.Expression(c.source);
|
||||
expect(exp.evaluate()).toBe(c.result);
|
||||
}
|
||||
});
|
||||
|
||||
it('accepts an optional this argument', function() {
|
||||
function Thing() {
|
||||
this.works = true;
|
||||
};
|
||||
|
||||
var exp = new ol.Expression('this.works ? "yes" : "no"');
|
||||
expect(exp.evaluate(new Thing())).toBe('yes');
|
||||
expect(exp.evaluate({})).toBe('no');
|
||||
});
|
||||
|
||||
it('accepts an optional scope argument', function() {
|
||||
var exp;
|
||||
var scope = {
|
||||
greeting: 'hello world',
|
||||
punctuation: '!',
|
||||
pick: function(array, index) {
|
||||
return array[index];
|
||||
}
|
||||
};
|
||||
|
||||
// access two members in the scope
|
||||
exp = new ol.Expression('greeting + punctuation');
|
||||
expect(exp.evaluate({}, scope)).toBe('hello world!');
|
||||
|
||||
// call a function in the scope
|
||||
exp = new ol.Expression(
|
||||
'pick([10, 42, "chicken"], 2) + Math.floor(Math.PI)');
|
||||
expect(exp.evaluate({}, scope)).toBe('chicken3');
|
||||
|
||||
});
|
||||
|
||||
it('throws on error', function() {
|
||||
var exp = new ol.Expression('@*)$(&');
|
||||
expect(function() {exp.evaluate()}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
201
test/spec/ol/feature.test.js
Normal file
201
test/spec/ol/feature.test.js
Normal file
@@ -0,0 +1,201 @@
|
||||
goog.provide('ol.test.Feature');
|
||||
|
||||
describe('ol.Feature', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a new feature', function() {
|
||||
var feature = new ol.Feature();
|
||||
expect(feature).toBeA(ol.Feature);
|
||||
});
|
||||
|
||||
it('takes attribute values', function() {
|
||||
var feature = new ol.Feature({
|
||||
foo: 'bar'
|
||||
});
|
||||
expect(feature.get('foo')).toBe('bar');
|
||||
});
|
||||
|
||||
it('will set the default geometry', function() {
|
||||
var feature = new ol.Feature({
|
||||
loc: new ol.geom.Point([10, 20]),
|
||||
foo: 'bar'
|
||||
});
|
||||
var geometry = feature.getGeometry();
|
||||
expect(geometry).toBeA(ol.geom.Point);
|
||||
expect(feature.get('loc')).toBe(geometry);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#get()', function() {
|
||||
|
||||
it('returns values set at construction', function() {
|
||||
var feature = new ol.Feature({
|
||||
a: 'first',
|
||||
b: 'second'
|
||||
});
|
||||
expect(feature.get('a')).toBe('first');
|
||||
expect(feature.get('b')).toBe('second');
|
||||
});
|
||||
|
||||
it('returns undefined for unset attributes', function() {
|
||||
var feature = new ol.Feature();
|
||||
expect(feature.get('a')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns values set by set', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.set('a', 'b');
|
||||
expect(feature.get('a')).toBe('b');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getAttributes()', function() {
|
||||
|
||||
it('returns an object with all attributes', function() {
|
||||
var point = new ol.geom.Point([15, 30]);
|
||||
var feature = new ol.Feature({
|
||||
foo: 'bar',
|
||||
ten: 10,
|
||||
loc: point
|
||||
});
|
||||
|
||||
var attributes = feature.getAttributes();
|
||||
|
||||
var keys = goog.object.getKeys(attributes);
|
||||
expect(keys.sort()).toEqual(['foo', 'loc', 'ten']);
|
||||
|
||||
expect(attributes.foo).toBe('bar');
|
||||
expect(attributes.loc).toBe(point);
|
||||
expect(attributes.ten).toBe(10);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('#getGeometry()', function() {
|
||||
|
||||
var point = new ol.geom.Point([15, 30]);
|
||||
|
||||
it('returns null for no geometry', function() {
|
||||
var feature = new ol.Feature();
|
||||
expect(feature.getGeometry()).toBeNull();
|
||||
});
|
||||
|
||||
it('gets the geometry set at construction', function() {
|
||||
var feature = new ol.Feature({
|
||||
geom: point
|
||||
});
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
});
|
||||
|
||||
it('gets any geometry set by setGeometry', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.setGeometry(point);
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
|
||||
var point2 = new ol.geom.Point([1, 2]);
|
||||
feature.setGeometry(point2);
|
||||
expect(feature.getGeometry()).toBe(point2);
|
||||
});
|
||||
|
||||
it('gets the first geometry set by set', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.set('foo', point);
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
|
||||
feature.set('bar', new ol.geom.Point([1, 2]));
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#set()', function() {
|
||||
|
||||
it('sets values', function() {
|
||||
var feature = new ol.Feature({
|
||||
a: 'first',
|
||||
b: 'second'
|
||||
});
|
||||
feature.set('a', 'new');
|
||||
expect(feature.get('a')).toBe('new');
|
||||
});
|
||||
|
||||
it('can be used to set the geometry', function() {
|
||||
var point = new ol.geom.Point([3, 4]);
|
||||
var feature = new ol.Feature({
|
||||
loc: new ol.geom.Point([1, 2])
|
||||
});
|
||||
feature.set('loc', point);
|
||||
expect(feature.get('loc')).toBe(point);
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
});
|
||||
|
||||
it('can be used to set attributes with arbitrary names', function() {
|
||||
|
||||
var feature = new ol.Feature();
|
||||
|
||||
feature.set('toString', 'string');
|
||||
expect(feature.get('toString')).toBe('string');
|
||||
expect(typeof feature.toString).toBe('function');
|
||||
|
||||
feature.set('getGeometry', 'x');
|
||||
expect(feature.get('getGeometry')).toBe('x');
|
||||
|
||||
feature.set('geom', new ol.geom.Point([1, 2]));
|
||||
expect(feature.getGeometry()).toBeA(ol.geom.Point);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#setGeometry()', function() {
|
||||
|
||||
var point = new ol.geom.Point([15, 30]);
|
||||
|
||||
it('sets the default geometry', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.setGeometry(point);
|
||||
expect(feature.get(ol.Feature.DEFAULT_GEOMETRY)).toBe(point);
|
||||
});
|
||||
|
||||
it('replaces previous default geometry', function() {
|
||||
var feature = new ol.Feature({
|
||||
geom: point
|
||||
});
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
|
||||
var point2 = new ol.geom.Point([1, 2]);
|
||||
feature.setGeometry(point2);
|
||||
expect(feature.getGeometry()).toBe(point2);
|
||||
});
|
||||
|
||||
it('gets any geometry set by setGeometry', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.setGeometry(point);
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
|
||||
var point2 = new ol.geom.Point([1, 2]);
|
||||
feature.setGeometry(point2);
|
||||
expect(feature.getGeometry()).toBe(point2);
|
||||
});
|
||||
|
||||
it('gets the first geometry set by set', function() {
|
||||
var feature = new ol.Feature();
|
||||
feature.set('foo', point);
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
|
||||
feature.set('bar', new ol.geom.Point([1, 2]));
|
||||
expect(feature.getGeometry()).toBe(point);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.Point');
|
||||
37
test/spec/ol/filter/extentfilter.test.js
Normal file
37
test/spec/ol/filter/extentfilter.test.js
Normal file
@@ -0,0 +1,37 @@
|
||||
goog.provide('ol.test.filter.Extent');
|
||||
|
||||
|
||||
describe('ol.filter.Extent', function() {
|
||||
|
||||
var extent, filter;
|
||||
|
||||
beforeEach(function() {
|
||||
extent = new ol.Extent(0, 0, 45, 90);
|
||||
filter = new ol.filter.Extent(extent);
|
||||
});
|
||||
|
||||
describe('#getExtent()', function() {
|
||||
|
||||
it('returns the configured extent', function() {
|
||||
expect(filter.getExtent()).toBe(extent);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#evaluate()', function() {
|
||||
|
||||
it('returns true if a feature intersects, false if not', function() {
|
||||
expect(filter.applies(new ol.Feature({g: new ol.geom.Point([44, 89])})))
|
||||
.toBe(true);
|
||||
expect(filter.applies(new ol.Feature({g: new ol.geom.Point([46, 91])})))
|
||||
.toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.geom.Point');
|
||||
51
test/spec/ol/filter/geometryfilter.test.js
Normal file
51
test/spec/ol/filter/geometryfilter.test.js
Normal file
@@ -0,0 +1,51 @@
|
||||
goog.provide('ol.test.filter.Geometry');
|
||||
|
||||
|
||||
describe('ol.filter.Geometry', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
it('creates a new filter', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.POINT);
|
||||
expect(filter).toBeA(ol.filter.Geometry);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getType()', function() {
|
||||
|
||||
it('works for point', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.POINT);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.POINT);
|
||||
});
|
||||
|
||||
it('works for linestring', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.LINESTRING);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.LINESTRING);
|
||||
});
|
||||
|
||||
it('works for polygon', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.POLYGON);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.POLYGON);
|
||||
});
|
||||
|
||||
it('works for multi-point', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.MULTIPOINT);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.MULTIPOINT);
|
||||
});
|
||||
|
||||
it('works for multi-linestring', function() {
|
||||
var filter = new ol.filter.Geometry(
|
||||
ol.filter.GeometryType.MULTILINESTRING);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.MULTILINESTRING);
|
||||
});
|
||||
|
||||
it('works for multi-polygon', function() {
|
||||
var filter = new ol.filter.Geometry(ol.filter.GeometryType.MULTIPOLYGON);
|
||||
expect(filter.getType()).toBe(ol.filter.GeometryType.MULTIPOLYGON);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.GeometryType');
|
||||
79
test/spec/ol/geom/geometrycollection.test.js
Normal file
79
test/spec/ol/geom/geometrycollection.test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
goog.provide('ol.test.geom.GeometryCollection');
|
||||
|
||||
describe('ol.geom.GeometryCollection', function() {
|
||||
|
||||
var outer = [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
|
||||
inner1 = [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]],
|
||||
inner2 = [[8, 8], [9, 8], [9, 9], [8, 9], [8, 8]];
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
|
||||
it('creates a geometry collection from an array of geometries', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
var multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||
expect(multi).toBeA(ol.geom.GeometryCollection);
|
||||
expect(multi).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#components', function() {
|
||||
|
||||
it('is an array of geometries', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
var multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||
|
||||
expect(multi.components.length).toBe(3);
|
||||
expect(multi.components[0]).toBeA(ol.geom.Point);
|
||||
expect(multi.components[1]).toBeA(ol.geom.LineString);
|
||||
expect(multi.components[2]).toBeA(ol.geom.Polygon);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
var multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||
expect(multi.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var multi = new ol.geom.GeometryCollection([
|
||||
new ol.geom.Point([30, 40, 50])
|
||||
]);
|
||||
expect(multi.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var point = new ol.geom.Point([10, 2]);
|
||||
var line = new ol.geom.LineString([[1, 20], [30, 40]]);
|
||||
var multi = new ol.geom.GeometryCollection([point, line]);
|
||||
var bounds = multi.getBounds();
|
||||
expect(bounds.minX).toBe(1);
|
||||
expect(bounds.minY).toBe(2);
|
||||
expect(bounds.maxX).toBe(30);
|
||||
expect(bounds.maxY).toBe(40);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryCollection');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
45
test/spec/ol/geom/linearring.test.js
Normal file
45
test/spec/ol/geom/linearring.test.js
Normal file
@@ -0,0 +1,45 @@
|
||||
goog.provide('ol.test.geom.LinearRing');
|
||||
|
||||
describe('ol.geom.LinearRing', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a ring from an array', function() {
|
||||
var ring = new ol.geom.LinearRing([[10, 20], [30, 40]]);
|
||||
expect(ring).toBeA(ol.geom.LinearRing);
|
||||
});
|
||||
|
||||
it('throws when given mismatched dimension', function() {
|
||||
expect(function() {
|
||||
var ring = new ol.geom.LinearRing([[10, 20], [30, 40, 50]]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var ring = new ol.geom.LinearRing([[10, 20], [30, 40]]);
|
||||
expect(ring.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var ring = new ol.geom.LinearRing([[10, 20, 30], [40, 50, 60]]);
|
||||
expect(ring.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates()', function() {
|
||||
|
||||
it('is an array', function() {
|
||||
var ring = new ol.geom.LinearRing([[10, 20], [30, 40]]);
|
||||
expect(ring.getCoordinates()).toEqual([[10, 20], [30, 40]]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.LinearRing');
|
||||
103
test/spec/ol/geom/linestring.test.js
Normal file
103
test/spec/ol/geom/linestring.test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
goog.provide('ol.test.geom.LineString');
|
||||
|
||||
describe('ol.geom.LineString', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a linestring from an array', function() {
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
expect(line).toBeA(ol.geom.LineString);
|
||||
expect(line).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('throws when given mismatched dimension', function() {
|
||||
expect(function() {
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40, 50]]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('accepts shared vertices', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var l1 = new ol.geom.LineString([[10, 20], [30, 40]], vertices);
|
||||
var l2 = new ol.geom.LineString([[50, 60], [70, 80]], vertices);
|
||||
expect(l1.getCoordinates()).toEqual([[10, 20], [30, 40]]);
|
||||
expect(l2.getCoordinates()).toEqual([[50, 60], [70, 80]]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
expect(line.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var line = new ol.geom.LineString([[10, 20, 30], [40, 50, 60]]);
|
||||
expect(line.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var line = new ol.geom.LineString([[10, 20], [20, 30], [30, 40]]);
|
||||
var bounds = line.getBounds();
|
||||
expect(bounds.minX).toBe(10);
|
||||
expect(bounds.minY).toBe(20);
|
||||
expect(bounds.maxX).toBe(30);
|
||||
expect(bounds.maxY).toBe(40);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
expect(line.getCoordinates()).toEqual([[10, 20], [30, 40]]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getSharedId()', function() {
|
||||
|
||||
it('returns identifiers', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
|
||||
var l1 = new ol.geom.LineString([[10, 20], [30, 40]], vertices);
|
||||
var l2 = new ol.geom.LineString(
|
||||
[[50, 60], [70, 80], [90, 100]], vertices);
|
||||
|
||||
var id1 = l1.getSharedId();
|
||||
var id2 = l2.getSharedId();
|
||||
|
||||
expect(vertices.coordinates).toEqual(
|
||||
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
|
||||
|
||||
expect(vertices.getStart(id1)).toBe(0);
|
||||
expect(vertices.getCount(id1)).toBe(2);
|
||||
expect(vertices.get(id1, 0, 0)).toBe(10);
|
||||
expect(vertices.get(id1, 0, 1)).toBe(20);
|
||||
expect(vertices.get(id1, 1, 0)).toBe(30);
|
||||
expect(vertices.get(id1, 1, 1)).toBe(40);
|
||||
|
||||
expect(vertices.getStart(id2)).toBe(4);
|
||||
expect(vertices.getCount(id2)).toBe(3);
|
||||
expect(vertices.get(id2, 0, 0)).toBe(50);
|
||||
expect(vertices.get(id2, 0, 1)).toBe(60);
|
||||
expect(vertices.get(id2, 1, 0)).toBe(70);
|
||||
expect(vertices.get(id2, 1, 1)).toBe(80);
|
||||
expect(vertices.get(id2, 2, 0)).toBe(90);
|
||||
expect(vertices.get(id2, 2, 1)).toBe(100);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
88
test/spec/ol/geom/multilinestring.test.js
Normal file
88
test/spec/ol/geom/multilinestring.test.js
Normal file
@@ -0,0 +1,88 @@
|
||||
goog.provide('ol.test.geom.MultiLineString');
|
||||
|
||||
describe('ol.geom.MultiLineString', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a multi-linestring from an array', function() {
|
||||
var multi = new ol.geom.MultiLineString([
|
||||
[[10, 20], [30, 40]],
|
||||
[[20, 30], [40, 50]]]);
|
||||
expect(multi).toBeA(ol.geom.MultiLineString);
|
||||
expect(multi).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('throws when given with insufficient dimensions', function() {
|
||||
expect(function() {
|
||||
var multi = new ol.geom.MultiLineString([1]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#components', function() {
|
||||
|
||||
it('is an array of linestrings', function() {
|
||||
var multi = new ol.geom.MultiLineString([
|
||||
[[10, 20], [30, 40]],
|
||||
[[20, 30], [40, 50]]]);
|
||||
|
||||
expect(multi.components.length).toBe(2);
|
||||
expect(multi.components[0]).toBeA(ol.geom.LineString);
|
||||
expect(multi.components[1]).toBeA(ol.geom.LineString);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var multi = new ol.geom.MultiLineString([
|
||||
[[10, 20], [30, 40]],
|
||||
[[20, 30], [40, 50]]]);
|
||||
expect(multi.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var multi = new ol.geom.MultiLineString([
|
||||
[[10, 20, 30], [30, 40, 50]],
|
||||
[[20, 30, 40], [40, 50, 60]]]);
|
||||
expect(multi.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var multi = new ol.geom.MultiLineString([
|
||||
[[10, 20], [30, 40]],
|
||||
[[20, 30], [40, 50]]]);
|
||||
var bounds = multi.getBounds();
|
||||
expect(bounds.minX).toBe(10);
|
||||
expect(bounds.minY).toBe(20);
|
||||
expect(bounds.maxX).toBe(40);
|
||||
expect(bounds.maxY).toBe(50);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var coordinates = [
|
||||
[[10, 20], [30, 40]],
|
||||
[[20, 30], [40, 50]]
|
||||
];
|
||||
var multi = new ol.geom.MultiLineString(coordinates);
|
||||
expect(multi.getCoordinates()).toEqual(coordinates);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.MultiLineString');
|
||||
74
test/spec/ol/geom/multipoint.test.js
Normal file
74
test/spec/ol/geom/multipoint.test.js
Normal file
@@ -0,0 +1,74 @@
|
||||
goog.provide('ol.test.geom.MultiPoint');
|
||||
|
||||
describe('ol.geom.MultiPoint', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a multi-point from an array', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
|
||||
expect(multi).toBeA(ol.geom.MultiPoint);
|
||||
expect(multi).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('throws when given with insufficient dimensions', function() {
|
||||
expect(function() {
|
||||
var multi = new ol.geom.MultiPoint([1]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#components', function() {
|
||||
|
||||
it('is an array of points', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
|
||||
|
||||
expect(multi.components.length).toBe(2);
|
||||
expect(multi.components[0]).toBeA(ol.geom.Point);
|
||||
expect(multi.components[1]).toBeA(ol.geom.Point);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
|
||||
expect(multi.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20, 30], [30, 40, 50]]);
|
||||
expect(multi.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
|
||||
var bounds = multi.getBounds();
|
||||
expect(bounds.minX).toBe(10);
|
||||
expect(bounds.minY).toBe(20);
|
||||
expect(bounds.maxX).toBe(30);
|
||||
expect(bounds.maxY).toBe(40);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
|
||||
expect(multi.getCoordinates()).toEqual([[10, 20], [30, 40]]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.Point');
|
||||
92
test/spec/ol/geom/multipolygon.test.js
Normal file
92
test/spec/ol/geom/multipolygon.test.js
Normal file
@@ -0,0 +1,92 @@
|
||||
goog.provide('ol.test.geom.MultiPolygon');
|
||||
|
||||
describe('ol.geom.MultiPolygon', function() {
|
||||
|
||||
var outer1 = [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
|
||||
inner1a = [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]],
|
||||
inner1b = [[8, 8], [9, 8], [9, 9], [8, 9], [8, 8]],
|
||||
outer2 = [[10, 10], [20, 0], [20, 50], [10, 50], [10, 10]];
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a multi-linestring from an array', function() {
|
||||
var multi = new ol.geom.MultiPolygon([
|
||||
[outer1, inner1a, inner1b],
|
||||
[outer2]]);
|
||||
expect(multi).toBeA(ol.geom.MultiPolygon);
|
||||
expect(multi).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('throws when given with insufficient dimensions', function() {
|
||||
expect(function() {
|
||||
var multi = new ol.geom.MultiPolygon([1]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#components', function() {
|
||||
|
||||
it('is an array of polygons', function() {
|
||||
var multi = new ol.geom.MultiPolygon([
|
||||
[outer1, inner1a, inner1b],
|
||||
[outer2]]);
|
||||
|
||||
expect(multi.components.length).toBe(2);
|
||||
expect(multi.components[0]).toBeA(ol.geom.Polygon);
|
||||
expect(multi.components[1]).toBeA(ol.geom.Polygon);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var multi = new ol.geom.MultiPolygon([
|
||||
[outer1, inner1a, inner1b],
|
||||
[outer2]]);
|
||||
expect(multi.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var multi = new ol.geom.MultiPolygon([[[[10, 20, 30], [40, 50, 60]]]]);
|
||||
expect(multi.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var multi = new ol.geom.MultiPolygon([
|
||||
[outer1, inner1a, inner1b],
|
||||
[outer2]]);
|
||||
var bounds = multi.getBounds();
|
||||
expect(bounds.minX).toBe(0);
|
||||
expect(bounds.minY).toBe(0);
|
||||
expect(bounds.maxX).toBe(20);
|
||||
expect(bounds.maxY).toBe(50);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var coordinates = [
|
||||
[outer1, inner1a, inner1b],
|
||||
[outer2]
|
||||
];
|
||||
var multi = new ol.geom.MultiPolygon(coordinates);
|
||||
expect(multi.getCoordinates()).toEqual(coordinates);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Polygon');
|
||||
106
test/spec/ol/geom/point.test.js
Normal file
106
test/spec/ol/geom/point.test.js
Normal file
@@ -0,0 +1,106 @@
|
||||
goog.provide('ol.test.geom.Point');
|
||||
|
||||
describe('ol.geom.Point', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a point from an array', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
expect(point).toBeA(ol.geom.Point);
|
||||
expect(point).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('accepts shared vertices', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var p1 = new ol.geom.Point([10, 20], vertices);
|
||||
var p2 = new ol.geom.Point([30, 40], vertices);
|
||||
var p3 = new ol.geom.Point([50, 60], vertices);
|
||||
expect(p1.getCoordinates()).toEqual([10, 20]);
|
||||
expect(p2.getCoordinates()).toEqual([30, 40]);
|
||||
expect(p3.getCoordinates()).toEqual([50, 60]);
|
||||
});
|
||||
|
||||
it('throws when given with insufficient dimensions', function() {
|
||||
expect(function() {
|
||||
var point = new ol.geom.Point([1]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
expect(point.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var point = new ol.geom.Point([10, 20, 30]);
|
||||
expect(point.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
var bounds = point.getBounds();
|
||||
expect(bounds.minX).toBe(10);
|
||||
expect(bounds.minY).toBe(20);
|
||||
expect(bounds.maxX).toBe(10);
|
||||
expect(bounds.maxY).toBe(20);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates()', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var point = new ol.geom.Point([10, 20]);
|
||||
expect(point.getCoordinates()).toEqual([10, 20]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('#getSharedId()', function() {
|
||||
|
||||
it('returns identifiers', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
|
||||
var p1 = new ol.geom.Point([10, 20], vertices);
|
||||
var p2 = new ol.geom.Point([30, 40], vertices);
|
||||
var p3 = new ol.geom.Point([50, 60], vertices);
|
||||
|
||||
var id1 = p1.getSharedId();
|
||||
var id2 = p2.getSharedId();
|
||||
var id3 = p3.getSharedId();
|
||||
|
||||
expect(vertices.coordinates).toEqual(
|
||||
[10, 20, 30, 40, 50, 60]);
|
||||
|
||||
expect(vertices.getStart(id1)).toBe(0);
|
||||
expect(vertices.getCount(id1)).toBe(1);
|
||||
expect(vertices.get(id1, 0, 0)).toBe(10);
|
||||
expect(vertices.get(id1, 0, 1)).toBe(20);
|
||||
|
||||
expect(vertices.getStart(id2)).toBe(2);
|
||||
expect(vertices.getCount(id2)).toBe(1);
|
||||
expect(vertices.get(id2, 0, 0)).toBe(30);
|
||||
expect(vertices.get(id2, 0, 1)).toBe(40);
|
||||
|
||||
expect(vertices.getStart(id3)).toBe(4);
|
||||
expect(vertices.getCount(id3)).toBe(1);
|
||||
expect(vertices.get(id3, 0, 0)).toBe(50);
|
||||
expect(vertices.get(id3, 0, 1)).toBe(60);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
89
test/spec/ol/geom/polygon.test.js
Normal file
89
test/spec/ol/geom/polygon.test.js
Normal file
@@ -0,0 +1,89 @@
|
||||
goog.provide('ol.test.geom.Polygon');
|
||||
|
||||
describe('ol.geom.Polygon', function() {
|
||||
|
||||
var outer = [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
|
||||
inner1 = [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]],
|
||||
inner2 = [[8, 8], [9, 8], [9, 9], [8, 9], [8, 8]];
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('creates a polygon from an array', function() {
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
expect(poly).toBeA(ol.geom.Polygon);
|
||||
expect(poly).toBeA(ol.geom.Geometry);
|
||||
});
|
||||
|
||||
it('throws when given mismatched dimension', function() {
|
||||
expect(function() {
|
||||
var poly = new ol.geom.Polygon([[[10, 20], [30, 40, 50]]]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('accepts shared vertices', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var p1 = new ol.geom.Polygon([outer], vertices);
|
||||
var p2 = new ol.geom.Polygon([outer, inner1], vertices);
|
||||
var p3 = new ol.geom.Polygon([outer, inner2], vertices);
|
||||
expect(p1.getCoordinates()).toEqual([outer]);
|
||||
expect(p2.getCoordinates()).toEqual([outer, inner1]);
|
||||
expect(p3.getCoordinates()).toEqual([outer, inner2]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#rings', function() {
|
||||
|
||||
it('is an array of LinearRing', function() {
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
|
||||
expect(poly.rings.length).toBe(3);
|
||||
expect(poly.rings[0]).toBeA(ol.geom.LinearRing);
|
||||
expect(poly.rings[1]).toBeA(ol.geom.LinearRing);
|
||||
expect(poly.rings[2]).toBeA(ol.geom.LinearRing);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#dimension', function() {
|
||||
|
||||
it('can be 2', function() {
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
expect(poly.dimension).toBe(2);
|
||||
});
|
||||
|
||||
it('can be 3', function() {
|
||||
var poly = new ol.geom.Polygon([[[10, 20, 30], [40, 50, 60]]]);
|
||||
expect(poly.dimension).toBe(3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getBounds()', function() {
|
||||
|
||||
it('returns the bounding extent', function() {
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
var bounds = poly.getBounds();
|
||||
expect(bounds.minX).toBe(0);
|
||||
expect(bounds.minY).toBe(0);
|
||||
expect(bounds.maxX).toBe(10);
|
||||
expect(bounds.maxY).toBe(10);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCoordinates()', function() {
|
||||
|
||||
it('returns an array', function() {
|
||||
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
expect(poly.getCoordinates()).toEqual([outer, inner1, inner2]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.LinearRing');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
202
test/spec/ol/geom/sharedvertices.test.js
Normal file
202
test/spec/ol/geom/sharedvertices.test.js
Normal file
@@ -0,0 +1,202 @@
|
||||
goog.provide('ol.test.geom.SharedVertices');
|
||||
|
||||
describe('ol.geom.SharedVertices', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
it('creates an instance', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
expect(vertices).toBeA(ol.geom.SharedVertices);
|
||||
});
|
||||
|
||||
it('accepts options', function() {
|
||||
var vertices = new ol.geom.SharedVertices({
|
||||
dimension: 4,
|
||||
offset: [1, 2, 3, 4]
|
||||
});
|
||||
|
||||
expect(vertices.getDimension()).toBe(4);
|
||||
expect(vertices.getOffset()).toEqual([1, 2, 3, 4]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('offset option', function() {
|
||||
it('offsets the internally stored vertex coordinates', function() {
|
||||
var vertices = new ol.geom.SharedVertices({offset: [3, -1]});
|
||||
vertices.add([[3, -1], [0, 0]]);
|
||||
vertices.add([[10, 20]]);
|
||||
expect(vertices.coordinates).toEqual([0, 0, -3, 1, 7, 21]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#add()', function() {
|
||||
it('adds vertex arrays to the shared coordinates', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
expect(vertices.coordinates.length).toBe(0);
|
||||
|
||||
vertices.add([[1, 2], [3, 4]]);
|
||||
expect(vertices.coordinates).toEqual([1, 2, 3, 4]);
|
||||
|
||||
vertices.add([[5, 6]]);
|
||||
expect(vertices.coordinates).toEqual([1, 2, 3, 4, 5, 6]);
|
||||
});
|
||||
|
||||
it('returns an identifier for coordinate access', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var id = vertices.add([[1, 2], [3, 4]]);
|
||||
expect(typeof id).toBe('number');
|
||||
});
|
||||
|
||||
it('returns the index of the added vertices', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
|
||||
var first = vertices.add([[1, 2]]);
|
||||
var second = vertices.add([[3, 4], [5, 6]]);
|
||||
var third = vertices.add([[7, 8], [9, 10], [11, 12]]);
|
||||
|
||||
expect(vertices.coordinates).toEqual(
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
|
||||
expect(first).toBe(0);
|
||||
expect(second).toBe(1);
|
||||
expect(third).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#get()', function() {
|
||||
it('provides access to vertex coordinates', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[1, 2], [3, 4]]);
|
||||
var second = vertices.add([[5, 6]]);
|
||||
|
||||
expect(vertices.get(first, 0, 0)).toBe(1);
|
||||
expect(vertices.get(first, 0, 1)).toBe(2);
|
||||
expect(vertices.get(first, 1, 0)).toBe(3);
|
||||
expect(vertices.get(first, 1, 1)).toBe(4);
|
||||
expect(vertices.get(second, 0, 0)).toBe(5);
|
||||
expect(vertices.get(second, 0, 1)).toBe(6);
|
||||
});
|
||||
|
||||
it('works for non-2d vertices', function() {
|
||||
var vertices = new ol.geom.SharedVertices({dimension: 3});
|
||||
var id = vertices.add([[1, 2, 3], [4, 5, 6]]);
|
||||
|
||||
expect(vertices.get(id, 0, 0)).toBe(1);
|
||||
expect(vertices.get(id, 0, 1)).toBe(2);
|
||||
expect(vertices.get(id, 0, 2)).toBe(3);
|
||||
expect(vertices.get(id, 1, 0)).toBe(4);
|
||||
expect(vertices.get(id, 1, 1)).toBe(5);
|
||||
expect(vertices.get(id, 1, 2)).toBe(6);
|
||||
});
|
||||
|
||||
it('works when an offset is provided', function() {
|
||||
var vertices = new ol.geom.SharedVertices({offset: [3, 3]});
|
||||
var id = vertices.add([[1, 2], [3, 4], [5, 6]]);
|
||||
|
||||
expect(vertices.get(id, 0, 0)).toBe(1);
|
||||
expect(vertices.get(id, 0, 1)).toBe(2);
|
||||
expect(vertices.get(id, 1, 0)).toBe(3);
|
||||
expect(vertices.get(id, 1, 1)).toBe(4);
|
||||
expect(vertices.get(id, 2, 0)).toBe(5);
|
||||
expect(vertices.get(id, 2, 1)).toBe(6);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getCount()', function() {
|
||||
it('returns the length of an identified vertex array', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[2, 3], [3, 4], [4, 5]]);
|
||||
var second = vertices.add([[5, 6], [6, 6]]);
|
||||
|
||||
expect(vertices.getCount(first)).toBe(3);
|
||||
expect(vertices.getCount(second)).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getCounts()', function() {
|
||||
it('returns the counts array', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[2, 3], [3, 4], [4, 5]]);
|
||||
var second = vertices.add([[5, 6], [6, 6]]);
|
||||
var third = vertices.add([[7, 8]]);
|
||||
|
||||
expect(vertices.getCounts()).toEqual([3, 2, 1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getDimension()', function() {
|
||||
it('returns 2 by default', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
expect(vertices.getDimension()).toBe(2);
|
||||
});
|
||||
|
||||
it('returns the dimension provided to the constructor', function() {
|
||||
var vertices = new ol.geom.SharedVertices({dimension: 10});
|
||||
expect(vertices.getDimension()).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getOffset()', function() {
|
||||
it('returns null by default', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
expect(vertices.getOffset()).toBeNull();
|
||||
});
|
||||
|
||||
it('returns the offset provided to the constructor', function() {
|
||||
var vertices = new ol.geom.SharedVertices({offset: [1, 2]});
|
||||
expect(vertices.getOffset()).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getStart()', function() {
|
||||
it('returns the start index of an identified vertex array', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[2, 3], [4, 5], [6, 7]]);
|
||||
var second = vertices.add([[8, 9], [10, 11]]);
|
||||
var third = vertices.add([[12, 13]]);
|
||||
|
||||
expect(vertices.coordinates).toEqual(
|
||||
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11
|
||||
|
||||
expect(vertices.getStart(first)).toBe(0);
|
||||
expect(vertices.getStart(second)).toBe(6);
|
||||
expect(vertices.getStart(third)).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getStarts()', function() {
|
||||
it('returns the counts array', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[2, 3], [3, 4], [4, 5]]);
|
||||
var second = vertices.add([[5, 6], [6, 6]]);
|
||||
var third = vertices.add([[7, 8]]);
|
||||
|
||||
expect(vertices.getStarts()).toEqual([0, 6, 10]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#coordinates', function() {
|
||||
it('is a flat array of all coordinate values', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[1, 2], [3, 4]]);
|
||||
var second = vertices.add([[5, 6]]);
|
||||
var third = vertices.add([[7, 8], [9, 10], [11, 12]]);
|
||||
expect(vertices.coordinates).toEqual(
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
});
|
||||
|
||||
it('is not reassigned', function() {
|
||||
var vertices = new ol.geom.SharedVertices();
|
||||
var first = vertices.add([[1, 2], [3, 4]]);
|
||||
var coordinates = vertices.coordinates;
|
||||
|
||||
var second = vertices.add([[5, 6]]);
|
||||
expect(vertices.coordinates).toBe(coordinates);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
195
test/spec/ol/layer/vectorlayer.test.js
Normal file
195
test/spec/ol/layer/vectorlayer.test.js
Normal file
@@ -0,0 +1,195 @@
|
||||
goog.provide('ol.test.layer.Vector');
|
||||
|
||||
describe('ol.layer.Vector', function() {
|
||||
|
||||
describe('#addFeatures()', function() {
|
||||
|
||||
it('allows adding features', function() {
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures([new ol.Feature(), new ol.Feature()]);
|
||||
expect(layer.getFeatures().length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getFeatures()', function() {
|
||||
|
||||
var layer, features;
|
||||
|
||||
beforeEach(function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.0, 48.0])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.1, 48.1])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.2, 48.2])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.Point([16.3, 48.3])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.4, 48.4], [16.5, 48.5]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.6, 48.6], [16.7, 48.7]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[16.8, 48.8], [16.9, 48.9]])
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[17.0, 49.0], [17.1, 49.1]])
|
||||
})
|
||||
];
|
||||
layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({})
|
||||
});
|
||||
layer.addFeatures(features);
|
||||
});
|
||||
|
||||
var geomFilter = new ol.filter.Geometry(ol.geom.GeometryType.LINESTRING);
|
||||
var extentFilter = new ol.filter.Extent(new ol.Extent(16, 48, 16.3, 48.3));
|
||||
|
||||
it('can filter by geometry type using its GeometryType index', function() {
|
||||
spyOn(geomFilter, 'applies');
|
||||
var lineStrings = layer.getFeatures(geomFilter);
|
||||
expect(geomFilter.applies).not.toHaveBeenCalled();
|
||||
expect(lineStrings.length).toEqual(4);
|
||||
expect(lineStrings).toContain(features[4]);
|
||||
});
|
||||
|
||||
it('can filter by extent using its RTree', function() {
|
||||
spyOn(extentFilter, 'applies');
|
||||
var subset = layer.getFeatures(extentFilter);
|
||||
expect(extentFilter.applies).not.toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(4);
|
||||
expect(subset).not.toContain(features[7]);
|
||||
});
|
||||
|
||||
it('can filter by extent and geometry type using its index', function() {
|
||||
var filter1 = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
var filter2 = new ol.filter.Logical([extentFilter, geomFilter],
|
||||
ol.filter.LogicalOperator.AND);
|
||||
spyOn(filter1, 'applies');
|
||||
spyOn(filter2, 'applies');
|
||||
var subset1 = layer.getFeatures(filter1);
|
||||
var subset2 = layer.getFeatures(filter2);
|
||||
expect(filter1.applies).not.toHaveBeenCalled();
|
||||
expect(filter2.applies).not.toHaveBeenCalled();
|
||||
expect(subset1.length).toEqual(0);
|
||||
expect(subset2.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('can handle query using the filter\'s applies function', function() {
|
||||
var filter = new ol.filter.Logical([geomFilter, extentFilter],
|
||||
ol.filter.LogicalOperator.OR);
|
||||
spyOn(filter, 'applies').andCallThrough();
|
||||
var subset = layer.getFeatures(filter);
|
||||
expect(filter.applies).toHaveBeenCalled();
|
||||
expect(subset.length).toEqual(8);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#groupFeaturesBySymbolizerLiteral()', function() {
|
||||
|
||||
var layer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
projection: ol.projection.get('EPSG:4326')
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
rules: [
|
||||
new ol.style.Rule({
|
||||
symbolizers: [
|
||||
new ol.style.Line({
|
||||
strokeWidth: 2,
|
||||
strokeColor: new ol.Expression('colorProperty'),
|
||||
opacity: 1
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
var features;
|
||||
|
||||
it('groups equal symbolizers', function() {
|
||||
features = [
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [10, -10]]),
|
||||
colorProperty: '#013'
|
||||
}),
|
||||
new ol.Feature({
|
||||
g: new ol.geom.LineString([[10, -10], [-10, -10]]),
|
||||
colorProperty: '#013'
|
||||
})
|
||||
];
|
||||
|
||||
var groups = layer.groupFeaturesBySymbolizerLiteral(features);
|
||||
expect(groups.length).toBe(2);
|
||||
expect(groups[0][0].length).toBe(1);
|
||||
expect(groups[0][1].strokeColor).toBe('#BADA55');
|
||||
expect(groups[1][0].length).toBe(2);
|
||||
expect(groups[1][1].strokeColor).toBe('#013');
|
||||
});
|
||||
|
||||
it('groups equal symbolizers also when defined on features', function() {
|
||||
var symbolizer = new ol.style.Line({
|
||||
strokeWidth: 3,
|
||||
strokeColor: new ol.Expression('colorProperty'),
|
||||
opacity: 1
|
||||
});
|
||||
var anotherSymbolizer = new ol.style.Line({
|
||||
strokeWidth: 3,
|
||||
strokeColor: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var featureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, -10], [-10, 10]]),
|
||||
colorProperty: '#BADA55'
|
||||
});
|
||||
featureWithSymbolizers.setSymbolizers([symbolizer]);
|
||||
var anotherFeatureWithSymbolizers = new ol.Feature({
|
||||
g: new ol.geom.LineString([[-10, 10], [-10, -10]])
|
||||
});
|
||||
anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]);
|
||||
features.push(featureWithSymbolizers, anotherFeatureWithSymbolizers);
|
||||
|
||||
var groups = layer.groupFeaturesBySymbolizerLiteral(features);
|
||||
expect(groups.length).toBe(3);
|
||||
expect(groups[2][0].length).toBe(2);
|
||||
expect(groups[2][1].strokeWidth).toBe(3);
|
||||
|
||||
});
|
||||
|
||||
layer.dispose();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.filter.Extent');
|
||||
goog.require('ol.filter.Geometry');
|
||||
goog.require('ol.filter.Logical');
|
||||
goog.require('ol.filter.LogicalOperator');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.projection');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Line');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Style');
|
||||
228
test/spec/ol/parser/geojson.test.js
Normal file
228
test/spec/ol/parser/geojson.test.js
Normal file
@@ -0,0 +1,228 @@
|
||||
goog.provide('ol.test.parser.GeoJSON');
|
||||
|
||||
describe('ol.parser.GeoJSON', function() {
|
||||
|
||||
var parser = new ol.parser.GeoJSON();
|
||||
|
||||
var data = {
|
||||
'type': 'FeatureCollection',
|
||||
'features': [
|
||||
{
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'LINK_ID': 573730499,
|
||||
'RP_TYPE': 14,
|
||||
'RP_FUNC': 0,
|
||||
'DIRECTION': 2,
|
||||
'LOGKOD': '',
|
||||
'CHANGED': '',
|
||||
'USERID': '',
|
||||
'ST_NAME': '',
|
||||
'L_REFADDR': '',
|
||||
'L_NREFADDR': '',
|
||||
'R_REFADDR': '',
|
||||
'R_NREFADDR': '',
|
||||
'SPEED_CAT': '7',
|
||||
'ZIPCODE': '59330',
|
||||
'SHAPE_LEN': 46.3826
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [
|
||||
[1549497.66985, 6403707.96],
|
||||
[1549491.1, 6403710.1],
|
||||
[1549488.03995, 6403716.7504],
|
||||
[1549488.5401, 6403724.5504],
|
||||
[1549494.37985, 6403733.54],
|
||||
[1549499.6799, 6403738.0504],
|
||||
[1549506.22, 6403739.2504]
|
||||
]
|
||||
}
|
||||
}, {
|
||||
'type': 'Feature',
|
||||
'properties': {
|
||||
'LINK_ID': 30760556,
|
||||
'RP_TYPE': 12,
|
||||
'RP_FUNC': 1,
|
||||
'DIRECTION': 0,
|
||||
'LOGKOD': '',
|
||||
'CHANGED': '',
|
||||
'USERID': '',
|
||||
'ST_NAME': 'BRUNNSGATAN',
|
||||
'L_REFADDR': '24',
|
||||
'L_NREFADDR': '16',
|
||||
'R_REFADDR': '',
|
||||
'R_NREFADDR': '',
|
||||
'SPEED_CAT': '7',
|
||||
'ZIPCODE': '59330',
|
||||
'SHAPE_LEN': 70.3106
|
||||
},
|
||||
'geometry': {
|
||||
'type': 'LineString',
|
||||
'coordinates': [
|
||||
[1549754.2769, 6403854.8024],
|
||||
[1549728.45985, 6403920.2]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
describe('#read()', function() {
|
||||
|
||||
it('parses point', function() {
|
||||
var str = JSON.stringify({
|
||||
type: 'Point',
|
||||
coordinates: [10, 20]
|
||||
});
|
||||
|
||||
var obj = parser.read(str);
|
||||
expect(obj).toBeA(ol.geom.Point);
|
||||
expect(obj.getCoordinates()).toEqual([10, 20]);
|
||||
});
|
||||
|
||||
it('parses linestring', function() {
|
||||
var str = JSON.stringify({
|
||||
type: 'LineString',
|
||||
coordinates: [[10, 20], [30, 40]]
|
||||
});
|
||||
|
||||
var obj = parser.read(str);
|
||||
expect(obj).toBeA(ol.geom.LineString);
|
||||
expect(obj.getCoordinates()).toEqual([[10, 20], [30, 40]]);
|
||||
});
|
||||
|
||||
it('parses polygon', function() {
|
||||
var outer = [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
|
||||
inner1 = [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]],
|
||||
inner2 = [[8, 8], [9, 8], [9, 9], [8, 9], [8, 8]],
|
||||
str = JSON.stringify({
|
||||
type: 'Polygon',
|
||||
coordinates: [outer, inner1, inner2]
|
||||
});
|
||||
|
||||
var obj = parser.read(str);
|
||||
expect(obj).toBeA(ol.geom.Polygon);
|
||||
expect(obj.rings.length).toBe(3);
|
||||
expect(obj.rings[0]).toBeA(ol.geom.LinearRing);
|
||||
expect(obj.rings[1]).toBeA(ol.geom.LinearRing);
|
||||
expect(obj.rings[2]).toBeA(ol.geom.LinearRing);
|
||||
});
|
||||
|
||||
it('parses geometry collection', function() {
|
||||
var str = JSON.stringify({
|
||||
type: 'GeometryCollection',
|
||||
geometries: [
|
||||
{type: 'Point', coordinates: [10, 20]},
|
||||
{type: 'LineString', coordinates: [[30, 40], [50, 60]]}
|
||||
]
|
||||
});
|
||||
|
||||
var array = parser.read(str);
|
||||
expect(array.length).toBe(2);
|
||||
expect(array[0]).toBeA(ol.geom.Point);
|
||||
expect(array[1]).toBeA(ol.geom.LineString);
|
||||
});
|
||||
|
||||
it('parses feature collection', function() {
|
||||
var str = JSON.stringify(data),
|
||||
array = parser.read(str);
|
||||
|
||||
expect(array.length).toBe(2);
|
||||
|
||||
var first = array[0];
|
||||
expect(first).toBeA(ol.Feature);
|
||||
expect(first.get('LINK_ID')).toBe(573730499);
|
||||
var firstGeom = first.getGeometry();
|
||||
expect(firstGeom).toBeA(ol.geom.LineString);
|
||||
|
||||
var second = array[1];
|
||||
expect(second).toBeA(ol.Feature);
|
||||
expect(second.get('ST_NAME')).toBe('BRUNNSGATAN');
|
||||
var secondGeom = second.getGeometry();
|
||||
expect(secondGeom).toBeA(ol.geom.LineString);
|
||||
});
|
||||
|
||||
it('parses countries.json', function() {
|
||||
afterLoadText('spec/ol/parser/geojson/countries.json', function(text) {
|
||||
var result = parser.read(text);
|
||||
expect(result.length).toBe(179);
|
||||
|
||||
var first = result[0];
|
||||
expect(first).toBeA(ol.Feature);
|
||||
expect(first.get('name')).toBe('Afghanistan');
|
||||
var firstGeom = first.getGeometry();
|
||||
expect(firstGeom).toBeA(ol.geom.Polygon);
|
||||
expect(firstGeom.getBounds().equals(
|
||||
new ol.Extent(60.52843, 29.318572, 75.158028, 38.486282)))
|
||||
.toBe(true);
|
||||
|
||||
var last = result[178];
|
||||
expect(last).toBeA(ol.Feature);
|
||||
expect(last.get('name')).toBe('Zimbabwe');
|
||||
var lastGeom = last.getGeometry();
|
||||
expect(lastGeom).toBeA(ol.geom.Polygon);
|
||||
expect(lastGeom.getBounds().equals(
|
||||
new ol.Extent(25.264226, -22.271612, 32.849861, -15.507787)))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('parses countries.json with shared vertices', function() {
|
||||
afterLoadText('spec/ol/parser/geojson/countries.json', function(text) {
|
||||
var pointVertices = new ol.geom.SharedVertices();
|
||||
var lineVertices = new ol.geom.SharedVertices();
|
||||
var polygonVertices = new ol.geom.SharedVertices();
|
||||
|
||||
var lookup = {
|
||||
'point': pointVertices,
|
||||
'linestring': lineVertices,
|
||||
'polygon': polygonVertices,
|
||||
'multipoint': pointVertices,
|
||||
'multilinstring': lineVertices,
|
||||
'multipolygon': polygonVertices
|
||||
};
|
||||
|
||||
var callback = function(feature, type) {
|
||||
return lookup[type];
|
||||
};
|
||||
|
||||
var result = parser.readFeaturesFromString(text, {callback: callback});
|
||||
expect(result.length).toBe(179);
|
||||
|
||||
expect(pointVertices.coordinates.length).toBe(0);
|
||||
expect(lineVertices.coordinates.length).toBe(0);
|
||||
expect(polygonVertices.coordinates.length).toBe(21344);
|
||||
|
||||
var first = result[0];
|
||||
expect(first).toBeA(ol.Feature);
|
||||
expect(first.get('name')).toBe('Afghanistan');
|
||||
var firstGeom = first.getGeometry();
|
||||
expect(firstGeom).toBeA(ol.geom.Polygon);
|
||||
expect(firstGeom.getBounds().equals(
|
||||
new ol.Extent(60.52843, 29.318572, 75.158028, 38.486282)))
|
||||
.toBe(true);
|
||||
|
||||
var last = result[178];
|
||||
expect(last).toBeA(ol.Feature);
|
||||
expect(last.get('name')).toBe('Zimbabwe');
|
||||
var lastGeom = last.getGeometry();
|
||||
expect(lastGeom).toBeA(ol.geom.Polygon);
|
||||
expect(lastGeom.getBounds().equals(
|
||||
new ol.Extent(25.264226, -22.271612, 32.849861, -15.507787)))
|
||||
.toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.LinearRing');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.geom.SharedVertices');
|
||||
goog.require('ol.parser.GeoJSON');
|
||||
181
test/spec/ol/parser/geojson/countries.json
Normal file
181
test/spec/ol/parser/geojson/countries.json
Normal file
File diff suppressed because one or more lines are too long
17
test/spec/ol/source/vectorsource.test.js
Normal file
17
test/spec/ol/source/vectorsource.test.js
Normal file
@@ -0,0 +1,17 @@
|
||||
goog.provide('ol.test.source.Vector');
|
||||
|
||||
|
||||
describe('ol.source.Vector', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
it('creates an instance', function() {
|
||||
var source = new ol.source.Vector({});
|
||||
expect(source).toBeA(ol.source.Vector);
|
||||
expect(source).toBeA(ol.source.Source);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.source.Source');
|
||||
goog.require('ol.source.Vector');
|
||||
62
test/spec/ol/structs/rtree.test.js
Normal file
62
test/spec/ol/structs/rtree.test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
goog.provide('ol.test.structs.RTree');
|
||||
|
||||
|
||||
describe('ol.structs.RTree', function() {
|
||||
|
||||
describe('put and find', function() {
|
||||
var rTree = new ol.structs.RTree();
|
||||
rTree.put(new ol.Rectangle(0, 0, 1, 1), 1);
|
||||
rTree.put(new ol.Rectangle(1, 1, 4, 4), 2);
|
||||
rTree.put(new ol.Rectangle(2, 2, 3, 3), 3);
|
||||
rTree.put(new ol.Rectangle(-5, -5, -4, -4), 4);
|
||||
rTree.put(new ol.Rectangle(-4, -4, -1, -1), 5);
|
||||
rTree.put(new ol.Rectangle(-3, -3, -2, -2), 6);
|
||||
|
||||
it('stores items', function() {
|
||||
expect(goog.object.getCount(rTree.find(new ol.Rectangle(
|
||||
Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY,
|
||||
Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY)))).toBe(6);
|
||||
});
|
||||
|
||||
it('filters by rectangle', function() {
|
||||
var result;
|
||||
result = goog.object.getValues(rTree.find(new ol.Rectangle(2, 2, 3, 3)));
|
||||
expect(result).toContain(2);
|
||||
expect(result).toContain(3);
|
||||
expect(result.length).toBe(2);
|
||||
result = goog.object.getValues(
|
||||
rTree.find(new ol.Rectangle(-1, -1, 2, 2)));
|
||||
expect(result).toContain(1);
|
||||
expect(result).toContain(2);
|
||||
expect(result).toContain(3);
|
||||
expect(result).toContain(5);
|
||||
expect(result.length).toBe(4);
|
||||
expect(goog.object.getCount(rTree.find(new ol.Rectangle(5, 5, 6, 6))))
|
||||
.toBe(0);
|
||||
});
|
||||
|
||||
it('can store thosands of items and find fast', function() {
|
||||
for (var i = 7; i <= 10000; ++i) {
|
||||
rTree.put(new ol.Rectangle(Math.random() * -10, Math.random() * -10,
|
||||
Math.random() * 10, Math.random() * 10), i);
|
||||
}
|
||||
expect(goog.object.getCount(
|
||||
rTree.find(new ol.Rectangle(-10, -10, 10, 10)))).toBe(10000);
|
||||
var result = rTree.find(new ol.Rectangle(0, 0, 0, 0));
|
||||
expect(goog.object.getCount(result)).toBe(9995);
|
||||
var values = goog.object.getValues(result);
|
||||
expect(values).toContain(1);
|
||||
expect(values).not.toContain(2);
|
||||
expect(values).not.toContain(3);
|
||||
expect(values).not.toContain(4);
|
||||
expect(values).not.toContain(5);
|
||||
expect(values).not.toContain(6);
|
||||
expect(values).toContain(7);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Rectangle');
|
||||
goog.require('ol.structs.RTree');
|
||||
79
test/spec/ol/style/line.test.js
Normal file
79
test/spec/ol/style/line.test.js
Normal file
@@ -0,0 +1,79 @@
|
||||
goog.provide('ol.test.style.Line');
|
||||
|
||||
describe('ol.style.LineLiteral', function() {
|
||||
|
||||
describe('#equals()', function() {
|
||||
|
||||
it('identifies equal literals', function() {
|
||||
var literal = new ol.style.LineLiteral({
|
||||
strokeWidth: 3,
|
||||
strokeColor: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var equalLiteral = new ol.style.LineLiteral({
|
||||
strokeColor: '#BADA55',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
var differentLiteral = new ol.style.LineLiteral({
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
expect(literal.equals(equalLiteral)).toBe(true);
|
||||
expect(literal.equals(differentLiteral)).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.style.Line', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('accepts literal values', function() {
|
||||
var symbolizer = new ol.style.Line({
|
||||
strokeColor: '#BADA55',
|
||||
strokeWidth: 3
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Line);
|
||||
});
|
||||
|
||||
it('accepts expressions', function() {
|
||||
var symbolizer = new ol.style.Line({
|
||||
opacity: new ol.Expression('value / 100'),
|
||||
strokeWidth: ol.Expression('widthAttr')
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Line);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#createLiteral()', function() {
|
||||
|
||||
it('evaluates expressions with the given feature', function() {
|
||||
var symbolizer = new ol.style.Line({
|
||||
opacity: new ol.Expression('value / 100'),
|
||||
strokeWidth: ol.Expression('widthAttr')
|
||||
});
|
||||
|
||||
var feature = new ol.Feature({
|
||||
value: 42,
|
||||
widthAttr: 1.5
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral(feature);
|
||||
expect(literal).toBeA(ol.style.LineLiteral);
|
||||
expect(literal.opacity).toBe(42 / 100);
|
||||
expect(literal.strokeWidth).toBe(1.5);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.style.Line');
|
||||
goog.require('ol.style.LineLiteral');
|
||||
95
test/spec/ol/style/polygon.test.js
Normal file
95
test/spec/ol/style/polygon.test.js
Normal file
@@ -0,0 +1,95 @@
|
||||
goog.provide('ol.test.style.Polygon');
|
||||
|
||||
describe('ol.style.PolygonLiteral', function() {
|
||||
|
||||
describe('#equals()', function() {
|
||||
|
||||
it('identifies equal literals', function() {
|
||||
var literal = new ol.style.PolygonLiteral({
|
||||
strokeWidth: 3,
|
||||
strokeColor: '#013',
|
||||
fillColor: '#BADA55',
|
||||
opacity: 1
|
||||
});
|
||||
var equalLiteral = new ol.style.PolygonLiteral({
|
||||
fillColor: '#BADA55',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
var differentLiteral = new ol.style.PolygonLiteral({
|
||||
fillColor: '#013',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
expect(literal.equals(equalLiteral)).toBe(true);
|
||||
expect(literal.equals(differentLiteral)).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.style.Polygon', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('accepts literal values', function() {
|
||||
var symbolizer = new ol.style.Polygon({
|
||||
fillColor: '#BADA55',
|
||||
strokeWidth: 3
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Polygon);
|
||||
});
|
||||
|
||||
it('accepts expressions', function() {
|
||||
var symbolizer = new ol.style.Polygon({
|
||||
opacity: new ol.Expression('value / 100'),
|
||||
fillColor: new ol.Expression('fillAttr')
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Polygon);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#createLiteral()', function() {
|
||||
|
||||
it('evaluates expressions with the given feature', function() {
|
||||
var symbolizer = new ol.style.Polygon({
|
||||
opacity: new ol.Expression('value / 100'),
|
||||
fillColor: new ol.Expression('fillAttr')
|
||||
});
|
||||
|
||||
var feature = new ol.Feature({
|
||||
value: 42,
|
||||
fillAttr: '#ff0000'
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral(feature);
|
||||
expect(literal).toBeA(ol.style.PolygonLiteral);
|
||||
expect(literal.opacity).toBe(42 / 100);
|
||||
expect(literal.fillColor).toBe('#ff0000');
|
||||
expect(literal.strokeColor).toBeUndefined();
|
||||
});
|
||||
|
||||
it('applies default strokeWidth if only strokeColor is given', function() {
|
||||
var symbolizer = new ol.style.Polygon({
|
||||
strokeColor: '#ff0000'
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral();
|
||||
expect(literal).toBeA(ol.style.PolygonLiteral);
|
||||
expect(literal.strokeColor).toBe('#ff0000');
|
||||
expect(literal.strokeWidth).toBe(1.5);
|
||||
expect(literal.fillColor).toBeUndefined();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.style.Polygon');
|
||||
goog.require('ol.style.PolygonLiteral');
|
||||
33
test/spec/ol/style/rule.test.js
Normal file
33
test/spec/ol/style/rule.test.js
Normal file
@@ -0,0 +1,33 @@
|
||||
goog.provide('ol.test.style.Rule');
|
||||
|
||||
describe('ol.style.Rule', function() {
|
||||
|
||||
describe('#applies()', function() {
|
||||
var feature = new ol.Feature(),
|
||||
rule;
|
||||
|
||||
it('returns true for a rule without filter', function() {
|
||||
rule = new ol.style.Rule({});
|
||||
expect(rule.applies(feature)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when the rule does not apply', function() {
|
||||
rule = new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function() { return false; })
|
||||
});
|
||||
expect(rule.applies(feature)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true when the rule applies', function() {
|
||||
rule = new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function() { return true; })
|
||||
});
|
||||
expect(rule.applies(feature)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.style.Rule');
|
||||
126
test/spec/ol/style/shape.test.js
Normal file
126
test/spec/ol/style/shape.test.js
Normal file
@@ -0,0 +1,126 @@
|
||||
goog.provide('ol.test.style.Shape');
|
||||
|
||||
describe('ol.style.ShapeLiteral', function() {
|
||||
|
||||
describe('#equals()', function() {
|
||||
|
||||
it('identifies equal literals', function() {
|
||||
var literal = new ol.style.ShapeLiteral({
|
||||
type: ol.style.ShapeType.CIRCLE,
|
||||
size: 4,
|
||||
fillColor: '#BADA55',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
var equalLiteral = new ol.style.ShapeLiteral({
|
||||
type: ol.style.ShapeType.CIRCLE,
|
||||
size: 4,
|
||||
fillColor: '#BADA55',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
var differentLiteral = new ol.style.ShapeLiteral({
|
||||
type: ol.style.ShapeType.CIRCLE,
|
||||
size: 4,
|
||||
fillColor: '#013',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 3,
|
||||
opacity: 1
|
||||
});
|
||||
expect(literal.equals(equalLiteral)).toBe(true);
|
||||
expect(literal.equals(differentLiteral)).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.style.Shape', function() {
|
||||
|
||||
describe('constructor', function() {
|
||||
|
||||
it('accepts literal values', function() {
|
||||
var symbolizer = new ol.style.Shape({
|
||||
size: 4,
|
||||
fillColor: '#BADA55'
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Shape);
|
||||
});
|
||||
|
||||
it('accepts expressions', function() {
|
||||
var symbolizer = new ol.style.Shape({
|
||||
size: new ol.Expression('sizeAttr'),
|
||||
strokeColor: new ol.Expression('color')
|
||||
});
|
||||
expect(symbolizer).toBeA(ol.style.Shape);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#createLiteral()', function() {
|
||||
|
||||
it('evaluates expressions with the given feature', function() {
|
||||
var symbolizer = new ol.style.Shape({
|
||||
size: new ol.Expression('sizeAttr'),
|
||||
opacity: new ol.Expression('opacityAttr'),
|
||||
fillColor: '#BADA55'
|
||||
});
|
||||
|
||||
var feature = new ol.Feature({
|
||||
sizeAttr: 42,
|
||||
opacityAttr: 0.4
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral(feature);
|
||||
expect(literal).toBeA(ol.style.ShapeLiteral);
|
||||
expect(literal.size).toBe(42);
|
||||
expect(literal.opacity).toBe(0.4);
|
||||
});
|
||||
|
||||
it('can be called without a feature', function() {
|
||||
var symbolizer = new ol.style.Shape({
|
||||
size: 10,
|
||||
opacity: 1,
|
||||
fillColor: '#BADA55',
|
||||
strokeColor: '#013',
|
||||
strokeWidth: 2
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral();
|
||||
expect(literal).toBeA(ol.style.ShapeLiteral);
|
||||
expect(literal.size).toBe(10);
|
||||
expect(literal.opacity).toBe(1);
|
||||
expect(literal.fillColor).toBe('#BADA55');
|
||||
expect(literal.strokeColor).toBe('#013');
|
||||
expect(literal.strokeWidth).toBe(2);
|
||||
});
|
||||
|
||||
it('applies default type if none provided', function() {
|
||||
var symbolizer = new ol.style.Shape({
|
||||
size: new ol.Expression('sizeAttr'),
|
||||
opacity: new ol.Expression('opacityAttr'),
|
||||
fillColor: '#BADA55'
|
||||
});
|
||||
|
||||
var feature = new ol.Feature({
|
||||
sizeAttr: 42,
|
||||
opacityAttr: 0.4
|
||||
});
|
||||
|
||||
var literal = symbolizer.createLiteral(feature);
|
||||
expect(literal).toBeA(ol.style.ShapeLiteral);
|
||||
expect(literal.size).toBe(42);
|
||||
expect(literal.opacity).toBe(0.4);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Expression');
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.style.Shape');
|
||||
goog.require('ol.style.ShapeLiteral');
|
||||
goog.require('ol.style.ShapeType');
|
||||
73
test/spec/ol/style/style.test.js
Normal file
73
test/spec/ol/style/style.test.js
Normal file
@@ -0,0 +1,73 @@
|
||||
goog.provide('ol.test.style.Style');
|
||||
|
||||
describe('ol.style.Style', function() {
|
||||
|
||||
describe('#apply()', function() {
|
||||
|
||||
it('applies a style to a feature', function() {
|
||||
|
||||
var style = new ol.style.Style({
|
||||
rules: [
|
||||
new ol.style.Rule({
|
||||
filter: new ol.filter.Filter(function(feature) {
|
||||
return feature.get('foo') == 'bar';
|
||||
}),
|
||||
symbolizers: [
|
||||
new ol.style.Shape({
|
||||
size: 4,
|
||||
fillColor: '#BADA55'
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
var feature = new ol.Feature();
|
||||
feature.set('foo', 'bar');
|
||||
expect(style.apply(feature).length).toBe(1);
|
||||
expect(style.apply(feature)[0].fillColor).toBe('#BADA55');
|
||||
feature.set('foo', 'baz');
|
||||
expect(style.apply(feature).length).toBe(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.style.Style.applyDefaultStyle()', function() {
|
||||
var feature = new ol.Feature();
|
||||
|
||||
it('returns an empty array for features without geometry', function() {
|
||||
expect(ol.style.Style.applyDefaultStyle(feature).length).toBe(0);
|
||||
});
|
||||
|
||||
it('returns an array with the Shape default for points', function() {
|
||||
feature.setGeometry(new ol.geom.Point([0, 0]));
|
||||
var symbolizers = ol.style.Style.applyDefaultStyle(feature);
|
||||
expect(symbolizers.length).toBe(1);
|
||||
expect(symbolizers[0]).toBeA(ol.style.ShapeLiteral);
|
||||
expect(symbolizers[0].equals(ol.style.ShapeDefaults)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns an array with the Line default for lines', function() {
|
||||
feature.setGeometry(new ol.geom.LineString([[0, 0], [1, 1]]));
|
||||
expect(ol.style.Style.applyDefaultStyle(feature)[0]
|
||||
.equals(ol.style.LineDefaults)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns an array with the Polygon default for polygons', function() {
|
||||
feature.setGeometry(new ol.geom.Polygon([[[0, 0], [1, 1], [0, 0]]]));
|
||||
expect(ol.style.Style.applyDefaultStyle(feature)[0]
|
||||
.equals(ol.style.PolygonDefaults)).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.filter.Filter');
|
||||
goog.require('ol.style.Rule');
|
||||
goog.require('ol.style.Shape');
|
||||
goog.require('ol.style.ShapeLiteral');
|
||||
goog.require('ol.style.Style');
|
||||
Reference in New Issue
Block a user