Skip to content

Commit 86dc1c7

Browse files
committed
added higher level API calls to scenario
1 parent 13ad018 commit 86dc1c7

File tree

4 files changed

+379
-59
lines changed

4 files changed

+379
-59
lines changed

javav2/example_code/location/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
<artifactId>gson</artifactId>
7575
<version>2.10.1</version>
7676
</dependency>
77+
<dependency>
78+
<groupId>software.amazon.awssdk</groupId>
79+
<artifactId>geoplaces</artifactId>
80+
</dependency>
7781
<dependency>
7882
<groupId>software.amazon.awssdk</groupId>
7983
<artifactId>sso</artifactId>

javav2/example_code/location/src/main/java/com/example/location/scenario/LocationActions.java

Lines changed: 175 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,18 @@
55

66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
8+
import software.amazon.awssdk.services.geoplaces.GeoPlacesAsyncClient;
89
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
910
import software.amazon.awssdk.core.retry.RetryMode;
1011
import software.amazon.awssdk.http.async.SdkAsyncHttpClient;
1112
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
13+
import software.amazon.awssdk.services.geoplaces.model.GetPlaceRequest;
14+
import software.amazon.awssdk.services.geoplaces.model.ReverseGeocodeRequest;
15+
import software.amazon.awssdk.services.geoplaces.model.ReverseGeocodeResponse;
16+
import software.amazon.awssdk.services.geoplaces.model.SearchNearbyRequest;
17+
import software.amazon.awssdk.services.geoplaces.model.SearchNearbyResponse;
18+
import software.amazon.awssdk.services.geoplaces.model.SearchTextRequest;
19+
import software.amazon.awssdk.services.geoplaces.model.SearchTextResponse;
1220
import software.amazon.awssdk.services.location.LocationAsyncClient;
1321
import software.amazon.awssdk.services.location.model.ApiKeyRestrictions;
1422
import software.amazon.awssdk.services.location.model.BatchUpdateDevicePositionRequest;
@@ -45,14 +53,18 @@
4553
import software.amazon.awssdk.services.location.paginators.ListGeofencesPublisher;
4654
import java.time.Duration;
4755
import java.time.Instant;
56+
import java.util.ArrayList;
4857
import java.util.Arrays;
4958
import java.util.List;
5059
import java.util.concurrent.CompletableFuture;
5160
import java.util.concurrent.CompletionException;
5261

62+
// snippet-start:[location.java2.actions.main]
5363
public class LocationActions {
5464

5565
private static LocationAsyncClient locationAsyncClient;
66+
67+
private static GeoPlacesAsyncClient geoPlacesAsyncClient;
5668
private static final Logger logger = LoggerFactory.getLogger(LocationActions.class);
5769

5870
// This Singleton pattern ensures that only one `LocationClient`
@@ -80,6 +92,140 @@ private LocationAsyncClient getClient() {
8092
return locationAsyncClient;
8193
}
8294

95+
private static GeoPlacesAsyncClient getGeoPlacesClient() {
96+
if (geoPlacesAsyncClient == null) {
97+
SdkAsyncHttpClient httpClient = NettyNioAsyncHttpClient.builder()
98+
.maxConcurrency(100)
99+
.connectionTimeout(Duration.ofSeconds(60))
100+
.readTimeout(Duration.ofSeconds(60))
101+
.writeTimeout(Duration.ofSeconds(60))
102+
.build();
103+
104+
ClientOverrideConfiguration overrideConfig = ClientOverrideConfiguration.builder()
105+
.apiCallTimeout(Duration.ofMinutes(2))
106+
.apiCallAttemptTimeout(Duration.ofSeconds(90))
107+
.retryStrategy(RetryMode.STANDARD)
108+
.build();
109+
110+
geoPlacesAsyncClient = GeoPlacesAsyncClient.builder()
111+
.httpClient(httpClient)
112+
.overrideConfiguration(overrideConfig)
113+
.build();
114+
}
115+
return geoPlacesAsyncClient;
116+
}
117+
118+
public void searchNearBy() {
119+
double latitude = 37.7749; // San Francisco
120+
double longitude = -122.4194;
121+
List<Double> queryPosition = List.of(longitude, latitude);
122+
123+
// Set up the request for searching nearby places
124+
SearchNearbyRequest request = SearchNearbyRequest.builder()
125+
.queryPosition(queryPosition) // Set the position (latitude, longitude)
126+
.queryRadius(1000L) // Radius in meters (1000 meters = 1 km)
127+
.build();
128+
129+
CompletableFuture<SearchNearbyResponse> futureResponse = getGeoPlacesClient().searchNearby(request);
130+
131+
futureResponse.whenComplete((response, exception) -> {
132+
if (exception != null) {
133+
throw new RuntimeException("Error performing nearby search", exception);
134+
}
135+
136+
// Process the response and print the results
137+
response.resultItems().forEach(result -> {
138+
System.out.println("Place Name: " + result.placeType().name());
139+
System.out.println("Address: " + result.address().label());
140+
System.out.println("Distance: " + result.distance() + " meters");
141+
System.out.println("-------------------------");
142+
});
143+
}).join(); // Ensures the main thread waits for completion
144+
}
145+
146+
147+
public void searchText(String searchQuery) {
148+
double latitude = 37.7749; // San Francisco
149+
double longitude = -122.4194;
150+
List<Double> queryPosition = List.of(longitude, latitude);
151+
152+
SearchTextRequest request = SearchTextRequest.builder()
153+
.queryText(searchQuery) // Search for "coffee shop"
154+
.biasPosition(queryPosition)
155+
.build();
156+
157+
// Asynchronous search request
158+
CompletableFuture<SearchTextResponse> futureResponse = getGeoPlacesClient().searchText(request);
159+
160+
futureResponse.whenComplete((response, exception) -> {
161+
if (exception != null) {
162+
throw new RuntimeException("Error performing place search", exception);
163+
}
164+
165+
// Process the response and fetch detailed information about the place
166+
response.resultItems().stream().findFirst().ifPresent(result -> {
167+
String placeId = result.placeId(); // Get Place ID
168+
System.out.println("Found Place with id: " + placeId);
169+
170+
// Fetch detailed info using getPlace()
171+
GetPlaceRequest getPlaceRequest = GetPlaceRequest.builder()
172+
.placeId(placeId)
173+
.build();
174+
175+
getGeoPlacesClient().getPlace(getPlaceRequest)
176+
.whenComplete((placeResponse, placeException) -> {
177+
if (placeException != null) {
178+
throw new CompletionException("Error fetching place details", placeException);
179+
}
180+
181+
// Print detailed place information
182+
System.out.println("Detailed Place Information:");
183+
System.out.println("Name: " + placeResponse.placeType().name());
184+
System.out.println("Address: " + placeResponse.address().label());
185+
186+
// Print each food type (if any)
187+
if (placeResponse.foodTypes() != null && !placeResponse.foodTypes().isEmpty()) {
188+
System.out.println("Food Types:");
189+
placeResponse.foodTypes().forEach(foodType -> {
190+
System.out.println(" - " + foodType);
191+
});
192+
} else {
193+
System.out.println("No food types available.");
194+
}
195+
196+
System.out.println("-------------------------");
197+
}).join(); // Waits for getPlace response
198+
});
199+
}).join(); // Ensures main thread waits for completion
200+
}
201+
202+
203+
public void reverseGeocode() {
204+
double latitude = 37.7749; // San Francisco
205+
double longitude = -122.4194;
206+
System.out.println("Use latitude 37.7749 and longitude -122.4194");
207+
208+
// AWS expects [longitude, latitude]
209+
List<Double> queryPosition = List.of(longitude, latitude);
210+
ReverseGeocodeRequest request = ReverseGeocodeRequest.builder()
211+
.queryPosition(queryPosition)
212+
.build();
213+
CompletableFuture<ReverseGeocodeResponse> futureResponse =
214+
getGeoPlacesClient().reverseGeocode(request);
215+
216+
futureResponse.whenComplete((response, exception) -> {
217+
if (exception != null) {
218+
throw new CompletionException("Error performing reverse geocoding", exception);
219+
}
220+
221+
response.resultItems().forEach(result ->
222+
System.out.println("The address is: " + result.address().label())
223+
);
224+
}).join(); // Ensures main thread waits for completion
225+
}
226+
227+
228+
// snippet-start:[location.java2.calc.distance.main]
83229
/**
84230
* Calculates the distance between two locations asynchronously.
85231
*
@@ -103,7 +249,7 @@ public CompletableFuture<CalculateRouteResponse> calcDistanceAsync(String routeC
103249
.whenComplete((response, exception) -> {
104250
if (response != null) {
105251
logger.info("Total Distance: " + response.summary().distance() + " km");
106-
logger.info("Estimated Duration: " + response.summary().durationSeconds() / 60 + " minutes");
252+
logger.info("Estimated Duration by car is: " + response.summary().durationSeconds() / 60 + " minutes");
107253
} else {
108254
if (exception == null) {
109255
throw new CompletionException("An unknown error occurred while calculating route.", null);
@@ -118,7 +264,9 @@ public CompletableFuture<CalculateRouteResponse> calcDistanceAsync(String routeC
118264
}
119265
});
120266
}
267+
// snippet-end:[location.java2.calc.distance.main]
121268

269+
// snippet-start:[location.java2.create.calculator.main]
122270
/**
123271
* Creates a new route calculator with the specified name and data source.
124272
*
@@ -148,7 +296,9 @@ public CompletableFuture<CreateRouteCalculatorResponse> createRouteCalculator(St
148296
}
149297
});
150298
}
299+
// snippet-end:[location.java2.create.calculator.main]
151300

301+
// snippet-start:[location.java2.get.device.position.main]
152302
/**
153303
* Retrieves the position of a device using the provided LocationClient.
154304
*
@@ -180,7 +330,9 @@ public CompletableFuture<GetDevicePositionResponse> getDevicePosition(String tra
180330
}
181331
});
182332
}
333+
// snippet-end:[location.java2.get.device.position.main]
183334

335+
// snippet-start:[location.java2.update.device.position.main]
184336
/**
185337
* Updates the position of a device in the location tracking system.
186338
*
@@ -223,7 +375,9 @@ public CompletableFuture<BatchUpdateDevicePositionResponse> updateDevicePosition
223375
}
224376
});
225377
}
378+
// snippet-end:[location.java2.update.device.position.main]
226379

380+
// snippet-start:[location.java2.create.tracker.main]
227381
/**
228382
* Creates a new tracker resource in your AWS account, which you can use to track the location of devices.
229383
*
@@ -254,13 +408,9 @@ public CompletableFuture<String> createTracker(String trackerName) {
254408
}
255409
}).thenApply(CreateTrackerResponse::trackerArn); // Return tracker ARN
256410
}
411+
// snippet-start:[location.java2.create.tracker.main]
257412

258-
/**
259-
* Lists the geofences in the specified collection.
260-
*
261-
* @param collectionName the name of the geofence collection to list
262-
*/
263-
413+
// snippet-start:[location.java2.put.geo.main]
264414
/**
265415
* Adds a new geofence to the specified collection.
266416
*
@@ -304,7 +454,9 @@ public CompletableFuture<PutGeofenceResponse> putGeofence(String collectionName,
304454
}
305455
});
306456
}
457+
// snippet-end:[location.java2.put.geo.main]
307458

459+
// snippet-start:[location.java2.create.collection.main]
308460
/**
309461
* Creates a new geofence collection.
310462
*
@@ -333,7 +485,9 @@ public CompletableFuture<CreateGeofenceCollectionResponse> createGeofenceCollect
333485
}
334486
});
335487
}
488+
// snippet-end:[location.java2.create.collection.main]
336489

490+
// snippet-start:[location.java2.create.key.main]
337491
/**
338492
* Creates a new API key with the specified name and restrictions.
339493
*
@@ -372,7 +526,9 @@ public CompletableFuture<String> createKey(String keyName, String mapArn) {
372526
}
373527
}).thenApply(response -> response != null ? response.keyArn() : null); // Return the key ARN
374528
}
529+
// snippet-end:[location.java2.create.key.main]
375530

531+
// snippet-start:[location.java2.create.map.main]
376532
/**
377533
* Creates a new map with the specified name and configuration.
378534
*
@@ -408,7 +564,9 @@ public CompletableFuture<String> createMap(String mapName) {
408564
}
409565
}).thenApply(response -> response != null ? response.mapArn() : null); // Return the map ARN
410566
}
567+
// snippet-end:[location.java2.create.map.main]
411568

569+
// snippet-start:[location.java2.delete.collection.main]
412570
/**
413571
* Deletes a geofence collection asynchronously.
414572
*
@@ -438,7 +596,9 @@ public CompletableFuture<Void> deleteGeofenceCollectionAsync(String collectionNa
438596
}
439597
}).thenApply(response -> null); // Ensures the method returns CompletableFuture<Void>
440598
}
599+
// snippet-end:[location.java2.delete.collection.main]
441600

601+
// snippet-start:[location.java2.delete.key.main]
442602
/**
443603
* Deletes the specified key from the key-value store.
444604
*
@@ -469,7 +629,9 @@ public CompletableFuture<Void> deleteKey(String keyName) {
469629
}
470630
}).thenApply(response -> null); // Ensures the method returns CompletableFuture<Void>
471631
}
632+
// snippet-end:[location.java2.delete.key.main]
472633

634+
// snippet-start:[location.java2.delete.map.main]
473635
/**
474636
* Deletes a map with the specified name.
475637
*
@@ -499,7 +661,9 @@ public CompletableFuture<Void> deleteMap(String mapName) {
499661
}
500662
}).thenApply(response -> null);
501663
}
664+
// snippet-end:[location.java2.delete.map.main]
502665

666+
// snippet-start:[location.java2.delete.tracker.main]
503667
/**
504668
* Deletes a tracker with the specified name.
505669
*
@@ -532,7 +696,9 @@ public CompletableFuture<Void> deleteTracker(String trackerName) {
532696
}
533697
}).thenApply(response -> null);
534698
}
699+
// snippet-end:[location.java2.delete.tracker.main]
535700

701+
// snippet-start:[location.java2.delete.calculator.main]
536702
/**
537703
* Deletes a route calculator from the system.
538704
*
@@ -565,5 +731,6 @@ public CompletableFuture<Void> deleteRouteCalculator(String calcName) {
565731
}
566732
}).thenApply(response -> null);
567733
}
734+
// snippet-end:[location.java2.delete.calculator.main]
568735
}
569-
736+
// snippet-end:[location.java2.actions.main]

javav2/example_code/location/src/main/java/com/example/location/scenario/LocationScenario.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ public static void main(String[] args) {
3636
// System.exit(1);
3737
// }
3838

39-
String mapName = "MyMap" ; //args[0];
40-
String keyName = "MyLocationKey" ; //args[1];
41-
String collectionName = "AWSLocationCollection" ; //args[2];
42-
String geoId = "geoId1"; //args[4];
43-
String trackerName = "geoTracker1"; //args[5];
44-
String calculatorName = "AWSRouteCalc32"; //args[6];
39+
String mapName = "MyMap40" ; //args[0];
40+
String keyName = "MyLocationKey40" ; //args[1];
41+
String collectionName = "AWSLocationCollection40" ; //args[2];
42+
String geoId = "geoId40"; //args[4];
43+
String trackerName = "geoTracker40"; //args[5];
44+
String calculatorName = "AWSRouteCalc40"; //args[6];
4545
String deviceId = "iPhone-112359" ; //args[7];
4646

4747
logger.info("""
@@ -183,7 +183,30 @@ restrict API keys to specific AWS Location operations (e.g., only
183183
waitForInputToContinue(scanner);
184184
logger.info(DASHES);
185185

186-
logger.info("11. Delete the AWS Location Services resources.");
186+
logger.info("11. AWS Location Services exposes higher level APIs to perform additional operations.");
187+
logger.info("""
188+
This scenario will show use of the GeoPlacesClient that enables
189+
location search and geocoding capabilities for your applications.\s
190+
191+
We are going to use this client to perform these tasks:
192+
- Reverse Geocoding (reverseGeocode): Converts geographic coordinates into addresses.
193+
- Place Search (searchText): Finds places based on search queries.
194+
- Nearby Search (searchNearby): Finds places near a specific location.
195+
""");
196+
197+
logger.info("First we will perform a Reverse Geocoding operation");
198+
waitForInputToContinue(scanner);
199+
locationActions.reverseGeocode();
200+
logger.info("Now we are going to perform a text search using coffee shop.");
201+
waitForInputToContinue(scanner);
202+
locationActions.searchText("coffee shop");
203+
204+
logger.info("Now we are going to perform a nearby Search.");
205+
waitForInputToContinue(scanner);
206+
locationActions.searchNearBy();
207+
logger.info(DASHES);
208+
209+
logger.info("12. Delete the AWS Location Services resources.");
187210
logger.info("Would you like to delete the AWS Location Services resources? (y/n)");
188211
String delAns = scanner.nextLine().trim();
189212
if (delAns.equalsIgnoreCase("y")) {

0 commit comments

Comments
 (0)