Skip to content

Commit

Permalink
Migrate geoCoder() endpoint to Retrofit
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverlockwood committed Jun 25, 2016
1 parent 518fabf commit d18cb8f
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 149 deletions.
4 changes: 1 addition & 3 deletions build.gradle
Expand Up @@ -61,9 +61,7 @@ subprojects {
exclude 'META-INF/NOTICE.txt'
} // packagingOptions

// Required as per:
// https://github.com/codepath/android_guides/wiki/Consuming-APIs-with-Retrofit#issues
// https://github.com/FasterXML/jackson-databind/issues/1192
// Required due to strictness of the Android developer tools. See lint.xml for full details.
lintOptions {
lintConfig rootProject.file('gradle/lint.xml')
}
Expand Down
4 changes: 4 additions & 0 deletions gradle/lint.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="InvalidPackage">
<!-- https://github.com/FasterXML/jackson-databind/issues/1192 -->
<ignore regexp=".*jackson.*" />
<!-- https://github.com/codepath/android_guides/wiki/Consuming-APIs-with-Retrofit#issues -->
<ignore regexp=".*okio.*" />
<ignore regexp=".*retrofit.*" />
<!-- http://sourceforge.net/p/simple/mailman/simple-support/thread/339270128E13BE47A6B10EED7367E7852BC2A912@MERCMBX18D.na.SAS.com/ -->
<ignore regexp=".*simple-xml.*" />
</issue>
</lint>
10 changes: 8 additions & 2 deletions libraries/cyclestreets-core/build.gradle
Expand Up @@ -10,8 +10,14 @@ dependencies {
compile 'org.slf4j:slf4j-android:1.7.21'

// Retrofit for HTTP Client activities
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-jackson:2.0.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile('com.squareup.retrofit2:converter-simplexml:2.1.0') {
// Exclusions required as per https://github.com/square/retrofit/issues/1796
exclude group: 'xpp3', module: 'xpp3'
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
compile 'com.squareup.retrofit2:converter-jackson:2.1.0'
compile 'de.grundid.opendatalab:geojson-jackson:1.6'

testCompile 'com.github.tomakehurst:wiremock-standalone:2.0.10-beta'
Expand Down
Expand Up @@ -78,7 +78,6 @@ public class ApiClient
public final static String API_PATH_SIGNIN = API_PATH + "uservalidate.xml";
public final static String API_PATH_REGISTER = API_PATH + "usercreate.xml";
public final static String API_PATH_FEEDBACK = API_PATH + "feedback.xml";
public final static String API_PATH_GEOCODER = API_PATH + "geocoder.xml";
public final static String API_PATH_POI_CATEGORIES = API_PATH_V2 + "pois.types";

private final static String BLOG_PATH = "/blog/";
Expand Down Expand Up @@ -111,7 +110,7 @@ public static void initialise(final Context context)
.withV2Host(API_HOST_V2)
.build();
} // initialise

public static void setCustomiser(ApiCustomiser customiser) {
customiser_ = customiser;
} // setCustomiser
Expand Down Expand Up @@ -174,17 +173,8 @@ static protected GeoPlaces geoCoder(final String search,
double n,
double s,
double e,
double w)
throws Exception
{
return callApi(GeoPlaces.factory(),
API_PATH_GEOCODER,
"street", search,
"n", Double.toString(n),
"s", Double.toString(s),
"e", Double.toString(e),
"w", Double.toString(w),
"countrycodes", "gb,ie");
double w) throws IOException {
return retrofitApiClient.geoCoder(search, n, s, e, w);
} // geoCoder

static Feedback.Result sendFeedback(final int itinerary,
Expand Down Expand Up @@ -309,7 +299,7 @@ private static String itineraryPoints(final double... lonLat)

private static byte[] callApiRaw(final String path, String... arguments) throws Exception {
Map<String, String> args = argMap(path, arguments);

final List<NameValuePair> params = createParamsList(args);
final URI uri = createURI(null, path, params);
final HttpGet httpget = new HttpGet(uri);
Expand Down Expand Up @@ -353,7 +343,7 @@ private static <T> T postApi(final Factory<T> factory, final String path, Object

public static byte[] postApiRaw(final String path, Object... arguments) throws Exception {
Map<String, Object> args = argMap(path, arguments);

final List<NameValuePair> params = createParamsList();
final URI uri = createURI(API_POST_SCHEME, path, params);

Expand Down Expand Up @@ -440,10 +430,10 @@ private static <T> Map<String, T> argMap(String path, T... args) {
Map<String, T> params = new HashMap<>();
for (int i = 0; i != args.length; i+=2)
params.put((String)args[i], args[i+1]);

if (customiser_ != null)
customiser_.customise(path, params);

return params;
} // argMap
} // ApiClient
@@ -1,135 +1,43 @@
package net.cyclestreets.api;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;

import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;

public class GeoPlaces implements Iterable<GeoPlace>
{
private List<GeoPlace> places_;

private GeoPlaces()
{
places_ = new ArrayList<>();
} // GeoPlaces

private void add(final GeoPlace place) { places_.add(place); }

private List<GeoPlace> places = new ArrayList<>();

public GeoPlaces(Collection<GeoPlace> places) {
this.places.addAll(places);
}

private GeoPlaces() {}

@Override
public Iterator<GeoPlace> iterator() { return places_.iterator(); }
public boolean isEmpty() { return places_.isEmpty(); }
public int size() { return places_.size(); }
public GeoPlace get(int index) { return places_.get(index); }
public List<GeoPlace> asList() { return places_; }
public Iterator<GeoPlace> iterator() { return places.iterator(); }

public boolean isEmpty() { return places.isEmpty(); }

public int size() { return places.size(); }
public GeoPlace get(int index) { return places.get(index); }

public List<GeoPlace> asList() { return places; }

static public GeoPlaces EMPTY = new GeoPlaces();

///////////////////////////////////////////////
static public GeoPlaces search(final String searchTerm,
final BoundingBoxE6 bounds)
throws Exception
{
return search(searchTerm,
bounds.getLatNorthE6() / 1E6,
bounds.getLatSouthE6() / 1E6,
bounds.getLonEastE6() / 1E6,
bounds.getLonWestE6() / 1E6);
} // search

static public GeoPlaces search(final String searchTerm,
double n,
double s,
double e,
double w)
throws Exception
{
return ApiClient.geoCoder(searchTerm, n, s, e, w);
} // search

////////////////////////////////////////////////////
static public Factory<GeoPlaces> factory() {
return new GeoPlacesFactory();
} // factory

static private class GeoPlacesFactory extends Factory.XmlReader<GeoPlaces>
{
private GeoPlaces places_;
private String name_;
private String near_;
private String lat_;
private String lon_;

public GeoPlacesFactory()
{
} // GeoPlacesFactory

@Override
protected ContentHandler contentHandler()
{
places_ = new GeoPlaces();

final RootElement root = new RootElement("sayt");
final Element item = root.getChild("results").getChild("result");
item.setStartElementListener(new StartElementListener() {
@Override
public void start(Attributes attributes)
{
name_ = null;
near_ = null;
lat_ = null;
lon_ = null;
}
});
item.setEndElementListener(new EndElementListener(){
public void end() {
final GeoPoint coord = new GeoPoint(Double.parseDouble(lat_),
Double.parseDouble(lon_));
places_.add(new GeoPlace(coord, name_, near_));
}
});
item.getChild("name").setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
name_ = body;
}
});
item.getChild("near").setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
near_ = body;
}
});
item.getChild("latitude").setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
lat_ = body;
}
});
item.getChild("longitude").setEndTextElementListener(new EndTextElementListener(){
public void end(String body) {
lon_ = body;
}
});

return root.getContentHandler();
} // contentHandler

@Override
protected GeoPlaces get()
{
return places_;
} // get
} // POICategoriesFactory
} // class GeoPlaces
throws IOException {
return ApiClient.geoCoder(searchTerm,
bounds.getLatNorthE6() / 1E6,
bounds.getLatSouthE6() / 1E6,
bounds.getLonEastE6() / 1E6,
bounds.getLonWestE6() / 1E6);
}
}
Expand Up @@ -3,9 +3,11 @@
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import net.cyclestreets.api.GeoPlaces;
import net.cyclestreets.api.POI;
import net.cyclestreets.api.Photos;
import net.cyclestreets.api.UserJourneys;
import net.cyclestreets.api.client.dto.GeoPlacesDto;
import net.cyclestreets.api.client.dto.UserJourneysDto;
import net.cyclestreets.api.client.geojson.PhotosFactory;
import net.cyclestreets.api.client.geojson.PoiFactory;
Expand All @@ -14,13 +16,13 @@

import java.io.IOException;
import java.util.List;
import java.util.Map;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

public class RetrofitApiClient {

Expand All @@ -38,10 +40,10 @@ public RetrofitApiClient(Builder builder) {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Retrofit retrofitV1 = new Retrofit.Builder()
.client(client)
.addConverterFactory(JacksonConverterFactory.create(objectMapper))
.baseUrl(builder.v1Host)
.build();
.client(client)
.addConverterFactory(SimpleXmlConverterFactory.createNonStrict())
.baseUrl(builder.v1Host)
.build();
v1Api = retrofitV1.create(V1Api.class);

Retrofit retrofitV2 = new Retrofit.Builder()
Expand Down Expand Up @@ -76,6 +78,22 @@ public RetrofitApiClient build() {
}
}

// --------------------------------------------------------------------------------
// V1 APIs
// --------------------------------------------------------------------------------
public GeoPlaces geoCoder(final String search,
final double n,
final double s,
final double e,
final double w) throws IOException {
Response<GeoPlacesDto> response = v1Api.geoCoder(search, n, s, e, w).execute();
return response.body().toGeoPlaces();
}

// --------------------------------------------------------------------------------
// V2 APIs
// --------------------------------------------------------------------------------

public List<POI> getPOIs(final String type,
final double lonE,
final double lonW,
Expand Down
@@ -1,6 +1,17 @@
package net.cyclestreets.api.client;

import net.cyclestreets.api.client.dto.GeoPlacesDto;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface V1Api {

// Pending
@GET("/api/geocoder.xml?countrycodes=gb,ie")
Call<GeoPlacesDto> geoCoder(@Query("street") String search,
@Query("n") double n,
@Query("s") double s,
@Query("e") double e,
@Query("w") double w);
}
@@ -0,0 +1,26 @@
package net.cyclestreets.api.client.dto;

import net.cyclestreets.api.GeoPlace;

import org.osmdroid.util.GeoPoint;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root(name = "result")
public class GeoPlaceDto {

@Element
private String name;
@Element
private String near;
@Element
private String type;
@Element
private double longitude;
@Element
private double latitude;

public GeoPlace toGeoPlace() {
return new GeoPlace(new GeoPoint(latitude, longitude), name, near);
}
}

0 comments on commit d18cb8f

Please sign in to comment.