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;
}
}
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 "";
}
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());
}
}
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());
}
}
}
Aggregations