void BSPTree::make(Communicator *communicator, time_t atime, const std::vector<TaggedLine> &lines, BSPNode *root) { typedef std::pair<std::vector<TaggedLine>, std::vector<TaggedLine>> TagLineVecPair; std::stack<BSPNode *> nodeStack; std::stack<TagLineVecPair> lineStack; nodeStack.push(root); lineStack.push(makeLines(communicator, atime, lines, root)); int progress = 0; while (!nodeStack.empty()) { progress++; // might need to increase by 2 because it was one for each left/right in the previous iteration if (communicator) { if (communicator->IsCancelled()) { throw Communicator::CancelledException(); } if (qtimer(atime, 500)) { communicator->CommPostMessage(Communicator::CURRENT_RECORD, progress); } } BSPNode *currNode = nodeStack.top(); nodeStack.pop(); TagLineVecPair currLines = lineStack.top(); lineStack.pop(); if (!currLines.first.empty()) { currNode->m_left = std::unique_ptr<BSPNode>(new BSPNode(currNode)); nodeStack.push(currNode->m_left.get()); lineStack.push(makeLines(communicator, atime, currLines.first, currNode->m_left.get())); } if (!currLines.second.empty()) { currNode->m_right = std::unique_ptr<BSPNode>(new BSPNode(currNode)); nodeStack.push(currNode->m_right.get()); lineStack.push(makeLines(communicator, atime, currLines.second, currNode->m_right.get())); } } }
void AgentEngine::run(Communicator *comm, PointMap *pointmap) { __time64_t atime = 0; if (comm) { qtimer( atime, 0 ); comm->CommPostMessage( Communicator::NUM_RECORDS, m_timesteps ); } AttributeTable& table = pointmap->getAttributeTable(); int displaycol = table.insertColumn(g_col_total_counts); int output_mode = Agent::OUTPUT_COUNTS; if (m_gatelayer != -1) { output_mode |= Agent::OUTPUT_GATE_COUNTS; } // remove any agent trails that are left from a previous run for (int k = 0; k < MAX_TRAILS; k++) { g_trails[k].clear(); } int trail_num = -1; if (m_record_trails) { if (m_trail_count < 1) { m_trail_count = 1; } if (m_trail_count > MAX_TRAILS) { m_trail_count = MAX_TRAILS; } trail_num = 0; } // remove any agents that are left from a previous run for (size_t j = 0; j < size(); j++) { at(j).clear(); } for (int i = 0; i < m_timesteps; i++) { size_t j; for (j = 0; j < size(); j++) { int q = invcumpoisson(prandomr(),at(j).m_release_rate); int length = at(j).size(); int k; for (k = 0; k < q; k++) { at(j).push_back(Agent(&(at(j)),pointmap,output_mode)); } for (k = 0; k < q; k++) { at(j).init(length+k,trail_num); if (trail_num != -1) { trail_num++; // after trail count, stop recording: if (trail_num == m_trail_count) { trail_num = -1; } } } } for (j = 0; j < size(); j++) { at(j).move(); } if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage( Communicator::CURRENT_RECORD, i ); } } } // output agent trails to file: if (m_record_trails) { // just dump in local file... ofstream trails("trails.cat"); trails << "CAT" << endl; for (int i = 0; i < m_trail_count; i++) { trails << "Begin Polyline" << endl; for (size_t j = 0; j < g_trails[i].size(); j++) { trails << g_trails[i][j].x << " " << g_trails[i][j].y << endl; } trails << "End Polyline" << endl; } } // actually, no, do this from the pointmap->overrideDisplayedAttribute(-2); pointmap->setDisplayedAttribute(displaycol); }
bool SegmentAngular::run(Communicator *comm, const Options &options, ShapeGraph &map, bool simple_version) { if (map.getMapType() != ShapeMap::SEGMENTMAP) { return false; } AttributeTable &attributes = map.getAttributeTable(); time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getConnections().size()); } // note: radius must be sorted lowest to highest, but if -1 occurs ("radius n") it needs to be last... // ...to ensure no mess ups, we'll re-sort here: bool radius_n = false; std::vector<double> radii; for (double radius : options.radius_set) { if (radius < 0) { radius_n = true; } else { radii.push_back(radius); } } if (radius_n) { radii.push_back(-1.0); } std::vector<int> depth_col, count_col, total_col; // first enter table values for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; attributes.insertOrResetColumn(depth_col_text.c_str()); std::string count_col_text = std::string("Angular Node Count") + radius_text; attributes.insertOrResetColumn(count_col_text.c_str()); std::string total_col_text = std::string("Angular Total Depth") + radius_text; attributes.insertOrResetColumn(total_col_text.c_str()); } for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; depth_col.push_back(attributes.getColumnIndex(depth_col_text.c_str())); std::string count_col_text = std::string("Angular Node Count") + radius_text; count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); std::string total_col_text = std::string("Angular Total Depth") + radius_text; total_col.push_back(attributes.getColumnIndex(total_col_text.c_str())); } std::vector<bool> covered(map.getShapeCount()); size_t i = 0; for (auto & iter : attributes){ for (size_t j = 0; j < map.getShapeCount(); j++) { covered[j] = false; } std::vector<std::pair<float, SegmentData>> anglebins; anglebins.push_back(std::make_pair(0.0f, SegmentData(0, i, SegmentRef(), 0, 0.0, 0))); std::vector<double> total_depth; std::vector<int> node_count; for (size_t r = 0; r < radii.size(); r++) { total_depth.push_back(0.0); node_count.push_back(0); } // node_count includes this one, but will be added in next algo: while (anglebins.size()) { auto iter = anglebins.begin(); SegmentData lineindex = iter->second; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; double depth_to_line = iter->first; total_depth[lineindex.coverage] += depth_to_line; node_count[lineindex.coverage] += 1; anglebins.erase(iter); Connector &line = map.getConnections()[lineindex.ref]; if (lineindex.dir != -1) { for (auto &segconn : line.m_forward_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; int rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } if (lineindex.dir != 1) { for (auto &segconn : line.m_back_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; int rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } } else { anglebins.erase(iter); } } AttributeRow &row = iter.getRow(); // set the attributes for this node: int curs_node_count = 0; double curs_total_depth = 0.0; for (size_t r = 0; r < radii.size(); r++) { curs_node_count += node_count[r]; curs_total_depth += total_depth[r]; row.setValue(count_col[r], float(curs_node_count)); if (curs_node_count > 1) { // note -- node_count includes this one -- mean depth as per p.108 Social Logic of Space double mean_depth = curs_total_depth / double(curs_node_count - 1); row.setValue(depth_col[r], float(mean_depth)); row.setValue(total_col[r], float(curs_total_depth)); } else { row.setValue(depth_col[r], -1); row.setValue(total_col[r], -1); } } // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, i); } } i++; } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(depth_col.back()); return true; }