is the code mentioned here still working in some form, ive tried a couple of variations with no data or errors ?
Which code? The Google Maps API stuff or Openstreetmap? The latter is working just fine with me.
Thanks, I tried the google maps api, as we use locations on our handsets, i will recheck the code
Hi Everyone!
Someone could help me? I used this method to get the Location of my phone. But now it shows only ‘null’. I use it with my iPhone (iCloud Binding).
I get an error, which I think belongs to this rule:
2018-03-28 19:16:07.768 [ERROR] [ore.transform.actions.Transformation] - Error executing the transformation ‘JSONPATH’: the given parameters ‘JSonPath’ and ‘source’ must not be null
Can anyone help?
Thanks
I like your opinion about it.
And will use OpenStreetMap instead of google
I experienced the same json issue.
First try to find out, if the response is really „null“ as a string.
This is interpreted as NULL by openhab (no response instead of string „null“).
You will find some help in the thread about my original issue:
Hope this helps
Thanks, I’ll have a look at it!
Where to place the lamda function?
Is this like a script in /scripts and called by the rule?
if so, How?
Or is this supposed to be placed within a rule?
Are you using the OpenStreetMap varient?
In that case I might have found the root cause.
The problem is, that OSM sometimes changes the format of the response.
Means: house_number is not always included. This can happen if the location is close to a restaurant or another POI.
In this case "address does not contain house_number, but “restaurant”.
Obviously OH cannot handle this (!?)
No, I’m using Google Maps. However it happens very rarely, so I could also think that internet might be out when this happens or the server didn’t respond… I haven’t tried resolving it yet…
At the top of the file where the rule resides. Please have a look at the official docs.
Hi Robert,
thanks for your work!
As Google now wants a payment for every usage of the Maps API i used your version of reverse address lookup with OSM.
I had some issue with the transformation of town
because it´s not used in my result.
Instead i had to use city
and now it works like a charm.
regards
Michael
Hi I am having the same issue that NCO has when the street name, city or town is missing from the OSM data.
The code is from rtvb (above).
The data is sometimes changed to suburb or district so throws all the data into the text line of the address.
I looked at checking the length of the returned string for each of the JSON transform result and it seems to partially work when the length is >20 I can see the logInfo at this point (restaurant is used as an example).
if(restaurant.length > 20) {
logInfo(“lookupAddress”,“no restaurant”)
val String restaurant = ’ ’
}
2019-01-04 16:57:46.520 [INFO ] [smarthome.model.script.lookupAddress] - no restaurant
However the rule throws an error that the variables are not used in the rule
2019-01-04 16:58:53.947 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘where_am_i.rules’, using it anyway:
The value of the local variable restaurant is not used
and then it puts all of the JSON data in the text string.
2019-01-04 16:57:46.526 [vent.ItemStateChangedEvent] - Address changed from correct address to {“place_id”:“xxxx1761”,“licence”:“Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",“osm_type”:“way”,“osm_id”:“xxxx6483”,“lat”:“xx.4189xxxx9024”,“lon”:“-x.056xx383674659”,“display_name”:"xxxxx Road, Lxxxxrd, Wxxxl, Nxxxxd, England, xx44 xxJ, United Kingdom”,“address”:{“road”:“xxxxx”,“suburb”:“xxx”,“city”:“xxxx”,“state_district”:“xxxd”,“state”:“England”,“postcode”:“xx44 2BJ”,“country”:“United Kingdom”,“country_code”:“gb”},“boundingbox”:[“xx.4xx636”,“xx.41xx08”,“-x.058xx246”,“-xx.05xx029”]}, xxxxx Road, Wxxx
I need a way to change the incorrect data returned by
val String restaurant = transform(“JSONPATH”, “$.address.restaurant”, result)
to something like
val String restaurant = ‘’
then combine it back to return the address string with a blank value for the road name (or any other that is missing from the JSON transform).
val String address = restaurant + ', ’ + road + ', ’ + city
return address
Is there any quick way to check the JSON transform data is correct and ignore it if returns an error?
Here´s what i build based on the work of @rtvb
@NCO this could help you too
// Reverse address lookup with OpenStreetmap
// https://wiki.openstreetmap.org/wiki/Nominatim#Reverse_Geocoding
// Function called to lookup address from a Location type item
// It assumes that the item
val Functions$Function1<GenericItem, String> lookupAddress= [ iPMichael_Location |
// get lat lon from item
val PointType location = iPMichael_Location.state as PointType
val String lat = location.latitude.toString
val String lon = location.longitude.toString
// build request
val String endpoint = 'https://nominatim.openstreetmap.org/reverse'
val String lang = 'de-DE'
val String query = 'lat=' + lat + '&lon=' + lon + '&accept-language=' + lang + '&format=json&addressdetails=1'
val String request = endpoint + '?' + query
// get result
val String result = sendHttpGetRequest(request)
// logInfo("lookupAddress", result)
var String road = transform("JSONPATH", "$.address.road", result)
var String house = transform("JSONPATH", "$.address.house_number", result)
var String city = transform("JSONPATH", "$.address.city", result)
var String town = transform("JSONPATH", "$.address.town", result)
var String country = transform("JSONPATH", "$.address.country", result)
var String hide = 'Deutschland' // in result language; hide your home country
// Strings leeren wenn kein Wert gefunden wurde und die Rohdaten enthalten sind
if(road.startsWith("{"))
{
road = ''
}
if(house.startsWith("{"))
{
house = ''
}
if(town.startsWith("{"))
{
town = ''
}
if(city.startsWith("{"))
{
city = ''
}
if(country.startsWith("{"))
{
country = ''
}
// Prüfen ob City leer ist und Town einfüllen
if(city == '')
{
city = town
}
// Prüfen ob City weiterhin leer ist und Unbekannt eintragen
if(city == '')
{
city = 'Unbekannt'
}
var String address = road + ' ' + house + ', ' + city
if(address.startsWith(", "))
{
address = '' + city
}
if (country != hide) {
address = address + ', ' + country
}
return address
]
I just check every Strings first character for the {
and empty that String.
I also added city as town as this value isn´t always filled.
Don´t ask me why but at home it´s city but at work it´s town…
If city is empty fill the result from town into the city string.
If city is still empty change the String to “Unkown”.
If house is empty build the address only with street and city.
So for your example it means:
val String restaurant = transform(“JSONPATH”, “$.address.restaurant”, result)
if(restaurant.startsWith("{"))
{
logInfo("lookupAddress","No restaurant")
restaurant = ''
}
if(restaurant == '')
{
val String address = road + ', ' + city
}
else
{
val String address = restaurant + ', ' + road + ', ' + city
}
kind regards
Michael
Thanks a lot for sharing, Michael.
I will use you approach to improve my existing code
However, I found already some “new” location properties which came up:
pedestrian, hamlet (small village obviously) which I handle like this:
// check whether pedestrian is available or not
if(result.contains("pedestrian")) {
pedestrian = transform("JSONPATH", "$.address.pedestrian", result)
address = address + ", " + pedestrian
}
else {
pedestrian = "-"
}
// check whether hamlet (small village) is available or not
if(result.contains("hamlet")) {
hamlet = transform("JSONPATH", "$.address.hamlet", result)
address = address + ", " + hamlet
}
else {
hamlet = "-"
}
And I guess there are many more “special phrases” to be found travelling around
By th way:
In the json response you will find “name” as well, which replaces sometimes street and house_number
Yeah there´s a display name but i think it´s not usable.
There are even addresses where the house number is already in the street String…
Thanks Bredmich and NCO.
That is a great help.
I did find the list of other location properties so will add them when I have time, they are on the OpenStreetMap wiki pages.
Address Key: https://wiki.openstreetmap.org/wiki/Key:addr
Amenity List: https://wiki.openstreetmap.org/wiki/Key:amenity
I´m not sure if this properties are used for the reverse lookup.
I didn´t had any of them in my results.
Here´s a typical result for my lookups:
{"place_id":"#",
"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type":"way",
"osm_id":"#",
"lat":"51.#",
"lon":"7.#",
"display_name":"#, # #, #, #, # #, #-#, #, Deutschland",
"address":{"house_number":"#",
"road":"# #",
"suburb":"#",
"city":"#",
"county":"#",
"state_district":"# #",
"state":"#-#",
"postcode":"#",
"country":"Deutschland",
"country_code":"de"}
,"boundingbox":["51.#","51.#","7.#","7.#"]}
Maybe i´ll start logging the raw results to have a look at them later.
I had a quick run through my events.log files and found the following:
“junction”
“county”
“hamlet”
“furniture”
“house_number”
“wood”
“fast_food”
There was a complete list here: https://wiki.openstreetmap.org/wiki/Map_Features