Skip to content

Commit

Permalink
breaking: Add Address Descriptors to Geocoding response. (#954)
Browse files Browse the repository at this point in the history
feat: Add Address Descriptors to Geocoding response.

BREAKING CHANGE: Refactored Geocoding response to allow fields outside the GeocodingResult to be exposed through the client.

Co-authored-by: Tom Clifford <[email protected]>
Co-authored-by: Angela Yu <[email protected]>
  • Loading branch information
3 people authored Apr 3, 2024
1 parent 10e89b9 commit 6dab87c
Show file tree
Hide file tree
Showing 10 changed files with 1,178 additions and 36 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ This example uses the [Geocoding API] with an API key:
GeoApiContext context = new GeoApiContext.Builder()
.apiKey("AIza...")
.build();
GeocodingResult[] results = GeocodingApi.geocode(context,
GeocodingResponse response = GeocodingApi.geocode(context,
"1600 Amphitheatre Parkway Mountain View, CA 94043").await();
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(results[0].addressComponents));
System.out.println(gson.toJson(response.results[0].addressComponents));

// Invoke .shutdown() after your application is done making requests
context.shutdown();
Expand Down Expand Up @@ -205,9 +205,9 @@ try {
req.awaitIgnoreError(); // No checked exception.

// Async
req.setCallback(new PendingResult.Callback<GeocodingResult[]>() {
req.setCallback(new PendingResult.Callback<GeocodingResponse>() {
@Override
public void onResult(GeocodingResult[] result) {
public void onResult(GeocodingResponse result) {
// Handle successful request.
}

Expand Down
15 changes: 11 additions & 4 deletions src/main/java/com/google/maps/GeocodingApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import com.google.maps.errors.ApiException;
import com.google.maps.internal.ApiResponse;
import com.google.maps.model.AddressDescriptor;
import com.google.maps.model.GeocodingResponse;
import com.google.maps.model.GeocodingResult;
import com.google.maps.model.LatLng;

Expand Down Expand Up @@ -68,19 +70,24 @@ public static GeocodingApiRequest reverseGeocode(GeoApiContext context, LatLng l
return request;
}

public static class Response implements ApiResponse<GeocodingResult[]> {
/** Requests the street address of a {@code location}. */
public static class Response implements ApiResponse<GeocodingResponse> {
public String status;
public String errorMessage;
public GeocodingResult[] results;
public GeocodingResult results[];
public AddressDescriptor addressDescriptor;

@Override
public boolean successful() {
return "OK".equals(status) || "ZERO_RESULTS".equals(status);
}

@Override
public GeocodingResult[] getResult() {
return results;
public GeocodingResponse getResult() {
GeocodingResponse response = new GeocodingResponse();
response.results = results;
response.addressDescriptor = addressDescriptor;
return response;
}

@Override
Expand Down
15 changes: 13 additions & 2 deletions src/main/java/com/google/maps/GeocodingApiRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
import com.google.maps.internal.ApiConfig;
import com.google.maps.model.AddressType;
import com.google.maps.model.ComponentFilter;
import com.google.maps.model.GeocodingResult;
import com.google.maps.model.GeocodingResponse;
import com.google.maps.model.LatLng;
import com.google.maps.model.LocationType;

/** A request for the Geocoding API. */
public class GeocodingApiRequest
extends PendingResultBase<GeocodingResult[], GeocodingApiRequest, GeocodingApi.Response> {
extends PendingResultBase<GeocodingResponse, GeocodingApiRequest, GeocodingApi.Response> {

private static final ApiConfig API_CONFIG = new ApiConfig("/maps/api/geocode/json");

Expand Down Expand Up @@ -151,4 +151,15 @@ public GeocodingApiRequest resultType(AddressType... resultTypes) {
public GeocodingApiRequest locationType(LocationType... locationTypes) {
return param("location_type", join('|', locationTypes));
}

/**
* Determines whether the address descriptor is returned in the response.
*
* @param enableAddressDescriptor Flag to determine whether to return the address descriptor in
* the response.
* @return Returns this {@code GeocodingApiRequest} for call chaining.
*/
public GeocodingApiRequest enableAddressDescriptor(boolean enableAddressDescriptor) {
return param("enable_address_descriptor", String.valueOf(enableAddressDescriptor));
}
}
212 changes: 212 additions & 0 deletions src/main/java/com/google/maps/model/AddressDescriptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* Copyright 2024 Google Inc. All rights reserved.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.google.maps.model;

import java.io.Serializable;
import java.util.Arrays;

/**
* Represents a descriptor of an address.
*
* <p>Please see <a href="https://mapsplatform.google.com/demos/address-descriptors/">Address
* Descriptors</a> for more detail.
*/
public class AddressDescriptor implements Serializable {

private static final long serialVersionUID = 1L;

/** Points of interest that provide a reference point for a location. */
public static class Landmark implements Serializable {

private static final long serialVersionUID = 1L;

/**
* The Place ID of the underlying establishment serving as the landmark. Can be used to resolve
* more information about the landmark through Place Details or Place Id Lookup.
*/
public String placeId;

/** The best name for the landmark. */
public LocalizedText displayName;

/**
* One or more values indicating the type of the returned result. Please see <a
* href="https://developers.google.com/maps/documentation/places/web-service/supported_types">Types
* </a> for more detail.
*/
public String types[];

/** An enum representing the relationship in space between the landmark and the target. */
public enum SpatialRelationship {
/** This is the default relationship when nothing more specific below applies. */
NEAR("near"),
/** The landmark has a spatial geometry and the target is within its bounds. */
WITHIN("within"),
/** The target is directly adjacent to the landmark or landmark's access point. */
BESIDE("beside"),
/** The target is directly opposite the landmark on the other side of the road. */
ACROSS_THE_ROAD("across_the_road"),
/** On the same route as the landmark but not besides or across. */
DOWN_THE_ROAD("down_the_road"),
/** Not on the same route as the landmark but a single 'turn' away. */
AROUND_THE_CORNER("around_the_corner"),
/** Close to the landmark's structure but further away from its access point. */
BEHIND("behind");

private final String spatialRelationship;

SpatialRelationship(final String spatialRelationship) {
this.spatialRelationship = spatialRelationship;
}

@Override
public String toString() {
return spatialRelationship;
}

public String toCanonicalLiteral() {
return toString();
}
}

/** Defines the spatial relationship between the target location and the landmark. */
public SpatialRelationship spatialRelationship;

/**
* The straight-line distance between the target location and one of the landmark's access
* points.
*/
public float straightLineDistanceMeters;

/**
* The travel distance along the road network between the target location's closest point on a
* road, and the landmark's closest access point on a road. This can be unpopulated if the
* landmark is disconnected from the road network the target is closest to OR if the target
* location was not actually considered to be on the road network.
*/
public float travelDistanceMeters;

@Override
public String toString() {
StringBuilder sb = new StringBuilder("[Landmark: ");
if (placeId != null) {
sb.append("placeId=").append(placeId);
}
if (displayName != null) {
sb.append(", displayName=").append(displayName);
}
if (types != null && types.length > 0) {
sb.append(", types=").append(Arrays.toString(types));
}
if (spatialRelationship != null) {
sb.append(", spatialRelationship=").append(spatialRelationship);
}
sb.append(", straightLineDistanceMeters=").append(straightLineDistanceMeters);
sb.append(", travelDistanceMeters=").append(travelDistanceMeters);
sb.append("]");
return sb.toString();
}
}

/**
* A ranked list of nearby landmarks. The most useful (recognizable and nearby) landmarks are
* ranked first.
*/
public Landmark landmarks[];

/** Precise regions that are useful at describing a location. */
public static class Area implements Serializable {

private static final long serialVersionUID = 1L;

/**
* The Place ID of the underlying area feature. Can be used to resolve more information about
* the area through Place Details or Place Id Lookup.
*/
public String placeId;

/** The best name for the area. */
public LocalizedText displayName;

/** An enum representing the relationship in space between the area and the target. */
public enum Containment {
/** Indicates an unknown containment returned by the server. */
CONTAINMENT_UNSPECIFIED("containment_unspecified"),

/** The target location is within the area region, close to the center. */
WITHIN("within"),

/** The target location is within the area region, close to the edge. */
OUTSKIRTS("outskirts"),

/** The target location is outside the area region, but close by. */
NEAR("near");

private final String containment;

Containment(final String containment) {
this.containment = containment;
}

@Override
public String toString() {
return containment;
}

public String toCanonicalLiteral() {
return toString();
}
}

/** Defines the spatial relationship between the target location and the political region. */
public Containment containment;

@Override
public String toString() {
StringBuilder sb = new StringBuilder("[Area: ");
if (placeId != null) {
sb.append("placeId=").append(placeId);
}
if (displayName != null) {
sb.append(", displayName=").append(displayName);
}
if (containment != null) {
sb.append(", containment=").append(containment);
}
sb.append("]");
return sb.toString();
}
}

/**
* A ranked list of containing or adjacent areas. The most useful (recognizable and precise) areas
* are ranked first.
*/
public Area areas[];

@Override
public String toString() {
StringBuilder sb = new StringBuilder("[AddressDescriptor: ");
if (areas != null && areas.length > 0) {
sb.append("areas=").append(Arrays.toString(areas));
}
if (landmarks != null && landmarks.length > 0) {
sb.append(", landmarks=").append(Arrays.toString(landmarks));
}
sb.append("]");
return sb.toString();
}
}
47 changes: 47 additions & 0 deletions src/main/java/com/google/maps/model/GeocodingResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2024 Google Inc. All rights reserved.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.google.maps.model;

import java.io.Serializable;

/**
* The response from a Geocoding request.
*
* <p>Please see <a
* href="https://developers.google.com/maps/documentation/geocoding/requests-geocoding#GeocodingResponses">Geocoding
* Responses</a> for more detail.
*/
public class GeocodingResponse implements Serializable {

private static final long serialVersionUID = 1L;

/** The list of Geocoding Results. */
public GeocodingResult results[];

/** The Address Descriptor for the target. */
public AddressDescriptor addressDescriptor;

@Override
public String toString() {
StringBuilder sb = new StringBuilder("[GeocodingResponse: ");
sb.append(results.length).append(" results");
if (addressDescriptor != null) {
sb.append(", addressDescriptor=").append(addressDescriptor);
}
sb.append("]");
return sb.toString();
}
}
38 changes: 38 additions & 0 deletions src/main/java/com/google/maps/model/LocalizedText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2024 Google Inc. All rights reserved.
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
* ANY KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.google.maps.model;

import java.io.Serializable;

/** Localized variant of a text in a particular language. */
public class LocalizedText implements Serializable {

private static final long serialVersionUID = 1L;

/** Localized string in the language corresponding to language_code below. */
public String text;

/**
* The text's BCP-47 language code, such as "en-US" or "sr-Latn". For more information, see
* http://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
*/
public String languageCode;

@Override
public String toString() {
return String.format("(text=%d, languageCode=%d)", text, languageCode);
}
}
Loading

0 comments on commit 6dab87c

Please sign in to comment.