Mercurial > hg > ChinaGisRestApi
annotate RestDbGisApi.py @ 252:efd2469d1722
geometry-column of tables will be displayed as string
author | fknauft |
---|---|
date | Tue, 20 Sep 2011 11:19:35 +0200 |
parents | d7ceeb8ccbd7 |
children | 901c1f745d13 |
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 |
57 | 14 import urllib |
247 | 15 import urlFunctions |
43 | 16 |
17 from RestDbInterface import * | |
18 | |
19 | |
20 | |
55 | 21 def kmlEncode(s): |
22 """returns string encoded for displaying in KML attribute""" | |
23 res = s.replace("'","__Apostroph__") | |
24 res = res.replace('"','__DoubleApostroph__') | |
25 res = res.replace(';','__$$__') | |
26 res = res.replace('&','&') | |
27 return res | |
28 | |
29 | |
43 | 30 class RestDbGisApi(RestDbInterface): |
31 """Object for RESTful GIS database queries | |
32 path schema: /db/{schema}/{table}/ | |
33 omitting table gives a list of schemas | |
34 omitting table and schema gives a list of schemas | |
35 """ | |
36 | |
37 meta_type="RESTgis" | |
38 | |
39 # data templates | |
40 GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals()) | |
55 | 41 KML_schema_table = PageTemplateFile('zpt/KML_schema_table', globals()) |
61 | 42 HTML_schema_usertables = PageTemplateFile('zpt/HTML_schema_usertables', globals()) |
55 | 43 |
44 | 44 # and scripts |
245 | 45 def KML_URL_schema_table(self,schema,table, useTimestamp=True): |
44 | 46 """KML_URL table function""" |
47 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") | |
48 id = self.REQUEST.get('id',[]) | |
49 doc = self.REQUEST.get('doc',None) | |
245 | 50 # return self.getLiveKmlUrl(schema=schema,table=table, useTimestamp=useTimestamp) |
51 return self.getLiveKmlUrl(schema=schema,table=table, useTimestamp=False) | |
43 | 52 |
61 | 53 # |
54 # database methods | |
55 # | |
70 | 56 toSqlTypeMap = { |
57 "text": "text", | |
58 "number": "numeric", | |
59 "id": "text", | |
60 "gis_id": "text", | |
61 "coord_lat": "numeric", | |
252
efd2469d1722
geometry-column of tables will be displayed as string
fknauft
parents:
250
diff
changeset
|
62 "coord_lon": "numeric", |
efd2469d1722
geometry-column of tables will be displayed as string
fknauft
parents:
250
diff
changeset
|
63 "the_geom": "the_geom" |
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""" | |
61 | 145 sqlFields = RestDbInterface.createEmptyTable(self,schema,table,fields) |
146 if sqlFields is not None: | |
43 | 147 self.setTableMetaTypes(schema,table,sqlFields) |
61 | 148 |
149 return sqlFields | |
43 | 150 |
151 | |
59 | 152 def getLiveKmlUrl(self,schema,table,useTimestamp=True,REQUEST=None): |
57 | 153 if REQUEST is None: |
154 REQUEST = self.REQUEST | |
55 | 155 logging.debug("getLiveKmlUrl") |
156 baseUrl = self.absolute_url() | |
57 | 157 timestamp = time.time() |
59 | 158 # filter parameters in URL and add to new URL |
57 | 159 params = [p for p in REQUEST.form.items() if p[0] not in ('format','timestamp')] |
160 params.append(('format','KML')) | |
59 | 161 if useTimestamp: |
162 # add timestamp so URL changes every time | |
163 params.append(('timestamp',timestamp)) | |
57 | 164 paramstr = urllib.urlencode(params) |
165 return "%s/db/%s/%s?%s"%(baseUrl,schema,table,paramstr) | |
55 | 166 |
127 | 167 def getKmlData(self, schema, table, ids=None, sortBy=1, gisIdField=None, latField=None, lonField=None, geomField="point", colorField="red"): |
55 | 168 """returns data structure for KML template""" |
249 | 169 logging.debug("getKMLdata gid=%s lat=%s lon=%s sortBy=%s geom=%s color=%s"%(gisIdField,latField,lonField,sortBy,geomField,colorField)) |
148 | 170 if geomField is None: |
171 geomField="point" | |
172 if colorField is None: | |
173 colorField="red" | |
55 | 174 # Mapping a set of points from table-based SQL-query: |
175 qstr='SELECT * FROM "%s"."%s"'%(schema,table) | |
176 idList = None | |
177 if ids is not None: | |
178 qstr += ' WHERE ' | |
179 if table=='mpdl': | |
180 qstr += 'mpdl_xmlsource_id IN (' | |
181 else: | |
182 qstr += 'CAST(id AS text) IN (' | |
183 | |
184 idList = ids.split(",") | |
185 qstr += ','.join(['%s' for i in idList]) | |
186 qstr += ')' | |
187 | |
58 | 188 if sortBy: |
189 # add sort clause | |
59 | 190 if sortBy == 1: |
191 qstr += ' ORDER BY 1' | |
249 | 192 elif sortBy == 'Default': |
193 qstr += ' ORDER BY 1' | |
250
d7ceeb8ccbd7
Layer gui reordered, point order can be defined, minor edit
fknauft
parents:
249
diff
changeset
|
194 elif sortBy == 'undefined': |
d7ceeb8ccbd7
Layer gui reordered, point order can be defined, minor edit
fknauft
parents:
249
diff
changeset
|
195 qstr += ' ORDER BY 1' |
59 | 196 else: |
197 # TODO: proper quoting for names | |
198 qstr += ' ORDER BY "%s"'%sortBy.replace('"','') | |
245 | 199 bad_luck=True |
200 bl_counter=0 | |
201 while (bad_luck): | |
202 try: | |
203 data = self.executeSQL(qstr,idList) | |
204 bad_luck=False | |
205 bl_counter=bl_counter+1 | |
206 except: | |
207 if (bl_counter<100): | |
208 bad_luck=True | |
209 else: | |
210 bad_luck=False | |
211 | |
55 | 212 fieldMap = self.getFieldNameMap(data['fields']) |
247 | 213 if (geomField!="point"): |
214 try: | |
215 geomstr='select astext(st_simplify(transform(the_geom,4326),0.05)) from "%s"."%s"'%(schema,table) | |
233 | 216 geomdata=self.executeSQL(geomstr) |
247 | 217 teststr=geomdata.values()[1][0] |
218 if (teststr == (u'MULTIPOLYGON EMPTY',)): | |
219 geomstr='select astext(st_simplify(transform(the_geom,2333),0.05)) from "%s"."%s"'%(schema,table) | |
220 geomdata=self.executeSQL(geomstr) | |
233 | 221 |
207 | 222 except: |
247 | 223 try: |
224 geomstr='select chgis.astext(chgis.st_simplify(chgis.transform(the_geom,4326),0.05)) from "%s"."%s"'%(schema,table) | |
225 geomdata=self.executeSQL(geomstr) | |
226 except: | |
227 geomdata=None | |
117 | 228 |
233 | 229 if (gisIdField is None) and (latField is None or lonField is None) and geomField=='point': |
55 | 230 # no fields given - choose automagically |
93 | 231 sql = 'SELECT field_name FROM public.gis_table_meta_rows WHERE table_name = %s and gis_type = %s' |
55 | 232 # gis id in metadata first |
61 | 233 res = self.executeSQL(sql, (table,'gis_id')) |
55 | 234 if len(res['rows']) > 0: |
235 gisIdField = res['rows'][0][0] | |
236 else: | |
93 | 237 # latitude in metadata |
238 res = self.executeSQL(sql, (table,'coord_lat')) | |
239 if len(res['rows']) > 0: | |
240 latField = res['rows'][0][0] | |
241 # longitude in metadata | |
242 res = self.executeSQL(sql, (table,'coord_lon')) | |
243 if len(res['rows']) > 0: | |
244 lonField = res['rows'][0][0] | |
245 | |
233 | 246 if (gisIdField is None) and (latField is None or lonField is None) and geomField=='point': |
93 | 247 logging.warning("no entry in metadata table for table %s" % table) |
248 # still no fields - try field names | |
249 if 'latitude' in fieldMap and 'longitude' in fieldMap: | |
250 latField = 'latitude' | |
251 lonField = 'longitude' | |
252 elif 'x_coord' in fieldMap and 'y_coord' in fieldMap: | |
253 latField = 'x_coord' | |
254 lonField = 'y_coord' | |
255 else: | |
256 logging.error("getKMLdata unable to find position fields") | |
257 return None | |
258 | |
55 | 259 |
260 # convert field names to row indexes | |
261 gisIdIdx = fieldMap.get(gisIdField,None) | |
262 latIdx = fieldMap.get(latField,None) | |
263 lonIdx = fieldMap.get(lonField,None) | |
117 | 264 the_geom=fieldMap.get("the_geom",None) |
55 | 265 logging.debug("gisidfield=%s idx=%s"%(gisIdField,gisIdIdx)) |
266 | |
267 # convert data | |
268 kmlData = [] | |
151 | 269 geom_list = {} |
233 | 270 try: |
271 if geomField=='poly' or geomField=='line': | |
150 | 272 geom_list=geomdata.values()[1] |
233 | 273 except: |
274 return "no geomdata in RestDbGisApi Line 254" | |
150 | 275 data_list=data['rows'] |
276 for k in range (len(data_list)): | |
277 dataset = data_list[k] | |
278 if len(geom_list)>k: | |
279 geom_value = geom_list[k] | |
280 | |
281 | |
282 | |
283 # for dataset in data['rows']: | |
65 | 284 xCoord = 0.0 |
285 yCoord = 0.0 | |
233 | 286 if gisIdIdx is not None and geomField=='point' : |
55 | 287 gisID = dataset[gisIdIdx] |
58 | 288 coords=self.getPointForChGisId(gisID) |
55 | 289 if coords!=None: |
290 xCoord=coords[0] | |
291 yCoord=coords[1] | |
292 | |
293 elif latIdx is not None: | |
294 xCoord = dataset[lonIdx] | |
295 yCoord = dataset[latIdx] | |
296 | |
233 | 297 elif geomField=='point' : |
55 | 298 logging.error("getKMLdata unable to find position") |
299 return None | |
300 | |
233 | 301 if geomField=='point' : |
302 if float(xCoord) == 0.0: | |
55 | 303 continue |
233 | 304 if float(yCoord) == 0.0: |
55 | 305 continue |
306 | |
307 kmlPlace = {} | |
308 | |
309 # description | |
310 desc = '' | |
150 | 311 |
312 | |
313 for i in range (len(dataset)): | |
314 value = dataset[i] | |
315 | |
55 | 316 name = data['fields'][i][0] |
58 | 317 #logging.debug("value=%s"%value) |
150 | 318 if name != 'the_geom': |
319 if value != None: | |
57 | 320 #if name.find('name')>-1: |
321 # desc += "<name>%s</name>\n"%value | |
322 # continue | |
323 #elif name.find('place')>-1: | |
324 # desc += "<name>%s</name>\n"%value | |
325 # continue | |
55 | 326 |
327 val = "%s: %s"%(name, value) | |
187 | 328 value=unicode(value) |
188 | 329 |
330 # If there is a link within the description data, create a valid href | |
191 | 331 if value.find('http://')>-1: |
332 link_str_beg=value.find('http://') | |
333 link_str_end = -1 | |
334 link_str_end0=value.find(' ',link_str_beg) | |
335 link_str_end1=value.find('>',link_str_beg) | |
336 if link_str_end0 <link_str_end1: | |
337 link_str_end=link_str_end0 | |
338 else: | |
339 link_str_end=link_str_end1 | |
340 if link_str_end > -1: | |
341 link_str=value[link_str_beg:link_str_end] | |
207 | 342 val =name+": "+value[0:link_str_beg]+'<a href=' + link_str + '> ' + link_str.replace('http://','') + ' </a>' + value[link_str_end:] |
191 | 343 else: |
344 link_str=value[link_str_beg:] | |
207 | 345 val =name+': '+value[0:link_str_beg]+'<a href=' + link_str + '> ' + link_str.replace('http://','') + ' </a>' |
188 | 346 |
347 | |
57 | 348 #desc += kmlEncode(val) |
349 desc += val | |
55 | 350 desc += '<br/>\n' |
351 | |
57 | 352 #kmlPlace['description'] = "<![CDATA[%s]]>"%desc |
150 | 353 |
124 | 354 |
133 | 355 if geomField=='point': |
207 | 356 kmlPlace['description'] = "<![CDATA[%s]]>"%desc |
193 | 357 |
133 | 358 kmlPlace['icon'] = '#marker_icon_'+colorField |
359 kmlPlace['coord_x'] = str(xCoord) | |
360 kmlPlace['coord_y'] = str(yCoord) | |
361 kmlPlace['coord_z'] = '0' | |
134 | 362 kmlData.append(kmlPlace) |
233 | 363 if (geomField=='poly' or geomField=='line') and len(geomdata)>0: |
150 | 364 polys=str(geom_value).split('(') |
144 | 365 aaa=len(polys) |
142 | 366 for poly in polys: |
150 | 367 kmlPlace = {} |
368 kmlPlace['description'] = desc | |
152 | 369 coords=poly.replace(')','').replace("'","").split(',') |
150 | 370 coord_string='' |
144 | 371 if len(coords)>1: |
146 | 372 for coord in coords: |
373 coord=coord.split(' ') | |
374 try: | |
375 x_coord=coord[0] | |
376 y_coord=coord[1] | |
377 except: | |
378 break | |
150 | 379 coord_string+=x_coord+','+y_coord+','+'0 ' |
380 if coord_string != '': | |
381 kmlPlace['LinearRing']=coord_string | |
245 | 382 kmlPlace['lineColor']='#'+colorField+'_'+geomField |
150 | 383 kmlData.append(kmlPlace) |
55 | 384 #logging.debug("kmlData=%s"%(repr(kmlData))) |
385 return kmlData | |
58 | 386 |
387 def getPointForChGisId(self, gis_id): | |
388 """returns coordinate pair for given gis_id""" | |
59 | 389 def getPoint(id): |
247 | 390 str_gis_id=str(id).split('.')[0] |
391 sql="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE CAST('%s' AS text)"%str(str_gis_id) | |
392 # logging.error("sql:",sql) | |
393 # res = self.executeSQL(sql, (str(str_gis_id),)) | |
394 res = self.executeSQL(sql) | |
59 | 395 if len(res['rows']) > 0: |
396 return res['rows'][0] | |
247 | 397 else: |
398 #logging.error("error on sql:",sql%(str(str_gis_id),)) | |
399 return None | |
55 | 400 |
58 | 401 if gis_id is None or gis_id == "": |
402 return None | |
403 | |
59 | 404 # try gis_id |
405 coords = getPoint(gis_id) | |
406 if coords is None: | |
58 | 407 # try to clean gis_id... |
247 | 408 gis_id_short = re.sub(r'[^0-9]','',gis_id) |
58 | 409 # try again |
247 | 410 coords = getPoint(gis_id_short) |
59 | 411 if coords is None: |
247 | 412 #logging.error("CH-GIS ID %s not found!"%str(gis_id_short)) |
413 | |
414 # this will ask the Harvard-Service for the Coords of this gis_id and write it into our coords-list | |
415 try: | |
416 coords=self.getCoordsFromREST_gisID(gis_id) | |
417 #logging.error("coords from REST"%str(coords)) | |
418 except: | |
419 logging.error("coords from REST did not work for "%str(gis_id)) | |
420 if coords[0] is None: | |
421 logging.error("CH-GIS ID %s not found in Harvard"%str(gis_id)) | |
422 else: | |
423 try: | |
424 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))" | |
425 SQL_analyze="ANALYZE chgis.chgis_coords" | |
426 self.executeSQL(SQL,(str(gis_id_short),str(coords[0][1]),str(coords[0][0])),False) | |
427 self.executeSQL(SQL_analyze,(),False) | |
428 except: | |
429 logging.error("Could not write into chgis_coords: ", str(gis_id_short)) | |
430 logging.error("coords[0][0]:"%coords[0][0]) | |
431 logging.error("coords[0][1]:"%coords[0][1]) | |
432 return coords[0] | |
433 coords_test = getPoint(gis_id) | |
434 #logging.error("SQL results now:", str(coords_test)) | |
435 return coords[0] | |
58 | 436 |
59 | 437 return coords |
438 | |
55 | 439 |
59 | 440 ## legacy methods... |
441 | |
442 def getKmlUrl(self,schema='chgis',table='mpdl',id=[],doc=None): | |
443 logging.debug("getKmlUrl") | |
444 data = self.getDataForGoogleMap(schema,table,id,doc) | |
445 kml=self.getKMLname(data=data,table=table) | |
446 baseUrl = self.absolute_url() | |
447 return "%s/daten/%s"%(baseUrl,kml) | |
448 | |
449 def getDataForGoogleMap(self,schema='chgis',table='mpdl',id=None,doc=None): | |
450 logging.debug("getDataForGoogleMap") | |
451 qstr="SELECT * FROM "+schema+"."+table | |
452 try: | |
453 if id is not None: | |
454 qstr=qstr+" WHERE " | |
455 for id_item in id.split(","): | |
456 if table=='mpdl': | |
457 qstr=qstr+" mpdl_xmlsource_id = '"+id_item+ "' OR" | |
458 else: | |
459 qstr=qstr+" cast(id as text) LIKE '"+id_item+ "' OR" | |
460 qstr=str(qstr).rsplit(" ",1)[0] #to remove last " and " | |
461 data=self.ZSQLSimpleSearch(qstr) | |
462 return data | |
463 except: | |
464 return qstr | |
55 | 465 |
466 | |
43 | 467 def getKMLname(self,data=[],table=""): |
468 logging.debug("getKMLname") | |
469 #session=context.REQUEST.SESSION | |
109 | 470 kml4Marker="<kml xmlns=\'http://www.opengis.net/kml/2.2\'><Document>" |
471 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" | |
472 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" | |
473 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" | |
474 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" | |
475 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 | 476 initializeStringForGoogleMaps="" |
477 #doLine=container.getVar('doLine') | |
478 # Mapping a set of points from table-based SQL-query: | |
479 if data!=None: | |
480 try: | |
481 SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s' | |
482 res = self.executeSQL(SQL, (table,)) | |
483 gisIDattribute = res['rows'][0][0] | |
484 except: | |
485 return "table not registered within metadata" | |
486 | |
487 for dataset in data: | |
488 try: | |
489 xCoord=getattr(dataset,'longitude') | |
490 yCoord=getattr(dataset,'latitude') | |
491 except: | |
492 try: | |
493 xCoord=getattr(dataset,'x_coord') | |
494 yCoord=getattr(dataset,'y_coord') | |
495 except: | |
496 #try: | |
497 gisID=getattr(dataset,gisIDattribute) | |
498 coords=self.getPoint4GISid(gisID) | |
499 if coords!=None: | |
500 xCoord=coords[0] | |
501 yCoord=coords[1] | |
502 # except: | |
503 # return "no coordinates found" | |
504 | |
505 if float(xCoord)!=0: | |
506 if float(yCoord)!=0: | |
507 kml4Marker=kml4Marker+"<Placemark>" | |
508 kml4Marker=kml4Marker+"<description> <![CDATA[<b>" | |
509 for values in dataset: | |
55 | 510 #logging.debug("values=%s"%repr(values)) |
43 | 511 if values != (None, None): |
512 if str(values).find('name')>-1: | |
513 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" | |
514 continue | |
515 elif str(values).find('place')>-1: | |
516 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n" | |
517 continue | |
518 | |
519 kml4Marker=kml4Marker+str(values)+": " | |
520 attribute_string=str(values).replace("'","__Apostroph__") | |
521 attribute_string=str(attribute_string).replace('"','__DoubleApostroph__') | |
522 attribute_string=str(attribute_string).replace(';','__$$__') | |
523 attribute_string=str(attribute_string).replace('&','&') | |
524 if str(attribute_string).find('http')>-1: | |
207 | 525 attribute_string='<A HREF=' + str(attribute_string) + ' target="_blank">' + str(attribute_string) + '</A>' |
43 | 526 kml4Marker=kml4Marker+attribute_string+"</a><br>\n" |
527 | |
528 kml4Marker=kml4Marker+"]]></description>\n" | |
117 | 529 kml4Marker=kml4Marker+"<styleURL>#marker_icon_red</styleURL>\n" |
43 | 530 kml4Marker=kml4Marker+"<Point>" |
531 | |
532 kml4Marker=kml4Marker+"<coordinates>"+str(xCoord)+","+str(yCoord)+",0</coordinates>\n" | |
533 kml4Marker=kml4Marker+"</Point>\n" | |
534 kml4Marker=kml4Marker+"</Placemark>\n" | |
535 | |
536 kml4Marker=kml4Marker+"</Document>\n</kml>" | |
537 kmlFileName="marker"+str(time.time())+".kml" | |
538 | |
539 #kml4Marker=str(kml4Marker).replace('&','$$') | |
540 #kml4Marker=str(kml4Marker).replace(';','__$$__') | |
541 #kml4Marker=str(kml4Marker).replace('#','__SHARP__') | |
542 isLoadReady='false' | |
543 while isLoadReady=='false': | |
544 isLoadReady=self.RESTwrite2File(self.daten,kmlFileName,kml4Marker) | |
545 | |
546 return kmlFileName | |
207 | 547 |
548 def trydatahas_key(self,data,index,key_string): | |
549 try: | |
550 return data[index].has_key(key_string) | |
551 except: | |
552 return 'false' | |
43 | 553 |
44 | 554 # def getGoogleMapString(self,kml): |
555 # logging.debug("getGoogleMapString") | |
556 # printed= '<body %s> '%kml +"""\n <div id="map_canvas" style="width: 98%; height: 95%"> </div> \n </body>" \n </html>""" | |
557 # return printed | |
43 | 558 |
559 def getPoint4GISid(self,gis_id): | |
560 j=0 | |
561 coords=(0,0) | |
562 if gis_id != None: | |
563 while (True): | |
564 j=j+1 | |
565 if (j>100): # FJK: just to prevent endless loops | |
566 break | |
567 if (gis_id.isdigit()): # FJK: regular exit from while-loop | |
568 break | |
569 else: | |
570 gis_id=gis_id.strip('abcdefghijklmnopqrstuvwxyz_') # FJK: to strip all letters | |
571 gis_id=gis_id.strip() # FJK: to strip all whitespaces | |
572 resultpoint = [0,0] | |
573 results = None | |
574 try: | |
575 if int(gis_id)>0: | |
576 SQL="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE cast("+ str(gis_id) +" as text);" | |
577 results=self.ZSQLSimpleSearch(SQL) | |
578 #print results | |
579 if results != None: | |
580 for result in results: | |
581 resultpoint=[getattr(result,str('x_coord')),getattr(result,str('y_coord'))] | |
582 if resultpoint !=[0,0]: | |
583 return resultpoint | |
584 else: | |
247 | 585 coords=self.getCoordsFromREST_gisID(gis_id) |
586 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 | 587 returnstring=self.ZSQLSimpleSearch(SQL) |
588 return coords[0] | |
589 except: | |
590 return "gis_id not to interpretable:"+str(gis_id) | |
591 else: | |
592 return coords[0] | |
593 | |
594 def getCoordsFromREST_gisID(self,gis_id): | |
247 | 595 gis_id=gis_id.strip() |
43 | 596 coordlist=[] |
597 i=0 | |
598 while (i<5 and coordlist==[]): | |
247 | 599 urlresponse=urlFunctions.zUrlopenParseString(self,urlFunctions.zUrlopenRead(self,"http://chgis.hmdc.harvard.edu/xml/id/"+gis_id)) |
600 baseDocElement= urlFunctions.zUrlopenDocumentElement(self,urlresponse) | |
601 childnodes=urlFunctions.zUrlopenChildNodes(self,baseDocElement) | |
602 itemnodes=urlFunctions.zUrlopenGetElementsByTagName(self,baseDocElement,'item') | |
603 itemspatialnodes=None | |
604 | |
605 for i in range(0,urlFunctions.zUrlopenLength(self,itemnodes)): | |
606 itemnode=urlFunctions.zUrlopenGetItem(self,itemnodes,i) | |
607 itemspatialnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemnode,'spatial') | |
608 if itemspatialnodes is not None: | |
609 for j in range(0,urlFunctions.zUrlopenLength(self,itemspatialnodes)): | |
610 coord=[] | |
611 itemspatialnode= urlFunctions.zUrlopenGetItem(self,itemspatialnodes,j) | |
612 itemspatiallatnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_latitude') | |
613 for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallatnodes)): | |
614 itemspatiallatnode= urlFunctions.zUrlopenGetItem(self,itemspatiallatnodes,k) | |
615 coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallatnode)) | |
616 itemspatiallngnodes=urlFunctions.zUrlopenGetElementsByTagName(self,itemspatialnode,'degrees_longitude') | |
617 for k in range(0,urlFunctions.zUrlopenLength(self,itemspatiallngnodes)): | |
618 itemspatiallngnode= urlFunctions.zUrlopenGetItem(self,itemspatiallngnodes,k) | |
619 coord.append(urlFunctions.zUrlopenGetTextData(self,itemspatiallngnode)) | |
620 coordlist.append(coord) | |
621 gis_id= "_"+gis_id | |
43 | 622 return coordlist |
623 | |
624 # End for GoogleMaps creation | |
625 | |
626 def RESTwrite2File(self,datadir, name,text): | |
627 logging.debug("RESTwrite2File datadir=%s name=%s"%(datadir,name)) | |
628 try: | |
629 import cStringIO as StringIO | |
630 except: | |
631 import StringIO | |
632 | |
633 # make filehandle from string | |
634 textfile = StringIO.StringIO(text) | |
635 fileid=name | |
636 if fileid in datadir.objectIds(): | |
637 datadir.manage_delObjects(fileid) | |
638 fileInZope=datadir.manage_addFile(id=fileid,file=textfile) | |
639 return "Write successful" | |
640 | |
641 def manage_editRestDbGisApi(self, title=None, connection_id=None, | |
642 REQUEST=None): | |
643 """Change the object""" | |
644 if title is not None: | |
645 self.title = title | |
646 | |
647 if connection_id is not None: | |
648 self.connection_id = connection_id | |
649 | |
650 #checkPermission=getSecurityManager().checkPermission | |
651 REQUEST.RESPONSE.redirect('manage_main') | |
652 | |
653 | |
654 manage_addRestDbGisApiForm=PageTemplateFile('zpt/addRestDbGisApi',globals()) | |
655 | |
656 def manage_addRestDbGisApi(self, id, title='', label='', description='', | |
657 createPublic=0, | |
658 createUserF=0, | |
659 REQUEST=None): | |
660 """Add a new object with id *id*.""" | |
661 | |
662 ob=RestDbGisApi(str(id),title) | |
663 self._setObject(id, ob) | |
664 | |
665 #checkPermission=getSecurityManager().checkPermission | |
666 REQUEST.RESPONSE.redirect('manage_main') | |
667 | |
247 | 668 |
669 | |
670 |