goog.provide('M.filter.spatial');
goog.require('M.filter.Spatial');
/**
* @namespace M.filter.spatial
*/
(function() {
/**
* This function creates a spatial filter to know which features contain another feature or layer
*
* @function
* @param {M.layer.Vector|object} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
* @api stable
*/
M.filter.spatial.CONTAIN = function(param) {
let geometries = M.filter.spatial.parseParamToGeometries(param);
return new M.filter.Spatial(function(geometryToFilter, index) {
let geojsonParser = new jsts.io.GeoJSONReader();
let jtsGeomToFilter = geojsonParser.read(geometryToFilter);
return geometries.some(geom => {
let jtsGeom = geojsonParser.read(geom);
return jtsGeomToFilter.contains(jtsGeom);
});
}, {
cqlFilter: M.filter.spatial.toCQLFilter_("CONTAINS", geometries)
});
};
/**
* This function creates a spatial filter to know which features disjoint another feature or layer
*
* @function
* @param {M.layer.Vector|object} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
* @api stable
*/
M.filter.spatial.DISJOINT = function(param) {
let geometries = M.filter.spatial.parseParamToGeometries(param);
return new M.filter.Spatial(function(geometryToFilter, index) {
let geojsonParser = new jsts.io.GeoJSONReader();
let jtsGeomToFilter = geojsonParser.read(geometryToFilter);
return geometries.some(geom => {
let jtsGeom = geojsonParser.read(geom);
return jtsGeomToFilter.disjoint(jtsGeom);
});
}, {
cqlFilter: M.filter.spatial.toCQLFilter_("DISJOINT", geometries)
});
};
/**
* This function creates a spatial filter to know which features within another feature or layer
*
* @function
* @param {M.layer.Vector|object} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
* @api stable
*/
M.filter.spatial.WITHIN = function(param) {
let geometries = M.filter.spatial.parseParamToGeometries(param);
return new M.filter.Spatial(function(geometryToFilter, index) {
let geojsonParser = new jsts.io.GeoJSONReader();
let jtsGeomToFilter = geojsonParser.read(geometryToFilter);
return geometries.some(geom => {
let jtsGeom = geojsonParser.read(geom);
return jtsGeomToFilter.within(jtsGeom);
});
}, {
cqlFilter: M.filter.spatial.toCQLFilter_("WITHIN", geometries)
});
};
/**
* This function creates a spatial filter to know which features intersects another feature or layer
*
* @function
* @param {M.layer.Vector|M.Feature|object|Array<M.Feature|object>} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
* @api stable
*/
M.filter.spatial.INTERSECT = function(param) {
let geometries = M.filter.spatial.parseParamToGeometries(param);
return new M.filter.Spatial(function(geometryToFilter, index) {
let geojsonParser = new jsts.io.GeoJSONReader();
let jtsGeomToFilter = geojsonParser.read(geometryToFilter);
return geometries.some(geom => {
let jtsGeom = geojsonParser.read(geom);
return jtsGeomToFilter.intersects(jtsGeom);
});
}, {
cqlFilter: M.filter.spatial.toCQLFilter_("INTERSECTS", geometries)
});
};
/**
* TODO
*
* @function
* @param {M.layer.Vector|M.Feature|object|Array<M.Feature|object>} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
* @api stable
*/
M.filter.spatial.parseParamToGeometries = function(param) {
let geometries = [];
if (param instanceof M.layer.Vector) {
geometries = [...param.getFeatures().map(feature => feature.getGeometry())];
}
else {
if (!M.utils.isArray(param)) {
param = [param];
}
geometries = param.map(p => {
let geom;
if (p instanceof M.Feature) {
geom = p.getGeometry();
}
else if (M.utils.isObject(p)) {
geom = p;
}
return geom;
});
}
return geometries;
};
/**
* TODO
*
* @private
* @function
* @param {M.layer.Vector|M.Feature|object|Array<M.Feature|object>} param - Layer or geometry on which the query is performed
* @return {M.filter.Spatial} Space filter
*/
M.filter.spatial.toCQLFilter_ = function(operation, geometries) {
let cqlFilter = "";
let wktFormat = new M.format.WKT();
for (let i = 0; i < geometries.length; i++) {
if (i !== 0) {
// es un OR porque se hace una interseccion completa con todas
// las geometries
cqlFilter += " OR ";
}
let geometry = geometries[i];
if (geometry.type.toLowerCase() === "point") {
geometry.coordinates.length = 2;
}
cqlFilter += operation + "({{geometryName}}, " + wktFormat.write(geometry) + ")";
}
return cqlFilter;
};
})();