restore-keys: |
yarn-${{ env.os }}-
- name: Install node modules
- run: bundle exec rails yarn:install
+ run: bundle exec bin/yarn install
- name: Create dummy database configuration
run: cp config/example.database.yml config/database.yml
- name: Run eslint
- name: Export javascript strings
run: bundle exec rails i18n:js:export
- name: Install node modules
- run: bundle exec rails yarn:install
+ run: bundle exec bin/yarn install
- name: Compile assets
run: bundle exec rails assets:precompile
- name: Run tests
RUN gem install bundler \
&& bundle install
-# Install NodeJS packages using yarnpkg
-# `bundle exec rails yarn:install` will not work
+# Install NodeJS packages using yarn
ADD package.json yarn.lock /app/
-RUN yarnpkg --ignore-engines install
+ADD bin/yarn /app/bin/
+RUN bundle exec bin/yarn install
We use [Yarn](https://yarnpkg.com/) to manage the Node.js modules required for the project.
```
-bundle exec rails yarn:install
+bundle exec bin/yarn install
```
## Prepare local settings file
can :search, :direction
can [:index, :permalink, :edit, :help, :fixthemap, :offline, :export, :about, :communities, :preview, :copyright, :key, :id], :site
can [:finish, :embed], :export
- can [:search, :search_latlon, :search_ca_postcode, :search_osm_nominatim,
- :search_geonames, :search_osm_nominatim_reverse, :search_geonames_reverse], :geocoder
+ can [:search, :search_latlon, :search_osm_nominatim, :search_osm_nominatim_reverse], :geocoder
can [:token, :request_token, :access_token, :test_request], :oauth
if Settings.status != "database_offline"
function formatDistance(m) {
if (m < 1000) {
- return Math.round(m) + "m";
+ return I18n.t("javascripts.directions.distance_m", { distance: Math.round(m) });
} else if (m < 10000) {
- return (m / 1000.0).toFixed(1) + "km";
+ return I18n.t("javascripts.directions.distance_km", { distance: (m / 1000.0).toFixed(1) });
} else {
- return Math.round(m / 1000) + "km";
+ return I18n.t("javascripts.directions.distance_km", { distance: Math.round(m / 1000) });
}
}
+ function formatHeight(m) {
+ return I18n.t("javascripts.directions.distance_m", { distance: Math.round(m) });
+ }
+
function formatTime(s) {
var m = Math.round(s / 60);
var h = Math.floor(m / 60);
if (typeof route.ascend !== "undefined" && typeof route.descend !== "undefined") {
distanceText.append(
$("<br>"),
- I18n.t("javascripts.directions.ascend") + ": " + Math.round(route.ascend) + "m. " +
- I18n.t("javascripts.directions.descend") + ": " + Math.round(route.descend) + "m.");
+ I18n.t("javascripts.directions.ascend") + ": " + formatHeight(route.ascend) + ". " +
+ I18n.t("javascripts.directions.descend") + ": " + formatHeight(route.descend) + ".");
}
var turnByTurnTable = $("<table class='mb-3'>");
if @params[:lat] && @params[:lon]
@sources.push "latlon"
@sources.push "osm_nominatim_reverse"
- @sources.push "geonames_reverse" if Settings.key?(:geonames_username)
elsif @params[:query]
- case @params[:query]
- when /^\d{5}(-\d{4})?$/,
- /^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})$/i
- @sources.push "osm_nominatim"
- when /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i
- @sources.push "ca_postcode"
- @sources.push "osm_nominatim"
- else
- @sources.push "osm_nominatim"
- @sources.push "geonames" if Settings.key?(:geonames_username)
- end
+ @sources.push "osm_nominatim"
end
if @sources.empty?
end
end
- def search_ca_postcode
- # get query parameters
- query = params[:query]
- @results = []
-
- # ask geocoder.ca (note - they have a per-day limit)
- response = fetch_xml("https://geocoder.ca/?geoit=XML&postal=#{escape_query(query)}")
-
- # parse the response
- if response.get_elements("geodata/error").empty?
- @results.push(:lat => response.text("geodata/latt"),
- :lon => response.text("geodata/longt"),
- :zoom => Settings.postcode_zoom,
- :name => query.upcase)
- end
-
- render :action => "results"
- rescue StandardError => e
- @error = "Error contacting geocoder.ca: #{e}"
- render :action => "error"
- end
-
def search_osm_nominatim
# get query parameters
query = params[:query]
render :action => "error"
end
- def search_geonames
- # get query parameters
- query = params[:query]
-
- # get preferred language
- lang = I18n.locale.to_s.split("-").first
-
- # create result array
- @results = []
-
- # ask geonames.org
- response = fetch_xml("http://api.geonames.org/search?q=#{escape_query(query)}&lang=#{lang}&maxRows=20&username=#{Settings.geonames_username}")
-
- # parse the response
- response.elements.each("geonames/geoname") do |geoname|
- lat = geoname.text("lat")
- lon = geoname.text("lng")
- name = geoname.text("name")
- country = geoname.text("countryName")
-
- @results.push(:lat => lat, :lon => lon,
- :zoom => Settings.geonames_zoom,
- :name => name,
- :suffix => ", #{country}")
- end
-
- render :action => "results"
- rescue StandardError => e
- @error = "Error contacting api.geonames.org: #{e}"
- render :action => "error"
- end
-
def search_osm_nominatim_reverse
# get query parameters
lat = params[:lat]
render :action => "error"
end
- def search_geonames_reverse
- # get query parameters
- lat = params[:lat]
- lon = params[:lon]
-
- # get preferred language
- lang = I18n.locale.to_s.split("-").first
-
- # create result array
- @results = []
-
- # ask geonames.org
- response = fetch_xml("http://api.geonames.org/countrySubdivision?lat=#{lat}&lng=#{lon}&lang=#{lang}&username=#{Settings.geonames_username}")
-
- # parse the response
- response.elements.each("geonames/countrySubdivision") do |geoname|
- name = geoname.text("adminName1")
- country = geoname.text("countryName")
-
- @results.push(:lat => lat, :lon => lon,
- :zoom => Settings.geonames_zoom,
- :name => name,
- :suffix => ", #{country}")
- end
-
- render :action => "results"
- rescue StandardError => e
- @error = "Error contacting api.geonames.org: #{e}"
- render :action => "error"
- end
-
private
def fetch_text(url)
before_action :authorize_web
before_action :set_locale
+ before_action :check_database_readable
authorize_resource
+ before_action :check_database_writable, :only => [:create]
+
def create
@issue = Issue.find(params[:issue_id])
comment = @issue.comments.build(issue_comment_params)
before_action :authorize_web
before_action :set_locale
+ before_action :check_database_readable
authorize_resource
before_action :find_issue, :only => [:show, :resolve, :reopen, :ignore]
+ before_action :check_database_writable, :only => [:resolve, :ignore, :reopen]
def index
@title = t ".title"
before_action :authorize_web
before_action :set_locale
+ before_action :check_database_readable
authorize_resource
+ before_action :check_database_writable, :only => [:new, :create]
+
def new
if required_new_report_params_present?
@report = Report.new
search:
title:
latlon_html: 'Results from <a href="https://openstreetmap.org/">Internal</a>'
- ca_postcode_html: 'Results from <a href="https://geocoder.ca/">Geocoder.CA</a>'
osm_nominatim_html: 'Results from <a href="https://nominatim.openstreetmap.org/">OpenStreetMap Nominatim</a>'
- geonames_html: 'Results from <a href="http://www.geonames.org/">GeoNames</a>'
osm_nominatim_reverse_html: 'Results from <a href="https://nominatim.openstreetmap.org/">OpenStreetMap Nominatim</a>'
- geonames_reverse_html: 'Results from <a href="http://www.geonames.org/">GeoNames</a>'
search_osm_nominatim:
prefix_format: "%{name}"
prefix:
descend: "Descend"
directions: "Directions"
distance: "Distance"
+ distance_m: "%{distance}m"
+ distance_km: "%{distance}km"
errors:
no_route: "Couldn't find a route between those two places."
no_place: "Sorry - couldn't locate '%{place}'."
# geocoder
get "/search" => "geocoder#search"
get "/geocoder/search_latlon" => "geocoder#search_latlon"
- get "/geocoder/search_ca_postcode" => "geocoder#search_ca_postcode"
get "/geocoder/search_osm_nominatim" => "geocoder#search_osm_nominatim"
- get "/geocoder/search_geonames" => "geocoder#search_geonames"
get "/geocoder/search_osm_nominatim_reverse" => "geocoder#search_osm_nominatim_reverse"
- get "/geocoder/search_geonames_reverse" => "geocoder#search_geonames_reverse"
# directions
get "/directions" => "directions#search"
max_note_request_area: 25
# Zoom level to use for postcode results from the geocoder
postcode_zoom: 15
-# Zoom level to use for geonames results from the geocoder
-geonames_zoom: 12
# Timeout for API calls in seconds
api_timeout: 300
# Timeout for web pages in seconds
max_friends_per_hour: 60
# Domain for handling message replies
#messages_domain: "messages.openstreetmap.org"
-# Geonames authentication details
-#geonames_username: ""
# MaxMind GeoIPv2 database
#maxmind_database: ""
# Users to show as being nearby
# Ignore the diary feed delay unless we're specifically testing it
diary_feed_delay: 0
-# Geonames credentials for testing
-geonames_username: "dummy"
# External authentication credentials for testing
google_auth_id: "dummy"
google_auth_secret: "dummy"
# do bundle install as a convenience
bundle install --retry=10 --jobs=2
# do yarn install as a convenience
-bundle exec rake yarn:install
+bundle exec bin/yarn install
# create user and database for openstreetmap-website
db_user_exists=`sudo -u postgres psql postgres -tAc "select 1 from pg_roles where rolname='vagrant'"`
if [ "$db_user_exists" != "1" ]; then
test "geocoder permission for a guest" do
ability = Ability.new nil
- [:search, :search_latlon, :search_ca_postcode, :search_osm_nominatim,
- :search_geonames, :search_osm_nominatim_reverse, :search_geonames_reverse].each do |action|
+ [:search, :search_latlon, :search_osm_nominatim,
+ :search_osm_nominatim_reverse].each do |action|
assert ability.can?(action, :geocoder), "should be able to #{action} geocoder"
end
end
{ :path => "/geocoder/search_latlon", :method => :get },
{ :controller => "geocoder", :action => "search_latlon" }
)
- assert_routing(
- { :path => "/geocoder/search_ca_postcode", :method => :get },
- { :controller => "geocoder", :action => "search_ca_postcode" }
- )
assert_routing(
{ :path => "/geocoder/search_osm_nominatim", :method => :get },
{ :controller => "geocoder", :action => "search_osm_nominatim" }
)
- assert_routing(
- { :path => "/geocoder/search_geonames", :method => :get },
- { :controller => "geocoder", :action => "search_geonames" }
- )
assert_routing(
{ :path => "/geocoder/search_osm_nominatim_reverse", :method => :get },
{ :controller => "geocoder", :action => "search_osm_nominatim_reverse" }
)
- assert_routing(
- { :path => "/geocoder/search_geonames_reverse", :method => :get },
- { :controller => "geocoder", :action => "search_geonames_reverse" }
- )
end
##
##
# Test identification of Canadian postcodes
def test_identify_ca_postcode
- search_check "A1B 2C3", %w[ca_postcode osm_nominatim]
+ search_check "A1B 2C3", %w[osm_nominatim]
end
##
# Test identification fall through to the default case
def test_identify_default
- search_check "foo bar baz", %w[osm_nominatim geonames]
+ search_check "foo bar baz", %w[osm_nominatim]
end
##
results_check_error "Latitude or longitude are out of range"
end
- ##
- # Test the Canadian postcode search
- def test_search_ca_postcode
- with_http_stubs "geocoder_ca" do
- get geocoder_search_ca_postcode_path(:query => "A1B 2C3", :zoom => 10,
- :minlon => -0.559, :minlat => 51.217,
- :maxlon => 0.836, :maxlat => 51.766), :xhr => true
-
- results_check :name => "A1B 2C3", :lat => "47.172520", :lon => "-55.440515"
-
- get geocoder_search_ca_postcode_path(:query => "k1a 0b1", :zoom => 10,
- :minlon => -0.559, :minlat => 51.217,
- :maxlon => 0.836, :maxlat => 51.766), :xhr => true
- results_check :name => "K1A 0B1", :lat => "45.375437", :lon => "-75.691041"
-
- get geocoder_search_ca_postcode_path(:query => "Q0Q 0Q0", :zoom => 10,
- :minlon => -0.559, :minlat => 51.217,
- :maxlon => 0.836, :maxlat => 51.766), :xhr => true
- results_check
- end
- end
-
##
# Test the nominatim forward search
def test_search_osm_nominatim
end
end
- ##
- # Test the geonames forward search
- def test_search_geonames
- with_http_stubs "geonames" do
- get geocoder_search_geonames_path(:query => "Hoddesdon", :zoom => 10, :minlon => -0.559, :minlat => 51.217,
- :maxlon => 0.836, :maxlat => 51.766), :xhr => true
- results_check :name => "Hoddesdon", :lat => 51.76148, :lon => -0.01144
-
- get geocoder_search_geonames_path(:query => "Broxbourne", :zoom => 10,
- :minlon => -0.559, :minlat => 51.217,
- :maxlon => 0.836, :maxlat => 51.766), :xhr => true
- results_check({ :name => "Broxbourne", :lat => 51.74712, :lon => -0.01923 },
- { :name => "Broxbourne District", :lat => 51.73026, :lon => -0.04821 },
- { :name => "Cheshunt", :lat => 51.70791, :lon => -0.03739 },
- { :name => "Hoddesdon", :lat => 51.76148, :lon => -0.01144 },
- { :name => "Waltham Cross", :lat => 51.68905, :lon => -0.0333 },
- { :name => "Goffs Oak", :lat => 51.71015, :lon => -0.0872 },
- { :name => "Wormley", :lat => 51.7324, :lon => -0.0242 },
- { :name => "Broxbourne", :lat => -27.50314, :lon => 151.378 },
- { :name => "Lee Valley White Water Centre", :lat => 51.68814, :lon => -0.01682 },
- { :name => "Cheshunt Railway Station", :lat => 51.703, :lon => -0.024 },
- { :name => "Theobalds Grove Railway Station", :lat => 51.692, :lon => -0.035 },
- { :name => "Waltham Cross Railway Station", :lat => 51.685, :lon => -0.027 },
- { :name => "Rye House Station", :lat => 51.76938, :lon => 0.00562 },
- { :name => "Broxbourne Station", :lat => 51.74697, :lon => -0.01105 },
- { :name => "Broxbornebury Park", :lat => 51.75252, :lon => -0.03839 },
- { :name => "Marriott Cheshunt", :lat => 51.7208, :lon => -0.0324 },
- { :name => "Cheshunt Community Hospital", :lat => 51.68396, :lon => -0.03951 })
- end
- end
-
##
# Test the nominatim reverse search
def test_search_osm_nominatim_reverse
end
end
- ##
- # Test the geonames reverse search
- def test_search_geonames_reverse
- with_http_stubs "geonames" do
- get geocoder_search_geonames_reverse_path(:lat => 51.7632, :lon => -0.0076, :zoom => 15), :xhr => true
- results_check :name => "England", :suffix => ", United Kingdom",
- :lat => 51.7632, :lon => -0.0076
- end
- end
-
private
def latlon_check(query, lat, lon)
assert_response :success
assert_template :search
assert_template :layout => "map"
- assert_equal %w[latlon osm_nominatim_reverse geonames_reverse], assigns(:sources)
+ assert_equal %w[latlon osm_nominatim_reverse], assigns(:sources)
assert_nil @controller.params[:query]
assert_in_delta lat, @controller.params[:lat]
assert_in_delta lon, @controller.params[:lon]
assert_response :success
assert_template :search
assert_template :layout => "xhr"
- assert_equal %w[latlon osm_nominatim_reverse geonames_reverse], assigns(:sources)
+ assert_equal %w[latlon osm_nominatim_reverse], assigns(:sources)
assert_nil @controller.params[:query]
assert_in_delta lat, @controller.params[:lat]
assert_in_delta lon, @controller.params[:lon]
+++ /dev/null
-/?geoit=XML&postal=A1B%202C3:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8"?>
- <geodata>
- <latt>47.172520</latt>
- <longt>-55.440515</longt>
- <postal>A1B2C3</postal>
- <standard>
- <stnumber>1</stnumber>
- <staddress/>
- <city>ST. JOHN&'S</city>
- <prov>NL</prov>
- <confidence>0.9</confidence>
- </standard>
- </geodata>
-
-/?geoit=XML&postal=k1a%200b1:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8"?>
- <geodata>
- <latt>45.375437</latt>
- <longt>-75.691041</longt>
- <postal>K1A0B1</postal>
- <standard>
- <stnumber>1</stnumber>
- <staddress/>
- <city>OTTAWA</city>
- <prov>ON</prov>
- <confidence>0.9</confidence>
- </standard>
- </geodata>
-
-/?geoit=XML&postal=Q0Q%200Q0:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8"?>
- <geodata>
- <error>
- <code>008</code>
- <description>Your request did not produce any results. Check your spelling and try again.</description>
- </error>
- <latt/>
- <longt>-</longt>
- <postal>Q0Q0Q0</postal>
- <standard>
- <stnumber>1</stnumber>
- <staddress/>
- <city/>
- <prov/>
- <confidence>0.9</confidence>
- </standard>
- </geodata>
+++ /dev/null
-/search?lang=en&maxRows=20&q=Hoddesdon&username=dummy:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <geonames style="MEDIUM">
- <totalResultsCount>1</totalResultsCount>
- <geoname>
- <toponymName>Hoddesdon</toponymName>
- <name>Hoddesdon</name>
- <lat>51.76148</lat>
- <lng>-0.01144</lng>
- <geonameId>2646807</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- </geonames>
-
-/search?lang=en&maxRows=20&q=Broxbourne&username=dummy:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <geonames style="MEDIUM">
- <totalResultsCount>17</totalResultsCount>
- <geoname>
- <toponymName>Broxbourne</toponymName>
- <name>Broxbourne</name>
- <lat>51.74712</lat>
- <lng>-0.01923</lng>
- <geonameId>2654481</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Broxbourne District</toponymName>
- <name>Broxbourne District</name>
- <lat>51.73026</lat>
- <lng>-0.04821</lng>
- <geonameId>7290563</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>A</fcl>
- <fcode>ADM3</fcode>
- </geoname>
- <geoname>
- <toponymName>Cheshunt</toponymName>
- <name>Cheshunt</name>
- <lat>51.70791</lat>
- <lng>-0.03739</lng>
- <geonameId>2653232</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Hoddesdon</toponymName>
- <name>Hoddesdon</name>
- <lat>51.76148</lat>
- <lng>-0.01144</lng>
- <geonameId>2646807</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Waltham Cross</toponymName>
- <name>Waltham Cross</name>
- <lat>51.68905</lat>
- <lng>-0.0333</lng>
- <geonameId>2634842</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Goffs Oak</toponymName>
- <name>Goffs Oak</name>
- <lat>51.71015</lat>
- <lng>-0.0872</lng>
- <geonameId>2648362</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Wormley</toponymName>
- <name>Wormley</name>
- <lat>51.7324</lat>
- <lng>-0.0242</lng>
- <geonameId>2633535</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>P</fcl>
- <fcode>PPL</fcode>
- </geoname>
- <geoname>
- <toponymName>Broxbourne</toponymName>
- <name>Broxbourne</name>
- <lat>-27.50314</lat>
- <lng>151.378</lng>
- <geonameId>8792801</geonameId>
- <countryCode>AU</countryCode>
- <countryName>Australia</countryName>
- <fcl>S</fcl>
- <fcode>HMSD</fcode>
- </geoname>
- <geoname>
- <toponymName>Lee Valley White Water Centre</toponymName>
- <name>Lee Valley White Water Centre</name>
- <lat>51.68814</lat>
- <lng>-0.01682</lng>
- <geonameId>7670551</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>FCL</fcode>
- </geoname>
- <geoname>
- <toponymName>Cheshunt Railway Station</toponymName>
- <name>Cheshunt Railway Station</name>
- <lat>51.703</lat>
- <lng>-0.024</lng>
- <geonameId>6952282</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>RSTN</fcode>
- </geoname>
- <geoname>
- <toponymName>Theobalds Grove Railway Station</toponymName>
- <name>Theobalds Grove Railway Station</name>
- <lat>51.692</lat>
- <lng>-0.035</lng>
- <geonameId>6953715</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>RSTN</fcode>
- </geoname>
- <geoname>
- <toponymName>Waltham Cross Railway Station</toponymName>
- <name>Waltham Cross Railway Station</name>
- <lat>51.685</lat>
- <lng>-0.027</lng>
- <geonameId>6953801</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>RSTN</fcode>
- </geoname>
- <geoname>
- <toponymName>Rye House Station</toponymName>
- <name>Rye House Station</name>
- <lat>51.76938</lat>
- <lng>0.00562</lng>
- <geonameId>6691700</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>RSTN</fcode>
- </geoname>
- <geoname>
- <toponymName>Broxbourne Station</toponymName>
- <name>Broxbourne Station</name>
- <lat>51.74697</lat>
- <lng>-0.01105</lng>
- <geonameId>6691701</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>RSTN</fcode>
- </geoname>
- <geoname>
- <toponymName>Broxbornebury Park</toponymName>
- <name>Broxbornebury Park</name>
- <lat>51.75252</lat>
- <lng>-0.03839</lng>
- <geonameId>6286417</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>CSTL</fcode>
- </geoname>
- <geoname>
- <toponymName>Marriott Cheshunt</toponymName>
- <name>Marriott Cheshunt</name>
- <lat>51.7208</lat>
- <lng>-0.0324</lng>
- <geonameId>6512481</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>HTL</fcode>
- </geoname>
- <geoname>
- <toponymName>Cheshunt Community Hospital</toponymName>
- <name>Cheshunt Community Hospital</name>
- <lat>51.68396</lat>
- <lng>-0.03951</lng>
- <geonameId>6289233</geonameId>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <fcl>S</fcl>
- <fcode>HSP</fcode>
- </geoname>
- </geonames>
-
-/countrySubdivision?lang=en&lat=51.7632&lng=-0.0076&username=dummy:
- code: 200
- body: |
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <geonames>
- <countrySubdivision>
- <countryCode>GB</countryCode>
- <countryName>United Kingdom</countryName>
- <adminCode1>ENG</adminCode1>
- <adminName1>England</adminName1>
- <code type="ISO3166-2">ENG</code>
- <distance>0.0</distance>
- </countrySubdivision>
- </geonames>