Beispiel #1
0
    def test_creategraph(self):
        #   |
        # --|--
        #   |__
        line_coords = array.array('d', [0, 0, 2, 0, 1, 1, 1, -1, 2, -1])
        line_indices = array.array('I', [0, 1, 2, 3, 3, 4])
        unlinks = array.array('d', [1, 0])
        points = array.array('d', [-1, 0])

        graph_handle = pstalgo.CreateGraph(line_coords, line_indices, unlinks,
                                           points, None)
        self.assertIsNotNone(graph_handle)

        graph_info = pstalgo.GetGraphInfo(graph_handle)
        self.assertEqual(graph_info.m_LineCount, 3)
        self.assertEqual(graph_info.m_CrossingCount,
                         1)  # One of the 2 crossings was unlinked
        self.assertEqual(graph_info.m_PointCount, 1)

        lengths = array.array('f', [0]) * 3
        pstalgo.GetGraphLineLengths(graph_handle, lengths)
        IsArrayRoughlyEqual(lengths, [2, 2, 1])

        crossings = array.array('d', [0]) * 2
        pstalgo.GetGraphCrossingCoords(graph_handle, crossings)
        IsArrayRoughlyEqual(crossings, [1, -1])

        pstalgo.FreeGraph(graph_handle)
Beispiel #2
0
	def test_NInt_single(self):
		line_count = 1
		line_length = 3
		graph = CreateChainGraph(line_count, line_length)
		tests = [
			(Radii(), [-1], [1], [0]),
		]
		self.runTests(graph, tests, line_count)
		pstalgo.FreeGraph(graph)
Beispiel #3
0
	def test_arch_region_origin(self):
		count = 5
		length = 3
		g = CreateRegionOriginChainGraph(count, length)
		attraction_points = array.array('d', [-1, 0, length*count+1, 0])  # One point left of and another right of graph
		attraction_values = array.array('f', [4, 3])
		collect_func = pstalgo.AttractionCollectionFunc.AVARAGE
		distr_func   = pstalgo.AttractionDistributionFunc.DIVIDE  # Redundant here
		self.doTest(g, count, OriginType.POINT_GROUPS, DistanceType.UNDEFINED, Radii(), AttractionWeightFunction.CONSTANT, 0, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4+3]*count)
		pstalgo.FreeGraph(g)
Beispiel #4
0
	def test_five_chain(self):
		graph = self.create_chain_graph(5)
		betweenness = array.array('f', [0])*5  # Fastest way of allocating arrays of array.array-type
		pstalgo.SegmentBetweenness(
			graph_handle = graph,
			distance_type = DistanceType.STEPS, 
			radius = pstalgo.Radii(steps=4),
			out_betweenness = betweenness)
		pstalgo.FreeGraph(graph)
		self.assertEqual(betweenness, array.array('f', [0, 3, 4, 3, 0]))
Beispiel #5
0
	def test_split2(self):
		graph = self.create_split_graph2()
		betweenness = array.array('f', [0])*6  # Fastest way of allocating arrays of array.array-type
		pstalgo.SegmentBetweenness(
			graph_handle = graph,
			distance_type = DistanceType.ANGULAR, 
			radius = pstalgo.Radii(angular=45),
			out_betweenness = betweenness)
		pstalgo.FreeGraph(graph)
		self.assertEqual(betweenness, array.array('f', [0, 1, 1, 2, 2, 0]))
Beispiel #6
0
 def test_odb_closest(self):
     g = CreateTestGraph()
     self.doTest(
         graph_handle=g,
         origin_points=array.array('d', [-0.5, 0]),
         origin_weights=None,
         destination_weights=None,
         destination_mode=ODBDestinationMode.CLOSEST_DESTINATION_ONLY,
         distance_type=DistanceType.WALKING,
         radius=Radii(),
         scores_check=[1, 1, 0])
     pstalgo.FreeGraph(g)
Beispiel #7
0
 def test_odb_dest_weights(self):
     g = CreateTestGraph()
     self.doTest(
         graph_handle=g,
         origin_points=array.array('d', [-0.5, 0]),
         origin_weights=array.array('f', [10]),
         destination_weights=array.array('f', [4, 1]),
         destination_mode=ODBDestinationMode.ALL_REACHABLE_DESTINATIONS,
         distance_type=DistanceType.WALKING,
         radius=Radii(),
         scores_check=[10, 10, 2])
     pstalgo.FreeGraph(g)
Beispiel #8
0
	def test_arch_region_attr(self):
		count = 5
		length = 3
		g = CreateRegionOriginChainGraph(count, length)
		attraction_points = array.array('d', [-2, 0, -1, 0, -1, -1, -2, -1, length*count+1, 0, length*count+2, 0, length*count+2, -1, length*count+1, -1])  # One region left of and another right of graph
		points_per_attraction_polygon = array.array('I', [4, 4])
		attraction_polygon_point_interval = 0.5
		attraction_values = array.array('f', [4, 3])
		collect_func = pstalgo.AttractionCollectionFunc.AVARAGE
		distr_func   = pstalgo.AttractionDistributionFunc.DIVIDE
		self.doTest(g, count, OriginType.POINT_GROUPS, DistanceType.UNDEFINED, Radii(), AttractionWeightFunction.CONSTANT, 0, attraction_points, points_per_attraction_polygon, attraction_polygon_point_interval, attraction_values, distr_func, collect_func, [4+3]*count)
		distr_func   = pstalgo.AttractionDistributionFunc.COPY
		self.doTest(g, count, OriginType.POINT_GROUPS, DistanceType.UNDEFINED, Radii(), AttractionWeightFunction.CONSTANT, 0, attraction_points, points_per_attraction_polygon, attraction_polygon_point_interval, attraction_values, distr_func, collect_func, [4+3]*count)
		pstalgo.FreeGraph(g)
Beispiel #9
0
	def test_arch_point_origin(self):
		count = 5
		length = 3
		g = CreatePointOriginChainGraph(count, length)
		attraction_points = array.array('d', [-1, 0, length*count+1, 0])  # One point left of and another right of graph
		attraction_values = array.array('f', [4, 3])
		collect_func = pstalgo.AttractionCollectionFunc.AVARAGE  # Redundant here
		distr_func   = pstalgo.AttractionDistributionFunc.DIVIDE  # Redundant here
		self.doTest(g, count, OriginType.POINTS,    DistanceType.UNDEFINED, Radii(),        AttractionWeightFunction.CONSTANT, 0, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4+3]*count)
		self.doTest(g, count, OriginType.LINES,     DistanceType.UNDEFINED, Radii(),        AttractionWeightFunction.CONSTANT, 0, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4+3]*count)
		self.doTest(g, count, OriginType.JUNCTIONS, DistanceType.UNDEFINED, Radii(),        AttractionWeightFunction.CONSTANT, 0, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4+3]*(count-1))
		self.doTest(g, count, OriginType.POINTS,    DistanceType.UNDEFINED, Radii(steps=2), AttractionWeightFunction.CONSTANT, 0, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4,4,4+3,3,3])
		self.doTest(g, count, OriginType.POINTS,    DistanceType.STEPS,     Radii(steps=2), AttractionWeightFunction.DIVIDE,   1, attraction_points, None, 0, attraction_values, distr_func, collect_func, [4,2,4.0/3+1,1.5,3])
		pstalgo.FreeGraph(g)
Beispiel #10
0
	def test_reach_square(self):
		line_count = 4
		line_length = 3
		graph = CreateSquareGraph(line_length)

		tests = [
			(Radii(), [4, 4, 4, 4], [line_length*line_count]*line_count, [line_length*line_length]*line_count),
			(Radii(angular=80), [1, 1, 1, 1], [line_length*1]*line_count, [0]*line_count),
			(Radii(angular=100), [3, 3, 3, 3], [line_length*3]*line_count, [line_length*line_length]*line_count),
			(Radii(angular=190), [4, 4, 4, 4], [line_length*line_count]*line_count, [line_length*line_length]*line_count),
		]

		self.runTests(graph, tests, line_count)

		pstalgo.FreeGraph(graph)
Beispiel #11
0
	def test_NInt_chain(self):
		line_count = 5
		line_length = 3
		graph = CreateChainGraph(line_count, line_length)
		tests = [
			(Radii(), [0.352, 0.704, 1.056, 0.704, 0.352], [line_count]*line_count, [10, 7, 6, 7, 10]),
			(Radii(straight=0), None, [1]*line_count, None),
			(Radii(straight=1), None, [1]*line_count, None),
			(Radii(straight=line_length), None, [2, 3, 3, 3, 2], None),
			(Radii(walking=0), None, [1]*line_count, None),
			(Radii(walking=1), None, [1]*line_count, None),
			(Radii(walking=3), None, [2, 3, 3, 3, 2], None),
			(Radii(steps=0), None, [1]*line_count, None),
			(Radii(steps=1), None, [2, 3, 3, 3, 2], None),
			(Radii(steps=2), None, [3, 4, 5, 4, 3], None),
			(Radii(angular=1), None, [line_count]*line_count, None),
		]
		self.runTests(graph, tests, line_count)
		pstalgo.FreeGraph(graph)
Beispiel #12
0
 def test_odb_radius(self):
     g = CreateTestGraph()
     self.doTest(
         graph_handle=g,
         origin_points=array.array('d', [-0.5, 0]),
         origin_weights=None,
         destination_weights=None,
         destination_mode=ODBDestinationMode.ALL_REACHABLE_DESTINATIONS,
         distance_type=DistanceType.WALKING,
         radius=Radii(walking=3.9),
         scores_check=[1, 1, 0])
     self.doTest(
         graph_handle=g,
         origin_points=array.array('d', [-0.5, 0]),
         origin_weights=None,
         destination_weights=None,
         destination_mode=ODBDestinationMode.ALL_REACHABLE_DESTINATIONS,
         distance_type=DistanceType.WALKING,
         radius=Radii(walking=4.1),
         scores_check=[1, 1, .5])
     pstalgo.FreeGraph(g)
Beispiel #13
0
	def test_reach_chain(self):
		line_count = 3
		line_length = 3
		graph = CreateChainGraph(line_count, line_length)

		tests = [
			(Radii(), [3, 3, 3], [9, 9, 9], [0, 0, 0]),
			(Radii(straight=0), [1, 1, 1], [3, 3, 3], [0, 0, 0]),
			(Radii(straight=1), [1, 1, 1], [3, 3, 3], [math.pi]*3),
			(Radii(straight=3), [2, 3, 2], [6, 9, 6], [3*3*math.pi]*3),
			(Radii(walking=0), [1, 1, 1], [3, 3, 3], [0, 0, 0]),
			(Radii(walking=1), [1, 1, 1], [3, 3, 3], [0, 0, 0]),
			(Radii(walking=3), [2, 3, 2], [6, 9, 6], [0, 0, 0]),
			(Radii(steps=0), [1, 1, 1], [3, 3, 3], [0, 0, 0]),
			(Radii(steps=1), [2, 3, 2], [6, 9, 6], [0, 0, 0]),
			(Radii(steps=2), [3, 3, 3], [9, 9, 9], [0, 0, 0]),
			(Radii(angular=1), [3, 3, 3], [9, 9, 9], [0, 0, 0]),
		]

		self.runTests(graph, tests, line_count)

		pstalgo.FreeGraph(graph)
Beispiel #14
0
    def run(self, delegate):

        import pstalgo  # Do it here when it is needed instead of on plugin load
        Vector = pstalgo.Vector
        props = self._props
        model = self._model

        radii_list = RadiiFromSettings(pstalgo, self._props).split()

        # Distance modes
        distance_modes = DistanceTypesFromSettings(pstalgo, props)

        def GenerateColumnName(attr_name, distance_mode, radii, norm):
            return GenColName(ColName.ATTRACTION_BETWEENNESS,
                              weight=attr_name,
                              pst_distance_type=distance_mode,
                              radii=radii,
                              normalization=norm)

        # Attraction columns (None = use value 1 for every attraction)
        attraction_columns = props['dest_data'] if props[
            'dest_data_enabled'] else [None]

        # Number of analyses
        analysis_count = len(attraction_columns) * len(radii_list) * len(
            distance_modes)

        # Tasks
        class Tasks(object):
            READ_ATTRACTIONS = 1
            BUILD_GRAPH = 2
            ANALYSIS = 3
            WRITE_RESULTS = 4

        progress = MultiTaskProgressDelegate(delegate)
        progress.addTask(Tasks.READ_ATTRACTIONS, 1, None)
        progress.addTask(Tasks.BUILD_GRAPH, 1, None)
        progress.addTask(Tasks.ANALYSIS, 10 * analysis_count, None)

        initial_alloc_state = stack_allocator.state()

        graph = None

        try:
            # Attraction points
            progress.setCurrentTask(Tasks.READ_ATTRACTIONS)
            (attr_table, attr_rows, attr_points,
             attr_points_per_polygon) = ReadAttractionPoints(
                 model, pstalgo, stack_allocator, props, progress)

            # Graph
            progress.setCurrentTask(Tasks.BUILD_GRAPH)
            (graph, line_rows, _) = BuildAxialGraph(
                self._model, pstalgo, stack_allocator,
                self._props['in_network'], self._props['in_unlinks']
                if self._props['in_unlinks_enabled'] else None, None, progress)
            line_count = line_rows.size()

            # Allocate output arrays
            scores = Vector(ctypes.c_float, line_count, stack_allocator,
                            line_count)
            scores_std = Vector(ctypes.c_float, line_count, stack_allocator,
                                line_count) if props['norm_standard'] else None

            # Analyses
            attr_values = None
            progress.setCurrentTask(Tasks.ANALYSIS)
            analysis_progress = TaskSplitProgressDelegate(
                analysis_count, "Performing analysis", progress)
            for attr_col in attraction_columns:
                # Attraction values
                if attr_col is not None:
                    if attr_values is None:
                        attr_values = Vector(ctypes.c_float, attr_rows.size(),
                                             stack_allocator)
                    attr_values.clear()
                    for value in AttractionValueGen(model, attr_table,
                                                    attr_rows, [attr_col],
                                                    progress):
                        attr_values.append(value)
                attr_title = GenerateAttractionDataName(
                    props['in_destinations'], attr_col, props['dest_name'])
                for radii in radii_list:
                    for distance_mode in distance_modes:
                        # Analysis sub progress
                        analysis_sub_progress = MultiTaskProgressDelegate(
                            analysis_progress)
                        analysis_sub_progress.addTask(Tasks.ANALYSIS, 1,
                                                      "Calculating")
                        analysis_sub_progress.addTask(Tasks.WRITE_RESULTS, 0,
                                                      "Writing line results")
                        # Analysis
                        analysis_sub_progress.setCurrentTask(Tasks.ANALYSIS)
                        pstalgo.SegmentBetweenness(
                            graph_handle=graph,
                            distance_type=distance_mode,
                            radius=radii,
                            weights=None if attr_col is None else attr_values,
                            attraction_points=attr_points,
                            progress_callback=pstalgo.
                            CreateAnalysisDelegateCallbackWrapper(
                                analysis_sub_progress),
                            out_betweenness=scores)
                        # Write
                        analysis_sub_progress.setCurrentTask(
                            Tasks.WRITE_RESULTS)
                        columns = []
                        if props['norm_none']:
                            columns.append(
                                (GenerateColumnName(attr_title, distance_mode,
                                                    radii, ColName.NORM_NONE),
                                 'float', scores.values()))
                        if props['norm_standard']:
                            pstalgo.StandardNormalize(scores, scores.size(),
                                                      scores_std)
                            columns.append(
                                (GenerateColumnName(attr_title, distance_mode,
                                                    radii,
                                                    ColName.NORM_STANDARD),
                                 'float', scores_std.values()))
                        self._model.writeColumns(self._props['in_network'],
                                                 line_rows, columns,
                                                 analysis_sub_progress)
                        # Progress
                        analysis_progress.nextTask()

        finally:
            stack_allocator.restore(initial_alloc_state)
            if graph:
                pstalgo.FreeGraph(graph)

        delegate.setStatus("Attraction Betweenness done")
        delegate.setProgress(1)
    def run(self, delegate):
        import pstalgo  # Do it here when it is needed instead of on plugin load
        Vector = pstalgo.Vector
        props = self._props
        model = self._model

        # Radius
        radii = RadiiFromSettings(pstalgo, self._props)

        # Origin type
        origin_type = OriginTypeFromProps(pstalgo, props)

        # Distance types
        distance_types = DistanceTypesFromSettings(pstalgo, props)

        # Attraction columns (None = use value 1 for every attraction)
        attraction_columns = props['dest_data'] if props[
            'dest_data_enabled'] else [None]

        # Number of analyses
        analysis_count = len(attraction_columns) * len(distance_types)

        def GenerateColumnName(dest_name, distance_type, radii):
            return GenColName(ColName.ATTRACTION_DISTANCE,
                              weight=dest_name,
                              pst_distance_type=distance_type,
                              radii=radii)

        # Tasks
        class Tasks(object):
            READ_ATTRACTIONS = 1
            BUILD_GRAPH = 2
            ANALYSIS = 3
            WRITE_RESULTS = 4

        progress = MultiTaskProgressDelegate(delegate)
        progress.addTask(Tasks.READ_ATTRACTIONS, 1, None)
        progress.addTask(Tasks.BUILD_GRAPH, 1, None)
        progress.addTask(Tasks.ANALYSIS, 5 * analysis_count, None)
        progress.addTask(Tasks.WRITE_RESULTS, 1, None)

        initial_alloc_state = stack_allocator.state()

        graph = None

        try:
            # Attraction points
            progress.setCurrentTask(Tasks.READ_ATTRACTIONS)
            (attr_table, attr_rows, attr_points,
             attr_points_per_polygon) = ReadAttractionPoints(
                 model, pstalgo, stack_allocator, props, progress)

            # Graph
            progress.setCurrentTask(Tasks.BUILD_GRAPH)
            (graph, line_rows, origin_rows) = BuildAxialGraph(
                model,
                pstalgo,
                stack_allocator,
                self._props['in_network'],
                self._props['in_unlinks']
                if self._props['in_unlinks_enabled'] else None,
                self._props['in_origin_points'] if origin_type in [
                    pstalgo.OriginType.POINTS, pstalgo.OriginType.POINT_GROUPS
                ] else None,
                progress,
                poly_edge_point_interval=props[
                    'origin_poly_edge_point_interval'] if
                (origin_type == pstalgo.OriginType.POINT_GROUPS) else 0)

            # Output count
            output_count = 0
            junction_coords = None
            if origin_type in [
                    pstalgo.OriginType.POINTS, pstalgo.OriginType.POINT_GROUPS
            ]:
                output_count = origin_rows.size()
            elif origin_type == pstalgo.OriginType.LINES:
                output_count = line_rows.size()
            elif origin_type == pstalgo.OriginType.JUNCTIONS:
                output_count = pstalgo.GetGraphInfo(graph).m_CrossingCount
                junction_coords = Vector(ctypes.c_double, output_count * 2,
                                         stack_allocator, output_count * 2)
                pstalgo.GetGraphCrossingCoords(graph, junction_coords)
            else:
                assert (False)

            columns = []

            attr_points_temp = None
            attr_points_per_polygon_temp = None

            progress.setCurrentTask(Tasks.ANALYSIS)
            analysis_progress = TaskSplitProgressDelegate(
                analysis_count, "Performing analysis", progress)
            for attr_col in attraction_columns:
                # Attraction values
                if attr_col is None:
                    attr_points_filtered = attr_points
                    attr_points_per_polygon_filtered = attr_points_per_polygon
                else:
                    attr_values = AttractionValueGen(model, attr_table,
                                                     attr_rows, [attr_col],
                                                     progress)
                    (attr_points_temp,
                     attr_points_per_polygon_temp) = FilterZeroAttractions(
                         attr_points, attr_points_per_polygon, attr_values,
                         stack_allocator, attr_points_temp,
                         attr_points_per_polygon_temp)
                    attr_points_filtered = attr_points_temp
                    attr_points_per_polygon_filtered = attr_points_per_polygon_temp
                # Distance types
                for distance_type in distance_types:
                    # Allocate output array
                    scores = Vector(ctypes.c_float, output_count,
                                    stack_allocator, output_count)
                    # Analysis
                    pstalgo.AttractionDistance(
                        graph_handle=graph,
                        origin_type=origin_type,
                        distance_type=distance_type,
                        radius=radii,
                        attraction_points=attr_points_filtered,
                        points_per_polygon=attr_points_per_polygon_filtered,
                        polygon_point_interval=props[
                            'dest_poly_edge_point_interval'],
                        progress_callback=pstalgo.
                        CreateAnalysisDelegateCallbackWrapper(
                            analysis_progress),
                        out_min_distances=scores)
                    # Output column
                    attr_title = GenerateAttractionDataName(
                        props['in_destinations'], attr_col, props['dest_name'])
                    columns.append(
                        (GenerateColumnName(attr_title, distance_type,
                                            radii), 'float', scores.values()))
                    # Progress
                    analysis_progress.nextTask()

            # Write
            progress.setCurrentTask(Tasks.WRITE_RESULTS)
            if origin_type in [
                    pstalgo.OriginType.POINTS, pstalgo.OriginType.POINT_GROUPS
            ]:
                model.writeColumns(self._props['in_origin_points'],
                                   origin_rows, columns, progress)
            elif origin_type == pstalgo.OriginType.LINES:
                model.writeColumns(self._props['in_network'], line_rows,
                                   columns, progress)
            elif origin_type == pstalgo.OriginType.JUNCTIONS:
                model.createTable(props['in_network'] + '_junctions',
                                  model.coordinateReferenceSystem(
                                      self._props['in_network']),
                                  columns,
                                  PointGen(junction_coords, model),
                                  int(junction_coords.size() / 2),
                                  progress,
                                  geo_type=GeometryType.POINT)
                pass
            else:
                assert (False)

        finally:
            stack_allocator.restore(initial_alloc_state)
            if graph:
                pstalgo.FreeGraph(graph)

        delegate.setStatus("Attraction Distance done")
        delegate.setProgress(1)
Beispiel #16
0
	def run(self, delegate):

		import pstalgo  # Do it here when it is needed instead of on plugin load
		Vector = pstalgo.Vector

		origins_enabled = self._props['in_origins_enabled']

		radii_list = RadiiFromSettings(pstalgo, self._props).split()

		analysis_count = len(radii_list)

		# Tasks
		class Tasks(object):
			BUILD_GRAPH = 1
			READ_POINTS = 2
			ANALYSIS = 3
			WRITE_RESULTS = 4
		progress = MultiTaskProgressDelegate(delegate)
		progress.addTask(Tasks.BUILD_GRAPH, 1, None)
		if origins_enabled:
			progress.addTask(Tasks.READ_POINTS, 1, "Reading points")
		progress.addTask(Tasks.ANALYSIS, 10*analysis_count, None)

		initial_alloc_state = stack_allocator.state()

		graph = None

		try:
			# Graph
			progress.setCurrentTask(Tasks.BUILD_GRAPH)
			(graph, line_rows, _) = BuildAxialGraph(
				self._model,
				pstalgo,
				stack_allocator,
				self._props['in_network'],
				self._props['in_unlinks'] if self._props['in_unlinks_enabled'] else None,
				None,
				progress)
			line_count = line_rows.size()

			# Origins
			origins = None
			origin_rows = None
			if origins_enabled:
				progress.setCurrentTask(Tasks.READ_POINTS)
				max_origin_count = self._model.rowCount(self._props['in_origins'])
				origin_rows = Vector(ctypes.c_uint, max_origin_count, stack_allocator)
				origins = Vector(ctypes.c_double, max_origin_count*2, stack_allocator)
				self._model.readPoints(self._props['in_origins'], origins, origin_rows, progress)

			# Allocate output arrays
			output_count = origin_rows.size() if origins_enabled else line_count
			reached_count =  Vector(ctypes.c_uint,  output_count, stack_allocator, output_count) if self._props['calc_count']  else None
			reached_length = Vector(ctypes.c_float, output_count, stack_allocator, output_count) if self._props['calc_length'] else None
			reached_area =   Vector(ctypes.c_float, output_count, stack_allocator, output_count) if self._props['calc_area']   else None

			# Radius
			progress.setCurrentTask(Tasks.ANALYSIS)
			analysis_progress = TaskSplitProgressDelegate(analysis_count, "Performing analysis", progress)
			for radii in radii_list:
				# Analysis sub progress
				analysis_sub_progress = MultiTaskProgressDelegate(analysis_progress)
				analysis_sub_progress.addTask(Tasks.ANALYSIS, 1, "Calculating")
				analysis_sub_progress.addTask(Tasks.WRITE_RESULTS, 0, "Writing line results")
				# Analysis
				analysis_sub_progress.setCurrentTask(Tasks.ANALYSIS)
				pstalgo.Reach(
					graph_handle = graph,
					radius = radii,
					origin_points = origins,
					progress_callback = pstalgo.CreateAnalysisDelegateCallbackWrapper(analysis_sub_progress),
					out_reached_count = reached_count,
					out_reached_length = reached_length,
					out_reached_area = reached_area)
				# Area unit conversion
				area_unit = self._props['area_unit']
				if reached_area is not None:
					if area_unit != 'm2':
						factor = {'km2' : 0.000001, 'ha' : 0.0001}[area_unit]
						ptr = reached_area.ptr()
						for i in range(reached_area.size()):
							ptr[i] = ptr[i] * factor

				# Output columns
				columns = []
				if reached_count is not None:
					columns.append((GenColName(ColName.REACH, radii=radii, extra=ColName.EXTRA_NODE_COUNT), 'integer', reached_count.values()))
				if reached_length is not None:
					columns.append((GenColName(ColName.REACH, radii=radii, extra=ColName.EXTRA_LENGTH), 'float', reached_length.values()))
				if reached_area is not None:
					columns.append((GenColName(ColName.REACH, radii=radii, extra=ColName.EXTRA_AREA_CONVEX_HULL, unit=ColNameUnitFromPropAreaUnit(area_unit)), 'float', reached_area.values()))
				# Write
				analysis_sub_progress.setCurrentTask(Tasks.WRITE_RESULTS)
				self._model.writeColumns(
					self._props['in_origins'] if origins_enabled else self._props['in_network'],
					origin_rows if origins_enabled else line_rows,
					columns,
					analysis_sub_progress)
				# Progress
				analysis_progress.nextTask()

		finally:
			stack_allocator.restore(initial_alloc_state)
			if graph:
				pstalgo.FreeGraph(graph)
				graph = None

		delegate.setStatus("Reach done")
		delegate.setProgress(1)
Beispiel #17
0
	def run(self, delegate):
		import pstalgo  # Do it here when it is needed instead of on plugin load
		Vector = pstalgo.Vector
		props = self._props
		model = self._model

		origin_weights_column = props['in_origin_weights']
		network_table = props['in_network']
		destination_weights_column = props['in_destination_weights'] if props['in_destination_weights_enabled'] else None

		destination_mode = {
			"all"     : pstalgo.ODBDestinationMode.ALL_REACHABLE_DESTINATIONS,
			"closest" : pstalgo.ODBDestinationMode.CLOSEST_DESTINATION_ONLY,
		}[props["destination_mode"]]

		distance_type = {
			"walking" : pstalgo.DistanceType.WALKING,
			"angular" : pstalgo.DistanceType.ANGULAR,
		}[props["route_choice"]]

		# Radii
		radii_list = RadiiFromSettings(pstalgo, props).split()  # Only applicable in non-weight mode

		column_suffix =  props['column_suffix'] if props['column_suffix_enabled'] else None

		def GenerateColumnName(distance_type, radii, suffix=None):
			# NOTE: Distance mode will be implicit since it will always be the same as radius type
			name = GenColName(
				analysis = ColName.ODBETWEENNESS,
				pst_distance_type = distance_type,
				radii  = radii)
			if suffix is not None:
				name += '_' + suffix
			return name

		# Number of analyses
		analysis_count = len(radii_list)

		# Tasks
		class Tasks(object):
			READ_ORIGIN_POINTS = 1
			READ_ORIGIN_WEIGHTS = 2
			BUILD_GRAPH = 3
			READ_DESTINATION_WEIGHTS = 4
			ANALYSIS = 5
			WRITE_RESULTS = 6
		progress = MultiTaskProgressDelegate(delegate)
		progress.addTask(Tasks.READ_ORIGIN_POINTS, 1, None)
		progress.addTask(Tasks.READ_ORIGIN_WEIGHTS, 1, None)
		progress.addTask(Tasks.BUILD_GRAPH, 3, None)
		progress.addTask(Tasks.READ_DESTINATION_WEIGHTS, 1, None)
		progress.addTask(Tasks.ANALYSIS, 10*analysis_count, None)
		progress.addTask(Tasks.WRITE_RESULTS, 1, None)

		initial_alloc_state = stack_allocator.state()

		graph_handle = None

		try:
			# Origins
			progress.setCurrentTask(Tasks.READ_ORIGIN_POINTS)
			origins_table = props['in_origins']
			origin_max_count = model.rowCount(origins_table)
			origin_ids = Vector(ctypes.c_longlong, origin_max_count, stack_allocator)
			origin_points = Vector(ctypes.c_double, origin_max_count*2, stack_allocator)
			model.readPoints(origins_table, origin_points, origin_ids, progress)
			progress.setCurrentTask(Tasks.READ_ORIGIN_WEIGHTS)
			origin_weights = Vector(ctypes.c_float, origin_ids.size(), stack_allocator)
			for value in AttractionValueGen(model, origins_table, origin_ids, [origin_weights_column], progress):
				origin_weights.append(value)

			# Graph
			progress.setCurrentTask(Tasks.BUILD_GRAPH)
			destinations_table = props['in_destinations']
			(graph_handle, line_rows, destination_rows) = BuildAxialGraph(
				model,
				pstalgo,
				stack_allocator,
				network_table,
				self._props['in_unlinks'] if self._props['in_unlinks_enabled'] else None,
				destinations_table,
				progress)

			# Destination weights
			if destination_weights_column:
				progress.setCurrentTask(Tasks.READ_DESTINATION_WEIGHTS)
				destination_weights = Vector(ctypes.c_float, destination_rows.size(), stack_allocator)
				for value in AttractionValueGen(model, destinations_table, destination_rows, [destination_weights_column], progress):
					destination_weights.append(value)
			else:
				destination_weights = None

			output_count = line_rows.size()
			output_columns = []

			# Analyses
			progress.setCurrentTask(Tasks.ANALYSIS)
			analysis_progress = TaskSplitProgressDelegate(analysis_count, "Performing analysis", progress)
			for radii in radii_list:
				# Allocate output array
				scores = Vector(ctypes.c_float, output_count, stack_allocator, output_count)
				# Analysis
				pstalgo.ODBetweenness(
					graph_handle = graph_handle, 
					origin_points = origin_points,
					origin_weights = origin_weights,
					destination_weights = destination_weights,
					destination_mode = destination_mode, 
					distance_type = distance_type, 
					radius = radii, 
					progress_callback = pstalgo.CreateAnalysisDelegateCallbackWrapper(analysis_progress), 
					out_scores = scores)
				output_columns.append((GenerateColumnName(distance_type=distance_type, radii=radii, suffix=column_suffix), 'float', scores.values()))
				analysis_progress.nextTask()

			# Write
			progress.setCurrentTask(Tasks.WRITE_RESULTS)
			model.writeColumns(network_table, line_rows, output_columns, progress)

		finally:
			stack_allocator.restore(initial_alloc_state)
			if graph_handle:
				pstalgo.FreeGraph(graph_handle)

		delegate.setStatus("Origin-Destination Betweenness done")
		delegate.setProgress(1)
Beispiel #18
0
    def run(self, delegate):

        import pstalgo  # Do it here when it is needed instead of on plugin load
        Vector = pstalgo.Vector

        junctions_enabled = self._props['output_at_junctions']

        radii_list = RadiiFromSettings(pstalgo, self._props).split()

        # Tasks
        class Tasks(object):
            BUILD_GRAPH = 1
            ANALYSIS = 2
            WRITE_LINE_RESULTS = 3
            WRITE_JUNCTION_RESULTS = 4

        progress = MultiTaskProgressDelegate(delegate)
        progress.addTask(Tasks.BUILD_GRAPH, 1, None)
        progress.addTask(Tasks.ANALYSIS, 2 * len(radii_list), None)

        initial_alloc_state = stack_allocator.state()

        graph = None

        try:
            # Graph
            progress.setCurrentTask(Tasks.BUILD_GRAPH)
            (graph, line_rows, _) = BuildAxialGraph(
                self._model, pstalgo, stack_allocator,
                self._props['in_network'], self._props['in_unlinks']
                if self._props['in_unlinks_enabled'] else None, None, progress)
            line_count = line_rows.size()

            # Allocate output arrays
            scores = Vector(ctypes.c_float, line_count, stack_allocator,
                            line_count)
            total_counts = Vector(
                ctypes.c_uint, line_count, stack_allocator, line_count
            ) if self._props['output_N'] or self._props['output_MD'] else None
            total_depths = Vector(
                ctypes.c_float, line_count, stack_allocator, line_count
            ) if self._props['output_TD'] or self._props['output_MD'] else None

            # Junction output
            junction_count = pstalgo.GetGraphInfo(
                graph).m_CrossingCount if junctions_enabled else 0
            junction_coords = Vector(ctypes.c_double, junction_count *
                                     2, stack_allocator, junction_count *
                                     2) if junctions_enabled else None
            junction_scores = Vector(
                ctypes.c_float, junction_count, stack_allocator,
                junction_count) if junctions_enabled else None

            progress.setCurrentTask(Tasks.ANALYSIS)

            radii_progress = TaskSplitProgressDelegate(len(radii_list),
                                                       "Performing analysis",
                                                       progress)
            for radii in radii_list:

                radii_sub_progress = MultiTaskProgressDelegate(radii_progress)
                radii_sub_progress.addTask(Tasks.ANALYSIS, 3, "Calculating")
                radii_sub_progress.addTask(Tasks.WRITE_LINE_RESULTS, 1,
                                           "Writing line results")
                if junctions_enabled:
                    radii_sub_progress.addTask(Tasks.WRITE_JUNCTION_RESULTS, 1,
                                               "Writing junction results")

                # Analysis
                radii_sub_progress.setCurrentTask(Tasks.ANALYSIS)
                pstalgo.NetworkIntegration(
                    graph_handle=graph,
                    radius=radii,
                    progress_callback=pstalgo.
                    CreateAnalysisDelegateCallbackWrapper(radii_sub_progress),
                    out_junction_coords=junction_coords,
                    out_junction_scores=junction_scores,
                    out_line_integration=scores,
                    out_line_node_count=total_counts,
                    out_line_total_depth=total_depths)

                # Line outputs
                radii_sub_progress.setCurrentTask(Tasks.WRITE_LINE_RESULTS)
                columns = []
                if scores is not None:
                    columns.append(
                        (GenColName(ColName.NETWORK_INTEGRATION,
                                    radii=radii), 'float', scores.values()))
                if total_counts is not None:
                    columns.append(
                        (GenColName(ColName.NETWORK_INTEGRATION,
                                    radii=radii,
                                    extra=ColName.EXTRA_NODE_COUNT), 'integer',
                         total_counts.values()))
                if total_depths is not None:
                    columns.append(
                        (GenColName(ColName.NETWORK_INTEGRATION,
                                    radii=radii,
                                    extra=ColName.EXTRA_TOTAL_DEPTH), 'float',
                         total_depths.values()))
                if self._props['output_MD']:
                    columns.append(
                        (GenColName(ColName.NETWORK_INTEGRATION,
                                    radii=radii,
                                    extra=ColName.EXTRA_MEAN_DEPTH), 'float',
                         MeanDepthGen(total_depths, total_counts)))
                self._model.writeColumns(self._props['in_network'], line_rows,
                                         columns, radii_sub_progress)

                # Junction output
                if junctions_enabled:
                    radii_sub_progress.setCurrentTask(
                        Tasks.WRITE_JUNCTION_RESULTS)
                    columns = []
                    columns.append(
                        (column_base_name, 'float', junction_scores.values()))
                    self._model.createTable(
                        self._props['in_network'] + '_junctions',
                        self._model.coordinateReferenceSystem(
                            self._props['in_network']),
                        columns,
                        PointGen(junction_coords, self._model),
                        junction_count,
                        radii_sub_progress,
                        geo_type=GeometryType.POINT)

                radii_progress.nextTask()

            # Free graph
            pstalgo.FreeGraph(graph)
            graph = None

        finally:
            stack_allocator.restore(initial_alloc_state)
            if graph:
                pstalgo.FreeGraph(graph)
                graph = None

        delegate.setStatus("Network Integration done")
        delegate.setProgress(1)
Beispiel #19
0
    def run(self, delegate):

        import pstalgo  # Do it here when it is needed instead of on plugin load
        Vector = pstalgo.Vector
        props = self._props

        radii_list = RadiiFromSettings(pstalgo, self._props).split()

        # Distance modes
        distance_modes = DistanceTypesFromSettings(pstalgo, props)

        # Weight modes
        class WeightMode(object):
            NONE = 0
            LENGTH = 1

        weight_modes = []
        if props['weight_none']:
            weight_modes.append(WeightMode.NONE)
        if props['weight_length']:
            weight_modes.append(WeightMode.LENGTH)
        if props['weight_data']:
            for name in props['weight_data_cols']:
                weight_modes.append(name)

        def GenerateScoreColumnName(distance_mode, weight, radii, norm):
            if weight == WeightMode.NONE:
                weight = ColName.WEIGHT_NONE
            elif weight == WeightMode.LENGTH:
                weight = ColName.WEIGHT_LENGTH
            return GenColName(ColName.NETWORK_BETWEENNESS,
                              pst_distance_type=distance_mode,
                              weight=weight,
                              radii=radii,
                              normalization=norm)

        def GenerateStatColumnName(stat, distance_mode, radii):
            name = GenColName(ColName.NETWORK_BETWEENNESS,
                              pst_distance_type=distance_mode,
                              radii=radii,
                              extra=stat)
            print(name)
            return name

        # Number of analyses
        analysis_count = len(radii_list) * len(distance_modes) * len(
            weight_modes)

        # Tasks
        class Tasks(object):
            BUILD_GRAPH = 1
            ANALYSIS = 2
            WRITE_RESULTS = 3

        progress = MultiTaskProgressDelegate(delegate)
        progress.addTask(Tasks.BUILD_GRAPH, 1, None)
        progress.addTask(Tasks.ANALYSIS, 5 * analysis_count, None)

        initial_alloc_state = stack_allocator.state()

        graph = None

        try:
            # Graph
            progress.setCurrentTask(Tasks.BUILD_GRAPH)
            (graph, line_rows, _) = BuildAxialGraph(
                self._model, pstalgo, stack_allocator,
                self._props['in_network'], self._props['in_unlinks']
                if self._props['in_unlinks_enabled'] else None, None, progress)
            line_count = line_rows.size()

            # Allocate output arrays
            weights = None
            scores = Vector(ctypes.c_float, line_count, stack_allocator,
                            line_count)
            scores_std = Vector(ctypes.c_float, line_count, stack_allocator,
                                line_count) if props['norm_standard'] else None
            total_counts = Vector(ctypes.c_uint, line_count, stack_allocator,
                                  line_count)
            total_depths = Vector(ctypes.c_float, line_count, stack_allocator,
                                  line_count)

            output_N = (False != props['output_N'])
            output_TD = (False != props['output_TD'])
            output_MD = (False != props['output_MD'])

            progress.setCurrentTask(Tasks.ANALYSIS)
            analysis_progress = TaskSplitProgressDelegate(
                analysis_count, "Performing analysis", progress)
            for weight_mode in weight_modes:

                # Get weights
                if weight_mode == WeightMode.NONE:
                    pass
                elif weight_mode == WeightMode.LENGTH:
                    if weights is None:
                        weights = Vector(ctypes.c_float, line_count,
                                         stack_allocator)
                    weights.resize(line_count)
                    pstalgo.GetGraphLineLengths(graph, weights)
                else:
                    if weights is None:
                        weights = Vector(ctypes.c_float, line_count,
                                         stack_allocator)
                    column_name = weight_mode
                    analysis_progress.setStatus("Reading weight data '%s'" %
                                                column_name)
                    weights.resize(0)
                    self._model.readValues(self._props['in_network'],
                                           column_name, line_rows, weights)

                # These metrics are independent of weight mode, and should therefore only be outputted for first weight mode
                if weight_mode != weight_modes[0]:
                    output_N = False
                    output_TD = False
                    output_MD = False

                for radii in radii_list:

                    for distance_mode in distance_modes:

                        # Analysis sub progress
                        analysis_sub_progress = MultiTaskProgressDelegate(
                            analysis_progress)
                        analysis_sub_progress.addTask(Tasks.ANALYSIS, 3,
                                                      "Calculating")
                        analysis_sub_progress.addTask(Tasks.WRITE_RESULTS, 1,
                                                      "Writing line results")

                        # Analysis
                        analysis_sub_progress.setCurrentTask(Tasks.ANALYSIS)
                        pstalgo.SegmentBetweenness(
                            graph_handle=graph,
                            distance_type=distance_mode,
                            radius=radii,
                            weights=None
                            if weight_mode == WeightMode.NONE else weights,
                            attraction_points=None,
                            progress_callback=pstalgo.
                            CreateAnalysisDelegateCallbackWrapper(
                                analysis_sub_progress),
                            out_betweenness=scores,
                            out_node_count=total_counts,
                            out_total_depth=total_depths)

                        # Output
                        analysis_sub_progress.setCurrentTask(
                            Tasks.WRITE_RESULTS)
                        columns = []
                        # No normalization
                        if props['norm_none']:
                            columns.append((GenerateScoreColumnName(
                                distance_mode, weight_mode, radii,
                                ColName.NORM_NONE), 'float', scores.values()))
                        # Standard normalization
                        if scores_std is not None:
                            pstalgo.StandardNormalize(scores, scores.size(),
                                                      scores_std)
                            columns.append((GenerateScoreColumnName(
                                distance_mode, weight_mode, radii,
                                ColName.NORM_STANDARD), 'float',
                                            scores_std.values()))
                        # Node counts
                        if output_N:
                            columns.append((GenerateStatColumnName(
                                ColName.EXTRA_NODE_COUNT, distance_mode,
                                radii), 'integer', total_counts.values()))
                        # Total depths
                        if output_TD:
                            columns.append((GenerateStatColumnName(
                                ColName.EXTRA_TOTAL_DEPTH, distance_mode,
                                radii), 'float', total_depths.values()))
                        # Mean depths
                        if output_MD:
                            columns.append(
                                (GenerateStatColumnName(
                                    ColName.EXTRA_MEAN_DEPTH, distance_mode,
                                    radii), 'float',
                                 MeanDepthGen(total_depths, total_counts)))

                        # Write
                        self._model.writeColumns(self._props['in_network'],
                                                 line_rows, columns,
                                                 analysis_sub_progress)

                        analysis_progress.nextTask()

        finally:
            stack_allocator.restore(initial_alloc_state)
            if graph:
                pstalgo.FreeGraph(graph)

        delegate.setStatus("Network Betweenness done")
        delegate.setProgress(1)