Search in sources :

Example 1 with GeoCodingResult

use of org.structr.common.geo.GeoCodingResult in project structr by structr.

the class SearchCommand method doSearch.

private Result<T> doSearch() throws FrameworkException {
    if (page == 0 || pageSize <= 0) {
        return Result.EMPTY_RESULT;
    }
    final Factory<S, T> factory = getFactory(securityContext, includeDeletedAndHidden, publicOnly, pageSize, page);
    boolean hasGraphSources = false;
    boolean hasSpatialSource = false;
    if (securityContext.getUser(false) == null && !isRelationshipSearch()) {
        rootGroup.add(new PropertySearchAttribute(GraphObject.visibleToPublicUsers, true, Occurrence.REQUIRED, true));
    } else if (securityContext.getUser(false) == null && isRelationshipSearch()) {
        rootGroup.add(new RelationshipVisibilitySearchAttribute());
    }
    // special handling of deleted and hidden flags
    if (!includeDeletedAndHidden && !isRelationshipSearch()) {
        rootGroup.add(new PropertySearchAttribute(NodeInterface.hidden, true, Occurrence.FORBIDDEN, true));
        rootGroup.add(new PropertySearchAttribute(NodeInterface.deleted, true, Occurrence.FORBIDDEN, true));
    }
    // At this point, all search attributes are ready
    final List<SourceSearchAttribute> sources = new ArrayList<>();
    boolean hasEmptySearchFields = false;
    boolean hasRelationshipVisibilitySearch = false;
    Result intermediateResult = null;
    // (some query types seem to allow no MUST occurs)
    for (final Iterator<SearchAttribute> it = rootGroup.getSearchAttributes().iterator(); it.hasNext(); ) {
        final SearchAttribute attr = it.next();
        if (attr instanceof SearchAttributeGroup) {
            // fixme: this needs to be done recursively, but how?
            for (final Iterator<SearchAttribute> groupIterator = ((SearchAttributeGroup) attr).getSearchAttributes().iterator(); groupIterator.hasNext(); ) {
                final SearchAttribute item = groupIterator.next();
                if (item instanceof SourceSearchAttribute) {
                    sources.add((SourceSearchAttribute) item);
                    // remove attribute from filter list
                    groupIterator.remove();
                    hasGraphSources = true;
                }
                if (item instanceof EmptySearchAttribute) {
                    hasEmptySearchFields = true;
                }
            }
        }
        // check for distance search and initialize
        if (attr instanceof DistanceSearchAttribute) {
            final DistanceSearchAttribute distanceSearch = (DistanceSearchAttribute) attr;
            if (distanceSearch.needsGeocding()) {
                final GeoCodingResult coords = GeoHelper.geocode(distanceSearch);
                if (coords != null) {
                    distanceSearch.setCoords(coords.toArray());
                }
            }
            hasSpatialSource = true;
        }
        // store source attributes for later use
        if (attr instanceof SourceSearchAttribute) {
            sources.add((SourceSearchAttribute) attr);
            hasGraphSources = true;
        }
        if (attr instanceof EmptySearchAttribute) {
            hasEmptySearchFields = true;
        }
        if (attr instanceof RelationshipVisibilitySearchAttribute) {
            hasRelationshipVisibilitySearch = true;
        }
    }
    // use filters to filter sources otherwise
    if (!hasSpatialSource && !sources.isEmpty()) {
        intermediateResult = new Result(new ArrayList<>(), null, false, false);
    } else {
        // apply sorting
        if (sortKey != null && !doNotSort) {
            rootGroup.setSortKey(sortKey);
            rootGroup.sortDescending(sortDescending);
        }
        final Index<S> index = getIndex();
        if (index != null) {
            // paging needs to be done AFTER instantiating all nodes
            if (hasEmptySearchFields || comparator != null) {
                factory.disablePaging();
            }
            // do query
            final QueryResult hits = index.query(getQueryContext(), rootGroup);
            intermediateResult = factory.instantiate(hits);
            if (comparator != null) {
                final List<T> rawResult = intermediateResult.getResults();
                Collections.sort(rawResult, comparator);
                return new Result(PagingHelper.subList(rawResult, pageSize, page), rawResult.size(), true, false);
            }
        }
    }
    if (intermediateResult != null && (hasEmptySearchFields || hasGraphSources || hasSpatialSource || hasRelationshipVisibilitySearch)) {
        // sorted result set
        final Set<GraphObject> intermediateResultSet = new LinkedHashSet<>(intermediateResult.getResults());
        final List<GraphObject> finalResult = new ArrayList<>();
        int resultCount = 0;
        if (hasGraphSources) {
            // merge sources according to their occur flag
            final Set<GraphObject> mergedSources = mergeSources(sources);
            if (hasSpatialSource) {
                // CHM 2014-02-24: preserve sorting of intermediate result, might be sorted by distance which we cannot reproduce easily
                intermediateResultSet.retainAll(mergedSources);
            } else {
                intermediateResultSet.addAll(mergedSources);
            }
        }
        // Filter intermediate result
        for (final GraphObject obj : intermediateResultSet) {
            boolean addToResult = true;
            // check all attributes before adding a node
            for (SearchAttribute attr : rootGroup.getSearchAttributes()) {
                // check all search attributes
                addToResult &= attr.includeInResult(obj);
            }
            if (addToResult) {
                finalResult.add(obj);
                resultCount++;
            }
        }
        // sort list
        Collections.sort(finalResult, new GraphObjectComparator(sortKey, sortDescending));
        // return paged final result
        return new Result(PagingHelper.subList(finalResult, pageSize, page), resultCount, true, false);
    } else {
        // no filtering
        return intermediateResult;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) GraphObject(org.structr.core.GraphObject) GeoCodingResult(org.structr.common.geo.GeoCodingResult) Result(org.structr.core.Result) QueryResult(org.structr.api.QueryResult) GeoCodingResult(org.structr.common.geo.GeoCodingResult) QueryResult(org.structr.api.QueryResult) GraphObjectComparator(org.structr.common.GraphObjectComparator)

Example 2 with GeoCodingResult

use of org.structr.common.geo.GeoCodingResult in project structr by structr.

the class GeocodeFunction method apply.

@Override
public Object apply(final ActionContext ctx, final Object caller, final Object[] sources) throws FrameworkException {
    try {
        if (arrayHasLengthAndAllElementsNotNull(sources, 3)) {
            final String street = sources[0].toString();
            final String city = sources[1].toString();
            final String country = sources[2].toString();
            final GeoCodingResult result = GeoHelper.geocode(street, null, null, city, null, country);
            if (result != null) {
                final Map<String, Object> map = new LinkedHashMap<>();
                map.put("latitude", result.getLatitude());
                map.put("longitude", result.getLongitude());
                AddressComponent cur = null;
                cur = result.getAddressComponent(GeoCodingResult.Type.country);
                if (cur != null) {
                    map.put("country", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.postal_code);
                if (cur != null) {
                    map.put("postalCode", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.locality);
                if (cur != null) {
                    map.put("city", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.route);
                if (cur != null) {
                    map.put("street", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.street_number);
                if (cur != null) {
                    map.put("houseNumber", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.administrative_area_level_1);
                if (cur != null) {
                    map.put("state", cur.getValue());
                }
                cur = result.getAddressComponent(GeoCodingResult.Type.administrative_area_level_3);
                if (cur != null) {
                    map.put("stateDistrict", cur.getValue());
                }
                return map;
            }
        }
    } catch (final IllegalArgumentException e) {
        logParameterError(caller, sources, ctx.isJavaScriptContext());
        return usage(ctx.isJavaScriptContext());
    }
    return "";
}
Also used : GeoCodingResult(org.structr.common.geo.GeoCodingResult) AddressComponent(org.structr.common.geo.AddressComponent) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with GeoCodingResult

use of org.structr.common.geo.GeoCodingResult in project structr by structr.

the class ScriptingTest method testGeoCoding.

@Test
public void testGeoCoding() {
    try (final Tx tx = app.tx()) {
        final ActionContext ctx = new ActionContext(securityContext, null);
        final String locationId = Scripting.replaceVariables(ctx, null, "${create('Location')}");
        final GeoCodingResult result = GeoHelper.geocode("", null, null, "Darmstadt", null, "");
        if (result != null) {
            // If geocoding itself fails, the test can not work => ignore
            Double lat = result.getLatitude();
            Double lon = result.getLongitude();
            Scripting.replaceVariables(ctx, null, "${set(find('Location', '" + locationId + "'), geocode('Darmstadt', '', ''))}");
            assertEquals("Latitude should be identical", lat.toString(), Scripting.replaceVariables(ctx, null, "${get(find('Location', '" + locationId + "'), 'latitude')}"));
            assertEquals("Longitude should be identical", lon.toString(), Scripting.replaceVariables(ctx, null, "${get(find('Location', '" + locationId + "'), 'longitude')}"));
        }
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail(fex.getMessage());
    }
}
Also used : GeoCodingResult(org.structr.common.geo.GeoCodingResult) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) ActionContext(org.structr.schema.action.ActionContext) StructrTest(org.structr.common.StructrTest) Test(org.junit.Test)

Example 4 with GeoCodingResult

use of org.structr.common.geo.GeoCodingResult in project structr by structr.

the class TestNine method geocode.

public void geocode() throws FrameworkException {
    Double lat = getProperty(latitude);
    Double lon = getProperty(longitude);
    if (lat == null || lon == null) {
        String _city = getProperty(city);
        String _street = getProperty(street);
        String _postalCode = getProperty(postalCode);
        GeoCodingResult geoCodingResult = GeoHelper.geocode(_street, null, _postalCode, _city, null, null);
        if (geoCodingResult == null) {
            return;
        }
        setProperty(latitude, geoCodingResult.getLatitude());
        setProperty(longitude, geoCodingResult.getLongitude());
        // set postal code if found
        AddressComponent postalCodeComponent = geoCodingResult.getAddressComponent(GeoCodingResult.Type.postal_code);
        if (postalCodeComponent != null) {
            setProperty(postalCode, postalCodeComponent.getValue());
        }
    }
}
Also used : GeoCodingResult(org.structr.common.geo.GeoCodingResult) AddressComponent(org.structr.common.geo.AddressComponent)

Aggregations

GeoCodingResult (org.structr.common.geo.GeoCodingResult)4 AddressComponent (org.structr.common.geo.AddressComponent)2 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Test (org.junit.Test)1 QueryResult (org.structr.api.QueryResult)1 GraphObjectComparator (org.structr.common.GraphObjectComparator)1 StructrTest (org.structr.common.StructrTest)1 FrameworkException (org.structr.common.error.FrameworkException)1 GraphObject (org.structr.core.GraphObject)1 Result (org.structr.core.Result)1 Tx (org.structr.core.graph.Tx)1 ActionContext (org.structr.schema.action.ActionContext)1