From dfcd46538012074625c1858f7769e53efc7d2523 Mon Sep 17 00:00:00 2001 From: Allen Chen Date: Sun, 8 Mar 2015 05:13:47 +0000 Subject: [PATCH] Zoom to location completed. Geonames search replaced with internal search of gis locations table. Added fallback to geonames when internal db search returns 0 results. Fixed GeoNamesSearchCombo.js to point to the host server using window.location.hostname Changed username from static "eden_test" to dynamic aquisition via function call. Modified code to confirm with pep8 --- controllers/gis.py | 75 ++++++++++++++++++- .../gis/GeoExt/ux/GeoNamesSearchCombo.js | 47 ++++++++++-- views/gis/search_gis_locations.html | 0 3 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 views/gis/search_gis_locations.html diff --git a/controllers/gis.py b/controllers/gis.py index 166ec49147..8ca5b916b0 100644 --- a/controllers/gis.py +++ b/controllers/gis.py @@ -3780,4 +3780,77 @@ def screenshot(): else: raise HTTP(500, "Screenshot not taken") -# END ========================================================================= +# ============================================================================= +def search_gis_locations(): + import urllib2 + + #Get vars from url + user_str = get_vars["name_startsWith"] + callback_func = request.vars["callback"] + atable = db.gis_location + query = atable.name.lower().like(user_str + '%') + rows = db(query).select(atable.id, + atable.level, + atable.name, + atable.lat, + atable.lon + ) + results = [] + count = 0 + for row in rows: + count += 1 + result = {} + + #Convert the level colum into the ADM codes geonames returns + #fcode = row["gis_location.level"] + level = row["gis_location.level"] + if level=="L0": #Country + fcode = "PCL" #Zoom 5 + elif level=="L1": #State/Province + fcode = "ADM1" + elif level=="L2": #County/District + fcode = "ADM2" + elif level=="L3": #Village/Suburb + fcode = "ADM3" + else: #City/Town/Village + fcode = "ADM4" + + result = {"id" : row["gis_location.id"], + "fcode" : fcode, + "name" : row["gis_location.name"], + "lat" : row["gis_location.lat"], + "lng" : row["gis_location.lon"]} + results.append(result) + + #if count = 0, then search on geonames + if count == 0: + username = settings.get_gis_geonames_username() + maxrows = "20" + lang = "en" + charset = "UTF8" + nameStartsWith = user_str + geonames_base_url = "http://ws.geonames.org/searchJSON?" + url = "%susername=%s&maxRows=%s&lang=%s&charset=%s&name_startsWith=%s" % (geonames_base_url,username,maxrows,lang,charset,nameStartsWith) + response = urllib2.urlopen(url) + dictResponse = json.loads(response.read().decode(response.info().getparam('charset') or 'utf-8')) + response.close() + + results = [] + if dictResponse["totalResultsCount"] != 0: + geonamesResults = dictResponse["geonames"] + for geonamesResult in geonamesResults: + result = {} + + result = {"id" : int(geonamesResult["geonameId"]), "fcode" : str(geonamesResult["fcode"]), + "name" : str(geonamesResult["name"]),"lat" : float(geonamesResult["lat"]), + "lng" : float(geonamesResult["lng"])} + results.append(result) + + returnVal = {} + returnVal["gislocations"] = results + returnVal["totalResultsCount"] = count + + #Autocomplete caller expects JSONP response. Callback wrapper. + return callback_func+'('+json.dumps(returnVal)+')' + +# END ========================================================================= \ No newline at end of file diff --git a/static/scripts/gis/GeoExt/ux/GeoNamesSearchCombo.js b/static/scripts/gis/GeoExt/ux/GeoNamesSearchCombo.js index 9c0b5c15e8..59b4a4b3c8 100644 --- a/static/scripts/gis/GeoExt/ux/GeoNamesSearchCombo.js +++ b/static/scripts/gis/GeoExt/ux/GeoNamesSearchCombo.js @@ -41,13 +41,13 @@ GeoExt.ux.GeoNamesSearchCombo = Ext.extend(Ext.form.ComboBox, { * See http://www.dev.sencha.com/deploy/dev/docs/source/Combo.html#cfg-Ext.form.ComboBox-loadingText, * default value is "Search in Geonames...". */ - loadingText: 'Search in Geonames...', + loadingText: 'Searching locations...', /** api: config[emptyText] * See http://www.dev.sencha.com/deploy/dev/docs/source/TextField.html#cfg-Ext.form.TextField-emptyText, - * default value is "Search location in Geonames". + * default value is "Search locations". */ - emptyText: 'Search location in Geonames', + emptyText: 'Search locations', /** api: config[username] * ``String`` Username to send with API requests. Mandatory. @@ -217,7 +217,8 @@ GeoExt.ux.GeoNamesSearchCombo = Ext.extend(Ext.form.ComboBox, { /** private: property[url] * Url of the GeoNames service: http://www.GeoNames.org/export/GeoNames-search.html */ - url: 'http://ws.geonames.org/searchJSON?', + /*url: 'http://ws.geonames.org/searchJSON?',*/ + url: 'http://'+window.location.hostname+':8000/eden/gis/search_gis_locations.html/', /** private: constructor */ @@ -238,9 +239,40 @@ GeoExt.ux.GeoNamesSearchCombo = Ext.extend(Ext.form.ComboBox, { urlAppendString = urlAppendString + this.featureCodeString; } + //Query internal locations first + this.store = new Ext.data.Store({ + proxy: new Ext.data.ScriptTagProxy({ + url: this.url, + method: 'GET' + }), + reader: new Ext.data.JsonReader({ + idProperty: 'id', + root: "gislocations", + totalProperty: "totalResultsCount", + fields: [ + { + name:'id' + }, + { + name:'fcode' + }, + { + name: 'name' + }, + { + name: 'lng' + }, + { + name: 'lat' + } + ] + }) //End reader + }); //End store + + /*if(this.store.reader.totalProperty==0){ //No internal matches this.store = new Ext.data.Store({ proxy: new Ext.data.ScriptTagProxy({ - url: this.url + urlAppendString, + url: 'http://ws.geonames.org/searchJSON?' + urlAppendString, method: 'GET' }), baseParams: { @@ -298,8 +330,9 @@ GeoExt.ux.GeoNamesSearchCombo = Ext.extend(Ext.form.ComboBox, { name: 'adminName1' } ] - }) - }); + }) //End reader + });//end store + }//end if*/ if (this.zoom > 0) { this.on("select", function(combo, record, index) { diff --git a/views/gis/search_gis_locations.html b/views/gis/search_gis_locations.html new file mode 100644 index 0000000000..e69de29bb2