Example #1
0
def getConversionInfo (request, **kwargs):
	"""
	Returns a json with the conversion table for a given map and the list of fields for that map
	:param request:
	:param kwargs:
	:return:
	"""

	print "Retrieving conversion table..."

	proxy_id = kwargs["proxy_id"]
	meta_id = kwargs["meta_id"]
	shape_id = kwargs["shape_id"]

	# loading pre-existing conversion; should include modelid and actual conversion structure as fields with corresponding field and value conversion
	try:
		mapconv = proxy_core.getConversionTable(kwargs["proxy_id"], kwargs["meta_id"], kwargs["shape_id"])
		print "Received conversion table: %s" % mapconv
		if mapconv is None:
			print "No conversion table for this map"
			mapconv = {}
	except Exception as ex:
		print "Error when loading shape conversion table: %s" % ex
		mapconv = {}

	# very simple check to be sure the conversion table has the correct structure, i.e. is in the most recent format
	if mapconv != {} and not (mapconv.has_key('modelid') and mapconv.has_key('fields')):
		print "Conversion table is in the wrong format"
		mapconv = {}

	# creating the full list of fields for this map
	sourcefields = []
	if learnProxyType(getProxyManifest(proxy_id)) != 'query':

		mapdata = proxy_core.convertShapeFileToJson(proxy_id, meta_id, shape_id, False)
		for feature in mapdata ['features']:
			for property in feature['properties'].keys():
				if property not in sourcefields:
					sourcefields.append(property)
	else:
		dbstructure = proxy_query.getPGStructure(proxy_id, meta_id, shape_id)
		for field in dbstructure:
			sourcefields.append(field[0])

	args = {
		"mapfields" : sourcefields,
		"conversion" : mapconv,
	}

	print "Retrieved conversion structure:",args

	return HttpResponse(json.dumps(args), mimetype="application/json")
Example #2
0
def getReverseConversion (proxy_id, meta_id, map_id):
	"""
	Gets the fields conversion table, but with the values (our model) in place of the keys (external model)
	:param proxy_id:
	:param meta_id:
	:param map_id:
	:return:
	"""

	basetable = (proxy_core.getConversionTable (proxy_id, meta_id, map_id))
	print "Found table as follows"
	print basetable


	basetable = basetable['fields']
	reversetable = {}

	for key in basetable.keys():

		reversetable[basetable[key]['to']] = key

	print "Returning reverse table"
	return reversetable
Example #3
0
def component_shapefile_table (request, **kwargs):
	"""
	Returns the conversion table for  specific shapefile according to its structure, available model etc.
	:param request:
	:param kwargs:
	:return:
	"""
	shapedata = None
	shapetable = None

	proxy_id = kwargs["proxy_id"]
	meta_id = kwargs["meta_id"]
	shape_id = kwargs["shape_id"]

	shapedata = proxy_core.convertShapeFileToJson(proxy_id, meta_id, shape_id, False)

	try:
		shapetable = proxy_core.getConversionTable(kwargs["proxy_id"], kwargs["meta_id"], kwargs["shape_id"])
	except Exception as ex:
		print "Error when loading shape conversion table: %s" % ex

	if shapetable is None:
		shapetable = {}


	try:
		jsonresponse = urllib2.urlopen(proxyconf.URL_CONVERSIONS)
		convtable = json.load(jsonresponse)
		print "Received conversion table from server: %s" % convtable

	except Exception as ex:
		if isinstance(ex, urllib2.HTTPError):
			errormess = ex.code
		elif isinstance(ex, urllib2.URLError):
			errormess = ex.reason
		else:
			errormess = ex.message
		print "Error when requesting conversion table from %s: %s" % (proxyconf.URL_CONVERSIONS, errormess)

		#todo: replace with handling at JS level
		raise

	conversionto = {}
	for objecttype in convtable.keys():
		conversionto[objecttype] = []
		for property in convtable[objecttype].keys():
			conversionto[objecttype].append(property)

	conversionfrom = []
	for feature in shapedata['features']:

		for ckey in feature['properties'].keys():
			if ckey not in conversionfrom:
				conversionfrom.append(ckey)


	args = {
		"shapedata" : conversionfrom,
		"conversion" : conversionto,
		"shapetable": shapetable
	}

	print args

	return HttpResponse(json.dumps(args), mimetype="application/json")
Example #4
0
def makeSelectFromJson (proxy_id, meta_id, map_id, jsonmessage):
	"""
	Takes a JSON message and builds a PGSQL query string from it; this function is expected to be called via makeQueryOnMeta
	:param jsonquery:
	:return: array of features, NOT a featurecollection object
	"""


	DEC2FLOAT = psycopg2.extensions.new_type(
		psycopg2._psycopg.DECIMAL.values, # oids for the decimal type
		'DEC2FLOAT', # the new typecaster name
		psycopg2.extensions.FLOAT) # the typecaster creating floats

	# register the typecaster globally
	psycopg2.extensions.register_type(DEC2FLOAT)


	proj_WGS84 = 4326


	# if the message is valid, we assemble the query

	# we do a quick check to ensure the query can be satisfied by the data provided with this table
	# i.e. if the columns chosen are supported in our translation

	columns = []
	for querybit in jsonmessage['query']['inventory']:
		columns.append(querybit['column'])

	revtable = getReverseConversion(proxy_id, meta_id, map_id)


	print "Retrieved reverse table for makeSelectFromJson"
	print revtable

	# if a column is missing, we return an empty list without checking the DB
	if not all (map(revtable.has_key, columns)):
		return []


	convtable = {}
	for key in revtable.keys():
		convtable[revtable[key]] = key

	# now we can proceed with the actual query process

	fp_conndata = open(os.path.join(proxyconf.baseproxypath, proxy_id, proxyconf.path_mirror, meta_id, map_id))
	conn_data = json.load(fp_conndata)
	fp_conndata.close()
	connstring = makeConnectString(conn_data['connection'])

	try:
		conn = psycopg2.connect(connstring)
		cur = conn.cursor()
		print "Connection established"
	except Exception as ex:
		raise QueryFailedException ("Connessione fallita: %s" % ex)

	#NOTE: bt as BETWEEN removed for now since it would require a specific syntax
	operators = {
		"gt": "> %s",
		"ge": ">= %s",
		"lt": "< %s",
		"le": "<= %s",
		"eq": "= %s",
		"in": "<@ ARRAY [%s]"
	}

	wherestring = ""
	sep = ""
	for querybit in jsonmessage['query']['inventory']:

		newbit = sep + " %s " + operators[querybit['operator']]
		wherestring += newbit % (revtable[querybit['column']], querybit['params'])

		sep = " AND "

	if len(jsonmessage['query']['BB']) > 0:

		#TODO: verify if we prefer to also have items that CROSS the bounding box or if we only what what is COMPLETELY inside (current)

		bb = jsonmessage['query']['BB']

		newbit = sep + " transform("+revtable['geometry'] +", "+str(proj_WGS84)+") @ ST_SetSRID(ST_MakeBox2D(ST_Point(%s, %s), ST_Point(%s , %s)), "+str(proj_WGS84)+")"
		wherestring += cur.mogrify(newbit, (bb[0], bb[1], bb[2], bb[3]))


	print "QUERY CONDITIONS: *************\n%s\n******************************" % wherestring

	view_id = conn_data['query']['view']
	schema_id = conn_data['query']['schema']
	if schema_id != "" and schema_id is not None:
		schema_id += "."


	fields = []
	selectcols = ""
	sep = ""
	for colname in convtable:

		alias = convtable[colname]
		fields.append(alias)
		if convtable[colname] == "geometry":
			colname = "ST_AsGeoJSON(transform("+colname+", 4326))"

		selectcols += sep + colname + " AS " + alias
		sep = ", "

	if selectcols == "":
		selectcols = " * "

	if wherestring != "":
		wherestring = " WHERE "+wherestring

	limitstring = ""
	offsetstring = ""
	if jsonmessage['maxitems'] != 0:
		limitstring = " LIMIT %s" % jsonmessage['maxitems']
	if jsonmessage['offset'] != 0:
		offsetstring = " OFFSET %s" % jsonmessage['offset']


	querystring = 'SELECT '+selectcols+' FROM '+schema_id+view_id + wherestring + limitstring + offsetstring + ";"

	print "REQUESTED SELECT: " + querystring

	cur.execute(querystring)

	results = cur.fetchall()

	cur.close()
	conn.close()

	collection = []

	#print "FIELDS: %s" % fields
	#print "RESULTS: %s" % results

	valuestable = proxy_core.getConversionTable(proxy_id, meta_id, map_id)

	print "Received (linear) conv table %s" % valuestable

	forced = valuestable['forcedfields']

	print "Set forced values, moving to value conversion"
	print "(revtable is now %s)" % revtable

	fieldvalues = {}
	for fedfield in revtable.keys():
		clientfield = revtable[fedfield]
		if len(valuestable['fields'][clientfield]['values']) > 0:
			print "Adding %s to quick conv" % clientfield
			fieldvalues[fedfield] = valuestable['fields'][clientfield]['values']

	print "Quick conv table is %s " % fieldvalues



	errors = 0
	for row in results:

		try:
			data = {}

			data['type'] = "Feature"
			data['geometry'] = json.loads(row[fields.index('geometry')])



			properties = {}

			for key in forced.keys():
				properties[key] = forced[key]['']

			for field in fields:
				if field != 'geometry':
					clientvalue = row[fields.index(field)]
					if field in fieldvalues.keys() and clientvalue in fieldvalues[field]:
						properties[field] = fieldvalues[field][clientvalue]
					else:
						properties[field] = clientvalue

			piperhash = hashlib.md5(json.dumps(data['geometry'])).hexdigest()
			data['properties'] = properties
			data['properties']['IDPiper'] = 'q'+piperhash[:11]

			try:
				for unmapped in valuestable['unmapped']:
					data['properties'][unmapped] = None
			except Exception as ex:
				#  supporting older conversion tables
				pass

			collection.append(data)

		except Exception as ex:
			errors += 1

	print "Found %s elements with %s errors" % (len(collection), errors)


	return collection