Filtros - sigcorporativo-ja/Mapea4 GitHub Wiki
Con Mapea se pueden establecer filtros que permiten comprobar si los elementos (features) cumplen o no con determinadas condiciones. Los filtros pueden aplicarse de dos formas diferentes:
Lo más común es aplicarlos sobre capas vectoriales del mapa, de modo que apliquen a los features de la misma. Estos filtros se ejecutan en memoria, es decir, estando la capa cargada ya con todos sus features en el cliente, establecer un filtro no supone realizar ninguna nueva petición al servidor.
Hay que tener en cuenta que una vez se aplica un filtro a una capa, este es efectivo hasta que el mismo se elimine o se modifique, por lo que a todos los efectos, es como si la capa tuviese únicamente aquellos features que cumplen el filtro: dibujado en el mapa, recorrido por sus features, etc.
La segunda forma de usar un filtro es ejecutándolo sobre un array de features. Eso nos devolverá una lista únicamente con los features que cumplen el filtro. Más adelante se mostrarán ejemplos de ambos casos.
Los filtros actualmente implementados son:
Filtros alfanuméricos
Filtro | Descripción |
---|---|
M.filter.AND | Condición Y |
M.filter.OR | Condición O |
M.filter.NOT | Condición NO |
M.filter.EQUAL | Condición IGUAL |
M.filter.LIKE | Condición de PATRÓN |
M.filter.LT | Condición MENOR QUE |
M.filter.GT | Condición MAYOR QUE |
M.filter.LTE | Condición MENOR O IGUAL QUE |
M.filter.GTE | Condición MAYOR O IGUAL QUE |
Mediante los filtros M.filter.AND y M.filter.OR podemos encadenar tantos filtros como queramos
let mapajs = M.map({
container: "map",
wmcfile: "mapa",
controls: ["layerswitcher"]
});
let lyProvincias = new M.layer.WFS({
url: "http://geostematicos-sigc.juntadeandalucia.es/geoserver/tematicos/ows?",
namespace: "tematicos",
name: "Provincias",
legend: "Provincias",
geometry: 'MPOLYGON'
});
mapajs.addLayers(lyProvincias);
lyProvincias.on(M.evt.LOAD, () => {
//Filtro por atributo nombre
let filter = M.filter.OR(
[M.filter.EQUAL("nombre", "Sevilla"),
M.filter.EQUAL("nombre", "Málaga")]);
// Si quiero aplicar el filtro a la capa sobre el mapa:
lyProvincias.setFilter(filter);
// Si solo quiero obtener los features que cumplen el filtro,
// Sin afectar a la capa:
let featuresFiltrados = filter.execute(layer.getFeatures());
//lyProvincias.removeFilter(); eliminar el filtro
});
Filtros espaciales
Filtro | Descripción |
---|---|
M.filter.spatial.CONTAIN | Comprueba que el un elemento A esté dentro de otro B |
M.filter.spatial.DISJOINT | Comprueba que los elementos A y B no tengan ningún punto en común |
M.filter.spatial.WITHIN | Comprueba que el elemento B esté dentro de A |
M.filter.spatial.INTERSECT | Comprueba si los elementos A y B tienen puntos en común |
Los filtros espaciales aceptan paŕametros en forma de Feature, o en forma de geometría GeoJSON.
:bulb: Para los filtros espaciales, se ha implementado la librería jsts. Esto permite acceder a ella y realizar multitud de operaciones espaciales adicionales. Ejemplo funcional
let mapajs = M.map({
container: "map",
wmcfile: "mapa",
controls: ["layerswitcher"]
});
var lyProvincias = new M.layer.WFS({
url: "http://geostematicos-sigc.juntadeandalucia.es/geoserver/tematicos/ows?",
namespace: "tematicos",
name: "Provincias",
legend: "Provincias",
geometry: 'MPOLYGON'
});
mapajs.addLayers(lyProvincias);
lyProvincias.on(M.evt.LOAD, () => {
// Si queremos usar un feature
let miFeature = new M.Feature("featurePrueba002", {
"type": "Feature",
"id": "prueba_pol_wfst.1985",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[263770.72265536943, 4085361.4590256726],
[230910.00600234355, 4031901.3328427672],
[288293.77947248437, 4017678.0840030923],
[263770.72265536943, 4085361.4590256726]
]
]
},
"properties": {
"nombre": "feature2"
}
});
// Si queremos una geometría:
let miGeometria = {
'type': 'Polygon',
'coordinates': [
[
[251853, 4200334],
[326894, 4200334],
[326894, 4129217],
[251853, 4129217],
[251853, 4200334]
]
]
};
//Filtro los features de la capa que intersecten con miFeature
let filter = M.filter.spatial.INTERSECT(miFeature);
// Si queremos usar GeoJSON
//let filter = M.filter.spatial.INTERSECT(miGeometria);
lyProvincias.setFilter(filter);
});
Aquí puede verse un ejemplo funcional
También se ofrece la posibilidad de transformar cualquier de estos filtros al estándar CQL, por si se quiere hacer uso de filtrado desde el servidor
let filtroCQL = filter.toCQL(); //devuelve un string con el filtro en formato CQL
lyProvincias.setCQL(filtroCQL);
Filtros personalizados
Si ninguno de los filtros disponibles se adaptan a nuestras necesidades, Mapea también ofrece la posibilidad de definir cualquier filtro mediante una función, de forma que no quedamos limitados a la hora de poder realizar cualquier filtro:
let mapajs = M.map({
container: "map",
wmcfile: "callejero",
controls: ["layerswitcher"]
});
var lyProvincias = new M.layer.WFS({
url: "http://geostematicos-sigc.juntadeandalucia.es/geoserver/tematicos/ows?",
namespace: "tematicos",
name: "Provincias",
legend: "Provincias",
geometry: 'MPOLYGON'
});
mapajs.addLayers(lyProvincias);
//se crea un filtro personalizado que sólo devuelve las features
//que tengan la letra 'C' en el atributo nombre
let filter = new M.filter.Function(feature => {
return feature.getAttribute('nombre').indexOf('C') >= 0;
});
lyProvincias.setFilter(filter);
Documentación API: M.filter