geomoose / gm3

GeoMoose 3.0 Development. Please submit pull requests to the 'main' branch.
https://www.geomoose.org
MIT License
58 stars 59 forks source link

Adding OR connector to search #315

Closed cabesuon closed 5 years ago

cabesuon commented 6 years ago

This is a question and suggestion at the same time. I don't know if this is already solved, so excuse me it it is. I am sure there are better ways to solve it, this is just an example.

Regards Manuel

User Case Example: The user wants to search for one or several parcels of an administrative limit. A parcel is search by a combination of a administrative limit name (Departamento) and a parcel number (Padrón).

Input Example: Departamento: COLONIA Padrón: 11938 7917 11977

Right now I could not find a way of doing this. So I have to change a bit the code of map.jsx, and aloud user to enter several numbers separated with a space character on the number input.

-> app.js - prepareFields function of parcel search *

    prepareFields: function(fields) {
        var query = [];
        // departamento
        if(fields[0].value !== '' && fields[0].value !== undefined) {
            query.push({
                comparitor: 'eq',
                name: fields[0].name,
                value: fields[0].value
            });
        }
        // padron
        if(fields[1].value !== '' && fields[1].value !== undefined) {
            let parcels = fields[1].value.trim().split(' ');
            let parcel_filter = null;
            if(parcels.length > 1) {
                parcel_filter = {
                    connector: 'or',
                    rightCondition: {
                        comparitor: 'eq',
                        name: fields[1].name,
                        value: parcels[0]
                    },
                    leftCondition: {
                        comparitor: 'eq',
                        name: fields[1].name,
                        value: parcels[1]
                    }
                }
                for(let i = 2, ii = parcels.length; i < ii; i++) {
                    parcel_filter = parcels_filter = {
                        connector: 'or',
                        rightCondition: parcel_filter,
                        leftCondition: {
                            comparitor: 'eq',
                            name: fields[1].name,
                            value: parcels[i]
                        }
                    }
                }
            } else {
                parcel_filter = {
                    comparitor: 'eq',
                    name: fields[1].name,
                    value: fields[1].value
                };
            }
            query.push(parcel_filter);
        }
        return query;
    }

-> map.jsx - function wfsGetFeatureQuery - added and commented code

    // to support binary connectors 'and' and/or 'or'
    let resolveFilter = function(filter) {
        if (filter.hasOwnProperty('comparitor')) {
            return filter_mapping[filter.comparitor](filter.name, filter.value);
        } else if (filter.hasOwnProperty('connector')) {
            if (filter.connector === 'and') {
                return ol_filters.and(
                    resolveFilter(filter.rightCondition),
                    resolveFilter(filter.leftCondition)
                );
            } else if (filter.connector === 'or') {
                return ol_filters.or(
                    resolveFilter(filter.rightCondition),
                    resolveFilter(filter.leftCondition)
                );
            }
        } else {
            return null;
        }
    }

    //  to not break default search
    let chained_filters = null;
    if(query.fields.length > 1) {
        chained_filters = ol_filters.and(resolveFilter(query.fields[0]), resolveFilter(query.fields[1]));
        for(let i = 2, ii = query.fields.length; i < ii; i++) {
            chained_filters = ol_filters.and(chained_filters, resolveFilter(query.fields[i]));
        }
    } else {
        chained_filters = resolveFilter(query.fields[0]);
    }

    // for(let filter of query.fields) {
    //     // TODO: Catch "filter.type" and use internal conversion
    //     //       functions for specialty filters.
    //     filters.push(filter_mapping[filter.comparitor](filter.name, filter.value));
    // }

    // // when multiple filters are set then they need to be
    // //  chained together to create the compound filter.
    // let chained_filters = null;
    // if(filters.length > 1) {
    //     chained_filters = ol_filters.and(filters[0], filters[1]);
    //     for(let i = 2, ii = filters.length; i < ii; i++) {
    //         chained_filters = ol_filters.and(chained_filters, filters[i]);
    //     }
    // } else {
    //     chained_filters = filters[0];
    // }
theduckylittle commented 5 years ago

PR Please!

cabesuon commented 5 years ago

OK, I will do it on the weekend.

Regards Manuel

theduckylittle commented 5 years ago

Got a PR put together that is a little more complete.

cabesuon commented 5 years ago

That's great @theduckylittle, thanks.