Skip to content

Commit

Permalink
Corrected format, removed API key
Browse files Browse the repository at this point in the history
  • Loading branch information
Diego committed Feb 7, 2024
1 parent 7121e3c commit dcf0b2c
Show file tree
Hide file tree
Showing 11 changed files with 1,508 additions and 1,495 deletions.
Original file line number Diff line number Diff line change
@@ -1,60 +1,36 @@
package org.integratedmodelling.random.adapters;

import java.util.List;
import java.util.Map;

import org.integratedmodelling.klab.exceptions.KlabException;

public class RecreationIDB {

private boolean isOnline = false;
RecreationIDBRuntimeEnvironment ribd;
RecreationIDBOutputDeserializer deserializer;
public String service = "";

public RecreationIDB(){
this("https://ridb.recreation.gov/api/v1");
}

public RecreationIDB(String serviceUrl){
this.service = serviceUrl;
ribd = new RecreationIDBRuntimeEnvironment(service);
isOnline = ribd.isOnline();
deserializer = new RecreationIDBOutputDeserializer();

}

public boolean isOnline() {
return isOnline;
}

public RecreationIDBOutputDeserializer.RecreationAreas recreationAreas(String input, String apiKey) throws KlabException{
String response = ribd.recreationIDBSendRequest(input, RecreationIDBRuntimeEnvironment.RecreationIDBRequestType.RecAreas, apiKey);
deserializer.setJson(response);
return deserializer.deserializeRecAreasData();
}

public static void main(String[] args) throws KlabException {

RecreationIDB ridb = new RecreationIDB();

// String input = "limit=1&offset=0&state=CO&activity=6,BOATING&radius=9.75";

// String input = "offset=0&activity=1&limit=10&state=CO&radius=10.0";

String input = "offset=0&state=CO&radius=20";

final String apiKey = "82b00cad-58b5-40e8-9d77-77caba299473";

RecreationIDBOutputDeserializer.RecreationAreas recreationAreas = ridb.recreationAreas(input,apiKey);

List<Map<String, Object>> list = recreationAreas.getData();
System.out.println(list);
System.out.println(list.size());

}



private boolean isOnline = false;
RecreationIDBRuntimeEnvironment ribd;
RecreationIDBOutputDeserializer deserializer;
public String service = "";

public RecreationIDB() {
this("https://ridb.recreation.gov/api/v1");
}

public RecreationIDB(String serviceUrl) {
this.service = serviceUrl;
ribd = new RecreationIDBRuntimeEnvironment(service);
isOnline = ribd.isOnline();
deserializer = new RecreationIDBOutputDeserializer();

}

public boolean isOnline() {
return isOnline;
}

public RecreationIDBOutputDeserializer.RecreationAreas recreationAreas(String input, String apiKey)
throws KlabException {
String response = ribd.recreationIDBSendRequest(input,
RecreationIDBRuntimeEnvironment.RecreationIDBRequestType.RecAreas, apiKey);
deserializer.setJson(response);
return deserializer.deserializeRecAreasData();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,152 +31,148 @@
public class RecreationIDBAdapter implements IUrnAdapter {

public static final String NAME = "ridb";

public static final String RECAREAS = "recreation.areas";

public static final String SITES = "sites";

public static final String LIMIT = "limit";
public static final String OFFSET = "offset";
public static final String STATE = "state";
public static final String ACTIVITY = "activity";
public static final String RADIUS = "radius";
public static final String APIKEY = "apikey";

public static final String APIKEY = "apikey";

// TODO: complete other possible namespaces.
public static String[] namespace_ids = new String[] { RECAREAS };
public static String[] area_attribute_ids = new String[] { LIMIT, OFFSET, STATE, ACTIVITY, RADIUS};
public RecreationIDBAdapter() {
public static String[] area_attribute_ids = new String[] { LIMIT, OFFSET, STATE, ACTIVITY, RADIUS };

public RecreationIDBAdapter() {
Arrays.sort(area_attribute_ids);
Arrays.sort(namespace_ids);
}

@Override
public String getName() {
return NAME;
}

@Override
public boolean isOnline(Urn urn) {
//TODO
// TODO
return true;
}

@Override
public void encodeData(Urn urn, Builder builder, IGeometry geometry, IContextualizationScope scope) {
Map<String,String> parameters = new HashMap<>();
if (urn.getParameters().containsKey(LIMIT)){
parameters.put(LIMIT,urn.getParameters().get(LIMIT));
}
public void encodeData(Urn urn, Builder builder, IGeometry geometry, IContextualizationScope scope) {

Map<String, String> parameters = new HashMap<>();
if (urn.getParameters().containsKey(LIMIT)) {
parameters.put(LIMIT, urn.getParameters().get(LIMIT));
}
if (urn.getParameters().containsKey(OFFSET)) {
parameters.put(OFFSET, urn.getParameters().get(OFFSET));
}
}
if (urn.getParameters().containsKey(STATE)) {
parameters.put(STATE,urn.getParameters().get(STATE));
}
parameters.put(STATE, urn.getParameters().get(STATE));
}
if (urn.getParameters().containsKey(ACTIVITY)) {
parameters.put(ACTIVITY,urn.getParameters().get(ACTIVITY)) ;
}
if (urn.getParameters().containsKey(RADIUS) ) {
parameters.put(RADIUS,urn.getParameters().get(RADIUS));
parameters.put(ACTIVITY, urn.getParameters().get(ACTIVITY));
}
if (urn.getParameters().containsKey(RADIUS)) {
parameters.put(RADIUS, urn.getParameters().get(RADIUS));
} else {
parameters.put(RADIUS,"0.0");
parameters.put(RADIUS, "0.0");
}
String apiKey = urn.getParameters().containsKey(APIKEY)
? urn.getParameters().get(APIKEY)
: "82b00cad-58b5-40e8-9d77-77caba299473";

IScale scale = geometry instanceof IScale ? (IScale) geometry : Scale.create(geometry);

if (scale.getSpace() != null) {
RecreationIDB ridb = new RecreationIDB();
List<String> inputs = buildRecreationIDBInput(parameters);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
inputs.forEach(input -> data.addAll(ridb.recreationAreas(input,apiKey).getData()));

IShape shape;
for (Map<String,Object> area : data) {
double lat = (double) area.get("lat");
double lon = (double) area.get("lon");
String siteName = (String) area.get("name");
// Create the point.
// TODO: in the general case recreation areas should be polygons while entrances to the areas are points.
shape = Shape.create(lon,lat,(Projection) scope.getScale().getSpace().getProjection());
Builder obuilder = builder.startObject(scope.getTargetName(), siteName, makeScale(urn, shape, scope));
// Add attributes to each recreation area like the name and id.
for (Map.Entry<String, Object> entry : area.entrySet()) {
if (entry.getKey()!="lat" || entry.getKey()!="lon" || entry.getKey()!="name") {
obuilder.withMetadata(entry.getKey(), entry.getValue());
}
}
obuilder.finishObject();
}
}

// API key must be defined as parameter in the URN
String apiKey = urn.getParameters().containsKey(APIKEY) ? urn.getParameters().get(APIKEY) : null;

IScale scale = geometry instanceof IScale ? (IScale) geometry : Scale.create(geometry);

if (scale.getSpace() != null) {
RecreationIDB ridb = new RecreationIDB();
List<String> inputs = buildRecreationIDBInput(parameters);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
inputs.forEach(input -> data.addAll(ridb.recreationAreas(input, apiKey).getData()));

IShape shape;

for (Map<String, Object> area : data) {

double lat = (double) area.get("lat");
double lon = (double) area.get("lon");
String siteName = (String) area.get("name");

// Create the point.
// TODO: in the general case recreation areas should be polygons while entrances
// to the areas are points.
shape = Shape.create(lon, lat, (Projection) scope.getScale().getSpace().getProjection());

Builder obuilder = builder.startObject(scope.getTargetName(), siteName, makeScale(urn, shape, scope));

// Add attributes to each recreation area like the name and id.
for (Map.Entry<String, Object> entry : area.entrySet()) {
if (entry.getKey() != "lat" || entry.getKey() != "lon" || entry.getKey() != "name") {
obuilder.withMetadata(entry.getKey(), entry.getValue());
}
}
obuilder.finishObject();

}

}

}

// TODO: There's a limit of 1000 entries hardcoded in the API. To make sure that we retrieve everything and with the ad hoc knowledge that
// there's always less than 1000 recreation sites per US state, when there are N states passed as arguments create N different GET calls to
// the API one per each state and assemble later all the responses. In the case no state parameter is specified default is retrieving from
// the entire US territory, in that case have a list of all the states hardcoded and create one GET message per state. Eventually it would
// be ideal to identify automatically the states involved and also reject responses out of the geographical scope of the context.
private final List<String> USA_STATES = Arrays.asList("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID",
"IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM",
"NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY");
private List<String> buildRecreationIDBInput(Map<String,String> parameters) {
ArrayList<String> query = new ArrayList<>();
List<String> states = parameters.containsKey(STATE) ? Arrays.asList(parameters.get(STATE).split(",")) : USA_STATES;
for(Map.Entry<String, String> entry : parameters.entrySet()) {
if (entry.getKey().equals(STATE)) {
continue;
}
query.add(entry.getKey()+"="+entry.getValue());
}
String finalQuery = String.join("&", query);
return states.stream().map(state -> finalQuery + "&" + STATE + "=" + state).toList();
}



private final List<String> USA_STATES = Arrays.asList("AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA",
"HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV",
"NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA",
"WA", "WV", "WI", "WY");

private List<String> buildRecreationIDBInput(Map<String, String> parameters) {
ArrayList<String> query = new ArrayList<>();
List<String> states = parameters.containsKey(STATE) ? Arrays.asList(parameters.get(STATE).split(","))
: USA_STATES;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
if (entry.getKey().equals(STATE)) {
continue;
}
query.add(entry.getKey() + "=" + entry.getValue());
}
String finalQuery = String.join("&", query);
return states.stream().map(state -> finalQuery + "&" + STATE + "=" + state).toList();
}

private IGeometry makeScale(Urn urn, IShape shape, IContextualizationScope scope) {
List<IExtent> extents = new ArrayList<>();
extents.add(scope.getContextSubject().getScale().getTime());
extents.add(shape);
return Scale.create(extents).asGeometry();
}
List<IExtent> extents = new ArrayList<>();
extents.add(scope.getContextSubject().getScale().getTime());
extents.add(shape);
return Scale.create(extents).asGeometry();
}

@Override
public IResource getResource(String urn) {
Urn kurn = new Urn(urn);
ResourceReference ref = new ResourceReference();
ref.setUrn(urn.toString());
ref.setAdapterType(getName());
ref.setLocalName(kurn.getResourceId());
ref.setGeometry("#S2");
ref.setVersion(Version.CURRENT);
ref.setType(getType(kurn));
return new Resource(ref);
ResourceReference ref = new ResourceReference();
ref.setUrn(urn.toString());
ref.setAdapterType(getName());
ref.setLocalName(kurn.getResourceId());
ref.setGeometry("#S2");
ref.setVersion(Version.CURRENT);
ref.setType(getType(kurn));
return new Resource(ref);
}

@Override
public IResource contextualize(IResource resource, IGeometry scale, IGeometry overallScale, IObservable semantics) {
return resource;
}


@Override
public Type getType(Urn urn) {
// Instances of recreation areas are all bounded objects: polygons or points.
// Instances of recreation areas are all bounded objects: polygons or points.
return Type.OBJECT;
}

Expand All @@ -194,9 +190,8 @@ public String getDescription() {
@Override
public Collection<String> getResourceUrns() {
List<String> ret = new ArrayList<>();
// TODO
return ret;
// TODO
return ret;
}



}
Loading

0 comments on commit dcf0b2c

Please sign in to comment.