#!/usr/bin/env python3 # -*- coding: utf-8 -*- u""" Created on Mon Mar 27 11:45:19 2017 @author: alexandros """ from __future__ import division from __future__ import absolute_import from itertools import imap from itertools import izip u""" Throughout this code first there is x coordinate and then y. """ import psycopg2 import random as rnd import numpy as np import matplotlib.pyplot as plt from math import radians, cos, sin, asin, sqrt from datetime import datetime def haversine(lon1, lat1, lon2, lat2): u""" Calculate the great circle distance between two points on the earth (specified in decimal degrees) """ # convert decimal degrees to radians lon1, lat1, lon2, lat2 = imap(radians, [lon1, lat1, lon2, lat2]) # haversine formula dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) km = 6367 * c return km def getDataFromDb(limit=0): try: connect_str = u"dbname='pgsnapshot' user='postgres' host='localhost' " + \ u"password=''" # use our connection values to establish a connection conn = psycopg2.connect(connect_str) # create a psycopg2 cursor that can execute queries cursor = conn.cursor() # run a SELECT statement - no data in there, but we can try it statement = u"""SELECT ST_Y(geom), ST_X(geom) FROM nodes """ if limit>0: statement += u"""ORDER BY RANDOM() LIMIT """+unicode(limit) # cursor.execute("""SELECT ST_X(geom), ST_Y(geom) FROM nodes LIMIT 10""") cursor.execute(statement) rows = cursor.fetchall() u""" if limit>0: print(rows) else: print(len(rows)) """ return rows except Exception, e: print u"Uh oh, can't connect. Invalid dbname, user or password?" print e def createUsers(data, num_users): rnd1 = rnd rnd1.seed(datetime.now()) users=[] users_inverted_index={} for _ in xrange(0,num_users): index = rnd1.randrange(len(data)) #print(index, end=' ') users.append(data[index]) users_inverted_index[data[index]]=index #print() return np.array(users), users_inverted_index def calcNearest(p, index, num): nearest=list(index.nearest((p[0], p[1], p[0], p[1]), num, objects=u"raw")) return nearest def calculateAllNearest(p_list, index, num): allpoints=[] for p in p_list: allpoints.append(list(calcNearest(p, index, num))) return allpoints def getValidIPOI(user, poisList): index=0 # print(user, poisList[index]) # _ = input("getValidIPOI 1:") while tuple(user)==poisList[index]: index +=1 # print(user, poisList[index]) # _ = input("getValidIPOI 2:") # print(user, poisList[index]) # _ = input("getValidIPOI 3:") return poisList[index] # Calculate IPOIs list def calculateIPOis(users, index): cand_iPOIS = calculateAllNearest(users, index, 50) iPois = [] # print(users, cand_iPOIS) for user, sublist in enumerate(cand_iPOIS): iPois.append(getValidIPOI(users[user],sublist)) return np.array(iPois) #def populateIndex(data, index): # for pointid, point in enumerate(data): # index.insert(pointid, (point[0], point[1], point[0], point[1])) # return(index) # Fill R*-tree def generator_function(data): for i, obj in enumerate(data): yield (i, (obj[0], obj[1], obj[0], obj[1]), obj) # Calculate sides of the square and distances #def calculateIpoiIDDistances(users, poiids, data): # distances = [geod.Inverse(users[i][0], users[i][1], # data[poiids[i]][0], data[poiids[i]][1])['s12'] # for i,_ in enumerate(users)] # return distances def calculateIpoiDistances(users, pois, data): distances = [np.linalg.norm(users[i]-pois[i]) for i,_ in enumerate(users)] return distances #def new_point(y0, x0, d, theta): # theta_rad = pi/2 - radians(theta) # return y0 + d*sin(theta_rad), x0 + d*cos(theta_rad) def new_point(y0, x0, d, angle): x = d * cos(radians(angle)); y = d * sin(radians(angle)); return (y0+y), (x0+x) # >>> left, bottom, right, top = (0.0, 0.0, 1.0, 1.0) # Azimuths are from north clockwise. # So, bottom left is SW with azimuth = 225 degrees # and, top right is NE with azimuth = 45 degrees def calcBoundingSquare(side, ipoi): return new_point(ipoi[0], ipoi[1], side, 225)+new_point(ipoi[0], ipoi[1], side, 45) def calcBoundingSquares(sides, ipois): u""" Calculates the bounding square given a side size and ipois. """ aa = [ calcBoundingSquare(sides[i],ipois[i]) for i,s in enumerate(sides)] # aa = [new_point(ipois[i][0], ipois[i][1], sides[i], 225)+ # new_point(ipois[i][0], ipois[i][1], sides[i], 45) # for i,_ in enumerate(sides)] # for a in aa: # print(a) return(aa) #return tuple(new_point(ipois[0][0], ipois[0][1], sides[0], 225)+ # new_point(ipois[0][0], ipois[0][1], sides[0], 45)) def rangeQuery(queryRectangle, index): return(list(index.intersection(queryRectangle, objects=u'raw'))) def rangeQueryCount(queryRectangle, index): return(index.count(queryRectangle)) def allRangeQueries(queryRectangles, index): return([rangeQuery(qr, index) for qr in queryRectangles]) def kAnonymousAllRangeQueries(queryRectangles, index, sides, ipois, k): for i, _ in enumerate(queryRectangles): num_of_elements = rangeQueryCount(queryRectangles[i], index) #print("For poi no:"+str(i)+" elements_found:"+str(num_of_elements)) while num_of_elements < k: sides[i] = sqrt(2)*sides[i] # Double square's area queryRectangles[i] = calcBoundingSquare(sides[i],ipois[i]) #print(str(i)+" Rect:"+str(queryRectangles[i])+" Side:"+str(sides[i])+" Ipoi:"+str(ipois[i])) #input("press enter:") num_of_elements = rangeQueryCount(queryRectangles[i], index) #print("For poi no:"+str(i)+" elements_found:"+str(num_of_elements)) return([rangeQuery(qr, index) for qr in queryRectangles]) def selectSPOI(cand_SPOIs): rnd2 = rnd rnd2.seed(datetime.now()) spois = [] for cspoi in cand_SPOIs: selection = rnd2.randrange(len(cspoi)) #print("=======>"+str(selection)+" "+str(len(cspoi))) spois.append( cspoi[selection] ) return spois def findAllNearestNeighbors(points, K, index): nearest_neigbors=[ list(index.nearest(( p[0], p[1], p[0], p[1]), K)) for p in points] return nearest_neigbors def buildSPOIsInvertedIndex(spois): u""" SPOIs inverted index """ invSpoisIndex = {} for ind,spoi in enumerate(spois): invSpoisIndex[ind]=spoi return(invSpoisIndex) def compareWithGroundTruth(method, ground, users, K): u""" Ground truth number of results: users*K Precision = count/K*users Recall = count/sum """ count=0 for index, m in enumerate(method): for m_elem in m: if m_elem in ground[index]: count += 1 print "===" print len(method) print len(ground) ground_truth = sum([len(g) for g in ground]) total_retrieved = sum([len(tr) for tr in method]) #print count, total_retrieved, ground_truth, K n_count = min(count,K) n_total_retrieved = min(total_retrieved,K) n_ground_truth = min(ground_truth,K) return n_count, count, n_ground_truth, ground_truth, n_total_retrieved, total_retrieved, K*users, n_count/n_total_retrieved, n_count/K