package de.komoot.photon.query;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;
import java.util.HashSet;
import java.util.Set;
import spark.QueryParamsMap;
import spark.Request;
/**
* A factory that creates a {@link PhotonRequest} from a {@link Request web request}
* Created by Sachin Dole on 2/12/2015.
*/
public class PhotonRequestFactory {
private final LanguageChecker languageChecker;
private final static GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
public PhotonRequestFactory(Set<String> supportedLanguages) {
this.languageChecker = new LanguageChecker(supportedLanguages);
}
public <R extends PhotonRequest> R create(Request webRequest) throws BadRequestException {
String language = webRequest.queryParams("lang");
language = language == null ? "en" : language;
languageChecker.apply(language);
String query = webRequest.queryParams("q");
if (query == null) throw new BadRequestException(400, "missing search term 'q': /?q=berlin");
Integer limit;
try {
limit = Integer.valueOf(webRequest.queryParams("limit"));
} catch (NumberFormatException e) {
limit = 15;
}
Point locationForBias = null;
try {
Double lon = Double.valueOf(webRequest.queryParams("lon"));
Double lat = Double.valueOf(webRequest.queryParams("lat"));
locationForBias = geometryFactory.createPoint(new Coordinate(lon, lat));
} catch (Exception nfe) {
//ignore
}
QueryParamsMap tagFiltersQueryMap = webRequest.queryMap("osm_tag");
if (!new CheckIfFilteredRequest().execute(tagFiltersQueryMap)) {
return (R) new PhotonRequest(query, limit, locationForBias, language);
}
FilteredPhotonRequest photonRequest = new FilteredPhotonRequest(query, limit, locationForBias, language);
String[] tagFilters = tagFiltersQueryMap.values();
setUpTagFilters(photonRequest, tagFilters);
return (R) photonRequest;
}
private void setUpTagFilters(FilteredPhotonRequest request, String[] tagFilters) {
for (String tagFilter : tagFilters) {
if (tagFilter.contains(":")) {
//might be tag and value OR just value.
if (tagFilter.startsWith("!")) {
//exclude
String keyValueCandidate = tagFilter.substring(1);
if (keyValueCandidate.startsWith(":")) {
//just value
request.notValues(keyValueCandidate.substring(1));
} else {
//key and value
String[] keyAndValue = keyValueCandidate.split(":");
String excludeKey = keyAndValue[0];
String value = keyAndValue[1].startsWith("!") ? keyAndValue[1].substring(1) : keyAndValue[1];
Set<String> valuesToExclude = request.notTags().get(excludeKey);
if (valuesToExclude == null) valuesToExclude = new HashSet<String>();
valuesToExclude.add(value);
request.notTags(excludeKey, valuesToExclude);
}
} else {
//include key, not sure about value
if (tagFilter.startsWith(":")) {
//just value
String valueCandidate = tagFilter.substring(1);
if (valueCandidate.startsWith("!")){
//exclude value
request.notValues(valueCandidate.substring(1));
}else {
//include value
request.values(valueCandidate);
}
} else {
//key and value
String[] keyAndValue = tagFilter.split(":");
String key = keyAndValue[0];
String value = keyAndValue[1];
if (value.startsWith("!")) {
//exclude value
Set<String> tagKeysValuesNotIncluded = request.tagNotValues().get(key);
if (tagKeysValuesNotIncluded == null) tagKeysValuesNotIncluded = new HashSet<String>();
tagKeysValuesNotIncluded.add(value.substring(1));
request.tagNotValues(key, tagKeysValuesNotIncluded);
} else {
//include value
Set<String> valuesToInclude = request.tags().get(key);
if (valuesToInclude == null) valuesToInclude = new HashSet<String>();
valuesToInclude.add(value);
request.tags(key, valuesToInclude);
}
}
}
} else {
//only tag
if (tagFilter.startsWith("!")) {
request.notKeys(tagFilter.substring(1));
} else {
request.keys(tagFilter);
}
}
}
}
}