Skip to content

Commit 96bd7e4

Browse files
Merge pull request #146 from sdole/master
much better, flexible tag filters. change from json search templates to java api
2 parents efdd9a5 + 8e0418e commit 96bd7e4

40 files changed

+2171
-47
lines changed

README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,24 @@ http://localhost:2322/api?q=berlin&lang=it
9090

9191
#### Filter results by [tags and values](http://taginfo.openstreetmap.org/projects/nominatim#tags)
9292
*Note: not all tags on [link in the title](http://taginfo.openstreetmap.org/projects/nominatim#tags) are supported. Please see [nominatim source](https://github.com/openstreetmap/osm2pgsql/blob/master/output-gazetteer.cpp#L81) for an accurate list.*
93+
If one or many query parameters named ```osm_tag``` are present, photon will attempt to filter results by those tags. In general, here is the expected format (syntax) for the value of osm_tag request parameters.
94+
95+
1. Include places with tag: ```osm_tag=key:value```
96+
2. Exclude places with tag: ```osm_tag=!key:value```
97+
3. Include places with tag key: ```osm_tag=key```
98+
4. Include places with tag value: ```osm_tag=:value```
99+
5. Exclude places with tag key: ```osm_tag=!key```
100+
6. Exclude places with tag value: ```osm_tag=:!value```
101+
102+
For example, to search for all places named ```berlin``` with tag of ```tourism=museum```, one should construct url as follows:
93103
```
94-
http://localhost:2322/api?q=berlin&osm_key=tourism&osm_value=museum
104+
http://localhost:2322/api?q=berlin&osm_tag=toursim:museum
95105
```
96106

97107
Or, just by they key
98108

99109
```
100-
http://localhost:2322/api?q=berlin&osm_key=tourism
110+
http://localhost:2322/api?q=berlin&osm_tag=tourism
101111
```
102112

103113
#### Results as GeoJSON

pom.xml

+21-2
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,22 @@
107107
<dependency>
108108
<groupId>org.mockito</groupId>
109109
<artifactId>mockito-all</artifactId>
110-
<version>1.8.4</version>
110+
<version>1.10.8</version>
111111
<scope>test</scope>
112112
</dependency>
113-
<dependency>
113+
<dependency>
114+
<groupId>org.powermock</groupId>
115+
<artifactId>powermock-module-junit4</artifactId>
116+
<version>1.6.1</version>
117+
<scope>test</scope>
118+
</dependency>
119+
<dependency>
120+
<groupId>org.powermock</groupId>
121+
<artifactId>powermock-api-mockito</artifactId>
122+
<version>1.6.1</version>
123+
<scope>test</scope>
124+
</dependency>
125+
<dependency>
114126
<groupId>com.google.guava</groupId>
115127
<artifactId>guava</artifactId>
116128
<version>17.0</version>
@@ -130,6 +142,13 @@
130142
<artifactId>json</artifactId>
131143
<version>20140107</version>
132144
</dependency>
145+
<dependency>
146+
<groupId>commons-beanutils</groupId>
147+
<artifactId>commons-beanutils</artifactId>
148+
<version>1.9.2</version>
149+
<scope>test</scope>
150+
</dependency>
151+
133152
</dependencies>
134153

135154
<repositories>

src/main/java/de/komoot/photon/App.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.beust.jcommander.JCommander;
44
import com.beust.jcommander.ParameterException;
5-
import de.komoot.photon.elasticsearch.Searcher;
65
import de.komoot.photon.elasticsearch.Server;
76
import de.komoot.photon.nominatim.NominatimConnector;
87
import de.komoot.photon.nominatim.NominatimUpdater;
@@ -19,6 +18,11 @@
1918

2019
@Slf4j
2120
public class App {
21+
private static Client esClient= null;
22+
public static Client getClient(){
23+
return esClient;
24+
25+
}
2226
public static void main(String[] rawArgs) {
2327
// parse command line arguments
2428
CommandLineArgs args = new CommandLineArgs();
@@ -43,7 +47,7 @@ public static void main(String[] rawArgs) {
4347
}
4448

4549
final Server esServer = new Server(args).start();
46-
Client esClient = esServer.getClient();
50+
esClient = esServer.getClient();
4751

4852
if(args.isRecreateIndex()) {
4953
startRecreatingIndex(esServer);
@@ -132,10 +136,11 @@ private static void startApi(CommandLineArgs args, Client esNodeClient) {
132136
setIpAddress(args.getListenIp());
133137

134138
// setup search API
135-
final Searcher searcher = new Searcher(esNodeClient);
136-
get(new RequestHandler("api", searcher, args.getLanguages()));
137-
get(new RequestHandler("api/", searcher, args.getLanguages()));
138-
139+
// final Searcher searcher = new Searcher(esNodeClient);
140+
// get(new RequestHandler("api", searcher, args.getLanguages()));
141+
// get(new RequestHandler("api/", searcher, args.getLanguages()));
142+
get(new SearchRequestHandler("api",args.getLanguages()));
143+
get(new SearchRequestHandler("api/",args.getLanguages()));
139144
// setup update API
140145
final NominatimUpdater nominatimUpdater = new NominatimUpdater(args.getHost(), args.getPort(), args.getDatabase(), args.getUser(), args.getPassword());
141146
Updater updater = new de.komoot.photon.elasticsearch.Updater(esNodeClient, args.getLanguages());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package de.komoot.photon;
2+
3+
/**
4+
* Created by sachi_000 on 2/20/2015.
5+
*/
6+
public interface Command<R, O> {
7+
R execute(O... operand);
8+
}

src/main/java/de/komoot/photon/OsmTag.java

-22
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package de.komoot.photon;
2+
3+
import de.komoot.photon.query.BadRequestException;
4+
import de.komoot.photon.query.PhotonRequest;
5+
import de.komoot.photon.query.PhotonRequestFactory;
6+
import de.komoot.photon.searcher.PhotonRequestHandler;
7+
import de.komoot.photon.searcher.PhotonRequestHandlerFactory;
8+
import de.komoot.photon.utils.ConvertToGeoJson;
9+
import org.json.JSONObject;
10+
import spark.Request;
11+
import spark.Response;
12+
import spark.Route;
13+
14+
import java.util.Arrays;
15+
import java.util.HashSet;
16+
import java.util.List;
17+
import java.util.Set;
18+
19+
/**
20+
* Created by Sachin Dole on 2/12/2015.
21+
*/
22+
public class SearchRequestHandler<R extends PhotonRequest> extends Route {
23+
private final PhotonRequestFactory photonRequestFactory;
24+
private final PhotonRequestHandlerFactory requestHandlerFactory;
25+
private final ConvertToGeoJson geoJsonConverter;
26+
27+
SearchRequestHandler(String path, String languages) {
28+
super(path);
29+
Set<String> supportedLanguages = new HashSet<String>(Arrays.asList(languages.split(",")));
30+
this.photonRequestFactory = new PhotonRequestFactory(supportedLanguages);
31+
this.geoJsonConverter = new ConvertToGeoJson();
32+
this.requestHandlerFactory = new PhotonRequestHandlerFactory();
33+
}
34+
35+
@Override
36+
public String handle(Request request, Response response) {
37+
R photonRequest = null;
38+
try {
39+
photonRequest = photonRequestFactory.create(request);
40+
} catch (BadRequestException e) {
41+
halt(e.getHttpStatus(), "bad request: " + e.getMessage());
42+
}
43+
PhotonRequestHandler<R> handler = requestHandlerFactory.createHandler(photonRequest);
44+
List<JSONObject> results = handler.handle(photonRequest);
45+
JSONObject geoJsonResults = geoJsonConverter.convert(results);
46+
response.type("application/json; charset=utf-8");
47+
response.header("Access-Control-Allow-Origin", "*");
48+
if (request.queryParams("debug") != null)
49+
return geoJsonResults.toString(4);
50+
51+
return geoJsonResults.toString();
52+
}
53+
}

src/main/java/de/komoot/photon/elasticsearch/Searcher.java

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* @author christoph
2828
*/
2929
@Slf4j
30+
@Deprecated
3031
public class Searcher {
3132
private final String queryTemplate;
3233
private final String queryLocationBiasTemplate;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package de.komoot.photon.query;
2+
3+
/**
4+
* Created by Sachin Dole on 2/12/2015.
5+
*/
6+
public class BadRequestException extends Exception{
7+
private final int httpStatus;
8+
9+
public BadRequestException(int httpStatusCode, String message) {
10+
super(message);
11+
this.httpStatus = httpStatusCode;
12+
}
13+
14+
public int getHttpStatus() {
15+
return httpStatus;
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package de.komoot.photon.query;
2+
3+
import de.komoot.photon.utils.Command;
4+
import spark.QueryParamsMap;
5+
6+
/**
7+
* Created by Sachin Dole on 2/22/2015.
8+
*/
9+
public class CheckIfFilteredRequest implements Command<Boolean, QueryParamsMap> {
10+
@Override
11+
public Boolean execute(QueryParamsMap... operand) {
12+
QueryParamsMap queryParam = operand[0];
13+
if (!queryParam.hasValue()) return false;
14+
String[] tagsToFilterOn = queryParam.values();
15+
for (String eachTagToFilterOn : tagsToFilterOn) {
16+
if (eachTagToFilterOn != null && eachTagToFilterOn.trim().length() > 0) {
17+
return true;
18+
}
19+
}
20+
return false;
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package de.komoot.photon.query;
2+
3+
import com.vividsolutions.jts.geom.Point;
4+
5+
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.Map;
8+
import java.util.Set;
9+
10+
/**
11+
* A photon request that can hold filter parameters requested by client.
12+
* Created by Sachin Dole on 2/12/2015.
13+
*/
14+
public class FilteredPhotonRequest extends PhotonRequest {
15+
private Set<String> excludeKeys = new HashSet<String>(3);
16+
private Set<String> includeKeys = new HashSet<String>(3);
17+
private Set<String> excludeValues = new HashSet<String>(3);
18+
private Set<String> includeValues = new HashSet<String>();
19+
private Map<String, Set<String>> includeTags = new HashMap<String, Set<String>>(3);
20+
private Map<String, Set<String>> excludeTags = new HashMap<String, Set<String>>(3);
21+
private Map<String, Set<String>> excludeTagValues = new HashMap<String, Set<String>>(3);
22+
FilteredPhotonRequest(String query, Integer limit, Point locationForBias, String language) {
23+
super(query, limit, locationForBias, language);
24+
}
25+
26+
public Set<String> keys() {
27+
return includeKeys;
28+
}
29+
30+
void keys(String includeKey) {
31+
this.includeKeys.add(includeKey);
32+
}
33+
34+
public Set<String> values() {
35+
return includeValues;
36+
}
37+
38+
void values(String keyToInclude) {
39+
includeValues.add(keyToInclude);
40+
}
41+
42+
public Map<String, Set<String>> tags() {
43+
return includeTags;
44+
}
45+
46+
void tags(String aKey, Set<String> manyValues) {
47+
this.includeTags.put(aKey, manyValues);
48+
}
49+
50+
public Set<String> notValues() {
51+
return excludeValues;
52+
}
53+
54+
public Map<String, Set<String>> notTags() {
55+
return excludeTags;
56+
}
57+
58+
void notKeys(String excludeKey) {
59+
excludeKeys.add(excludeKey);
60+
}
61+
62+
void notTags(String excludeKey, Set<String> excludeManyValues) {
63+
excludeTags.put(excludeKey, excludeManyValues);
64+
}
65+
66+
void notValues(String excludeValue) {
67+
excludeValues.add(excludeValue);
68+
}
69+
70+
public Set<String> notKeys() {
71+
return excludeKeys;
72+
}
73+
74+
void tagNotValues(String key, Set<String> excludeValues) {
75+
excludeTagValues.put(key,excludeValues);
76+
}
77+
public Map<String,Set<String>> tagNotValues(){
78+
return excludeTagValues;
79+
80+
}
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package de.komoot.photon.query;
2+
3+
import com.google.common.base.Joiner;
4+
import de.komoot.photon.utils.Function;
5+
6+
import java.util.Set;
7+
8+
/**
9+
* Checks if a the requested language is supported by photon.
10+
* Created by Sachin Dole on 2/20/2015.
11+
*/
12+
public class LanguageChecker implements Function<String,Boolean,BadRequestException> {
13+
private final Set<String> supportedLanguages;
14+
15+
public LanguageChecker(Set<String> supportedLanguages) {
16+
this.supportedLanguages = supportedLanguages;
17+
}
18+
19+
@Override
20+
public Boolean apply(String lang) throws BadRequestException {
21+
if(lang == null) lang = "en";
22+
if(!supportedLanguages.contains(lang)) {
23+
throw new BadRequestException(400, "language " + lang + " is not supported, supported languages are: " + Joiner.on(", ").join(supportedLanguages));
24+
}
25+
return true;
26+
}
27+
}

0 commit comments

Comments
 (0)