diff --git a/Code/IO/otbPlaceNameToLonLat.cxx b/Code/IO/otbPlaceNameToLonLat.cxx
index d2dae151061f9485ef35e41b8b48d481aa88b154..a371c818ae173fa5e81cec874da4c94b97523d7b 100644
--- a/Code/IO/otbPlaceNameToLonLat.cxx
+++ b/Code/IO/otbPlaceNameToLonLat.cxx
@@ -49,17 +49,31 @@ bool PlaceNameToLonLat::Evaluate()
     m_PlaceName.replace(loc, 1, "+");
     loc = m_PlaceName.find(" ", loc);
     }
+  // TODO : replace unsafe ASCII character with "%" followed by their hex equivalent
 
+  // Geonames service
   if ((m_Lat == -1000.0) && (m_Lon == -1000.0))
     {
     std::ostringstream urlStream;
-    urlStream << "http://maps.google.com/maps?q=";
+    urlStream << "http://api.geonames.org/search?q=";
     urlStream << m_PlaceName;
-    urlStream << "&sll=38.9594,-95.2655&sspn=119.526,360&output=kml&ie=utf-8&v=2.2&cv=4.2.0180.1134&hl=en";
+    urlStream << "&maxRows=1&type=xml&orderby=relevance&username=otbteam";
     RetrieveXML(urlStream);
     if ( m_RequestSucceed )
-      ParseXMLGoogle();
+      ParseXMLGeonames();
     }
+  
+  // Google Maps service 
+  // if ((m_Lat == -1000.0) && (m_Lon == -1000.0))
+  //   {
+  //   std::ostringstream urlStream;
+  //   urlStream << "http://maps.google.com/maps?q=";
+  //   urlStream << m_PlaceName;
+  //   urlStream << "&sll=38.9594,-95.2655&sspn=119.526,360&output=kml&ie=utf-8&v=2.2&cv=4.2.0180.1134&hl=en";
+  //   RetrieveXML(urlStream);
+  //   if ( m_RequestSucceed )
+  //     ParseXMLGoogle();
+  //   }
 
   // Yahoo new PlaceFinder API need an application ID to be able
   // to use it
@@ -136,7 +150,20 @@ void PlaceNameToLonLat::ParseXMLGoogle()
 
 void PlaceNameToLonLat::ParseXMLGeonames()
 {
+  TiXmlDocument doc;
+  doc.Parse(m_CurlOutput.c_str());
 
+  TiXmlHandle docHandle(&doc);
+  TiXmlElement* childLat = docHandle.FirstChild("geonames").FirstChild("geoname").FirstChild("lat").Element();
+  if (childLat)
+    {
+    m_Lat = atof(childLat->GetText());
+    }
+  TiXmlElement* childLon = docHandle.FirstChild("geonames").FirstChild("geoname").FirstChild("lng").Element();
+  if (childLon)
+    {
+    m_Lon = atof(childLon->GetText());
+    }
 }
 
 } // namespace otb
diff --git a/Code/IO/otbPlaceNameToLonLat.h b/Code/IO/otbPlaceNameToLonLat.h
index afe34be68781d962093ea13e63d46166c52e167d..88c49ecc665b2cc185fe9253742c4aab00a8c339 100644
--- a/Code/IO/otbPlaceNameToLonLat.h
+++ b/Code/IO/otbPlaceNameToLonLat.h
@@ -62,7 +62,7 @@ protected:
   void RetrieveXML(const std::ostringstream& urlStream);
   void ParseXMLYahoo();
   void ParseXMLGoogle();
-  void ParseXMLGeonames(); //Not implemented yet TODO
+  void ParseXMLGeonames();
 
 private:
   PlaceNameToLonLat(const Self &);  //purposely not implemented