merged with upstream and improved key handling

This commit is contained in:
Dmitry Fedorov
2018-11-02 17:19:10 -07:00
252 changed files with 5980 additions and 3750 deletions
+11 -1
View File
@@ -2,6 +2,16 @@
### Next version ### Next version
#### The `getUid` function returns string
The `getUid` function from the `ol/util` module now returns a string instead of a number.
#### Attributions are not collapsible for `ol/source/OSM`
When a map contains a layer from a `ol/source/OSM` source, the `ol/control/Attribution` control will be shown with the `collapsible: false` behavior.
To get the previous behavior, configure the `ol/control/Attribution` control with `collapsible: true`.
### v5.2.0 ### v5.2.0
#### Removal of the `snapToPixel` option for `ol/style/Image` subclasses #### Removal of the `snapToPixel` option for `ol/style/Image` subclasses
@@ -16,7 +26,7 @@ When rendering with the Immediate API, symbols will no longer be snapped to inte
#### Geometry constructor and `setCoordinates` no longer accept `null` coordinates #### Geometry constructor and `setCoordinates` no longer accept `null` coordinates
Geometries (`ol/geom/*`) now need to be constructed with valid coordinates (center for `ol/geom/Circle`) as first constructor argument. The same applies to the `setCoordinates()` (`setCenter() for `ol/geom/Circle`) method. Geometries (`ol/geom/*`) now need to be constructed with valid coordinates (center for `ol/geom/Circle`) as first constructor argument. The same applies to the `setCoordinates()` (`setCenter()` for `ol/geom/Circle`) method.
### v5.0.0 ### v5.0.0
+6 -5
View File
@@ -7,22 +7,23 @@
"allowUnknownTags": true "allowUnknownTags": true
}, },
"source": { "source": {
"includePattern": ".+\\.js(doc)?$", "includePattern": ".+\\.js$",
"excludePattern": "(^|\\/|\\\\)_", "excludePattern": "(^|\\/|\\\\)_",
"include": [ "include": [
"src/ol" "src/ol"
] ]
}, },
"plugins": [ "plugins": [
"plugins/markdown", "config/jsdoc/api/plugins/markdown",
"config/jsdoc/api/plugins/normalize-exports", "jsdoc-plugin-typescript",
"config/jsdoc/api/plugins/inline-options", "config/jsdoc/api/plugins/inline-options",
"config/jsdoc/api/plugins/inheritdoc",
"config/jsdoc/api/plugins/events", "config/jsdoc/api/plugins/events",
"config/jsdoc/api/plugins/observable", "config/jsdoc/api/plugins/observable",
"config/jsdoc/api/plugins/api" "config/jsdoc/api/plugins/api"
], ],
"markdown": { "typescript": {
"parser": "gfm" "moduleRoot": "src"
}, },
"templates": { "templates": {
"cleverLinks": true, "cleverLinks": true,
+14 -14
View File
@@ -8,10 +8,10 @@
<td><p>The view manages the visual parameters of the map view, like resolution or rotation.</p> <td><p>The view manages the visual parameters of the map view, like resolution or rotation.</p>
[View](module-ol_View-View.html) with center, projection, resolution and rotation</td> [View](module-ol_View-View.html) with center, projection, resolution and rotation</td>
<td><p>Layers are lightweight containers that get their data from [sources](module-ol_source_Source-Source.html).</p> <td><p>Layers are lightweight containers that get their data from [sources](module-ol_source_Source-Source.html).</p>
[layer/Tile](module-ol_layer_Tile-TileLayer.html)<br> [ol/layer/Tile](module-ol_layer_Tile-TileLayer.html)<br>
[layer/Image](module-ol_layer_Image-ImageLayer.html)<br> [ol/layer/Image](module-ol_layer_Image-ImageLayer.html)<br>
[layer/Vector](module-ol_layer_Vector-VectorLayer.html)<br> [ol/layer/Vector](module-ol_layer_Vector-VectorLayer.html)<br>
[layer/VectorTile](module-ol_layer_VectorTile-VectorTileLayer.html)</td> [ol/layer/VectorTile](module-ol_layer_VectorTile-VectorTileLayer.html)</td>
</tr><tr> </tr><tr>
<th>Controls</th><th>Interactions</th><th>Sources and formats</th> <th>Controls</th><th>Interactions</th><th>Sources and formats</th>
</tr><tr> </tr><tr>
@@ -21,20 +21,20 @@
<td> <td>
[Map default interactions](module-ol_interaction.html#~defaults)<br> [Map default interactions](module-ol_interaction.html#~defaults)<br>
Interactions for [vector features](module-ol_Feature-Feature.html) Interactions for [vector features](module-ol_Feature-Feature.html)
<ul><li>[interaction/Select](module-ol_interaction_Select-Select.html)</li> <ul><li>[ol/interaction/Select](module-ol_interaction_Select-Select.html)</li>
<li>[interaction/Draw](module-ol_interaction_Draw-Draw.html)</li> <li>[ol/interaction/Draw](module-ol_interaction_Draw-Draw.html)</li>
<li>[interaction/Modify](module-ol_interaction_Modify-Modify.html)</li></ul> <li>[ol/interaction/Modify](module-ol_interaction_Modify-Modify.html)</li></ul>
[All interactions](module-ol_interaction_Interaction-Interaction.html)</td> [All interactions](module-ol_interaction_Interaction-Interaction.html)</td>
<td>[Tile sources](module-ol_source_Tile-TileSource.html) for [layer/Tile](module-ol_layer_Tile-TileLayer.html) <td>[Tile sources](module-ol_source_Tile-TileSource.html) for [ol/layer/Tile](module-ol_layer_Tile-TileLayer.html)
<br>[Image sources](module-ol_source_Image-ImageSource.html) for [layer/Image](module-ol_layer_Image-ImageLayer.html) <br>[Image sources](module-ol_source_Image-ImageSource.html) for [ol/layer/Image](module-ol_layer_Image-ImageLayer.html)
<br>[Vector sources](module-ol_source_Vector-VectorSource.html) for [layer/Vector](module-ol_layer_Vector-VectorLayer.html) <br>[Vector sources](module-ol_source_Vector-VectorSource.html) for [ol/layer/Vector](module-ol_layer_Vector-VectorLayer.html)
<br>[Vector tile sources](module-ol_source_VectorTile-VectorTile.html) for [layer/VectorTile](module-ol_layer_VectorTile-VectorTileLayer.html) <br>[Vector tile sources](module-ol_source_VectorTile-VectorTile.html) for [ol/layer/VectorTile](module-ol_layer_VectorTile-VectorTileLayer.html)
<br>[Formats](module-ol_format_Feature-FeatureFormat.html) for reading/writing vector data <br>[Formats](module-ol_format_Feature-FeatureFormat.html) for reading/writing vector data
<br>[format/WMSCapabilities](module-ol_format_WMSCapabilities-WMSCapabilities.html)</td></tr> <br>[ol/format/WMSCapabilities](module-ol_format_WMSCapabilities-WMSCapabilities.html)</td></tr>
<tr><th>Projections</th><th>Observable objects</th><th>Other components</th></tr> <tr><th>Projections</th><th>Observable objects</th><th>Other components</th></tr>
<tr><td><p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform, use [proj.transform()](module-ol_proj.html#.transform) and [proj.transformExtent()](module-ol_proj.html#.transformExtent).</p> <tr><td><p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform, use [ol/proj#transform()](module-ol_proj.html#.transform) and [ol/proj#transformExtent()](module-ol_proj.html#.transformExtent).</p>
[ol/proj](module-ol_proj.html)</td> [ol/proj](module-ol_proj.html)</td>
<td><p>Changes to all [ol/Object](module-ol_Object-BaseObject.html)s can be observed by calling the [object.on('propertychange')](module-ol_Object-BaseObject.html#on) method. Listeners receive an [ol/Object~ObjectEvent](module-ol_Object-ObjectEvent.html) with information on the changed property and old value.</p> <td><p>Changes to all [ol/Object](module-ol_Object-BaseObject.html)s can be observed by calling the [object.on('propertychange')](module-ol_Object-BaseObject.html#on) method. Listeners receive an [ol/Object.ObjectEvent](module-ol_Object-ObjectEvent.html) with information on the changed property and old value.</p>
<td> <td>
[ol/Geolocation](module-ol_Geolocation.html)<br> [ol/Geolocation](module-ol_Geolocation.html)<br>
[ol/Overlay](module-ol_Overlay-Overlay.html)<br></td> [ol/Overlay](module-ol_Overlay-Overlay.html)<br></td>
+12 -9
View File
@@ -95,17 +95,20 @@ exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
const doclet = e.doclet; const doclet = e.doclet;
if (doclet.stability) { if (doclet.stability) {
modules[doclet.longname.split('~').shift()] = true; modules[doclet.longname.split(/[~\.]/).shift()] = true;
api.push(doclet); api.push(doclet);
} }
// Mark explicity defined namespaces - needed in parseComplete to keep
// namespaces that we need as containers for api items.
if (/.*\.jsdoc$/.test(doclet.meta.filename) && doclet.kind == 'namespace') {
doclet.namespace_ = true;
}
if (doclet.kind == 'class') { if (doclet.kind == 'class') {
modules[doclet.longname.split('~').shift()] = true; modules[doclet.longname.split(/[~\.]/).shift()] = true;
classes[doclet.longname] = doclet; if (!(doclet.longname in classes)) {
classes[doclet.longname] = doclet;
} else if ('augments' in doclet) {
classes[doclet.longname].augments = doclet.augments;
}
}
if (doclet.name === doclet.longname && !doclet.memberof) {
// Make sure anonymous default exports are documented
doclet.setMemberof(doclet.longname);
} }
}, },
@@ -113,7 +116,7 @@ exports.handlers = {
const doclets = e.doclets; const doclets = e.doclets;
for (let i = doclets.length - 1; i >= 0; --i) { for (let i = doclets.length - 1; i >= 0; --i) {
const doclet = doclets[i]; const doclet = doclets[i];
if (doclet.stability || doclet.namespace_) { if (doclet.stability) {
if (doclet.kind == 'class') { if (doclet.kind == 'class') {
includeAugments(doclet); includeAugments(doclet);
} }
+2 -3
View File
@@ -12,7 +12,7 @@ exports.handlers = {
events[cls] = []; events[cls] = [];
} }
events[cls].push(doclet.longname); events[cls].push(doclet.longname);
} else if (doclet.kind == 'class') { } else if (doclet.kind == 'class' && !(doclet.longname in classes)) {
classes[doclet.longname] = doclet; classes[doclet.longname] = doclet;
} }
}, },
@@ -29,7 +29,7 @@ exports.handlers = {
event = doclet.fires[j].replace('event:', ''); event = doclet.fires[j].replace('event:', '');
if (events[event]) { if (events[event]) {
fires.push.apply(fires, events[event]); fires.push.apply(fires, events[event]);
} else { } else if (doclet.fires[j] !== 'event:ObjectEvent') {
fires.push(doclet.fires[j]); fires.push(doclet.fires[j]);
} }
} }
@@ -40,4 +40,3 @@ exports.handlers = {
} }
}; };
+109
View File
@@ -0,0 +1,109 @@
/*
* This is a hack to prevent inheritDoc tags from entirely removing
* documentation of the method that inherits the documentation.
*
* TODO: Remove this hack when https://github.com/jsdoc3/jsdoc/issues/53
* is addressed.
*/
exports.defineTags = function(dictionary) {
dictionary.defineTag('inheritDoc', {
mustHaveValue: false,
canHaveType: false,
canHaveName: false,
onTagged: function(doclet, tag) {
doclet.inheritdoc = true;
}
});
};
const lookup = {};
const incompleteByClass = {};
const keepKeys = ['comment', 'meta', 'name', 'memberof', 'longname', 'augment',
'stability'];
exports.handlers = {
newDoclet: function(e) {
const doclet = e.doclet;
let incompletes;
if (!(doclet.longname in lookup)) {
lookup[doclet.longname] = [];
}
lookup[doclet.longname].push(doclet);
if (doclet.inheritdoc) {
if (!(doclet.memberof in incompleteByClass)) {
incompleteByClass[doclet.memberof] = [];
}
incompletes = incompleteByClass[doclet.memberof];
if (incompletes.indexOf(doclet.name) == -1) {
incompletes.push(doclet.name);
}
}
},
parseComplete: function(e) {
let ancestors, candidate, candidates, doclet, i, j, k, l, key;
let incompleteDoclet, stability, incomplete, incompletes;
const doclets = e.doclets;
for (i = doclets.length - 1; i >= 0; --i) {
doclet = doclets[i];
if (doclet.augments) {
ancestors = [].concat(doclet.augments);
}
incompletes = incompleteByClass[doclet.longname];
if (ancestors && incompletes) {
// collect ancestors from the whole hierarchy
for (j = 0; j < ancestors.length; ++j) {
candidates = lookup[ancestors[j]];
if (candidates) {
for (k = candidates.length - 1; k >= 0; --k) {
candidate = candidates[k];
if (candidate.augments) {
ancestors = ancestors.concat(candidate.augments);
}
}
}
}
// walk through all inheritDoc members
for (j = incompletes.length - 1; j >= 0; --j) {
incomplete = incompletes[j];
candidates = lookup[doclet.longname + '#' + incomplete];
if (candidates) {
// get the incomplete doclet that needs to be augmented
for (k = candidates.length - 1; k >= 0; --k) {
incompleteDoclet = candidates[k];
if (incompleteDoclet.inheritdoc) {
break;
}
}
}
// find the documented ancestor
for (k = ancestors.length - 1; k >= 0; --k) {
candidates = lookup[ancestors[k] + '#' + incomplete];
if (candidates) {
for (l = candidates.length - 1; l >= 0; --l) {
candidate = candidates[l];
if (candidate && !candidate.inheritdoc) {
stability = candidate.stability || incompleteDoclet.stability;
if (stability) {
incompleteDoclet.stability = stability;
for (key in candidate) {
if (candidate.hasOwnProperty(key) &&
keepKeys.indexOf(key) == -1) {
incompleteDoclet[key] = candidate[key];
}
}
}
}
}
}
}
}
}
}
}
};
+111
View File
@@ -0,0 +1,111 @@
/**
* Modified from JSDoc's plugins/markdown and lib/jsdoc/util/markdown modules
* (see https://github.com/jsdoc3/jsdoc/), which are licensed under the Apache 2
* license (see http://www.apache.org/licenses/LICENSE-2.0).
*
* This version does not protect http(s) urls from being turned into links, and
* works around an issue with `~` characters in module paths by escaping them.
*/
const marked = require('marked');
const format = require('util').format;
const tags = [
'author',
'classdesc',
'description',
'exceptions',
'params',
'properties',
'returns',
'see',
'summary'
];
const hasOwnProp = Object.prototype.hasOwnProperty;
const markedRenderer = new marked.Renderer();
// Allow prettyprint to work on inline code samples
markedRenderer.code = function(code, language) {
const langClass = language ? ' lang-' + language : '';
return format('<pre class="prettyprint source%s"><code>%s</code></pre>',
langClass, escapeCode(code));
};
function escapeCode(source) {
return source.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function escapeUnderscoresAndTildes(source) {
return source.replace(/\{@[^}\r\n]+\}/g, function(wholeMatch) {
return wholeMatch
.replace(/(^|[^\\])_/g, '$1\\_')
.replace('~', '&tilde;');
});
}
function unencodeQuotesAndTildes(source) {
return source.replace(/\{@[^}\r\n]+\}/g, function(wholeMatch) {
return wholeMatch
.replace(/&quot;/g, '"')
.replace(/&tilde;/g, '~');
});
}
function parse(source) {
let result;
source = escapeUnderscoresAndTildes(source);
result = marked(source, {renderer: markedRenderer})
.replace(/\s+$/, '')
.replace(/&#39;/g, '\'');
result = unencodeQuotesAndTildes(result);
return result;
}
function shouldProcessString(tagName, text) {
let shouldProcess = true;
// we only want to process `@author` and `@see` tags that contain Markdown links
if ((tagName === 'author' || tagName === 'see') && text.indexOf('[') === -1) {
shouldProcess = false;
}
return shouldProcess;
}
function process(doclet) {
tags.forEach(function(tag) {
if (!hasOwnProp.call(doclet, tag)) {
return;
}
if (typeof doclet[tag] === 'string' && shouldProcessString(tag, doclet[tag])) {
doclet[tag] = parse(doclet[tag]);
} else if (Array.isArray(doclet[tag])) {
doclet[tag].forEach(function(value, index, original) {
const inner = {};
inner[tag] = value;
process(inner);
original[index] = inner[tag];
});
} else if (doclet[tag]) {
process(doclet[tag]);
}
});
}
exports.handlers = {
newDoclet: function(e) {
process(e.doclet);
}
};
@@ -1,106 +0,0 @@
/**
* @filedesc
* Expands module path type to point to default export when no name is given
*/
const fs = require('fs');
const path = require('path');
let moduleRoot;
function addDefaultExportPath(obj) {
if (!Array.isArray(obj)) {
obj = obj.names;
}
obj.forEach((name, index) => {
const matches = name.match(/module\:([^>|),\.<]|)+/g);
if (matches) {
matches.forEach(module => {
if (!/[~\.]/.test(module)) {
const checkFile = path.resolve(moduleRoot, module.replace(/^module\:/, ''));
const file = fs.readFileSync(require.resolve(checkFile), 'utf-8');
const lines = file.split('\n');
let hasDefaultExport = false;
for (let i = 0, ii = lines.length; i < ii; ++i) {
hasDefaultExport = hasDefaultExport || /^export default [^\{]/.test(lines[i]);
const match = lines[i].match(/^export default ([A-Za-z_$][A-Za-z0-9_$]+);$/);
if (match) {
// Use variable name if default export is assigned to a variable.
obj[index] = name = name.replace(module, `${module}~${match[1]}`);
return;
}
}
if (hasDefaultExport) {
// Duplicate last part if default export is not assigned to a variable.
obj[index] = name = name.replace(module, `${module}~${module.split('/').pop()}`);
}
}
});
}
});
}
function replaceLinks(comment) {
const matches = comment.match(/\{@link [^\} #]+}/g);
if (matches) {
const modules = matches.map(m => {
const mm = m.match(/(module:[^\}]+)}$/);
if (mm) {
return mm[1];
}
}).filter(m => !!m);
const newModules = modules.concat();
addDefaultExportPath(newModules);
modules.forEach((module, i) => {
comment = comment.replace(module, newModules[i]);
});
}
return comment;
}
exports.handlers = {
/**
* Adds default export to module path types without name
* @param {Object} e Event object.
*/
newDoclet: function(e) {
const doclet = e.doclet;
if (doclet.kind == 'module') {
const levelsUp = doclet.longname.replace(/^module\:/, '').split('/');
if (doclet.meta.filename != 'index.js') {
levelsUp.pop();
}
const pathArgs = [doclet.meta.path].concat(levelsUp.map(() => '../'));
moduleRoot = path.resolve.apply(null, pathArgs);
} else {
if (doclet.description) {
doclet.description = replaceLinks(doclet.description);
}
if (doclet.classdesc) {
doclet.classdesc = replaceLinks(doclet.classdesc);
}
const module = doclet.longname.split('#').shift();
if (module.indexOf('module:') == 0 && module.indexOf('.') !== -1) {
doclet.longname = doclet.longname.replace(module, module.replace('.', '~'));
}
if (doclet.augments) {
addDefaultExportPath(doclet.augments);
}
if (doclet.params) {
doclet.params.forEach(p => addDefaultExportPath(p.type));
}
if (doclet.returns) {
doclet.returns.forEach(r => addDefaultExportPath(r.type));
}
if (doclet.properties) {
doclet.properties.forEach(p => addDefaultExportPath(p.type));
}
if (doclet.type) {
addDefaultExportPath(doclet.type);
}
}
}
};
+2 -2
View File
@@ -5,7 +5,7 @@ exports.handlers = {
newDoclet: function(e) { newDoclet: function(e) {
const doclet = e.doclet; const doclet = e.doclet;
if (doclet.kind == 'class') { if (doclet.kind == 'class' && !(doclet.longname in classes)) {
classes[doclet.longname] = doclet; classes[doclet.longname] = doclet;
} }
}, },
@@ -47,7 +47,7 @@ exports.handlers = {
if (!cls.fires) { if (!cls.fires) {
cls.fires = []; cls.fires = [];
} }
event = 'module:ol/Object~ObjectEvent#event:change:' + name; event = 'module:ol/Object.ObjectEvent#event:change:' + name;
if (cls.fires.indexOf(event) == -1) { if (cls.fires.indexOf(event) == -1) {
cls.fires.push(event); cls.fires.push(event);
} }
-85
View File
@@ -1,85 +0,0 @@
/*
* Changes @enum annotations into @typedef.
*/
// types that are undefined or typedefs containing undefined
let undefinedLikes = null;
/**
* Changes the description of the param if it is required.
* @param {Object} doclet The doclet.
* @returns {Object} The modified doclet.
*/
function markRequiredIfNeeded(doclet) {
const memberof = doclet.memberof;
if (!memberof) {
return doclet;
}
const types = doclet.type.names;
let isRequiredParam = true;
// iterate over all types that are like-undefined (see above for explanation)
for (let idx = undefinedLikes.length - 1; idx >= 0; idx--) {
const undefinedLike = undefinedLikes[idx];
// … if the current types contains a type that is undefined-like,
// it is not required.
if (types.indexOf(undefinedLike) != -1) {
isRequiredParam = false;
}
}
if (isRequiredParam) {
const reqSnippet = '<span class="required-option">Required.</span></p>';
const endsWithP = /<\/p>$/i;
let description = doclet.description;
if (description && endsWithP.test(description)) {
description = description.replace(endsWithP, ' ' + reqSnippet);
} else if (doclet.description === undefined) {
description = '<p>' + reqSnippet;
}
doclet.description = description;
}
return doclet;
}
/**
* Iterates over all doclets and finds the names of types that contain
* undefined. Stores the names in the global variable undefinedLikes, so
* that e.g. markRequiredIfNeeded can use these.
* @param {Array} doclets The doclets.
*/
function findTypesLikeUndefined(doclets) {
undefinedLikes = ['undefined']; // include type 'undefined' explicitly
for (let i = doclets.length - 1; i >= 0; --i) {
const doclet = doclets[i];
if (doclet.kind === 'typedef') {
const types = doclet.type.names;
if (types.indexOf('undefined') !== -1) {
// the typedef contains 'undefined', so it self is undefinedLike.
undefinedLikes.push(doclet.longname);
}
}
}
}
exports.handlers = {
newDoclet: function(e) {
const doclet = e.doclet;
if (doclet.isEnum) {
// We never export enums, so we document them like typedefs
doclet.kind = 'typedef';
delete doclet.isEnum;
}
},
parseComplete: function(e) {
const doclets = e.doclets;
findTypesLikeUndefined(doclets);
for (let i = doclets.length - 1; i >= 0; --i) {
markRequiredIfNeeded(doclets[i]);
}
}
};
@@ -30,7 +30,11 @@ $(function () {
}); });
// Show an item related a current documentation automatically // Show an item related a current documentation automatically
var filename = $('.page-title').data('filename').replace(/\.[a-z]+$/, ''); var filename = $('.page-title').data('filename')
.replace(/\.[a-z]+$/, '')
.replace('module-', 'module:')
.replace(/_/g, '/')
.replace(/-/g, '~');
var $currentItem = $('.navigation .item[data-name*="' + filename + '"]:eq(0)'); var $currentItem = $('.navigation .item[data-name*="' + filename + '"]:eq(0)');
if ($currentItem.length) { if ($currentItem.length) {
@@ -97,7 +101,8 @@ $(function () {
var anchors = $('.anchor'); var anchors = $('.anchor');
var _onHashChange = function () { var _onHashChange = function () {
var activeHash = window.document.location.hash var activeHash = window.document.location.hash
.replace(/\./g, '\\.'); // Escape dot in element id .replace(/\./g, '\\.') // Escape dot in element id
.replace(/\~/g, '\\~'); // Escape tilde in element id
anchors.removeClass('highlighted'); anchors.removeClass('highlighted');
+3 -3
View File
@@ -14,7 +14,7 @@ if (data.type && data.type.names) {
<div class="anchor" id="<?js= id ?>"> <div class="anchor" id="<?js= id ?>">
</div> </div>
<h4 class="name"> <h4 class="name">
<?js= data.attribs + (data.scope === 'static' ? longname : name) + typeSignature ?> <?js= data.attribs + (data.scope === 'static' ? longname : name.indexOf('module:') === 0 ? name.split('/').pop() : name) + typeSignature ?>
<?js= this.partial('stability.tmpl', data) ?> <?js= this.partial('stability.tmpl', data) ?>
</h4> </h4>
</div> </div>
@@ -28,9 +28,9 @@ if (data.type && data.type.names) {
<?js= data.description ?> <?js= data.description ?>
</div> </div>
<?js } ?> <?js } ?>
<?js= this.partial('details.tmpl', data) ?> <?js= this.partial('details.tmpl', data) ?>
<?js if (data.examples && examples.length) { ?> <?js if (data.examples && examples.length) { ?>
<h5>Example<?js= examples.length > 1? 's':'' ?></h5> <h5>Example<?js= examples.length > 1? 's':'' ?></h5>
<?js= this.partial('examples.tmpl', examples) ?> <?js= this.partial('examples.tmpl', examples) ?>
+1 -1
View File
@@ -77,7 +77,7 @@ var self = this;
(<?js= self.linkto(eventClass.longname) ?>) (<?js= self.linkto(eventClass.longname) ?>)
<?js } ?> <?js } ?>
<?js } ?> <?js } ?>
<?js= self.partial('stability.tmpl', eventDoclet || (data.stability ? data : {stability: 'experimental'})) ?> <?js= self.partial('stability.tmpl', eventDoclet || (data.stability ? data : {})) ?>
<?js if (description) { ?> - <?js if (description) { ?> -
<?js= description ?> <?js= description ?>
<?js } ?> <?js } ?>
@@ -1,5 +1,8 @@
<?js <?js
var self = this; var self = this;
function toShortName(name) {
return name.indexOf('module:') === 0 ? name.split('/').pop() : name;
}
?> ?>
<div class="navigation"> <div class="navigation">
<div class="search"> <div class="search">
@@ -25,7 +28,7 @@ var self = this;
<?js <?js
item.members.forEach(function (v) { item.members.forEach(function (v) {
?> ?>
<li data-name="<?js= v.longname ?>"><?js= self.linkto(v.longname, v.name) ?></li> <li data-name="<?js= v.longname ?>"><?js= self.linkto(v.longname, toShortName(v.name)) ?></li>
<?js <?js
}); });
} }
@@ -40,7 +43,7 @@ var self = this;
item.typedefs.forEach(function (v) { item.typedefs.forEach(function (v) {
?> ?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>"> <li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>">
<?js= self.linkto(v.longname, v.name) ?> <?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li> </li>
<?js <?js
}); });
@@ -57,7 +60,7 @@ var self = this;
item.methods.forEach(function (v) { item.methods.forEach(function (v) {
?> ?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>"> <li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>">
<?js= self.linkto(v.longname, v.name) ?> <?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li> </li>
<?js <?js
}); });
@@ -74,7 +77,7 @@ var self = this;
v = self.find({longname: v})[0] || {longname: v, name: v.split(/#?event:/)[1]}; v = self.find({longname: v})[0] || {longname: v, name: v.split(/#?event:/)[1]};
?> ?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability != 'stable') ? 'unstable' : '' ?>"> <li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability != 'stable') ? 'unstable' : '' ?>">
<?js= self.linkto(v.longname, v.name) ?> <?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li> </li>
<?js <?js
}); });
@@ -8,7 +8,7 @@
<th>Name</th> <th>Name</th>
<th>Type</th> <th>Type</th>
<th>Settable</th> <th>Settable</th>
<th><a href="module-ol_Object-ObjectEvent.html">ol/Object~ObjectEvent</a> type</th> <th><a href="module-ol_Object-ObjectEvent.html">ol/Object.ObjectEvent</a> type</th>
<th class="last">Description</th> <th class="last">Description</th>
</tr> </tr>
</thead> </thead>
+5 -1
View File
@@ -10,8 +10,12 @@
"includePattern": "\\.js$" "includePattern": "\\.js$"
}, },
"plugins": [ "plugins": [
"jsdoc-plugin-typescript",
"config/jsdoc/info/api-plugin", "config/jsdoc/info/api-plugin",
"config/jsdoc/info/define-plugin", "config/jsdoc/info/define-plugin",
"config/jsdoc/info/virtual-plugin" "config/jsdoc/info/virtual-plugin"
] ],
"typescript": {
"moduleRoot": "src"
}
} }
-21
View File
@@ -1,21 +0,0 @@
// Rollup configuration for the full build
import noderesolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import {uglify} from 'rollup-plugin-uglify';
import buble from 'rollup-plugin-buble';
import sourcemaps from 'rollup-plugin-sourcemaps';
export default {
input: 'build/index.js',
output: [
{file: 'build/ol.js', format: 'iife', sourcemap: true}
],
plugins: [
noderesolve(),
commonjs(),
buble(),
uglify(),
sourcemaps()
]
};
+13
View File
@@ -0,0 +1,13 @@
const path = require('path');
module.exports = {
entry: './build/index.js',
devtool: 'source-map',
mode: 'production',
output: {
path: path.resolve('./build/legacy'),
filename: 'ol.js',
library: 'ol',
libraryTarget: 'umd',
libraryExport: 'default'
}
};
+86 -46
View File
@@ -54,9 +54,12 @@ The projection of your map can be set through the `view`-property. Here are some
examples: examples:
```javascript ```javascript
import Map from 'ol/Map';
import View from 'ol/View';
// OpenLayers comes with support for the World Geodetic System 1984, EPSG:4326: // OpenLayers comes with support for the World Geodetic System 1984, EPSG:4326:
var map = new ol.Map({ const map = new Map({
view: new ol.View({ view: new View({
projection: 'EPSG:4326' projection: 'EPSG:4326'
// other view properties like map center etc. // other view properties like map center etc.
}) })
@@ -65,23 +68,29 @@ var map = new ol.Map({
``` ```
```javascript ```javascript
import Map from 'ol/Map';
import View from 'ol/View';
import proj4 from 'proj4';
import {register} from 'ol/proj/proj4';
import {get as getProjection} from 'ol/proj';
// To use other projections, you have to register the projection in OpenLayers. // To use other projections, you have to register the projection in OpenLayers.
// This can easily be done with [https://proj4js.org](proj4) // This can easily be done with [https://proj4js.org](proj4)
// //
// By default OpenLayers does not know about the EPSG:21781 (Swiss) projection. // By default OpenLayers does not know about the EPSG:21781 (Swiss) projection.
// So we create a projection instance for EPSG:21781 and pass it to // So we create a projection instance for EPSG:21781 and pass it to
// ol.proj.addProjection to make it available to the library for lookup by its // register to make it available to the library for lookup by its
// code. // code.
proj4.defs('EPSG:21781', proj4.defs('EPSG:21781',
'+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 ' + '+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 ' +
'+x_0=600000 +y_0=200000 +ellps=bessel ' + '+x_0=600000 +y_0=200000 +ellps=bessel ' +
'+towgs84=660.077,13.551,369.344,2.484,1.783,2.939,5.66 +units=m +no_defs'); '+towgs84=660.077,13.551,369.344,2.484,1.783,2.939,5.66 +units=m +no_defs');
ol.proj.proj4.register(proj4); register(proj4);
var swissProjection = ol.proj.get('EPSG:21781'); const swissProjection = getProjection('EPSG:21781');
// we can now use the projection: // we can now use the projection:
var map = new ol.Map({ const map = new Map({
view: new ol.View({ view: new View({
projection: swissProjection projection: swissProjection
// other view properties like map center etc. // other view properties like map center etc.
}) })
@@ -104,15 +113,20 @@ coordinates for the center have to be provided in that projection. Chances are
that your map looks like this: that your map looks like this:
```javascript ```javascript
var washingtonLonLat = [-77.036667, 38.895]; import Map from 'ol/Map';
var map = new ol.Map({ import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
const washingtonLonLat = [-77.036667, 38.895];
const map = new Map({
layers: [ layers: [
new ol.layer.Tile({ new TileLayer({
source: new ol.source.OSM() source: new OSM()
}) })
], ],
target: 'map', target: 'map',
view: new ol.View({ view: new View({
center: washingtonLonLat, center: washingtonLonLat,
zoom: 12 zoom: 12
}) })
@@ -128,31 +142,38 @@ The solution is easy: Provide the coordinates projected into Web Mercator.
OpenLayers has some helpful utility methods to assist you: OpenLayers has some helpful utility methods to assist you:
```javascript ```javascript
var washingtonLonLat = [-77.036667, 38.895]; import Map from 'ol/Map';
var washingtonWebMercator = ol.proj.fromLonLat(washingtonLonLat); import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import {fromLonLat} from 'ol/proj';
var map = new ol.Map({ const washingtonLonLat = [-77.036667, 38.895];
const washingtonWebMercator = fromLonLat(washingtonLonLat);
const map = new Map({
layers: [ layers: [
new ol.layer.Tile({ new TileLayer({
source: new ol.source.OSM() source: new OSM()
}) })
], ],
target: 'map', target: 'map',
view: new ol.View({ view: new View({
center: washingtonWebMercator, center: washingtonWebMercator,
zoom: 8 zoom: 8
}) })
}); });
``` ```
The method `ol.proj.fromLonLat()` is available from version 3.5 onwards. The method `fromLonLat()` is available from version 3.5 onwards.
If you told OpenLayers about a custom projection (see above), you can use the If you told OpenLayers about a custom projection (see above), you can use the
following method to transform a coordinate from WGS84 to your projection: following method to transform a coordinate from WGS84 to your projection:
```javascript ```javascript
import {transform} from 'ol/proj';
// assuming that OpenLayers knows about EPSG:21781, see above // assuming that OpenLayers knows about EPSG:21781, see above
var swissCoord = ol.proj.transform([8.23, 46.86], 'EPSG:4326', 'EPSG:21781'); const swissCoord = transform([8.23, 46.86], 'EPSG:4326', 'EPSG:21781');
``` ```
@@ -189,18 +210,24 @@ So the next step would be to put the decimal coordinates into an array and use
it as center: it as center:
```javascript ```javascript
var schladming = [47.394167, 13.689167]; // caution partner, read on... import Map from 'ol/Map';
// since we are using OSM, we have to transform the coordinates... import View from 'ol/View';
var schladmingWebMercator = ol.proj.fromLonLat(schladming); import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import {fromLonLat} from 'ol/proj';
var map = new ol.Map({ const schladming = [47.394167, 13.689167]; // caution partner, read on...
// since we are using OSM, we have to transform the coordinates...
const schladmingWebMercator = fromLonLat(schladming);
const map = new Map({
layers: [ layers: [
new ol.layer.Tile({ new TileLayer({
source: new ol.source.OSM() source: new OSM()
}) })
], ],
target: 'map', target: 'map',
view: new ol.View({ view: new View({
center: schladmingWebMercator, center: schladmingWebMercator,
zoom: 9 zoom: 9
}) })
@@ -219,18 +246,24 @@ e.g. try to change the map center.
Ok, then let's flip the coordinates: Ok, then let's flip the coordinates:
```javascript ```javascript
var schladming = [13.689167, 47.394167]; // longitude first, then latitude import Map from 'ol/Map';
// since we are using OSM, we have to transform the coordinates... import View from 'ol/View';
var schladmingWebMercator = ol.proj.fromLonLat(schladming); import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import {fromLonLat} from 'ol/proj';
var map = new ol.Map({ const schladming = [13.689167, 47.394167]; // longitude first, then latitude
// since we are using OSM, we have to transform the coordinates...
const schladmingWebMercator = fromLonLat(schladming);
const map = new Map({
layers: [ layers: [
new ol.layer.Tile({ new TileLayer({
source: new ol.source.OSM() source: new OSM()
}) })
], ],
target: 'map', target: 'map',
view: new ol.View({ view: new View({
center: schladmingWebMercator, center: schladmingWebMercator,
zoom: 9 zoom: 9
}) })
@@ -244,7 +277,7 @@ first, and then the latitude. This behaviour is the same as we had in OpenLayers
2, and it actually makes sense because of the natural axis order in WGS84. 2, and it actually makes sense because of the natural axis order in WGS84.
If you cannot remember the correct order, just have a look at the method name If you cannot remember the correct order, just have a look at the method name
we used: `ol.proj.fromLonLat`; even there we hint that we expect longitude we used: `fromLonLat`; even there we hint that we expect longitude
first, and then latitude. first, and then latitude.
@@ -254,8 +287,11 @@ Suppose you want to load a KML file and display the contained features on the
map. Code like the following could be used: map. Code like the following could be used:
```javascript ```javascript
var vector = new ol.layer.Vector({ import VectorLayer from 'ol/layer/Vector';
source: new ol.source.KML({ import KMLSource from 'ol/source/KML';
const vector = new VectorLayer({
source: new KMLSource({
projection: 'EPSG:3857', projection: 'EPSG:3857',
url: 'data/kml/2012-02-10.kml' url: 'data/kml/2012-02-10.kml'
}) })
@@ -266,13 +302,16 @@ You may ask yourself how many features are in that KML, and try something like
the following: the following:
```javascript ```javascript
var vector = new ol.layer.Vector({ import VectorLayer from 'ol/layer/Vector';
source: new ol.source.KML({ import KMLSource from 'ol/source/KML';
const vector = new VectorLayer({
source: new KMLSource({
projection: 'EPSG:3857', projection: 'EPSG:3857',
url: 'data/kml/2012-02-10.kml' url: 'data/kml/2012-02-10.kml'
}) })
}); });
var numFeatures = vector.getSource().getFeatures().length; const numFeatures = vector.getSource().getFeatures().length;
console.log("Count right after construction: " + numFeatures); console.log("Count right after construction: " + numFeatures);
``` ```
@@ -284,9 +323,9 @@ been populated with features), you should use an event listener function on the
```javascript ```javascript
vector.getSource().on('change', function(evt){ vector.getSource().on('change', function(evt){
var source = evt.target; const source = evt.target;
if (source.getState() === 'ready') { if (source.getState() === 'ready') {
var numFeatures = source.getFeatures().length; const numFeatures = source.getFeatures().length;
console.log("Count after change: " + numFeatures); console.log("Count after change: " + numFeatures);
} }
}); });
@@ -315,16 +354,17 @@ map.renderSync();
## Why are my features not found? ## Why are my features not found?
You are using `ol.Map#forEachFeatureAtPixel` or `ol.Map#hasFeatureAtPixel`, but You are using `Map#forEachFeatureAtPixel` or `Map#hasFeatureAtPixel`, but
it sometimes does not work for large icons or labels? The *hit detection* only it sometimes does not work for large icons or labels? The *hit detection* only
checks features that are within a certain distance of the given position. For large checks features that are within a certain distance of the given position. For large
icons, the actual geometry of a feature might be too far away and is not considered. icons, the actual geometry of a feature might be too far away and is not considered.
In this case, set the `renderBuffer` property of `ol.layer.Vector` (the default In this case, set the `renderBuffer` property of `VectorLayer` (the default value is 100px):
value is 100px):
```javascript ```javascript
var vectorLayer = new ol.layer.Vector({ import VectorLayer from 'ol/layer/Vector';
const vectorLayer = new VectorLayer({
... ...
renderBuffer: 200 renderBuffer: 200
}); });
+1 -1
View File
@@ -17,7 +17,7 @@ OpenLayers is available as [`ol` npm package](https://npmjs.com/package/ol), whi
## Renderers and Browser Support ## Renderers and Browser Support
By default, OpenLayers uses a performance optimized Canvas renderer. An experimental WebGL renderer (without text rendering support) is also avaialble. By default, OpenLayers uses a performance optimized Canvas renderer. An experimental WebGL renderer (without text rendering support) is also available.
OpenLayers runs on all modern browsers that support [HTML5](https://html.spec.whatwg.org/multipage/) and [ECMAScript 5](http://www.ecma-international.org/ecma-262/5.1/). This includes Chrome, Firefox, Safari and Edge. For older browsers and platforms like Internet Explorer (down to version 9) and Android 4.x, [polyfills](http://polyfill.io), the application bundle needs to be transpiled (e.g. using [Babel](https://babeljs.io)) and bundled with polyfills for `requestAnimationFrame`, `Element.prototype.classList` and `URL`. OpenLayers runs on all modern browsers that support [HTML5](https://html.spec.whatwg.org/multipage/) and [ECMAScript 5](http://www.ecma-international.org/ecma-262/5.1/). This includes Chrome, Firefox, Safari and Edge. For older browsers and platforms like Internet Explorer (down to version 9) and Android 4.x, [polyfills](http://polyfill.io), the application bundle needs to be transpiled (e.g. using [Babel](https://babeljs.io)) and bundled with polyfills for `requestAnimationFrame`, `Element.prototype.classList` and `URL`.
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -12,11 +11,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {fromLonLat} from '../src/ol/proj.js'; import {fromLonLat} from '../src/ol/proj.js';
import {OSM, TileDebug} from '../src/ol/source.js'; import {OSM, TileDebug} from '../src/ol/source.js';
@@ -20,11 +19,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: fromLonLat([-0.1275, 51.507222]), center: fromLonLat([-0.1275, 51.507222]),
zoom: 10 zoom: 10
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import GeoJSON from '../src/ol/format/GeoJSON.js'; import GeoJSON from '../src/ol/format/GeoJSON.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js';
@@ -45,11 +44,6 @@ const map = new Map({
vectorLayer vectorLayer
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: view view: view
}); });
+20 -33
View File
@@ -1,4 +1,3 @@
import {inherits} from '../src/ol/util.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls, Control} from '../src/ol/control.js'; import {defaults as defaultControls, Control} from '../src/ol/control.js';
@@ -6,13 +5,6 @@ import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
/**
* Define a namespace for the application.
*/
window.app = {};
const app = window.app;
// //
// Define rotate to north control. // Define rotate to north control.
// //
@@ -23,32 +15,31 @@ const app = window.app;
* @extends {module:ol/control/Control~Control} * @extends {module:ol/control/Control~Control}
* @param {Object=} opt_options Control options. * @param {Object=} opt_options Control options.
*/ */
app.RotateNorthControl = function(opt_options) { class RotateNorthControl extends Control {
const options = opt_options || {}; constructor(opt_options) {
const options = opt_options || {};
const button = document.createElement('button'); const button = document.createElement('button');
button.innerHTML = 'N'; button.innerHTML = 'N';
const this_ = this; const element = document.createElement('div');
const handleRotateNorth = function() { element.className = 'rotate-north ol-unselectable ol-control';
this_.getMap().getView().setRotation(0); element.appendChild(button);
};
button.addEventListener('click', handleRotateNorth, false); super({
button.addEventListener('touchstart', handleRotateNorth, false); element: element,
target: options.target
});
const element = document.createElement('div'); button.addEventListener('click', this.handleRotateNorth.bind(this), false);
element.className = 'rotate-north ol-unselectable ol-control'; }
element.appendChild(button);
Control.call(this, { handleRotateNorth() {
element: element, this.getMap().getView().setRotation(0);
target: options.target }
});
}; }
inherits(app.RotateNorthControl, Control);
// //
@@ -57,12 +48,8 @@ inherits(app.RotateNorthControl, Control);
const map = new Map({ const map = new Map({
controls: defaultControls({ controls: defaultControls().extend([
attributionOptions: { new RotateNorthControl()
collapsible: false
}
}).extend([
new app.RotateNorthControl()
]), ]),
layers: [ layers: [
new TileLayer({ new TileLayer({
+39 -47
View File
@@ -1,4 +1,3 @@
import {inherits} from '../src/ol/util.js';
import Feature from '../src/ol/Feature.js'; import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
@@ -9,58 +8,51 @@ import {TileJSON, Vector as VectorSource} from '../src/ol/source.js';
import {Fill, Icon, Stroke, Style} from '../src/ol/style.js'; import {Fill, Icon, Stroke, Style} from '../src/ol/style.js';
/**
* Define a namespace for the application.
*/
const app = {};
/** /**
* @constructor * @constructor
* @extends {module:ol/interaction/Pointer} * @extends {module:ol/interaction/Pointer}
*/ */
app.Drag = function() { class Drag extends PointerInteraction {
constructor() {
super({
handleDownEvent: handleDownEvent,
handleDragEvent: handleDragEvent,
handleMoveEvent: handleMoveEvent,
handleUpEvent: handleUpEvent
});
PointerInteraction.call(this, { /**
handleDownEvent: app.Drag.prototype.handleDownEvent, * @type {module:ol/pixel~Pixel}
handleDragEvent: app.Drag.prototype.handleDragEvent, * @private
handleMoveEvent: app.Drag.prototype.handleMoveEvent, */
handleUpEvent: app.Drag.prototype.handleUpEvent this.coordinate_ = null;
});
/** /**
* @type {module:ol/pixel~Pixel} * @type {string|undefined}
* @private * @private
*/ */
this.coordinate_ = null; this.cursor_ = 'pointer';
/** /**
* @type {string|undefined} * @type {module:ol/Feature~Feature}
* @private * @private
*/ */
this.cursor_ = 'pointer'; this.feature_ = null;
/** /**
* @type {module:ol/Feature~Feature} * @type {string|undefined}
* @private * @private
*/ */
this.feature_ = null; this.previousCursor_ = undefined;
}
/** }
* @type {string|undefined}
* @private
*/
this.previousCursor_ = undefined;
};
inherits(app.Drag, PointerInteraction);
/** /**
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event. * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
* @return {boolean} `true` to start the drag sequence. * @return {boolean} `true` to start the drag sequence.
*/ */
app.Drag.prototype.handleDownEvent = function(evt) { function handleDownEvent(evt) {
const map = evt.map; const map = evt.map;
const feature = map.forEachFeatureAtPixel(evt.pixel, const feature = map.forEachFeatureAtPixel(evt.pixel,
@@ -74,13 +66,13 @@ app.Drag.prototype.handleDownEvent = function(evt) {
} }
return !!feature; return !!feature;
}; }
/** /**
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event. * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
*/ */
app.Drag.prototype.handleDragEvent = function(evt) { function handleDragEvent(evt) {
const deltaX = evt.coordinate[0] - this.coordinate_[0]; const deltaX = evt.coordinate[0] - this.coordinate_[0];
const deltaY = evt.coordinate[1] - this.coordinate_[1]; const deltaY = evt.coordinate[1] - this.coordinate_[1];
@@ -89,13 +81,13 @@ app.Drag.prototype.handleDragEvent = function(evt) {
this.coordinate_[0] = evt.coordinate[0]; this.coordinate_[0] = evt.coordinate[0];
this.coordinate_[1] = evt.coordinate[1]; this.coordinate_[1] = evt.coordinate[1];
}; }
/** /**
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Event. * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Event.
*/ */
app.Drag.prototype.handleMoveEvent = function(evt) { function handleMoveEvent(evt) {
if (this.cursor_) { if (this.cursor_) {
const map = evt.map; const map = evt.map;
const feature = map.forEachFeatureAtPixel(evt.pixel, const feature = map.forEachFeatureAtPixel(evt.pixel,
@@ -113,17 +105,17 @@ app.Drag.prototype.handleMoveEvent = function(evt) {
this.previousCursor_ = undefined; this.previousCursor_ = undefined;
} }
} }
}; }
/** /**
* @return {boolean} `false` to stop the drag sequence. * @return {boolean} `false` to stop the drag sequence.
*/ */
app.Drag.prototype.handleUpEvent = function() { function handleUpEvent() {
this.coordinate_ = null; this.coordinate_ = null;
this.feature_ = null; this.feature_ = null;
return false; return false;
}; }
const pointFeature = new Feature(new Point([0, 0])); const pointFeature = new Feature(new Point([0, 0]));
@@ -137,7 +129,7 @@ const polygonFeature = new Feature(
const map = new Map({ const map = new Map({
interactions: defaultInteractions().extend([new app.Drag()]), interactions: defaultInteractions().extend([new Drag()]),
layers: [ layers: [
new TileLayer({ new TileLayer({
source: new TileJSON({ source: new TileJSON({
+1 -1
View File
@@ -8,7 +8,7 @@ docs: >
normalize the events from the browser. normalize the events from the browser.
tags: "device, orientation, gyronorm" tags: "device, orientation, gyronorm"
resources: resources:
- https://cdn.rawgit.com/dorukeker/gyronorm.js/v2.0.6/dist/gyronorm.complete.min.js - https://unpkg.com/gyronorm@2.0.6/dist/gyronorm.complete.min.js
--- ---
<div id="map" class="map"></div> <div id="map" class="map"></div>
<p> <p>
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {toRadians} from '../src/ol/math.js'; import {toRadians} from '../src/ol/math.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -16,11 +15,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: view view: view
}); });
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import GeoJSON from '../src/ol/format/GeoJSON.js'; import GeoJSON from '../src/ol/format/GeoJSON.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js';
@@ -18,11 +17,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import WKT from '../src/ol/format/WKT.js'; import WKT from '../src/ol/format/WKT.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js';
@@ -26,11 +25,6 @@ const vector = new VectorLayer({
const map = new Map({ const map = new Map({
layers: [raster, vector], layers: [raster, vector],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -2,7 +2,6 @@ import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import {unByKey} from '../src/ol/Observable.js'; import {unByKey} from '../src/ol/Observable.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import {easeOut} from '../src/ol/easing.js'; import {easeOut} from '../src/ol/easing.js';
import Point from '../src/ol/geom/Point.js'; import Point from '../src/ol/geom/Point.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
@@ -19,11 +18,6 @@ const map = new Map({
}) })
}) })
], ],
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
target: 'map', target: 'map',
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
-6
View File
@@ -1,7 +1,6 @@
import Feature from '../src/ol/Feature.js'; import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import GeoJSON from '../src/ol/format/GeoJSON.js'; import GeoJSON from '../src/ol/format/GeoJSON.js';
import Circle from '../src/ol/geom/Circle.js'; import Circle from '../src/ol/geom/Circle.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
@@ -174,11 +173,6 @@ const map = new Map({
vectorLayer vectorLayer
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -2,7 +2,6 @@ import Geolocation from '../src/ol/Geolocation.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import Overlay from '../src/ol/Overlay.js'; import Overlay from '../src/ol/Overlay.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import LineString from '../src/ol/geom/LineString.js'; import LineString from '../src/ol/geom/LineString.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {fromLonLat} from '../src/ol/proj.js'; import {fromLonLat} from '../src/ol/proj.js';
@@ -22,11 +21,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: view view: view
}); });
-6
View File
@@ -2,7 +2,6 @@ import Feature from '../src/ol/Feature.js';
import Geolocation from '../src/ol/Geolocation.js'; import Geolocation from '../src/ol/Geolocation.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import Point from '../src/ol/geom/Point.js'; import Point from '../src/ol/geom/Point.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js'; import {OSM, Vector as VectorSource} from '../src/ol/source.js';
@@ -20,11 +19,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: view view: view
}); });
-6
View File
@@ -1,7 +1,6 @@
import Feature from '../src/ol/Feature.js'; import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import IGC from '../src/ol/format/IGC.js'; import IGC from '../src/ol/format/IGC.js';
import {LineString, Point} from '../src/ol/geom.js'; import {LineString, Point} from '../src/ol/geom.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
@@ -93,11 +92,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [703365.7089403362, 5714629.865071137], center: [703365.7089403362, 5714629.865071137],
zoom: 9 zoom: 9
+1 -1
View File
@@ -7,6 +7,6 @@ docs: >
with OpenLayers. with OpenLayers.
tags: "vector, jsts, buffer" tags: "vector, jsts, buffer"
resources: resources:
- https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/1.6.0/jsts.min.js - https://unpkg.com/jsts@2.0.2/dist/jsts.min.js
--- ---
<div id="map" class="map"></div> <div id="map" class="map"></div>
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/WebGLMap.js'; import Map from '../src/ol/WebGLMap.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import {WEBGL} from '../src/ol/has.js'; import {WEBGL} from '../src/ol/has.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -20,11 +19,6 @@ if (!WEBGL) {
const map = new Map({ const map = new Map({
layers: [osm], layers: [osm],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -11,11 +10,6 @@ const osm = new TileLayer({
const map = new Map({ const map = new Map({
layers: [osm], layers: [osm],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import BingMaps from '../src/ol/source/BingMaps.js'; import BingMaps from '../src/ol/source/BingMaps.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -18,11 +17,6 @@ const bing = new TileLayer({
const map = new Map({ const map = new Map({
layers: [osm, bing], layers: [osm, bing],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM, {ATTRIBUTION} from '../src/ol/source/OSM.js'; import OSM, {ATTRIBUTION} from '../src/ol/source/OSM.js';
@@ -34,11 +33,6 @@ const map = new Map({
openSeaMapLayer openSeaMapLayer
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
maxZoom: 18, maxZoom: 18,
center: [-244780.24508882355, 5986452.183179816], center: [-244780.24508882355, 5986452.183179816],
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
import TileJSON from '../src/ol/source/TileJSON.js'; import TileJSON from '../src/ol/source/TileJSON.js';
@@ -26,11 +25,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [653600, 5723680], center: [653600, 5723680],
zoom: 5 zoom: 5
+1 -5
View File
@@ -17,11 +17,7 @@ const mousePositionControl = new MousePosition({
}); });
const map = new Map({ const map = new Map({
controls: defaultControls({ controls: defaultControls().extend([mousePositionControl]),
attributionOptions: {
collapsible: false
}
}).extend([mousePositionControl]),
layers: [ layers: [
new TileLayer({ new TileLayer({
source: new OSM() source: new OSM()
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import {getBottomLeft, getTopRight} from '../src/ol/extent.js'; import {getBottomLeft, getTopRight} from '../src/ol/extent.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {toLonLat} from '../src/ol/proj.js'; import {toLonLat} from '../src/ol/proj.js';
@@ -14,11 +13,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
+1 -5
View File
@@ -6,11 +6,7 @@ import OSM from '../src/ol/source/OSM.js';
const map = new Map({ const map = new Map({
controls: defaultControls({ controls: defaultControls().extend([
attributionOptions: {
collapsible: false
}
}).extend([
new ZoomToExtent({ new ZoomToExtent({
extent: [ extent: [
813079.7791264898, 5929220.284081122, 813079.7791264898, 5929220.284081122,
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -29,11 +28,6 @@ const map = new Map({
source: new OSM() source: new OSM()
}) })
], ],
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
target: 'map', target: 'map',
view: new View({ view: new View({
center: center, center: center,
@@ -15,8 +15,9 @@ function createMapboxStreetsV6Style(Style, Fill, Stroke, Icon, Text) {
var icon = iconCache[iconName]; var icon = iconCache[iconName];
if (!icon) { if (!icon) {
icon = new Style({image: new Icon({ icon = new Style({image: new Icon({
src: 'https://cdn.rawgit.com/mapbox/maki/master/icons/' + iconName + '-15.svg', src: 'https://unpkg.com/@mapbox/maki@4.0.0/icons/' + iconName + '-15.svg',
imgSize: [15, 15] imgSize: [15, 15],
crossOrigin: 'anonymous'
})}); })});
iconCache[iconName] = icon; iconCache[iconName] = icon;
} }
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -12,11 +11,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [14200000, 4130000], center: [14200000, 4130000],
rotation: Math.PI / 6, rotation: Math.PI / 6,
+1 -5
View File
@@ -8,11 +8,7 @@ import OSM from '../src/ol/source/OSM.js';
const scaleLineControl = new ScaleLine(); const scaleLineControl = new ScaleLine();
const map = new Map({ const map = new Map({
controls: defaultControls({ controls: defaultControls().extend([
attributionOptions: {
collapsible: false
}
}).extend([
scaleLineControl scaleLineControl
]), ]),
layers: [ layers: [
+3 -1
View File
@@ -53,7 +53,9 @@ const ExampleModify = {
const selectedFeatures = this.select.getFeatures(); const selectedFeatures = this.select.getFeatures();
this.select.on('change:active', function() { this.select.on('change:active', function() {
selectedFeatures.forEach(selectedFeatures.remove, selectedFeatures); selectedFeatures.forEach(function(each) {
selectedFeatures.remove(each);
});
}); });
}, },
setActive: function(active) { setActive: function(active) {
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import OSM from '../src/ol/source/OSM.js'; import OSM from '../src/ol/source/OSM.js';
@@ -11,11 +10,6 @@ const map = new Map({
source: new OSM() source: new OSM()
}) })
], ],
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2
+1 -1
View File
@@ -7,7 +7,7 @@ docs: >
with OpenLayers, enabling creating and editing topological geometry. Standard interaction draws edges, snapping to existing edges. Delete an edge by drawing a new edge crossing the one to delete. with OpenLayers, enabling creating and editing topological geometry. Standard interaction draws edges, snapping to existing edges. Delete an edge by drawing a new edge crossing the one to delete.
tags: "draw, edit, vector, topology, topolis" tags: "draw, edit, vector, topology, topolis"
resources: resources:
- https://cdn.rawgit.com/bjornharrtell/topolis/releases/0.1.1/topolis.min.js - https://unpkg.com/topolis@0.2.5/dist/topolis.js
- https://code.jquery.com/jquery-3.1.1.min.js - https://code.jquery.com/jquery-3.1.1.min.js
- https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js - https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js
- https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.css - https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.css
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import OSMXML from '../src/ol/format/OSMXML.js'; import OSMXML from '../src/ol/format/OSMXML.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js'; import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {bbox as bboxStrategy} from '../src/ol/loadingstrategy.js'; import {bbox as bboxStrategy} from '../src/ol/loadingstrategy.js';
@@ -121,11 +120,6 @@ const raster = new TileLayer({
map = new Map({ map = new Map({
layers: [raster, vector], layers: [raster, vector],
target: document.getElementById('map'), target: document.getElementById('map'),
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [739218, 5906096], center: [739218, 5906096],
maxZoom: 19, maxZoom: 19,
+1 -1
View File
@@ -77,7 +77,7 @@ function getJsSource(chunk, jsName) {
return jsSource; return jsSource;
} }
} }
if (module.identifier.endsWith(jsName)) { if (module.identifier.endsWith(jsName) && module.source) {
return module.source; return module.source;
} }
} }
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import {getWidth} from '../src/ol/extent.js'; import {getWidth} from '../src/ol/extent.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {fromLonLat, get as getProjection} from '../src/ol/proj.js'; import {fromLonLat, get as getProjection} from '../src/ol/proj.js';
@@ -10,11 +9,6 @@ import WMTSTileGrid from '../src/ol/tilegrid/WMTS.js';
const map = new Map({ const map = new Map({
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
zoom: 5, zoom: 5,
center: fromLonLat([5, 45]) center: fromLonLat([5, 45])
-6
View File
@@ -1,6 +1,5 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls} from '../src/ol/control.js';
import {getWidth, getTopLeft} from '../src/ol/extent.js'; import {getWidth, getTopLeft} from '../src/ol/extent.js';
import TileLayer from '../src/ol/layer/Tile.js'; import TileLayer from '../src/ol/layer/Tile.js';
import {get as getProjection} from '../src/ol/proj.js'; import {get as getProjection} from '../src/ol/proj.js';
@@ -48,11 +47,6 @@ const map = new Map({
}) })
], ],
target: 'map', target: 'map',
controls: defaultControls({
attributionOptions: {
collapsible: false
}
}),
view: new View({ view: new View({
center: [-11158582, 4813697], center: [-11158582, 4813697],
zoom: 4 zoom: 4
+10 -12
View File
@@ -18,7 +18,7 @@
"build-examples": "webpack --config examples/webpack/config.js --mode production", "build-examples": "webpack --config examples/webpack/config.js --mode production",
"build-package": "npm run transpile && npm run copy-css && node tasks/prepare-package && cp README.md build/ol", "build-package": "npm run transpile && npm run copy-css && node tasks/prepare-package && cp README.md build/ol",
"build-index": "npm run build-package && node tasks/generate-index", "build-index": "npm run build-package && node tasks/generate-index",
"build-legacy": "rm -rf build && npm run build-index && rollup --config config/rollup.js && cleancss --source-map src/ol/ol.css -o build/ol.css", "build-legacy": "rm -rf build && npm run build-index && webpack --config config/webpack-config-legacy-build.js && cleancss --source-map src/ol/ol.css -o build/legacy/ol.css",
"copy-css": "cp src/ol/ol.css build/ol/ol.css", "copy-css": "cp src/ol/ol.css build/ol/ol.css",
"transpile": "rm -rf build/ol && mkdir -p build && buble --input src/ol --output build/ol --no modules --sourcemap", "transpile": "rm -rf build/ol && mkdir -p build && buble --input src/ol --output build/ol --no modules --sourcemap",
"typecheck": "tsc --pretty", "typecheck": "tsc --pretty",
@@ -40,7 +40,9 @@
}, },
"devDependencies": { "devDependencies": {
"@openlayers/eslint-plugin": "^4.0.0-beta.1", "@openlayers/eslint-plugin": "^4.0.0-beta.1",
"@types/arcgis-rest-api": "^10.4.3",
"@types/geojson": "^7946.0.4", "@types/geojson": "^7946.0.4",
"@types/rbush": "^2.0.2",
"@types/topojson-specification": "^1.0.0", "@types/topojson-specification": "^1.0.0",
"buble": "^0.19.3", "buble": "^0.19.3",
"buble-loader": "^0.5.1", "buble-loader": "^0.5.1",
@@ -51,13 +53,14 @@
"eslint": "5.0.1", "eslint": "5.0.1",
"eslint-config-openlayers": "^11.0.0", "eslint-config-openlayers": "^11.0.0",
"expect.js": "0.3.1", "expect.js": "0.3.1",
"front-matter": "^2.1.2", "front-matter": "^3.0.0",
"fs-extra": "^7.0.0", "fs-extra": "^7.0.0",
"glob": "^7.1.2", "glob": "^7.1.2",
"handlebars": "4.0.11", "handlebars": "4.0.11",
"istanbul": "0.4.5", "istanbul": "0.4.5",
"jquery": "3.3.1", "jquery": "3.3.1",
"jsdoc": "3.5.5", "jsdoc": "3.5.5",
"jsdoc-plugin-typescript": "^1.0.2",
"karma": "^3.0.0", "karma": "^3.0.0",
"karma-chrome-launcher": "2.2.0", "karma-chrome-launcher": "2.2.0",
"karma-coverage": "^1.1.1", "karma-coverage": "^1.1.1",
@@ -66,23 +69,18 @@
"karma-sauce-launcher": "1.2.0", "karma-sauce-launcher": "1.2.0",
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "4.0.0-beta.0", "karma-webpack": "4.0.0-beta.0",
"marked": "0.5.0", "marked": "0.5.1",
"mocha": "5.2.0", "mocha": "5.2.0",
"mustache": "^2.3.0", "mustache": "^3.0.0",
"pixelmatch": "^4.0.2", "pixelmatch": "^4.0.2",
"proj4": "2.5.0", "proj4": "2.5.0",
"rollup": "0.65.2", "rollup": "0.66.6",
"rollup-plugin-buble": "0.19.2",
"rollup-plugin-commonjs": "9.1.6",
"rollup-plugin-node-resolve": "3.4.0",
"rollup-plugin-sourcemaps": "0.4.2",
"rollup-plugin-uglify": "5.0.2",
"sinon": "^6.0.0", "sinon": "^6.0.0",
"typescript": "^3.1.0-dev.20180905", "typescript": "^3.1.0-dev.20180905",
"uglifyjs-webpack-plugin": "^1.2.5", "uglifyjs-webpack-plugin": "^2.0.1",
"url-polyfill": "^1.0.13", "url-polyfill": "^1.0.13",
"walk": "^2.3.9", "walk": "^2.3.9",
"webpack": "4.19.0", "webpack": "4.23.1",
"webpack-cli": "^3.0.8", "webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4" "webpack-dev-server": "^3.1.4"
}, },
+1 -1
View File
@@ -14,7 +14,7 @@ class AssertionError extends Error {
* @param {number} code Error code. * @param {number} code Error code.
*/ */
constructor(code) { constructor(code) {
const path = VERSION.split('-')[0]; const path = VERSION === 'latest' ? VERSION : 'v' + VERSION.split('-')[0];
const message = 'Assertion failed. See https://openlayers.org/en/' + path + const message = 'Assertion failed. See https://openlayers.org/en/' + path +
'/doc/errors/#' + code + ' for details.'; '/doc/errors/#' + code + ' for details.';
+4 -2
View File
@@ -24,7 +24,7 @@ const Property = {
export class CollectionEvent extends Event { export class CollectionEvent extends Event {
/** /**
* @param {import("./CollectionEventType.js").default} type Type. * @param {CollectionEventType} type Type.
* @param {*=} opt_element Element. * @param {*=} opt_element Element.
*/ */
constructor(type, opt_element) { constructor(type, opt_element) {
@@ -56,6 +56,8 @@ export class CollectionEvent extends Event {
* Collection; they trigger events on the appropriate object, not on the * Collection; they trigger events on the appropriate object, not on the
* Collection as a whole. * Collection as a whole.
* *
* @fires CollectionEvent
*
* @template T * @template T
* @api * @api
*/ */
@@ -160,7 +162,7 @@ class Collection extends BaseObject {
* @api * @api
*/ */
getLength() { getLength() {
return /** @type {number} */ (this.get(Property.LENGTH)); return this.get(Property.LENGTH);
} }
/** /**
+2 -2
View File
@@ -8,13 +8,13 @@
export default { export default {
/** /**
* Triggered when an item is added to the collection. * Triggered when an item is added to the collection.
* @event module:ol/Collection~CollectionEvent#add * @event module:ol/Collection.CollectionEvent#add
* @api * @api
*/ */
ADD: 'add', ADD: 'add',
/** /**
* Triggered when an item is removed from the collection. * Triggered when an item is removed from the collection.
* @event module:ol/Collection~CollectionEvent#remove * @event module:ol/Collection.CollectionEvent#remove
* @api * @api
*/ */
REMOVE: 'remove' REMOVE: 'remove'
+19 -14
View File
@@ -5,8 +5,14 @@ import {assert} from './asserts.js';
import {listen, unlisten, unlistenByKey} from './events.js'; import {listen, unlisten, unlistenByKey} from './events.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
import BaseObject, {getChangeEventType} from './Object.js'; import BaseObject, {getChangeEventType} from './Object.js';
import Geometry from './geom/Geometry.js';
import Style from './style/Style.js'; /**
* @typedef {typeof Feature|typeof import("./render/Feature.js").default} FeatureClass
*/
/**
* @typedef {Feature|import("./render/Feature.js").default} FeatureLike
*/
/** /**
* @classdesc * @classdesc
@@ -78,7 +84,7 @@ class Feature extends BaseObject {
/** /**
* User provided style. * User provided style.
* @private * @private
* @type {import("./style/Style.js").default|Array<import("./style/Style.js").default>|import("./style/Style.js").StyleFunction} * @type {import("./style/Style.js").StyleLike}
*/ */
this.style_ = null; this.style_ = null;
@@ -98,11 +104,9 @@ class Feature extends BaseObject {
this, getChangeEventType(this.geometryName_), this, getChangeEventType(this.geometryName_),
this.handleGeometryChanged_, this); this.handleGeometryChanged_, this);
if (opt_geometryOrProperties !== undefined) { if (opt_geometryOrProperties) {
if (opt_geometryOrProperties instanceof Geometry || if (typeof /** @type {?} */ (opt_geometryOrProperties).getSimplifiedGeometry === 'function') {
!opt_geometryOrProperties) { const geometry = /** @type {import("./geom/Geometry.js").default} */ (opt_geometryOrProperties);
/** @type {?Geometry} */
const geometry = opt_geometryOrProperties;
this.setGeometry(geometry); this.setGeometry(geometry);
} else { } else {
/** @type {Object<string, *>} */ /** @type {Object<string, *>} */
@@ -171,7 +175,7 @@ class Feature extends BaseObject {
/** /**
* Get the feature's style. Will return what was provided to the * Get the feature's style. Will return what was provided to the
* {@link module:ol/Feature~Feature#setStyle} method. * {@link module:ol/Feature~Feature#setStyle} method.
* @return {import("./style/Style.js").default|Array<import("./style/Style.js").default>|import("./style/Style.js").StyleFunction} The feature style. * @return {import("./style/Style.js").StyleLike} The feature style.
* @api * @api
*/ */
getStyle() { getStyle() {
@@ -226,7 +230,7 @@ class Feature extends BaseObject {
* Set the style for the feature. This can be a single style object, an array * Set the style for the feature. This can be a single style object, an array
* of styles, or a function that takes a resolution and returns an array of * of styles, or a function that takes a resolution and returns an array of
* styles. If it is `null` the feature has no style (a `null` style). * styles. If it is `null` the feature has no style (a `null` style).
* @param {import("./style/Style.js").default|Array<import("./style/Style.js").default>|import("./style/Style.js").StyleFunction} style Style for this feature. * @param {import("./style/Style.js").StyleLike} style Style for this feature.
* @api * @api
* @fires module:ol/events/Event~Event#event:change * @fires module:ol/events/Event~Event#event:change
*/ */
@@ -272,9 +276,9 @@ class Feature extends BaseObject {
/** /**
* Convert the provided object into a feature style function. Functions passed * Convert the provided object into a feature style function. Functions passed
* through unchanged. Arrays of import("./style/Style.js").default or single style objects wrapped * through unchanged. Arrays of Style or single style objects wrapped
* in a new feature style function. * in a new feature style function.
* @param {import("./style/Style.js").StyleFunction|!Array<import("./style/Style.js").default>|!import("./style/Style.js").default} obj * @param {!import("./style/Style.js").StyleFunction|!Array<import("./style/Style.js").default>|!import("./style/Style.js").default} obj
* A feature style function, a single style, or an array of styles. * A feature style function, a single style, or an array of styles.
* @return {import("./style/Style.js").StyleFunction} A style function. * @return {import("./style/Style.js").StyleFunction} A style function.
*/ */
@@ -289,9 +293,10 @@ export function createStyleFunction(obj) {
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
styles = obj; styles = obj;
} else { } else {
assert(obj instanceof Style, assert(typeof /** @type {?} */ (obj).getZIndex === 'function',
41); // Expected an `import("./style/Style.js").Style` or an array of `import("./style/Style.js").Style` 41); // Expected an `import("./style/Style.js").Style` or an array of `import("./style/Style.js").Style`
styles = [obj]; const style = /** @type {import("./style/Style.js").default} */ (obj);
styles = [style];
} }
return function() { return function() {
return styles; return styles;
+26 -2
View File
@@ -4,6 +4,7 @@
import GeolocationProperty from './GeolocationProperty.js'; import GeolocationProperty from './GeolocationProperty.js';
import BaseObject, {getChangeEventType} from './Object.js'; import BaseObject, {getChangeEventType} from './Object.js';
import {listen} from './events.js'; import {listen} from './events.js';
import Event from './events/Event.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
import {circular as circularPolygon} from './geom/Polygon.js'; import {circular as circularPolygon} from './geom/Polygon.js';
import {GEOLOCATION} from './has.js'; import {GEOLOCATION} from './has.js';
@@ -11,6 +12,30 @@ import {toRadians} from './math.js';
import {get as getProjection, getTransformFromProjections, identityTransform} from './proj.js'; import {get as getProjection, getTransformFromProjections, identityTransform} from './proj.js';
/**
* @classdesc
* Events emitted on Geolocation error.
*/
class GeolocationError extends Event {
/**
* @param {PositionError} error error object.
*/
constructor(error) {
super(EventType.ERROR);
/**
* @type {number}
*/
this.code = error.code;
/**
* @type {string}
*/
this.message = error.message;
}
}
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {boolean} [tracking=false] Start Tracking right after * @property {boolean} [tracking=false] Start Tracking right after
@@ -174,9 +199,8 @@ class Geolocation extends BaseObject {
* @param {PositionError} error error object. * @param {PositionError} error error object.
*/ */
positionError_(error) { positionError_(error) {
error.type = EventType.ERROR;
this.setTracking(false); this.setTracking(false);
this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error)); this.dispatchEvent(new GeolocationError(error));
} }
/** /**
+32 -22
View File
@@ -17,7 +17,7 @@ import Text from './style/Text.js';
/** /**
* @type {import("./style/Stroke.js").default} * @type {Stroke}
* @private * @private
* @const * @const
*/ */
@@ -26,7 +26,6 @@ const DEFAULT_STROKE_STYLE = new Stroke({
}); });
/** /**
* TODO can be configurable
* @type {Array<number>} * @type {Array<number>}
* @private * @private
*/ */
@@ -36,7 +35,7 @@ const INTERVALS = [
/** /**
* @typedef {Object} GraticuleLabelDataType * @typedef {Object} GraticuleLabelDataType
* @property {import("./geom/Point.js").default} geom * @property {Point} geom
* @property {string} text * @property {string} text
*/ */
@@ -50,7 +49,7 @@ const INTERVALS = [
* appropriate for conformal projections like Spherical Mercator. If you * appropriate for conformal projections like Spherical Mercator. If you
* increase the value, more lines will be drawn and the drawing performance will * increase the value, more lines will be drawn and the drawing performance will
* decrease. * decrease.
* @property {import("./style/Stroke.js").default} [strokeStyle='rgba(0,0,0,0.2)'] The * @property {Stroke} [strokeStyle='rgba(0,0,0,0.2)'] The
* stroke style to use for drawing the graticule. If not provided, a not fully * stroke style to use for drawing the graticule. If not provided, a not fully
* opaque black will be used. * opaque black will be used.
* @property {number} [targetSize=100] The target size of the graticule cells, * @property {number} [targetSize=100] The target size of the graticule cells,
@@ -71,7 +70,7 @@ const INTERVALS = [
* @property {number} [latLabelPosition=1] Latitude label position in fractions * @property {number} [latLabelPosition=1] Latitude label position in fractions
* (0..1) of view extent. 0 means at the left of the viewport, 1 means at the * (0..1) of view extent. 0 means at the left of the viewport, 1 means at the
* right. * right.
* @property {import("./style/Text.js").default} [lonLabelStyle] Longitude label text * @property {Text} [lonLabelStyle] Longitude label text
* style. If not provided, the following style will be used: * style. If not provided, the following style will be used:
* ```js * ```js
* new Text({ * new Text({
@@ -89,7 +88,7 @@ const INTERVALS = [
* Note that the default's `textBaseline` configuration will not work well for * Note that the default's `textBaseline` configuration will not work well for
* `lonLabelPosition` configurations that position labels close to the top of * `lonLabelPosition` configurations that position labels close to the top of
* the viewport. * the viewport.
* @property {import("./style/Text.js").default} [latLabelStyle] Latitude label text style. * @property {Text} [latLabelStyle] Latitude label text style.
* If not provided, the following style will be used: * If not provided, the following style will be used:
* ```js * ```js
* new Text({ * new Text({
@@ -107,6 +106,11 @@ const INTERVALS = [
* Note that the default's `textAlign` configuration will not work well for * Note that the default's `textAlign` configuration will not work well for
* `latLabelPosition` configurations that position labels close to the left of * `latLabelPosition` configurations that position labels close to the left of
* the viewport. * the viewport.
* @property {Array<number>} [intervals=[90, 45, 30, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.01, 0.005, 0.002, 0.001]]
* Intervals (in degrees) for the graticule. Example to limit graticules to 30 and 10 degrees intervals:
* ```js
* [30, 10]
* ```
*/ */
@@ -200,19 +204,19 @@ class Graticule {
this.maxLines_ = options.maxLines !== undefined ? options.maxLines : 100; this.maxLines_ = options.maxLines !== undefined ? options.maxLines : 100;
/** /**
* @type {Array<import("./geom/LineString.js").default>} * @type {Array<LineString>}
* @private * @private
*/ */
this.meridians_ = []; this.meridians_ = [];
/** /**
* @type {Array<import("./geom/LineString.js").default>} * @type {Array<LineString>}
* @private * @private
*/ */
this.parallels_ = []; this.parallels_ = [];
/** /**
* @type {import("./style/Stroke.js").default} * @type {Stroke}
* @private * @private
*/ */
this.strokeStyle_ = options.strokeStyle !== undefined ? options.strokeStyle : DEFAULT_STROKE_STYLE; this.strokeStyle_ = options.strokeStyle !== undefined ? options.strokeStyle : DEFAULT_STROKE_STYLE;
@@ -282,7 +286,7 @@ class Graticule {
options.latLabelPosition; options.latLabelPosition;
/** /**
* @type {import("./style/Text.js").default} * @type {Text}
* @private * @private
*/ */
this.lonLabelStyle_ = options.lonLabelStyle !== undefined ? options.lonLabelStyle : this.lonLabelStyle_ = options.lonLabelStyle !== undefined ? options.lonLabelStyle :
@@ -299,7 +303,7 @@ class Graticule {
}); });
/** /**
* @type {import("./style/Text.js").default} * @type {Text}
* @private * @private
*/ */
this.latLabelStyle_ = options.latLabelStyle !== undefined ? options.latLabelStyle : this.latLabelStyle_ = options.latLabelStyle !== undefined ? options.latLabelStyle :
@@ -319,6 +323,12 @@ class Graticule {
this.parallelsLabels_ = []; this.parallelsLabels_ = [];
} }
/**
* @type {Array<number>}
* @private
*/
this.intervals_ = options.intervals !== undefined ? options.intervals : INTERVALS;
this.setMap(options.map !== undefined ? options.map : null); this.setMap(options.map !== undefined ? options.map : null);
} }
@@ -348,10 +358,10 @@ class Graticule {
} }
/** /**
* @param {import("./geom/LineString.js").default} lineString Meridian * @param {LineString} lineString Meridian
* @param {import("./extent.js").Extent} extent Extent. * @param {import("./extent.js").Extent} extent Extent.
* @param {number} index Index. * @param {number} index Index.
* @return {import("./geom/Point.js").default} Meridian point. * @return {Point} Meridian point.
* @private * @private
*/ */
getMeridianPoint_(lineString, extent, index) { getMeridianPoint_(lineString, extent, index) {
@@ -398,10 +408,10 @@ class Graticule {
} }
/** /**
* @param {import("./geom/LineString.js").default} lineString Parallels. * @param {LineString} lineString Parallels.
* @param {import("./extent.js").Extent} extent Extent. * @param {import("./extent.js").Extent} extent Extent.
* @param {number} index Index. * @param {number} index Index.
* @return {import("./geom/Point.js").default} Parallel point. * @return {Point} Parallel point.
* @private * @private
*/ */
getParallelPoint_(lineString, extent, index) { getParallelPoint_(lineString, extent, index) {
@@ -530,8 +540,8 @@ class Graticule {
const p1 = []; const p1 = [];
/** @type {Array<number>} **/ /** @type {Array<number>} **/
const p2 = []; const p2 = [];
for (let i = 0, ii = INTERVALS.length; i < ii; ++i) { for (let i = 0, ii = this.intervals_.length; i < ii; ++i) {
const delta = INTERVALS[i] / 2; const delta = this.intervals_[i] / 2;
p1[0] = centerLon - delta; p1[0] = centerLon - delta;
p1[1] = centerLat - delta; p1[1] = centerLat - delta;
p2[0] = centerLon + delta; p2[0] = centerLon + delta;
@@ -542,7 +552,7 @@ class Graticule {
if (dist <= target) { if (dist <= target) {
break; break;
} }
interval = INTERVALS[i]; interval = this.intervals_[i];
} }
return interval; return interval;
} }
@@ -561,7 +571,7 @@ class Graticule {
* @param {number} minLat Minimal latitude. * @param {number} minLat Minimal latitude.
* @param {number} maxLat Maximal latitude. * @param {number} maxLat Maximal latitude.
* @param {number} squaredTolerance Squared tolerance. * @param {number} squaredTolerance Squared tolerance.
* @return {import("./geom/LineString.js").default} The meridian line string. * @return {LineString} The meridian line string.
* @param {number} index Index. * @param {number} index Index.
* @private * @private
*/ */
@@ -579,7 +589,7 @@ class Graticule {
/** /**
* Get the list of meridians. Meridians are lines of equal longitude. * Get the list of meridians. Meridians are lines of equal longitude.
* @return {Array<import("./geom/LineString.js").default>} The meridians. * @return {Array<LineString>} The meridians.
* @api * @api
*/ */
getMeridians() { getMeridians() {
@@ -591,7 +601,7 @@ class Graticule {
* @param {number} minLon Minimal longitude. * @param {number} minLon Minimal longitude.
* @param {number} maxLon Maximal longitude. * @param {number} maxLon Maximal longitude.
* @param {number} squaredTolerance Squared tolerance. * @param {number} squaredTolerance Squared tolerance.
* @return {import("./geom/LineString.js").default} The parallel line string. * @return {LineString} The parallel line string.
* @param {number} index Index. * @param {number} index Index.
* @private * @private
*/ */
@@ -609,7 +619,7 @@ class Graticule {
/** /**
* Get the list of parallels. Parallels are lines of equal latitude. * Get the list of parallels. Parallels are lines of equal latitude.
* @return {Array<import("./geom/LineString.js").default>} The parallels. * @return {Array<LineString>} The parallels.
* @api * @api
*/ */
getParallels() { getParallels() {
+1 -1
View File
@@ -64,7 +64,7 @@ class ImageWrapper extends ImageBase {
/** /**
* @protected * @protected
* @type {import("./ImageState.js").default} * @type {ImageState}
*/ */
this.state = ImageState.IDLE; this.state = ImageState.IDLE;
+7 -2
View File
@@ -1,6 +1,7 @@
/** /**
* @module ol/ImageBase * @module ol/ImageBase
*/ */
import {abstract} from './util.js';
import EventTarget from './events/Target.js'; import EventTarget from './events/Target.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
@@ -63,7 +64,9 @@ class ImageBase extends EventTarget {
* @abstract * @abstract
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image. * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
*/ */
getImage() {} getImage() {
return abstract();
}
/** /**
* @return {number} PixelRatio. * @return {number} PixelRatio.
@@ -90,7 +93,9 @@ class ImageBase extends EventTarget {
* Load not yet loaded URI. * Load not yet loaded URI.
* @abstract * @abstract
*/ */
load() {} load() {
abstract();
}
} }
+2 -2
View File
@@ -11,7 +11,7 @@ import ImageState from './ImageState.js';
* If any error occurs during drawing, the "done" callback should be called with * If any error occurs during drawing, the "done" callback should be called with
* that error. * that error.
* *
* @typedef {function(function(Error))} Loader * @typedef {function(function(Error=))} Loader
*/ */
@@ -62,7 +62,7 @@ class ImageCanvas extends ImageBase {
/** /**
* Handle async drawing complete. * Handle async drawing complete.
* @param {Error} err Any error during drawing. * @param {Error=} err Any error during drawing.
* @private * @private
*/ */
handleLoad_(err) { handleLoad_(err) {
+3 -7
View File
@@ -7,17 +7,12 @@ import {createCanvasContext2D} from './dom.js';
import {listenOnce, unlistenByKey} from './events.js'; import {listenOnce, unlistenByKey} from './events.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
/**
* @typedef {function(new: ImageTile, import("./tilecoord.js").TileCoord,
* import("./TileState.js").default, string, ?string, import("./Tile.js").LoadFunction)} TileClass
* @api
*/
class ImageTile extends Tile { class ImageTile extends Tile {
/** /**
* @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate. * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("./TileState.js").default} state State. * @param {TileState} state State.
* @param {string} src Image source URI. * @param {string} src Image source URI.
* @param {?string} crossOrigin Cross origin. * @param {?string} crossOrigin Cross origin.
* @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function. * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.
@@ -114,7 +109,8 @@ class ImageTile extends Tile {
* @private * @private
*/ */
handleImageLoad_() { handleImageLoad_() {
if (this.image_.naturalWidth && this.image_.naturalHeight) { const image = /** @type {HTMLImageElement} */ (this.image_);
if (image.naturalWidth && image.naturalHeight) {
this.state = TileState.LOADED; this.state = TileState.LOADED;
} else { } else {
this.state = TileState.EMPTY; this.state = TileState.EMPTY;
+5 -5
View File
@@ -27,10 +27,10 @@ class MapBrowserEventHandler extends EventTarget {
this.map_ = map; this.map_ = map;
/** /**
* @type {number} * @type {any}
* @private * @private
*/ */
this.clickTimeoutId_ = 0; this.clickTimeoutId_;
/** /**
* @type {boolean} * @type {boolean}
@@ -118,17 +118,17 @@ class MapBrowserEventHandler extends EventTarget {
let newEvent = new MapBrowserPointerEvent( let newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.CLICK, this.map_, pointerEvent); MapBrowserEventType.CLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent); this.dispatchEvent(newEvent);
if (this.clickTimeoutId_ !== 0) { if (this.clickTimeoutId_ !== undefined) {
// double-click // double-click
clearTimeout(this.clickTimeoutId_); clearTimeout(this.clickTimeoutId_);
this.clickTimeoutId_ = 0; this.clickTimeoutId_ = undefined;
newEvent = new MapBrowserPointerEvent( newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.DBLCLICK, this.map_, pointerEvent); MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent); this.dispatchEvent(newEvent);
} else { } else {
// click // click
this.clickTimeoutId_ = setTimeout(function() { this.clickTimeoutId_ = setTimeout(function() {
this.clickTimeoutId_ = 0; this.clickTimeoutId_ = undefined;
const newEvent = new MapBrowserPointerEvent( const newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent); MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent); this.dispatchEvent(newEvent);
+1 -1
View File
@@ -8,7 +8,7 @@
export default { export default {
/** /**
* Triggered when a property is changed. * Triggered when a property is changed.
* @event module:ol/Object~ObjectEvent#propertychange * @event module:ol/Object.ObjectEvent#propertychange
* @api * @api
*/ */
PROPERTYCHANGE: 'propertychange' PROPERTYCHANGE: 'propertychange'
+5 -5
View File
@@ -22,7 +22,7 @@ import {containsExtent} from './extent.js';
* shifts the overlay down. * shifts the overlay down.
* @property {import("./coordinate.js").Coordinate} [position] The overlay position * @property {import("./coordinate.js").Coordinate} [position] The overlay position
* in map projection. * in map projection.
* @property {import("./OverlayPositioning.js").default} [positioning='top-left'] Defines how * @property {OverlayPositioning} [positioning='top-left'] Defines how
* the overlay is actually positioned with respect to its `position` property. * the overlay is actually positioned with respect to its `position` property.
* Possible values are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`, * Possible values are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`,
* `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`, * `'center-left'`, `'center-center'`, `'center-right'`, `'top-left'`,
@@ -205,7 +205,7 @@ class Overlay extends BaseObject {
this.setOffset(options.offset !== undefined ? options.offset : [0, 0]); this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);
this.setPositioning(options.positioning !== undefined ? this.setPositioning(options.positioning !== undefined ?
/** @type {import("./OverlayPositioning.js").default} */ (options.positioning) : /** @type {OverlayPositioning} */ (options.positioning) :
OverlayPositioning.TOP_LEFT); OverlayPositioning.TOP_LEFT);
if (options.position !== undefined) { if (options.position !== undefined) {
@@ -271,14 +271,14 @@ class Overlay extends BaseObject {
/** /**
* Get the current positioning of this overlay. * Get the current positioning of this overlay.
* @return {import("./OverlayPositioning.js").default} How the overlay is positioned * @return {OverlayPositioning} How the overlay is positioned
* relative to its point on the map. * relative to its point on the map.
* @observable * @observable
* @api * @api
*/ */
getPositioning() { getPositioning() {
return ( return (
/** @type {import("./OverlayPositioning.js").default} */ (this.get(Property.POSITIONING)) /** @type {OverlayPositioning} */ (this.get(Property.POSITIONING))
); );
} }
@@ -469,7 +469,7 @@ class Overlay extends BaseObject {
/** /**
* Set the positioning for this overlay. * Set the positioning for this overlay.
* @param {import("./OverlayPositioning.js").default} positioning how the overlay is * @param {OverlayPositioning} positioning how the overlay is
* positioned relative to its point on the map. * positioned relative to its point on the map.
* @observable * @observable
* @api * @api
+36 -27
View File
@@ -42,7 +42,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* @property {null|import("./extent.js").Extent} extent * @property {null|import("./extent.js").Extent} extent
* @property {import("./coordinate.js").Coordinate} focus * @property {import("./coordinate.js").Coordinate} focus
* @property {number} index * @property {number} index
* @property {Object<number, import("./layer/Layer.js").State>} layerStates * @property {Object<string, import("./layer/Layer.js").State>} layerStates
* @property {Array<import("./layer/Layer.js").State>} layerStatesArray * @property {Array<import("./layer/Layer.js").State>} layerStatesArray
* @property {import("./transform.js").Transform} pixelToCoordinateTransform * @property {import("./transform.js").Transform} pixelToCoordinateTransform
* @property {Array<PostRenderFunction>} postRenderFunctions * @property {Array<PostRenderFunction>} postRenderFunctions
@@ -88,7 +88,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* @typedef {Object} MapOptions * @typedef {Object} MapOptions
* @property {Collection<import("./control/Control.js").default>|Array<import("./control/Control.js").default>} [controls] * @property {Collection<import("./control/Control.js").default>|Array<import("./control/Control.js").default>} [controls]
* Controls initially added to the map. If not specified, * Controls initially added to the map. If not specified,
* {@link module:ol/control/util~defaults} is used. * {@link module:ol/control~defaults} is used.
* @property {number} [pixelRatio=window.devicePixelRatio] The ratio between * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between
* physical pixels and device-independent pixels (dips) on the device. * physical pixels and device-independent pixels (dips) on the device.
* @property {Collection<import("./interaction/Interaction.js").default>|Array<import("./interaction/Interaction.js").default>} [interactions] * @property {Collection<import("./interaction/Interaction.js").default>|Array<import("./interaction/Interaction.js").default>} [interactions]
@@ -102,7 +102,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* map target (i.e. the user-provided div for the map). If this is not * map target (i.e. the user-provided div for the map). If this is not
* `document`, the target element needs to be focused for key events to be * `document`, the target element needs to be focused for key events to be
* emitted, requiring that the target element has a `tabindex` attribute. * emitted, requiring that the target element has a `tabindex` attribute.
* @property {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>} [layers] * @property {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>|LayerGroup} [layers]
* Layers. If this is not defined, a map with no layers will be rendered. Note * Layers. If this is not defined, a map with no layers will be rendered. Note
* that layers are rendered in the order supplied, so if you want, for example, * that layers are rendered in the order supplied, so if you want, for example,
* a vector layer to appear on top of a tile layer, it must come after the tile * a vector layer to appear on top of a tile layer, it must come after the tile
@@ -464,6 +464,10 @@ class PluggableMap extends BaseObject {
} }
/**
* @abstract
* @return {import("./renderer/Map.js").default} The map renderer
*/
createRenderer() { createRenderer() {
throw new Error('Use a map type that has a createRenderer method'); throw new Error('Use a map type that has a createRenderer method');
} }
@@ -546,7 +550,7 @@ class PluggableMap extends BaseObject {
* callback with each intersecting feature. Layers included in the detection can * callback with each intersecting feature. Layers included in the detection can
* be configured through the `layerFilter` option in `opt_options`. * be configured through the `layerFilter` option in `opt_options`.
* @param {import("./pixel.js").Pixel} pixel Pixel. * @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {function(this: S, (import("./Feature.js").default|import("./render/Feature.js").default), * @param {function(this: S, import("./Feature.js").FeatureLike,
* import("./layer/Layer.js").default): T} callback Feature callback. The callback will be * import("./layer/Layer.js").default): T} callback Feature callback. The callback will be
* called with two arguments. The first argument is one * called with two arguments. The first argument is one
* {@link module:ol/Feature feature} or * {@link module:ol/Feature feature} or
@@ -565,7 +569,8 @@ class PluggableMap extends BaseObject {
return; return;
} }
const coordinate = this.getCoordinateFromPixel(pixel); const coordinate = this.getCoordinateFromPixel(pixel);
opt_options = opt_options !== undefined ? opt_options : {}; opt_options = opt_options !== undefined ? opt_options :
/** @type {AtPixelOptions} */ ({});
const hitTolerance = opt_options.hitTolerance !== undefined ? const hitTolerance = opt_options.hitTolerance !== undefined ?
opt_options.hitTolerance * this.frameState_.pixelRatio : 0; opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
const layerFilter = opt_options.layerFilter !== undefined ? const layerFilter = opt_options.layerFilter !== undefined ?
@@ -579,7 +584,7 @@ class PluggableMap extends BaseObject {
* Get all features that intersect a pixel on the viewport. * Get all features that intersect a pixel on the viewport.
* @param {import("./pixel.js").Pixel} pixel Pixel. * @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {AtPixelOptions=} opt_options Optional options. * @param {AtPixelOptions=} opt_options Optional options.
* @return {Array<import("./Feature.js").default|import("./render/Feature.js").default>} The detected features or * @return {Array<import("./Feature.js").FeatureLike>} The detected features or
* `null` if none were found. * `null` if none were found.
* @api * @api
*/ */
@@ -637,7 +642,8 @@ class PluggableMap extends BaseObject {
return false; return false;
} }
const coordinate = this.getCoordinateFromPixel(pixel); const coordinate = this.getCoordinateFromPixel(pixel);
opt_options = opt_options !== undefined ? opt_options : {}; opt_options = opt_options !== undefined ? opt_options :
/** @type {AtPixelOptions} */ ({});
const layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE; const layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;
const hitTolerance = opt_options.hitTolerance !== undefined ? const hitTolerance = opt_options.hitTolerance !== undefined ?
opt_options.hitTolerance * this.frameState_.pixelRatio : 0; opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
@@ -657,13 +663,16 @@ class PluggableMap extends BaseObject {
/** /**
* Returns the map pixel position for a browser event relative to the viewport. * Returns the map pixel position for a browser event relative to the viewport.
* @param {Event} event Event. * @param {Event|TouchEvent} event Event.
* @return {import("./pixel.js").Pixel} Pixel. * @return {import("./pixel.js").Pixel} Pixel.
* @api * @api
*/ */
getEventPixel(event) { getEventPixel(event) {
const viewportPosition = this.viewport_.getBoundingClientRect(); const viewportPosition = this.viewport_.getBoundingClientRect();
const eventPosition = event.changedTouches ? event.changedTouches[0] : event; const eventPosition = 'changedTouches' in event ?
/** @type {TouchEvent} */ (event).changedTouches[0] :
/** @type {MouseEvent} */ (event);
return [ return [
eventPosition.clientX - viewportPosition.left, eventPosition.clientX - viewportPosition.left,
eventPosition.clientY - viewportPosition.top eventPosition.clientY - viewportPosition.top
@@ -963,7 +972,7 @@ class PluggableMap extends BaseObject {
tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads); tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
} }
} }
if (frameState && this.hasListener(MapEventType.RENDERCOMPLETE) && !frameState.animate && if (frameState && this.hasListener(RenderEventType.RENDERCOMPLETE) && !frameState.animate &&
!this.tileQueue_.getTilesLoading() && !getLoading(this.getLayers().getArray())) { !this.tileQueue_.getTilesLoading() && !getLoading(this.getLayers().getArray())) {
this.renderer_.dispatchRenderEvent(RenderEventType.RENDERCOMPLETE, frameState); this.renderer_.dispatchRenderEvent(RenderEventType.RENDERCOMPLETE, frameState);
} }
@@ -1295,8 +1304,7 @@ class PluggableMap extends BaseObject {
* @param {import("./Feature.js").default} feature Feature. * @param {import("./Feature.js").default} feature Feature.
*/ */
skipFeature(feature) { skipFeature(feature) {
const featureUid = getUid(feature).toString(); this.skippedFeatureUids_[getUid(feature)] = true;
this.skippedFeatureUids_[featureUid] = true;
this.render(); this.render();
} }
@@ -1331,8 +1339,7 @@ class PluggableMap extends BaseObject {
* @param {import("./Feature.js").default} feature Feature. * @param {import("./Feature.js").default} feature Feature.
*/ */
unskipFeature(feature) { unskipFeature(feature) {
const featureUid = getUid(feature).toString(); delete this.skippedFeatureUids_[getUid(feature)];
delete this.skippedFeatureUids_[featureUid];
this.render(); this.render();
} }
} }
@@ -1359,8 +1366,8 @@ function createOptionsInternal(options) {
*/ */
const values = {}; const values = {};
const layerGroup = (options.layers instanceof LayerGroup) ? const layerGroup = options.layers && typeof /** @type {?} */ (options.layers).getLayers === 'function' ?
options.layers : new LayerGroup({layers: options.layers}); /** @type {LayerGroup} */ (options.layers) : new LayerGroup({layers: /** @type {Collection} */ (options.layers)});
values[MapProperty.LAYERGROUP] = layerGroup; values[MapProperty.LAYERGROUP] = layerGroup;
values[MapProperty.TARGET] = options.target; values[MapProperty.TARGET] = options.target;
@@ -1373,9 +1380,9 @@ function createOptionsInternal(options) {
if (Array.isArray(options.controls)) { if (Array.isArray(options.controls)) {
controls = new Collection(options.controls.slice()); controls = new Collection(options.controls.slice());
} else { } else {
assert(options.controls instanceof Collection, assert(typeof /** @type {?} */ (options.controls).getArray === 'function',
47); // Expected `controls` to be an array or an `import("./Collection.js").Collection` 47); // Expected `controls` to be an array or an `import("./Collection.js").Collection`
controls = options.controls; controls = /** @type {Collection} */ (options.controls);
} }
} }
@@ -1384,9 +1391,9 @@ function createOptionsInternal(options) {
if (Array.isArray(options.interactions)) { if (Array.isArray(options.interactions)) {
interactions = new Collection(options.interactions.slice()); interactions = new Collection(options.interactions.slice());
} else { } else {
assert(options.interactions instanceof Collection, assert(typeof /** @type {?} */ (options.interactions).getArray === 'function',
48); // Expected `interactions` to be an array or an `import("./Collection.js").Collection` 48); // Expected `interactions` to be an array or an `import("./Collection.js").Collection`
interactions = options.interactions; interactions = /** @type {Collection} */ (options.interactions);
} }
} }
@@ -1395,7 +1402,7 @@ function createOptionsInternal(options) {
if (Array.isArray(options.overlays)) { if (Array.isArray(options.overlays)) {
overlays = new Collection(options.overlays.slice()); overlays = new Collection(options.overlays.slice());
} else { } else {
assert(options.overlays instanceof Collection, assert(typeof /** @type {?} */ (options.overlays).getArray === 'function',
49); // Expected `overlays` to be an array or an `import("./Collection.js").Collection` 49); // Expected `overlays` to be an array or an `import("./Collection.js").Collection`
overlays = options.overlays; overlays = options.overlays;
} }
@@ -1421,12 +1428,14 @@ export default PluggableMap;
function getLoading(layers) { function getLoading(layers) {
for (let i = 0, ii = layers.length; i < ii; ++i) { for (let i = 0, ii = layers.length; i < ii; ++i) {
const layer = layers[i]; const layer = layers[i];
if (layer instanceof LayerGroup) { if (typeof /** @type {?} */ (layer).getLayers === 'function') {
return getLoading(layer.getLayers().getArray()); return getLoading(/** @type {LayerGroup} */ (layer).getLayers().getArray());
} } else {
const source = layers[i].getSource(); const source = /** @type {import("./layer/Layer.js").default} */ (
if (source && source.loading) { layer).getSource();
return true; if (source && source.loading) {
return true;
}
} }
} }
return false; return false;
+5 -5
View File
@@ -122,7 +122,7 @@ class Tile extends EventTarget {
/** /**
* Lookup of start times for rendering transitions. If the start time is * Lookup of start times for rendering transitions. If the start time is
* equal to -1, the transition is complete. * equal to -1, the transition is complete.
* @type {Object<number, number>} * @type {Object<string, number>}
*/ */
this.transitionStarts_ = {}; this.transitionStarts_ = {};
@@ -180,7 +180,7 @@ class Tile extends EventTarget {
} }
let tile = this.interimTile; let tile = this.interimTile;
let prev = this; let prev = /** @type {Tile} */ (this);
do { do {
if (tile.getState() == TileState.LOADED) { if (tile.getState() == TileState.LOADED) {
@@ -244,7 +244,7 @@ class Tile extends EventTarget {
/** /**
* Get the alpha value for rendering. * Get the alpha value for rendering.
* @param {number} id An id for the renderer. * @param {string} id An id for the renderer.
* @param {number} time The render frame time. * @param {number} time The render frame time.
* @return {number} A number between 0 and 1. * @return {number} A number between 0 and 1.
*/ */
@@ -272,7 +272,7 @@ class Tile extends EventTarget {
* Determine if a tile is in an alpha transition. A tile is considered in * Determine if a tile is in an alpha transition. A tile is considered in
* transition if tile.getAlpha() has not yet been called or has been called * transition if tile.getAlpha() has not yet been called or has been called
* and returned 1. * and returned 1.
* @param {number} id An id for the renderer. * @param {string} id An id for the renderer.
* @return {boolean} The tile is in transition. * @return {boolean} The tile is in transition.
*/ */
inTransition(id) { inTransition(id) {
@@ -284,7 +284,7 @@ class Tile extends EventTarget {
/** /**
* Mark a transition as complete. * Mark a transition as complete.
* @param {number} id An id for the renderer. * @param {string} id An id for the renderer.
*/ */
endTransition(id) { endTransition(id) {
if (this.transition_) { if (this.transition_) {
+9 -9
View File
@@ -92,30 +92,30 @@ class TileRange {
} }
/** /**
* @return {number} Height. * @return {number} Height.
*/ */
getHeight() { getHeight() {
return this.maxY - this.minY + 1; return this.maxY - this.minY + 1;
} }
/** /**
* @return {import("./size.js").Size} Size. * @return {import("./size.js").Size} Size.
*/ */
getSize() { getSize() {
return [this.getWidth(), this.getHeight()]; return [this.getWidth(), this.getHeight()];
} }
/** /**
* @return {number} Width. * @return {number} Width.
*/ */
getWidth() { getWidth() {
return this.maxX - this.minX + 1; return this.maxX - this.minX + 1;
} }
/** /**
* @param {TileRange} tileRange Tile range. * @param {TileRange} tileRange Tile range.
* @return {boolean} Intersects. * @return {boolean} Intersects.
*/ */
intersects(tileRange) { intersects(tileRange) {
return this.minX <= tileRange.maxX && return this.minX <= tileRange.maxX &&
this.maxX >= tileRange.minX && this.maxX >= tileRange.minX &&
-1
View File
@@ -12,7 +12,6 @@ export default {
/** /**
* Indicates that tile loading failed * Indicates that tile loading failed
* @type {number} * @type {number}
* @api
*/ */
ERROR: 3, ERROR: 3,
EMPTY: 4, EMPTY: 4,
+4 -5
View File
@@ -25,7 +25,7 @@ class VectorImageTile extends Tile {
/** /**
* @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate. * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("./TileState.js").default} state State. * @param {TileState} state State.
* @param {number} sourceRevision Source revision. * @param {number} sourceRevision Source revision.
* @param {import("./format/Feature.js").default} format Feature format. * @param {import("./format/Feature.js").default} format Feature format.
* @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function. * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.
@@ -36,8 +36,7 @@ class VectorImageTile extends Tile {
* @param {Object<string, import("./VectorTile.js").default>} sourceTiles Source tiles. * @param {Object<string, import("./VectorTile.js").default>} sourceTiles Source tiles.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {import("./proj/Projection.js").default} projection Projection. * @param {import("./proj/Projection.js").default} projection Projection.
* @param {function(new: import("./VectorTile.js").default, import("./tilecoord.js").TileCoord, import("./TileState.js").default, string, * @param {typeof import("./VectorTile.js").default} tileClass Class to
* import("./format/Feature.js").default, import("./Tile.js").LoadFunction)} tileClass Class to
* instantiate for source tiles. * instantiate for source tiles.
* @param {function(this: import("./source/VectorTile.js").default, import("./events/Event.js").default)} handleTileChange * @param {function(this: import("./source/VectorTile.js").default, import("./events/Event.js").default)} handleTileChange
* Function to call when a source tile's state changes. * Function to call when a source tile's state changes.
@@ -192,7 +191,7 @@ class VectorImageTile extends Tile {
* @return {CanvasRenderingContext2D} The rendering context. * @return {CanvasRenderingContext2D} The rendering context.
*/ */
getContext(layer) { getContext(layer) {
const key = getUid(layer).toString(); const key = getUid(layer);
if (!(key in this.context_)) { if (!(key in this.context_)) {
this.context_[key] = createCanvasContext2D(); this.context_[key] = createCanvasContext2D();
} }
@@ -214,7 +213,7 @@ class VectorImageTile extends Tile {
* @return {ReplayState} The replay state. * @return {ReplayState} The replay state.
*/ */
getReplayState(layer) { getReplayState(layer) {
const key = getUid(layer).toString(); const key = getUid(layer);
if (!(key in this.replayState_)) { if (!(key in this.replayState_)) {
this.replayState_[key] = { this.replayState_[key] = {
dirty: false, dirty: false,
+1 -7
View File
@@ -12,12 +12,6 @@ import TileState from './TileState.js';
const DEFAULT_EXTENT = [0, 0, 4096, 4096]; const DEFAULT_EXTENT = [0, 0, 4096, 4096];
/**
* @typedef {function(new: VectorTile, import("./tilecoord.js").TileCoord,
* TileState, string, ?string, import("./Tile.js").LoadFunction)} TileClass
* @api
*/
class VectorTile extends Tile { class VectorTile extends Tile {
/** /**
@@ -120,7 +114,7 @@ class VectorTile extends Tile {
/** /**
* Get the features for this tile. Geometries will be in the projection returned * Get the features for this tile. Geometries will be in the projection returned
* by {@link module:ol/VectorTile~VectorTile#getProjection}. * by {@link module:ol/VectorTile~VectorTile#getProjection}.
* @return {Array<import("./Feature.js").default|import("./render/Feature.js").default>} Features. * @return {Array<import("./Feature.js").FeatureLike>} Features.
* @api * @api
*/ */
getFeatures() { getFeatures() {
+4 -5
View File
@@ -17,7 +17,6 @@ import {inAndOut} from './easing.js';
import {getForViewAndSize, getCenter, getHeight, getWidth, isEmpty} from './extent.js'; import {getForViewAndSize, getCenter, getHeight, getWidth, isEmpty} from './extent.js';
import GeometryType from './geom/GeometryType.js'; import GeometryType from './geom/GeometryType.js';
import {fromExtent as polygonFromExtent} from './geom/Polygon.js'; import {fromExtent as polygonFromExtent} from './geom/Polygon.js';
import SimpleGeometry from './geom/SimpleGeometry.js';
import {clamp, modulo} from './math.js'; import {clamp, modulo} from './math.js';
import {assign} from './obj.js'; import {assign} from './obj.js';
import {createProjection, METERS_PER_UNIT} from './proj.js'; import {createProjection, METERS_PER_UNIT} from './proj.js';
@@ -987,9 +986,9 @@ class View extends BaseObject {
} }
/** @type {import("./geom/SimpleGeometry.js").default} */ /** @type {import("./geom/SimpleGeometry.js").default} */
let geometry; let geometry;
if (!(geometryOrExtent instanceof SimpleGeometry)) { assert(Array.isArray(geometryOrExtent) || typeof /** @type {?} */ (geometryOrExtent).getSimplifiedGeometry === 'function',
assert(Array.isArray(geometryOrExtent), 24); // Invalid extent or geometry provided as `geometry`
24); // Invalid extent or geometry provided as `geometry` if (Array.isArray(geometryOrExtent)) {
assert(!isEmpty(geometryOrExtent), assert(!isEmpty(geometryOrExtent),
25); // Cannot fit empty extent provided as `geometry` 25); // Cannot fit empty extent provided as `geometry`
geometry = polygonFromExtent(geometryOrExtent); geometry = polygonFromExtent(geometryOrExtent);
@@ -1135,7 +1134,7 @@ class View extends BaseObject {
} }
/** /**
* @param {import("./ViewHint.js").default} hint Hint. * @param {ViewHint} hint Hint.
* @param {number} delta Delta. * @param {number} delta Delta.
* @return {number} New value. * @return {number} New value.
*/ */
+2 -4
View File
@@ -133,7 +133,7 @@ export function asArray(color) {
if (Array.isArray(color)) { if (Array.isArray(color)) {
return color; return color;
} else { } else {
return fromString(/** @type {string} */ (color)); return fromString(color);
} }
} }
@@ -185,9 +185,7 @@ function fromStringInternal_(s) {
} else { } else {
assert(false, 14); // Invalid color assert(false, 14); // Invalid color
} }
return ( return color;
/** @type {Color} */ (color)
);
} }
+3 -16
View File
@@ -23,22 +23,9 @@ import {toString} from './color.js';
* @api * @api
*/ */
export function asColorLike(color) { export function asColorLike(color) {
if (isColorLike(color)) { if (Array.isArray(color)) {
return /** @type {string|CanvasPattern|CanvasGradient} */ (color); return toString(color);
} else { } else {
return toString(/** @type {import("./color.js").Color} */ (color)); return color;
} }
} }
/**
* @param {?} color The value that is potentially an {@link ol/colorlike~ColorLike}.
* @return {boolean} The color is an {@link ol/colorlike~ColorLike}.
*/
export function isColorLike(color) {
return (
typeof color === 'string' ||
color instanceof CanvasPattern ||
color instanceof CanvasGradient
);
}
+1
View File
@@ -5,6 +5,7 @@
export {default as Attribution} from './control/Attribution.js'; export {default as Attribution} from './control/Attribution.js';
export {default as Control} from './control/Control.js'; export {default as Control} from './control/Control.js';
export {default as FullScreen} from './control/FullScreen.js'; export {default as FullScreen} from './control/FullScreen.js';
export {default as MousePosition} from './control/MousePosition.js';
export {default as OverviewMap} from './control/OverviewMap.js'; export {default as OverviewMap} from './control/OverviewMap.js';
export {default as Rotate} from './control/Rotate.js'; export {default as Rotate} from './control/Rotate.js';
export {default as ScaleLine} from './control/ScaleLine.js'; export {default as ScaleLine} from './control/ScaleLine.js';
+17 -7
View File
@@ -16,9 +16,9 @@ import {visibleAtResolution} from '../layer/Layer.js';
* @property {HTMLElement|string} [target] Specify a target if you * @property {HTMLElement|string} [target] Specify a target if you
* want the control to be rendered outside of the map's * want the control to be rendered outside of the map's
* viewport. * viewport.
* @property {boolean} [collapsible=true] Specify if attributions can * @property {boolean} [collapsible] Specify if attributions can
* be collapsed. If you use an OSM source, should be set to `false` — see * be collapsed. If not specified, sources control this behavior with their
* {@link https://www.openstreetmap.org/copyright OSM Copyright} — * `attributionsCollapsible` setting.
* @property {boolean} [collapsed=true] Specify if attributions should * @property {boolean} [collapsed=true] Specify if attributions should
* be collapsed at startup. * be collapsed at startup.
* @property {string} [tipLabel='Attributions'] Text label to use for the button tip. * @property {string} [tipLabel='Attributions'] Text label to use for the button tip.
@@ -70,6 +70,12 @@ class Attribution extends Control {
*/ */
this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true; this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;
/**
* @private
* @type {boolean}
*/
this.overrideCollapsible_ = options.collapsible !== undefined;
/** /**
* @private * @private
* @type {boolean} * @type {boolean}
@@ -145,12 +151,12 @@ class Attribution extends Control {
} }
/** /**
* Get a list of visible attributions. * Collect a list of visible attributions and set the collapsible state.
* @param {import("../PluggableMap.js").FrameState} frameState Frame state. * @param {import("../PluggableMap.js").FrameState} frameState Frame state.
* @return {Array<string>} Attributions. * @return {Array<string>} Attributions.
* @private * @private
*/ */
getSourceAttributions_(frameState) { collectSourceAttributions_(frameState) {
/** /**
* Used to determine if an attribution already exists. * Used to determine if an attribution already exists.
* @type {!Object<string, boolean>} * @type {!Object<string, boolean>}
@@ -171,7 +177,7 @@ class Attribution extends Control {
continue; continue;
} }
const source = layerState.layer.getSource(); const source = /** @type {import("../layer/Layer.js").default} */ (layerState.layer).getSource();
if (!source) { if (!source) {
continue; continue;
} }
@@ -186,6 +192,10 @@ class Attribution extends Control {
continue; continue;
} }
if (!this.overrideCollapsible_ && source.getAttributionsCollapsible() === false) {
this.setCollapsible(false);
}
if (Array.isArray(attributions)) { if (Array.isArray(attributions)) {
for (let j = 0, jj = attributions.length; j < jj; ++j) { for (let j = 0, jj = attributions.length; j < jj; ++j) {
if (!(attributions[j] in lookup)) { if (!(attributions[j] in lookup)) {
@@ -216,7 +226,7 @@ class Attribution extends Control {
return; return;
} }
const attributions = this.getSourceAttributions_(frameState); const attributions = this.collectSourceAttributions_(frameState);
const visible = attributions.length > 0; const visible = attributions.length > 0;
if (this.renderedVisible_ != visible) { if (this.renderedVisible_ != visible) {
+34 -16
View File
@@ -34,9 +34,9 @@ const getChangeType = (function() {
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-full-screen'] CSS class name. * @property {string} [className='ol-full-screen'] CSS class name.
* @property {string|HTMLElement} [label='\u2922'] Text label to use for the button. * @property {string|Text} [label='\u2922'] Text label to use for the button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string|HTMLElement} [labelActive='\u00d7'] Text label to use for the * @property {string|Text} [labelActive='\u00d7'] Text label to use for the
* button when full-screen is active. * button when full-screen is active.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip. * @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip.
@@ -87,7 +87,7 @@ class FullScreen extends Control {
/** /**
* @private * @private
* @type {HTMLElement} * @type {Text}
*/ */
this.labelNode_ = typeof label === 'string' ? this.labelNode_ = typeof label === 'string' ?
document.createTextNode(label) : label; document.createTextNode(label) : label;
@@ -96,19 +96,24 @@ class FullScreen extends Control {
/** /**
* @private * @private
* @type {HTMLElement} * @type {Text}
*/ */
this.labelActiveNode_ = typeof labelActive === 'string' ? this.labelActiveNode_ = typeof labelActive === 'string' ?
document.createTextNode(labelActive) : labelActive; document.createTextNode(labelActive) : labelActive;
const tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen'; /**
const button = document.createElement('button'); * @private
button.className = this.cssClassName_ + '-' + isFullScreen(); * @type {HTMLElement}
button.setAttribute('type', 'button'); */
button.title = tipLabel; this.button_ = document.createElement('button');
button.appendChild(this.labelNode_);
listen(button, EventType.CLICK, const tipLabel = options.tipLabel ? options.tipLabel : 'Toggle full-screen';
this.setClassName_(this.button_, isFullScreen());
this.button_.setAttribute('type', 'button');
this.button_.title = tipLabel;
this.button_.appendChild(this.labelNode_);
listen(this.button_, EventType.CLICK,
this.handleClick_, this); this.handleClick_, this);
const cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE + const cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE +
@@ -116,7 +121,7 @@ class FullScreen extends Control {
(!isFullScreenSupported() ? CLASS_UNSUPPORTED : ''); (!isFullScreenSupported() ? CLASS_UNSUPPORTED : '');
const element = this.element; const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(button); element.appendChild(this.button_);
/** /**
* @private * @private
@@ -176,13 +181,12 @@ class FullScreen extends Control {
* @private * @private
*/ */
handleFullScreenChange_() { handleFullScreenChange_() {
const button = this.element.firstElementChild;
const map = this.getMap(); const map = this.getMap();
if (isFullScreen()) { if (isFullScreen()) {
button.className = this.cssClassName_ + '-true'; this.setClassName_(this.button_, true);
replaceNode(this.labelActiveNode_, this.labelNode_); replaceNode(this.labelActiveNode_, this.labelNode_);
} else { } else {
button.className = this.cssClassName_ + '-false'; this.setClassName_(this.button_, false);
replaceNode(this.labelNode_, this.labelActiveNode_); replaceNode(this.labelNode_, this.labelActiveNode_);
} }
if (map) { if (map) {
@@ -190,6 +194,20 @@ class FullScreen extends Control {
} }
} }
/**
* @param {HTMLElement} element Target element
* @param {boolean} fullscreen True if fullscreen class name should be active
* @private
*/
setClassName_(element, fullscreen) {
const activeClassName = this.cssClassName_ + '-true';
const inactiveClassName = this.cssClassName_ + '-false';
const nextClassName = fullscreen ? activeClassName : inactiveClassName;
element.classList.remove(activeClassName);
element.classList.remove(inactiveClassName);
element.classList.add(nextClassName);
}
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
@@ -253,7 +271,7 @@ function requestFullScreenWithKeys(element) {
if (element.mozRequestFullScreenWithKeys) { if (element.mozRequestFullScreenWithKeys) {
element.mozRequestFullScreenWithKeys(); element.mozRequestFullScreenWithKeys();
} else if (element.webkitRequestFullscreen) { } else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); element.webkitRequestFullscreen();
} else { } else {
requestFullScreen(element); requestFullScreen(element);
} }
+2 -2
View File
@@ -23,11 +23,11 @@ const COORDINATE_FORMAT = 'coordinateFormat';
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-mouse-position'] CSS class name. * @property {string} [className='ol-mouse-position'] CSS class name.
* @property {import("../coordinate.js").CoordinateFormat} [coordinateFormat] Coordinate format. * @property {import("../coordinate.js").CoordinateFormat} [coordinateFormat] Coordinate format.
* @property {import("../proj.js").ProjectionLike} projection Projection. * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {function(import("../MapEvent.js").default)} [render] Function called when the * @property {function(import("../MapEvent.js").default)} [render] Function called when the
* control should be re-rendered. This is called in a `requestAnimationFrame` * control should be re-rendered. This is called in a `requestAnimationFrame`
* callback. * callback.
* @property {Element|string} [target] Specify a target if you want the * @property {HTMLElement|string} [target] Specify a target if you want the
* control to be rendered outside of the map's viewport. * control to be rendered outside of the map's viewport.
* @property {string} [undefinedHTML='&#160;'] Markup to show when coordinates are not * @property {string} [undefinedHTML='&#160;'] Markup to show when coordinates are not
* available (e.g. when the pointer leaves the map viewport). By default, the last position * available (e.g. when the pointer leaves the map viewport). By default, the last position
+3 -2
View File
@@ -155,7 +155,7 @@ class OverviewMap extends Control {
const ovmap = this.ovmap_; const ovmap = this.ovmap_;
if (options.layers) { if (options.layers) {
options.layers.forEach( /** @type {Array<import("../layer/Layer.js").default>} */ (options.layers).forEach(
/** /**
* @param {import("../layer/Layer.js").default} layer Layer. * @param {import("../layer/Layer.js").default} layer Layer.
*/ */
@@ -204,7 +204,8 @@ class OverviewMap extends Control {
}; };
const move = function(event) { const move = function(event) {
const coordinates = ovmap.getEventCoordinate(computeDesiredMousePosition(event)); const position = /** @type {?} */ (computeDesiredMousePosition(event));
const coordinates = ovmap.getEventCoordinate(/** @type {Event} */ (position));
overlay.setPosition(coordinates); overlay.setPosition(coordinates);
}; };
+3 -6
View File
@@ -121,22 +121,19 @@ class ScaleLine extends Control {
this, getChangeEventType(UNITS_PROP), this, getChangeEventType(UNITS_PROP),
this.handleUnitsChanged_, this); this.handleUnitsChanged_, this);
this.setUnits(/** @type {Units} */ (options.units) || this.setUnits(/** @type {Units} */ (options.units) || Units.METRIC);
Units.METRIC);
} }
/** /**
* Return the units to use in the scale line. * Return the units to use in the scale line.
* @return {Units|undefined} The units * @return {Units} The units
* to use in the scale line. * to use in the scale line.
* @observable * @observable
* @api * @api
*/ */
getUnits() { getUnits() {
return ( return this.get(UNITS_PROP);
/** @type {Units|undefined} */ (this.get(UNITS_PROP))
);
} }
/** /**
+25 -6
View File
@@ -5,7 +5,7 @@ import ViewHint from '../ViewHint.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
import {easeOut} from '../easing.js'; import {easeOut} from '../easing.js';
import {listen} from '../events.js'; import {listen, unlistenByKey} from '../events.js';
import {stopPropagation} from '../events/Event.js'; import {stopPropagation} from '../events/Event.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import {clamp} from '../math.js'; import {clamp} from '../math.js';
@@ -57,6 +57,12 @@ class ZoomSlider extends Control {
render: options.render || render render: options.render || render
}); });
/**
* @type {!Array.<import("../events.js").EventsKey>}
* @private
*/
this.dragListenerKeys_ = [];
/** /**
* Will hold the current resolution of the view. * Will hold the current resolution of the view.
* *
@@ -133,7 +139,7 @@ class ZoomSlider extends Control {
containerElement.className = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL; containerElement.className = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
containerElement.appendChild(thumbElement); containerElement.appendChild(thumbElement);
/** /**
* @type {import("../pointer/PointerEventHandler.js").default} * @type {PointerEventHandler}
* @private * @private
*/ */
this.dragger_ = new PointerEventHandler(containerElement); this.dragger_ = new PointerEventHandler(containerElement);
@@ -231,20 +237,31 @@ class ZoomSlider extends Control {
this.previousX_ = event.clientX; this.previousX_ = event.clientX;
this.previousY_ = event.clientY; this.previousY_ = event.clientY;
this.dragging_ = true; this.dragging_ = true;
if (this.dragListenerKeys_.length === 0) {
const drag = this.handleDraggerDrag_;
const end = this.handleDraggerEnd_;
this.dragListenerKeys_.push(
listen(document, EventType.MOUSEMOVE, drag, this),
listen(document, PointerEventType.POINTERMOVE, drag, this),
listen(document, EventType.MOUSEUP, end, this),
listen(document, PointerEventType.POINTERUP, end, this)
);
}
} }
} }
/** /**
* Handle dragger drag events. * Handle dragger drag events.
* *
* @param {import("../pointer/PointerEvent.js").default|Event} event The drag event. * @param {import("../pointer/PointerEvent.js").default} event The drag event.
* @private * @private
*/ */
handleDraggerDrag_(event) { handleDraggerDrag_(event) {
if (this.dragging_) { if (this.dragging_) {
const element = /** @type {HTMLElement} */ (this.element.firstElementChild); const element = /** @type {HTMLElement} */ (this.element.firstElementChild);
const deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10); const deltaX = event.clientX - this.previousX_ + parseFloat(element.style.left);
const deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10); const deltaY = event.clientY - this.previousY_ + parseFloat(element.style.top);
const relativePosition = this.getRelativePosition_(deltaX, deltaY); const relativePosition = this.getRelativePosition_(deltaX, deltaY);
this.currentResolution_ = this.getResolutionForPosition_(relativePosition); this.currentResolution_ = this.getResolutionForPosition_(relativePosition);
this.getMap().getView().setResolution(this.currentResolution_); this.getMap().getView().setResolution(this.currentResolution_);
@@ -256,7 +273,7 @@ class ZoomSlider extends Control {
/** /**
* Handle dragger end events. * Handle dragger end events.
* @param {import("../pointer/PointerEvent.js").default|Event} event The drag event. * @param {import("../pointer/PointerEvent.js").default} event The drag event.
* @private * @private
*/ */
handleDraggerEnd_(event) { handleDraggerEnd_(event) {
@@ -273,6 +290,8 @@ class ZoomSlider extends Control {
this.dragging_ = false; this.dragging_ = false;
this.previousX_ = undefined; this.previousX_ = undefined;
this.previousY_ = undefined; this.previousY_ = undefined;
this.dragListenerKeys_.forEach(unlistenByKey);
this.dragListenerKeys_.length = 0;
} }
} }
+1 -1
View File
@@ -34,7 +34,7 @@ import Zoom from './Zoom.js';
* *
* @param {DefaultsOptions=} opt_options * @param {DefaultsOptions=} opt_options
* Defaults options. * Defaults options.
* @return {import("../Collection.js").default<import("./Control.js").default>} * @return {Collection<import("./Control.js").default>}
* Controls. * Controls.
* @function module:ol/control.defaults * @function module:ol/control.defaults
* @api * @api
+29 -15
View File
@@ -22,7 +22,7 @@ import {clear} from './obj.js';
* Listener function. This function is called with an event object as argument. * Listener function. This function is called with an event object as argument.
* When the function returns `false`, event propagation will stop. * When the function returns `false`, event propagation will stop.
* *
* @typedef {function(import("./events/Event.js").default): (void|boolean)} ListenerFunction * @typedef {function((Event|import("./events/Event.js").default)): (void|boolean)} ListenerFunction
* @api * @api
*/ */
@@ -78,27 +78,36 @@ export function findListener(listeners, listener, opt_this, opt_setDeleteIndex)
* @return {Array<EventsKey>|undefined} Listeners. * @return {Array<EventsKey>|undefined} Listeners.
*/ */
export function getListeners(target, type) { export function getListeners(target, type) {
const listenerMap = target.ol_lm; const listenerMap = getListenerMap(target);
return listenerMap ? listenerMap[type] : undefined; return listenerMap ? listenerMap[type] : undefined;
} }
/** /**
* Get the lookup of listeners. If one does not exist on the target, it is * Get the lookup of listeners.
* created. * @param {Object} target Target.
* @param {import("./events/Target.js").EventTargetLike} target Target. * @param {boolean=} opt_create If a map should be created if it doesn't exist.
* @return {!Object<string, Array<EventsKey>>} Map of * @return {!Object<string, Array<EventsKey>>} Map of
* listeners by event type. * listeners by event type.
*/ */
function getListenerMap(target) { function getListenerMap(target, opt_create) {
let listenerMap = target.ol_lm; let listenerMap = target.ol_lm;
if (!listenerMap) { if (!listenerMap && opt_create) {
listenerMap = target.ol_lm = {}; listenerMap = target.ol_lm = {};
} }
return listenerMap; return listenerMap;
} }
/**
* Remove the listener map from a target.
* @param {Object} target Target.
*/
function removeListenerMap(target) {
delete target.ol_lm;
}
/** /**
* Clean up all listener objects of the given type. All properties on the * Clean up all listener objects of the given type. All properties on the
* listener objects will be removed, and if no listeners remain in the listener * listener objects will be removed, and if no listeners remain in the listener
@@ -110,15 +119,16 @@ function removeListeners(target, type) {
const listeners = getListeners(target, type); const listeners = getListeners(target, type);
if (listeners) { if (listeners) {
for (let i = 0, ii = listeners.length; i < ii; ++i) { for (let i = 0, ii = listeners.length; i < ii; ++i) {
target.removeEventListener(type, listeners[i].boundListener); /** @type {import("./events/Target.js").default} */ (target).
removeEventListener(type, listeners[i].boundListener);
clear(listeners[i]); clear(listeners[i]);
} }
listeners.length = 0; listeners.length = 0;
const listenerMap = target.ol_lm; const listenerMap = getListenerMap(target);
if (listenerMap) { if (listenerMap) {
delete listenerMap[type]; delete listenerMap[type];
if (Object.keys(listenerMap).length === 0) { if (Object.keys(listenerMap).length === 0) {
delete target.ol_lm; removeListenerMap(target);
} }
} }
} }
@@ -141,7 +151,7 @@ function removeListeners(target, type) {
* @return {EventsKey} Unique key for the listener. * @return {EventsKey} Unique key for the listener.
*/ */
export function listen(target, type, listener, opt_this, opt_once) { export function listen(target, type, listener, opt_this, opt_once) {
const listenerMap = getListenerMap(target); const listenerMap = getListenerMap(target, true);
let listeners = listenerMap[type]; let listeners = listenerMap[type];
if (!listeners) { if (!listeners) {
listeners = listenerMap[type] = []; listeners = listenerMap[type] = [];
@@ -160,7 +170,8 @@ export function listen(target, type, listener, opt_this, opt_once) {
target: target, target: target,
type: type type: type
}); });
target.addEventListener(type, bindListener(listenerObj)); /** @type {import("./events/Target.js").default} */ (target).
addEventListener(type, bindListener(listenerObj));
listeners.push(listenerObj); listeners.push(listenerObj);
} }
@@ -228,7 +239,8 @@ export function unlisten(target, type, listener, opt_this) {
*/ */
export function unlistenByKey(key) { export function unlistenByKey(key) {
if (key && key.target) { if (key && key.target) {
key.target.removeEventListener(key.type, key.boundListener); /** @type {import("./events/Target.js").default} */ (key.target).
removeEventListener(key.type, key.boundListener);
const listeners = getListeners(key.target, key.type); const listeners = getListeners(key.target, key.type);
if (listeners) { if (listeners) {
const i = 'deleteIndex' in key ? key.deleteIndex : listeners.indexOf(key); const i = 'deleteIndex' in key ? key.deleteIndex : listeners.indexOf(key);
@@ -252,7 +264,9 @@ export function unlistenByKey(key) {
*/ */
export function unlistenAll(target) { export function unlistenAll(target) {
const listenerMap = getListenerMap(target); const listenerMap = getListenerMap(target);
for (const type in listenerMap) { if (listenerMap) {
removeListeners(target, type); for (const type in listenerMap) {
removeListeners(target, type);
}
} }
} }
+2 -1
View File
@@ -72,7 +72,8 @@ class Target extends Disposable {
* Object with a `type` property. * Object with a `type` property.
* *
* @param {{type: string, * @param {{type: string,
* target: (EventTargetLike|undefined)}| * target: (EventTargetLike|undefined),
* propagationStopped: (boolean|undefined)}|
* import("./Event.js").default|string} event Event object. * import("./Event.js").default|string} event Event object.
* @return {boolean|undefined} `false` if anyone called preventDefault on the * @return {boolean|undefined} `false` if anyone called preventDefault on the
* event object or if any of the listeners returned false. * event object or if any of the listeners returned false.
+12 -12
View File
@@ -24,7 +24,7 @@ import {WEBKIT, MAC} from '../has.js';
* @api * @api
*/ */
export const altKeyOnly = function(mapBrowserEvent) { export const altKeyOnly = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);
return ( return (
originalEvent.altKey && originalEvent.altKey &&
!(originalEvent.metaKey || originalEvent.ctrlKey) && !(originalEvent.metaKey || originalEvent.ctrlKey) &&
@@ -41,7 +41,7 @@ export const altKeyOnly = function(mapBrowserEvent) {
* @api * @api
*/ */
export const altShiftKeysOnly = function(mapBrowserEvent) { export const altShiftKeysOnly = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);
return ( return (
originalEvent.altKey && originalEvent.altKey &&
!(originalEvent.metaKey || originalEvent.ctrlKey) && !(originalEvent.metaKey || originalEvent.ctrlKey) &&
@@ -94,7 +94,7 @@ export const click = function(mapBrowserEvent) {
* @return {boolean} The result. * @return {boolean} The result.
*/ */
export const mouseActionButton = function(mapBrowserEvent) { export const mouseActionButton = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {MouseEvent} */ (mapBrowserEvent.originalEvent);
return originalEvent.button == 0 && return originalEvent.button == 0 &&
!(WEBKIT && MAC && originalEvent.ctrlKey); !(WEBKIT && MAC && originalEvent.ctrlKey);
}; };
@@ -156,7 +156,7 @@ export const doubleClick = function(mapBrowserEvent) {
* @api * @api
*/ */
export const noModifierKeys = function(mapBrowserEvent) { export const noModifierKeys = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);
return ( return (
!originalEvent.altKey && !originalEvent.altKey &&
!(originalEvent.metaKey || originalEvent.ctrlKey) && !(originalEvent.metaKey || originalEvent.ctrlKey) &&
@@ -174,7 +174,7 @@ export const noModifierKeys = function(mapBrowserEvent) {
* @api * @api
*/ */
export const platformModifierKeyOnly = function(mapBrowserEvent) { export const platformModifierKeyOnly = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);
return !originalEvent.altKey && return !originalEvent.altKey &&
(MAC ? originalEvent.metaKey : originalEvent.ctrlKey) && (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&
!originalEvent.shiftKey; !originalEvent.shiftKey;
@@ -190,7 +190,7 @@ export const platformModifierKeyOnly = function(mapBrowserEvent) {
* @api * @api
*/ */
export const shiftKeyOnly = function(mapBrowserEvent) { export const shiftKeyOnly = function(mapBrowserEvent) {
const originalEvent = mapBrowserEvent.originalEvent; const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (mapBrowserEvent.originalEvent);
return ( return (
!originalEvent.altKey && !originalEvent.altKey &&
!(originalEvent.metaKey || originalEvent.ctrlKey) && !(originalEvent.metaKey || originalEvent.ctrlKey) &&
@@ -208,7 +208,7 @@ export const shiftKeyOnly = function(mapBrowserEvent) {
*/ */
export const targetNotEditable = function(mapBrowserEvent) { export const targetNotEditable = function(mapBrowserEvent) {
const target = mapBrowserEvent.originalEvent.target; const target = mapBrowserEvent.originalEvent.target;
const tagName = target.tagName; const tagName = /** @type {Element} */ (target).tagName;
return ( return (
tagName !== 'INPUT' && tagName !== 'INPUT' &&
tagName !== 'SELECT' && tagName !== 'SELECT' &&
@@ -224,11 +224,10 @@ export const targetNotEditable = function(mapBrowserEvent) {
* @api * @api
*/ */
export const mouseOnly = function(mapBrowserEvent) { export const mouseOnly = function(mapBrowserEvent) {
assert(mapBrowserEvent.pointerEvent, 56); // mapBrowserEvent must originate from a pointer event const pointerEvent = /** @type {import("../MapBrowserPointerEvent").default} */ (mapBrowserEvent).pointerEvent;
assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event
// see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
return ( return pointerEvent.pointerType == 'mouse';
/** @type {import("../MapBrowserEvent.js").default} */ (mapBrowserEvent).pointerEvent.pointerType == 'mouse'
);
}; };
@@ -242,6 +241,7 @@ export const mouseOnly = function(mapBrowserEvent) {
* @api * @api
*/ */
export const primaryAction = function(mapBrowserEvent) { export const primaryAction = function(mapBrowserEvent) {
const pointerEvent = mapBrowserEvent.pointerEvent; const pointerEvent = /** @type {import("../MapBrowserPointerEvent").default} */ (mapBrowserEvent).pointerEvent;
assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event
return pointerEvent.isPrimary && pointerEvent.button === 0; return pointerEvent.isPrimary && pointerEvent.button === 0;
}; };
+3 -5
View File
@@ -165,7 +165,7 @@ export function containsXY(extent, x, y) {
* Get the relationship between a coordinate and extent. * Get the relationship between a coordinate and extent.
* @param {Extent} extent The extent. * @param {Extent} extent The extent.
* @param {import("./coordinate.js").Coordinate} coordinate The coordinate. * @param {import("./coordinate.js").Coordinate} coordinate The coordinate.
* @return {import("./extent/Relationship.js").default} The relationship (bitwise compare with * @return {Relationship} The relationship (bitwise compare with
* import("./extent/Relationship.js").Relationship). * import("./extent/Relationship.js").Relationship).
*/ */
export function coordinateRelationship(extent, coordinate) { export function coordinateRelationship(extent, coordinate) {
@@ -478,7 +478,7 @@ export function getCenter(extent) {
/** /**
* Get a corner coordinate of an extent. * Get a corner coordinate of an extent.
* @param {Extent} extent Extent. * @param {Extent} extent Extent.
* @param {import("./extent/Corner.js").default} corner Corner. * @param {Corner} corner Corner.
* @return {import("./coordinate.js").Coordinate} Corner coordinate. * @return {import("./coordinate.js").Coordinate} Corner coordinate.
*/ */
export function getCorner(extent, corner) { export function getCorner(extent, corner) {
@@ -494,9 +494,7 @@ export function getCorner(extent, corner) {
} else { } else {
assert(false, 13); // Invalid corner assert(false, 13); // Invalid corner
} }
return ( return coordinate;
/** @type {!import("./coordinate.js").Coordinate} */ (coordinate)
);
} }
+9 -7
View File
@@ -4,7 +4,6 @@
import {VOID} from './functions.js'; import {VOID} from './functions.js';
import FormatType from './format/FormatType.js'; import FormatType from './format/FormatType.js';
/** /**
* {@link module:ol/source/Vector} sources use a function of this type to * {@link module:ol/source/Vector} sources use a function of this type to
* load features. * load features.
@@ -17,7 +16,7 @@ import FormatType from './format/FormatType.js';
* *
* The function is responsible for loading the features and adding them to the * The function is responsible for loading the features and adding them to the
* source. * source.
* @typedef {function(this:import("./source/Vector.js").default, import("./extent.js").Extent, number, * @typedef {function(this:(import("./source/Vector").default|import("./VectorTile.js").default), import("./extent.js").Extent, number,
* import("./proj/Projection.js").default)} FeatureLoader * import("./proj/Projection.js").default)} FeatureLoader
* @api * @api
*/ */
@@ -39,10 +38,10 @@ import FormatType from './format/FormatType.js';
/** /**
* @param {string|FeatureUrlFunction} url Feature URL service. * @param {string|FeatureUrlFunction} url Feature URL service.
* @param {import("./format/Feature.js").default} format Feature format. * @param {import("./format/Feature.js").default} format Feature format.
* @param {function(this:import("./VectorTile.js").default, Array<import("./Feature.js").default>, import("./proj/Projection.js").default, import("./extent.js").Extent)|function(this:import("./source/Vector.js").default, Array<import("./Feature.js").default>)} success * @param {function(this:import("./VectorTile.js").default, Array<import("./Feature.js").default>, import("./proj/Projection.js").default, import("./extent.js").Extent)|function(this:import("./source/Vector").default, Array<import("./Feature.js").default>)} success
* Function called with the loaded features and optionally with the data * Function called with the loaded features and optionally with the data
* projection. Called with the vector tile or source as `this`. * projection. Called with the vector tile or source as `this`.
* @param {function(this:import("./VectorTile.js").default)|function(this:import("./source/Vector.js").default)} failure * @param {function(this:import("./VectorTile.js").default)|function(this:import("./source/Vector").default)} failure
* Function called when loading failed. Called with the vector tile or * Function called when loading failed. Called with the vector tile or
* source as `this`. * source as `this`.
* @return {FeatureLoader} The feature loader. * @return {FeatureLoader} The feature loader.
@@ -53,7 +52,7 @@ export function loadFeaturesXhr(url, format, success, failure) {
* @param {import("./extent.js").Extent} extent Extent. * @param {import("./extent.js").Extent} extent Extent.
* @param {number} resolution Resolution. * @param {number} resolution Resolution.
* @param {import("./proj/Projection.js").default} projection Projection. * @param {import("./proj/Projection.js").default} projection Projection.
* @this {import("./source/Vector.js").default|import("./VectorTile.js").default} * @this {import("./source/Vector").default|import("./VectorTile.js").default}
*/ */
function(extent, resolution, projection) { function(extent, resolution, projection) {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
@@ -121,9 +120,12 @@ export function xhr(url, format) {
* @param {Array<import("./Feature.js").default>} features The loaded features. * @param {Array<import("./Feature.js").default>} features The loaded features.
* @param {import("./proj/Projection.js").default} dataProjection Data * @param {import("./proj/Projection.js").default} dataProjection Data
* projection. * projection.
* @this {import("./source/Vector.js").default} * @this {import("./source/Vector").default|import("./VectorTile.js").default}
*/ */
function(features, dataProjection) { function(features, dataProjection) {
this.addFeatures(features); const sourceOrTile = /** @type {?} */ (this);
if (typeof sourceOrTile.addFeatures === 'function') {
/** @type {import("./source/Vector").default} */ (sourceOrTile).addFeatures(features);
}
}, /* FIXME handle error */ VOID); }, /* FIXME handle error */ VOID);
} }
+64 -40
View File
@@ -17,9 +17,31 @@ import Point from '../geom/Point.js';
import Polygon from '../geom/Polygon.js'; import Polygon from '../geom/Polygon.js';
import {deflateCoordinates} from '../geom/flat/deflate.js'; import {deflateCoordinates} from '../geom/flat/deflate.js';
import {linearRingIsClockwise} from '../geom/flat/orient.js'; import {linearRingIsClockwise} from '../geom/flat/orient.js';
import {assign, isEmpty} from '../obj.js'; import {isEmpty} from '../obj.js';
import {get as getProjection} from '../proj.js'; import {get as getProjection} from '../proj.js';
/**
* @typedef {import("arcgis-rest-api").Feature} EsriJSONFeature
* @typedef {import("arcgis-rest-api").FeatureSet} EsriJSONFeatureSet
* @typedef {import("arcgis-rest-api").Geometry} EsriJSONGeometry
* @typedef {import("arcgis-rest-api").Point} EsriJSONPoint
* @typedef {import("arcgis-rest-api").Polyline} EsriJSONPolyline
* @typedef {import("arcgis-rest-api").Polygon} EsriJSONPolygon
* @typedef {import("arcgis-rest-api").Multipoint} EsriJSONMultipoint
* @typedef {import("arcgis-rest-api").HasZM} EsriJSONHasZM
* @typedef {import("arcgis-rest-api").Position} EsriJSONPosition
* @typedef {import("arcgis-rest-api").SpatialReferenceWkid} EsriJSONSpatialReferenceWkid
*/
/**
* @typedef {Object} EsriJSONMultiPolygon
* @property {Array<Array<Array<Array<number>>>>} rings Rings for the MultiPolygon.
* @property {boolean} [hasM] If the polygon coordinates have an M value.
* @property {boolean} [hasZ] If the polygon coordinates have a Z value.
* @property {EsriJSONSpatialReferenceWkid} [spatialReference] The coordinate reference system.
*/
/** /**
* @const * @const
@@ -104,13 +126,12 @@ class EsriJSON extends JSONFeature {
* @inheritDoc * @inheritDoc
*/ */
readFeaturesFromObject(object, opt_options) { readFeaturesFromObject(object, opt_options) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object);
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
if (esriJSONObject.features) { if (object['features']) {
const esriJSONFeatureCollection = /** @type {EsriJSONFeatureCollection} */ (object); const esriJSONFeatureSet = /** @type {EsriJSONFeatureSet} */ (object);
/** @type {Array<import("../Feature.js").default>} */ /** @type {Array<import("../Feature.js").default>} */
const features = []; const features = [];
const esriJSONFeatures = esriJSONFeatureCollection.features; const esriJSONFeatures = esriJSONFeatureSet.features;
options.idField = object.objectIdFieldName; options.idField = object.objectIdFieldName;
for (let i = 0, ii = esriJSONFeatures.length; i < ii; ++i) { for (let i = 0, ii = esriJSONFeatures.length; i < ii; ++i) {
features.push(this.readFeatureFromObject(esriJSONFeatures[i], options)); features.push(this.readFeatureFromObject(esriJSONFeatures[i], options));
@@ -132,9 +153,9 @@ class EsriJSON extends JSONFeature {
* @inheritDoc * @inheritDoc
*/ */
readProjectionFromObject(object) { readProjectionFromObject(object) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object); if (object['spatialReference'] && object['spatialReference']['wkid'] !== undefined) {
if (esriJSONObject.spatialReference && esriJSONObject.spatialReference.wkid) { const spatialReference = /** @type {EsriJSONSpatialReferenceWkid} */ (object['spatialReference']);
const crs = esriJSONObject.spatialReference.wkid; const crs = spatialReference.wkid;
return getProjection('EPSG:' + crs); return getProjection('EPSG:' + crs);
} else { } else {
return null; return null;
@@ -170,8 +191,8 @@ class EsriJSON extends JSONFeature {
if (geometry) { if (geometry) {
object['geometry'] = writeGeometry(geometry, opt_options); object['geometry'] = writeGeometry(geometry, opt_options);
if (opt_options && opt_options.featureProjection) { if (opt_options && opt_options.featureProjection) {
object['geometry']['spatialReference'] = /** @type {EsriJSONCRS} */({ object['geometry']['spatialReference'] = /** @type {EsriJSONSpatialReferenceWkid} */({
wkid: getProjection(opt_options.featureProjection).getCode().split(':').pop() wkid: Number(getProjection(opt_options.featureProjection).getCode().split(':').pop())
}); });
} }
} }
@@ -200,7 +221,7 @@ class EsriJSON extends JSONFeature {
for (let i = 0, ii = features.length; i < ii; ++i) { for (let i = 0, ii = features.length; i < ii; ++i) {
objects.push(this.writeFeatureObject(features[i], opt_options)); objects.push(this.writeFeatureObject(features[i], opt_options));
} }
return /** @type {EsriJSONFeatureCollection} */ ({ return /** @type {EsriJSONFeatureSet} */ ({
'features': objects 'features': objects
}); });
} }
@@ -218,26 +239,27 @@ function readGeometry(object, opt_options) {
} }
/** @type {import("../geom/GeometryType.js").default} */ /** @type {import("../geom/GeometryType.js").default} */
let type; let type;
if (typeof object.x === 'number' && typeof object.y === 'number') { if (typeof object['x'] === 'number' && typeof object['y'] === 'number') {
type = GeometryType.POINT; type = GeometryType.POINT;
} else if (object.points) { } else if (object['points']) {
type = GeometryType.MULTI_POINT; type = GeometryType.MULTI_POINT;
} else if (object.paths) { } else if (object['paths']) {
if (object.paths.length === 1) { const esriJSONPolyline = /** @type {EsriJSONPolyline} */ (object);
if (esriJSONPolyline.paths.length === 1) {
type = GeometryType.LINE_STRING; type = GeometryType.LINE_STRING;
} else { } else {
type = GeometryType.MULTI_LINE_STRING; type = GeometryType.MULTI_LINE_STRING;
} }
} else if (object.rings) { } else if (object['rings']) {
const layout = getGeometryLayout(object); const esriJSONPolygon = /** @type {EsriJSONPolygon} */ (object);
const rings = convertRings(object.rings, layout); const layout = getGeometryLayout(esriJSONPolygon);
object = /** @type {EsriJSONGeometry} */(assign({}, object)); const rings = convertRings(esriJSONPolygon.rings, layout);
if (rings.length === 1) { if (rings.length === 1) {
type = GeometryType.POLYGON; type = GeometryType.POLYGON;
object.rings = rings[0]; object['rings'] = rings[0];
} else { } else {
type = GeometryType.MULTI_POLYGON; type = GeometryType.MULTI_POLYGON;
object.rings = rings; object['rings'] = rings;
} }
} }
const geometryReader = GEOMETRY_READERS[type]; const geometryReader = GEOMETRY_READERS[type];
@@ -254,7 +276,7 @@ function readGeometry(object, opt_options) {
* Logic inspired by: https://github.com/Esri/terraformer-arcgis-parser * Logic inspired by: https://github.com/Esri/terraformer-arcgis-parser
* @param {Array<!Array<!Array<number>>>} rings Rings. * @param {Array<!Array<!Array<number>>>} rings Rings.
* @param {import("../geom/GeometryLayout.js").default} layout Geometry layout. * @param {import("../geom/GeometryLayout.js").default} layout Geometry layout.
* @return {Array<!Array<!Array<number>>>} Transformed rings. * @return {Array<!Array<!Array<!Array<number>>>>} Transformed rings.
*/ */
function convertRings(rings, layout) { function convertRings(rings, layout) {
const flatRing = []; const flatRing = [];
@@ -301,7 +323,7 @@ function convertRings(rings, layout) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONPoint} object Object.
* @return {import("../geom/Geometry.js").default} Point. * @return {import("../geom/Geometry.js").default} Point.
*/ */
function readPointGeometry(object) { function readPointGeometry(object) {
@@ -323,7 +345,7 @@ function readPointGeometry(object) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONPolyline} object Object.
* @return {import("../geom/Geometry.js").default} LineString. * @return {import("../geom/Geometry.js").default} LineString.
*/ */
function readLineStringGeometry(object) { function readLineStringGeometry(object) {
@@ -333,7 +355,7 @@ function readLineStringGeometry(object) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONPolyline} object Object.
* @return {import("../geom/Geometry.js").default} MultiLineString. * @return {import("../geom/Geometry.js").default} MultiLineString.
*/ */
function readMultiLineStringGeometry(object) { function readMultiLineStringGeometry(object) {
@@ -343,7 +365,7 @@ function readMultiLineStringGeometry(object) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONHasZM} object Object.
* @return {import("../geom/GeometryLayout.js").default} The geometry layout to use. * @return {import("../geom/GeometryLayout.js").default} The geometry layout to use.
*/ */
function getGeometryLayout(object) { function getGeometryLayout(object) {
@@ -360,7 +382,7 @@ function getGeometryLayout(object) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONMultipoint} object Object.
* @return {import("../geom/Geometry.js").default} MultiPoint. * @return {import("../geom/Geometry.js").default} MultiPoint.
*/ */
function readMultiPointGeometry(object) { function readMultiPointGeometry(object) {
@@ -370,19 +392,17 @@ function readMultiPointGeometry(object) {
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONMultiPolygon} object Object.
* @return {import("../geom/Geometry.js").default} MultiPolygon. * @return {import("../geom/Geometry.js").default} MultiPolygon.
*/ */
function readMultiPolygonGeometry(object) { function readMultiPolygonGeometry(object) {
const layout = getGeometryLayout(object); const layout = getGeometryLayout(object);
return new MultiPolygon( return new MultiPolygon(object.rings, layout);
/** @type {Array<Array<Array<Array<number>>>>} */(object.rings),
layout);
} }
/** /**
* @param {EsriJSONGeometry} object Object. * @param {EsriJSONPolygon} object Object.
* @return {import("../geom/Geometry.js").default} Polygon. * @return {import("../geom/Geometry.js").default} Polygon.
*/ */
function readPolygonGeometry(object) { function readPolygonGeometry(object) {
@@ -452,13 +472,14 @@ function getHasZM(geometry) {
* @return {EsriJSONPolyline} EsriJSON geometry. * @return {EsriJSONPolyline} EsriJSON geometry.
*/ */
function writeLineStringGeometry(geometry, opt_options) { function writeLineStringGeometry(geometry, opt_options) {
const hasZM = getHasZM(/** @type {import("../geom/LineString.js").default} */(geometry)); const lineString = /** @type {import("../geom/LineString.js").default} */ (geometry);
const hasZM = getHasZM(lineString);
return ( return (
/** @type {EsriJSONPolyline} */ { /** @type {EsriJSONPolyline} */ {
hasZ: hasZM.hasZ, hasZ: hasZM.hasZ,
hasM: hasZM.hasM, hasM: hasZM.hasM,
paths: [ paths: [
/** @type {import("../geom/LineString.js").default} */ (geometry).getCoordinates() /** @type {Array<EsriJSONPosition>} */ (lineString.getCoordinates())
] ]
} }
); );
@@ -471,13 +492,14 @@ function writeLineStringGeometry(geometry, opt_options) {
* @return {EsriJSONPolygon} EsriJSON geometry. * @return {EsriJSONPolygon} EsriJSON geometry.
*/ */
function writePolygonGeometry(geometry, opt_options) { function writePolygonGeometry(geometry, opt_options) {
const polygon = /** @type {import("../geom/Polygon.js").default} */ (geometry);
// Esri geometries use the left-hand rule // Esri geometries use the left-hand rule
const hasZM = getHasZM(/** @type {import("../geom/Polygon.js").default} */(geometry)); const hasZM = getHasZM(polygon);
return ( return (
/** @type {EsriJSONPolygon} */ { /** @type {EsriJSONPolygon} */ {
hasZ: hasZM.hasZ, hasZ: hasZM.hasZ,
hasM: hasZM.hasM, hasM: hasZM.hasM,
rings: /** @type {import("../geom/Polygon.js").default} */ (geometry).getCoordinates(false) rings: /** @type {Array<Array<EsriJSONPosition>>} */ (polygon.getCoordinates(false))
} }
); );
} }
@@ -489,12 +511,13 @@ function writePolygonGeometry(geometry, opt_options) {
* @return {EsriJSONPolyline} EsriJSON geometry. * @return {EsriJSONPolyline} EsriJSON geometry.
*/ */
function writeMultiLineStringGeometry(geometry, opt_options) { function writeMultiLineStringGeometry(geometry, opt_options) {
const hasZM = getHasZM(/** @type {import("../geom/MultiLineString.js").default} */(geometry)); const multiLineString = /** @type {import("../geom/MultiLineString.js").default} */ (geometry);
const hasZM = getHasZM(multiLineString);
return ( return (
/** @type {EsriJSONPolyline} */ { /** @type {EsriJSONPolyline} */ {
hasZ: hasZM.hasZ, hasZ: hasZM.hasZ,
hasM: hasZM.hasM, hasM: hasZM.hasM,
paths: /** @type {import("../geom/MultiLineString.js").default} */ (geometry).getCoordinates() paths: /** @type {Array<Array<EsriJSONPosition>>} */ (multiLineString.getCoordinates())
} }
); );
} }
@@ -506,12 +529,13 @@ function writeMultiLineStringGeometry(geometry, opt_options) {
* @return {EsriJSONMultipoint} EsriJSON geometry. * @return {EsriJSONMultipoint} EsriJSON geometry.
*/ */
function writeMultiPointGeometry(geometry, opt_options) { function writeMultiPointGeometry(geometry, opt_options) {
const hasZM = getHasZM(/** @type {import("../geom/MultiPoint.js").default} */(geometry)); const multiPoint = /** @type {import("../geom/MultiPoint.js").default} */ (geometry);
const hasZM = getHasZM(multiPoint);
return ( return (
/** @type {EsriJSONMultipoint} */ { /** @type {EsriJSONMultipoint} */ {
hasZ: hasZM.hasZ, hasZ: hasZM.hasZ,
hasM: hasZM.hasM, hasM: hasZM.hasM,
points: /** @type {import("../geom/MultiPoint.js").default} */ (geometry).getCoordinates() points: /** @type {Array<EsriJSONPosition>} */ (multiPoint.getCoordinates())
} }
); );
} }
+41 -24
View File
@@ -1,8 +1,8 @@
/** /**
* @module ol/format/Feature * @module ol/format/Feature
*/ */
import Geometry from '../geom/Geometry.js';
import {assign} from '../obj.js'; import {assign} from '../obj.js';
import {abstract} from '../util.js';
import {get as getProjection, equivalent as equivalentProjection, transformExtent} from '../proj.js'; import {get as getProjection, equivalent as equivalentProjection, transformExtent} from '../proj.js';
@@ -123,7 +123,9 @@ class FeatureFormat {
* @abstract * @abstract
* @return {import("./FormatType.js").default} Format. * @return {import("./FormatType.js").default} Format.
*/ */
getType() {} getType() {
return abstract();
}
/** /**
* Read a single feature from a source. * Read a single feature from a source.
@@ -131,9 +133,11 @@ class FeatureFormat {
* @abstract * @abstract
* @param {Document|Node|Object|string} source Source. * @param {Document|Node|Object|string} source Source.
* @param {ReadOptions=} opt_options Read options. * @param {ReadOptions=} opt_options Read options.
* @return {import("../Feature.js").default} Feature. * @return {import("../Feature.js").FeatureLike} Feature.
*/ */
readFeature(source, opt_options) {} readFeature(source, opt_options) {
return abstract();
}
/** /**
* Read all features from a source. * Read all features from a source.
@@ -141,9 +145,11 @@ class FeatureFormat {
* @abstract * @abstract
* @param {Document|Node|ArrayBuffer|Object|string} source Source. * @param {Document|Node|ArrayBuffer|Object|string} source Source.
* @param {ReadOptions=} opt_options Read options. * @param {ReadOptions=} opt_options Read options.
* @return {Array<import("../Feature.js").default>} Features. * @return {Array<import("../Feature.js").FeatureLike>} Features.
*/ */
readFeatures(source, opt_options) {} readFeatures(source, opt_options) {
return abstract();
}
/** /**
* Read a single geometry from a source. * Read a single geometry from a source.
@@ -151,9 +157,11 @@ class FeatureFormat {
* @abstract * @abstract
* @param {Document|Node|Object|string} source Source. * @param {Document|Node|Object|string} source Source.
* @param {ReadOptions=} opt_options Read options. * @param {ReadOptions=} opt_options Read options.
* @return {Geometry} Geometry. * @return {import("../geom/Geometry.js").default} Geometry.
*/ */
readGeometry(source, opt_options) {} readGeometry(source, opt_options) {
return abstract();
}
/** /**
* Read the projection from a source. * Read the projection from a source.
@@ -162,7 +170,9 @@ class FeatureFormat {
* @param {Document|Node|Object|string} source Source. * @param {Document|Node|Object|string} source Source.
* @return {import("../proj/Projection.js").default} Projection. * @return {import("../proj/Projection.js").default} Projection.
*/ */
readProjection(source) {} readProjection(source) {
return abstract();
}
/** /**
* Encode a feature in this format. * Encode a feature in this format.
@@ -172,7 +182,9 @@ class FeatureFormat {
* @param {WriteOptions=} opt_options Write options. * @param {WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
writeFeature(feature, opt_options) {} writeFeature(feature, opt_options) {
return abstract();
}
/** /**
* Encode an array of features in this format. * Encode an array of features in this format.
@@ -182,26 +194,30 @@ class FeatureFormat {
* @param {WriteOptions=} opt_options Write options. * @param {WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
writeFeatures(features, opt_options) {} writeFeatures(features, opt_options) {
return abstract();
}
/** /**
* Write a single geometry in this format. * Write a single geometry in this format.
* *
* @abstract * @abstract
* @param {Geometry} geometry Geometry. * @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {WriteOptions=} opt_options Write options. * @param {WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
writeGeometry(geometry, opt_options) {} writeGeometry(geometry, opt_options) {
return abstract();
}
} }
export default FeatureFormat; export default FeatureFormat;
/** /**
* @param {Geometry|import("../extent.js").Extent} geometry Geometry. * @param {import("../geom/Geometry.js").default|import("../extent.js").Extent} geometry Geometry.
* @param {boolean} write Set to true for writing, false for reading. * @param {boolean} write Set to true for writing, false for reading.
* @param {(WriteOptions|ReadOptions)=} opt_options Options. * @param {(WriteOptions|ReadOptions)=} opt_options Options.
* @return {Geometry|import("../extent.js").Extent} Transformed geometry. * @return {import("../geom/Geometry.js").default|import("../extent.js").Extent} Transformed geometry.
*/ */
export function transformWithOptions(geometry, write, opt_options) { export function transformWithOptions(geometry, write, opt_options) {
const featureProjection = opt_options ? const featureProjection = opt_options ?
@@ -209,28 +225,29 @@ export function transformWithOptions(geometry, write, opt_options) {
const dataProjection = opt_options ? const dataProjection = opt_options ?
getProjection(opt_options.dataProjection) : null; getProjection(opt_options.dataProjection) : null;
/** /**
* @type {Geometry|import("../extent.js").Extent} * @type {import("../geom/Geometry.js").default|import("../extent.js").Extent}
*/ */
let transformed; let transformed;
if (featureProjection && dataProjection && if (featureProjection && dataProjection &&
!equivalentProjection(featureProjection, dataProjection)) { !equivalentProjection(featureProjection, dataProjection)) {
if (geometry instanceof Geometry) { if (Array.isArray(geometry)) {
transformed = (write ? geometry.clone() : geometry).transform(
write ? featureProjection : dataProjection,
write ? dataProjection : featureProjection);
} else {
// FIXME this is necessary because GML treats extents // FIXME this is necessary because GML treats extents
// as geometries // as geometries
transformed = transformExtent( transformed = transformExtent(
geometry, geometry,
dataProjection, dataProjection,
featureProjection); featureProjection);
} else {
transformed = (write ? /** @type {import("../geom/Geometry").default} */ (geometry).clone() : geometry).transform(
write ? featureProjection : dataProjection,
write ? dataProjection : featureProjection);
} }
} else { } else {
transformed = geometry; transformed = geometry;
} }
if (write && opt_options && opt_options.decimals !== undefined) { if (write && opt_options && /** @type {WriteOptions} */ (opt_options).decimals !== undefined &&
const power = Math.pow(10, opt_options.decimals); !Array.isArray(transformed)) {
const power = Math.pow(10, /** @type {WriteOptions} */ (opt_options).decimals);
// if decimals option on write, round each coordinate appropriately // if decimals option on write, round each coordinate appropriately
/** /**
* @param {Array<number>} coordinates Coordinates. * @param {Array<number>} coordinates Coordinates.
@@ -243,7 +260,7 @@ export function transformWithOptions(geometry, write, opt_options) {
return coordinates; return coordinates;
}; };
if (transformed === geometry) { if (transformed === geometry) {
transformed = transformed.clone(); transformed = /** @type {import("../geom/Geometry").default} */ (geometry).clone();
} }
transformed.applyTransform(transform); transformed.applyTransform(transform);
} }
+9 -10
View File
@@ -5,7 +5,6 @@ import {createOrUpdate} from '../extent.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import GMLBase, {GMLNS} from '../format/GMLBase.js'; import GMLBase, {GMLNS} from '../format/GMLBase.js';
import {writeStringTextNode} from '../format/xsd.js'; import {writeStringTextNode} from '../format/xsd.js';
import Geometry from '../geom/Geometry.js';
import {assign} from '../obj.js'; import {assign} from '../obj.js';
import {get as getProjection, transformExtent} from '../proj.js'; import {get as getProjection, transformExtent} from '../proj.js';
import {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender, import {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender,
@@ -179,7 +178,7 @@ class GML2 extends GMLBase {
writeFeatureElement(node, feature, objectStack) { writeFeatureElement(node, feature, objectStack) {
const fid = feature.getId(); const fid = feature.getId();
if (fid) { if (fid) {
node.setAttribute('fid', fid); node.setAttribute('fid', /** @type {string} */ (fid));
} }
const context = /** @type {Object} */ (objectStack[objectStack.length - 1]); const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const featureNS = context['featureNS']; const featureNS = context['featureNS'];
@@ -196,7 +195,7 @@ class GML2 extends GMLBase {
if (value !== null) { if (value !== null) {
keys.push(key); keys.push(key);
values.push(value); values.push(value);
if (key == geometryName || value instanceof Geometry) { if (key == geometryName || typeof /** @type {?} */ (value).getSimplifiedGeometry === 'function') {
if (!(key in context.serializers[featureNS])) { if (!(key in context.serializers[featureNS])) {
context.serializers[featureNS][key] = makeChildAppender( context.serializers[featureNS][key] = makeChildAppender(
this.writeGeometryElement, this); this.writeGeometryElement, this);
@@ -285,7 +284,7 @@ class GML2 extends GMLBase {
writeGeometryElement(node, geometry, objectStack) { writeGeometryElement(node, geometry, objectStack) {
const context = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[objectStack.length - 1]); const context = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[objectStack.length - 1]);
const item = assign({}, context); const item = assign({}, context);
item.node = node; item['node'] = node;
let value; let value;
if (Array.isArray(geometry)) { if (Array.isArray(geometry)) {
if (context.dataProjection) { if (context.dataProjection) {
@@ -588,9 +587,9 @@ class GML2 extends GMLBase {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = { GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'coordinates': makeReplacer(GML2.prototype.readFlatCoordinates_) 'coordinates': makeReplacer(GML2.prototype.readFlatCoordinates_)
} }
@@ -599,9 +598,9 @@ GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = { GML2.prototype.FLAT_LINEAR_RINGS_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'innerBoundaryIs': GML2.prototype.innerBoundaryIsParser_, 'innerBoundaryIs': GML2.prototype.innerBoundaryIsParser_,
'outerBoundaryIs': GML2.prototype.outerBoundaryIsParser_ 'outerBoundaryIs': GML2.prototype.outerBoundaryIsParser_
@@ -623,9 +622,9 @@ GML2.prototype.BOX_PARSERS_ = {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML2.prototype.GEOMETRY_PARSERS_ = { GML2.prototype.GEOMETRY_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'Point': makeReplacer(GMLBase.prototype.readPoint), 'Point': makeReplacer(GMLBase.prototype.readPoint),
'MultiPoint': makeReplacer( 'MultiPoint': makeReplacer(
+20 -20
View File
@@ -6,7 +6,6 @@ import {createOrUpdate} from '../extent.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import GMLBase, {GMLNS} from '../format/GMLBase.js'; import GMLBase, {GMLNS} from '../format/GMLBase.js';
import {readNonNegativeIntegerString, writeStringTextNode} from '../format/xsd.js'; import {readNonNegativeIntegerString, writeStringTextNode} from '../format/xsd.js';
import Geometry from '../geom/Geometry.js';
import GeometryLayout from '../geom/GeometryLayout.js'; import GeometryLayout from '../geom/GeometryLayout.js';
import LineString from '../geom/LineString.js'; import LineString from '../geom/LineString.js';
import MultiLineString from '../geom/MultiLineString.js'; import MultiLineString from '../geom/MultiLineString.js';
@@ -183,7 +182,7 @@ class GML3 extends GMLBase {
*/ */
readPolygonPatch_(node, objectStack) { readPolygonPatch_(node, objectStack) {
return pushParseAndPop([null], return pushParseAndPop([null],
this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); this.FLAT_LINEAR_RINGS_PARSERS, node, objectStack, this);
} }
/** /**
@@ -194,7 +193,7 @@ class GML3 extends GMLBase {
*/ */
readLineStringSegment_(node, objectStack) { readLineStringSegment_(node, objectStack) {
return pushParseAndPop([null], return pushParseAndPop([null],
this.GEOMETRY_FLAT_COORDINATES_PARSERS_, this.GEOMETRY_FLAT_COORDINATES_PARSERS,
node, objectStack, this); node, objectStack, this);
} }
@@ -357,9 +356,9 @@ class GML3 extends GMLBase {
} else if (node.getAttribute('dimension')) { } else if (node.getAttribute('dimension')) {
dim = readNonNegativeIntegerString( dim = readNonNegativeIntegerString(
node.getAttribute('dimension')); node.getAttribute('dimension'));
} else if (node.parentNode.getAttribute('srsDimension')) { } else if (/** @type {Element} */ (node.parentNode).getAttribute('srsDimension')) {
dim = readNonNegativeIntegerString( dim = readNonNegativeIntegerString(
node.parentNode.getAttribute('srsDimension')); /** @type {Element} */ (node.parentNode).getAttribute('srsDimension'));
} else if (contextDimension) { } else if (contextDimension) {
dim = readNonNegativeIntegerString(contextDimension); dim = readNonNegativeIntegerString(contextDimension);
} }
@@ -387,7 +386,7 @@ class GML3 extends GMLBase {
writePos_(node, value, objectStack) { writePos_(node, value, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsDimension = hasZ ? 3 : 2; const srsDimension = hasZ ? '3' : '2';
node.setAttribute('srsDimension', srsDimension); node.setAttribute('srsDimension', srsDimension);
const srsName = context['srsName']; const srsName = context['srsName'];
let axisOrientation = 'enu'; let axisOrientation = 'enu';
@@ -443,7 +442,7 @@ class GML3 extends GMLBase {
writePosList_(node, value, objectStack) { writePosList_(node, value, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsDimension = hasZ ? 3 : 2; const srsDimension = hasZ ? '3' : '2';
node.setAttribute('srsDimension', srsDimension); node.setAttribute('srsDimension', srsDimension);
const srsName = context['srsName']; const srsName = context['srsName'];
// only 2d for simple features profile // only 2d for simple features profile
@@ -731,7 +730,7 @@ class GML3 extends GMLBase {
writeGeometryElement(node, geometry, objectStack) { writeGeometryElement(node, geometry, objectStack) {
const context = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[objectStack.length - 1]); const context = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[objectStack.length - 1]);
const item = assign({}, context); const item = assign({}, context);
item.node = node; item['node'] = node;
let value; let value;
if (Array.isArray(geometry)) { if (Array.isArray(geometry)) {
if (context.dataProjection) { if (context.dataProjection) {
@@ -757,7 +756,7 @@ class GML3 extends GMLBase {
writeFeatureElement(node, feature, objectStack) { writeFeatureElement(node, feature, objectStack) {
const fid = feature.getId(); const fid = feature.getId();
if (fid) { if (fid) {
node.setAttribute('fid', fid); node.setAttribute('fid', /** @type {string} */ (fid));
} }
const context = /** @type {Object} */ (objectStack[objectStack.length - 1]); const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const featureNS = context['featureNS']; const featureNS = context['featureNS'];
@@ -774,7 +773,7 @@ class GML3 extends GMLBase {
if (value !== null) { if (value !== null) {
keys.push(key); keys.push(key);
values.push(value); values.push(value);
if (key == geometryName || value instanceof Geometry) { if (key == geometryName || typeof /** @type {?} */ (value).getSimplifiedGeometry === 'function') {
if (!(key in context.serializers[featureNS])) { if (!(key in context.serializers[featureNS])) {
context.serializers[featureNS][key] = makeChildAppender( context.serializers[featureNS][key] = makeChildAppender(
this.writeGeometryElement, this); this.writeGeometryElement, this);
@@ -805,6 +804,7 @@ class GML3 extends GMLBase {
const context = /** @type {Object} */ (objectStack[objectStack.length - 1]); const context = /** @type {Object} */ (objectStack[objectStack.length - 1]);
const featureType = context['featureType']; const featureType = context['featureType'];
const featureNS = context['featureNS']; const featureNS = context['featureNS'];
/** @type {Object<string, Object<string, import("../xml.js").Serializer>>} */
const serializers = {}; const serializers = {};
serializers[featureNS] = {}; serializers[featureNS] = {};
serializers[featureNS][featureType] = makeChildAppender( serializers[featureNS][featureType] = makeChildAppender(
@@ -828,7 +828,7 @@ class GML3 extends GMLBase {
*/ */
MULTIGEOMETRY_MEMBER_NODE_FACTORY_(value, objectStack, opt_nodeName) { MULTIGEOMETRY_MEMBER_NODE_FACTORY_(value, objectStack, opt_nodeName) {
const parentNode = objectStack[objectStack.length - 1].node; const parentNode = objectStack[objectStack.length - 1].node;
return createElementNS('http://www.opengis.net/gml', return createElementNS(this.namespace,
MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]); MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]);
} }
@@ -861,7 +861,7 @@ class GML3 extends GMLBase {
} else { } else {
nodeName = 'Envelope'; nodeName = 'Envelope';
} }
return createElementNS('http://www.opengis.net/gml', return createElementNS(this.namespace,
nodeName); nodeName);
} }
@@ -876,7 +876,7 @@ class GML3 extends GMLBase {
*/ */
writeGeometryNode(geometry, opt_options) { writeGeometryNode(geometry, opt_options) {
opt_options = this.adaptOptions(opt_options); opt_options = this.adaptOptions(opt_options);
const geom = createElementNS('http://www.opengis.net/gml', 'geom'); const geom = createElementNS(this.namespace, 'geom');
const context = {node: geom, hasZ: this.hasZ, srsName: this.srsName, const context = {node: geom, hasZ: this.hasZ, srsName: this.srsName,
curve: this.curve_, surface: this.surface_, curve: this.curve_, surface: this.surface_,
multiSurface: this.multiSurface_, multiCurve: this.multiCurve_}; multiSurface: this.multiSurface_, multiCurve: this.multiCurve_};
@@ -898,7 +898,7 @@ class GML3 extends GMLBase {
*/ */
writeFeaturesNode(features, opt_options) { writeFeaturesNode(features, opt_options) {
opt_options = this.adaptOptions(opt_options); opt_options = this.adaptOptions(opt_options);
const node = createElementNS('http://www.opengis.net/gml', 'featureMembers'); const node = createElementNS(this.namespace, 'featureMembers');
node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation); node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation);
const context = { const context = {
srsName: this.srsName, srsName: this.srsName,
@@ -921,9 +921,9 @@ class GML3 extends GMLBase {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = { GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'pos': makeReplacer(GML3.prototype.readFlatPos_), 'pos': makeReplacer(GML3.prototype.readFlatPos_),
'posList': makeReplacer(GML3.prototype.readFlatPosList_) 'posList': makeReplacer(GML3.prototype.readFlatPosList_)
@@ -934,9 +934,9 @@ GML3.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = { GML3.prototype.FLAT_LINEAR_RINGS_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'interior': GML3.prototype.interiorParser_, 'interior': GML3.prototype.interiorParser_,
'exterior': GML3.prototype.exteriorParser_ 'exterior': GML3.prototype.exteriorParser_
@@ -947,9 +947,9 @@ GML3.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private * @protected
*/ */
GML3.prototype.GEOMETRY_PARSERS_ = { GML3.prototype.GEOMETRY_PARSERS = {
'http://www.opengis.net/gml': { 'http://www.opengis.net/gml': {
'Point': makeReplacer(GMLBase.prototype.readPoint), 'Point': makeReplacer(GMLBase.prototype.readPoint),
'MultiPoint': makeReplacer( 'MultiPoint': makeReplacer(
+386
View File
@@ -0,0 +1,386 @@
/**
* @module ol/format/GML32
*/
import GML3 from './GML3.js';
import GMLBase from './GMLBase.js';
import {makeArrayPusher, makeReplacer, makeChildAppender} from '../xml.js';
import {writeStringTextNode} from '../format/xsd.js';
/**
* @classdesc Feature format for reading and writing data in the GML format
* version 3.2.1.
* @api
*/
class GML32 extends GML3 {
/**
* @param {import("./GMLBase.js").Options=} opt_options Optional configuration object.
*/
constructor(opt_options) {
const options = /** @type {import("./GMLBase.js").Options} */ (opt_options ? opt_options : {});
super(options);
/**
* @inheritDoc
*/
this.schemaLocation = options.schemaLocation ?
options.schemaLocation : this.namespace + ' http://schemas.opengis.net/gml/3.2.1/gml.xsd';
}
}
GML32.prototype.namespace = 'http://www.opengis.net/gml/3.2';
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GML32.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS = {
'http://www.opengis.net/gml/3.2': {
'pos': makeReplacer(GML3.prototype.readFlatPos_),
'posList': makeReplacer(GML3.prototype.readFlatPosList_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GML32.prototype.FLAT_LINEAR_RINGS_PARSERS = {
'http://www.opengis.net/gml/3.2': {
'interior': GML3.prototype.interiorParser_,
'exterior': GML3.prototype.exteriorParser_
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GML32.prototype.GEOMETRY_PARSERS = {
'http://www.opengis.net/gml/3.2': {
'Point': makeReplacer(GMLBase.prototype.readPoint),
'MultiPoint': makeReplacer(
GMLBase.prototype.readMultiPoint),
'LineString': makeReplacer(
GMLBase.prototype.readLineString),
'MultiLineString': makeReplacer(
GMLBase.prototype.readMultiLineString),
'LinearRing': makeReplacer(
GMLBase.prototype.readLinearRing),
'Polygon': makeReplacer(GMLBase.prototype.readPolygon),
'MultiPolygon': makeReplacer(
GMLBase.prototype.readMultiPolygon),
'Surface': makeReplacer(GML32.prototype.readSurface_),
'MultiSurface': makeReplacer(
GML3.prototype.readMultiSurface_),
'Curve': makeReplacer(GML32.prototype.readCurve_),
'MultiCurve': makeReplacer(
GML3.prototype.readMultiCurve_),
'Envelope': makeReplacer(GML32.prototype.readEnvelope_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.MULTICURVE_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'curveMember': makeArrayPusher(
GML3.prototype.curveMemberParser_),
'curveMembers': makeArrayPusher(
GML3.prototype.curveMemberParser_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.MULTISURFACE_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'surfaceMember': makeArrayPusher(
GML3.prototype.surfaceMemberParser_),
'surfaceMembers': makeArrayPusher(
GML3.prototype.surfaceMemberParser_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.CURVEMEMBER_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'LineString': makeArrayPusher(
GMLBase.prototype.readLineString),
'Curve': makeArrayPusher(GML3.prototype.readCurve_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.SURFACEMEMBER_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'Polygon': makeArrayPusher(GMLBase.prototype.readPolygon),
'Surface': makeArrayPusher(GML3.prototype.readSurface_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.SURFACE_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'patches': makeReplacer(GML3.prototype.readPatch_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.CURVE_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'segments': makeReplacer(GML3.prototype.readSegment_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.ENVELOPE_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'lowerCorner': makeArrayPusher(
GML3.prototype.readFlatPosList_),
'upperCorner': makeArrayPusher(
GML3.prototype.readFlatPosList_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.PATCHES_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'PolygonPatch': makeReplacer(
GML3.prototype.readPolygonPatch_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.SEGMENTS_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'LineStringSegment': makeReplacer(
GML3.prototype.readLineStringSegment_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.MULTIPOINT_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'pointMember': makeArrayPusher(
GMLBase.prototype.pointMemberParser_),
'pointMembers': makeArrayPusher(
GMLBase.prototype.pointMemberParser_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.MULTILINESTRING_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'lineStringMember': makeArrayPusher(
GMLBase.prototype.lineStringMemberParser_),
'lineStringMembers': makeArrayPusher(
GMLBase.prototype.lineStringMemberParser_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.MULTIPOLYGON_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'polygonMember': makeArrayPusher(
GMLBase.prototype.polygonMemberParser_),
'polygonMembers': makeArrayPusher(
GMLBase.prototype.polygonMemberParser_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.POINTMEMBER_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'Point': makeArrayPusher(
GMLBase.prototype.readFlatCoordinatesFromNode_)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.LINESTRINGMEMBER_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'LineString': makeArrayPusher(
GMLBase.prototype.readLineString)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @private
*/
GML32.prototype.POLYGONMEMBER_PARSERS_ = {
'http://www.opengis.net/gml/3.2': {
'Polygon': makeArrayPusher(
GMLBase.prototype.readPolygon)
}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GML32.prototype.RING_PARSERS = {
'http://www.opengis.net/gml/3.2': {
'LinearRing': makeReplacer(
GMLBase.prototype.readFlatLinearRing_)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.RING_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'exterior': makeChildAppender(GML3.prototype.writeRing_),
'interior': makeChildAppender(GML3.prototype.writeRing_)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.ENVELOPE_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'lowerCorner': makeChildAppender(writeStringTextNode),
'upperCorner': makeChildAppender(writeStringTextNode)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'surfaceMember': makeChildAppender(
GML3.prototype.writeSurfaceOrPolygonMember_),
'polygonMember': makeChildAppender(
GML3.prototype.writeSurfaceOrPolygonMember_)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.POINTMEMBER_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'pointMember': makeChildAppender(
GML3.prototype.writePointMember_)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'lineStringMember': makeChildAppender(
GML3.prototype.writeLineStringOrCurveMember_),
'curveMember': makeChildAppender(
GML3.prototype.writeLineStringOrCurveMember_)
}
};
/**
* @type {Object<string, Object<string, import("../xml.js").Serializer>>}
* @private
*/
GML32.prototype.GEOMETRY_SERIALIZERS_ = {
'http://www.opengis.net/gml/3.2': {
'Curve': makeChildAppender(
GML3.prototype.writeCurveOrLineString_),
'MultiCurve': makeChildAppender(
GML3.prototype.writeMultiCurveOrLineString_),
'Point': makeChildAppender(GML32.prototype.writePoint_),
'MultiPoint': makeChildAppender(
GML3.prototype.writeMultiPoint_),
'LineString': makeChildAppender(
GML3.prototype.writeCurveOrLineString_),
'MultiLineString': makeChildAppender(
GML3.prototype.writeMultiCurveOrLineString_),
'LinearRing': makeChildAppender(
GML3.prototype.writeLinearRing_),
'Polygon': makeChildAppender(
GML3.prototype.writeSurfaceOrPolygon_),
'MultiPolygon': makeChildAppender(
GML3.prototype.writeMultiSurfaceOrPolygon_),
'Surface': makeChildAppender(
GML3.prototype.writeSurfaceOrPolygon_),
'MultiSurface': makeChildAppender(
GML3.prototype.writeMultiSurfaceOrPolygon_),
'Envelope': makeChildAppender(
GML3.prototype.writeEnvelope)
}
};
export default GML32;
+105 -40
View File
@@ -71,6 +71,7 @@ const ONLY_WHITESPACE_RE = /^[\s\xa0]*$/;
* gml:MultiPolygon. Since the latter is deprecated in GML 3. * gml:MultiPolygon. Since the latter is deprecated in GML 3.
* @property {string} [schemaLocation] Optional schemaLocation to use when * @property {string} [schemaLocation] Optional schemaLocation to use when
* writing out the GML, this will override the default provided. * writing out the GML, this will override the default provided.
* @property {boolean} [hasZ=false] If coordinates have a Z value.
*/ */
@@ -122,11 +123,10 @@ class GMLBase extends XMLFeature {
* @type {Object<string, Object<string, Object>>} * @type {Object<string, Object<string, Object>>}
*/ */
this.FEATURE_COLLECTION_PARSERS = {}; this.FEATURE_COLLECTION_PARSERS = {};
this.FEATURE_COLLECTION_PARSERS[GMLNS] = { this.FEATURE_COLLECTION_PARSERS[this.namespace] = {
'featureMember': makeReplacer(this.readFeaturesInternal), 'featureMember': makeArrayPusher(this.readFeaturesInternal),
'featureMembers': makeReplacer(this.readFeaturesInternal) 'featureMembers': makeReplacer(this.readFeaturesInternal)
}; };
} }
/** /**
@@ -138,15 +138,9 @@ class GMLBase extends XMLFeature {
const localName = node.localName; const localName = node.localName;
let features = null; let features = null;
if (localName == 'FeatureCollection') { if (localName == 'FeatureCollection') {
if (node.namespaceURI === 'http://www.opengis.net/wfs') { features = pushParseAndPop([],
features = pushParseAndPop([], this.FEATURE_COLLECTION_PARSERS, node,
this.FEATURE_COLLECTION_PARSERS, node, objectStack, this);
objectStack, this);
} else {
features = pushParseAndPop(null,
this.FEATURE_COLLECTION_PARSERS, node,
objectStack, this);
}
} else if (localName == 'featureMembers' || localName == 'featureMember') { } else if (localName == 'featureMembers' || localName == 'featureMember') {
const context = objectStack[0]; const context = objectStack[0];
let featureType = context['featureType']; let featureType = context['featureType'];
@@ -189,9 +183,11 @@ class GMLBase extends XMLFeature {
featureNS = {}; featureNS = {};
featureNS[defaultPrefix] = ns; featureNS[defaultPrefix] = ns;
} }
/** @type {Object<string, Object<string, import("../xml.js").Parser>>} */
const parsersNS = {}; const parsersNS = {};
const featureTypes = Array.isArray(featureType) ? featureType : [featureType]; const featureTypes = Array.isArray(featureType) ? featureType : [featureType];
for (const p in featureNS) { for (const p in featureNS) {
/** @type {Object<string, import("../xml.js").Parser>} */
const parsers = {}; const parsers = {};
for (let i = 0, ii = featureTypes.length; i < ii; ++i) { for (let i = 0, ii = featureTypes.length; i < ii; ++i) {
const featurePrefix = featureTypes[i].indexOf(':') === -1 ? const featurePrefix = featureTypes[i].indexOf(':') === -1 ?
@@ -227,7 +223,7 @@ class GMLBase extends XMLFeature {
context['srsName'] = node.firstElementChild.getAttribute('srsName'); context['srsName'] = node.firstElementChild.getAttribute('srsName');
context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension'); context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension');
/** @type {import("../geom/Geometry.js").default} */ /** @type {import("../geom/Geometry.js").default} */
const geometry = pushParseAndPop(null, this.GEOMETRY_PARSERS_, node, objectStack, this); const geometry = pushParseAndPop(null, this.GEOMETRY_PARSERS, node, objectStack, this);
if (geometry) { if (geometry) {
return ( return (
/** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, context)) /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, context))
@@ -240,42 +236,77 @@ class GMLBase extends XMLFeature {
/** /**
* @param {Element} node Node. * @param {Element} node Node.
* @param {Array<*>} objectStack Object stack. * @param {Array<*>} objectStack Object stack.
* @return {Feature} Feature. * @param {boolean} asFeature whether result should be wrapped as a feature.
* @return {Feature|Object} Feature
*/ */
readFeatureElement(node, objectStack) { readFeatureElementInternal(node, objectStack, asFeature) {
let n;
const fid = node.getAttribute('fid') || getAttributeNS(node, GMLNS, 'id');
const values = {};
let geometryName; let geometryName;
for (n = node.firstElementChild; n; n = n.nextElementSibling) { const values = {};
for (let n = node.firstElementChild; n; n = n.nextElementSibling) {
let value;
const localName = n.localName; const localName = n.localName;
// Assume attribute elements have one child node and that the child // first, check if it is simple attribute
// is a text or CDATA node (to be treated as text). if (n.childNodes.length === 0
// Otherwise assume it is a geometry node. || (n.childNodes.length === 1 && (n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) {
if (n.childNodes.length === 0 || value = getAllTextContent(n, false);
(n.childNodes.length === 1 &&
(n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) {
let value = getAllTextContent(n, false);
if (ONLY_WHITESPACE_RE.test(value)) { if (ONLY_WHITESPACE_RE.test(value)) {
value = undefined; value = undefined;
} }
values[localName] = value;
} else { } else {
// boundedBy is an extent and must not be considered as a geometry if (asFeature) {
if (localName !== 'boundedBy') { //if feature, try it as a geometry
value = this.readGeometryElement(n, objectStack);
}
if (!value) { //if not a geometry or not a feature, treat it as a complex attribute
value = this.readFeatureElementInternal(n, objectStack, false);
} else if (localName !== 'boundedBy') {
// boundedBy is an extent and must not be considered as a geometry
geometryName = localName; geometryName = localName;
} }
values[localName] = this.readGeometryElement(n, objectStack); }
if (values[localName]) {
if (!(values[localName] instanceof Array)) {
values[localName] = [values[localName]];
}
values[localName].push(value);
} else {
values[localName] = value;
}
const len = n.attributes.length;
if (len > 0) {
values[localName] = {_content_: values[localName]};
for (let i = 0; i < len; i++) {
const attName = n.attributes[i].name;
values[localName][attName] = n.attributes[i].value;
}
} }
} }
const feature = new Feature(values); if (!asFeature) {
if (geometryName) { return values;
feature.setGeometryName(geometryName); } else {
const feature = new Feature(values);
if (geometryName) {
feature.setGeometryName(geometryName);
}
const fid = node.getAttribute('fid') ||
getAttributeNS(node, this.namespace, 'id');
if (fid) {
feature.setId(fid);
}
return feature;
} }
if (fid) { }
feature.setId(fid);
}
return feature; /**
* @param {Element} node Node.
* @param {Array<*>} objectStack Object stack.
* @return {Feature} Feature.
*/
readFeatureElement(node, objectStack) {
return this.readFeatureElementInternal(node, objectStack, true);
} }
/** /**
@@ -383,7 +414,7 @@ class GMLBase extends XMLFeature {
*/ */
readFlatLinearRing_(node, objectStack) { readFlatLinearRing_(node, objectStack) {
const ring = pushParseAndPop(null, const ring = pushParseAndPop(null,
this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, this.GEOMETRY_FLAT_COORDINATES_PARSERS, node,
objectStack, this); objectStack, this);
if (ring) { if (ring) {
return ring; return ring;
@@ -412,7 +443,7 @@ class GMLBase extends XMLFeature {
readPolygon(node, objectStack) { readPolygon(node, objectStack) {
/** @type {Array<Array<number>>} */ /** @type {Array<Array<number>>} */
const flatLinearRings = pushParseAndPop([null], const flatLinearRings = pushParseAndPop([null],
this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); this.FLAT_LINEAR_RINGS_PARSERS, node, objectStack, this);
if (flatLinearRings && flatLinearRings[0]) { if (flatLinearRings && flatLinearRings[0]) {
const flatCoordinates = flatLinearRings[0]; const flatCoordinates = flatLinearRings[0];
const ends = [flatCoordinates.length]; const ends = [flatCoordinates.length];
@@ -434,7 +465,7 @@ class GMLBase extends XMLFeature {
* @return {Array<number>} Flat coordinates. * @return {Array<number>} Flat coordinates.
*/ */
readFlatCoordinatesFromNode_(node, objectStack) { readFlatCoordinatesFromNode_(node, objectStack) {
return pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this); return pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS, node, objectStack, this);
} }
/** /**
@@ -469,6 +500,40 @@ class GMLBase extends XMLFeature {
} }
} }
GMLBase.prototype.namespace = GMLNS;
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GMLBase.prototype.FLAT_LINEAR_RINGS_PARSERS = {
'http://www.opengis.net/gml': {}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GMLBase.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS = {
'http://www.opengis.net/gml': {}
};
/**
* @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>}
* @protected
*/
GMLBase.prototype.GEOMETRY_PARSERS = {
'http://www.opengis.net/gml': {}
};
/** /**
* @const * @const
* @type {Object<string, Object<string, import("../xml.js").Parser>>} * @type {Object<string, Object<string, import("../xml.js").Parser>>}
+24 -22
View File
@@ -7,6 +7,7 @@ import {transformWithOptions} from '../format/Feature.js';
import XMLFeature from '../format/XMLFeature.js'; import XMLFeature from '../format/XMLFeature.js';
import {readString, readDecimal, readNonNegativeInteger, readDateTime, writeStringTextNode, writeNonNegativeIntegerTextNode, writeDecimalTextNode, writeDateTimeTextNode} from '../format/xsd.js'; import {readString, readDecimal, readNonNegativeInteger, readDateTime, writeStringTextNode, writeNonNegativeIntegerTextNode, writeDecimalTextNode, writeDateTimeTextNode} from '../format/xsd.js';
import GeometryLayout from '../geom/GeometryLayout.js'; import GeometryLayout from '../geom/GeometryLayout.js';
import GeometryType from '../geom/GeometryType.js';
import LineString from '../geom/LineString.js'; import LineString from '../geom/LineString.js';
import MultiLineString from '../geom/MultiLineString.js'; import MultiLineString from '../geom/MultiLineString.js';
import Point from '../geom/Point.js'; import Point from '../geom/Point.js';
@@ -738,8 +739,8 @@ function writeWptType(node, coordinate, objectStack) {
const namespaceURI = parentNode.namespaceURI; const namespaceURI = parentNode.namespaceURI;
const properties = context['properties']; const properties = context['properties'];
//FIXME Projection handling //FIXME Projection handling
node.setAttributeNS(null, 'lat', coordinate[1]); node.setAttributeNS(null, 'lat', String(coordinate[1]));
node.setAttributeNS(null, 'lon', coordinate[0]); node.setAttributeNS(null, 'lon', String(coordinate[0]));
const geometryLayout = context['geometryLayout']; const geometryLayout = context['geometryLayout'];
switch (geometryLayout) { switch (geometryLayout) {
case GeometryLayout.XYZM: case GeometryLayout.XYZM:
@@ -779,12 +780,13 @@ function writeWptType(node, coordinate, objectStack) {
function writeRte(node, feature, objectStack) { function writeRte(node, feature, objectStack) {
const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]); const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]);
const properties = feature.getProperties(); const properties = feature.getProperties();
const context = {node: node, 'properties': properties}; const context = {node: node};
let geometry = feature.getGeometry(); context['properties'] = properties;
if (geometry) { const geometry = feature.getGeometry();
geometry = /** @type {LineString} */ (transformWithOptions(geometry, true, options)); if (geometry.getType() == GeometryType.LINE_STRING) {
context['geometryLayout'] = geometry.getLayout(); const lineString = /** @type {LineString} */ (transformWithOptions(geometry, true, options));
properties['rtept'] = geometry.getCoordinates(); context['geometryLayout'] = lineString.getLayout();
properties['rtept'] = lineString.getCoordinates();
} }
const parentNode = objectStack[objectStack.length - 1].node; const parentNode = objectStack[objectStack.length - 1].node;
const orderedKeys = RTE_SEQUENCE[parentNode.namespaceURI]; const orderedKeys = RTE_SEQUENCE[parentNode.namespaceURI];
@@ -804,12 +806,12 @@ function writeTrk(node, feature, objectStack) {
const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]); const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]);
const properties = feature.getProperties(); const properties = feature.getProperties();
/** @type {import("../xml.js").NodeStackItem} */ /** @type {import("../xml.js").NodeStackItem} */
const context = {node: node, 'properties': properties}; const context = {node: node};
let geometry = feature.getGeometry(); context['properties'] = properties;
if (geometry) { const geometry = feature.getGeometry();
geometry = /** @type {MultiLineString} */ if (geometry.getType() == GeometryType.MULTI_LINE_STRING) {
(transformWithOptions(geometry, true, options)); const multiLineString = /** @type {MultiLineString} */ (transformWithOptions(geometry, true, options));
properties['trkseg'] = geometry.getLineStrings(); properties['trkseg'] = multiLineString.getLineStrings();
} }
const parentNode = objectStack[objectStack.length - 1].node; const parentNode = objectStack[objectStack.length - 1].node;
const orderedKeys = TRK_SEQUENCE[parentNode.namespaceURI]; const orderedKeys = TRK_SEQUENCE[parentNode.namespaceURI];
@@ -827,8 +829,9 @@ function writeTrk(node, feature, objectStack) {
*/ */
function writeTrkSeg(node, lineString, objectStack) { function writeTrkSeg(node, lineString, objectStack) {
/** @type {import("../xml.js").NodeStackItem} */ /** @type {import("../xml.js").NodeStackItem} */
const context = {node: node, 'geometryLayout': lineString.getLayout(), const context = {node: node};
'properties': {}}; context['geometryLayout'] = lineString.getLayout();
context['properties'] = {};
pushSerializeAndPop(context, pushSerializeAndPop(context,
TRKSEG_SERIALIZERS, TRKSEG_NODE_FACTORY, TRKSEG_SERIALIZERS, TRKSEG_NODE_FACTORY,
lineString.getCoordinates(), objectStack); lineString.getCoordinates(), objectStack);
@@ -844,12 +847,11 @@ function writeWpt(node, feature, objectStack) {
const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]); const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]);
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
context['properties'] = feature.getProperties(); context['properties'] = feature.getProperties();
let geometry = feature.getGeometry(); const geometry = feature.getGeometry();
if (geometry) { if (geometry.getType() == GeometryType.POINT) {
geometry = /** @type {Point} */ const point = /** @type {Point} */ (transformWithOptions(geometry, true, options));
(transformWithOptions(geometry, true, options)); context['geometryLayout'] = point.getLayout();
context['geometryLayout'] = geometry.getLayout(); writeWptType(node, point.getCoordinates(), objectStack);
writeWptType(node, geometry.getCoordinates(), objectStack);
} }
} }
+23 -23
View File
@@ -293,14 +293,14 @@ function readGeometry(object, opt_options) {
throw new Error('Unsupported GeoJSON type: ' + object.type); throw new Error('Unsupported GeoJSON type: ' + object.type);
} }
} }
return transformWithOptions(geometry, false, opt_options); return /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, false, opt_options));
} }
/** /**
* @param {GeoJSONGeometryCollection} object Object. * @param {GeoJSONGeometryCollection} object Object.
* @param {import("./Feature.js").ReadOptions=} opt_options Read options. * @param {import("./Feature.js").ReadOptions=} opt_options Read options.
* @return {import("../geom/GeometryCollection.js").default} Geometry collection. * @return {GeometryCollection} Geometry collection.
*/ */
function readGeometryCollectionGeometry(object, opt_options) { function readGeometryCollectionGeometry(object, opt_options) {
const geometries = object['geometries'].map( const geometries = object['geometries'].map(
@@ -317,7 +317,7 @@ function readGeometryCollectionGeometry(object, opt_options) {
/** /**
* @param {GeoJSONPoint} object Object. * @param {GeoJSONPoint} object Object.
* @return {import("../geom/Point.js").default} Point. * @return {Point} Point.
*/ */
function readPointGeometry(object) { function readPointGeometry(object) {
return new Point(object['coordinates']); return new Point(object['coordinates']);
@@ -326,7 +326,7 @@ function readPointGeometry(object) {
/** /**
* @param {GeoJSONLineString} object Object. * @param {GeoJSONLineString} object Object.
* @return {import("../geom/LineString.js").default} LineString. * @return {LineString} LineString.
*/ */
function readLineStringGeometry(object) { function readLineStringGeometry(object) {
return new LineString(object['coordinates']); return new LineString(object['coordinates']);
@@ -335,7 +335,7 @@ function readLineStringGeometry(object) {
/** /**
* @param {GeoJSONMultiLineString} object Object. * @param {GeoJSONMultiLineString} object Object.
* @return {import("../geom/MultiLineString.js").default} MultiLineString. * @return {MultiLineString} MultiLineString.
*/ */
function readMultiLineStringGeometry(object) { function readMultiLineStringGeometry(object) {
return new MultiLineString(object['coordinates']); return new MultiLineString(object['coordinates']);
@@ -344,7 +344,7 @@ function readMultiLineStringGeometry(object) {
/** /**
* @param {GeoJSONMultiPoint} object Object. * @param {GeoJSONMultiPoint} object Object.
* @return {import("../geom/MultiPoint.js").default} MultiPoint. * @return {MultiPoint} MultiPoint.
*/ */
function readMultiPointGeometry(object) { function readMultiPointGeometry(object) {
return new MultiPoint(object['coordinates']); return new MultiPoint(object['coordinates']);
@@ -353,7 +353,7 @@ function readMultiPointGeometry(object) {
/** /**
* @param {GeoJSONMultiPolygon} object Object. * @param {GeoJSONMultiPolygon} object Object.
* @return {import("../geom/MultiPolygon.js").default} MultiPolygon. * @return {MultiPolygon} MultiPolygon.
*/ */
function readMultiPolygonGeometry(object) { function readMultiPolygonGeometry(object) {
return new MultiPolygon(object['coordinates']); return new MultiPolygon(object['coordinates']);
@@ -362,7 +362,7 @@ function readMultiPolygonGeometry(object) {
/** /**
* @param {GeoJSONPolygon} object Object. * @param {GeoJSONPolygon} object Object.
* @return {import("../geom/Polygon.js").default} Polygon. * @return {Polygon} Polygon.
*/ */
function readPolygonGeometry(object) { function readPolygonGeometry(object) {
return new Polygon(object['coordinates']); return new Polygon(object['coordinates']);
@@ -375,38 +375,38 @@ function readPolygonGeometry(object) {
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
function writeGeometry(geometry, opt_options) { function writeGeometry(geometry, opt_options) {
geometry = transformWithOptions(geometry, true, opt_options); geometry = /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, true, opt_options));
const type = geometry.getType(); const type = geometry.getType();
/** @type {GeoJSONGeometry} */ /** @type {GeoJSONGeometry} */
let geoJSON; let geoJSON;
switch (type) { switch (type) {
case GeometryType.POINT: { case GeometryType.POINT: {
geoJSON = writePointGeometry(/** @type {import("../geom/Point.js").default} */ (geometry), opt_options); geoJSON = writePointGeometry(/** @type {Point} */ (geometry), opt_options);
break; break;
} }
case GeometryType.LINE_STRING: { case GeometryType.LINE_STRING: {
geoJSON = writeLineStringGeometry(/** @type {import("../geom/LineString.js").default} */ (geometry), opt_options); geoJSON = writeLineStringGeometry(/** @type {LineString} */ (geometry), opt_options);
break; break;
} }
case GeometryType.POLYGON: { case GeometryType.POLYGON: {
geoJSON = writePolygonGeometry(/** @type {import("../geom/Polygon.js").default} */ (geometry), opt_options); geoJSON = writePolygonGeometry(/** @type {Polygon} */ (geometry), opt_options);
break; break;
} }
case GeometryType.MULTI_POINT: { case GeometryType.MULTI_POINT: {
geoJSON = writeMultiPointGeometry(/** @type {import("../geom/MultiPoint.js").default} */ (geometry), opt_options); geoJSON = writeMultiPointGeometry(/** @type {MultiPoint} */ (geometry), opt_options);
break; break;
} }
case GeometryType.MULTI_LINE_STRING: { case GeometryType.MULTI_LINE_STRING: {
geoJSON = writeMultiLineStringGeometry(/** @type {import("../geom/MultiLineString.js").default} */ (geometry), opt_options); geoJSON = writeMultiLineStringGeometry(/** @type {MultiLineString} */ (geometry), opt_options);
break; break;
} }
case GeometryType.MULTI_POLYGON: { case GeometryType.MULTI_POLYGON: {
geoJSON = writeMultiPolygonGeometry(/** @type {import("../geom/MultiPolygon.js").default} */ (geometry), opt_options); geoJSON = writeMultiPolygonGeometry(/** @type {MultiPolygon} */ (geometry), opt_options);
break; break;
} }
case GeometryType.GEOMETRY_COLLECTION: { case GeometryType.GEOMETRY_COLLECTION: {
geoJSON = writeGeometryCollectionGeometry(/** @type {import("../geom/GeometryCollection.js").default} */ (geometry), opt_options); geoJSON = writeGeometryCollectionGeometry(/** @type {GeometryCollection} */ (geometry), opt_options);
break; break;
} }
case GeometryType.CIRCLE: { case GeometryType.CIRCLE: {
@@ -425,7 +425,7 @@ function writeGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/GeometryCollection.js").default} geometry Geometry. * @param {GeometryCollection} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometryCollection} GeoJSON geometry collection. * @return {GeoJSONGeometryCollection} GeoJSON geometry collection.
*/ */
@@ -443,7 +443,7 @@ function writeGeometryCollectionGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/LineString.js").default} geometry Geometry. * @param {LineString} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
@@ -456,7 +456,7 @@ function writeLineStringGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/MultiLineString.js").default} geometry Geometry. * @param {MultiLineString} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
@@ -469,7 +469,7 @@ function writeMultiLineStringGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/MultiPoint.js").default} geometry Geometry. * @param {MultiPoint} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
@@ -482,7 +482,7 @@ function writeMultiPointGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/MultiPolygon.js").default} geometry Geometry. * @param {MultiPolygon} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
@@ -499,7 +499,7 @@ function writeMultiPolygonGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/Point.js").default} geometry Geometry. * @param {Point} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
@@ -512,7 +512,7 @@ function writePointGeometry(geometry, opt_options) {
/** /**
* @param {import("../geom/Polygon.js").default} geometry Geometry. * @param {Polygon} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry} GeoJSON geometry. * @return {GeoJSONGeometry} GeoJSON geometry.
*/ */
+22 -7
View File
@@ -1,6 +1,7 @@
/** /**
* @module ol/format/JSONFeature * @module ol/format/JSONFeature
*/ */
import {abstract} from '../util.js';
import FeatureFormat from '../format/Feature.js'; import FeatureFormat from '../format/Feature.js';
import FormatType from '../format/FormatType.js'; import FormatType from '../format/FormatType.js';
@@ -59,7 +60,9 @@ class JSONFeature extends FeatureFormat {
* @protected * @protected
* @return {import("../Feature.js").default} Feature. * @return {import("../Feature.js").default} Feature.
*/ */
readFeatureFromObject(object, opt_options) {} readFeatureFromObject(object, opt_options) {
return abstract();
}
/** /**
* @abstract * @abstract
@@ -68,7 +71,9 @@ class JSONFeature extends FeatureFormat {
* @protected * @protected
* @return {Array<import("../Feature.js").default>} Features. * @return {Array<import("../Feature.js").default>} Features.
*/ */
readFeaturesFromObject(object, opt_options) {} readFeaturesFromObject(object, opt_options) {
return abstract();
}
/** /**
* Read a geometry. * Read a geometry.
@@ -90,7 +95,9 @@ class JSONFeature extends FeatureFormat {
* @protected * @protected
* @return {import("../geom/Geometry.js").default} Geometry. * @return {import("../geom/Geometry.js").default} Geometry.
*/ */
readGeometryFromObject(object, opt_options) {} readGeometryFromObject(object, opt_options) {
return abstract();
}
/** /**
* Read the projection. * Read the projection.
@@ -109,7 +116,9 @@ class JSONFeature extends FeatureFormat {
* @protected * @protected
* @return {import("../proj/Projection.js").default} Projection. * @return {import("../proj/Projection.js").default} Projection.
*/ */
readProjectionFromObject(object) {} readProjectionFromObject(object) {
return abstract();
}
/** /**
* Encode a feature as string. * Encode a feature as string.
@@ -129,7 +138,9 @@ class JSONFeature extends FeatureFormat {
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {Object} Object. * @return {Object} Object.
*/ */
writeFeatureObject(feature, opt_options) {} writeFeatureObject(feature, opt_options) {
return abstract();
}
/** /**
* Encode an array of features as string. * Encode an array of features as string.
@@ -149,7 +160,9 @@ class JSONFeature extends FeatureFormat {
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {Object} Object. * @return {Object} Object.
*/ */
writeFeaturesObject(features, opt_options) {} writeFeaturesObject(features, opt_options) {
return abstract();
}
/** /**
* Encode a geometry as string. * Encode a geometry as string.
@@ -169,7 +182,9 @@ class JSONFeature extends FeatureFormat {
* @param {import("./Feature.js").WriteOptions=} opt_options Write options. * @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {Object} Object. * @return {Object} Object.
*/ */
writeGeometryObject(geometry, opt_options) {} writeGeometryObject(geometry, opt_options) {
return abstract();
}
} }
+39 -35
View File
@@ -26,7 +26,7 @@ import IconOrigin from '../style/IconOrigin.js';
import Stroke from '../style/Stroke.js'; import Stroke from '../style/Stroke.js';
import Style from '../style/Style.js'; import Style from '../style/Style.js';
import Text from '../style/Text.js'; import Text from '../style/Text.js';
import {createElementNS, getAllTextContent, isDocument, isNode, makeArrayExtender, import {createElementNS, getAllTextContent, isDocument, makeArrayExtender,
makeArrayPusher, makeChildAppender, makeObjectPropertySetter, makeArrayPusher, makeChildAppender, makeObjectPropertySetter,
makeReplacer, makeSequence, makeSimpleNodeFactory, makeStructureNS, makeReplacer, makeSequence, makeSimpleNodeFactory, makeStructureNS,
OBJECT_PROPERTY_NODE_FACTORY, parse, parseNode, pushParseAndPop, OBJECT_PROPERTY_NODE_FACTORY, parse, parseNode, pushParseAndPop,
@@ -639,15 +639,15 @@ class KML extends XMLFeature {
* @api * @api
*/ */
readName(source) { readName(source) {
if (isDocument(source)) { if (!source) {
return this.readNameFromDocument(/** @type {Document} */ (source)); return undefined;
} else if (isNode(source)) {
return this.readNameFromNode(/** @type {Element} */ (source));
} else if (typeof source === 'string') { } else if (typeof source === 'string') {
const doc = parse(source); const doc = parse(source);
return this.readNameFromDocument(doc); return this.readNameFromDocument(doc);
} else if (isDocument(source)) {
return this.readNameFromDocument(/** @type {Document} */ (source));
} else { } else {
return undefined; return this.readNameFromNode(/** @type {Element} */ (source));
} }
} }
@@ -656,7 +656,7 @@ class KML extends XMLFeature {
* @return {string|undefined} Name. * @return {string|undefined} Name.
*/ */
readNameFromDocument(doc) { readNameFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) { for (let n = /** @type {Node} */ (doc.firstChild); n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) { if (n.nodeType == Node.ELEMENT_NODE) {
const name = this.readNameFromNode(/** @type {Element} */ (n)); const name = this.readNameFromNode(/** @type {Element} */ (n));
if (name) { if (name) {
@@ -703,15 +703,15 @@ class KML extends XMLFeature {
*/ */
readNetworkLinks(source) { readNetworkLinks(source) {
const networkLinks = []; const networkLinks = [];
if (isDocument(source)) { if (typeof source === 'string') {
extend(networkLinks, this.readNetworkLinksFromDocument(
/** @type {Document} */ (source)));
} else if (isNode(source)) {
extend(networkLinks, this.readNetworkLinksFromNode(
/** @type {Element} */ (source)));
} else if (typeof source === 'string') {
const doc = parse(source); const doc = parse(source);
extend(networkLinks, this.readNetworkLinksFromDocument(doc)); extend(networkLinks, this.readNetworkLinksFromDocument(doc));
} else if (isDocument(source)) {
extend(networkLinks, this.readNetworkLinksFromDocument(
/** @type {Document} */ (source)));
} else {
extend(networkLinks, this.readNetworkLinksFromNode(
/** @type {Element} */ (source)));
} }
return networkLinks; return networkLinks;
} }
@@ -722,7 +722,7 @@ class KML extends XMLFeature {
*/ */
readNetworkLinksFromDocument(doc) { readNetworkLinksFromDocument(doc) {
const networkLinks = []; const networkLinks = [];
for (let n = doc.firstChild; n; n = n.nextSibling) { for (let n = /** @type {Node} */ (doc.firstChild); n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) { if (n.nodeType == Node.ELEMENT_NODE) {
extend(networkLinks, this.readNetworkLinksFromNode(/** @type {Element} */ (n))); extend(networkLinks, this.readNetworkLinksFromNode(/** @type {Element} */ (n)));
} }
@@ -765,15 +765,15 @@ class KML extends XMLFeature {
*/ */
readRegion(source) { readRegion(source) {
const regions = []; const regions = [];
if (isDocument(source)) { if (typeof source === 'string') {
extend(regions, this.readRegionFromDocument(
/** @type {Document} */ (source)));
} else if (isNode(source)) {
extend(regions, this.readRegionFromNode(
/** @type {Element} */ (source)));
} else if (typeof source === 'string') {
const doc = parse(source); const doc = parse(source);
extend(regions, this.readRegionFromDocument(doc)); extend(regions, this.readRegionFromDocument(doc));
} else if (isDocument(source)) {
extend(regions, this.readRegionFromDocument(
/** @type {Document} */ (source)));
} else {
extend(regions, this.readRegionFromNode(
/** @type {Element} */ (source)));
} }
return regions; return regions;
} }
@@ -784,7 +784,7 @@ class KML extends XMLFeature {
*/ */
readRegionFromDocument(doc) { readRegionFromDocument(doc) {
const regions = []; const regions = [];
for (let n = doc.firstChild; n; n = n.nextSibling) { for (let n = /** @type {Node} */ (doc.firstChild); n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) { if (n.nodeType == Node.ELEMENT_NODE) {
extend(regions, this.readRegionFromNode(/** @type {Element} */ (n))); extend(regions, this.readRegionFromNode(/** @type {Element} */ (n)));
} }
@@ -838,6 +838,7 @@ class KML extends XMLFeature {
kml.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION); kml.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION);
const /** @type {import("../xml.js").NodeStackItem} */ context = {node: kml}; const /** @type {import("../xml.js").NodeStackItem} */ context = {node: kml};
/** @type {!Object<string, (Array<Feature>|Feature|undefined)>} */
const properties = {}; const properties = {};
if (features.length > 1) { if (features.length > 1) {
properties['Document'] = features; properties['Document'] = features;
@@ -931,7 +932,7 @@ function createFeatureStyleFunction(style, styleUrl, defaultStyle, sharedStyles,
if (drawName) { if (drawName) {
name = /** @type {string} */ (feature.get('name')); name = /** @type {string} */ (feature.get('name'));
drawName = drawName && name; drawName = drawName && !!name;
} }
if (style) { if (style) {
@@ -1714,11 +1715,13 @@ function readStyle(node, objectStack) {
if (fill !== undefined && !fill) { if (fill !== undefined && !fill) {
fillStyle = null; fillStyle = null;
} }
let imageStyle = /** @type {import("../style/Image.js").default} */ let imageStyle;
('imageStyle' in styleObject ? if ('imageStyle' in styleObject) {
styleObject['imageStyle'] : DEFAULT_IMAGE_STYLE); if (styleObject['imageStyle'] != DEFAULT_NO_IMAGE_STYLE) {
if (imageStyle == DEFAULT_NO_IMAGE_STYLE) { imageStyle = styleObject['imageStyle'];
imageStyle = undefined; }
} else {
imageStyle = DEFAULT_IMAGE_STYLE;
} }
const textStyle = /** @type {Text} */ const textStyle = /** @type {Text} */
('textStyle' in styleObject ? ('textStyle' in styleObject ?
@@ -2073,9 +2076,10 @@ function whenParser(node, objectStack) {
function writeColorTextNode(node, color) { function writeColorTextNode(node, color) {
const rgba = asArray(color); const rgba = asArray(color);
const opacity = (rgba.length == 4) ? rgba[3] : 1; const opacity = (rgba.length == 4) ? rgba[3] : 1;
/** @type {Array<string|number>} */
const abgr = [opacity * 255, rgba[2], rgba[1], rgba[0]]; const abgr = [opacity * 255, rgba[2], rgba[1], rgba[0]];
for (let i = 0; i < 4; ++i) { for (let i = 0; i < 4; ++i) {
const hex = parseInt(abgr[i], 10).toString(16); const hex = Math.floor(/** @type {number} */ (abgr[i])).toString(16);
abgr[i] = (hex.length == 1) ? '0' + hex : hex; abgr[i] = (hex.length == 1) ? '0' + hex : hex;
} }
writeStringTextNode(node, abgr.join('')); writeStringTextNode(node, abgr.join(''));
@@ -2666,7 +2670,7 @@ function writePlacemark(node, feature, objectStack) {
// set id // set id
if (feature.getId()) { if (feature.getId()) {
node.setAttribute('id', feature.getId()); node.setAttribute('id', /** @type {string} */ (feature.getId()));
} }
// serialize properties (properties unknown to KML are not serialized) // serialize properties (properties unknown to KML are not serialized)
@@ -2713,7 +2717,7 @@ function writePlacemark(node, feature, objectStack) {
const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]); const options = /** @type {import("./Feature.js").WriteOptions} */ (objectStack[0]);
let geometry = feature.getGeometry(); let geometry = feature.getGeometry();
if (geometry) { if (geometry) {
geometry = transformWithOptions(geometry, true, options); geometry = /** @type {import("../geom/Geometry.js").default} */ (transformWithOptions(geometry, true, options));
} }
pushSerializeAndPop(context, PLACEMARK_SERIALIZERS, pushSerializeAndPop(context, PLACEMARK_SERIALIZERS,
GEOMETRY_NODE_FACTORY, [geometry], objectStack); GEOMETRY_NODE_FACTORY, [geometry], objectStack);
@@ -2893,7 +2897,7 @@ function writeStyle(node, style, objectStack) {
const strokeStyle = style.getStroke(); const strokeStyle = style.getStroke();
const imageStyle = style.getImage(); const imageStyle = style.getImage();
const textStyle = style.getText(); const textStyle = style.getText();
if (imageStyle instanceof Icon) { if (imageStyle && typeof /** @type {?} */ (imageStyle).getSrc === 'function') {
properties['IconStyle'] = imageStyle; properties['IconStyle'] = imageStyle;
} }
if (textStyle) { if (textStyle) {
@@ -2918,8 +2922,8 @@ function writeStyle(node, style, objectStack) {
* @param {Vec2} vec2 Vec2. * @param {Vec2} vec2 Vec2.
*/ */
function writeVec2(node, vec2) { function writeVec2(node, vec2) {
node.setAttribute('x', vec2.x); node.setAttribute('x', String(vec2.x));
node.setAttribute('y', vec2.y); node.setAttribute('y', String(vec2.y));
node.setAttribute('xunits', vec2.xunits); node.setAttribute('xunits', vec2.xunits);
node.setAttribute('yunits', vec2.yunits); node.setAttribute('yunits', vec2.yunits);
} }

Some files were not shown because too many files have changed in this diff Show More