@@ -102,7 +102,7 @@ void GeoCoding::jumpToAddress(std::string_view searchQuery)
102102 }
103103
104104 // Nominatim request URL
105- std::string url = " https://nominatim.openstreetmap.org/search?q=" + std::string (encoded) + " &format=json &limit=1" ;
105+ std::string url = " https://nominatim.openstreetmap.org/search?q=" + std::string (encoded) + " &format=geocodejson &limit=1&addressdetails=1&accept-language=en " ;
106106 curl_free (encoded);
107107
108108 GET getRequest (url);
@@ -123,33 +123,41 @@ void GeoCoding::jumpToAddress(std::string_view searchQuery)
123123 if (document.Parse (jsonData.c_str ()).HasParseError ())
124124 return ;
125125
126- if (!document.IsArray () || document.Empty ())
126+ if (!document.IsObject () || !document. HasMember ( " features " ) || !document[ " features " ]. IsArray () || document[ " features " ] .Empty ())
127127 return ;
128128
129- const rapidjson::Value &location = document[0 ];
130- if (!location. HasMember ( " lat " ) || !location. HasMember ( " lon " ) )
129+ const rapidjson::Value &coords = document[" features " ][ 0 ][ " geometry " ][ " coordinates " ];
130+ if (!coords. IsArray ( ) || coords. Size () < 2 )
131131 return ;
132132
133- double latitude, longitude;
134-
135- try
133+ double latitude = 0.0 , longitude = 0.0 ;
134+ if (coords[0 ].IsNumber () && coords[1 ].IsNumber ())
136135 {
137- latitude = std::stod (location[ " lat " ]. GetString () );
138- longitude = std::stod (location[ " lon " ]. GetString () );
136+ longitude = coords[ 0 ]. GetDouble ( );
137+ latitude = coords[ 1 ]. GetDouble ( );
139138 }
140- catch (std::invalid_argument &e)
139+ else
141140 {
142- std::cerr << " Failed to parse geo coordinates from geocoding result." << std::endl;
143- return ;
141+ try
142+ {
143+ if (coords[0 ].IsString ())
144+ longitude = std::stod (coords[0 ].GetString ());
145+ if (coords[1 ].IsString ())
146+ latitude = std::stod (coords[1 ].GetString ());
147+ }
148+ catch (const std::exception &)
149+ {
150+ std::cerr << " Failed to parse geo coordinates from geocoding result." << std::endl;
151+ return ;
152+ }
144153 }
145154
146155 auto projectLocation = GeoData::instance ()->globalToProject (osg::Vec3 (longitude, latitude, 500.0 ));
147156 GeoData::instance ()->jumpToLocation (projectLocation, 100.0 );
148157
149- if (location.HasMember (" display_name" ))
150- m_currentLocationLabel->setText (location[" display_name" ].GetString ());
151- else
152- m_currentLocationLabel->setText (" " );
158+ const rapidjson::Value &locationProperties = document[" features" ][0 ][" properties" ][" geocoding" ];
159+ std::string text = formatAddressLabel (locationProperties);
160+ m_currentLocationLabel->setText (text);
153161}
154162
155163#include < osg/io_utils>
@@ -177,7 +185,7 @@ void GeoCoding::geocode()
177185 m_currentLocationLabel->setText (text);
178186
179187 // Nominatim request URL
180- std::string url = " https://nominatim.openstreetmap.org/reverse?lon=" + longitude + " &lat=" + latitude + " &format=json " ;
188+ std::string url = " https://nominatim.openstreetmap.org/reverse?lon=" + longitude + " &lat=" + latitude + " &format=geocodejson&limit=1&addressdetails=1&accept-language=en " ;
181189
182190 GET getRequest (url);
183191 Request::Options options = {
@@ -197,14 +205,86 @@ void GeoCoding::geocode()
197205 if (document.Parse (jsonData.c_str ()).HasParseError ())
198206 return ;
199207
200- if (document.IsArray () || document.Empty ())
208+ if (! document.IsObject () || !document. HasMember ( " features " ) || !document[ " features " ]. IsArray () || document[ " features " ] .Empty ())
201209 return ;
202210
203- if (document.HasMember (" display_name" ))
211+ const rapidjson::Value &locationProperties = document[" features" ][0 ][" properties" ][" geocoding" ];
212+ std::string addressText = formatAddressLabel (locationProperties);
213+ m_currentLocationLabel->setText (text + " \n " + addressText);
214+ std::cout << " Geocoded: " << addressText << std::endl;
215+ }
216+
217+ std::string GeoCoding::formatAddressLabel (const rapidjson::Value &locationProperties)
218+ {
219+ std::string line1;
220+ std::string line2;
221+ std::string line3;
222+ std::string line4;
223+
224+ if (locationProperties.HasMember (" name" ))
225+ line1 += locationProperties[" name" ].GetString ();
226+
227+ if (locationProperties.HasMember (" street" ))
228+ line2 += std::string (locationProperties[" street" ].GetString ()) + " " ;
229+
230+ if (locationProperties.HasMember (" housenumber" ))
231+ line2 += locationProperties[" housenumber" ].GetString ();
232+
233+ if (locationProperties.HasMember (" postcode" ))
234+ line3 += std::string (locationProperties[" postcode" ].GetString ()) + " " ;
235+
236+ if (locationProperties.HasMember (" city" ))
237+ line3 += locationProperties[" city" ].GetString ();
238+
239+ if (locationProperties.HasMember (" county" ))
240+ {
241+ if (!line3.empty ())
242+ line3 += " , " ;
243+
244+ line3 += locationProperties[" county" ].GetString ();
245+ }
246+
247+ if (locationProperties.HasMember (" state" ))
248+ {
249+ if (!line4.empty ())
250+ line4 += " , " ;
251+
252+ line4 += locationProperties[" state" ].GetString ();
253+ }
254+
255+ if (locationProperties.HasMember (" country" ))
256+ {
257+ if (!line4.empty ())
258+ line4 += " , " ;
259+
260+ line4 += locationProperties[" country" ].GetString ();
261+ }
262+
263+ std::vector<std::string> lines;
264+
265+ if (!line1.empty ())
266+ lines.push_back (line1);
267+
268+ if (!line2.empty ())
269+ lines.push_back (line2);
270+
271+ if (!line3.empty ())
272+ lines.push_back (line3);
273+
274+ if (!line4.empty ())
275+ lines.push_back (line4);
276+
277+ std::string text;
278+
279+ for (size_t i = 0 ; i < lines.size (); ++i)
204280 {
205- m_currentLocationLabel->setText (text + " ; " + document[" display_name" ].GetString ());
206- std::cout << " Geocoded: " << document[" display_name" ].GetString () << std::endl;
281+ if (i > 0 )
282+ text += " \n " ;
283+
284+ text += lines[i];
207285 }
286+
287+ return text;
208288}
209289
210290COVERPLUGIN (GeoCoding)
0 commit comments