Non puoi selezionare più di 25 argomenti
Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
2131 righe
57 KiB
2131 righe
57 KiB
2 anni fa
|
/*! leaflet-wfst 2.0.1-beta.20 2018-03-15 */
|
||
|
(function(window, document, undefined) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
L.XmlUtil = {
|
||
|
namespaces: {
|
||
|
xlink: 'http://www.w3.org/1999/xlink',
|
||
|
xmlns: 'http://www.w3.org/2000/xmlns/',
|
||
|
xsd: 'http://www.w3.org/2001/XMLSchema',
|
||
|
xsi: 'http://www.w3.org/2001/XMLSchema-instance',
|
||
|
wfs: 'http://www.opengis.net/wfs',
|
||
|
gml: 'http://www.opengis.net/gml',
|
||
|
ogc: 'http://www.opengis.net/ogc',
|
||
|
ows: 'http://www.opengis.net/ows'
|
||
|
},
|
||
|
|
||
|
// TODO: find another way to create a new document with doctype text/xml?
|
||
|
xmldoc: (new DOMParser()).parseFromString('<root />', 'text/xml'),
|
||
|
|
||
|
setAttributes: function (node, attributes) {
|
||
|
for (var name in attributes) {
|
||
|
if (attributes[name] != null && attributes[name].toString) {
|
||
|
var value = attributes[name].toString();
|
||
|
var uri = this.namespaces[name.substring(0, name.indexOf(':'))] || null;
|
||
|
node.setAttributeNS(uri, name, value);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
evaluate: function (xpath, xml) {
|
||
|
var xmlDoc = xml;
|
||
|
if (!(xmlDoc instanceof Document)) {
|
||
|
xmlDoc = this.parseXml(xml);
|
||
|
}
|
||
|
|
||
|
var xpe = new XPathEvaluator();
|
||
|
var nsResolver = xpe.createNSResolver(xmlDoc.documentElement);
|
||
|
|
||
|
return xpe.evaluate(xpath, xmlDoc, nsResolver, XPathResult.ANY_TYPE, null);
|
||
|
},
|
||
|
|
||
|
createElementNS: function (name, attributes, options) {
|
||
|
options = options || {};
|
||
|
|
||
|
var uri = options.uri;
|
||
|
|
||
|
if (!uri) {
|
||
|
uri = this.namespaces[name.substring(0, name.indexOf(':'))];
|
||
|
}
|
||
|
|
||
|
if (!uri) {
|
||
|
uri = this.namespaces[options.prefix];
|
||
|
}
|
||
|
|
||
|
var node = uri ? this.xmldoc.createElementNS(uri, name) : this.xmldoc.createElement(name);
|
||
|
|
||
|
if (attributes) {
|
||
|
this.setAttributes(node, attributes);
|
||
|
}
|
||
|
|
||
|
if (options.value != null) {
|
||
|
node.appendChild(this.xmldoc.createTextNode(options.value));
|
||
|
}
|
||
|
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
createTextNode: function (value) {
|
||
|
if(value === null || value === undefined) {
|
||
|
value = '';
|
||
|
} else if(value instanceof Date) {
|
||
|
value = value.toISOString();
|
||
|
}
|
||
|
|
||
|
return this.xmldoc.createTextNode(value);
|
||
|
},
|
||
|
|
||
|
getNodeText: function (node) {
|
||
|
if (!node) {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
return node.innerText || node.textContent || node.text;
|
||
|
},
|
||
|
|
||
|
serializeXmlDocumentString: function (node) {
|
||
|
var doc = document.implementation.createDocument('', '', null);
|
||
|
doc.appendChild(node);
|
||
|
var serializer = new XMLSerializer();
|
||
|
return serializer.serializeToString(doc);
|
||
|
},
|
||
|
|
||
|
serializeXmlToString: function (node) {
|
||
|
var serializer = new XMLSerializer();
|
||
|
return serializer.serializeToString(node);
|
||
|
},
|
||
|
|
||
|
parseXml: function (rawXml) {
|
||
|
if (typeof window.DOMParser !== 'undefined') {
|
||
|
return (new window.DOMParser()).parseFromString(rawXml, 'text/xml');
|
||
|
} else if (typeof window.ActiveXObject !== 'undefined' && new window.ActiveXObject('Microsoft.XMLDOM')) {
|
||
|
var xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
|
||
|
xmlDoc.async = 'false';
|
||
|
xmlDoc.loadXML(rawXml);
|
||
|
return xmlDoc;
|
||
|
} else {
|
||
|
throw new Error('No XML parser found');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
parseOwsExceptionReport: function (xml) {
|
||
|
var xmlDoc = xml;
|
||
|
if (!(xmlDoc instanceof Document)) {
|
||
|
xmlDoc = this.parseXml(xml);
|
||
|
}
|
||
|
|
||
|
var exceptionReportElement = xmlDoc.documentElement;
|
||
|
if (!exceptionReportElement || exceptionReportElement.tagName !== 'ows:ExceptionReport') {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
var exceptionReport = {
|
||
|
exceptions: [],
|
||
|
message: ''
|
||
|
};
|
||
|
|
||
|
var exceptionsNodes = exceptionReportElement.getElementsByTagNameNS(L.XmlUtil.namespaces.ows, 'Exception');
|
||
|
for (var i = 0, exceptionsNodesCount = exceptionsNodes.length; i < exceptionsNodesCount; i++) {
|
||
|
var exceptionNode = exceptionsNodes[i];
|
||
|
var exceptionCode = exceptionNode.getAttribute('exceptionCode');
|
||
|
var exceptionsTextNodes = exceptionNode.getElementsByTagNameNS(L.XmlUtil.namespaces.ows, 'ExceptionText');
|
||
|
var exception = {
|
||
|
code: exceptionCode,
|
||
|
text: ''
|
||
|
};
|
||
|
|
||
|
for (var j = 0, textNodesCount = exceptionsTextNodes.length; j < textNodesCount; j++) {
|
||
|
var exceptionTextNode = exceptionsTextNodes[j];
|
||
|
var exceptionText = exceptionTextNode.innerText || exceptionTextNode.textContent || exceptionTextNode.text;
|
||
|
|
||
|
exception.text += exceptionText;
|
||
|
if (j < textNodesCount - 1) {
|
||
|
exception.text += '. ';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exceptionReport.message += exception.code + ' - ' + exception.text;
|
||
|
if (i < exceptionsNodesCount - 1) {
|
||
|
exceptionReport.message += ' ';
|
||
|
}
|
||
|
|
||
|
exceptionReport.exceptions.push(exception);
|
||
|
}
|
||
|
|
||
|
return exceptionReport;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
L.Util.request = function (options) {
|
||
|
options = L.extend({
|
||
|
async: true,
|
||
|
method: 'POST',
|
||
|
data: '',
|
||
|
params: {},
|
||
|
headers: {},
|
||
|
url: window.location.href,
|
||
|
withCredentials: false,
|
||
|
success: function (data) {
|
||
|
console.log(data);
|
||
|
},
|
||
|
error: function (data) {
|
||
|
console.log('Ajax request fail');
|
||
|
console.log(data);
|
||
|
},
|
||
|
complete: function () {
|
||
|
}
|
||
|
}, options);
|
||
|
|
||
|
// good bye IE 6,7
|
||
|
var xhr = new XMLHttpRequest();
|
||
|
|
||
|
xhr.onreadystatechange = function () {
|
||
|
if (xhr.readyState === 4) {
|
||
|
if (xhr.status === 200) {
|
||
|
options.success(xhr.responseText);
|
||
|
} else {
|
||
|
options.error(xhr.responseText);
|
||
|
}
|
||
|
options.complete();
|
||
|
}
|
||
|
};
|
||
|
xhr.withCredentials = options.withCredentials;
|
||
|
|
||
|
var url = options.url + L.Util.getParamString(options.params, options.url);
|
||
|
|
||
|
xhr.open(options.method, url, options.async);
|
||
|
for (var header in options.headers) {
|
||
|
xhr.setRequestHeader(header, options.headers[header]);
|
||
|
}
|
||
|
|
||
|
xhr.send(options.data);
|
||
|
};
|
||
|
|
||
|
L.Filter = {};
|
||
|
|
||
|
L.filter = function (filters) {
|
||
|
var result = L.XmlUtil.createElementNS('ogc:Filter');
|
||
|
|
||
|
if (Array.isArray(filters)) {
|
||
|
filters.forEach(function (element) {
|
||
|
result.appendChild(element instanceof Element ? element : element.toGml());
|
||
|
});
|
||
|
} else if (filters) {
|
||
|
result.appendChild(filters instanceof Element ? filters : filters.toGml());
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
L.Filter.propertyName = function (value) {
|
||
|
return L.XmlUtil.createElementNS('ogc:PropertyName', {}, { value: value });
|
||
|
};
|
||
|
|
||
|
L.Filter.literal = function (value) {
|
||
|
return L.XmlUtil.createElementNS('ogc:Literal', {}, { value: value });
|
||
|
};
|
||
|
|
||
|
L.Filter.element = function(value) {
|
||
|
if(value instanceof Element) {
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
return value.toGml();
|
||
|
};
|
||
|
|
||
|
L.Filter.propertyElement = function (value) {
|
||
|
if (value instanceof Element) {
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
if (value && typeof (value.toGml) === "function") {
|
||
|
return value.toGml();
|
||
|
}
|
||
|
|
||
|
return L.Filter.propertyName(value);
|
||
|
};
|
||
|
|
||
|
L.Filter.literalElement = function (value) {
|
||
|
if (value instanceof Element) {
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
if (value && typeof (value.toGml) === "function") {
|
||
|
return value.toGml();
|
||
|
}
|
||
|
|
||
|
return L.Filter.literal(value);
|
||
|
};
|
||
|
|
||
|
L.Filter.Abstract = L.Class.extend({
|
||
|
attributes: {},
|
||
|
|
||
|
options: {},
|
||
|
|
||
|
tagName: null,
|
||
|
|
||
|
buildFilterContent: function() {
|
||
|
throw "Build filter content is abstract and should be implemented";
|
||
|
},
|
||
|
|
||
|
toGml: function() {
|
||
|
var filterElement = L.XmlUtil.createElementNS(this.tagName, this.attributes, this.options);
|
||
|
this.buildFilterContent(filterElement);
|
||
|
return filterElement;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.BinarySpatial = L.Filter.Abstract.extend({
|
||
|
initialize: function (propertyName, value, crs) {
|
||
|
this.propertyName = propertyName;
|
||
|
this.value = value;
|
||
|
this.crs = crs;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
filterElement.appendChild(L.Filter.propertyName(this.propertyName));
|
||
|
if (typeof(this.value) === "string") {
|
||
|
filterElement.appendChild(L.Filter.propertyName(this.value));
|
||
|
} else {
|
||
|
filterElement.appendChild(this.value.toGml(this.crs));
|
||
|
}
|
||
|
return filterElement;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.Equals = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Equals'
|
||
|
});
|
||
|
|
||
|
L.Filter.equals = function(options) {
|
||
|
return new L.Filter.Equals(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Disjoint = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Disjoint'
|
||
|
});
|
||
|
|
||
|
L.Filter.disjoint = function(options) {
|
||
|
return new L.Filter.Disjoint(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Touches = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Touches'
|
||
|
});
|
||
|
|
||
|
L.Filter.touches = function(options) {
|
||
|
return new L.Filter.Touches(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Within = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Within'
|
||
|
});
|
||
|
|
||
|
L.Filter.within = function(options) {
|
||
|
return new L.Filter.Within(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Overlaps = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Overlaps'
|
||
|
});
|
||
|
|
||
|
L.Filter.overlaps = function(options) {
|
||
|
return new L.Filter.Overlaps(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Crosses = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Crosses'
|
||
|
});
|
||
|
|
||
|
L.Filter.crosses = function(options) {
|
||
|
return new L.Filter.Crosses(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Intersects = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Intersects'
|
||
|
});
|
||
|
|
||
|
L.Filter.intersects = function(options) {
|
||
|
return new L.Filter.Intersects(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.Contains = L.Filter.BinarySpatial.extend({
|
||
|
tagName: 'ogc:Contains'
|
||
|
});
|
||
|
|
||
|
L.Filter.contains = function(options) {
|
||
|
return new L.Filter.Contains(options);
|
||
|
};
|
||
|
|
||
|
L.Filter.DistanceBuffer = L.Filter.Abstract.extend({
|
||
|
initialize: function (propertyName, geometry, crs, distance, units) {
|
||
|
this.propertyName = propertyName;
|
||
|
this.geomerty = geometry;
|
||
|
this.crs = crs;
|
||
|
this.distance = distance;
|
||
|
this.units = units;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
filterElement.appendChild(L.Filter.propertyName(this.propertyName));
|
||
|
filterElement.appendChild(this.geomerty.toGml(this.crs));
|
||
|
filterElement.appendChild(L.XmlUtil.createElementNS('ogc:Distance', { 'units': this.units }, { value: this.distance }));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.DWithin = L.Filter.DistanceBuffer.extend({
|
||
|
tagName: 'ogc:DWithin'
|
||
|
});
|
||
|
|
||
|
L.Filter.dwithin = function(propertyName, geometry, crs, distance, units) {
|
||
|
return new L.Filter.DWithin(propertyName, geometry, crs, distance, units);
|
||
|
};
|
||
|
|
||
|
L.Filter.Beyond = L.Filter.DistanceBuffer.extend({
|
||
|
tagName: 'ogc:Beyond'
|
||
|
});
|
||
|
|
||
|
L.Filter.beyond = function(propertyName, geometry, crs, distance, units) {
|
||
|
return new L.Filter.Beyond(propertyName, geometry, crs, distance, units);
|
||
|
};
|
||
|
|
||
|
L.Filter.BBox = L.Filter.Abstract.extend({
|
||
|
tagName: 'ogc:BBOX',
|
||
|
|
||
|
geometryField: null,
|
||
|
|
||
|
bbox: null,
|
||
|
|
||
|
crs: null,
|
||
|
|
||
|
initialize: function (geometryField, bbox, crs) {
|
||
|
this.bbox = bbox;
|
||
|
this.geometryField = geometryField;
|
||
|
this.crs = crs;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
if (this.geometryField) {
|
||
|
filterElement.appendChild(L.Filter.propertyName(this.geometryField));
|
||
|
}
|
||
|
|
||
|
filterElement.appendChild(this.bbox.toGml(this.crs));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.bbox = function (geometryField, bbox, crs) {
|
||
|
return new L.Filter.BBox(geometryField, bbox, crs);
|
||
|
};
|
||
|
|
||
|
L.Filter.GmlObjectID = L.Filter.Abstract.extend({
|
||
|
tagName: 'ogc:GmlObjectId',
|
||
|
|
||
|
initialize: function (id) {
|
||
|
this.attributes = { 'gml:id': id };
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function() {
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.gmlobjectid = function(id) {
|
||
|
return new L.Filter.GmlObjectID(id);
|
||
|
};
|
||
|
|
||
|
L.Filter.BinaryOperator = L.Filter.Abstract.extend({
|
||
|
initialize: function (firstValue, secondValue) {
|
||
|
this.firstValue = firstValue;
|
||
|
this.secondValue = secondValue;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
filterElement.appendChild(L.Filter.propertyElement(this.firstValue));
|
||
|
filterElement.appendChild(L.Filter.literalElement(this.secondValue));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.Add = L.Filter.BinaryOperator.extend({
|
||
|
tagName: 'Add'
|
||
|
});
|
||
|
|
||
|
L.Filter.add = function(a, b) {
|
||
|
return new L.Filter.Add(a, b);
|
||
|
};
|
||
|
|
||
|
L.Filter.Sub = L.Filter.BinaryOperator.extend({
|
||
|
tagName: 'Sub'
|
||
|
});
|
||
|
|
||
|
L.Filter.sub = function(a, b) {
|
||
|
return new L.Filter.Sub(a, b);
|
||
|
};
|
||
|
|
||
|
L.Filter.Mul = L.Filter.BinaryOperator.extend({
|
||
|
tagName: 'Mul'
|
||
|
});
|
||
|
|
||
|
L.Filter.mul = function(a, b) {
|
||
|
return new L.Filter.Mul(a, b);
|
||
|
};
|
||
|
|
||
|
L.Filter.Div = L.Filter.BinaryOperator.extend({
|
||
|
tagName: 'Div'
|
||
|
});
|
||
|
|
||
|
L.Filter.div = function(a, b) {
|
||
|
return new L.Filter.Div(a, b);
|
||
|
};
|
||
|
|
||
|
L.Filter.BinaryComparison = L.Filter.BinaryOperator.extend({
|
||
|
matchCase: false,
|
||
|
|
||
|
initialize: function(firstValue, secondValue, matchCase) {
|
||
|
L.Filter.BinaryOperator.prototype.initialize.call(this, firstValue, secondValue);
|
||
|
this.attributes = { matchCase: !!matchCase };
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.EQ = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsEqualTo'
|
||
|
});
|
||
|
|
||
|
L.Filter.eq = function(firstValue, secondValue) {
|
||
|
return new L.Filter.EQ(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.NotEQ = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsNotEqualTo'
|
||
|
});
|
||
|
|
||
|
L.Filter.neq = function(firstValue, secondValue) {
|
||
|
return new L.Filter.NotEQ(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.LT = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsLessThan'
|
||
|
});
|
||
|
|
||
|
L.Filter.lt = function(firstValue, secondValue) {
|
||
|
return new L.Filter.LT(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.GT = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsGreaterThan'
|
||
|
});
|
||
|
|
||
|
L.Filter.gt = function(firstValue, secondValue) {
|
||
|
return new L.Filter.GT(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.LEQ = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsLessThanOrEqualTo'
|
||
|
});
|
||
|
|
||
|
L.Filter.leq = function(firstValue, secondValue) {
|
||
|
return new L.Filter.LEQ(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.GEQ = L.Filter.BinaryComparison.extend({
|
||
|
tagName: 'ogc:PropertyIsGreaterThanOrEqualTo'
|
||
|
});
|
||
|
|
||
|
L.Filter.geq = function(firstValue, secondValue) {
|
||
|
return new L.Filter.GEQ(firstValue, secondValue);
|
||
|
};
|
||
|
|
||
|
L.Filter.Like = L.Filter.Abstract.extend({
|
||
|
tagName: 'ogc:PropertyIsLike',
|
||
|
|
||
|
wildCard: '*',
|
||
|
singleChar: '#',
|
||
|
escapeChar: '!',
|
||
|
matchCase: true,
|
||
|
|
||
|
initialize: function (name, val, attributes) {
|
||
|
this.name = name;
|
||
|
this.val = val;
|
||
|
var defaultAttributes = { wildCard: this.wildCard, singleChar: this.singleChar, escapeChar: this.escapeChar, matchCase: this.matchCase };
|
||
|
this.attributes = L.extend(defaultAttributes, attributes || {});
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
var nameElement = L.Filter.propertyName(this.name);
|
||
|
var valueElement = L.Filter.literal(this.val);
|
||
|
filterElement.appendChild(nameElement);
|
||
|
filterElement.appendChild(valueElement);
|
||
|
return filterElement;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.like = function(name, val, attributes) {
|
||
|
return new L.Filter.Like(name, val, attributes);
|
||
|
};
|
||
|
|
||
|
L.Filter.IsNull = L.Filter.Abstract.extend({
|
||
|
tagName: 'ogc:PropertyIsNull',
|
||
|
|
||
|
initialize: function (propertyName) {
|
||
|
this.propertyName = propertyName;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
filterElement.appendChild(L.Filter.propertyName(this.propertyName));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.isnull = function(propertyName) {
|
||
|
return new L.Filter.IsNull(propertyName);
|
||
|
};
|
||
|
|
||
|
L.Filter.IsBetween = L.Filter.Abstract.extend({
|
||
|
tagName: 'ogc:PropertyIsBetween',
|
||
|
|
||
|
initialize: function (property, lowerBoundary, upperBoundary) {
|
||
|
this.property = property;
|
||
|
this.lowerBoundary = lowerBoundary;
|
||
|
this.upperBoundary = upperBoundary;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
filterElement.appendChild(L.Filter.propertyElement(this.property));
|
||
|
|
||
|
var lowerBoundaryElement = L.XmlUtil.createElementNS('ogc:LowerBoundary');
|
||
|
lowerBoundaryElement.appendChild(L.Filter.literalElement(this.lowerBoundary));
|
||
|
|
||
|
filterElement.appendChild(lowerBoundaryElement);
|
||
|
|
||
|
var upperBoundaryElement = L.XmlUtil.createElementNS('ogc:UpperBoundary');
|
||
|
upperBoundaryElement.appendChild(L.Filter.literalElement(this.upperBoundary));
|
||
|
|
||
|
filterElement.appendChild(upperBoundaryElement);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.isbetween = function(property, lowerBoundary, upperBoundary) {
|
||
|
return new L.Filter.IsBetween(property, lowerBoundary, upperBoundary);
|
||
|
};
|
||
|
|
||
|
L.Filter.BinaryLogic = L.Filter.Abstract.extend({
|
||
|
filters: null,
|
||
|
|
||
|
initialize: function () {
|
||
|
var filters = [];
|
||
|
for (var i = 0; i < arguments.length; i++) {
|
||
|
filters.push(arguments[i]);
|
||
|
}
|
||
|
|
||
|
this.filters = filters;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
this.filters.forEach(function(filter) {
|
||
|
filterElement.appendChild(L.Filter.element(filter));
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.And = L.Filter.BinaryLogic.extend({
|
||
|
tagName: 'And'
|
||
|
});
|
||
|
|
||
|
L.Filter.and = function() {
|
||
|
return new (Function.prototype.bind.apply(L.Filter.And, arguments))();
|
||
|
};
|
||
|
|
||
|
L.Filter.Or = L.Filter.BinaryLogic.extend({
|
||
|
tagName: 'Or'
|
||
|
});
|
||
|
|
||
|
L.Filter.or = function() {
|
||
|
return new (Function.prototype.bind.apply(L.Filter.Or, arguments))();
|
||
|
};
|
||
|
|
||
|
L.Filter.Not = L.Filter.Abstract.extend({
|
||
|
tagName: 'Not',
|
||
|
|
||
|
initialize: function(filter) {
|
||
|
this.filter = filter;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function(filterElement) {
|
||
|
filterElement.appendChild(L.Filter.element(this.filter));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.not = function(filter) {
|
||
|
return new L.Filter.Not(filter);
|
||
|
};
|
||
|
|
||
|
L.Filter.Function = L.Filter.Abstract.extend({
|
||
|
tagName: 'Function',
|
||
|
|
||
|
initialize: function () {
|
||
|
var functionName = arguments[0];
|
||
|
this.attributes = { name: functionName };
|
||
|
var expressions = [];
|
||
|
for (var i = 1; i < arguments.length; i++) {
|
||
|
expressions.push(arguments[i]);
|
||
|
}
|
||
|
|
||
|
this.expressions = expressions;
|
||
|
},
|
||
|
|
||
|
buildFilterContent: function (filterElement) {
|
||
|
var firstArgument = this.expressions[0];
|
||
|
filterElement.appendChild(L.Filter.propertyElement(firstArgument));
|
||
|
|
||
|
for (var i = 1; i < this.expressions.length; i++) {
|
||
|
var functionArgument = this.expressions[i];
|
||
|
filterElement.appendChild(L.Filter.literalElement(functionArgument));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Filter.function = function() {
|
||
|
return new (Function.prototype.bind.apply(L.Filter.Function, arguments))();
|
||
|
};
|
||
|
|
||
|
L.Format = {};
|
||
|
|
||
|
L.Format.Scheme = L.Class.extend({
|
||
|
options: {
|
||
|
geometryField: 'Shape',
|
||
|
},
|
||
|
|
||
|
initialize: function (options) {
|
||
|
L.setOptions(this, options);
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
var featureType = new L.GML.FeatureType({
|
||
|
geometryField: this.options.geometryField
|
||
|
});
|
||
|
var complexTypeDefinition = element.getElementsByTagNameNS(L.XmlUtil.namespaces.xsd, 'complexType')[0];
|
||
|
var properties = complexTypeDefinition.getElementsByTagNameNS(L.XmlUtil.namespaces.xsd, 'sequence')[0];
|
||
|
for (var i = 0; i < properties.childNodes.length; i++) {
|
||
|
var node = properties.childNodes[i];
|
||
|
if (node.nodeType !== document.ELEMENT_NODE) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var propertyAttr = node.attributes.name;
|
||
|
if (!propertyAttr) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var propertyName = node.attributes.name.value;
|
||
|
|
||
|
var typeAttr = node.attributes.type;
|
||
|
if (!typeAttr) {
|
||
|
var restriction = node.getElementsByTagNameNS(L.XmlUtil.namespaces.xsd, 'restriction');
|
||
|
typeAttr = restriction.attributes.base;
|
||
|
}
|
||
|
|
||
|
if (!typeAttr) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var typeName = typeAttr.value.split(':').pop();
|
||
|
|
||
|
if (propertyName === this.options.geometryField) {
|
||
|
featureType.geometryFields[propertyName] = typeName;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
featureType.appendField(propertyName, typeName);
|
||
|
}
|
||
|
|
||
|
return featureType;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Format.Base = L.Class.extend({
|
||
|
defaultOptions: {
|
||
|
crs: L.CRS.EPSG3857,
|
||
|
coordsToLatLng: function (coords) {
|
||
|
return new L.LatLng(coords[1], coords[0], coords[2]);
|
||
|
},
|
||
|
latLngToCoords: function (latlng) {
|
||
|
var coords = [latlng.lng, latlng.lat];
|
||
|
if (latlng.alt !== undefined) {
|
||
|
coords.push(latlng.alt);
|
||
|
}
|
||
|
return coords;
|
||
|
},
|
||
|
geometryField: 'Shape'
|
||
|
},
|
||
|
|
||
|
initialize: function (options) {
|
||
|
L.setOptions(this, L.extend({}, this.defaultOptions, options));
|
||
|
if (options.crs) {
|
||
|
var crs = options.crs;
|
||
|
this.options.coordsToLatLng = function (coords) {
|
||
|
var point = L.point(coords[0], coords[1]);
|
||
|
var ll = crs.projection.unproject(point);
|
||
|
if (coords[2]) {
|
||
|
ll.alt = coords[2];
|
||
|
}
|
||
|
return ll;
|
||
|
};
|
||
|
this.options.latLngToCoords = function (ll) {
|
||
|
var latLng = L.latLng(ll);
|
||
|
return crs.projection.project(latLng);
|
||
|
};
|
||
|
}
|
||
|
},
|
||
|
|
||
|
setFeatureDescription: function (featureInfo) {
|
||
|
this.namespaceUri = featureInfo.attributes.targetNamespace.value;
|
||
|
var schemeParser = new L.Format.Scheme({
|
||
|
geometryField: this.options.geometryField
|
||
|
});
|
||
|
this.featureType = schemeParser.parse(featureInfo);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Format.GeoJSON = L.Format.Base.extend({
|
||
|
|
||
|
initialize: function (options) {
|
||
|
L.Format.Base.prototype.initialize.call(this, options);
|
||
|
this.outputFormat = 'application/json';
|
||
|
},
|
||
|
|
||
|
responseToLayers: function (rawData) {
|
||
|
var layers = [];
|
||
|
var geoJson = JSON.parse(rawData);
|
||
|
|
||
|
for (var i = 0; i < geoJson.features.length; i++) {
|
||
|
var layer = this.processFeature(geoJson.features[i]);
|
||
|
if (layer) {
|
||
|
layers.push(layer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return layers;
|
||
|
},
|
||
|
|
||
|
processFeature: function (feature) {
|
||
|
var layer = this.generateLayer(feature);
|
||
|
if (!layer) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
layer.feature = feature;
|
||
|
return layer;
|
||
|
},
|
||
|
|
||
|
generateLayer: function (feature) {
|
||
|
var layer = L.GeoJSON.geometryToLayer(feature, this.options || null);
|
||
|
if (!layer) {
|
||
|
console.log(
|
||
|
'Geometry field doesn\' exist inside received feature: \'' + feature + '\', ' +
|
||
|
'so feature will be skipped and won\'t be converted into leaflet layer');
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML = L.GML || {};
|
||
|
|
||
|
L.GML.ParserContainerMixin = {
|
||
|
|
||
|
parsers: {},
|
||
|
|
||
|
initializeParserContainer: function () {
|
||
|
this.parsers = {};
|
||
|
},
|
||
|
|
||
|
appendParser: function (parser) {
|
||
|
this.parsers[parser.elementTag] = parser;
|
||
|
},
|
||
|
|
||
|
parseElement: function (element, options) {
|
||
|
var parser = this.parsers[element.tagName];
|
||
|
if (!parser) throw('unknown child element ' + element.tagName);
|
||
|
|
||
|
return parser.parse(element, options);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
L.GML.Element = L.Class.extend({
|
||
|
elementTag: '',
|
||
|
parse: function () {
|
||
|
throw('not implemented parse function in parser for ' + this.elementTag);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.Geometry = L.GML.Element.extend({
|
||
|
statics: {
|
||
|
DIM: 2
|
||
|
},
|
||
|
|
||
|
dimensions: function (element) {
|
||
|
if (element.attributes.srsDimension) {
|
||
|
return parseInt(element.attributes.srsDimension.value);
|
||
|
}
|
||
|
|
||
|
return L.GML.Geometry.DIM;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.Coordinates = L.GML.Element.extend({
|
||
|
|
||
|
defaultSeparator: {
|
||
|
ds: '.', //decimal separator
|
||
|
cs: ',', // component separator
|
||
|
ts: ' ' // tuple separator
|
||
|
},
|
||
|
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:coordinates';
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
|
||
|
var ds = this.defaultSeparator.ds;
|
||
|
if (element.attributes.decimal) {
|
||
|
ds = element.attributes.decimal.value;
|
||
|
}
|
||
|
|
||
|
var cs = this.defaultSeparator.cs;
|
||
|
if (element.attributes.cs) {
|
||
|
cs = element.attributes.cs.value;
|
||
|
}
|
||
|
|
||
|
var ts = this.defaultSeparator.ts;
|
||
|
if (element.attributes.ts) {
|
||
|
ts = element.attributes.ts.value;
|
||
|
}
|
||
|
|
||
|
var result = [];
|
||
|
var coords = element.textContent.split(ts);
|
||
|
|
||
|
var mapFunction = function (coord) {
|
||
|
if (ds !== '.') {
|
||
|
coord = coord.replace(ds, '.');
|
||
|
}
|
||
|
|
||
|
return parseFloat(coord);
|
||
|
};
|
||
|
|
||
|
for (var i = 0; i < coords.length; i++) {
|
||
|
result.push(coords[i].split(cs).map(mapFunction));
|
||
|
}
|
||
|
|
||
|
if (result.length === 1) {
|
||
|
return result[0];
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.Pos = L.GML.Element.extend({
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:pos';
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
return element.textContent.split(' ').map(function (coord) {
|
||
|
return parseFloat(coord);
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.PosList = L.GML.Element.extend({
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:posList';
|
||
|
},
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var result = [];
|
||
|
var dim = options.dimensions;
|
||
|
var coords = element.textContent.split(' ');
|
||
|
for (var i = 0; i < coords.length; i += dim) {
|
||
|
var coord = [];
|
||
|
for (var j = i; j < i + dim; j++) {
|
||
|
coord.push(parseFloat(coords[j]));
|
||
|
}
|
||
|
result.push(coord);
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.PointNode = L.GML.Geometry.extend({
|
||
|
includes: L.GML.ParserContainerMixin,
|
||
|
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:Point';
|
||
|
this.initializeParserContainer();
|
||
|
this.appendParser(new L.GML.Pos());
|
||
|
this.appendParser(new L.GML.Coordinates());
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
return this.parseElement(element.firstChild, {dimensions: this.dimensions(element)});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.PointSequence = L.GML.Geometry.extend({
|
||
|
includes: L.GML.ParserContainerMixin,
|
||
|
|
||
|
initialize: function () {
|
||
|
this.initializeParserContainer();
|
||
|
this.appendParser(new L.GML.Pos());
|
||
|
this.appendParser(new L.GML.PosList());
|
||
|
this.appendParser(new L.GML.Coordinates());
|
||
|
this.appendParser(new L.GML.PointNode());
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
var firstChild = element.firstChild;
|
||
|
var coords = [];
|
||
|
var tagName = firstChild.tagName;
|
||
|
if (tagName === 'gml:pos' || tagName === 'gml:Point') {
|
||
|
var childParser = this.parsers[tagName];
|
||
|
var elements = element.getElementsByTagNameNS(L.XmlUtil.namespaces.gml, tagName.split(':').pop());
|
||
|
for (var i = 0; i < elements.length; i++) {
|
||
|
coords.push(childParser.parse(elements[i]));
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
coords = this.parseElement(firstChild, {dimensions: this.dimensions(element)});
|
||
|
}
|
||
|
|
||
|
return coords;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.LinearRing = L.GML.PointSequence.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.PointSequence.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:LinearRing';
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
var coords = L.GML.PointSequence.prototype.parse.call(this, element);
|
||
|
//for leaflet polygons its not recommended insert additional last point equal to the first one
|
||
|
coords.pop();
|
||
|
return coords;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.LineStringNode = L.GML.PointSequence.extend({
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:LineString';
|
||
|
L.GML.PointSequence.prototype.initialize.call(this);
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
return L.GML.PointSequence.prototype.parse.call(this, element);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.PolygonNode = L.GML.Geometry.extend({
|
||
|
|
||
|
initialize: function () {
|
||
|
this.elementTag = 'gml:Polygon';
|
||
|
this.linearRingParser = new L.GML.LinearRing();
|
||
|
},
|
||
|
|
||
|
parse: function (element) {
|
||
|
var coords = [];
|
||
|
for (var i = 0; i < element.childNodes.length; i++) {
|
||
|
//there can be exterior and interior, by GML standard and for leaflet its not significant
|
||
|
var child = element.childNodes[i];
|
||
|
if (child.nodeType === document.ELEMENT_NODE) {
|
||
|
coords.push(this.linearRingParser.parse(child.firstChild));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return coords;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.CoordsToLatLngMixin = {
|
||
|
transform: function (coordinates, options) {
|
||
|
if (Array.isArray(coordinates[0])) {
|
||
|
var latLngs = [];
|
||
|
for (var i = 0; i < coordinates.length; i++) {
|
||
|
latLngs.push(this.transform(coordinates[i], options));
|
||
|
}
|
||
|
|
||
|
return latLngs;
|
||
|
}
|
||
|
|
||
|
return options.coordsToLatLng(coordinates);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
L.GML.Point = L.GML.PointNode.extend({
|
||
|
includes: L.GML.CoordsToLatLngMixin,
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var coords = L.GML.PointNode.prototype.parse.call(this, element);
|
||
|
var layer = new L.Marker();
|
||
|
layer.setLatLng(this.transform(coords, options));
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.LineString = L.GML.LineStringNode.extend({
|
||
|
|
||
|
includes: L.GML.CoordsToLatLngMixin,
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var layer = new L.Polyline([]);
|
||
|
var coordinates = L.GML.LineStringNode.prototype.parse.call(this, element);
|
||
|
layer.setLatLngs(this.transform(coordinates, options));
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.Polygon = L.GML.PolygonNode.extend({
|
||
|
|
||
|
includes: L.GML.CoordsToLatLngMixin,
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var layer = new L.Polygon([]);
|
||
|
var coordinates = L.GML.PolygonNode.prototype.parse.call(this, element);
|
||
|
layer.setLatLngs(this.transform(coordinates, options));
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiGeometry = L.GML.Geometry.extend({
|
||
|
includes: [L.GML.ParserContainerMixin, L.GML.CoordsToLatLngMixin],
|
||
|
|
||
|
initialize: function () {
|
||
|
this.initializeParserContainer();
|
||
|
},
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var childObjects = [];
|
||
|
for (var i = 0; i < element.childNodes.length; i++) {
|
||
|
var geometryMember = element.childNodes[i];
|
||
|
if (geometryMember.nodeType !== document.ELEMENT_NODE) continue;
|
||
|
|
||
|
for (var j = 0; j < geometryMember.childNodes.length; j++) {
|
||
|
var singleGeometry = geometryMember.childNodes[j];
|
||
|
if (singleGeometry.nodeType !== document.ELEMENT_NODE) continue;
|
||
|
|
||
|
childObjects.push(this.parseElement(singleGeometry, options));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return this.transform(childObjects, options);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.AbstractMultiPolyline = L.GML.MultiGeometry.extend({
|
||
|
|
||
|
initialize: function () {
|
||
|
L.GML.MultiGeometry.prototype.initialize.call(this);
|
||
|
this.appendParser(new L.GML.LineStringNode());
|
||
|
},
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var latLngs = L.GML.MultiGeometry.prototype.parse.call(this, element, options);
|
||
|
var layer = new L.Polyline([]);
|
||
|
layer.setLatLngs(latLngs);
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.AbstractMultiPolygon = L.GML.MultiGeometry.extend({
|
||
|
|
||
|
initialize: function () {
|
||
|
L.GML.MultiGeometry.prototype.initialize.call(this);
|
||
|
this.appendParser(new L.GML.PolygonNode());
|
||
|
},
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var latLngs = L.GML.MultiGeometry.prototype.parse.call(this, element, options);
|
||
|
var layer = new L.Polygon([]);
|
||
|
layer.setLatLngs(latLngs);
|
||
|
return layer;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiLineString = L.GML.AbstractMultiPolyline.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.AbstractMultiPolyline.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:MultiLineString';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiCurve = L.GML.AbstractMultiPolyline.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.AbstractMultiPolyline.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:MultiCurve';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiPolygon = L.GML.AbstractMultiPolygon.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.AbstractMultiPolygon.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:MultiPolygon';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiSurface = L.GML.AbstractMultiPolygon.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.AbstractMultiPolygon.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:MultiSurface';
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.MultiPoint = L.GML.MultiGeometry.extend({
|
||
|
initialize: function () {
|
||
|
L.GML.MultiGeometry.prototype.initialize.call(this);
|
||
|
this.elementTag = 'gml:MultiPoint';
|
||
|
this.appendParser(new L.GML.PointNode());
|
||
|
},
|
||
|
|
||
|
parse: function (element, options) {
|
||
|
var coordinates = L.GML.MultiGeometry.prototype.parse.call(this, element, options);
|
||
|
var multiPoint = new L.FeatureGroup();
|
||
|
for (var i = 0; i < coordinates.length; i++) {
|
||
|
var point = new L.Marker();
|
||
|
point.setLatLng(coordinates[i]);
|
||
|
multiPoint.addLayer(point);
|
||
|
}
|
||
|
|
||
|
return multiPoint;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.GML.FeatureType = L.Class.extend({
|
||
|
options: {
|
||
|
geometryField: 'Shape',
|
||
|
},
|
||
|
|
||
|
primitives: [
|
||
|
{
|
||
|
types: ['byte', 'short', 'int', 'integer', 'long', 'float', 'double', 'decimal'],
|
||
|
parse: function (input) {
|
||
|
if (input === 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
input = String.prototype.trim.call(input || '');
|
||
|
return input === '' ? null : Number(input);
|
||
|
},
|
||
|
validate: function (parsedValue) {
|
||
|
// Invalid number can be detected by isNaN check.
|
||
|
return !isNaN(parsedValue);
|
||
|
},
|
||
|
type: 'number'
|
||
|
},
|
||
|
{
|
||
|
types: ['string'],
|
||
|
parse: function (input) {
|
||
|
return input;
|
||
|
},
|
||
|
validate: function (parsedValue) {
|
||
|
// Any value is valid for 'string' type.
|
||
|
return true;
|
||
|
},
|
||
|
type: 'string'
|
||
|
},
|
||
|
{
|
||
|
types: ['boolean'],
|
||
|
parse: function (input) {
|
||
|
input = String.prototype.trim.call(input || '').toLowerCase();
|
||
|
return input !== 'false';
|
||
|
},
|
||
|
validate: function (parsedValue) {
|
||
|
// Any value is valid for 'boolean' type if parser parses it like so: input !== 'false'.
|
||
|
return true;
|
||
|
},
|
||
|
type: 'boolean'
|
||
|
},
|
||
|
{
|
||
|
types: ['date', 'time', 'datetime'],
|
||
|
parse: function (input) {
|
||
|
input = String.prototype.trim.call(input || '');
|
||
|
return input === '' ? null : new Date(input);
|
||
|
},
|
||
|
validate: function (parsedValue) {
|
||
|
// Invalid date also can be detected by isNaN check.
|
||
|
return !isNaN(parsedValue);
|
||
|
},
|
||
|
type: 'date'
|
||
|
}
|
||
|
],
|
||
|
|
||
|
initialize: function (options) {
|
||
|
L.setOptions(this, options);
|
||
|
|
||
|
this.fields = {};
|
||
|
this.fieldValidators = {};
|
||
|
this.fieldTypes = {};
|
||
|
this.geometryFields = {};
|
||
|
},
|
||
|
|
||
|
appendField: function (name, type) {
|
||
|
var that = this;
|
||
|
type = String.prototype.toLowerCase.call(type || '');
|
||
|
|
||
|
this.primitives.forEach(function (primitive) {
|
||
|
if (primitive.types.indexOf(type) !== -1) {
|
||
|
that.fields[name] = primitive.parse;
|
||
|
that.fieldValidators[name] = primitive.validate;
|
||
|
that.fieldTypes[name] = primitive.type;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
parse: function (feature) {
|
||
|
var properties = {};
|
||
|
for (var i = 0; i < feature.childNodes.length; i++) {
|
||
|
var node = feature.childNodes[i];
|
||
|
if (node.nodeType !== document.ELEMENT_NODE) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var propertyName = node.tagName.split(':').pop();
|
||
|
if (propertyName === this.options.geometryField) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var parseField = this.fields[propertyName];
|
||
|
if (!parseField) {
|
||
|
this.appendField(propertyName, 'string');
|
||
|
parseField = this.fields[propertyName];
|
||
|
}
|
||
|
|
||
|
properties[propertyName] = parseField(node.textContent);
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
type: 'Feature',
|
||
|
properties: properties,
|
||
|
id: feature.attributes['gml:id'].value
|
||
|
};
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Format.GML = L.Format.Base.extend({
|
||
|
|
||
|
includes: L.GML.ParserContainerMixin,
|
||
|
|
||
|
initialize: function (options) {
|
||
|
L.Format.Base.prototype.initialize.call(this, options);
|
||
|
this.outputFormat = 'text/xml; subtype=gml/3.1.1';
|
||
|
this.initializeParserContainer();
|
||
|
this.appendParser(new L.GML.Point());
|
||
|
this.appendParser(new L.GML.LineString());
|
||
|
this.appendParser(new L.GML.Polygon());
|
||
|
this.appendParser(new L.GML.MultiLineString());
|
||
|
this.appendParser(new L.GML.MultiPolygon());
|
||
|
this.appendParser(new L.GML.MultiCurve());
|
||
|
this.appendParser(new L.GML.MultiSurface());
|
||
|
this.appendParser(new L.GML.MultiPoint());
|
||
|
},
|
||
|
|
||
|
responseToLayers: function (rawData) {
|
||
|
var layers = [];
|
||
|
var xmlDoc = L.XmlUtil.parseXml(rawData);
|
||
|
var featureCollection = xmlDoc.documentElement;
|
||
|
var featureMemberNodes = featureCollection.getElementsByTagNameNS(L.XmlUtil.namespaces.gml, 'featureMember');
|
||
|
for (var i = 0; i < featureMemberNodes.length; i++) {
|
||
|
var feature = featureMemberNodes[i].firstChild;
|
||
|
var featureAsLayer = this.processFeature(feature);
|
||
|
if (featureAsLayer) {
|
||
|
layers.push(featureAsLayer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var featureMembersNode = featureCollection.getElementsByTagNameNS(L.XmlUtil.namespaces.gml, 'featureMembers');
|
||
|
if (featureMembersNode.length > 0) {
|
||
|
var features = featureMembersNode[0].childNodes;
|
||
|
for (var j = 0; j < features.length; j++) {
|
||
|
var node = features[j];
|
||
|
if (node.nodeType !== document.ELEMENT_NODE) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
var nodeAsLayer = this.processFeature(node);
|
||
|
if (nodeAsLayer) {
|
||
|
layers.push(nodeAsLayer);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return layers;
|
||
|
},
|
||
|
|
||
|
processFeature: function (feature) {
|
||
|
var layer = this.generateLayer(feature);
|
||
|
if (!layer) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
layer.feature = this.featureType.parse(feature);
|
||
|
return layer;
|
||
|
},
|
||
|
|
||
|
generateLayer: function (feature) {
|
||
|
var geometryField = feature.getElementsByTagNameNS(this.namespaceUri, this.options.geometryField)[0];
|
||
|
if (!geometryField) {
|
||
|
console.log(
|
||
|
'Geometry field \'' + this.options.geometryField + '\' doesn\' exist inside received feature: \'' + feature.innerHTML + '\', ' +
|
||
|
'so feature will be skipped and won\'t be converted into leaflet layer');
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return this.parseElement(geometryField.firstChild, this.options);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Util.project = function (crs, latlngs) {
|
||
|
if (L.Util.isArray(latlngs)) {
|
||
|
var result = [];
|
||
|
latlngs.forEach(function (latlng) {
|
||
|
result.push(L.Util.project(crs, latlng));
|
||
|
});
|
||
|
|
||
|
return result;
|
||
|
} else {
|
||
|
return crs.projection.project(latlngs);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// 1.0.1 <=> 1.1.0 <=> 1.2.0 compatibility.
|
||
|
L.Util.isFlat = L.LineUtil.isFlat || L.LineUtil._flat || L.Polyline._flat;
|
||
|
|
||
|
L.GmlUtil = {
|
||
|
posNode: function (coord) {
|
||
|
return L.XmlUtil.createElementNS('gml:pos', { srsDimension: 2 }, { value: coord.x + ' ' + coord.y });
|
||
|
},
|
||
|
|
||
|
posListNode: function (coords, close) {
|
||
|
var localcoords = [];
|
||
|
coords.forEach(function (coord) {
|
||
|
localcoords.push(coord.x + ' ' + coord.y);
|
||
|
});
|
||
|
if (close && coords.length > 0) {
|
||
|
var coord = coords[0];
|
||
|
localcoords.push(coord.x + ' ' + coord.y);
|
||
|
}
|
||
|
|
||
|
var posList = localcoords.join(' ');
|
||
|
return L.XmlUtil.createElementNS('gml:posList', {}, { value: posList });
|
||
|
}
|
||
|
};
|
||
|
|
||
|
L.CircleMarker.include({
|
||
|
toGml: function(crs) {
|
||
|
var node = L.XmlUtil.createElementNS('gml:Point', {srsName: crs.code});
|
||
|
node.appendChild(L.GmlUtil.posNode(L.Util.project(crs, this.getLatLng())));
|
||
|
return node;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.LatLngBounds.prototype.toGml = function (crs) {
|
||
|
var projectedSW = crs.project(this.getSouthWest());
|
||
|
var projectedNE = crs.project(this.getNorthEast());
|
||
|
|
||
|
var envelopeElement = L.XmlUtil.createElementNS('gml:Envelope', { srsName: crs.code });
|
||
|
envelopeElement.appendChild(L.XmlUtil.createElementNS('gml:lowerCorner', {}, { value: projectedSW.x + ' ' + projectedSW.y }));
|
||
|
envelopeElement.appendChild(L.XmlUtil.createElementNS('gml:upperCorner', {}, { value: projectedNE.x + ' ' + projectedNE.y }));
|
||
|
|
||
|
return envelopeElement;
|
||
|
};
|
||
|
|
||
|
L.Marker.include({
|
||
|
toGml: function (crs) {
|
||
|
var node = L.XmlUtil.createElementNS('gml:Point', {srsName: crs.code});
|
||
|
node.appendChild(L.GmlUtil.posNode(L.Util.project(crs, this.getLatLng())));
|
||
|
return node;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Polygon.include({
|
||
|
toGml: function (crs, forceMulti) {
|
||
|
var polygons = this.getLatLngs();
|
||
|
var gmlPolygons = [];
|
||
|
|
||
|
for (var i = 0; i < polygons.length; i++) {
|
||
|
var polygonCoordinates = polygons[i];
|
||
|
var flat = L.Util.isFlat(polygonCoordinates);
|
||
|
var node = L.XmlUtil.createElementNS('gml:Polygon', {srsName: crs.code, srsDimension: 2});
|
||
|
node.appendChild(L.XmlUtil.createElementNS('gml:exterior'))
|
||
|
.appendChild(L.XmlUtil.createElementNS('gml:LinearRing', {srsDimension: 2}))
|
||
|
.appendChild(L.GmlUtil.posListNode(L.Util.project(crs, flat ? polygonCoordinates : polygonCoordinates[0]), true));
|
||
|
|
||
|
if (!flat) {
|
||
|
for (var hole = 1; hole < polygonCoordinates.length; hole++) {
|
||
|
node.appendChild(L.XmlUtil.createElementNS('gml:interior'))
|
||
|
.appendChild(L.XmlUtil.createElementNS('gml:LinearRing', {srsDimension: 2}))
|
||
|
.appendChild(L.GmlUtil.posListNode(L.Util.project(crs, polygonCoordinates[hole]), true));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gmlPolygons.push(node);
|
||
|
}
|
||
|
|
||
|
if (gmlPolygons.length === 1 && !forceMulti) return gmlPolygons[0];
|
||
|
|
||
|
// else make multipolygon
|
||
|
var multi = L.XmlUtil.createElementNS('gml:MultiSurface', {srsName: crs.code, srsDimension: 2});
|
||
|
var collection = multi.appendChild(L.XmlUtil.createElementNS('gml:surfaceMembers'));
|
||
|
for (var p = 0; p < gmlPolygons.length; p++) {
|
||
|
collection.appendChild(gmlPolygons[p]);
|
||
|
}
|
||
|
|
||
|
return multi;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.Polyline.include({
|
||
|
_lineStringNode: function (crs, latlngs) {
|
||
|
var node = L.XmlUtil.createElementNS('gml:LineString', {srsName: crs.code, srsDimension: 2});
|
||
|
node.appendChild(L.GmlUtil.posListNode(L.Util.project(crs, latlngs), false));
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
toGml: function (crs, forceMulti) {
|
||
|
var latLngs = this.getLatLngs();
|
||
|
var gmlElements = [];
|
||
|
|
||
|
if (L.Util.isFlat(latLngs)) {
|
||
|
gmlElements.push(this._lineStringNode(crs, latLngs));
|
||
|
} else {
|
||
|
for (var i = 0; i < latLngs.length; i++) {
|
||
|
gmlElements.push(this._lineStringNode(crs, latLngs[i]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(gmlElements.length === 1 && !forceMulti) {
|
||
|
return gmlElements[0];
|
||
|
}
|
||
|
|
||
|
var multi = L.XmlUtil.createElementNS('gml:MultiCurve', {srsName: crs.code, srsDimension: 2});
|
||
|
var collection = multi.appendChild(L.XmlUtil.createElementNS('gml:curveMembers'));
|
||
|
for (var lines = 0; lines < gmlElements.length; lines++) {
|
||
|
collection.appendChild(gmlElements[lines]);
|
||
|
}
|
||
|
|
||
|
return multi;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var PropertiesMixin = {
|
||
|
setProperties: function (obj) {
|
||
|
for (var i in obj) {
|
||
|
if (obj.hasOwnProperty(i)) {
|
||
|
this.feature.properties[i] = obj[i];
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
getProperty: function (field) {
|
||
|
return this.feature.properties[field];
|
||
|
},
|
||
|
deleteProperties: function (arr) {
|
||
|
for (var i = 0; i < arr.length; i++) {
|
||
|
if (this.feature.properties.hasOwnProperty(arr[i])) {
|
||
|
delete this.feature.properties[arr[i]];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
L.Marker.include(PropertiesMixin);
|
||
|
L.Path.include(PropertiesMixin);
|
||
|
|
||
|
L.WFS = L.FeatureGroup.extend({
|
||
|
|
||
|
_capabilities: null,
|
||
|
|
||
|
_boundingBox: null,
|
||
|
|
||
|
options: {
|
||
|
crs: L.CRS.EPSG3857,
|
||
|
showExisting: true,
|
||
|
geometryField: 'Shape',
|
||
|
url: '',
|
||
|
version: '1.1.0',
|
||
|
typeNS: '',
|
||
|
typeName: '',
|
||
|
typeNSName: '',
|
||
|
maxFeatures: null,
|
||
|
filter: null,
|
||
|
opacity: 1,
|
||
|
fillOpacity: 1,
|
||
|
style: {
|
||
|
color: 'black',
|
||
|
weight: 1,
|
||
|
opacity: 1,
|
||
|
fillOpacity: 1
|
||
|
},
|
||
|
namespaceUri: ''
|
||
|
},
|
||
|
|
||
|
state: {},
|
||
|
|
||
|
initialize: function (options, readFormat) {
|
||
|
L.setOptions(this, options);
|
||
|
|
||
|
this.state = {
|
||
|
exist: 'exist'
|
||
|
};
|
||
|
|
||
|
this._layers = {};
|
||
|
|
||
|
this.readFormat = readFormat || new L.Format.GML({
|
||
|
crs: this.options.crs,
|
||
|
geometryField: this.options.geometryField
|
||
|
});
|
||
|
|
||
|
this.options.typeNSName = this.namespaceName(this.options.typeName);
|
||
|
this.options.srsName = this.options.crs.code;
|
||
|
|
||
|
this._updateOpacity();
|
||
|
|
||
|
var that = this;
|
||
|
this.describeFeatureType(function () {
|
||
|
if (that.options.showExisting) {
|
||
|
that.loadFeatures(that.options.filter);
|
||
|
}
|
||
|
}, function (errorMessage) {
|
||
|
that.fire('error', {
|
||
|
error: new Error(errorMessage)
|
||
|
});
|
||
|
});
|
||
|
},
|
||
|
|
||
|
namespaceName: function (name) {
|
||
|
return this.options.typeNS + ':' + name;
|
||
|
},
|
||
|
|
||
|
describeFeatureType: function (successCallback, errorCallback) {
|
||
|
var requestData = L.XmlUtil.createElementNS('wfs:DescribeFeatureType', {
|
||
|
service: 'WFS',
|
||
|
version: this.options.version
|
||
|
});
|
||
|
requestData.appendChild(L.XmlUtil.createElementNS('TypeName', {}, {
|
||
|
value: this.options.typeNSName
|
||
|
}));
|
||
|
|
||
|
var that = this;
|
||
|
L.Util.request({
|
||
|
url: this.options.url,
|
||
|
data: L.XmlUtil.serializeXmlDocumentString(requestData),
|
||
|
headers: this.options.headers || {},
|
||
|
success: function (data) {
|
||
|
// If some exception occur, WFS-service can response successfully, but with ExceptionReport,
|
||
|
// and such situation must be handled.
|
||
|
var exceptionReport = L.XmlUtil.parseOwsExceptionReport(data);
|
||
|
if (exceptionReport) {
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(exceptionReport.message);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var xmldoc = L.XmlUtil.parseXml(data);
|
||
|
var featureInfo = xmldoc.documentElement;
|
||
|
that.readFormat.setFeatureDescription(featureInfo);
|
||
|
that.options.namespaceUri = featureInfo.attributes.targetNamespace.value;
|
||
|
if (typeof (successCallback) === 'function') {
|
||
|
successCallback();
|
||
|
}
|
||
|
},
|
||
|
error: function (errorMessage) {
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(errorMessage);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
getFeature: function (filter) {
|
||
|
var request = L.XmlUtil.createElementNS('wfs:GetFeature', {
|
||
|
service: 'WFS',
|
||
|
version: this.options.version,
|
||
|
maxFeatures: this.options.maxFeatures,
|
||
|
outputFormat: this.readFormat.outputFormat
|
||
|
});
|
||
|
|
||
|
var query = request.appendChild(L.XmlUtil.createElementNS('wfs:Query', {
|
||
|
typeName: this.options.typeNSName,
|
||
|
srsName: this.options.srsName
|
||
|
}));
|
||
|
|
||
|
if (filter) {
|
||
|
query.appendChild(L.filter(filter));
|
||
|
}
|
||
|
|
||
|
return request;
|
||
|
},
|
||
|
|
||
|
loadFeatures: function (filter) {
|
||
|
var that = this;
|
||
|
L.Util.request({
|
||
|
url: this.options.url,
|
||
|
data: L.XmlUtil.serializeXmlDocumentString(that.getFeature(filter)),
|
||
|
headers: this.options.headers || {},
|
||
|
success: function (responseText) {
|
||
|
// If some exception occur, WFS-service can response successfully, but with ExceptionReport,
|
||
|
// and such situation must be handled.
|
||
|
var exceptionReport = L.XmlUtil.parseOwsExceptionReport(responseText);
|
||
|
if (exceptionReport) {
|
||
|
that.fire('error', {
|
||
|
error: new Error(exceptionReport.message)
|
||
|
});
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
|
||
|
// Request was truly successful (without exception report),
|
||
|
// so convert response to layers.
|
||
|
var layers = that.readFormat.responseToLayers(responseText, {
|
||
|
coordsToLatLng: that.options.coordsToLatLng,
|
||
|
pointToLayer: that.options.pointToLayer
|
||
|
});
|
||
|
|
||
|
if (typeof that.options.style === "function") {
|
||
|
layers.forEach(function (element) {
|
||
|
element.state = that.state.exist;
|
||
|
if (element.setStyle) {
|
||
|
element.setStyle(that.options.style(element));
|
||
|
}
|
||
|
that.addLayer(element);
|
||
|
});
|
||
|
} else {
|
||
|
layers.forEach(function (element) {
|
||
|
element.state = that.state.exist;
|
||
|
that.addLayer(element);
|
||
|
});
|
||
|
that.setStyle(that.options.style);
|
||
|
}
|
||
|
|
||
|
that.fire('load', {
|
||
|
responseText: responseText
|
||
|
});
|
||
|
|
||
|
return that;
|
||
|
},
|
||
|
error: function (errorMessage) {
|
||
|
that.fire('error', {
|
||
|
error: new Error(errorMessage)
|
||
|
});
|
||
|
|
||
|
return that;
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
getCapabilities: function (successCallback, errorCallback) {
|
||
|
var capabilities = this._capabilities;
|
||
|
|
||
|
// Check if capabilities were already received & cached.
|
||
|
if (capabilities) {
|
||
|
if (typeof (successCallback) === 'function') {
|
||
|
successCallback(capabilities);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var requestData = L.XmlUtil.createElementNS('wfs:GetCapabilities', {
|
||
|
service: 'WFS',
|
||
|
version: this.options.version
|
||
|
});
|
||
|
|
||
|
var that = this;
|
||
|
L.Util.request({
|
||
|
url: this.options.url,
|
||
|
data: L.XmlUtil.serializeXmlDocumentString(requestData),
|
||
|
headers: this.options.headers || {},
|
||
|
success: function (data) {
|
||
|
// If some exception occur, WFS-service can response successfully, but with ExceptionReport,
|
||
|
// and such situation must be handled.
|
||
|
var exceptionReport = L.XmlUtil.parseOwsExceptionReport(data);
|
||
|
if (exceptionReport) {
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(new Error(exceptionReport.message));
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
// Request was truly successful (without exception report), parse WFS_Capabilities.
|
||
|
capabilities = L.XmlUtil.parseXml(data).documentElement;
|
||
|
} catch (error) {
|
||
|
// If parsing failed.
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(error);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Cache received capabilities.
|
||
|
that._capabilities = capabilities;
|
||
|
|
||
|
if (typeof (successCallback) === 'function') {
|
||
|
successCallback(capabilities);
|
||
|
}
|
||
|
},
|
||
|
error: function (errorMessage) {
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(new Error(errorMessage));
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
getBoundingBox: function (successCallback, errorCallback) {
|
||
|
var boundingBox = this._boundingBox;
|
||
|
|
||
|
// Check if bounding box was already received & cached.
|
||
|
if (boundingBox) {
|
||
|
if (typeof (successCallback) === 'function') {
|
||
|
successCallback(boundingBox);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var that = this;
|
||
|
this.getCapabilities(function (capabilities) {
|
||
|
var featureTypeListElement = capabilities.getElementsByTagName('FeatureTypeList')[0];
|
||
|
|
||
|
// Extract all 'FeatureType' nodes to list.
|
||
|
var featureTypeList = featureTypeListElement.getElementsByTagName('FeatureType');
|
||
|
|
||
|
for (var i = 0, len = featureTypeList.length; i < len; i++) {
|
||
|
var featureType = featureTypeList[i];
|
||
|
|
||
|
// Extract current FeatureType's name.
|
||
|
var featureTypeNSName = L.XmlUtil.getNodeText(featureType.getElementsByTagName('Name')[0]);
|
||
|
|
||
|
// Find node with current layer instance's name and namespace.
|
||
|
if (featureTypeNSName === that.options.typeNSName) {
|
||
|
// The <WGS84BoundingBox> element is used to indicate the edges of an
|
||
|
// enclosing rectangle in decimal degrees of latitude and longitude in WGS84.
|
||
|
var wgs84BoundingBox = featureType.getElementsByTagNameNS(L.XmlUtil.namespaces.ows, 'WGS84BoundingBox')[0];
|
||
|
var lowerCornerElement = wgs84BoundingBox.getElementsByTagNameNS(L.XmlUtil.namespaces.ows, 'LowerCorner')[0];
|
||
|
var upperCornerElement = wgs84BoundingBox.getElementsByTagNameNS(L.XmlUtil.namespaces.ows, 'UpperCorner')[0];
|
||
|
|
||
|
// Corner node's inner text format is like '-74.047185 40.679648', Lng and Lat with a space between.
|
||
|
var lowerCorner = L.XmlUtil.getNodeText(lowerCornerElement);
|
||
|
var upperCorner = L.XmlUtil.getNodeText(upperCornerElement);
|
||
|
|
||
|
// Extract LngLats and reverse it to LatLngs.
|
||
|
var sw = lowerCorner.split(' ').reverse();
|
||
|
var ne = upperCorner.split(' ').reverse();
|
||
|
|
||
|
// Wrap it into LatLngBounds.
|
||
|
boundingBox = L.latLngBounds([sw, ne]);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Cache received and calculated bounding box.
|
||
|
that._boundingBox = boundingBox;
|
||
|
|
||
|
if (typeof (successCallback) === 'function') {
|
||
|
successCallback(boundingBox);
|
||
|
}
|
||
|
}, function (errorMessage) {
|
||
|
if (typeof (errorCallback) === 'function') {
|
||
|
errorCallback(new Error(errorMessage));
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
setOpacity: function (opacity, fillOpacity) {
|
||
|
this.options.opacity = opacity;
|
||
|
this.options.fillOpacity = fillOpacity || opacity;
|
||
|
|
||
|
this._updateOpacity();
|
||
|
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
_updateOpacity: function () {
|
||
|
var style = L.extend(this.options.style || {}, {
|
||
|
opacity: this.options.opacity,
|
||
|
fillOpacity: this.options.fillOpacity
|
||
|
});
|
||
|
|
||
|
this.setStyle(style);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.wfs = function (options, readFormat) {
|
||
|
return new L.WFS(options, readFormat);
|
||
|
};
|
||
|
|
||
|
L.WFST = L.WFS.extend({
|
||
|
options: {
|
||
|
forceMulti: false
|
||
|
},
|
||
|
|
||
|
initialize: function (options, readFormat) {
|
||
|
L.WFS.prototype.initialize.call(this, options, readFormat);
|
||
|
this.state = L.extend(this.state, {
|
||
|
insert: 'insertElement',
|
||
|
update: 'updateElement',
|
||
|
remove: 'removeElement'
|
||
|
});
|
||
|
|
||
|
this.changes = {};
|
||
|
},
|
||
|
|
||
|
addLayer: function (layer) {
|
||
|
L.FeatureGroup.prototype.addLayer.call(this, layer);
|
||
|
if (!layer.feature) {
|
||
|
layer.feature = { properties: {} };
|
||
|
}
|
||
|
|
||
|
if (!layer.state) {
|
||
|
layer.state = this.state.insert;
|
||
|
var id = this.getLayerId(layer);
|
||
|
this.changes[id] = layer;
|
||
|
}
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
removeLayer: function (layer) {
|
||
|
L.FeatureGroup.prototype.removeLayer.call(this, layer);
|
||
|
|
||
|
var id = this.getLayerId(layer);
|
||
|
|
||
|
if (id in this.changes) {
|
||
|
var change = this.changes[id];
|
||
|
if (change.state === this.state.insert) {
|
||
|
delete this.changes[id];
|
||
|
}
|
||
|
else {
|
||
|
change.state = this.state.remove;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
layer.state = this.state.remove;
|
||
|
this.changes[id] = layer;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
editLayer: function (layer) {
|
||
|
if (layer.state !== this.state.insert) {
|
||
|
layer.state = this.state.update;
|
||
|
}
|
||
|
|
||
|
var id = this.getLayerId(layer);
|
||
|
this.changes[id] = layer;
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
save: function () {
|
||
|
var transaction = L.XmlUtil.createElementNS('wfs:Transaction', { service: 'WFS', version: this.options.version });
|
||
|
|
||
|
var inserted = [];
|
||
|
|
||
|
for (var id in this.changes) {
|
||
|
var layer = this.changes[id];
|
||
|
var action = this[layer.state](layer);
|
||
|
transaction.appendChild(action);
|
||
|
|
||
|
if (layer.state === this.state.insert) {
|
||
|
inserted.push(layer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var that = this;
|
||
|
|
||
|
L.Util.request({
|
||
|
url: this.options.url,
|
||
|
data: L.XmlUtil.serializeXmlDocumentString(transaction),
|
||
|
headers: this.options.headers || {},
|
||
|
withCredentials: true,
|
||
|
success: function (data) {
|
||
|
var xmlDoc = L.XmlUtil.parseXml(data);
|
||
|
var exception = L.XmlUtil.parseOwsExceptionReport(xmlDoc);
|
||
|
if(exception !== null) {
|
||
|
that.fire('save:failed', exception);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var insertResult = L.XmlUtil.evaluate('//wfs:InsertResults/wfs:Feature/ogc:FeatureId/@fid', xmlDoc);
|
||
|
var insertedIds = [];
|
||
|
var id = insertResult.iterateNext();
|
||
|
while (id) {
|
||
|
insertedIds.push(new L.Filter.GmlObjectID(id.value));
|
||
|
id = insertResult.iterateNext();
|
||
|
}
|
||
|
|
||
|
inserted.forEach(function (layer) {
|
||
|
L.FeatureGroup.prototype.removeLayer.call(that, layer);
|
||
|
});
|
||
|
|
||
|
that.once('load', function () {
|
||
|
that.fire('save:success');
|
||
|
that.changes = {};
|
||
|
});
|
||
|
|
||
|
that.loadFeatures(insertedIds);
|
||
|
},
|
||
|
error: function (data) {
|
||
|
that.fire('save:failed', data);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.wfst = function (options, readFormat) {
|
||
|
return new L.WFST(options, readFormat);
|
||
|
};
|
||
|
|
||
|
L.WFST.include({
|
||
|
gmlFeature: function (layer) {
|
||
|
var featureNode = L.XmlUtil.createElementNS(this.options.typeNSName, {}, { uri: this.options.namespaceUri });
|
||
|
var feature = layer.feature;
|
||
|
for (var propertyName in feature.properties) {
|
||
|
featureNode.appendChild(this.gmlProperty(propertyName,
|
||
|
feature.properties[propertyName]));
|
||
|
}
|
||
|
|
||
|
featureNode.appendChild(
|
||
|
this.gmlProperty(
|
||
|
this.options.geometryField,
|
||
|
layer.toGml(
|
||
|
this.options.crs,
|
||
|
this.options.forceMulti
|
||
|
)
|
||
|
)
|
||
|
);
|
||
|
|
||
|
return featureNode;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
Returns element with name as tag and value as innerText or child element
|
||
|
```xml
|
||
|
<name>value<name>
|
||
|
```
|
||
|
|
||
|
or if value is element
|
||
|
|
||
|
```xml
|
||
|
<name><value /><name>
|
||
|
```
|
||
|
|
||
|
@method gmlProperty
|
||
|
@param {string} name Name of property
|
||
|
@param {Object} value Value of property
|
||
|
@return {Element} simple property element <name>value<name>
|
||
|
*/
|
||
|
gmlProperty: function (name, value) {
|
||
|
var propertyNode = L.XmlUtil.createElementNS(this.namespaceName(name));
|
||
|
if (value instanceof Element) {
|
||
|
propertyNode.appendChild(value);
|
||
|
}
|
||
|
else if (value === null || value === undefined || value === '') {
|
||
|
L.XmlUtil.setAttributes(propertyNode, { 'xsi:nil': true });
|
||
|
} else {
|
||
|
propertyNode.appendChild(L.XmlUtil.createTextNode(value));
|
||
|
}
|
||
|
|
||
|
return propertyNode;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
Returns wfs:Property element with passed property name and value:
|
||
|
```xml
|
||
|
<wfs:Property>
|
||
|
<wfs:Name>%name%</wfs:Name>
|
||
|
<wfs:Value>%value%</wfs:Value>
|
||
|
</wfs:Property>
|
||
|
```
|
||
|
|
||
|
@method wfsProperty
|
||
|
@param {string} name Property name
|
||
|
@param {Object} value Property value, if passed Element object it will be added as child element of value
|
||
|
@return {Element}
|
||
|
*/
|
||
|
wfsProperty: function (name, value) {
|
||
|
var propertyNode = L.XmlUtil.createElementNS('wfs:Property');
|
||
|
propertyNode.appendChild(L.XmlUtil.createElementNS('wfs:Name', {}, { value: name }));
|
||
|
var valueNode = L.XmlUtil.createElementNS('wfs:Value');
|
||
|
if (value instanceof Element) {
|
||
|
valueNode.appendChild(value);
|
||
|
}
|
||
|
else {
|
||
|
valueNode.appendChild(L.XmlUtil.createTextNode(value));
|
||
|
}
|
||
|
|
||
|
propertyNode.appendChild(valueNode);
|
||
|
|
||
|
return propertyNode;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
L.WFST.include({
|
||
|
|
||
|
/**
|
||
|
Returns wfs:Insert element for passed layer
|
||
|
|
||
|
@method insertElement
|
||
|
@param {Layer} layer
|
||
|
@return {Element} wfs:Insert element with layer
|
||
|
*/
|
||
|
insertElement: function (layer) {
|
||
|
var node = L.XmlUtil.createElementNS('wfs:Insert');
|
||
|
node.appendChild(this.gmlFeature(layer));
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
Returns wfs:Update element for specified layer
|
||
|
|
||
|
@method updateElement
|
||
|
@param {Layer} layer
|
||
|
@return {Element} wfs:Update element for passed layer properties limited with filter by feature.id
|
||
|
*/
|
||
|
updateElement: function (layer) {
|
||
|
var node = L.XmlUtil.createElementNS('wfs:Update', { typeName: this.options.typeNSName });
|
||
|
var feature = layer.feature;
|
||
|
for (var propertyName in feature.properties) {
|
||
|
if (feature.properties.hasOwnProperty(propertyName)) {
|
||
|
node.appendChild(this.wfsProperty(propertyName, feature.properties[propertyName]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
node.appendChild(
|
||
|
this.wfsProperty(
|
||
|
this.namespaceName(this.options.geometryField),
|
||
|
layer.toGml(this.options.crs, this.options.forceMulti)
|
||
|
)
|
||
|
);
|
||
|
|
||
|
var idFilter = new L.Filter.GmlObjectID(layer.feature.id);
|
||
|
node.appendChild(L.filter(idFilter));
|
||
|
return node;
|
||
|
},
|
||
|
|
||
|
removeElement: function (layer) {
|
||
|
var node = L.XmlUtil.createElementNS('wfs:Delete', { typeName: this.options.typeNSName });
|
||
|
var idFilter = new L.Filter.GmlObjectID(layer.feature.id);
|
||
|
node.appendChild(L.filter(idFilter));
|
||
|
return node;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
})(window, document);
|