how to get the latitude and longitude by search location names with open street map osmdroid.
My Expectation is, It looks like implement google map places autocomplete, but I don't know how to make autocomplete places in osmdroid. I am not found any tutorial for search locations by location name with osmdroid
so I found this way to search location with osmdroid, but it's not what I expected. I am using geocoder to search the location here the reference
https://developer.android.com/reference/android/location/Geocoder
In the first step we need to make a search box Edittext to search the location and make the logic looks like this.
etSearch.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
etSearch.clearFocus()
val query = etSearch.text.toString()
if (query != "") {
getLocationName(query)
} else {
Toast.makeText(
requireContext(),
getString(R.string.mohon_isi_terlebih_dahulu),
Toast.LENGTH_SHORT
).show()
}
}
true
}
after getting the query text from the search box we need to call function getLocationName(String) and the function looks like this
fun getLocationName(locationName: String){
try {
val geocoder = Geocoder(requireContext(), Locale.getDefault())
var geoResults: List<Address> = geocoder.getFromLocationName("$locationName", 1)
if (geoResults.isNotEmpty()) {
val addr = geoResults[0]
val location = GeoPoint(addr.latitude, addr.longitude)
moveCameraMap(location)
}else{
Toast.makeText(requireContext(),"Location Not Found",Toast.LENGTH_LONG)
}
} catch (e: java.lang.Exception) {
print(e.message)
}
}
in the function we can see the geocoder call getFromLocationName("location name", max result), and we got the lat and long.
It's my solution and I hope someone can make it better. thanks for your help
Related
I have done as below in Kotlin to get the Address from LatLng using GeoCoder in Android :
private fun getAddress(latLng: LatLng): String {
// 1
val geocoder = Geocoder(this)
val addresses: List<Address>?
val address: Address?
var addressText = ""
try {
// 2
addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1)
// 3
if (null != addresses && !addresses.isEmpty()) {
address = addresses[0]
for (i in 0 until address.maxAddressLineIndex) {
addressText += if (i == 0) address.getAddressLine(i) else "\n" + address.getAddressLine(i)
}
}
} catch (e: IOException) {
Log.e("MapsActivity", e.localizedMessage)
}
Log.e("ADDRESS TEXT >>",""+addressText)
return addressText
}
But, Am getting 0 for address.maxAddressLineIndex.
address and addresses[0] has the values. I checked by debugging it.
And that's why my for loop is not executing inside.
What might be the issue? Any Solution please.
I’m not quite sure about what You are trying to implement but I believe You want to access an address based on given coordinates.
The for loop I believe is executing and like You said, it’s returning the value 0. This zero is not the number of addresses associated with the coordinates but the index at which the address You have supplied can be accessed for the available AddressLines.
So it means there is only one address at index zero.
So since You know it’s one address linked to the address line at those coordinates, then You can access the data at this index directly.
if (null != addresses && !addresses.isEmpty()) {
address = addresses[0]
addressText = “$address.locality , $address.latitude” //etc and other methods You can access.....
}
Hope that It helps but if You still want to access the addresses via the loop, its better You have the maximumAddressLine more than zero.
It worked well.
the problem that you are facing is that maxAddressLineIndex returns an index starting from 0.
The quickest fix is just to add 1 to the for loop as it goes until address.maxAddressLineIndex.
for (i in 0 until address.maxAddressLineIndex + 1) {
addressText += if (i == 0) address.getAddressLine(i) else "\n" + address.getAddressLine(i)
}
This should solve the problem.
So, in my project I need to check, every minute, if a user is in a given distance radius of a specified KML.
I searched methods from KmlDocument and FolderOverlay, but none of them give me a list of points or anything else to compare with my current location.
Here is how I get my KML and then apply the overlay to the map:
KmlDocument kmlDocument = new KmlDocument();
map.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);
if (trail.isDownloaded() && UtilsClass.getInstance().isNetworkAvailable(context) && trail.getFileKmlLocalPath() != null &&
!trail.getFileKmlLocalPath().isEmpty()) {
File kmlFile = new File(trail.getFileKmlLocalPath());
if (kmlFile.exists()) {
kmlDocument.parseKMLFile(kmlFile);
} else {
kmlDocument.parseKMLUrl(trail.getFileKml());
}
} else {
kmlDocument.parseKMLUrl(trail.getFileKml());
}
FolderOverlay kmOverlay = (FolderOverlay)
kmlDocument.mKmlRoot.buildOverlay(map, null, null, kmlDocument);
map.getOverlays().add(kmOverlay);
Is there a way to accomplish what I want/need?
Thanks in advance
The list of points for each KmlPlacemark (Point, LineString, and Polygon) are in KmlPlacemark.mGeometry.mCoordinates
In the map below I have three markers, the red one is the users current position while the green ones are the clickable markers.
Clicking the bottom one is not a problem. But clicking the one the user is close to is a different matter as the position marker is in the way. So for that one the user usually has to click 2 - 8 times before the green one is touched.
Is there a way to define that some markers are not clickable so they dont trigger the onMarkerClickListener?
I am aware that I can change the z-index and put the position marker below but it wont be nice for the user if he can't see his own position when close to another marker.
Another solution can think of but dont like is to intercept the click for the user marker and then go through a list of the other markers and find possible matches and trigger a click myself. I'd prefer an existing solution.
So what I have ended up doing is adding the object the marker represents to its tag. Then in onMarkerClickListener I check the marker type by the tag object. Like so (kotlin):
map.setOnMarkerClickListener { marker ->
val mapEvent: MapEvent?
mapEvent =
if (marker.tag is MapEvent) {
marker.tag as MapEvent?
} else {
val clickedMarker = getClickedMarker(from = map)
if (clickedMarker != null)
clickedMarker.tag as MapEvent?
else
return#setOnMarkerClickListener false
}
markerClicked(this#MainActivity, mapEvent)
true
}
If the object is of type MapEvent I call markerClicked() if the clicked marker is not of type MapEvent I go through a list of all markers to see if the clicked marker is inside the radius of any of the MapEvent markers. If so I use that marker and call markerClicked().
This is how I sort through the list of markers:
fun getClickedMarker(from: GoogleMap): Marker? {
if (!::userMarker.isInitialized)
return null
var clickWidth = ContextCompat.getDrawable(App.context, R.drawable.ic_map_permanent)!!.intrinsicWidth
clickWidth += (clickWidth / 3)
val g0 = from.projection.fromScreenLocation(Point(0, 0))
val g1 = from.projection.fromScreenLocation(Point(clickWidth, clickWidth))
val latRadius = (g1.latitude - g0.latitude) / 2
val lonRadius = (g1.longitude - g0.longitude) / 2
return try {
eventMarkers.single {
it.position!!.latitude - latRadius > userMarker.position.latitude && // west
it.position!!.latitude + latRadius < userMarker.position.latitude && // east
it.position!!.longitude + lonRadius > userMarker.position.longitude && // north
it.position!!.longitude - lonRadius < userMarker.position.longitude // south
}
} catch (e: Exception) {
null
}
}
Please comment if anything is unclear. I hope this might help anyone else!
I am trying to get pincode for longitude and latitude using google location services. I used geocoder to get the Address Object. I see that in for some address getPostalCode is Null but postal code can be seen in the address lines.
How do I get the postal code in this case? Should i use regex to get it?
Based from this documentation, you need to specify the restriction by using the componentRestrictions parameter and can be filter by postalCode or country.
The following example function demonstrates using the componentRestrictions parameter to filter by country and postalCode:
function codeAddress() {
geocoder.geocode({
componentRestrictions: {
country: 'AU',
postalCode: '2000'
}
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
window.alert('Geocode was not successful for the following reason: ' + status);
}
});
}
You can check this example in GitHub.
I am doing a location search from my android app. User enter an address and I do a lookup with the following code,
private void doSearch(String query){
FNMApplication.logInfo("Searching:"+query);
//create a geocoder
Geocoder gc = new Geocoder(this,Locale.getDefault());
try{
//lookup locations which match the query input by the user
List<Address> addresses = gc.getFromLocationName(query, 5, -44.00, 111.00, -12.0, 155.0);
//if there are any results save them in an ivar for re-use
locationSearchResults=addresses;
promptSearch();
}
catch (Exception e){
;
}
}
The bounding box above is for australia but if I search for "Los Angelos" it returns results in the US. Is there something I have missed? As I see it, it should only return addresses within the bounding box as per the reference document
From the Question I tried this and the results I got are shown below.
18.55, 72.54 = Mumbai
22.18, 70.56 = Rajkot
1)
When I pass lower latitude vaue as left lower and search for the string I got this
Geocoder gc = new Geocoder(this, Locale.getDefault());
try {
List<Address> addresses = gc.getFromLocationName("akshardham", 5,
18.55, 72.54, 22.18, 70.56);
Log.i("Address", "=========0----------------------"
+ addresses.get(0).getAddressLine(0)
+ addresses.get(0).getAddressLine(1));
Log.i("Address", "=========0----------------------"
+ addresses.get(1).getAddressLine(0)
+ addresses.get(1).getAddressLine(1));
Log.i("Address", "=========0----------------------"
+ addresses.get(2).getAddressLine(0));
Log.i("Address", "=========0----------------------"
+ addresses.get(3).getAddressLine(0));
Log.i("Address", "=========0----------------------"
+ addresses.get(4).getAddressLine(0));
} catch (Exception e) {
;
}
Logcat of this
11-17 12:42:32.419: INFO/Address(802): =========0----------------------AkshardhamNH 8C, Sector 20
11-17 12:42:32.429: INFO/Address(802): =========0----------------------AkshardhamRajkot, Gujarat 360005
11-17 12:42:32.429: INFO/Address(802): =========0----------------------Akshardham
2)
When I pass higher latitude vaue as left lower and search for the string I got this
List<Address> addresses = gc.getFromLocationName("akshardham",5, 22.18, 70.56,18.55, 72.54 );
Logcat of this
11-17 12:43:53.170: INFO/Address(837): =========0----------------------HardhamPulborough, West Sussex RH20 1
3)
The doc here itself says "The addresses matching inside the bounding box is given higher rank." , I think they mean to say, Its not necessary that If search string is address between this box only will be return,if they found the address they will return even if its out of bounding box.
I Suppose;Bounding Box is just for setting the priority of result while getting means result from the box wil be first and and then other like in get(0),get(1) of the list. but the result will be given even if they are not in bounding box.
4)
In the Geocoder.java here they are just calling the method to get addresses with passing double values as argument simple..no any checking for the result is used there else to check the lowest and highest value
=> So final answer to you problem you just call the function as you are calling and you can check the second address line that does they matches to yours means the state or country is same. to find the country,state name of your bounding box value use getFromLocation(latitude, longitude, maxResults), I still Didn't Find A Perfect Solution For this,So me too Searching
=> More on this can be explained by an expert (That's I am not) or Developer from Google itself.