Mercurial > hg > ChinaGisRestApi
annotate RestDbGisApi.py @ 276:55bc9972fb1b
Merge with d1b43624cc63b829f64cc952540748e15272e389
author | casties |
---|---|
date | Thu, 23 Feb 2012 21:29:06 +0100 |
parents | eb8a18f94d2d d1b43624cc63 |
children | 4ade9b80b563 |
rev | line source |
---|---|
43 | 1 ''' |
2 Created on 2.9.2010 | |
3 | |
4 @author: casties, fknauft | |
5 ''' | |
6 | |
7 from OFS.Folder import Folder | |
8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile | |
9 from Products.ZSQLExtend import ZSQLExtend | |
10 import logging | |
11 import re | |
12 import time | |
61 | 13 import datetime |
247 | 14 import urlFunctions |
43 | 15 |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
16 from Products.ZDBInterface.WritableRestDbInterface import * |
43 | 17 |
18 | |
55 | 19 def kmlEncode(s): |
20 """returns string encoded for displaying in KML attribute""" | |
21 res = s.replace("'","__Apostroph__") | |
22 res = res.replace('"','__DoubleApostroph__') | |
23 res = res.replace(';','__$$__') | |
24 res = res.replace('&','&') | |
25 return res | |
26 | |
27 | |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
28 class RestDbGisApi(WritableRestDbInterface): |
43 | 29 """Object for RESTful GIS database queries |
30 path schema: /db/{schema}/{table}/ | |
31 omitting table gives a list of schemas | |
32 omitting table and schema gives a list of schemas | |
33 """ | |
34 | |
35 meta_type="RESTgis" | |
36 | |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
37 # data templates |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
38 GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals()) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
39 KML_schema_table = PageTemplateFile('zpt/KML_schema_table', globals()) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
40 HTML_schema_usertables = PageTemplateFile('zpt/HTML_schema_usertables', globals()) |
55 | 41 |
44 | 42 # and scripts |
254
901c1f745d13
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
252
diff
changeset
|
43 def KML_URL_schema_table(self,schema,table, useTimestamp=True, args=None): |
44 | 44 """KML_URL table function""" |
45 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") | |
46 id = self.REQUEST.get('id',[]) | |
47 doc = self.REQUEST.get('doc',None) | |
245 | 48 # return self.getLiveKmlUrl(schema=schema,table=table, useTimestamp=useTimestamp) |
49 return self.getLiveKmlUrl(schema=schema,table=table, useTimestamp=False) | |
43 | 50 |
61 | 51 # |
52 # database methods | |
53 # | |
70 | 54 toSqlTypeMap = { |
55 "text": "text", | |
56 "number": "numeric", | |
57 "id": "text", | |
58 "gis_id": "text", | |
59 "coord_lat": "numeric", | |
252
efd2469d1722
geometry-column of tables will be displayed as string
fknauft
parents:
250
diff
changeset
|
60 "coord_lon": "numeric", |
263 | 61 "the_geom": "the_geom", |
62 "from_year":"text", | |
63 "until_year":"text" | |
70 | 64 } |
65 | |
60 | 66 def getTableOwner(self,schema,table): |
67 """returns the owner of the table""" | |
61 | 68 # what do we do with the schema? |
69 sql = 'select table_owner from public.gis_table_meta where table_name = %s' | |
70 res = self.executeSQL(sql,(table,)) | |
71 if len(res['rows']) > 0: | |
72 return res['rows'][0][0] | |
60 | 73 return None |
74 | |
75 def isAllowed(self,action,schema,table,user=None,owner=None): | |
43 | 76 """returns if the requested action on the table is allowed""" |
77 if user is None: | |
78 user = self.REQUEST.get('AUTHENTICATED_USER',None) | |
60 | 79 logging.debug("isAllowed action=%s schema=%s table=%s user=%s"%(action,schema,table,user)) |
80 if action == "create": | |
81 if user is not None and str(user) != 'Anonymous User': | |
82 # any authenticated user can create | |
83 return True | |
84 else: | |
85 return False | |
86 | |
87 if action == "update": | |
88 if owner is None: | |
89 owner = self.getTableOwner(schema,table) | |
61 | 90 logging.debug("isAllowed user=%s owner=%s"%(user,owner)) |
60 | 91 if user is not None and str(user) == str(owner): |
92 # update only your own table | |
93 return True | |
94 else: | |
95 return False | |
96 | |
62 | 97 # anything else is allowed |
43 | 98 return True |
99 | |
61 | 100 def setTableMetaTypes(self,schema,table,fields,user=None): |
43 | 101 """sets the GIS meta information for table""" |
61 | 102 if user is None: |
103 user = self.REQUEST.get('AUTHENTICATED_USER',None) | |
104 | |
105 logging.debug("settablemetatypes schema=%s, table=%s, fields=%s user=%s"%(schema,table,fields,user)) | |
43 | 106 |
61 | 107 today = datetime.date.today().isoformat() |
108 | |
109 res = self.executeSQL('select * from public.gis_table_meta where table_name = %s', (table,)) | |
43 | 110 if len(res['rows']) > 0: |
111 # meta record exists | |
61 | 112 sql = 'update public.gis_table_meta set table_owner=%s, table_modified=%s where table_name=%s' |
113 self.executeSQL(sql, (str(user),today,table), hasResult=False) | |
43 | 114 else: |
115 # new meta record | |
61 | 116 sql = 'insert into public.gis_table_meta (table_name,table_owner,table_created) values (%s,%s,%s)' |
117 self.executeSQL(sql, (table,str(user),today), hasResult=False) | |
118 | |
119 # update row info | |
120 sql = 'delete from public.gis_table_meta_rows where table_name=%s' | |
121 self.executeSQL(sql,(table,),hasResult=False) | |
122 sql = 'insert into public.gis_table_meta_rows (table_name,field_name,gis_type) values (%s,%s,%s)' | |
123 for f in fields: | |
124 t = f['type'] | |
125 fn = f['name'] | |
126 self.executeSQL(sql, (table,fn,t), hasResult=False) | |
43 | 127 |
128 | |
61 | 129 def getListOfUserTables(self,schema='public',username='guest'): |
130 """return list of tables""" | |
131 logging.debug("getlistofusertables") | |
132 # get list of db tables | |
100 | 133 # qstr = """SELECT t.table_name FROM information_schema.tables t, public.gis_table_meta m WHERE t.table_type = 'BASE TABLE' |
134 # AND t.table_schema = %s AND t.table_name = m.table_name ORDER BY 1""" | |
135 qstr = """SELECT t.table_name FROM information_schema.tables t, public.gis_table_meta m | |
136 WHERE t.table_schema = %s AND t.table_name = m.table_name ORDER BY 1""" | |
43 | 137 |
61 | 138 data=self.executeSQL(qstr,(schema,)) |
139 return data | |
140 | |
43 | 141 |
142 def createEmptyTable(self,schema,table,fields): | |
143 """create a table with the given fields | |
144 returns list of created fields""" | |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
145 sqlFields = WritableRestDbInterface.createEmptyTable(self,schema,table,fields) |
61 | 146 if sqlFields is not None: |
43 | 147 self.setTableMetaTypes(schema,table,sqlFields) |
61 | 148 |
149 return sqlFields | |
43 | 150 |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
151 # TODO: move this |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
152 def getAttributeNames(self,schema='public',table=None): |
275 | 153 return self.executeSQL("SELECT attname FROM pg_attribute, pg_class WHERE pg_class.oid = attrelid AND attnum>0 AND relname = %s", (table)) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
154 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
155 # TODO: move this |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
156 def getAttributeTypes(self,schema='public',table=None): |
275 | 157 return self.executeSQL("SELECT field_name, gis_type FROM public.gis_table_meta_rows WHERE table_name = %s", (table)) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
158 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
159 # TODO: move back to inherited version |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
160 def showTable(self,format='XML',schema='public',table=None,REQUEST=None,RESPONSE=None): |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
161 """returns PageTemplate with tables""" |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
162 logging.debug("showtable") |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
163 if REQUEST is None: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
164 REQUEST = self.REQUEST |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
165 queryArgs={'doc':None,'id':None} |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
166 queryArgs['doc'] = REQUEST.get('doc') |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
167 queryArgs['id'] = REQUEST.get('id') |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
168 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
169 # should be cross-site accessible |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
170 if RESPONSE is None: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
171 RESPONSE = self.REQUEST.RESPONSE |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
172 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
173 RESPONSE.setHeader('Access-Control-Allow-Origin', '*') |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
174 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
175 # everything else has its own template |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
176 pt = getattr(self.template, '%s_schema_table'%format, REQUEST) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
177 if pt is None: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
178 return "ERROR!! template %s_schema_table not found at %s"%(format, self.template ) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
179 #data = self.getTable(schema,table) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
180 return pt(schema=schema,table=table,args=queryArgs) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
181 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
182 #TODO: move to parent class |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
183 def getLiveUrl(self,schema,table,useTimestamp=True,REQUEST=None): |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
184 if REQUEST is None: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
185 REQUEST = self.REQUEST |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
186 logging.debug("getLiveUrl") |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
187 baseUrl = self.absolute_url() |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
188 timestamp = time.time() |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
189 # filter parameters in URL and add to new URL |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
190 params = [p for p in REQUEST.form.items() if p[0] not in ('format','timestamp')] |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
191 params.append(('format','KML')) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
192 if useTimestamp: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
193 # add timestamp so URL changes every time |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
194 params.append(('timestamp',timestamp)) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
195 paramstr = urllib.urlencode(params) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
196 return "%s/db/%s/%s?%s"%(baseUrl,schema,table,paramstr) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
197 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
198 |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
199 # TODO: remove changes from parent version |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
200 def getTable(self,schema='public',table=None,sortBy=1,username='guest'): |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
201 """return table data""" |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
202 logging.debug("gettable") |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
203 attrNames=self.getAttributeNames(schema,table) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
204 attrTypes=self.getAttributeTypes(schema,table) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
205 attrString="" |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
206 # try: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
207 for name in attrNames['rows']: |
275 | 208 logging.debug("name: %s"%name[0]) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
209 not_added=True |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
210 if name[0] == "the_geom": #FJK: the table column is "the_geom" |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
211 attrString=attrString+"ST_AsText("+name[0]+")," |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
212 not_added=False |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
213 break |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
214 for a_iter in attrTypes['rows']: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
215 not_added = True |
275 | 216 logging.debug("attrTypes.field_name: %s"%a_iter[0]) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
217 if a_iter[0]==name[0]: |
275 | 218 logging.debug("attrTypes.gis_type: %s"%a_iter[1]) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
219 if a_iter[1] == "the_geom": #FJK: the table column is registered in gis_table_meta_rows as type "the_geom" |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
220 attrString=attrString+"ST_AsText("+name[0]+")," |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
221 not_added=False |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
222 if not_added: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
223 if name[0].find('pg.dropped')==-1: |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
224 attrString=attrString+name[0]+"," |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
225 attrString=str(attrString).rsplit(",",1)[0] #to remove last "," |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
226 if sortBy: |
275 | 227 data = self.executeSQL('select %s from "%s"."%s" order by %%s'%(attrString,sqlName(schema),sqlName(table)),(sortBy,)) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
228 else: |
275 | 229 data = self.executeSQL('select %s from "%s"."%s"'%(attrString,sqlName(schema),sqlName(table))) |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
230 # except: |
275 | 231 # """ table does not exist """ |
274
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
232 # fields=self.get |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
233 # self.createEmptyTable(schema, table, fields) |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
234 return data |
9b7db308d2e6
refactor RestDbGisApi to use RestDbInterface from ZDbInterface Product.
casties
parents:
264
diff
changeset
|
235 |
43 | 236 |
59 | 237 def getLiveKmlUrl(self,schema,table,useTimestamp=True,REQUEST=None): |
254
901c1f745d13
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
252
diff
changeset
|
238 return self.getLiveUrl(schema,table,useTimestamp,REQUEST) |
55 | 239 |
273 | 240 def getKmlData(self, schema, table, ids=None, sortBy=1, gisIdField=None, latField=None, lonField=None, geomField="point", colorField="red_big",from_year_name='from_year',until_year_name=''): |
55 | 241 """returns data structure for KML template""" |
249 | 242 logging.debug("getKMLdata gid=%s lat=%s lon=%s sortBy=%s geom=%s color=%s"%(gisIdField,latField,lonField,sortBy,geomField,colorField)) |
148 | 243 if geomField is None: |
244 geomField="point" | |
245 if colorField is None: | |
246 colorField="red" | |
55 | 247 # Mapping a set of points from table-based SQL-query: |
275 | 248 qstr='SELECT * FROM "%s"."%s"'%(sqlName(schema),sqlName(table)) |
55 | 249 idList = None |
250 if ids is not None: | |
251 qstr += ' WHERE ' | |
255
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
252 if schema=='mpdl': |
55 | 253 qstr += 'mpdl_xmlsource_id IN (' |
254 else: | |
255 qstr += 'CAST(id AS text) IN (' | |
256 | |
257 idList = ids.split(",") | |
258 qstr += ','.join(['%s' for i in idList]) | |
259 qstr += ')' | |
260 | |
58 | 261 if sortBy: |
262 # add sort clause | |
59 | 263 if sortBy == 1: |
264 qstr += ' ORDER BY 1' | |
249 | 265 elif sortBy == 'Default': |
266 qstr += ' ORDER BY 1' | |
250
d7ceeb8ccbd7
Layer gui reordered, point order can be defined, minor edit
fknauft
parents:
249
diff
changeset
|
267 elif sortBy == 'undefined': |
d7ceeb8ccbd7
Layer gui reordered, point order can be defined, minor edit
fknauft
parents:
249
diff
changeset
|
268 qstr += ' ORDER BY 1' |
59 | 269 else: |
270 # TODO: proper quoting for names | |
271 qstr += ' ORDER BY "%s"'%sortBy.replace('"','') | |
245 | 272 bad_luck=True |
273 bl_counter=0 | |
274 while (bad_luck): | |
275 try: | |
276 data = self.executeSQL(qstr,idList) | |
277 bad_luck=False | |
278 bl_counter=bl_counter+1 | |
279 except: | |
255
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
280 if (bl_counter<5): |
245 | 281 bad_luck=True |
282 else: | |
283 bad_luck=False | |
284 | |
55 | 285 fieldMap = self.getFieldNameMap(data['fields']) |
261 | 286 geomdata=None |
247 | 287 if (geomField!="point"): |
261 | 288 # first check if the file is registered as geo-dataset (which then should have an attribute "the_geom") |
289 requeststring="select f_geometry_column from geometry_columns where f_table_schema=%s and f_table_name=%s " | |
290 geocolumn_res=self.executeSQL(requeststring,(schema,table)) | |
291 if len(geocolumn_res['rows'])>0: | |
292 geocolumn=geocolumn_res['rows'][0][0] | |
293 try: | |
275 | 294 geomstr="select astext(st_simplify(transform(%s,4326),0.05)) from %s.%s"%(geocolumn,sqlName(schema),sqlName(table)) # the string variables have to be added here and not in executeSQL! |
247 | 295 geomdata=self.executeSQL(geomstr) |
261 | 296 teststr=geomdata.values()[1][0] |
297 if (teststr == (u'MULTIPOLYGON EMPTY',)): | |
275 | 298 geomstr="select astext(st_simplify(transform(%s,4326),0.05)) from %s.%s"%(geocolumn,sqlName(schema),sqlName(table)) # the string variables have to be added here and not in executeSQL! |
261 | 299 geomdata=self.executeSQL(geomstr) |
300 | |
301 except: | |
302 try: | |
275 | 303 geomstr="select chgis.astext(chgis.st_simplify(chgis.transform(%s,4326),0.05)) from %s.%s"%(geocolumn,sqlName(schema),sqlName(table)) # the string variables have to be added here and not in executeSQL! |
261 | 304 geomdata=self.executeSQL(geomstr) |
305 except: | |
306 geomdata=None | |
233 | 307 |
308 if (gisIdField is None) and (latField is None or lonField is None) and geomField=='point': | |
55 | 309 # no fields given - choose automagically |
261 | 310 sql = "SELECT field_name FROM public.gis_table_meta_rows WHERE table_name = %s and gis_type = %s" |
55 | 311 # gis id in metadata first |
61 | 312 res = self.executeSQL(sql, (table,'gis_id')) |
55 | 313 if len(res['rows']) > 0: |
314 gisIdField = res['rows'][0][0] | |
255
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
315 # latitude in metadata |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
316 res = self.executeSQL(sql, (table,'coord_lat')) |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
317 if len(res['rows']) > 0: |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
318 latField = res['rows'][0][0] |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
319 # longitude in metadata |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
320 res = self.executeSQL(sql, (table,'coord_lon')) |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
321 if len(res['rows']) > 0: |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
322 lonField = res['rows'][0][0] |
93 | 323 |
233 | 324 if (gisIdField is None) and (latField is None or lonField is None) and geomField=='point': |
93 | 325 logging.warning("no entry in metadata table for table %s" % table) |
326 # still no fields - try field names | |
327 if 'latitude' in fieldMap and 'longitude' in fieldMap: | |
328 latField = 'latitude' | |
329 lonField = 'longitude' | |
330 elif 'x_coord' in fieldMap and 'y_coord' in fieldMap: | |
331 latField = 'x_coord' | |
332 lonField = 'y_coord' | |
333 else: | |
334 logging.error("getKMLdata unable to find position fields") | |
263 | 335 self.REQUEST.RESPONSE.write("Please define Position field") |
93 | 336 return None |
337 | |
55 | 338 |
339 # convert field names to row indexes | |
340 gisIdIdx = fieldMap.get(gisIdField,None) | |
341 latIdx = fieldMap.get(latField,None) | |
342 lonIdx = fieldMap.get(lonField,None) | |
117 | 343 the_geom=fieldMap.get("the_geom",None) |
55 | 344 logging.debug("gisidfield=%s idx=%s"%(gisIdField,gisIdIdx)) |
345 | |
346 # convert data | |
347 kmlData = [] | |
151 | 348 geom_list = {} |
261 | 349 # try: |
350 # if geomField=='poly' or geomField=='line': | |
351 # geom_list=geomdata.values()[1] | |
352 # except: | |
353 # return "no geomdata in RestDbGisApi Line 254" | |
354 | |
150 | 355 data_list=data['rows'] |
356 for k in range (len(data_list)): | |
357 dataset = data_list[k] | |
358 if len(geom_list)>k: | |
359 geom_value = geom_list[k] | |
360 | |
361 | |
261 | 362 if gisIdIdx != None and geomField!='point': |
363 gisID = dataset[gisIdIdx] | |
364 geomdata = self.getLineForChGisId(gisID) | |
365 | |
150 | 366 # for dataset in data['rows']: |
65 | 367 xCoord = 0.0 |
368 yCoord = 0.0 | |
255
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
369 if gisIdIdx != None and geomField=='point' : |
55 | 370 gisID = dataset[gisIdIdx] |
257
61525f0ca492
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
256
diff
changeset
|
371 if gisID != " " and gisID != " 0": |
255
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
372 coords=self.getPointForChGisId(gisID) |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
373 if coords!=None: |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
374 xCoord=coords[0] |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
375 yCoord=coords[1] |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
376 elif latIdx != None: |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
377 xCoord = dataset[lonIdx] |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
378 yCoord = dataset[latIdx] |
ec7b63319fad
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
254
diff
changeset
|
379 elif latIdx != None: |
55 | 380 xCoord = dataset[lonIdx] |
381 yCoord = dataset[latIdx] | |
382 | |
233 | 383 elif geomField=='point' : |
55 | 384 logging.error("getKMLdata unable to find position") |
385 return None | |
386 | |
233 | 387 if geomField=='point' : |
262 | 388 if type(xCoord).__name__=='string': |
389 if float(xCoord) == 0.0: | |
390 continue | |
391 else: | |
392 if xCoord == 0.0: | |
393 continue | |
394 if type(yCoord).__name__=='string': | |
395 if float(yCoord) == 0.0: | |
396 continue | |
397 else: | |
398 if yCoord == 0.0: | |
399 continue | |
55 | 400 |
401 kmlPlace = {} | |
402 | |
403 # description | |
404 desc = '' | |
150 | 405 |
262 | 406 timestring = '' |
264 | 407 beg_yr = '-9999' |
408 end_yr = '9999' | |
263 | 409 from_year = '' |
410 until_year = '' | |
411 sql = "SELECT field_name FROM public.gis_table_meta_rows WHERE table_name = %s and gis_type = %s" | |
412 # from_year and until_year in metadata first | |
264 | 413 try: |
273 | 414 res = self.executeSQL(sql, (table,from_year_name)) |
264 | 415 if len(res['rows']) > 0: |
416 from_year = res['rows'][0][0] | |
417 except: | |
418 from_year = "from_year_dummy" | |
419 try: | |
273 | 420 res = self.executeSQL(sql, (table,until_year_name)) |
264 | 421 if len(res['rows']) > 0: |
422 until_year = res['rows'][0][0] | |
423 except: | |
424 until_year = "until_year_dummy" | |
276 | 425 |
273 | 426 #DW added for testing E4D with names |
427 from_year=from_year_name | |
428 until_year=until_year_name | |
276 | 429 |
273 | 430 logging.debug("from_year:"+from_year) |
431 logging.debug("until_year:"+until_year) | |
150 | 432 for i in range (len(dataset)): |
433 value = dataset[i] | |
434 | |
55 | 435 name = data['fields'][i][0] |
58 | 436 #logging.debug("value=%s"%value) |
150 | 437 if name != 'the_geom': |
438 if value != None: | |
57 | 439 #if name.find('name')>-1: |
440 # desc += "<name>%s</name>\n"%value | |
441 # continue | |
442 #elif name.find('place')>-1: | |
443 # desc += "<name>%s</name>\n"%value | |
444 # continue | |
262 | 445 |
55 | 446 val = "%s: %s"%(name, value) |
273 | 447 logging.debug(name) |
187 | 448 value=unicode(value) |
263 | 449 if name == from_year: |
262 | 450 beg_yr= value |
263 | 451 if name == until_year: |
262 | 452 end_yr=value |
188 | 453 # If there is a link within the description data, create a valid href |
191 | 454 if value.find('http://')>-1: |
455 link_str_beg=value.find('http://') | |
456 link_str_end = -1 | |
457 link_str_end0=value.find(' ',link_str_beg) | |
458 link_str_end1=value.find('>',link_str_beg) | |
459 if link_str_end0 <link_str_end1: | |
460 link_str_end=link_str_end0 | |
461 else: | |
462 link_str_end=link_str_end1 | |
463 if link_str_end > -1: | |
464 link_str=value[link_str_beg:link_str_end] | |
207 | 465 val =name+": "+value[0:link_str_beg]+'<a href=' + link_str + '> ' + link_str.replace('http://','') + ' </a>' + value[link_str_end:] |
191 | 466 else: |
467 link_str=value[link_str_beg:] | |
207 | 468 val =name+': '+value[0:link_str_beg]+'<a href=' + link_str + '> ' + link_str.replace('http://','') + ' </a>' |
188 | 469 |
470 | |
57 | 471 #desc += kmlEncode(val) |
472 desc += val | |
55 | 473 desc += '<br/>\n' |
474 | |
57 | 475 #kmlPlace['description'] = "<![CDATA[%s]]>"%desc |
150 | 476 |
264 | 477 if end_yr!='9999': |
263 | 478 kmlPlace['TimeSpan0'] = '%s'%beg_yr |
479 kmlPlace['TimeSpan1'] = '%s'%end_yr | |
264 | 480 else: |
263 | 481 kmlPlace['TimeStamp'] = '%s'%beg_yr |
124 | 482 |
133 | 483 if geomField=='point': |
207 | 484 kmlPlace['description'] = "<![CDATA[%s]]>"%desc |
193 | 485 |
133 | 486 kmlPlace['icon'] = '#marker_icon_'+colorField |
487 kmlPlace['coord_x'] = str(xCoord) | |
488 kmlPlace['coord_y'] = str(yCoord) | |
258
ed99a2468264
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
257
diff
changeset
|
489 kmlPlace['coord_z'] = '50' |
134 | 490 kmlData.append(kmlPlace) |
261 | 491 if (geomField=='poly' or geomField=='line') and geomdata is not None: |
492 polys=str(geomdata).split('(') | |
144 | 493 aaa=len(polys) |
142 | 494 for poly in polys: |
150 | 495 kmlPlace = {} |
496 kmlPlace['description'] = desc | |
152 | 497 coords=poly.replace(')','').replace("'","").split(',') |
150 | 498 coord_string='' |
144 | 499 if len(coords)>1: |
146 | 500 for coord in coords: |
501 coord=coord.split(' ') | |
502 try: | |
503 x_coord=coord[0] | |
504 y_coord=coord[1] | |
505 except: | |
506 break | |
150 | 507 coord_string+=x_coord+','+y_coord+','+'0 ' |
508 if coord_string != '': | |
509 kmlPlace['LinearRing']=coord_string | |
245 | 510 kmlPlace['lineColor']='#'+colorField+'_'+geomField |
150 | 511 kmlData.append(kmlPlace) |
262 | 512 |
513 | |
55 | 514 #logging.debug("kmlData=%s"%(repr(kmlData))) |
515 return kmlData | |
58 | 516 |
517 def getPointForChGisId(self, gis_id): | |
260
e9a1ac7d2ab2
Bug resolved in request point_id from Harvard ChGIS
fknauft
parents:
259
diff
changeset
|
518 """returns coordinate pair for given gis_id""" # gets called by getKml |
59 | 519 def getPoint(id): |
247 | 520 str_gis_id=str(id).split('.')[0] |
521 sql="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE CAST('%s' AS text)"%str(str_gis_id) | |
522 # logging.error("sql:",sql) | |
523 # res = self.executeSQL(sql, (str(str_gis_id),)) | |
524 res = self.executeSQL(sql) | |
59 | 525 if len(res['rows']) > 0: |
526 return res['rows'][0] | |
247 | 527 else: |
528 #logging.error("error on sql:",sql%(str(str_gis_id),)) | |
529 return None | |
55 | 530 |
58 | 531 if gis_id is None or gis_id == "": |
532 return None | |
261 | 533 if len(str(gis_id)) < 4: |
260
e9a1ac7d2ab2
Bug resolved in request point_id from Harvard ChGIS
fknauft
parents:
259
diff
changeset
|
534 return None |
58 | 535 |
59 | 536 # try gis_id |
537 coords = getPoint(gis_id) | |
538 if coords is None: | |
58 | 539 # try to clean gis_id... |
247 | 540 gis_id_short = re.sub(r'[^0-9]','',gis_id) |
58 | 541 # try again |
247 | 542 coords = getPoint(gis_id_short) |
59 | 543 if coords is None: |
247 | 544 #logging.error("CH-GIS ID %s not found!"%str(gis_id_short)) |
545 | |
546 # this will ask the Harvard-Service for the Coords of this gis_id and write it into our coords-list | |
547 try: | |
548 coords=self.getCoordsFromREST_gisID(gis_id) | |
549 #logging.error("coords from REST"%str(coords)) | |
550 except: | |
551 logging.error("coords from REST did not work for "%str(gis_id)) | |
552 if coords[0] is None: | |
553 logging.error("CH-GIS ID %s not found in Harvard"%str(gis_id)) | |
554 else: | |
555 try: | |
556 SQL="INSERT INTO chgis.chgis_coords (gis_id,x_coord,y_coord) VALUES (CAST(%s AS text),CAST(%s AS numeric),CAST(%s AS numeric))" | |
557 SQL_analyze="ANALYZE chgis.chgis_coords" | |
558 self.executeSQL(SQL,(str(gis_id_short),str(coords[0][1]),str(coords[0][0])),False) | |
559 self.executeSQL(SQL_analyze,(),False) | |
560 except: | |
561 logging.error("Could not write into chgis_coords: ", str(gis_id_short)) | |
562 logging.error("coords[0][0]:"%coords[0][0]) | |
563 logging.error("coords[0][1]:"%coords[0][1]) | |
564 return coords[0] | |
565 coords_test = getPoint(gis_id) | |
566 #logging.error("SQL results now:", str(coords_test)) | |
567 return coords[0] | |
58 | 568 |
59 | 569 return coords |
570 | |
55 | 571 |
261 | 572 def getLineForChGisId(self, gis_id): |
573 """returns line/poly coordinates for given gis_id""" # gets called by getKml | |
574 def getLine(id): | |
575 str_gis_id=str(id).split('.')[0] | |
576 sql="SELECT astext(st_simplify(transform(the_geom,4326),0.05)) FROM chgis.chgis_linesandpolys WHERE gis_id LIKE CAST('%s' AS text)"%(str_gis_id) | |
577 # logging.error("sql:",sql) | |
578 # res = self.executeSQL(sql, (str(str_gis_id),)) | |
579 res = self.executeSQL(sql) | |
580 if len(res['rows']) > 0: | |
581 return res['rows'][0] | |
582 else: | |
583 #logging.error("error on sql:",sql%(str(str_gis_id),)) | |
584 return None | |
585 | |
586 if gis_id is None or gis_id == "": | |
587 return None | |
588 if len(str(gis_id)) < 4: | |
589 return None | |
590 | |
591 # try gis_id | |
592 line_coords = getLine(gis_id) | |
593 if line_coords is None: | |
594 # try to clean gis_id... | |
595 gis_id_short = re.sub(r'[^0-9]','',gis_id) | |
596 # try again | |
597 line_coords = getLine(gis_id_short) | |
598 if line_coords is None: | |
599 logging.error("CH-GIS ID %s not found!"%(gis_id_short)) | |
600 | |
601 | |
602 return line_coords | |
603 | |
59 | 604 ## legacy methods... |
605 | |
254
901c1f745d13
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
252
diff
changeset
|
606 def getKmlUrl(self,schema='chgis',table='mpdl',args={'doc':None,'id':None}): |
59 | 607 logging.debug("getKmlUrl") |
254
901c1f745d13
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
252
diff
changeset
|
608 id=args.get('id') |
901c1f745d13
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
252
diff
changeset
|
609 doc=args.get('doc') |
59 | 610 data = self.getDataForGoogleMap(schema,table,id,doc) |
611 kml=self.getKMLname(data=data,table=table) | |
612 baseUrl = self.absolute_url() | |
613 return "%s/daten/%s"%(baseUrl,kml) | |
614 | |
615 def getDataForGoogleMap(self,schema='chgis',table='mpdl',id=None,doc=None): | |
616 logging.debug("getDataForGoogleMap") | |
617 qstr="SELECT * FROM "+schema+"."+table | |
618 try: | |
619 if id is not None: | |
620 qstr=qstr+" WHERE " | |
621 for id_item in id.split(","): | |
622 if table=='mpdl': | |
623 qstr=qstr+" mpdl_xmlsource_id = '"+id_item+ "' OR" | |
624 else: | |
625 qstr=qstr+" cast(id as text) LIKE '"+id_item+ "' OR" | |
626 qstr=str(qstr).rsplit(" ",1)[0] #to remove last " and " | |
627 data=self.ZSQLSimpleSearch(qstr) | |
628 return data | |
629 except: | |
630 return qstr | |
55 | 631 |
632 | |
43 | 633 def getKMLname(self,data=[],table=""): |
634 logging.debug("getKMLname") | |
635 #session=context.REQUEST.SESSION | |
109 | 636 kml4Marker="<kml xmlns=\'http://www.opengis.net/kml/2.2\'><Document>" |
637 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" | |
638 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" | |
639 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" | |
640 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" | |
641 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" | |
43 | 642 initializeStringForGoogleMaps="" |
643 #doLine=container.getVar('doLine') | |
644 # Mapping a set of points from table-based SQL-query: | |
645 if data!=None: | |
646 try: | |
647 SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s' | |
648 res = self.executeSQL(SQL, (table,)) | |
649 gisIDattribute = res['rows'][0][0] | |
650 except: | |
651 return "table not registered within metadata" | |
652 | |
653 for dataset in data: | |
654 try: | |
655 xCoord=getattr(dataset,'longitude') | |
656 yCoord=getattr(dataset,'latitude') | |
657 except: | |
658 try: | |
659 xCoord=getattr(dataset,'x_coord') | |
660 yCoord=getattr(dataset,'y_coord') | |
661 except: | |
662 #try: | |
663 gisID=getattr(dataset,gisIDattribute) | |
664 coords=self.getPoint4GISid(gisID) | |
665 if coords!=None: | |
666 xCoord=coords[0] | |
667 yCoord=coords[1] | |
668 # except: | |
669 # return "no coordinates found" | |
670 | |
671 if float(xCoord)!=0: | |
672 if float(yCoord)!=0: | |
673 kml4Marker=kml4Marker+"<Placemark>" | |
674 kml4Marker=kml4Marker+"<description> <![CDATA[<b>" | |
675 for values in dataset: | |
55 | 676 #logging.debug("values=%s"%repr(values)) |
43 | 677 if values != (None, None): |
678 if str(values).find('name')>-1: | |
679 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" | |
680 continue | |
681 elif str(values).find('place')>-1: | |
682 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" | |
683 continue | |
684 | |
685 kml4Marker=kml4Marker+str(values)+": " | |
686 attribute_string=str(values).replace("'","__Apostroph__") | |
687 attribute_string=str(attribute_string).replace('"','__DoubleApostroph__') | |
688 attribute_string=str(attribute_string).replace(';','__$$__') | |
689 attribute_string=str(attribute_string).replace('&','&') | |
690 if str(attribute_string).find('http')>-1: | |
207 | 691 attribute_string='<A HREF=' + str(attribute_string) + ' target="_blank">' + str(attribute_string) + '</A>' |
43 | 692 kml4Marker=kml4Marker+attribute_string+"</a><br>\n" |
693 | |
694 kml4Marker=kml4Marker+"]]></description>\n" | |
117 | 695 kml4Marker=kml4Marker+"<styleURL>#marker_icon_red</styleURL>\n" |
43 | 696 kml4Marker=kml4Marker+"<Point>" |
697 | |
698 kml4Marker=kml4Marker+"<coordinates>"+str(xCoord)+","+str(yCoord)+",0</coordinates>\n" | |
699 kml4Marker=kml4Marker+"</Point>\n" | |
700 kml4Marker=kml4Marker+"</Placemark>\n" | |
701 | |
702 kml4Marker=kml4Marker+"</Document>\n</kml>" | |
703 kmlFileName="marker"+str(time.time())+".kml" | |
704 | |
705 #kml4Marker=str(kml4Marker).replace('&','$$') | |
706 #kml4Marker=str(kml4Marker).replace(';','__$$__') | |
707 #kml4Marker=str(kml4Marker).replace('#','__SHARP__') | |
708 isLoadReady='false' | |
709 while isLoadReady=='false': | |
710 isLoadReady=self.RESTwrite2File(self.daten,kmlFileName,kml4Marker) | |
711 | |
712 return kmlFileName | |
207 | 713 |
714 def trydatahas_key(self,data,index,key_string): | |
273 | 715 logging.debug("trying:"+key_string) |
207 | 716 try: |
717 return data[index].has_key(key_string) | |
718 except: | |
719 return 'false' | |
43 | 720 |
44 | 721 # def getGoogleMapString(self,kml): |
722 # logging.debug("getGoogleMapString") | |
723 # printed= '<body %s> '%kml +"""\n <div id="map_canvas" style="width: 98%; height: 95%"> </div> \n </body>" \n </html>""" | |
724 # return printed | |
43 | 725 |
726 def getPoint4GISid(self,gis_id): | |
727 j=0 | |
728 coords=(0,0) | |
729 if gis_id != None: | |
730 while (True): | |
731 j=j+1 | |
732 if (j>100): # FJK: just to prevent endless loops | |
733 break | |
734 if (gis_id.isdigit()): # FJK: regular exit from while-loop | |
735 break | |
736 else: | |
737 gis_id=gis_id.strip('abcdefghijklmnopqrstuvwxyz_') # FJK: to strip all letters | |
738 gis_id=gis_id.strip() # FJK: to strip all whitespaces | |
739 resultpoint = [0,0] | |
740 results = None | |
741 try: | |
742 if int(gis_id)>0: | |
743 SQL="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE cast("+ str(gis_id) +" as text);" | |
744 results=self.ZSQLSimpleSearch(SQL) | |
745 #print results | |
746 if results != None: | |
747 for result in results: | |
748 resultpoint=[getattr(result,str('x_coord')),getattr(result,str('y_coord'))] | |
749 if resultpoint !=[0,0]: | |
750 return resultpoint | |
751 else: | |
247 | 752 coords=self.getCoordsFromREST_gisID(gis_id) |
753 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;" | |
43 | 754 returnstring=self.ZSQLSimpleSearch(SQL) |
755 return coords[0] | |
756 except: | |
757 return "gis_id not to interpretable:"+str(gis_id) | |
758 else: | |
759 return coords[0] | |
760 | |
761 def getCoordsFromREST_gisID(self,gis_id): | |
247 | 762 gis_id=gis_id.strip() |
43 | 763 coordlist=[] |
764 i=0 | |
765 while (i<5 and coordlist==[]): | |
256
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
766 urlinfo=urlFunctions.zUrlopenInfo(self,"http://chgis.hmdc.harvard.edu/xml/id/"+gis_id) |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
767 urlinfoLength=urlinfo.get('content-length') |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
768 if int(urlinfoLength)<500: |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
769 urlresponse=urlFunctions.zUrlopenRead(self,"http://chgis.hmdc.harvard.edu/xml/id/cts_"+gis_id) |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
770 else: |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
771 urlresponse=urlFunctions.zUrlopenRead(self,"http://chgis.hmdc.harvard.edu/xml/id/"+gis_id) |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
772 urlresponseString=urlFunctions.zUrlopenParseString(self,urlresponse) |
cb953cc153a6
GIS-Links from MPDL-Documents now served by Mappit-Server
fknauft
parents:
255
diff
changeset
|
773 baseDocElement= urlFunctions.zUrlopenDocumentElement(self,urlresponseString) |
247 | 774 childnodes=urlFunctions.zUrlopenChildNodes(self,baseDocElement) |
775 itemnodes=urlFunctions.zUrlopenGetElementsByTagName(self,baseDocElement,'item') | |
776 itemspatialnodes=None | |
777 | |
778 for i in range(0,urlFunctions.zUrlopenLength(self,itemnodes)): | |
779 itemnode=urlFunctions.zUrlopenGetItem(self,itemnodes,i) | |
780 itemspatialnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemnode,'spatial') | |
781 if itemspatialnodes is not None: | |
782 for j in range(0,urlFunctions.zUrlopenLength(self,itemspatialnodes)): | |
783 coord=[] | |
784 itemspatialnode= urlFunctions.zUrlopenGetItem(self,itemspatialnodes,j) | |
785 itemspatiallatnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_latitude') | |
786 for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallatnodes)): | |
787 itemspatiallatnode= urlFunctions.zUrlopenGetItem(self,itemspatiallatnodes,k) | |
788 coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallatnode)) | |
789 itemspatiallngnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_longitude') | |
790 for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallngnodes)): | |
791 itemspatiallngnode= urlFunctions.zUrlopenGetItem(self,itemspatiallngnodes,k) | |
792 coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallngnode)) | |
793 coordlist.append(coord) | |
794 gis_id= "_"+gis_id | |
43 | 795 return coordlist |
796 | |
797 # End for GoogleMaps creation | |
798 | |
799 def RESTwrite2File(self,datadir, name,text): | |
800 logging.debug("RESTwrite2File datadir=%s name=%s"%(datadir,name)) | |
801 try: | |
802 import cStringIO as StringIO | |
803 except: | |
804 import StringIO | |
805 | |
806 # make filehandle from string | |
807 textfile = StringIO.StringIO(text) | |
808 fileid=name | |
809 if fileid in datadir.objectIds(): | |
810 datadir.manage_delObjects(fileid) | |
811 fileInZope=datadir.manage_addFile(id=fileid,file=textfile) | |
812 return "Write successful" | |
813 | |
814 def manage_editRestDbGisApi(self, title=None, connection_id=None, | |
815 REQUEST=None): | |
816 """Change the object""" | |
817 if title is not None: | |
818 self.title = title | |
819 | |
820 if connection_id is not None: | |
821 self.connection_id = connection_id | |
822 | |
823 #checkPermission=getSecurityManager().checkPermission | |
824 REQUEST.RESPONSE.redirect('manage_main') | |
825 | |
826 | |
827 manage_addRestDbGisApiForm=PageTemplateFile('zpt/addRestDbGisApi',globals()) | |
828 | |
829 def manage_addRestDbGisApi(self, id, title='', label='', description='', | |
830 createPublic=0, | |
831 createUserF=0, | |
832 REQUEST=None): | |
833 """Add a new object with id *id*.""" | |
834 | |
835 ob=RestDbGisApi(str(id),title) | |
836 self._setObject(id, ob) | |
837 | |
838 #checkPermission=getSecurityManager().checkPermission | |
839 REQUEST.RESPONSE.redirect('manage_main') | |
840 | |
247 | 841 |
842 | |
843 |