Exemple #1
1
        bool insert(T newData, float x, float y)
        {
            //std::cout << "["<< depth <<"] " << newData << " at " << x << " , " << y << " \n";
            //Make sure point is within the bounds of this node
            if (!isPointInRange(x, y, bounds))
            {
                //std::cout << "point not in bounds\n";
                //Point is not within bounds
                return false;
            }
            
            //Node isn't full yet, so add data to this node
            if (!tL && data.size() < maxCapacity)
            {
                QuadPoint<T> newPoint;
                newPoint.x = x;
                newPoint.y = y;
                newPoint.data = newData;
                data.push_back(newPoint);
                return true;
            }

            //Safety max depth
            if (depth >= MAX_TREE_DEPTH)
            {
                std::cout << "\033[31mWARNING: Max tree depth (" << MAX_TREE_DEPTH << ") reached!\033[0m\n";
                //return false;
            }
            
            //Node is full; subdivide (if not already subdivided)
            if (!tL)
            {
                subdivide();
                /*if (tL->subdivideInsert(newData, x, y)) return true;
                if (tR->subdivideInsert(newData, x, y)) return true;
                if (bL->subdivideInsert(newData, x, y)) return true;
                if (bR->subdivideInsert(newData, x, y)) return true;
                //Point wouldn't be accepted by any nodes
                //std::cout <<"point rejected; keeping\n";
                QuadPoint<T> newPoint;
                newPoint.x = x;
                newPoint.y = y;
                newPoint.data = newData;
                data.push_back(newPoint);
                return true;*/
            }

            //If already subdivided, try inserting into child nodes
            if (tL->insert(newData, x, y)) return true;
            if (tR->insert(newData, x, y)) return true;
            if (bL->insert(newData, x, y)) return true;
            if (bR->insert(newData, x, y)) return true;
            //Shouldn't ever happen
            //std::cout << "This shouldn't happen\n";
            return false;
        }
Exemple #2
0
void qtreeinit()
{
	quadtree.insert(Line2D(Point2D(100,100),Point2D(100,150)));
	quadtree.insert(Line2D(Point2D(300,100),Point2D(300,150)));
	quadtree.insert(Line2D(Point2D(450,320),Point2D(600,320)));
	quadtree.insert(Line2D(Point2D(50,360),Point2D(50,385)));
	quadtree.insert(Line2D(Point2D(150,360),Point2D(150,398)));
	quadtree.insert(Line2D(Point2D(150,405),Point2D(250,405)));
	quadtree.insert(Line2D(Point2D(150,760),Point2D(150,785)));
}
Exemple #3
0
        /*bool subdivideInsert(T newData, float x, float y)
        {
            //std::cout << this << "\n";
            //std::cout << "subdiv insert bounds: " << bounds.x << " , " << bounds.y << " w " << bounds.w << " h " << bounds.h;
            //std::cout << "; is in range: ";
            //Make sure point is within the bounds of this node
            if (!isPointInRange(x, y, bounds))
            {
                //std::cout << "rejected b/c bounds\n";
                //Point is not within bounds
                return false;
            }
            
            //Node isn't full yet, so add data to this node
            if (data.size() < maxCapacity)
            {
                QuadPoint<T> newPoint;
                newPoint.x = x;
                newPoint.y = y;
                newPoint.data = newData;
                data.push_back(newPoint);
                //std::cout << "data added\n";
                return true;
            }

            //Node is already full; don't try to add any more
            //std::cout << "rejected b/c full\n";
            return false;
        }*/
        void subdivide()
        {
            float halfWidth = bounds.w/2;
            float halfHeight = bounds.h/2;
            tL = new QuadTree<T>(maxCapacity, bounds.x, bounds.y, halfWidth, halfHeight, depth); 
            tR = new QuadTree<T>(maxCapacity, bounds.x + halfWidth, bounds.y, halfWidth, halfHeight, depth); 
            bL = new QuadTree<T>(maxCapacity, bounds.x, bounds.y + halfHeight, halfWidth, halfHeight, depth); 
            bR = new QuadTree<T>(maxCapacity, bounds.x + halfWidth, bounds.y + halfHeight, halfWidth, halfHeight, depth);

            //Redistribute points into child nodes
            while(!data.empty())
            {
                //std::cout << "REDIS\n";
                QuadPoint<T> newDataPoint = data.back();
                T newData = newDataPoint.data;
                float x = newDataPoint.x;
                float y = newDataPoint.y;
                //std::cout << "redis tl\n";
                if (tL->insert(newData, x, y))
                {
                    //std::cout << "success\n";
                    data.pop_back();
                    continue;
                }
                //std::cout << "redis tr\n";
                if (tR->insert(newData, x, y))
                {
                    //std::cout << "success\n";
                    data.pop_back();
                    continue;
                }
                //std::cout << "redis bl\n";
                if (bL->insert(newData, x, y))
                {
                    //std::cout << "success\n";
                    data.pop_back();
                    continue;
                }
                //std::cout << "redis br\n";
                if (bR->insert(newData, x, y))
                {
                    //std::cout << "success\n";
                    data.pop_back();
                    continue;
                }
                //For some reason a point will not be accepted, so
                //stop redistributing
                //std::cout << "[!] point not accepted\n";
                break;
            } 
        }
bool ZoneContainerComponent::insertActiveArea(Zone* newZone, ActiveArea* activeArea) {
	if (newZone == NULL)
		return false;

	if (!activeArea->isDeplyoed())
		activeArea->deploy();

	Zone* zone = activeArea->getZone();

	ManagedReference<SceneObject*> thisLocker = activeArea;

	Locker zoneLocker(newZone);

	if (activeArea->isInQuadTree() && newZone != zone) {
		activeArea->error("trying to insert to zone an object that is already in a different quadtree");

		activeArea->destroyObjectFromWorld(true);

		//StackTrace::printStackTrace();
	}

	activeArea->setZone(newZone);

	QuadTree* regionTree = newZone->getRegionTree();

	regionTree->insert(activeArea);

	//regionTree->inRange(activeArea, 512);

	// lets update area to the in range players
	SortedVector<QuadTreeEntry*> objects;
	float range = activeArea->getRadius() + 64;

	newZone->getInRangeObjects(activeArea->getPositionX(), activeArea->getPositionY(), range, &objects, false);

	for (int i = 0; i < objects.size(); ++i) {
		SceneObject* object = cast<SceneObject*>(objects.get(i));

		if (!object->isTangibleObject()) {
			continue;
		}

		TangibleObject* tano = cast<TangibleObject*>(object);
		Vector3 worldPos = object->getWorldPosition();

		if (!tano->hasActiveArea(activeArea) && activeArea->containsPoint(worldPos.getX(), worldPos.getY())) {
			tano->addActiveArea(activeArea);
			activeArea->enqueueEnterEvent(object);
		}
	}

	newZone->addSceneObject(activeArea);

	return true;
}
void build_tree(QuadTree& tree)
{
    high_resolution_clock::time_point t = high_resolution_clock::now();
    double _min = 0, _max = 0;
    for (int i = 0; i < num_body; ++i) {
        Body& t = bodies[i];
        _min = min(_min, min(t.x, t.y));
        _max = max(_max, max(t.x, t.y));
    }
    if (gui) {
        draw_points(0);
        draw_lines(_min, _max, _max, _max);
        draw_lines(_min, _min, _max, _min);
        draw_lines(_min, _min, _min, _max);
        draw_lines(_max, _min, _max, _max);
    }
    tree.set_region({_min, _max}, {_max, _min});
    for (int i = 0; i < num_body; ++i) tree.insert(bodies[i]);
    build_time += timeit(t);
    if (gui) draw_points(1);
}
Exemple #6
0
// Rebuilds a possibly incorrect tree (LAURENS: This function is not tested yet!)
void QuadTree::rebuildTree()
{
    for(int n = 0; n < size; n++) {
        
        // Check whether point is erroneous
        double* point = data + index[n] * QT_NO_DIMS;
        if(!boundary.containsPoint(point)) {
            
            // Remove erroneous point
            int rem_index = index[n];
            for(int m = n + 1; m < size; m++) index[m - 1] = index[m];
            index[size - 1] = -1;
            size--;
            
            // Update center-of-mass and counter in all parents
            bool done = false;
            QuadTree* node = this;
            while(!done) {
                for(int d = 0; d < QT_NO_DIMS; d++) {
                    node->center_of_mass[d] = ((double) node->cum_size * node->center_of_mass[d] - point[d]) / (double) (node->cum_size - 1);
                }
                node->cum_size--;
                if(node->getParent() == NULL) done = true;
                else node = node->getParent();
            }
            
            // Reinsert point in the root tree
            node->insert(rem_index);
        }
    }    
    
    // Rebuild lower parts of the tree
    northWest->rebuildTree();
    northEast->rebuildTree();
    southWest->rebuildTree();
    southEast->rebuildTree();
}
Exemple #7
0
void simple_test() {

  std::cout << "Beginning simple_test()..." << std::endl;


  // --------------------------------------------------------
  // a collection of 21 points that make a nice sample tree
  std::vector< std::pair<Point<int>,char> > simple_points;
  simple_points.push_back(std::make_pair(Point<int>(20,10), 'A'));
  simple_points.push_back(std::make_pair(Point<int>(10,5), 'B'));
  simple_points.push_back(std::make_pair(Point<int>(30,4), 'C'));
  simple_points.push_back(std::make_pair(Point<int>(11,15), 'D'));
  simple_points.push_back(std::make_pair(Point<int>(31,16), 'E'));
  simple_points.push_back(std::make_pair(Point<int>(5,3), 'F'));
  simple_points.push_back(std::make_pair(Point<int>(15,2), 'G'));
  simple_points.push_back(std::make_pair(Point<int>(4,7), 'H'));
  simple_points.push_back(std::make_pair(Point<int>(14,8), 'I'));
  simple_points.push_back(std::make_pair(Point<int>(25,1), 'J'));
  simple_points.push_back(std::make_pair(Point<int>(35,2), 'K'));
  simple_points.push_back(std::make_pair(Point<int>(26,7), 'L'));
  simple_points.push_back(std::make_pair(Point<int>(36,6), 'M'));
  simple_points.push_back(std::make_pair(Point<int>(3,13), 'N'));
  simple_points.push_back(std::make_pair(Point<int>(16,12), 'O'));
  simple_points.push_back(std::make_pair(Point<int>(4,17), 'P'));
  simple_points.push_back(std::make_pair(Point<int>(15,18), 'Q'));
  simple_points.push_back(std::make_pair(Point<int>(25,13), 'R'));
  simple_points.push_back(std::make_pair(Point<int>(37,14), 'S'));
  simple_points.push_back(std::make_pair(Point<int>(24,19), 'T'));
  simple_points.push_back(std::make_pair(Point<int>(36,18), 'U'));


  // --------------------------------------------------------
  // the quad tree data structure starts out empty
  QuadTree<int,char> simple;
  assert (simple.size() == 0);
  // an empty tree has height == -1
  assert (simple.height() == -1); 
  // plot the structure with with these dimensions (width=40,height=20)
  std::cout << "\nan empty tree:" << std::endl;
  simple.plot(40,20);

  

  // --------------------------------------------------------
  for (int i = 0; i < simple_points.size(); i++) {

    // add each point from the collection
    //cout << "hello"<< endl;
    simple.insert(simple_points[i].first,simple_points[i].second);
    // verify the size (total # of points in the tree)
     //cout << "hello"<< endl;
    assert (simple.size() == i+1);

    // a few some specific checks along the way
    if (i == 0) { 
      std::cout << "\nafter inserting first data point:" << std::endl;
      simple.plot(40,20);
      // a tree with 1 node has height == 0
      //cout << simple.height() << endl;
      assert (simple.height() == 0); 
      // check that the newly inserted element can be found
      //cout << "hello"<< endl;
      QuadTree<int,char>::iterator itr = simple.find(20,10);
      //cout << itr.getLabel() << endl;
      //cout << "hello"<< endl;
      assert (itr != simple.end());
      // read the label & coordinates from the iterator
      assert (itr.getLabel() == 'A');
      // dereference the iterator to get the point
      const Point<int> &pt = *itr;
      assert (pt.x == 20);
      assert (pt.y == 10);
      //cout << "hello"<< endl;
    } else if (i <= 4) {
      std::cout << "\nafter inserting " << i+1 << " data points:" << std::endl;
      simple.plot(40,20);
      // the next 4 additions for this simple all happen at the
      // second level, tree has height = 1
      assert (simple.height() == 1);
    } else if (i == 8) {
      std::cout << "\nafter inserting " << i+1 << " data points:" << std::endl;
      simple.plot(40,20);
      assert (simple.height() == 2);
      // check for an element that exists
      QuadTree<int,char>::iterator itr = simple.find(4,7);
      assert (itr != simple.end());
      assert (itr.getLabel() == 'H');
      assert ((*itr).x == 4);
      assert ((*itr).y == 7);
      // check for a couple elements that aren't in the tree
      itr = simple.find(14,14);
      assert (itr == simple.end());
      itr = simple.find(15,18);
      assert (itr == simple.end());
      // another visualization of the tree structure
      // note: this is a pre-order traversal of the data (print the node, then recurse on each child)
      std::cout << "\na 'sideways' printing of the tree structure with 9 nodes:" << std::endl;
      simple.print_sideways();
    }
  }


  // --------------------------------------------------------
  // a few more checks
  std::cout << "\nafter inserting all 21 data points:" << std::endl;
  simple.plot(40,20);
  assert (simple.size() == 21);
  assert (simple.height() == 2);
  QuadTree<int,char>::iterator itr = simple.find(15,18);
  assert (itr != simple.end());
  assert (itr.getLabel() == 'Q');
  assert ((*itr).x == 15);
  assert ((*itr).y == 18);

  // plot the data without the lines
  std::cout << "\na plot of the point data without the lines:" << std::endl;
  simple.plot(40,20,false);


  // --------------------------------------------------------
  // another visualization of the tree structure
  // note: this is a pre-order traversal of the data (print the node, then recurse on each child)
  std::cout << "\na 'sideways' printing of the finished tree structure:" << std::endl;
  simple.print_sideways();


  // --------------------------------------------------------
  // use the primary (depth-first) iterator to traverse the tree structure
  // note: this is a pre-order traversal, the same order as the 'sideways' tree above!!
  std::cout << "\nA depth-first traversal of the simple tree (should match sideways output!):" << std::endl;
  QuadTree<int,char>::iterator df_itr = simple.begin();
  char expected_depth_first_order[21] = 
    { 'A','B','F','G','H','I','C','J','K','L','M','D','N','O','P','Q','E','R','S','T','U' };
  for (int i = 0; i < 21; i++) {
    assert (df_itr != simple.end());
    // get the depth/level of this element in the tree (distance from root node!)
    int depth = df_itr.getDepth();
    // use the depth to indent the output (& match the sideways tree output above)
    std::cout << std::string(depth*2,' ') << df_itr.getLabel() << " " << *df_itr << std::endl;
    // check that the output is in the correct order!
    assert (df_itr.getLabel() == expected_depth_first_order[i]);
    // test the pre-increment operator++ 
    ++df_itr;  
  }
  // after 21 increments, we better be at the end!
  assert (df_itr == simple.end());


  // --------------------------------------------------------
  // using the breadth-first iterator to traverse the data by level
  std::cout << "\nA breadth first traversal of the simple tree:";
  QuadTree<int,char>::bf_iterator bf_itr = simple.bf_begin();
  char expected_breadth_first_order[21] = 
    { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U' };
  int level = -1;
  for (int i = 0; i < 21; i++) {
    assert (bf_itr != simple.bf_end());
    // get the depth/level of this element in the tree (distance from root node!)
    int depth = bf_itr.getDepth();
    if (level != depth) {
      level = depth;
      // starting a new level!
      std::cout << std::endl << "   level " << level << ":";
    }
    // print out this data point
    std::cout << " " << bf_itr.getLabel() << *bf_itr;
    // check that the output is in the correct order!
    assert (bf_itr.getLabel() == expected_breadth_first_order[i]);
    // test the pre-increment operator++
    ++bf_itr;
  }
  // after 21 increments, we better be at the end!
  assert (bf_itr == simple.bf_end());
  std::cout << std::endl;

  // --------------------------------------------------------
  std::cout << "\nFinished with simple_test().\n" << std::endl;
  

  // Note: the destructor for the QuadTree object 'simple' is
  // automatically called when we leave this function and the variable
  // goes out of scope!
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	QuadTree<100000, 4000100> qt;
	
	int N, Q;
	cin >> N >> Q >> ws;
	
	vector<string> inp(N, "");
	Node *ft = new Node(), *bt = new Node();
	for (int i = 0; i < N; ++i) {
		getline(cin, inp[i]);
		ft->insert(inp[i]);
		bt->rinsert(inp[i], inp[i].length() - 1);
	}
	
	int fc = 0, bc = 0;
	ft->leaf_fix(fc);
	bt->leaf_fix(bc);
	
	vii lr(N, {-1, -1});
	for (int i = 0; i < N; ++i) {
		lr[i].first = ft->getleaf(inp[i], 0).first;
		lr[i].second = bt->getleaf_r(inp[i], inp[i].length()-1).first;
//		cerr << i << ' ' << lr[i].first << ' '<<lr[i].second << endl;
	}
	
	vii bysize;
	for (int i = 0; i < N; ++i) bysize.push_back({inp[i].size(), i});
	sort(bysize.rbegin(), bysize.rend());
	inp.clear();
	
	vector<string> query(Q, "");
	vii qbysize;
	for (int q = 0; q < Q; ++q) {
		getline(cin, query[q]);
		qbysize.push_back({query[q].size(), q});
	}
	sort(qbysize.rbegin(), qbysize.rend());
	vi ans(Q, 0LL);
	
	// Handle queries one by one
	for (int _q = 0, i = 0; _q < Q; ++_q) {
		int q = qbysize[_q].second;
		
		// Insert all strings that are strictly smaller
		while (i < N && bysize[i].first + 1 >= qbysize[_q].first) {
			int s = bysize[i].second;
			qt.insert(lr[s], 1);
			++i;
		}
		
		// Process the query
		ii prefr = ft->getleaf_ast(query[q], 0);
		ii suffr = bt->getleaf_rast(query[q], query[q].length()-1);
		if (prefr.second == -1 || suffr.second == -1) continue;
		
//		cerr << q << "  ";
//		cerr << prefr.first << ' ' <<prefr.second << "  ";
//		cerr << suffr.first << ' ' <<suffr.second << endl;
		--prefr.second;
		--suffr.second;
		
		ans[q] = qt.query(prefr.first, suffr.first, prefr.second, suffr.second);
	}
	
	for (size_t i = 0; i < ans.size(); ++i) cout << ans[i] << '\n';
	
	return 0;
}
Exemple #9
0
int test_main()
{
	os::gfx::Gfx gx;
	gx.change_mode(os::gfx::VideoMode(800, 600));
	reaper::debug::ExitFail ef(1);
	os::event::EventSystem es(gx);
	os::event::EventProxy ep = os::event::EventSystem::get_ref(0);

	qt.insert(new world::Triangle(
				Point(200, 0, 200),
				Point(500, 1, 200),
				Point(500, 1, 500)
				));
	qt.insert(new world::Triangle(
				Point(500, 10, 500),
				Point(700, 10, 500),
				Point(700, 10, 700)
				));

	glViewport(0,0,gx.current_mode().width, gx.current_mode().height);		// hela fönstret
	glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
	gluPerspective(70,1,1,1000);

	glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0,500,0, 0,0,0, 0,0,1);

	glClearColor(0,0,0,0);
	::glEnable(GL_DEPTH_TEST);

	world::Line line(Point(500, 100, 500), Point(480, -10, 490));
	float step = 1;
	os::time::TimeSpan start = os::time::get_time();

	while (true) {
		if (ep.key(os::event::id::Escape))
			break;
		if (ep.key('1')) line.p1.x += 10.0;
		if (ep.key('2')) line.p1.x -= 10.0;
		if (ep.key('3')) line.p1.y += 10.0;
		if (ep.key('4')) line.p1.y -= 10.0;
		if (ep.key('5')) line.p1.z += 10.0;
		if (ep.key('6')) line.p1.z -= 10.0;

		if (ep.key('7')) line.p2.x += 10.0;
		if (ep.key('8')) line.p2.x -= 10.0;
		if (ep.key('9')) line.p2.y += 10.0;
		if (ep.key('0')) line.p2.y -= 10.0;
		if (ep.key('-')) line.p2.z += 10.0;
		if (ep.key('=')) line.p2.z -= 10.0;

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		draw_it(line);
		gx.update_screen();
		os::time::msleep(50);
		if (exit_now())
			break;
	}

	ef.disable();
	return 0;
}
int main(){
    
    unordered_map<string, Location>* addresses = parseLocFile();

    // builds the QuadTree! and reads in all of the restauraunts.
    // I constructed the restauraunt class so as to simply use the >> operator
    // to read a line from the CSV file
    Restauraunt* r = new Restauraunt;
    ifstream foodFile(FOOD_FILE);
    foodFile.ignore(1000, '\n'); // Ignore first line
    QuadTree<Restauraunt> quad;
    while(!(foodFile >> (*r)).eof()){
        // If the location wasn't set, use the address to find the location
        if(!r->locationSet()){
            r->setLocation(getLocationFromAddress(addresses, r->address));
        }
        // Which means that now the metric location of the restauraunt is known, 
        // and can be inserted into the QuadTree
        quad.insert(r->metricLocation, r);
        r = new Restauraunt;
    }
    delete r;
    foodFile.close();
    
    /* Data is stored in crime csv as:
     * COMPNOS,NatureCode,INCIDENT_TYPE_DESCRIPTION,MAIN_CRIMECODE,REPTDISTRICT,
     * REPORTINGAREA,FROMDATE,WEAPONTYPE,Shooting,DOMESTIC,
     * SHIFT,Year,Month,DAY_WEEK,UCRPART,
     * X,Y,STREETNAME,XSTREETNAME,Location
     * 
     * We want INCIDENT_TYPE_DESCRIPTION [2], FROMDATE [6], WEAPONTYPE [7], Shooting [8], and Location [19]
     */
    
    ifstream crimeFile(CRIME_FILE);
    ofstream crimeOut (CRIME_OUT);
    // Output the crime header
    crimeOut << "Location, Date, Type, Danger\n";
    crimeFile.ignore(1000, '\n'); // Ignore first line
    
    char buff[128];
    
    // There were only like 30 destinct incident types, not all of which I understood, so I just assigned
    // each a numerical value. This unordered_map is how: if an incident was not in incidentTypes, set
    // the value to the incidentCount and store that in incidentTypes, and increment incidentCount
    unordered_map<string, unsigned char> incidentTypes;
    unsigned char incidentCount = 0;
    string incidentType;
    
    unordered_map<string, unsigned char>::const_iterator iter;
    // m stores metric location, l stores latitude/longitude
    Location m,l;
    
    int i=0;
    
    // I realized after a bit that I would want a date representing now to determine how long ago things
    // happened, but I didn't want too create a new date for every restauraunt or crime, so last minute
    // I added this variable
    Date now = Date::now();
    vector<struct Crime*> crimes;
    
    // I decided for the crimes, ad I wanted to keep tack of incident types
    // and the like, that rather than doing stream operators I would just do it all
    // here. It doesn't make or the cleanes code, b
    while(!crimeFile.eof()){
        struct Crime* c = new struct Crime;
        c->copies = 0;
        // This loops through the 20 cells of information in the CSV and extracts
        // the relevent bits
        for(int i=0;i<19;i++){
            crimeFile.getline(buff, 128, ',');
            
            if(crimeFile.eof())
                break;
            switch(i){
                case 2:// INCIDENT_TYPE_DESCRIPTION
                    ;
                    incidentType = string(buff); 
                    iter = incidentTypes.find(incidentType);
                    if(iter == incidentTypes.end()){
                        // Then the incidentType isn't in incidentTypes
                        incidentTypes.emplace(incidentType, incidentCount);
                        c->type = incidentCount;
                        incidentCount++;
                    }else{
                        c->type = iter->second;
                    }
                    break;
                case 6: // FROMDATE
                    c->date.setDate(buff);
                    break;
                case 7: // WEAPONTYPE (either Unarmed, Other, Knife, or Firearm)
                    switch(buff[0]){
                        case 'U': // Unarmed
                            c->weapon = 0;
                            break;
                        case 'O': // Other
                            c->weapon = 1;
                            break;
                        case 'K': // Knife
                            c->weapon = 2;
                            break;
                        case 'F': // Firearm
                            c->weapon = 3;
                            break;
                        default:
                            break;
                    }
                    break;
                case 8: //Shooting (Yes or No)
                    
                    // If there was a shooting, add a shooting flag
                    if(buff[0] == 'Y'){ 
                        c->weapon += 4;
                    }
                    break;
                default:
                    break;
            }
        }   
        crimeFile.getline(buff, 128); //This is the location
        l.setLocation(buff);
        m.setLocation((l.x - MIN_LAT)*LAT_TO_METERS , 
                      (l.y - MIN_LNG)*LNG_TO_METERS);
        // Output the crime CSV
        crimeOut << '"' << l << "\", " << c->date << ", "
                 << int(c->type) << ", " << int(c->weapon) << endl;
        
        // the call to quad.findNodes(m, 100) finds all nodes in the QuadTree within
        // a distance of 100 from the location m, which is the metric coordinates of the crime
        vector<Restauraunt*> v = quad.findNodes(m, 100);
        
        // This bit iterates through and adds the crime to the objects of nearby restauraunts
        if(!v.empty()){
            int initialCost = initialCrimeCost(*c);
            // If the initial cost is 0, no need to add the crime, as that means it was ignorable?
            // Basically I just decided that a MedAssist incident probably shouldn't be counted,
            // although I don't actually kknow what that means, its frequency and name suggests
            // that perhaps the police were merely assisting with something of a medical nature.
            
            if(initialCost > 0){
                for(Restauraunt* r: v){
                    r->addCrime(c, m, initialCost, now);
                }
            }
        }
        // if c->copies = 0, then it wasn't within 100 meters of any restauraunt and should be deleted
        if(c->copies = 0)
            delete c;
        else
            crimes.push_back(c);
        i++;
        if(i%100 == 0)
            cout << i << " crimes processed\n";
    }
    crimeFile.close();
    crimeOut.close();
    cout << "MedAssist: " << (int)incidentTypes["MedAssist"] << endl;
    // This section outputs the food CSV nice and succinctly
    ofstream foodOut (FOOD_OUT);
    foodOut << "Location, Name, Date, Address, Description, CrimeCost, Crimes\n";
    quad.mapNodes(writeRestauraunt, &foodOut);
    
    for(struct Crime* crime : crimes){
        delete crime;
    }
    
    delete addresses;
    
    // I should free all of the restauraunts in the quad, but this doesn't seem
    // to work and I don't really care that much for a one-off script:
    // quad.mapNodes(deleteRestauraunt, NULL);
    
}