Mercurial > hg > ChinaGisRestApi
changeset 278:4ade9b80b563 default tip
more cleanup.
descriptions work better now.
author | casties |
---|---|
date | Fri, 24 Feb 2012 16:41:30 +0100 |
parents | 9bfa7a6858f1 |
children | |
files | RestDbGisApi.py RestDbInterface.py RestDbJsonStore.py gis_gui/blocks/layer.js gis_gui/home.pt zpt/KML_schema_table.zpt |
diffstat | 6 files changed, 40 insertions(+), 940 deletions(-) [+] |
line wrap: on
line diff
--- a/RestDbGisApi.py Thu Feb 23 21:37:37 2012 +0100 +++ b/RestDbGisApi.py Fri Feb 24 16:41:30 2012 +0100 @@ -481,7 +481,8 @@ kmlPlace['TimeStamp'] = '%s'%beg_yr if geomField=='point': - kmlPlace['description'] = "<![CDATA[%s]]>"%desc + #kmlPlace['description'] = "<![CDATA[%s]]>"%desc + kmlPlace['description'] = desc kmlPlace['icon'] = '#marker_icon_'+colorField kmlPlace['coord_x'] = str(xCoord) @@ -603,114 +604,6 @@ ## legacy methods... - def getKmlUrl(self,schema='chgis',table='mpdl',args={'doc':None,'id':None}): - logging.debug("getKmlUrl") - id=args.get('id') - doc=args.get('doc') - data = self.getDataForGoogleMap(schema,table,id,doc) - kml=self.getKMLname(data=data,table=table) - baseUrl = self.absolute_url() - return "%s/daten/%s"%(baseUrl,kml) - - def getDataForGoogleMap(self,schema='chgis',table='mpdl',id=None,doc=None): - logging.debug("getDataForGoogleMap") - qstr="SELECT * FROM "+schema+"."+table - try: - if id is not None: - qstr=qstr+" WHERE " - for id_item in id.split(","): - if table=='mpdl': - qstr=qstr+" mpdl_xmlsource_id = '"+id_item+ "' OR" - else: - qstr=qstr+" cast(id as text) LIKE '"+id_item+ "' OR" - qstr=str(qstr).rsplit(" ",1)[0] #to remove last " and " - data=self.ZSQLSimpleSearch(qstr) - return data - except: - return qstr - - - def getKMLname(self,data=[],table=""): - logging.debug("getKMLname") - #session=context.REQUEST.SESSION - kml4Marker="<kml xmlns=\'http://www.opengis.net/kml/2.2\'><Document>" - kml4Marker+="<Style id=\'marker_icon_red\'><IconStyle><scale>15</scale><Icon><href>http://mappit.mpiwg-berlin.mpg.de/mappit/icons/dot_red.png</href></Icon></IconStyle></Style>\n" - kml4Marker+="<Style id=\'marker_icon_black\'><IconStyle><scale>15</scale><Icon><href>http://mappit.mpiwg-berlin.mpg.de/mappit/icons/dot_black.png</href></Icon></IconStyle></Style>\n" - kml4Marker+="<Style id=\'marker_icon_blue\'><IconStyle><scale>15</scale><Icon><href>http://mappit.mpiwg-berlin.mpg.de/mappit/icons/dot_blue.png</href></Icon></IconStyle></Style>\n" - kml4Marker+="<Style id=\'marker_icon_green\'><IconStyle><scale>15</scale><Icon><href>http://mappit.mpiwg-berlin.mpg.de/mappit/icons/dot_green.png</href></Icon></IconStyle></Style>\n" - kml4Marker+="<Style id=\'marker_icon_violett\'><IconStyle><scale>15</scale><Icon><href>http://mappit.mpiwg-berlin.mpg.de/mappit/icons/dot_violett.png</href></Icon></IconStyle></Style>\n" - initializeStringForGoogleMaps="" - #doLine=container.getVar('doLine') - # Mapping a set of points from table-based SQL-query: - if data!=None: - try: - SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s' - res = self.executeSQL(SQL, (table,)) - gisIDattribute = res['rows'][0][0] - except: - return "table not registered within metadata" - - for dataset in data: - try: - xCoord=getattr(dataset,'longitude') - yCoord=getattr(dataset,'latitude') - except: - try: - xCoord=getattr(dataset,'x_coord') - yCoord=getattr(dataset,'y_coord') - except: - #try: - gisID=getattr(dataset,gisIDattribute) - coords=self.getPoint4GISid(gisID) - if coords!=None: - xCoord=coords[0] - yCoord=coords[1] - # except: - # return "no coordinates found" - - if float(xCoord)!=0: - if float(yCoord)!=0: - kml4Marker=kml4Marker+"<Placemark>" - kml4Marker=kml4Marker+"<description> <![CDATA[<b>" - for values in dataset: - #logging.debug("values=%s"%repr(values)) - if values != (None, None): - if str(values).find('name')>-1: - kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" - continue - elif str(values).find('place')>-1: - kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" - continue - - kml4Marker=kml4Marker+str(values)+": " - attribute_string=str(values).replace("'","__Apostroph__") - attribute_string=str(attribute_string).replace('"','__DoubleApostroph__') - attribute_string=str(attribute_string).replace(';','__$$__') - attribute_string=str(attribute_string).replace('&','&') - if str(attribute_string).find('http')>-1: - attribute_string='<A HREF=' + str(attribute_string) + ' target="_blank">' + str(attribute_string) + '</A>' - kml4Marker=kml4Marker+attribute_string+"</a><br>\n" - - kml4Marker=kml4Marker+"]]></description>\n" - kml4Marker=kml4Marker+"<styleURL>#marker_icon_red</styleURL>\n" - kml4Marker=kml4Marker+"<Point>" - - kml4Marker=kml4Marker+"<coordinates>"+str(xCoord)+","+str(yCoord)+",0</coordinates>\n" - kml4Marker=kml4Marker+"</Point>\n" - kml4Marker=kml4Marker+"</Placemark>\n" - - kml4Marker=kml4Marker+"</Document>\n</kml>" - kmlFileName="marker"+str(time.time())+".kml" - - #kml4Marker=str(kml4Marker).replace('&','$$') - #kml4Marker=str(kml4Marker).replace(';','__$$__') - #kml4Marker=str(kml4Marker).replace('#','__SHARP__') - isLoadReady='false' - while isLoadReady=='false': - isLoadReady=self.RESTwrite2File(self.daten,kmlFileName,kml4Marker) - - return kmlFileName - def trydatahas_key(self,data,index,key_string): logging.debug("trying:"+key_string) try: @@ -718,82 +611,6 @@ except: return 'false' -# def getGoogleMapString(self,kml): -# logging.debug("getGoogleMapString") -# printed= '<body %s> '%kml +"""\n <div id="map_canvas" style="width: 98%; height: 95%"> </div> \n </body>" \n </html>""" -# return printed - - def getPoint4GISid(self,gis_id): - j=0 - coords=(0,0) - if gis_id != None: - while (True): - j=j+1 - if (j>100): # FJK: just to prevent endless loops - break - if (gis_id.isdigit()): # FJK: regular exit from while-loop - break - else: - gis_id=gis_id.strip('abcdefghijklmnopqrstuvwxyz_') # FJK: to strip all letters - gis_id=gis_id.strip() # FJK: to strip all whitespaces - resultpoint = [0,0] - results = None - try: - if int(gis_id)>0: - SQL="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE cast("+ str(gis_id) +" as text);" - results=self.ZSQLSimpleSearch(SQL) - #print results - if results != None: - for result in results: - resultpoint=[getattr(result,str('x_coord')),getattr(result,str('y_coord'))] - if resultpoint !=[0,0]: - return resultpoint - else: - coords=self.getCoordsFromREST_gisID(gis_id) - SQL="INSERT INTO chgis.chgis_coords (chgis_coords_pkey,gis_id,x_coord,y_coord) VALUES (default," +gis_id+ "," +coords[0][1]+ "," +coords[0][0]+ "); ANALYZE chgis.chgis_coords;" - returnstring=self.ZSQLSimpleSearch(SQL) - return coords[0] - except: - return "gis_id not to interpretable:"+str(gis_id) - else: - return coords[0] - - def getCoordsFromREST_gisID(self,gis_id): - gis_id=gis_id.strip() - coordlist=[] - i=0 - while (i<5 and coordlist==[]): - urlinfo=urlFunctions.zUrlopenInfo(self,"http://chgis.hmdc.harvard.edu/xml/id/"+gis_id) - urlinfoLength=urlinfo.get('content-length') - if int(urlinfoLength)<500: - urlresponse=urlFunctions.zUrlopenRead(self,"http://chgis.hmdc.harvard.edu/xml/id/cts_"+gis_id) - else: - urlresponse=urlFunctions.zUrlopenRead(self,"http://chgis.hmdc.harvard.edu/xml/id/"+gis_id) - urlresponseString=urlFunctions.zUrlopenParseString(self,urlresponse) - baseDocElement= urlFunctions.zUrlopenDocumentElement(self,urlresponseString) - childnodes=urlFunctions.zUrlopenChildNodes(self,baseDocElement) - itemnodes=urlFunctions.zUrlopenGetElementsByTagName(self,baseDocElement,'item') - itemspatialnodes=None - - for i in range(0,urlFunctions.zUrlopenLength(self,itemnodes)): - itemnode=urlFunctions.zUrlopenGetItem(self,itemnodes,i) - itemspatialnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemnode,'spatial') - if itemspatialnodes is not None: - for j in range(0,urlFunctions.zUrlopenLength(self,itemspatialnodes)): - coord=[] - itemspatialnode= urlFunctions.zUrlopenGetItem(self,itemspatialnodes,j) - itemspatiallatnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_latitude') - for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallatnodes)): - itemspatiallatnode= urlFunctions.zUrlopenGetItem(self,itemspatiallatnodes,k) - coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallatnode)) - itemspatiallngnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_longitude') - for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallngnodes)): - itemspatiallngnode= urlFunctions.zUrlopenGetItem(self,itemspatiallngnodes,k) - coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallngnode)) - coordlist.append(coord) - gis_id= "_"+gis_id - return coordlist - # End for GoogleMaps creation def RESTwrite2File(self,datadir, name,text):
--- a/RestDbInterface.py Thu Feb 23 21:37:37 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,722 +0,0 @@ -''' -Created on 19.5.2010 - -@author: casties -''' - -from OFS.Folder import Folder -from Products.PageTemplates.PageTemplateFile import PageTemplateFile -from AccessControl import getSecurityManager, Unauthorized -from Products.ZSQLExtend import ZSQLExtend -import logging -import re -import json -import time -import psycopg2 -import urllib - -# make psycopg use unicode objects -import psycopg2.extensions -psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) -psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY) - -from zope.interface import implements -from zope.publisher.interfaces import IPublishTraverse -from ZPublisher.BaseRequest import DefaultPublishTraverse - - -def unicodify(s,alternate='latin-1'): - """decode str (utf-8 or latin-1 representation) into unicode object""" - if not s: - return u"" - if isinstance(s, str): - try: - return s.decode('utf-8') - except: - return s.decode(alternate) - else: - return s - -def utf8ify(s): - """encode unicode object or string into byte string in utf-8 representation. - assumes string objects to be utf-8""" - if not s: - return "" - if isinstance(s, str): - return s - else: - return s.encode('utf-8') - -def getTextFromNode(node): - """get the cdata content of a XML node""" - if node is None: - return "" - - if isinstance(node, list): - nodelist = node - else: - nodelist=node.childNodes - - rc = "" - for node in nodelist: - if node.nodeType == node.TEXT_NODE: - rc = rc + node.data - return rc - -def sqlName(s,lc=True): - """returns restricted ASCII-only version of string""" - if s is None: - return "" - - # all else -> "_" - s = re.sub(r'[^A-Za-z0-9_]','_',s) - if lc: - return s.lower() - - return s - - -class RestDbInterface(Folder): - """Object for RESTful database queries - path schema: /db/{schema}/{table}/ - omitting table gives a list of schemas - omitting table and schema gives a list of schemas - """ - implements(IPublishTraverse) - - meta_type="RESTdb" - manage_options=Folder.manage_options+( - {'label':'Config','action':'manage_editRestDbInterfaceForm'}, - ) - - # management templates - manage_editRestDbInterfaceForm=PageTemplateFile('zpt/editRestDbInterface',globals()) - - # data templates - XML_index = PageTemplateFile('zpt/XML_index', globals()) - XML_schema = PageTemplateFile('zpt/XML_schema', globals()) - XML_schema_table = PageTemplateFile('zpt/XML_schema_table', globals()) - HTML_index = PageTemplateFile('zpt/HTML_index', globals()) - HTML_schema = PageTemplateFile('zpt/HTML_schema', globals()) - HTML_schema_table = PageTemplateFile('zpt/HTML_schema_table', globals()) - GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals()) - KML_schema_table = PageTemplateFile('zpt/KML_schema_table', globals()) - HTML_schema_usertables = PageTemplateFile('zpt/HTML_schema_usertables', globals()) - - - - JSONHTML_index = PageTemplateFile('zpt/JSONHTML_index', globals()) - JSONHTML_schema = PageTemplateFile('zpt/JSONHTML_schema', globals()) - JSONHTML_schema_table = PageTemplateFile('zpt/JSONHTML_schema_table', globals()) - # JSON_* templates are scripts - - - def JSON_index(self): - """JSON index function""" - self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") - json.dump(self.getListOfSchemas(), self.REQUEST.RESPONSE) - - def JSON_schema(self,schema): - """JSON index function""" - self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") - json.dump(self.getListOfTables(schema), self.REQUEST.RESPONSE) - - def JSON_schema_table(self,schema,table): - """JSON index function""" - logging.debug("start: json_schema") - self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json") - json.dump(self.getTable(schema, table), self.REQUEST.RESPONSE) - logging.debug("end: json_schema") - - def __init__(self, id, title, connection_id=None): - """init""" - self.id = id - self.title = title - # database connection id - self.connection_id = connection_id - # create template folder - self.manage_addFolder('template') - - - def getRestDbUrl(self): - """returns url to the RestDb instance""" - return self.absolute_url() - - def getJsonString(self,object): - """returns a JSON formatted string from object""" - return json.dumps(object) - - def getCursor(self,autocommit=True): - """returns fresh DB cursor""" - conn = getattr(self,"_v_database_connection",None) - if conn is None: - # create a new connection object - try: - if self.connection_id is None: - # try to take the first existing ID - connids = SQLConnectionIDs(self) - if len(connids) > 0: - connection_id = connids[0][0] - self.connection_id = connection_id - logging.debug("connection_id: %s"%repr(connection_id)) - - da = getattr(self, self.connection_id) - da.connect('') - # we copy the DAs database connection - conn = da._v_database_connection - #conn._register() # register with the Zope transaction system - self._v_database_connection = conn - except Exception, e: - raise IOError("No database connection! (%s)"%str(e)) - - cursor = conn.getcursor() - if autocommit: - # is there a better version to get to the connection? - cursor.connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) - - return cursor - - def getFieldNameMap(self,fields): - """returns a dict mapping field names to row indexes""" - map = {} - i = 0 - for f in fields: - map[f[0]] = i - i += 1 - - return map - - def getFieldNames(self,fields): - """returns a dict mapping field names to row indexes""" - map = [] - i = 0 - for f in fields: - map.append(f[0]) - - - return map - - def executeSQL(self, query, args=None, hasResult=True, autocommit=True): - """execute query with args on database and return all results. - result format: {"fields":fields, "rows":data}""" - logging.debug("executeSQL query=%s args=%s"%(query,args)) - cur = self.getCursor(autocommit=autocommit) - if args is not None: - # make sure args is a list - if isinstance(args,basestring): - args = (args,) - - cur.execute(query, args) - # description of returned fields - fields = cur.description - if hasResult: - # get all data in an array - data = cur.fetchall() - cur.close() - #logging.debug("fields: %s"%repr(fields)) - #logging.debug("rows: %s"%repr(data)) - return {"fields":fields, "rows":data} - else: - cur.close() - return None - - def isAllowed(self,action,schema,table,user=None): - """returns if the requested action on the table is allowed""" - if user is None: - user = self.REQUEST.get('AUTHENTICATED_USER',None) - logging.debug("isAllowed action=%s schema=%s table=%s user=%s"%(action,schema,table,user)) - # no default policy! - return True - - - def publishTraverse(self,request,name): - """change the traversal""" - # get stored path - path = request.get('restdb_path', []) - logging.debug("publishtraverse: name=%s restdb_path=%s"%(name,path)) - - if name in ("index_html", "PUT"): - # end of traversal - if request.get("method") == "POST" and request.get("action",None) == "PUT": - # fake PUT by POST with action=PUT - name = "PUT" - - return getattr(self, name) - #TODO: should we check more? - else: - # traverse - if len(path) == 0: - # first segment - if name == 'db': - # virtual path -- continue traversing - path = [name] - request['restdb_path'] = path - else: - # try real path - tr = DefaultPublishTraverse(self, request) - ob = tr.publishTraverse(request, name) - return ob - else: - path.append(name) - - # continue traversing - return self - - - def index_html(self,REQUEST,RESPONSE): - """index method""" - # ReST path was stored in request - path = REQUEST.get('restdb_path',[]) - - # type and format are real parameter - resultFormat = REQUEST.get('format','HTML').upper() - queryType = REQUEST.get('type',None) - from_year_name = REQUEST.get('from_year_name',None) - until_year_name = REQUEST.get('until_year_name',None) - - logging.debug("index_html path=%s resultFormat=%s queryType=%s"%(path,resultFormat,queryType)) - - if queryType is not None: - # non-empty queryType -- look for template - pt = getattr(self.template, "%s_%s"%(resultFormat,queryType), None) - if pt is not None: - return pt(format=resultFormat,type=queryType,path=path,from_year_name=from_year_name,until_year_name=until_year_name) - - if len(path) == 1: - # list of schemas - return self.showListOfSchemas(format=resultFormat) - elif len(path) == 2: - # list of tables - return self.showListOfTables(format=resultFormat,schema=path[1]) - elif len(path) == 3: - # table - if REQUEST.get("method") == "POST" and REQUEST.get("create_table_file",None) is not None: - # POST to table to check - return self.checkTable(format=resultFormat,schema=path[1],table=path[2]) - # else show table - logging.debug("index_html:will showTable") - x= self.showTable(format=resultFormat,schema=path[1],table=path[2],REQUEST=REQUEST, RESPONSE=RESPONSE) - logging.debug("index_html:have done showTable") - return x - # don't know what to do - return str(REQUEST) - - def PUT(self, REQUEST, RESPONSE): - """ - Implement WebDAV/HTTP PUT/FTP put method for this object. - """ - logging.debug("RestDbInterface PUT") - #logging.debug("req=%s"%REQUEST) - #self.dav__init(REQUEST, RESPONSE) - #self.dav__simpleifhandler(REQUEST, RESPONSE) - # ReST path was stored in request - path = REQUEST.get('restdb_path',[]) - if len(path) == 3: - schema = path[1] - tablename = path[2] - file = REQUEST.get("create_table_file",None) - if file is None: - RESPONSE.setStatus(400) - return - - fields = None - fieldsStr = REQUEST.get("create_table_fields",None) - logging.debug("put with schema=%s table=%s file=%s fields=%s"%(schema,tablename,file,repr(fieldsStr))) - if fieldsStr is not None: - # unpack fields - fields = [{"name":n, "type": t} for (n,t) in [f.split(":") for f in fieldsStr.split(",")]] - - ret = self.createTableFromXML(schema, tablename, file, fields) - # return the result as JSON - format = REQUEST.get("format","JSON") - if format == "JSON": - RESPONSE.setHeader("Content-Type", "application/json") - json.dump(ret, RESPONSE) - - elif format == "JSONHTML": - RESPONSE.setHeader("Content-Type", "text/html") - RESPONSE.write("<html>\n<body>\n<pre>") - json.dump(ret, RESPONSE) - RESPONSE.write("</pre>\n</body>\n</html>") - - else: - # 400 Bad Request - RESPONSE.setStatus(400) - return - def getAttributeNames(self,schema='public',table=None): - return self.executeSQL("SELECT attname FROM pg_attribute, pg_class WHERE pg_class.oid = attrelid AND attnum>0 AND relname = '%s';"%(table)) - - def getAttributeTypes(self,schema='public',table=None): - return self.executeSQL("SELECT field_name, gis_type FROM public.gis_table_meta_rows WHERE table_name = '%s';"%(table)) - - def showTable(self,format='XML',schema='public',table=None,REQUEST=None,RESPONSE=None): - """returns PageTemplate with tables""" - logging.debug("showtable") - if REQUEST is None: - REQUEST = self.REQUEST - queryArgs={'doc':None,'id':None} - queryArgs['doc'] = REQUEST.get('doc') - queryArgs['id'] = REQUEST.get('id') - - # should be cross-site accessible - if RESPONSE is None: - RESPONSE = self.REQUEST.RESPONSE - - RESPONSE.setHeader('Access-Control-Allow-Origin', '*') - - # everything else has its own template - pt = getattr(self.template, '%s_schema_table'%format, REQUEST) - logging.debug("showtable: gottemplate") - if pt is None: - return "ERROR!! template %s_schema_table not found at %s"%(format, self.template ) - #data = self.getTable(schema,table) - logging.debug("table:"+repr(table)) - #x = pt(schema=schema,table=table,args={}) - x = pt(schema=schema,table=table,args=queryArgs) - logging.debug("showtable: executed Table") - return x - - def getLiveUrl(self,schema,table,useTimestamp=True,REQUEST=None): - if REQUEST is None: - REQUEST = self.REQUEST - logging.debug("getLiveUrl") - baseUrl = self.absolute_url() - timestamp = time.time() - # filter parameters in URL and add to new URL - params = [p for p in REQUEST.form.items() if p[0] not in ('format','timestamp')] - params.append(('format','KML')) - if useTimestamp: - # add timestamp so URL changes every time - params.append(('timestamp',timestamp)) - paramstr = urllib.urlencode(params) - return "%s/db/%s/%s?%s"%(baseUrl,schema,table,paramstr) - - - - def getTable(self,schema='public',table=None,sortBy=1,username='guest'): - """return table data""" - logging.debug("gettable") - attrNames=self.getAttributeNames(schema,table) - attrTypes=self.getAttributeTypes(schema,table) - attrString="" - # try: - for name in attrNames['rows']: - logging.debug("name: "+repr( name[0])) - not_added=True - if name[0] == "the_geom": #FJK: the table column is "the_geom" - attrString=attrString+"ST_AsText("+name[0]+")," - not_added=False - break - for a_iter in attrTypes['rows']: - not_added = True - logging.debug("attrTypes.field_name: "+ repr(a_iter[0])) - if a_iter[0]==name[0]: - logging.debug("attrTypes.gis_type: "+ repr(a_iter[1])) - if a_iter[1] == "the_geom": #FJK: the table column is registered in gis_table_meta_rows as type "the_geom" - attrString=attrString+"ST_AsText("+name[0]+")," - not_added=False - if not_added: - if name[0].find('pg.dropped')==-1: - attrString=attrString+name[0]+"," - attrString=str(attrString).rsplit(",",1)[0] #to remove last "," - if sortBy: - data = self.executeSQL('select %s from "%s"."%s" order by %s'%(attrString,schema,table,sortBy)) - else: - data = self.executeSQL('select %s from "%s"."%s"'%(attrString,schema,table)) - # except: - """ table does not exist """ - # fields=self.get - # self.createEmptyTable(schema, table, fields) - logging.debug("getTable: done") - return data - - def hasTable(self,schema='public',table=None,username='guest'): - """return if table exists""" - logging.debug("hastable") - data = self.executeSQL('select 1 from information_schema.tables where table_schema=%s and table_name=%s',(schema,table)) - ret = bool(data['rows']) - return ret - - def showListOfTables(self,format='XML',schema='public',REQUEST=None,RESPONSE=None): - """returns PageTemplate with list of tables""" - logging.debug("showlistoftables") - # should be cross-site accessible - if RESPONSE is None: - RESPONSE = self.REQUEST.RESPONSE - RESPONSE.setHeader('Access-Control-Allow-Origin', '*') - - pt = getattr(self.template, '%s_schema'%format, None) - if pt is None: - return "ERROR!! template %s_schema not found"%format - - #data = self.getListOfTables(schema) - return pt(schema=schema) - - def getListOfTables(self,schema='public',username='guest'): - """return list of tables""" - logging.debug("getlistoftables") - # get list of fields and types of db table - #qstr="""SELECT c.relname AS tablename FROM pg_catalog.pg_class c - # LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace - # WHERE c.relkind IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast') - # AND pg_catalog.pg_table_is_visible(c.oid) - # AND c.relname ORDER BY 1""" - qstr = """SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' - AND table_schema = %s ORDER BY 1""" - data=self.executeSQL(qstr,(schema,)) - return data - - def showListOfSchemas(self,format='XML',REQUEST=None,RESPONSE=None): - """returns PageTemplate with list of schemas""" - logging.debug("showlistofschemas") - # should be cross-site accessible - if RESPONSE is None: - RESPONSE = self.REQUEST.RESPONSE - RESPONSE.setHeader('Access-Control-Allow-Origin', '*') - - pt = getattr(self.template, '%s_index'%format, None) - if pt is None: - return "ERROR!! template %s_index not found"%format - - #data = self.getListOfSchemas() - return pt() - - def getListOfSchemas(self,username='guest'): - """return list of schemas""" - logging.debug("getlistofschemas") - # TODO: really look up schemas - data={'fields': (('schemas',),), 'rows': [('public',),]} - return data - - def checkTable(self,format,schema,table,REQUEST=None,RESPONSE=None): - """check the table. - returns valid data fields and table name.""" - if REQUEST is None: - REQUEST = self.REQUEST - RESPONSE = REQUEST.RESPONSE - - file = REQUEST.get("create_table_file",None) - res = self.checkTableFromXML(schema, table, file) - logging.debug("checkTable result=%s"%repr(res)) - # return the result as JSON - if format == "JSON": - RESPONSE.setHeader("Content-Type", "application/json") - json.dump(res, RESPONSE) - - elif format == "JSONHTML": - RESPONSE.setHeader("Content-Type", "text/html") - RESPONSE.write("<html>\n<body>\n<pre>") - json.dump(res, RESPONSE) - RESPONSE.write("</pre>\n</body>\n</html>") - - else: - return "ERROR: invalid format" - - def checkTableFromXML(self,schema,table,data,REQUEST=None,RESPONSE=None): - """check the table with the given XML data. - returns valid data fields and table name.""" - logging.debug("checkTableFromXML schema=%s table=%s"%(schema,table)) - # clean table name - tablename = sqlName(table) - tableExists = self.hasTable(schema, table) - if data is None: - fieldNames = [] - else: - # get list of field names from upload file - fields = self.importExcelXML(schema,tablename,data,fieldsOnly=True) - - res = {'tablename': tablename, 'table_exists': tableExists} - res['fields'] = fields - return res - - def createEmptyTable(self,schema,table,fields): - """create a table with the given fields - returns list of created fields""" - logging.debug("createEmptyTable") - - sqlFields = [] - for f in fields: - if isinstance(f,dict): - # {name: XX, type: YY} - name = sqlName(f['name']) - type = f['type'] - if hasattr(self, 'toSqlTypeMap'): - sqltype = self.toSqlTypeMap[type] - else: - sqltype = 'text' - - else: - # name only - name = sqlName(f) - type = 'text' - sqltype = 'text' - - sqlFields.append({'name':name, 'type':type, 'sqltype':sqltype}) - - if self.hasTable(schema,table): - # TODO: find owner - if not self.isAllowed("update", schema, table): - raise Unauthorized - self.executeSQL('drop table "%s"."%s"'%(schema,table),hasResult=False) - else: - if not self.isAllowed("create", schema, table): - raise Unauthorized - - fieldString = ", ".join(['"%s" %s'%(f['name'],f['sqltype']) for f in sqlFields]) - sqlString = 'create table "%s"."%s" (%s)'%(schema,table,fieldString) - logging.debug("createemptytable: SQL=%s"%sqlString) - self.executeSQL(sqlString,hasResult=False) - self.setTableMetaTypes(schema,table,sqlFields) - return sqlFields - - def createTableFromXML(self,schema,table,data, fields=None): - """create or replace a table with the given XML data""" - logging.debug("createTableFromXML schema=%s table=%s data=%s fields=%s"%(schema,table,data,fields)) - tablename = sqlName(table) - self.importExcelXML(schema, tablename, data, fields) - return {"tablename": tablename} - - def importExcelXML(self,schema,table,xmldata,fields=None,fieldsOnly=False): - ''' - Import XML file in Excel format into the table - @param table: name of the table the xml shall be imported into - ''' - from xml.dom.pulldom import parseString,parse - - if not (fieldsOnly or self.isAllowed("create", schema, table)): - raise Unauthorized - - namespace = "urn:schemas-microsoft-com:office:spreadsheet" - containerTagName = "Table" - rowTagName = "Row" - colTagName = "Cell" - dataTagName = "Data" - xmlFields = [] - sqlFields = [] - numFields = 0 - sqlInsert = None - - logging.debug("import excel xml") - - ret="" - if isinstance(xmldata, str): - logging.debug("importXML reading string data") - doc=parseString(xmldata) - else: - logging.debug("importXML reading file data") - doc=parse(xmldata) - - cnt = 0 - while True: - node=doc.getEvent() - - if node is None: - break - - else: - #logging.debug("tag=%s"%node[1].localName) - if node[1].localName is not None: - tagName = node[1].localName.lower() - else: - # ignore non-tag nodes - continue - - if tagName == rowTagName.lower(): - # start of row - doc.expandNode(node[1]) - cnt += 1 - if cnt == 1: - # first row -- field names - names=node[1].getElementsByTagNameNS(namespace, dataTagName) - for name in names: - fn = getTextFromNode(name) - xmlFields.append({'name':sqlName(fn),'type':'text'}) - - if fieldsOnly: - # return just field names - return xmlFields - - # create table - if fields is None: - fields = xmlFields - - sqlFields = self.createEmptyTable(schema, table, fields) - numFields = len(sqlFields) - fieldString = ", ".join(['"%s"'%f['name'] for f in sqlFields]) - valString = ", ".join(["%s" for f in sqlFields]) - sqlInsert = 'insert into "%s"."%s" (%s) values (%s)'%(schema,table,fieldString,valString) - #logging.debug("importexcelsql: sqlInsert=%s"%sqlInsert) - - else: - # following rows are data - colNodes=node[1].getElementsByTagNameNS(namespace, colTagName) - data = [] - hasData = False - lineIndex=0 - for colNode in colNodes: - lineIndex+=1 - dataNodes=colNode.getElementsByTagNameNS(namespace, dataTagName) - if len(dataNodes) > 0: - dataIndex=0 - if colNode.hasAttribute(u'ss:Index'): - dataIndex=int(colNode.getAttribute(u'ss:Index')) - while dataIndex>lineIndex: - data.append(None) - lineIndex+=1 - else: - val = getTextFromNode(dataNodes[0]) - hasData = True - else: - val = None - - if val!=None: - a=val.rfind('.0') - b=len(val) - if a==b-2: - val=val.rpartition('.')[0] - data.append(val) - - if not hasData: - # ignore empty rows - continue - - # fix number of data fields - if len(data) > numFields: - del data[numFields:] - elif len(data) < numFields: - missFields = numFields - len(data) - data.extend(missFields * [None,]) - - logging.debug("importexcel sqlinsert=%s data=%s"%(sqlInsert,data)) - self.executeSQL(sqlInsert, data, hasResult=False) - - return cnt - - def manage_editRestDbInterface(self, title=None, connection_id=None, - REQUEST=None): - """Change the object""" - if title is not None: - self.title = title - - if connection_id is not None: - self.connection_id = connection_id - - #checkPermission=getSecurityManager().checkPermission - REQUEST.RESPONSE.redirect('manage_main') - - -manage_addRestDbInterfaceForm=PageTemplateFile('zpt/addRestDbInterface',globals()) - -def manage_addRestDbInterface(self, id, title='', label='', description='', - createPublic=0, - createUserF=0, - REQUEST=None): - """Add a new object with id *id*.""" - - ob=RestDbInterface(str(id),title) - self._setObject(id, ob) - - #checkPermission=getSecurityManager().checkPermission - REQUEST.RESPONSE.redirect('manage_main') - -
--- a/RestDbJsonStore.py Thu Feb 23 21:37:37 2012 +0100 +++ b/RestDbJsonStore.py Fri Feb 24 16:41:30 2012 +0100 @@ -15,10 +15,8 @@ from zope.interface import implements from zope.publisher.interfaces import IPublishTraverse from ZPublisher.BaseRequest import DefaultPublishTraverse -import Shared.DC.ZRDB.DA -from Products.ZSQLMethods.SQL import SQLConnectionIDs -from RestDbInterface import * +from Products.ZDBInterface.RestDbInterface import * class RestDbJsonStore(RestDbInterface):
--- a/gis_gui/blocks/layer.js Thu Feb 23 21:37:37 2012 +0100 +++ b/gis_gui/blocks/layer.js Fri Feb 24 16:41:30 2012 +0100 @@ -169,18 +169,20 @@ console.debug("new google map=",map," on el=",le); //geocoder = new google.maps.Geocoder(); - var newMarker=new google.maps.KmlLayer(kmlURL,{ suppressInfoWindows: true, map: map}); + var newMarker=new google.maps.KmlLayer(kmlURL, {suppressInfoWindows: false, map: map}); - google.maps.event.addListener(newMarker, 'click', function(kmlEvent) { + google.maps.event.addListener(newMarker, 'status_changed', function() { + console.debug("layer loaded:", newMarker.status); + }); + + /* google.maps.event.addListener(newMarker, 'click', function(kmlEvent) { var text = kmlEvent.featureData.description; - showInContentWindow(text); - }); - - function showInContentWindow(text) { - var orig_obj=$(elem).find(".mapping_info").html(); + var orig_obj=$(elem).find(".mapping_info").html(); $(elem).find(".mapping_info").html(text); - $(elem).find(".mapping_info").one("click",function(){$(elem).find(".mapping_info").html(orig_obj);}); - } + $(elem).find(".mapping_info").one("click", function () { + $(elem).find(".mapping_info").html(orig_obj); + }); + }); */ console.debug("new marker layer=",newMarker); //newMarker.setMap(map);
--- a/gis_gui/home.pt Thu Feb 23 21:37:37 2012 +0100 +++ b/gis_gui/home.pt Fri Feb 24 16:41:30 2012 +0100 @@ -1,8 +1,9 @@ +<!DOCTYPE html> <html> <head> - <title>Mappit, Map Places in Time, Mappit by MPI for the History of Scinces</title> - <meta name="description" content="Mappit, Web-GIS, Mappit developed by F.-J. Knauft, Max-Planck-Institut"> - <meta name="keywords" content="Mappit, Geo-Information System, Mappit, Max-Planck-Institut f. Wissenschaftsgeschichte Berlin, MPI, Falk-Juri Knauft"> + <title>Mappit, Map Places in Time, by MPI for the History of Scinces</title> + <meta name="description" content="Mappit, Web-GIS, Mappit developed by F.-J. Knauft, Max-Planck-Institut"/> + <meta name="keywords" content="Mappit, Geo-Information System, Mappit, Max-Planck-Institut f. Wissenschaftsgeschichte Berlin, MPI, Falk-Juri Knauft"/> <script type="text/javascript" src="lib/jquery-1.4.2.js"></script> <script type="text/javascript" src="lib/json2.js"></script> @@ -25,7 +26,7 @@ <script type="text/javascript" src="blocks/notes.js"></script> <script type="text/javascript" src="blocks/home.js"></script> - <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> + <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> <link href="lib/jqueryui/css/smoothness/jquery-ui-1.8.1.custom.css" rel="stylesheet" content="text/css"/> <link href="lib/blocks.css" rel="stylesheet" content="text/css"/> @@ -39,7 +40,7 @@ <link href="blocks/search.css" rel="stylesheet" content="text/css"/> <link href="blocks/notes.css" rel="stylesheet" content="text/css"/> - <script> + <script type="text/javascript"> $(document).ready(function(){ var blockContainer = $("#moduleslot").get(); blocks = new guiBlocks(blockContainer); @@ -53,8 +54,6 @@ } }); }); - - </script> </head>
--- a/zpt/KML_schema_table.zpt Thu Feb 23 21:37:37 2012 +0100 +++ b/zpt/KML_schema_table.zpt Fri Feb 24 16:41:30 2012 +0100 @@ -1,16 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:tal="http://xml.zope.org/namespaces/tal" - tal:define="gisIdField python:request.get('gis_id_field',None); colorField python:request.get('color_field','red'); - latField python:request.get('lat_field',None); lonField python:request.get('lon_field',None); geomField python:request.get('geometry_field','point'); - sortBy python:request.get('sort_field',1); ids python:request.get('id'); + tal:define="gisIdField python:request.get('gis_id_field',None); + colorField python:request.get('color_field','red'); + latField python:request.get('lat_field',None); + lonField python:request.get('lon_field',None); + geomField python:request.get('geometry_field','point'); + sortBy python:request.get('sort_field',1); + ids python:request.get('id'); from_year_name python:request.get('from_year_name','from_year'); until_year_name python:request.get('until_year_name','until_year'); schema options/schema; table options/table; - data python:here.getKmlData(schema=schema,table=table, - sortBy=sortBy,ids=ids,gisIdField=gisIdField, - latField=latField,lonField=lonField, - geomField=geomField,colorField=colorField, - from_year_name=from_year_name,until_year_name=until_year_name ); + data python:here.getKmlData(schema=schema,table=table,sortBy=sortBy,ids=ids,gisIdField=gisIdField, + latField=latField,lonField=lonField,geomField=geomField,colorField=colorField, + from_year_name=from_year_name,until_year_name=until_year_name); withLine python:request.get('connect_line',None);"> <Document> <Style id="marker_icon_red"> @@ -185,11 +187,13 @@ <description tal:content="place/description"> ERD-0815: ERD-0815 </description> - <TimeStamp tal:condition="python:here.trydatahas_key(data,0,'TimeStamp')"><when tal:content="place/TimeStamp"></when> + <TimeStamp tal:condition="python:here.trydatahas_key(data,0,'TimeStamp')"> + <when tal:content="place/TimeStamp"></when> </TimeStamp> - <TimeSpan tal:condition="python:here.trydatahas_key(data,0,'TimeSpan0')"><begin tal:content="place/TimeSpan0" ></begin><end tal:content="place/TimeSpan1"></end> + <TimeSpan tal:condition="python:here.trydatahas_key(data,0,'TimeSpan0')"> + <begin tal:content="place/TimeSpan0" ></begin> + <end tal:content="place/TimeSpan1"></end> </TimeSpan> - <styleUrl tal:content="place/icon" >#marker_icon_red</styleUrl> <Point tal:condition="python:place.has_key('icon')"> <extrude>1</extrude> @@ -201,11 +205,13 @@ <description tal:content="place/description" > ERD-0815: ERD-0815 </description> - <TimeStamp tal:condition="python:here.trydatahas_key(data,0,'TimeStamp')"><when tal:content="place/TimeStamp"></when> + <TimeStamp tal:condition="python:here.trydatahas_key(data,0,'TimeStamp')"> + <when tal:content="place/TimeStamp"></when> </TimeStamp> - <TimeSpan tal:condition="python:here.trydatahas_key(data,0,'TimeSpan0')"><begin tal:content="place/TimeSpan0" ></begin><end tal:content="place/TimeSpan1"></end> + <TimeSpan tal:condition="python:here.trydatahas_key(data,0,'TimeSpan0')"> + <begin tal:content="place/TimeSpan0" ></begin> + <end tal:content="place/TimeSpan1"></end> </TimeSpan> - <styleUrl tal:content="place/lineColor" >#red_line</styleUrl> <LineString> <extrude>1</extrude>