diff --git a/Open_Folder.ico b/Open_Folder.ico new file mode 100644 index 0000000..b750b38 Binary files /dev/null and b/Open_Folder.ico differ diff --git a/files/__init__.py b/files/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/files/__init__.py @@ -0,0 +1 @@ + diff --git a/files/analytics.py b/files/analytics.py new file mode 100644 index 0000000..e99d79e --- /dev/null +++ b/files/analytics.py @@ -0,0 +1,118 @@ +import math +import random +from .utils import euclidean_distance +from .utils import generate_random + + + +def find_largest_city(gj): + """ + Iterate through a geojson feature collection and + find the largest city. Assume that the key + to access the maximum population is 'pop_max'. + Parameters + ---------- + gj : dict + A GeoJSON file read in as a Python dictionary + Returns + ------- + city : str + The largest city + population : int + The population of the largest city + """ + + temp = 0 + city = "" + max_population = 0 + for i in gj['features']: + if i['properties']['pop_max'] > temp: + temp = i['properties']['pop_max'] + city = i['properties']['name'] + max_population = temp + + return city, max_population + + +def average_nearest_neighbor_distance(points, mark=None): + """ + Given a set of points, compute the average nearest neighbor. + Parameters + ---------- + points : list + A list of points in the form (x,y) + Returns + ------- + mean_d : float + Average nearest neighbor distance + References + ---------- + Clark and Evan (1954 Distance to Nearest Neighbor as a + Measure of Spatial Relationships in Populations. Ecology. 35(4) + p. 445-453. + """ + + sum_nn_dis = 0 + + for point_1 in points: + first = True + for point_2 in points: + if point_1 == point_2: + continue + else: + distance = euclidean_distance(point_1, point_2) + if first: + nn_dis = distance + first = False + elif distance < nn_dis: + nn_dis = distance + + sum_nn_dis += nn_dis + mean_distance = sum_nn_dis / len(points) + return mean_distance + +def avg_nn_marks(points, marks=None): + + if marks is not None: + marked_points = list() + for point in points: + if point.mark is marks: + marked_points.append(point) + else: + continue + return average_nearest_neighbor_distance(marked_points) + else: + combined_points = list((point) for point in points) + + return average_nearest_neighbor_distance(combined_points) + + + + +def permutations(p = 99, marks=None): + n = 100 + permutations = [] + for i in range(p): + points_list = generate_random(n) + permutations.append(average_nearest_neighbor_distance(utils.generate_random(n), marks)) + + return permutations + + +def critical_points(permutations): + """ + Lowest distance and greatest distance of points. + """ + + lower = min(permutations) + upper = max(permutations) + return lower, upper + + +def significant_distance(lower, upper, observed): + if (lower > observed) or (upper < observed): + result = True + else: + result = False + + return result diff --git a/files/exit.png b/files/exit.png new file mode 100644 index 0000000..6d40c5b Binary files /dev/null and b/files/exit.png differ diff --git a/files/io_geojson.py b/files/io_geojson.py new file mode 100644 index 0000000..279ed3a --- /dev/null +++ b/files/io_geojson.py @@ -0,0 +1,26 @@ +import json + +def read_geojson(input_file): + """ + Read a geojson file + Parameters + ---------- + input_file : str + The PATH to the data to be read + Returns + ------- + gj : dict + An in memory version of the geojson + """ + # Please use the python json module (imported above) + # to solve this one. + with open ('data/us_cities.geojson', 'r') as f: + gj = json.load(f) + + return gj + +def read_twitter(input_file): + + with open('F:/GitHub GIS 321/assignment_10/tweets.json', 'r') as fp: + twitter_gj = json.load(fp) + return twitter_gj diff --git a/files/point.py b/files/point.py new file mode 100644 index 0000000..27d5550 --- /dev/null +++ b/files/point.py @@ -0,0 +1,34 @@ +from . import utils + + + +class Point(object): + + def __init__(self, x, y, mark={}): + self.x = x + self.y = y + self.mark = mark + + def __eq__(self, other): + return self.x == other.x and self.y == other.y + + def __add__(self, other): + return Point(self.x + other.x, self.y + other.y) + + def __ne__(self, other): + return self.x != other.x or self.y != other.y + + def __str__(self): + return ("({0}, {1}").format(self.x, self.y) + + def array(self): + return [self.x, self.y] + + def point_check_coincident(self, test): + return utils.check_coincident((self.x, self.y), test) + + def point_shift_point(self, x_shift, y_shift): + test = utils.shift_point((self.x, self.y), x_shift, y_shift) + self.x = utils.getx(test) + self.y = utils.gety(test) + diff --git a/files/point_pattern.py b/files/point_pattern.py new file mode 100644 index 0000000..006c62f --- /dev/null +++ b/files/point_pattern.py @@ -0,0 +1,160 @@ +from . import point +from . import analytics +from .utils import euclidean_distance +import random +import numpy as np +import scipy.spatial as ss + + +class PointPattern(object): + def __init__(self): + self.points = [] + + def add_point(self, point): + self.points.append(point) + + def remove_point(self, index): + try: + del(self.points[index]) + except: + pass + + def average_nearest_neighbor_distance(self, mark=None, points_list=None): + + mean_d = 0 + if points_list == None: + temp_points = self.points + else: + temp_points = points_list + + if mark != None: + temp_points = [point for point in self.points if point.mark == mark] + + list = len(temp_points) + + nn_dis = [] + for i in range(list): + distance = [] + + for j in range(list): + if i == j: + continue + else: + distance.append(self.euclidian_distance((temp_points[i].x, temp_points[i].y),(temp_points[j].x, temp_points[j].y))) + nn_dis.append(min(distance)) + + mean_d = (sum(nn_dis)/len(nn_dis)) + return mean_d + + def average_nearest_neighbor_distance_kdtree(self): + point_list = [] + points = self.points + for point in points: + point_list.append(point.array()) + stack = np.vstack(point_list) + + nn_dis = [] + kdtree = ss.KDTree(stack) + for p in stack: + nearest_neighbor_distance, nearest_neighbor = kdtree.query(p, k=2) + nn_dis.append(nearest_neighbor_distance[1]) + nn_distances = np.array(nn_dis) + + return(np.mean(nn_distances)) + + + def average_nearest_neighbor_distance_numpy(self): + point_list = [] + for point in self.points: + point_list.append(point.array()) + ndarray = np.array(point_list) + nearest_neighbor = [] + temp_nearest_neighbor = None + + for i, point_1 in enumerate(ndarray): + for j, point_2 in enumerate(ndarray): + if i == j: + continue + distance = ss.distance.euclidean(point_1, point_2) + + if temp_nearest_neighbor is None: + temp_nearest_neighbor = distance + elif temp_nearest_neighbor > distance: + temp_nearest_neighbor = distance + + nearest_neighbor.append(temp_nearest_neighbor) + temp_nearest_neighbor = None + + + + def number_of_coincident(self): + + nc = 0 + indexed = [] + + for i in range(len(self.points)): + for j in range(len(self.points)): + if j in indexed: + continue + if i == j: + continue + if self.points[i] == self.points[j]: + nc += 1 + indexed.append(j) + return nc + + def list_marks(self): + + marks = [] + for point in self.points: + if point.mark is not None and point.mark not in marks: + marks.append(point.mark) + return marks + + def subsets_with_mark(self, mark): + + marked_points = [] + for points in self.points: + if points.mark == mark: + marked_points.append(points) + return marked_points + + def generate_random_points(self, n=None): + + if n is None: + n = len(self.points) + random_points = [] + self.marks = ['Blue', 'Rare', 'Medium-Rare', 'Medium', 'Medium-Well', 'Well-Done'] + + for i in range(n): + random_points.append(Point(round(random.random(), 2), round(random.random(), 2), random.choice(self.marks))) + return random_points + + def generate_realizations(self, k): + + return analytics.permutations(k) + + def get_critical_points(self): + + return analytics.compute_critical(self.generate_realizations(100)) + + def compute_g(self, nsteps): + + disc_step = np.linspace(0, 1, nsteps) + sum = 0 + for i in range(nsteps): + i_step = disc_step[i] + min_dist = None + for j in range(len(disc_step)): + if i == j: + continue + if min_dist is None: + min_dist = abs(disc_step[j] - i_step) + else: + if abs(disc_step[j] - i_step) < min_dist: + min_dist = abs(disc_step[j] - i_step) + else: + min_dist = min_dist + sum += min_dist + + return sum / nsteps diff --git a/files/point_pattern_1.ipynb b/files/point_pattern_1.ipynb new file mode 100644 index 0000000..fe1c984 --- /dev/null +++ b/files/point_pattern_1.ipynb @@ -0,0 +1,95 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pysal as ps \n", + "from . import point_pattern\n", + "from . import analytics\n", + "from .point import Point\n", + "import numpy as np\n", + "\n", + "\n", + "shapefile = ps.open(ps.examples.get_path('new_haven_merged.shp'))\n", + "dbf = ps.open(ps.examples.get_path('new_haven_merged.dbf'))\n", + "\n", + "points = []\n", + "i = 0\n", + "for geometry, attributes in zip(shapefile, dbf):\n", + " i += 1\n", + " points.append(Point, geometry[0], geometry[1], attributes[0])\n", + " print(geometry, attributes)\n", + " \n", + "# Run a few tests to explore the dataset\n", + "nn = point_pattern.average_nearest_neighbor_distance_kdtree()\n", + "print('This dataset has a nearest neighbor distance of {}'.format(nn))\n", + "# Use your monte carlo simulation code to see if the result is statistically significant\n", + "lower, upper = analytics.critical_points(analytics.permutations())\n", + "if analytics.significant_distance(lower, upper, nn):\n", + " print('The mark is significant.')\n", + "else: \n", + " print('The mark is not significant.')\n", + " \n", + "%matplotlib inline\n", + "import matplotlib\n", + "import matplotlib.pyplot as plt\n", + "from point_pattern import PointPattern\n", + "\n", + "import pysal as ps\n", + "\n", + "shapefile = ps.open(ps.examples.get_path('new_haven_merged.shp'))\n", + "dbf = ps.open(ps.examples.get_path('new_haven_merged.dbf'))\n", + "\n", + "def create_plot(x, y, **kwargs):\n", + " fig, axes = plt.subplots()\n", + " \n", + " axes.plot(x, y, **kwargs)\n", + " axes.set_xlabel('x')\n", + " axes.set_ylabel('y')\n", + " axes.set_title('Point Pattern')\n", + " \n", + "\n", + "x = []\n", + "y = []\n", + "\n", + "critical_1, critical_2 = point_pattern.get_critical_points()\n", + "\n", + "for point in point_pattern.points:\n", + " x.append(point.x)\n", + " y.append(point.y)\n", + " \n", + "create_plot(np.array(x), np.array(y), color='red', marker='o', markersize='10')\n", + "\n", + "fig, ax = plt.subplots()\n", + "\n", + "x2 = np.array([10, 50, 100, 1000])\n", + "y2 = np.array([point_pattern.compute_g(10),\n", + " point_pattern.compute_g(50),\n", + " point_pattern.compute_g(100),\n", + " point_pattern.compute_g(1000)])\n", + "ax.plot(x2, y2, label='Compute G', color='red')\n", + "ax.plot((np.array[0], np.array[3]), (critical_1, critical_1), label='Lower', color='green')\n", + "ax.plot((np.array[0], np.array[3]), (critical_2, critical_2), label='Upper', color='green')\n", + "ax.legend(loc=0)\n", + "ax.set_xlabel('x')\n", + "axes.set_ylabel('y')\n", + "axes.set_title('Compute G');" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/files/tests/__init__.py b/files/tests/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/files/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/files/tests/point_pattern_test.py b/files/tests/point_pattern_test.py new file mode 100644 index 0000000..b836623 --- /dev/null +++ b/files/tests/point_pattern_test.py @@ -0,0 +1,24 @@ +import unittest +from ..point_pattern import PointPattern +from ..point import Point + + +class TestPointPattern(unittest.TestCase): + def setUp(self): + self.point_pattern = PointPattern() + self.point_pattern.add_point(point.Point(1,1, 'Blue')) + self.point_pattern.add_point(point.Point(2,2, 'Rare')) + self.point_pattern.add_point(point.Point(3,3, 'Medium-Rare')) + self.point_pattern.add_point(point.Point(4,4, 'Medium')) + self.point_pattern.add_point(point.Point(5,5, 'Medium-Well')) + self.point_pattern.add_point(point.Point(6,6, 'Well-Done')) + self.point_pattern.add_point(point.Point(1,1,)) + + def test_coincident(self): + self.assertEqual(self.point_pattern.number_of_coincident(), 3) + + def test_list_marks(self): + self.assertEqual(self.point_pattern.list_marks(), ['Blue', 'Rare', 'Medium-Rare', 'Medium', 'Medium-Well', 'Well-Done']) + + def test_subsets_with_mark(self): + self.assertEqual(len(self.point_pattern.subsets_with_mark())) \ No newline at end of file diff --git a/files/tests/point_test.py b/files/tests/point_test.py new file mode 100644 index 0000000..41d1551 --- /dev/null +++ b/files/tests/point_test.py @@ -0,0 +1,53 @@ +import unittest +import random + +from .. import point + + +class TestPointClass(unittest.TestCase): + def setUp(self): + pass + + def set_attributes(self): + x = 3 + y = 9 + test = point.Point(x, y) + self.assertEqual(test.x, x) + self.assertEqual(test.y, y) + + def test_coincident(self): + Point1 = point.Point(0, 10) + Point2 = point.Point(0, 10) + Point3 = point.Point(0, 9) + Point4 = point.Point(1, 10) + + self.assertTrue(Point1.point_check_coincident(Point2)) + self.assertFalse(Point1.point_check_coincident(Point3)) + self.assertFalse(Point1.point_check_coinsident(Point4)) + + def test_shift(self): + test = point.Point(0, 10) + test.point_shift_point(5, 5) + + self.assertEqual(test.x, 5) + self.assertEqual(test.y, 15) + + def test_marked_points(self): + random.seed(12345) + marks = ['Blue', 'Rare', 'Medium-Rare', 'Medium', 'Medium-Well', 'Well-Done'] + points = [] + i = 0 + for i in range(20): + points.append(point.Point(0, 0, random.choice(marks))) + + count = {} + for i in range(len(points)): + if points[i].mark in count: + count[points[i].mark] = count[points[i].mark] + 1 + else: + count[points[i].mark] = 1 + + print (count) + + self.assertEqual(count['Rare'], 4) + self.assertEqual(count['Medium-Well'], 4) diff --git a/files/twitter.py b/files/twitter.py new file mode 100644 index 0000000..65e01f8 --- /dev/null +++ b/files/twitter.py @@ -0,0 +1,18 @@ +from . import utils +import random + +class Tweet(object): + def __init__(self, tweet_dict): + + self.tweet = tweet_dict['text'] + self.lat = tweet_dict['place']['bounding_box']['coordinates'][0][1] + self.long = tweet_dict['place']['bounding_box']['coordinates'][0][0] + self.follower_count = tweet_dict['user']['followers_count'] + self.screen_name = tweet_dict['user']['screen_name'] + self.freinds = tweet_dict['user']['friends_count'] + + def generate_bounds(self): + + lat = random.uniform((min(self.lat)), (max(self.lat))) + long = random.uniform((min(self.long)), (max(self.long))) + return lat,long diff --git a/files/utils.py b/files/utils.py new file mode 100644 index 0000000..7550538 --- /dev/null +++ b/files/utils.py @@ -0,0 +1,158 @@ +import math +import random + +def generate_random_marks(n, marks=[]): + + points = random.Random() + random_marks = [] + + if marks is None: + for i in range(n): + random_marks.append(Point(points.randint(0, 100), points.randint(0,100))) + else: + for i in range(n): + random_marks.append(Point(points.randint(0, 100), points.randint(0,100), points.choice(marks))) + + return random_marks + + +def generate_random(n): + """ + Generates n random points within the domain of 0 - 1. + :param n: + :return: + """ + points = random.Random() + points_list = [] + for i in range(n): + points_list.append((round(points.uniform(0, 1), 2), round(points.uniform(0, 1), 2))) + return (points_list) + + + +def shift_point(point, x_shift, y_shift): + """ + Shift a point by some amount in the x and y directions + Parameters + ---------- + point : tuple + in the form (x,y) + x_shift : int or float + distance to shift in the x direction + y_shift : int or float + distance to shift in the y direction + Returns + ------- + new_x : int or float + shited x coordinate + new_y : int or float + shifted y coordinate + Note that the new_x new_y elements are returned as a tuple + Example + ------- + >>> point = (0,0) + >>> shift_point(point, 1, 2) + (1,2) + """ + x = getx(point) + y = gety(point) + + x += x_shift + y += y_shift + + return x, y + +def check_coincident(a, b): + """ + Check whether two points are coincident + Parameters + ---------- + a : tuple + A point in the form (x,y) + b : tuple + A point in the form (x,y) + Returns + ------- + equal : bool + Whether the points are equal + """ + return a == b + +def check_in(point, point_list): + """ + Check whether point is in the point list + Parameters + ---------- + point : tuple + In the form (x,y) + point_list : list + in the form [point, point_1, point_2, ..., point_n] + """ + return point in point_list + +def manhattan_distance(a, b): + """ + Compute the Manhattan distance between two points + Parameters + ---------- + a : tuple + A point in the form (x,y) + b : tuple + A point in the form (x,y) + Returns + ------- + distance : float + The Manhattan distance between the two points + """ + distance = abs(a.x - b.x) + abs(a.y - b.y) + return distance + +def euclidean_distance(a, b): + """ + Compute the Euclidean distance between two points + Parameters + ---------- + a : tuple + A point in the form (x,y) + b : tuple + A point in the form (x,y) + Returns + ------- + distance : float + The Euclidean distance between the two points + """ + distance = math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) + return distance + +def getx(point): + """ + A simple method to return the x coordinate of + an tuple in the form(x,y). We will look at + sequences in a coming lesson. + Parameters + ---------- + point : tuple + in the form (x,y) + Returns + ------- + : int or float + x coordinate + """ + return point[0] + + +def gety(point): + """ + A simple method to return the x coordinate of + an tuple in the form(x,y). We will look at + sequences in a coming lesson. + Parameters + ---------- + point : tuple + in the form (x,y) + Returns + ------- + : int or float + y coordinate + """ + return point[1] diff --git a/files/view.py b/files/view.py new file mode 100644 index 0000000..95141d0 --- /dev/null +++ b/files/view.py @@ -0,0 +1,72 @@ +import sys +import os +from PyQt4 import QtGui +from PyQt4 import QtWebKit +from PyQt4 import QtCore +from . import io_geojson +from . import twitter +import folium +import random + +map_osm = folium.Map(location=[33.4484, -112.0178]) + +class View(QtGui.QMainWindow): + + def __init__(self): + super(View, self).__init__() + self.map = None + self.web_view = None + map_osm.save('/tmp/map.html') + self.init_ui + + def init_ui(self): + #central widget + self.web_view = QtWebkit.QWebView() + self.map = folium.Map(location=[33.4484, -112.0178] + self.map.zoom_start = 10 + self.map.save(map_osm.save('/tmp/map.html')) + self.web_view.load + self.setCentralWidget(self.web_view) + + #Open actions + open_action = QtGui.QAction(QtGui.QIcon('Open_Folder.ico'), 'Open', self) + open_action.setShortcut('Ctrl+O') + open_action.triggered.connect(self.open) + + #Exit actions + exit_action = QtGui.QAction(QtGui.QIcon('exit.png'), 'Exit', self) + exit_action.setShortcut('Ctrl+Q') + exit_action.triggered.connect(self.close) + + self.statusBar() + + toolbar = self.addToolBar('Exit') + toolbar.addAction(exit_action) + + self.setGeometry(300, 300, 700, 700) + self.setWindowTitle('Title Window') + self.show() + +def open_tweets(self): + file_name = QfileDialog.getOpenFileName(self, caption='Open File', directory='', filter='*.json') + if not file_name: + return + + tweets = [] + tmp_tweets = io_geojson.read_twitter(file_name): + for i in tmp_tweets: + tweets.append( + +def show_tweets(self, tweets): + + for tweet in tweets: + lat = + +def main(): + app = QtGui.QApplication(sys.argv) + view = View() + sys.exit(app.exec_()) + + +if __name__ == '__main__': + main()