-
-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathGeocoding.java
More file actions
191 lines (171 loc) · 6.74 KB
/
Geocoding.java
File metadata and controls
191 lines (171 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package com.baseflow.geocoding;
import androidx.annotation.Nullable;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Build;
import androidx.annotation.RequiresApi;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Geocoding components to lookup address or coordinates.
*/
class Geocoding {
private final Context androidContext;
@Nullable
private Locale locale;
/**
* Uses the given {@code androidContext} to execute geocoding features
*
* @param androidContext the context to use when requesting geocoding features
*/
Geocoding(Context androidContext) {
this.androidContext = androidContext;
}
void setLocaleIdentifier(@Nullable Locale locale) {
this.locale = locale;
}
/**
* Returns true if there is a geocoder implementation present that may return results.
* If true, there is still no guarantee that any individual geocoding attempt will succeed.
*
*/
boolean isPresent() {
return Geocoder.isPresent();
}
/**
* Returns a list of Address objects matching the supplied address string.
*
* @param address the address string for the search
* @param callback the GeocodeListenerAdapter that listens for success or error
* @return a list of Address objects. Returns null or empty list if no matches were found or there is no backend service available.
*/
void placemarkFromAddress(
String address,
Double lowerLeftLatitude,
Double lowerLeftLongitude,
Double upperRightLatitude,
Double upperRightLongitude,
GeocodeListenerAdapter callback
) {
final Geocoder geocoder = createGeocoder(androidContext, locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getAddressesWithGeocodeListener(
geocoder,
address,
5,
lowerLeftLatitude,
lowerLeftLongitude,
upperRightLatitude,
upperRightLongitude,
callback
);
} else {
try {
List<Address> addresses = deprecatedGetFromLocationName(
geocoder,
address,
lowerLeftLatitude,
lowerLeftLongitude,
upperRightLatitude,
upperRightLongitude
);
callback.onGeocode(addresses);
} catch (IOException ex) {
callback.onError(ex.getMessage());
}
}
}
@SuppressWarnings("deprecation")
private List<Address> deprecatedGetFromLocationName(
Geocoder geocoder,
String address,
Double lowerLeftLatitude,
Double lowerLeftLongitude,
Double upperRightLatitude,
Double upperRightLongitude
) throws IOException {
if (lowerLeftLatitude == null || lowerLeftLongitude == null || upperRightLatitude == null || upperRightLongitude == null) {
return geocoder.getFromLocationName(address, 5);
} else {
return geocoder.getFromLocationName(address, 5, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude);
}
}
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
private void getAddressesWithGeocodeListener(
Geocoder geocoder,
String address,
int maxResults,
Double lowerLeftLatitude,
Double lowerLeftLongitude,
Double upperRightLatitude,
Double upperRightLongitude,
GeocodeListenerAdapter callback
) {
final Geocoder.GeocodeListener listener = new Geocoder.GeocodeListener() {
@Override
public void onGeocode(List<Address> geocodedAddresses) {
callback.onGeocode(geocodedAddresses);
}
@Override
public void onError(@Nullable String errorMessage) {
callback.onError(errorMessage);
}
};
if (lowerLeftLatitude == null || lowerLeftLongitude == null || upperRightLatitude == null || upperRightLongitude == null) {
geocoder.getFromLocationName(address, maxResults, listener);
} else {
geocoder.getFromLocationName(address, maxResults, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude, listener);
}
}
/**
* Returns a list of Address objects matching the supplied coordinates.
*
* @param latitude the latitude point for the search
* @param longitude the longitude point for the search
* @param callback the GeocodeListenerAdapter that listens for success or error
* @return a list of Address objects. Returns null or empty list if no matches were found or there is no backend service available.
*/
void placemarkFromCoordinates(
double latitude,
double longitude,
GeocodeListenerAdapter callback
) {
final Geocoder geocoder = createGeocoder(androidContext, locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
getLocationWithGeocodeListener(geocoder, latitude, longitude, 5, callback);
} else {
try {
List<Address> addresses = deprecatedGetFromLocation(geocoder, latitude, longitude);
callback.onGeocode(addresses);
} catch (IOException ex) {
callback.onError(ex.getMessage());
}}
}
@SuppressWarnings("deprecation")
private List<Address> deprecatedGetFromLocation(Geocoder geocoder,
double latitude,
double longitude) throws IOException {
return geocoder.getFromLocation(latitude, longitude, 5);
}
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
private void getLocationWithGeocodeListener(Geocoder geocoder, double latitude, double longitude, int maxResults, GeocodeListenerAdapter callback) {
geocoder.getFromLocation(latitude, longitude, maxResults, new Geocoder.GeocodeListener() {
@Override
public void onGeocode(List<Address> geocodedAddresses) {
callback.onGeocode(geocodedAddresses);
}
@Override
public void onError(@Nullable String errorMessage) {
callback.onError(errorMessage);
}
});
}
private static Geocoder createGeocoder(Context androidContext, @Nullable Locale locale) {
return (locale != null)
? new Geocoder(androidContext, locale)
: new Geocoder(androidContext);
}
}