class MetropAccessDigiroadTest(unittest.TestCase):
    def setUp(self):
        # self.wfsServiceProvider = WFSServiceProvider(wfs_url="http://*****:*****@unittest.skip("")  # about 13 m for 12 points (132 possible paths)
    def test_givenAMultiPointGeojson_then_returnGeojsonFeatures(self):
        inputStartCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        inputEndCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        # inputStartCoordinatesURL = self.dir + '%digiroad%test%data%geojson%not-fast-points.geojson'.replace("%", os.sep)
        # inputEndCoordinatesURL = self.dir + '%digiroad%test%data%geojson%not-fast-points2.geojson'.replace("%", os.sep)
        # outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderNotFast3%'.replace("%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        # distanceCostAttribute = CostAttributes.BICYCLE_FAST_TIME
        distanceCostAttribute = {
            # "DISTANCE": CostAttributes.DISTANCE,
            "BICYCLE_FAST_TIME": CostAttributes.BICYCLE_FAST_TIME
            # "BICYCLE_SLOW_TIME": CostAttributes.BICYCLE_SLOW_TIME,
        }

        prefix = CostAttributes.BICYCLE_FAST_TIME + "_log."

        Logger.configureLogger(outputFolderFeaturesURL, prefix)
        self.metroAccessDigiroad.calculateTotalTimeTravel(
            startCoordinatesGeojsonFilename=inputStartCoordinatesURL,
            endCoordinatesGeojsonFilename=inputEndCoordinatesURL,
            outputFolderPath=outputFolderFeaturesURL,
            costAttribute=distanceCostAttribute)

        inputCoordinatesGeojson = self.fileActions.readJson(
            inputStartCoordinatesURL)
        for key in distanceCostAttribute:
            if not outputFolderFeaturesURL.endswith(os.sep):
                geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + \
                                               "geoms" + os.sep + getEnglishMeaning(distanceCostAttribute[key]) + os.sep
            else:
                geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + "geoms" + os.sep + getEnglishMeaning(
                    distanceCostAttribute[key]) + os.sep

            outputFileList = self.readOutputFolderFiles(
                geomsOutputFolderFeaturesURL)

            totalCombinatory = len(inputCoordinatesGeojson["features"]) * len(
                inputCoordinatesGeojson["features"]) - len(
                    inputCoordinatesGeojson["features"])
            self.assertEqual(totalCombinatory, len(outputFileList))

    def test_givenAListOfGeojson_then_createSummary(self):
        self.maxDiff = None
        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%metroAccessDigiroadSummaryResult.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)
        self.metroAccessDigiroad.createDetailedSummary(
            outputFolderFeaturesURL, CostAttributes.BICYCLE_FAST_TIME,
            "metroAccessDigiroadSummary.geojson")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_metroAccessDigiroadSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenAShortestPathGeojson_then_calculateTheTotalTravelTime(self):
        shortestPathFile = self.dir + '%digiroad%test%data%geojson%shortestPath-fast_time-bicycle.geojson'.replace(
            "%", os.sep)
        shortestPath = self.fileActions.readJson(shortestPathFile)

        startPointId, endPointId, totalDistance, totalTravelTime = self.metroAccessDigiroad.calculateSmallSummary(
            shortestPath=shortestPath,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME)

        self.assertEqual(0, startPointId)
        self.assertEqual(38, endPointId)
        self.assertEqual(19610.75592183732, totalDistance)
        self.assertEqual(58.30832489071997, totalTravelTime)

    def test_givenOneStartPointGeojsonAndOneEndPointGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%anotherPoint.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="oneToOneCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_oneToOneCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenOneStartPointGeojsonAndManyEndPointsGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToManyCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="oneToManyCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_oneToManyCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenManyStartPointsGeojsonAndOneEndPointGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%manyToOneCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="manyToOneCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_manyToOneCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenManyStartPointsGeojsonAndManyEndPointsGeojson_then_createMultiPointSummary(
            self):
        # startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%pointsInTheForest.geojson'.replace("%", os.sep)
        # endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%rautatientoriPoint.geojson'.replace("%", os.sep)

        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderForest%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%manyToManyCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="manyToManyCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_manyToManyCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    ################################################
    # @unittest.SkipTest
    def test_givenYKRGridCellPoints_then_createMultiPointSummary(self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-13000.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-5.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderBicycleRoadNetwork%'.replace(
            "%", os.sep)

        # startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-100.geojson'.replace("%",
        #                                                                                                           os.sep)
        # endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-100.geojson'.replace("%",
        #                                                                                                             os.sep)
        # outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderYKR-100%'.replace("%", os.sep)

        # expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep)

        # expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.BICYCLE_FAST_TIME,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="BicycleRoadNetwork-13000-5")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) +
            "_BicycleRoadNetwork-13000-5.geojson")

        # self.assertEqual(expectedResult, summaryResult)
        self.assertIsNotNone(summaryResult)

    def readOutputFolderFiles(self, outputFeaturesURL):
        outputFileList = []
        for file in os.listdir(outputFeaturesURL):
            if file.endswith(".geojson"):
                outputFileList.append(file)

        return outputFileList

    def test_parallelism(self):
        with Parallel(n_jobs=2, backend="threading", verbose=5) as parallel:
            accumulator = 0.
            n_iter = 0
            while accumulator < 1000:
                results = parallel(
                    delayed(myDelay)(accumulator + i**2) for i in range(5))
                accumulator += sum(results)  # synchronization barrier
                n_iter += 1
        print(accumulator, n_iter)

    @unittest.SkipTest
    def test_parallelism2(self):
        vertexIDs = multiprocessing.Queue()
        features = multiprocessing.Queue()
        # Setup a list of processes that we want to run
        pool = multiprocessing.Pool(processes=4)
        processes = [
            pool.apply_async(func=mySubprocess, args=(vertexIDs, features, x))
            for x in range(4)
        ]

        # # Run processes
        # for p in processes:
        #     p.start()
        #
        # # Exit the completed processes
        # for p in processes:
        #     p.join()

        # Get process results from the output queue
        # results = [output.get() for p in processes]
        self.assertRaises(RuntimeError, [p.get() for p in processes])
Exemplo n.º 2
0
class PrivateCarTransportModeTest(unittest.TestCase):
    def setUp(self):
        postgisServiceProvider = PostgisServiceProvider()
        self.privateCarTransportMode = PrivateCarTransportMode(
            postgisServiceProvider)
        self.fileActions = FileActions()
        self.operations = Operations(self.fileActions)
        self.dir = os.getcwd()

    def test_givenAPoint_retrieveNearestCarRoutingVertexGeojson(self):
        # point_coordinates = {  # EPSG:3857
        #     "lat": 8443095.452975733,
        #     "lng": 2770620.87667954
        # }
        vertexGeojsonURL = self.dir + '/digiroad/test/data/geojson/nearestCarRoutingVertexResponse.geojson'
        nearestVertexExpectedGeojson = self.fileActions.readJson(
            vertexGeojsonURL)

        coordinates = Point(latitute=6672380.0,
                            longitude=385875.0,
                            epsgCode="EPSG:3047")

        coordinates = self.operations.transformPoint(
            coordinates, self.privateCarTransportMode.getEPSGCode())

        geoJson = self.privateCarTransportMode.getNearestRoutableVertexFromAPoint(
            coordinates)

        for feature in nearestVertexExpectedGeojson["features"]:
            if "id" in feature:
                del feature["id"]

        if "totalFeatures" in geoJson:
            del geoJson["totalFeatures"]

        for feature in geoJson["features"]:
            if "id" in feature:
                del feature["id"]
            if "geometry_name" in feature:
                del feature["geometry_name"]

        self.assertEqual(nearestVertexExpectedGeojson, geoJson)

    def test_givenAPairOfVertex_then_retrieveDijsktraOneToOneCostSummaryGeojson(
            self):
        dir = self.dir + '%digiroad%test%data%geojson%oneToOneCostSummary.geojson'.replace(
            "%", os.sep)

        expectedSummary = self.fileActions.readJson(dir)
        summaryShortestPathCostOneToOne = self.privateCarTransportMode.getTotalShortestPathCostOneToOne(
            startVertexID=59227,
            endVertexID=2692,
            costAttribute=CostAttributes.DISTANCE)
        self.assertEqual(expectedSummary, summaryShortestPathCostOneToOne)

    def test_givenASetOfVertexesVsOneVertex_then_retrieveDijsktraManyToOneCostSummaryGeojson(
            self):
        dir = self.dir + '%digiroad%test%data%geojson%manyToOneCostSummary.geojson'.replace(
            "%", os.sep)

        expectedSummary = self.fileActions.readJson(dir)
        summaryShortestPathCostManyToOne = self.privateCarTransportMode.getTotalShortestPathCostManyToOne(
            startVerticesID=[
                99080, 78618, 45174, 46020, 44823, 110372, 140220, 78317,
                106993, 127209, 33861, 49020
            ],
            endVertexID=99080,
            costAttribute=CostAttributes.DISTANCE)
        self.assertEqual(expectedSummary, summaryShortestPathCostManyToOne)

    def test_givenAVertexVsASetOfVertexes_then_retrieveDijsktraOneToManyCostSummaryGeojson(
            self):
        dir = self.dir + '%digiroad%test%data%geojson%oneToManyCostSummary.geojson'.replace(
            "%", os.sep)

        expectedSummary = self.fileActions.readJson(dir)
        summaryShortestPathCostOneToMany = self.privateCarTransportMode.getTotalShortestPathCostOneToMany(
            startVertexID=99080,
            endVerticesID=[
                99080, 78618, 45174, 46020, 44823, 110372, 140220, 78317,
                106993, 127209, 33861, 49020
            ],
            costAttribute=CostAttributes.DISTANCE)
        self.assertEqual(expectedSummary, summaryShortestPathCostOneToMany)

    def test_givenASetOfVertexesVsASetOfVertexes_then_retrieveDijsktraManyToManyCostSummaryGeojson(
            self):
        dir = self.dir + '%digiroad%test%data%geojson%manyToManyCostSummary.geojson'.replace(
            "%", os.sep)

        expectedSummary = self.fileActions.readJson(dir)
        summaryShortestPathCostManyToMany = self.privateCarTransportMode.getTotalShortestPathCostManyToMany(
            startVerticesID=[
                99080, 78618, 45174, 46020, 44823, 110372, 140220, 78317,
                106993, 127209, 33861, 49020
            ],
            endVerticesID=[
                99080, 78618, 45174, 46020, 44823, 110372, 140220, 78317,
                106993, 127209, 33861, 49020
            ],
            costAttribute=CostAttributes.DISTANCE)
        self.assertEqual(expectedSummary, summaryShortestPathCostManyToMany)

    def test_bucle(self):
        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8]
        expected = [[0, 3], [4, 7], [8, 8]]

        jump = 4
        self.assertEqual(expected, self.getModules(arrayList, jump))

        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        expected = [[0, 3], [4, 7], [8, 9]]

        self.assertEqual(expected, self.getModules(arrayList, jump))

        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        expected = [[0, 3], [4, 7], [8, 10]]

        self.assertEqual(expected, self.getModules(arrayList, jump))

        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        expected = [[0, 3], [4, 7], [8, 11]]

        self.assertEqual(expected, self.getModules(arrayList, jump))

        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
        expected = [[0, 3], [4, 7], [8, 11], [12, 12]]

        self.assertEqual(expected, self.getModules(arrayList, jump))

        arrayList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
        expected = [[0, 2], [3, 5], [6, 8], [9, 11], [12, 12]]
        jump = 3
        self.assertEqual(expected, self.getModules(arrayList, jump))

    def getModules(self, arrayList, jump):
        counter = 0
        intervals = []
        while counter < len(arrayList):
            if counter + jump > len(arrayList):
                jump = len(arrayList) % jump

            intervals.append([counter, counter + jump - 1])
            counter = counter + jump
        print(intervals)
        return intervals
Exemplo n.º 3
0
class MetropAccessDigiroadApplication:
    def __init__(self, transportMode=None):
        self.fileActions = FileActions()
        self.operations = Operations(FileActions())
        self.reflection = Reflection()
        self.transportMode = transportMode
        self.nearestVerticesCache = {}
        self.additionalStartFeaturePropertiesCache = {}
        self.additionalEndFeaturePropertiesCache = {}
        self.shortestPathCache = {}

    @dgl_timer_enabled
    def calculateTotalTimeTravel(self,
                                 startCoordinatesGeojsonFilename=None,
                                 endCoordinatesGeojsonFilename=None,
                                 outputFolderPath=None,
                                 costAttribute=None):
        """
        Given a set of pair points and the ``cost attribute``, calculate the shortest path between each of them and
        store the Shortest Path Geojson file in the ``outputFolderPath``.

        :param wfsServiceProvider: WFS Service Provider data connection
        :param startCoordinatesGeojsonFilename: Geojson file (Geometry type: MultiPoint) containing pair of points.
        :param outputFolderPath: URL to store the shortest path geojson features of each pair of points.
        :param costAttribute: Attribute to calculate the impedance of the Shortest Path algorithm.
        :return: None. Store the information in the ``outputFolderPath``.
        """

        if not self.transportMode:
            raise TransportModeNotDefinedException()
        if not startCoordinatesGeojsonFilename or not outputFolderPath:
            raise NotURLDefinedException()

        if not outputFolderPath.endswith(os.sep):
            summaryFolderPath = outputFolderPath + os.sep + "summary" + os.sep
        else:
            summaryFolderPath = outputFolderPath + "summary" + os.sep

        if isinstance(costAttribute, dict):
            for key in costAttribute:
                newOutputFolderPath = outputFolderPath + os.sep + "geoms" + os.sep + \
                                      getEnglishMeaning(costAttribute[key]) + os.sep
                csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                    endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(costAttribute[key]) + "_costSummary.csv"
                zipCSVFilename = getEnglishMeaning(costAttribute[key]) + "_summary_csv.zip"

                self.fileActions.deleteFolder(path=newOutputFolderPath)
                self.fileActions.deleteFile(summaryFolderPath, csv_filename)
                # self.fileActions.deleteFile(summaryFolderPath, zipCSVFilename)

        else:
            newOutputFolderPath = outputFolderPath + os.sep + "geoms" + os.sep + getEnglishMeaning(
                costAttribute) + os.sep
            csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(
                costAttribute) + "_costSummary.csv"
            zipCSVFilename = getEnglishMeaning(costAttribute) + "_summary_csv.zip"

            self.fileActions.deleteFolder(path=newOutputFolderPath)
            self.fileActions.deleteFile(summaryFolderPath, csv_filename)
            # self.fileActions.deleteFile(summaryFolderPath, zipCSVFilename)

        inputStartCoordinates = self.operations.mergeAdditionalLayers(
            originalJsonURL=startCoordinatesGeojsonFilename,
            outputFolderPath=outputFolderPath
        )

        inputEndCoordinates = self.operations.mergeAdditionalLayers(
            originalJsonURL=endCoordinatesGeojsonFilename,
            outputFolderPath=outputFolderPath
        )

        epsgCode = self.operations.extractCRSWithGeopandas(
            startCoordinatesGeojsonFilename)  # extractCRS(inputStartCoordinates)

        delayedShortedPathCalculations = []

        ################################################################################################################
        for startPointFeature in inputStartCoordinates["features"]:
            # nearestStartPoint, startPoint, startPointEPSGCode, startVertexId = self.featureDataCompilation(
            #     startPointFeature, startCoordinatesGeojsonFilename, epsgCode
            # )


            for endPointFeature in inputEndCoordinates["features"]:
                # nearestEndPoint, endPoint, endPointEPSGCode, endVertexId = self.featureDataCompilation(
                #     endPointFeature, endCoordinatesGeojsonFilename, epsgCode
                # )

                if isinstance(costAttribute, dict):
                    for key in costAttribute:
                        newOutputFolderPath = outputFolderPath + os.sep + "geoms" + os.sep + getEnglishMeaning(
                            costAttribute[key]) + os.sep
                        csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                            endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(
                            costAttribute[key]) + "_costSummary.csv"

                        # self.createShortestPathFileWithAdditionalProperties(costAttribute[key], startVertexId,
                        #                                                     endVertexId,
                        #                                                     startPoint, newStartPointFeature,
                        #                                                     endPoint,
                        #                                                     newEndPointFeature, nearestEndPoint,
                        #                                                     nearestStartPoint,
                        #                                                     newOutputFolderPath, summaryFolderPath,
                        #                                                     csv_filename)

                        delayedShortedPathCalculations.append(
                            delayed(createShortestPathFileWithAdditionalProperties)(
                                self, costAttribute[key],
                                startPointFeature, endPointFeature,
                                newOutputFolderPath, summaryFolderPath,
                                csv_filename,
                                epsgCode
                            )
                        )
                else:
                    csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                        endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(costAttribute) + "_costSummary.csv"

                    # self.createShortestPathFileWithAdditionalProperties(costAttribute, startVertexId, endVertexId,
                    #                                                     startPoint, newStartPointFeature, endPoint,
                    #                                                     newEndPointFeature, nearestEndPoint,
                    #                                                     nearestStartPoint,
                    #                                                     newOutputFolderPath, summaryFolderPath,
                    #                                                     csv_filename)

                    delayedShortedPathCalculations.append(
                        delayed(createShortestPathFileWithAdditionalProperties)(
                            self,
                            costAttribute,
                            startPointFeature, endPointFeature,
                            newOutputFolderPath, summaryFolderPath,
                            csv_filename,
                            epsgCode)
                    )

        ################################################################################################################

        with Parallel(n_jobs=int(getConfigurationProperties(section="PARALLELIZATION")["jobs"]),
                      backend="threading",
                      verbose=int(getConfigurationProperties(section="PARALLELIZATION")["verbose"])) as parallel:
            parallel._print = parallel_job_print
            returns = parallel(tuple(delayedShortedPathCalculations))

        if isinstance(costAttribute, dict):
            for key in costAttribute:
                csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                    endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(costAttribute[key]) + "_costSummary.csv"

                self.storeCSVFile(getEnglishMeaning(costAttribute[key]), outputFolderPath, csv_filename)
        else:
            csv_filename = os.path.basename(startCoordinatesGeojsonFilename) + "_" + os.path.basename(
                endCoordinatesGeojsonFilename) + "_" + getEnglishMeaning(costAttribute) + "_costSummary.csv"

            self.storeCSVFile(getEnglishMeaning(costAttribute), outputFolderPath, csv_filename)

    def storeCSVFile(self, costAttribute, outputFolderPath, csv_filename):
        if not outputFolderPath.endswith(os.sep):
            summaryFolderPath = outputFolderPath + os.sep + "summary" + os.sep
        else:
            summaryFolderPath = outputFolderPath + "summary" + os.sep

        self.fileActions.compressOutputFile(
            folderPath=summaryFolderPath,
            zip_filename=costAttribute + "_summary_csv.zip",
            filepath=summaryFolderPath + os.sep + csv_filename
        )

        debug = False
        if "debug" in getConfigurationProperties(section="WFS_CONFIG"):
            debug = "True".__eq__(getConfigurationProperties(section="WFS_CONFIG")["debug"])

        if not debug:
            # self.fileActions.deleteFile(folderPath=summaryFolderPath, filename=outputFilename + ".geojson")
            self.fileActions.deleteFile(folderPath=summaryFolderPath, filename=csv_filename)

    def insertAdditionalProperties(self, startPointFeature, endPointFeature):
        startFeatureProperties = {}
        endFeatureProperties = {}

        pointIdentifierKey = getConfigurationProperties(section="WFS_CONFIG")["point_identifier"]

        startPointId = startPointFeature["properties"][pointIdentifierKey]
        endPointId = endPointFeature["properties"][pointIdentifierKey]

        existStartFeaturePropertiesCache = startPointId in self.additionalStartFeaturePropertiesCache
        if existStartFeaturePropertiesCache:
            startFeatureProperties = self.additionalStartFeaturePropertiesCache[startPointId]

        existEndFeaturePropertiesCache = endPointId in self.additionalEndFeaturePropertiesCache
        if existEndFeaturePropertiesCache:
            endFeatureProperties = self.additionalEndFeaturePropertiesCache[endPointId]


            # self.additionalFeaturePropertiesCache[newPropertiesId] = newProperties
        if (not existStartFeaturePropertiesCache) or (not existEndFeaturePropertiesCache):
            additionalLayerOperationLinkedList = self.reflection.getLinkedAbstractAdditionalLayerOperation()
            while additionalLayerOperationLinkedList.hasNext():
                additionalLayerOperation = additionalLayerOperationLinkedList.next()

                if not existStartFeaturePropertiesCache:
                    newPropertiesStartPointFeature = additionalLayerOperation.runOperation(
                        featureJson=startPointFeature,
                        prefix="startPoint_")
                    # for property in newPropertiesStartPointFeature:
                    #     startPointFeature["properties"][property] = newPropertiesStartPointFeature[property]
                    #     featureProperties[property] = newPropertiesStartPointFeature[property]
                    startFeatureProperties.update(newPropertiesStartPointFeature)

                if not existEndFeaturePropertiesCache:
                    newPropertiesEndPointFeature = additionalLayerOperation.runOperation(
                        featureJson=endPointFeature,
                        prefix="endPoint_")
                    # for property in newPropertiesEndPointFeature:
                    #     endPointFeature["properties"][property] = newPropertiesEndPointFeature[property]
                    #     featureProperties[property] = newPropertiesEndPointFeature[property]
                    endFeatureProperties.update(newPropertiesEndPointFeature)

        if not existStartFeaturePropertiesCache:
            self.additionalStartFeaturePropertiesCache[startPointId] = copy.deepcopy(startFeatureProperties)

        if not existEndFeaturePropertiesCache:
            self.additionalEndFeaturePropertiesCache[endPointId] = copy.deepcopy(endFeatureProperties)

        # featureProperties = {}
        # if existStartFeaturePropertiesCache:
        #     startFeatureProperties.update(endFeatureProperties)
        #     featureProperties = startFeatureProperties
        # elif existEndFeaturePropertiesCache:
        #     endFeatureProperties.update(startFeatureProperties)
        #     featureProperties = endFeatureProperties
        # else:
        startFeatureProperties.update(endFeatureProperties)
        featureProperties = startFeatureProperties

        return featureProperties

    @dgl_timer_enabled
    def createDetailedSummary(self, folderPath, costAttribute, outputFilename):
        """
        Given a set of Geojson (Geometry type: LineString) files, read all the files from the given ``folderPath`` and
        sum all the attribute values (distance, speed_limit_time, day_avg_delay_time, midday_delay_time and
        rush_hour_delay_time) and create a simple features Geojson (Geometry type: LineString)
        with the summary information.

        :param folderPath: Folder containing the shortest path geojson features.
        :param outputFilename: Filename to give to the summary file.
        :return: None. Store the summary information in the folderPath with the name given in outputFilename.
        """
        Logger.getInstance().info("Start createDetailedSummary for: %s" % costAttribute)

        if not folderPath.endswith(os.sep):
            attributeFolderPath = folderPath + os.sep + "geoms" + os.sep + getEnglishMeaning(costAttribute) + os.sep
            summaryFolderPath = folderPath + os.sep + "summary" + os.sep
        else:
            attributeFolderPath = folderPath + "geoms" + os.sep + getEnglishMeaning(costAttribute) + os.sep
            summaryFolderPath = folderPath + "summary" + os.sep

        totals = {
            "features": [],
            "totalFeatures": 0,
            "type": "FeatureCollection"
        }
        for file in os.listdir(attributeFolderPath):
            if file.endswith(".geojson") and file != "metroAccessDigiroadSummary.geojson":

                filemetadata = file.split("-")
                if len(filemetadata) < 2:
                    Logger.getInstance().info(filemetadata)

                shortestPath = self.fileActions.readJson(url=attributeFolderPath + file)

                if "crs" not in totals:
                    totals["crs"] = shortestPath["crs"]

                newSummaryFeature = {
                    "geometry": {
                        "coordinates": [
                        ],
                        "type": GeometryType.LINE_STRING
                    },
                    "properties": {
                        # "startVertexId": int(filemetadata[2]),
                        # "endVertexId": int(filemetadata[3].replace(".geojson", "")),
                        "costAttribute": filemetadata[1]
                    }
                }

                for property in shortestPath["overallProperties"]:
                    newSummaryFeature["properties"][property] = shortestPath["overallProperties"][property]

                startPoints = None
                endPoints = None
                lastSequence = 1

                for segmentFeature in shortestPath["features"]:
                    for key in segmentFeature["properties"]:
                        if key == "seq":
                            if segmentFeature["properties"][key] == 1:
                                # Sequence one is the first linestring geometry in the path
                                startPoints = segmentFeature["geometry"]["coordinates"]
                            if segmentFeature["properties"][key] > lastSequence:
                                # The last sequence is the last linestring geometry in the path
                                endPoints = segmentFeature["geometry"]["coordinates"]
                                lastSequence = segmentFeature["properties"][key]

                        if key not in ["id", "direction", "seq"]:
                            if key not in newSummaryFeature["properties"]:
                                newSummaryFeature["properties"][key] = 0

                            newSummaryFeature["properties"][key] = newSummaryFeature["properties"][key] + \
                                                                   segmentFeature["properties"][key]

                try:
                    newSummaryFeature["geometry"]["coordinates"] = newSummaryFeature["geometry"]["coordinates"] + \
                                                                   startPoints

                    startAndEndPointAreDifferent = lastSequence > 1
                    if startAndEndPointAreDifferent:
                        newSummaryFeature["geometry"]["coordinates"] = newSummaryFeature["geometry"]["coordinates"] + \
                                                                       endPoints
                    totals["features"].append(newSummaryFeature)
                except Exception as err:
                    Logger.getInstance().exception(err)
                    raise err

        totals["totalFeatures"] = len(totals["features"])
        outputFilename = getEnglishMeaning(costAttribute) + "_" + outputFilename
        self.fileActions.writeFile(folderPath=summaryFolderPath, filename=outputFilename, data=totals)

    @dgl_timer
    def calculateSmallSummary(self, shortestPath, costAttribute):
        """
        Given a Geojson (Geometry type: LineString) files, read all the files from the given ``folderPath`` and
        sum cost attribute and distance values (distance, and any of: speed_limit_time, day_avg_delay_time, midday_delay_time and
        rush_hour_delay_time) and return the sum up of those values.

        :param shortestPath: Shortest path geojson features.
        :param costAttribute: The sum up will be based on the given cost impedance value.
        :return: start point centroid id, end point centroid id, total distance and total travel time.
        """

        Logger.getInstance().info("Start calculateSmallSummary for: %s" % costAttribute)

        pointIdentifierKey = getConfigurationProperties(section="WFS_CONFIG")["point_identifier"]

        startPointId = shortestPath["overallProperties"]["startPoint_" + pointIdentifierKey]
        endPointId = shortestPath["overallProperties"]["endPoint_" + pointIdentifierKey]

        travelTime = 0.0
        distance = 0.0
        for segmentFeature in shortestPath["features"]:
            for key in segmentFeature["properties"]:
                if costAttribute == key:
                    travelTime += segmentFeature["properties"][costAttribute]
                if getEnglishMeaning(CostAttributes.DISTANCE) == key:
                    distance += segmentFeature["properties"][getEnglishMeaning(CostAttributes.DISTANCE)]

        totalDistance = shortestPath["overallProperties"]["startPoint_" + PostfixAttribute.EUCLIDEAN_DISTANCE] + \
                          shortestPath["overallProperties"]["startPoint_" + PostfixAttribute.AVG_WALKING_DISTANCE] + \
                          distance + \
                          shortestPath["overallProperties"]["endPoint_" + PostfixAttribute.AVG_WALKING_DISTANCE] + \
                          shortestPath["overallProperties"]["endPoint_" + PostfixAttribute.EUCLIDEAN_DISTANCE]

        totalTravelTime = shortestPath["overallProperties"]["startPoint_" + PostfixAttribute.EUCLIDEAN_DISTANCE + PostfixAttribute.WALKING_TIME] + \
                          shortestPath["overallProperties"]["startPoint_" + PostfixAttribute.AVG_WALKING_DISTANCE + PostfixAttribute.WALKING_TIME] + \
                          travelTime + \
                          shortestPath["overallProperties"]["endPoint_" + PostfixAttribute.PARKING_TIME] + \
                          shortestPath["overallProperties"]["endPoint_" + PostfixAttribute.AVG_WALKING_DISTANCE + PostfixAttribute.WALKING_TIME] + \
                          shortestPath["overallProperties"]["endPoint_" + PostfixAttribute.EUCLIDEAN_DISTANCE + PostfixAttribute.WALKING_TIME]

        return startPointId, endPointId, totalDistance, totalTravelTime

    @dgl_timer_enabled
    def createGeneralSummary(self, startCoordinatesGeojsonFilename, endCoordinatesGeojsonFilename, costAttribute,
                             outputFolderPath, outputFilename):
        """
        Using the power of pgr_Dijsktra algorithm this function calculate the total routing cost for a pair of set of points.
        It differentiate if must to use one-to-one, one-to-many, many-to-one or many-to-many specific stored procedures from the pgrouting extension.

        :param startCoordinatesGeojsonFilename: Geojson file (Geometry type: MultiPoint) containing pair of points.
        :param outputFolderPath: URL to store the shortest path geojson features of each pair of points.
        :param costAttribute: Attribute to calculate the impedance of the Shortest Path algorithm.
        :param outputFolderPath: Folder containing the shortest path geojson features.
        :param outputFilename: Filename to give to the summary file.
        :return: None. Store the information in the ``outputFolderPath``.
        """
        Logger.getInstance().info("Start createGeneralSummary for: %s" % costAttribute)

        Logger.getInstance().info("Start merge additional layers")
        inputStartCoordinates = self.operations.mergeAdditionalLayers(
            originalJsonURL=startCoordinatesGeojsonFilename,
            outputFolderPath=outputFolderPath
        )

        inputEndCoordinates = self.operations.mergeAdditionalLayers(
            originalJsonURL=endCoordinatesGeojsonFilename,
            outputFolderPath=outputFolderPath
        )
        Logger.getInstance().info("End merge additional layers")

        Logger.getInstance().info("Start nearest vertices finding")
        epsgCode = self.operations.extractCRSWithGeopandas(startCoordinatesGeojsonFilename)
        endEpsgCode = self.operations.extractCRSWithGeopandas(endCoordinatesGeojsonFilename)
        startVerticesID, startPointsFeaturesList = self.getVerticesID(inputStartCoordinates, epsgCode)
        endVerticesID, endPointsFeaturesList = self.getVerticesID(inputEndCoordinates, endEpsgCode)
        Logger.getInstance().info("End nearest vertices finding")

        totals = None

        Logger.getInstance().info("Start cost summary calculation")
        if len(startVerticesID) == 1 and len(endVerticesID) == 1:
            totals = self.transportMode.getTotalShortestPathCostOneToOne(
                startVertexID=startVerticesID[0],
                endVertexID=endVerticesID[0],
                costAttribute=costAttribute
            )
        elif len(startVerticesID) == 1 and len(endVerticesID) > 1:
            totals = self.transportMode.getTotalShortestPathCostOneToMany(
                startVertexID=startVerticesID[0],
                endVerticesID=endVerticesID,
                costAttribute=costAttribute
            )
        elif len(startVerticesID) > 1 and len(endVerticesID) == 1:
            totals = self.transportMode.getTotalShortestPathCostManyToOne(
                startVerticesID=startVerticesID,
                endVertexID=endVerticesID[0],
                costAttribute=costAttribute
            )
        elif len(startVerticesID) > 1 and len(endVerticesID) > 1:
            totals = self.transportMode.getTotalShortestPathCostManyToMany(
                startVerticesID=startVerticesID,
                endVerticesID=endVerticesID,
                costAttribute=costAttribute
            )
        Logger.getInstance().info("End cost summary calculation")

        costSummaryMap = self.createCostSummaryMap(totals)
        # summaryFeature = costSummaryMap[startVertexID][endVertexID]
        # KeyError: 125736

        counterStartPoints = 0
        counterEndPoints = 0

        ################################################################################################################
        # for featureShortPathSummary in totals["features"]:
        #     startVertexID = featureShortPathSummary["properties"]["start_vertex_id"]
        #     endVertexID = featureShortPathSummary["properties"]["end_vertex_id"]
        #     total_cost = featureShortPathSummary["properties"]["total_cost"]
        #     del featureShortPathSummary["properties"]["start_vertex_id"]
        #     del featureShortPathSummary["properties"]["end_vertex_id"]
        #     del featureShortPathSummary["properties"]["total_cost"]
        #
        #     startPointFeature = startPointsFeaturesList[counterStartPoints]
        #     endPointFeature = endPointsFeaturesList[counterEndPoints]
        #
        #     self.createCostSummaryWithAdditionalProperties(costAttribute, endPointFeature, endVertexID,
        #                                                    featureShortPathSummary, startPointFeature,
        #                                                    startVertexID,
        #                                                    total_cost)
        #     counterEndPoints += 1
        #     if counterEndPoints == len(endPointsFeaturesList):
        #         counterStartPoints += 1
        #         counterEndPoints = 0
        ################################################################################################################



        features = []
        ################################################################################################################
        # for startPointFeature in startPointsFeaturesList:
        #     for endPointFeature in endPointsFeaturesList:
        #         newFeature = createCostSummaryWithAdditionalProperties(costAttribute,
        #                                                                     startPointFeature,
        #                                                                     endPointFeature,
        #                                                                     costSummaryMap)
        #         if newFeature:
        #             features.append(newFeature)
        ################################################################################################################

        Logger.getInstance().info("Start createCostSummaryWithAdditionalProperties")
        with Parallel(n_jobs=int(getConfigurationProperties(section="PARALLELIZATION")["jobs"]),
                      backend="threading",
                      verbose=int(getConfigurationProperties(section="PARALLELIZATION")["verbose"])) as parallel:
            # while len(verticesID) <= len(geojson["features"]):
            parallel._print = parallel_job_print
            returns = parallel(delayed(createCostSummaryWithAdditionalProperties)(self,
                                                                                  costAttribute,
                                                                                  copy.deepcopy(startPointFeature),
                                                                                  copy.deepcopy(endPointFeature),
                                                                                  costSummaryMap)
                               for startPointFeature in startPointsFeaturesList
                               for endPointFeature in endPointsFeaturesList)

            for newFeature in returns:
                if newFeature:
                    features.append(newFeature)
                    # print(returns)

        Logger.getInstance().info("End createCostSummaryWithAdditionalProperties")

        ################################################################################################################

        totals["features"] = features
        if not outputFolderPath.endswith(os.sep):
            summaryFolderPath = outputFolderPath + os.sep + "summary" + os.sep
        else:
            summaryFolderPath = outputFolderPath + "summary" + os.sep

        pointIdentifierKey = getConfigurationProperties(section="WFS_CONFIG")["point_identifier"]
        columns = {
            "startPoint_" + pointIdentifierKey: "ykr_from_id",
            "endPoint_" + pointIdentifierKey: "ykr_to_id",
            "total_travel_time": "travel_time"
        }


        filepath = self.fileActions.writeFile(folderPath=summaryFolderPath, filename=outputFilename + ".geojson",
                                              data=totals)
        del totals

        dataframeSummary = self.operations.calculateTravelTimeFromGeojsonFile(
            travelTimeSummaryURL=filepath
        )

        dataframeSummary = self.operations.renameColumnsAndExtractSubSet(
            travelTimeMatrix=dataframeSummary,
            columns=columns
        )

        outputFilename = getEnglishMeaning(costAttribute) + "_" + outputFilename

        csv_separator = getConfigurationProperties(section="WFS_CONFIG")["csv_separator"]
        csv_path = os.path.join(summaryFolderPath, outputFilename + ".csv")

        if not os.path.exists(summaryFolderPath):
            os.makedirs(summaryFolderPath)

        dataframeSummary.to_csv(csv_path, sep=csv_separator, index=False)

        self.fileActions.compressOutputFile(
            folderPath=summaryFolderPath,
            zip_filename="summary.zip",
            filepath=filepath
        )

        self.fileActions.compressOutputFile(
            folderPath=summaryFolderPath,
            zip_filename="summary_csv.zip",
            filepath=csv_path
        )

        debug = False
        if "debug" in getConfigurationProperties(section="WFS_CONFIG"):
            debug = "True".__eq__(getConfigurationProperties(section="WFS_CONFIG")["debug"])

        if not debug:
            self.fileActions.deleteFile(folderPath=summaryFolderPath, filename=outputFilename + ".geojson")
            self.fileActions.deleteFile(folderPath=summaryFolderPath, filename=outputFilename + ".csv")

    @dgl_timer
    def getVerticesID(self, geojson, endEPSGCode):

        verticesID = []
        features = []

        # for feature in geojson["features"]:
        #     vertexID, feature = self.extractFeatureInformation(endEPSGCode, feature)
        #
        #     verticesID.append(vertexID)
        #     features.append(feature)
        with Parallel(n_jobs=int(getConfigurationProperties(section="PARALLELIZATION")["jobs"]),
                      backend="threading",
                      verbose=int(getConfigurationProperties(section="PARALLELIZATION")["verbose"])) as parallel:
            # while len(verticesID) <= len(geojson["features"]):
            parallel._print = parallel_job_print
            returns = parallel(
                delayed(extractFeatureInformation)(self, endEPSGCode, feature, self.transportMode, self.operations)
                for feature in geojson["features"])
            for vertexID, feature in returns:
                verticesID.append(vertexID)
                features.append(feature)
                # print(returns)

        return verticesID, features

    @dgl_timer
    def createCostSummaryMap(self, totals):
        """

        :param totals:
        :return:
        """
        """
            {
                "startId1": {
                    endId1: {feature1},
                    endId2: {feature2}
                }
                "startId2": {
                    endId1: {feature3},
                    endId2: {feature4}
                }
            }
            
        """

        costSummaryMap = {}
        for featureShortPathSummary in totals["features"]:
            startVertexID = featureShortPathSummary["properties"]["start_vertex_id"]
            endVertexID = featureShortPathSummary["properties"]["end_vertex_id"]
            if startVertexID not in costSummaryMap:
                costSummaryMap[startVertexID] = {}

            startVertexMap = costSummaryMap[startVertexID]
            startVertexMap[endVertexID] = featureShortPathSummary

        return costSummaryMap
Exemplo n.º 4
0
class MetropAccessDigiroadTest(unittest.TestCase):
    def setUp(self):
        # self.wfsServiceProvider = WFSServiceProvider(wfs_url="http://*****:*****@unittest.skip("")  # about 13 m for 12 points (132 possible paths)
    def test_givenAMultiPointGeojson_then_returnGeojsonFeatures(self):
        inputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        # distanceCostAttribute = CostAttributes.DISTANCE
        distanceCostAttribute = {
            "DISTANCE": CostAttributes.DISTANCE,
            "SPEED_LIMIT_TIME": CostAttributes.SPEED_LIMIT_TIME,
            "DAY_AVG_DELAY_TIME": CostAttributes.DAY_AVG_DELAY_TIME,
            "MIDDAY_DELAY_TIME": CostAttributes.MIDDAY_DELAY_TIME,
            "RUSH_HOUR_DELAY": CostAttributes.RUSH_HOUR_DELAY
        }
        self.metroAccessDigiroad.calculateTotalTimeTravel(
            startCoordinatesGeojsonFilename=inputCoordinatesURL,
            endCoordinatesGeojsonFilename=inputCoordinatesURL,
            outputFolderPath=outputFolderFeaturesURL,
            costAttribute=distanceCostAttribute)

        inputCoordinatesGeojson = self.fileActions.readJson(
            inputCoordinatesURL)
        for key in distanceCostAttribute:
            if not outputFolderFeaturesURL.endswith(os.sep):
                geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + \
                                               "geoms" + os.sep + getEnglishMeaning(distanceCostAttribute[key]) + os.sep
            else:
                geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + "geoms" + os.sep + getEnglishMeaning(
                    distanceCostAttribute[key]) + os.sep

            outputFileList = self.readOutputFolderFiles(
                geomsOutputFolderFeaturesURL)

            totalCombinatory = len(inputCoordinatesGeojson["features"]) * len(
                inputCoordinatesGeojson["features"]) - len(
                    inputCoordinatesGeojson["features"])
            self.assertEqual(totalCombinatory, len(outputFileList))

    def test_givenAListOfGeojson_then_createSummary(self):
        self.maxDiff = None
        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%metroAccessDigiroadSummaryResult.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)
        self.metroAccessDigiroad.createDetailedSummary(
            outputFolderFeaturesURL, CostAttributes.DISTANCE,
            "metroAccessDigiroadSummary.geojson")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.DISTANCE) +
            "_metroAccessDigiroadSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenOneStartPointGeojsonAndOneEndPointGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%anotherPoint.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.DISTANCE,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="oneToOneCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.DISTANCE) +
            "_oneToOneCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenOneStartPointGeojsonAndManyEndPointsGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToManyCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.DISTANCE,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="oneToManyCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.DISTANCE) +
            "_oneToManyCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenManyStartPointsGeojsonAndOneEndPointGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%manyToOneCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.DISTANCE,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="manyToOneCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.DISTANCE) +
            "_manyToOneCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

    def test_givenManyStartPointsGeojsonAndManyEndPointsGeojson_then_createMultiPointSummary(
            self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace(
            "%", os.sep)

        expectedJsonURL = self.dir + '%digiroad%test%data%geojson%manyToManyCostSummaryAdditionalInfo.geojson'.replace(
            "%", os.sep)

        expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.DISTANCE,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="manyToManyCostSummary")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.DISTANCE) +
            "_manyToManyCostSummary.geojson")

        self.assertEqual(expectedResult, summaryResult)

################################################

    @unittest.SkipTest
    def test_givenYKRGridCellPoints_then_createMultiPointSummary(self):
        startInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-5.geojson'.replace(
            "%", os.sep)
        endInputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%sampleYKRGridPoints-13000.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderYKR-5-13000%'.replace(
            "%", os.sep)

        # expectedJsonURL = self.dir + '%digiroad%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep)

        # expectedResult = self.fileActions.readJson(expectedJsonURL)

        self.metroAccessDigiroad.createGeneralSummary(
            startCoordinatesGeojsonFilename=startInputCoordinatesURL,
            endCoordinatesGeojsonFilename=endInputCoordinatesURL,
            costAttribute=CostAttributes.RUSH_HOUR_DELAY,
            outputFolderPath=outputFolderFeaturesURL,
            outputFilename="YKRCostSummary-5")

        summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep
        summaryResult = self.fileActions.readJson(
            summaryOutputFolderFeaturesURL +
            getEnglishMeaning(CostAttributes.RUSH_HOUR_DELAY) +
            "_YKRCostSummary-5.geojson")

        # self.assertEqual(expectedResult, summaryResult)
        self.assertIsNotNone(summaryResult)

    def readOutputFolderFiles(self, outputFeaturesURL):
        outputFileList = []
        for file in os.listdir(outputFeaturesURL):
            if file.endswith(".geojson"):
                outputFileList.append(file)

        return outputFileList
Exemplo n.º 5
0
class OperationsTest(unittest.TestCase):
    def setUp(self):
        self.wfsServiceProvider = WFSServiceProvider(wfs_url="http://localhost:8080/geoserver/wfs?",
                                                     nearestVertexTypeName="tutorial:dgl_nearest_vertex",
                                                     nearestRoutingVertexTypeName="tutorial:dgl_nearest_car_routable_vertex",
                                                     shortestPathTypeName="tutorial:dgl_shortest_path",
                                                     outputFormat="application/json")
        self.fileActions = FileActions()
        self.operations = Operations(self.fileActions)

        self.dir = os.getcwd()

    def test_givenASetOfPointsAndASetOfPolygons_then_mergeAttributesFromThePolygonToThePointsWithinThePolygon(self):
        withinPointsURL = self.dir + '%digiroad%test%data%geojson%withinPoints.geojson'.replace("%", os.sep)
        testPointsURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep)
        testPolygonsURL = self.dir + '%digiroad%test%data%geojson%helsinki-regions.geojson'.replace("%", os.sep)

        expectedWithinPoints = self.fileActions.readJson(withinPointsURL)

        withinPoints = self.operations.mergeWithinPointsDataWithPolygonsAttributes(testPointsURL,
                                                                                   testPolygonsURL,
                                                                                   "walking_distance",
                                                                                   "parking_time")

        self.assertEqual(expectedWithinPoints, withinPoints)

    def test_givenASetOfPoints_then_mergeAllTheMergeableLayersWithTheOriginalPoints(self):
        expectedMergedLayerURL = self.dir + '%digiroad%test%data%geojson%mergedLayer.geojson'.replace("%", os.sep)
        testPointsURL = self.dir + '%digiroad%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolder%'.replace("%", os.sep)

        mergedLayer = self.operations.mergeAdditionalLayers(originalJsonURL=testPointsURL,
                                                            outputFolderPath=outputFolderFeaturesURL)

        expectedMergedLayer = self.fileActions.readJson(expectedMergedLayerURL)
        self.assertEqual(expectedMergedLayer, mergedLayer)

    def test_calculateEuclideanDistanceToTheNearestVertex(self):
        euclideanDistanceExpected = 54.918796781644275  # 307.99402311696525  # meters
        startPoint = {
            "lat": 6672380.0,
            "lng": 385875.0,
            "crs": "EPSG:3047"
        }
        startPoint = Point(latitute=startPoint["lat"],
                           longitude=startPoint["lng"],
                           epsgCode="EPSG:3047")
        newStartPoint = self.operations.transformPoint(startPoint, targetEPSGCode=self.wfsServiceProvider.getEPSGCode())

        nearestVertex = self.wfsServiceProvider.getNearestRoutableVertexFromAPoint(newStartPoint)
        epsgCode = nearestVertex["crs"]["properties"]["name"].split(":")[-3] + ":" + \
                   nearestVertex["crs"]["properties"]["name"].split(":")[-1]

        # endPoint = {
        #     "lat": nearestVertex["features"][0]["geometry"]["coordinates"][0][1],
        #     "lng": nearestVertex["features"][0]["geometry"]["coordinates"][0][0],
        #     "crs": epsgCode
        # }

        endPoint = Point(latitute=nearestVertex["features"][0]["geometry"]["coordinates"][1],
                         longitude=nearestVertex["features"][0]["geometry"]["coordinates"][0],
                         epsgCode=epsgCode)

        self.assertEqual(euclideanDistanceExpected,
                         self.operations.calculateEuclideanDistance(newStartPoint, endPoint))

    def test_givenAPoint_retrieveEuclideanDistanceToTheNearestVertex(self):
        euclideanDistanceExpected = 1.4044170756169843  # meters
        # startPoint = {
        #     "lat": 8443095.452975733,
        #     "lng": 2770620.87667954,
        #     "crs": "EPSG:3857"
        # }
        startPoint = Point(latitute=8443095.452975733,
                           longitude=2770620.87667954,
                           epsgCode="EPSG:3857")

        nearestVertex = self.wfsServiceProvider.getNearestRoutableVertexFromAPoint(startPoint)
        epsgCode = nearestVertex["crs"]["properties"]["name"].split(":")[-3] + ":" + \
                   nearestVertex["crs"]["properties"]["name"].split(":")[-1]

        # endPoint = {
        #     "lat": nearestVertex["features"][0]["geometry"]["coordinates"][0][1],
        #     "lng": nearestVertex["features"][0]["geometry"]["coordinates"][0][0],
        #     "crs": epsgCode
        # }

        endPoint = Point(latitute=nearestVertex["features"][0]["geometry"]["coordinates"][1],
                         longitude=nearestVertex["features"][0]["geometry"]["coordinates"][0],
                         epsgCode=epsgCode)

        self.assertEqual(euclideanDistanceExpected,
                         self.operations.calculateEuclideanDistance(startPoint, endPoint))

    def test_transformPoint_to_newCoordinateSystem(self):
        url = self.dir + '%digiroad%test%data%geojson%Subsets%1_Origs_WGS84.geojson'.replace("%", os.sep)
        epsgCode = self.operations.extractCRSWithGeopandas(url)
        print(epsgCode)
        self.assertEqual("epsg:4326", epsgCode)

    def test_logger(self):
        outputFolder = self.dir + '%digiroad%test%data%outputFolder'.replace("%", os.sep)

        Logger.configureLogger(outputFolder=outputFolder,
                               prefix="prefix")

        Logger.getInstance().info("MY LOG")
Exemplo n.º 6
0
class WFSServiceProviderTest(unittest.TestCase):
    def setUp(self):
        self.wfsServiceProvider = WFSServiceProvider(
            wfs_url="http://localhost:8080/geoserver/wfs?",
            nearestVertexTypeName="tutorial:dgl_nearest_vertex",
            nearestRoutingVertexTypeName=
            "tutorial:dgl_nearest_car_routable_vertex",
            shortestPathTypeName="tutorial:dgl_shortest_path",
            outputFormat="application/json")
        self.fileActions = FileActions()
        self.operations = Operations(self.fileActions)
        self.dir = os.getcwd()

    def test_givenA_URL_then_returnJsonObject(self):
        dir = self.dir + '/digiroad/test/data/geojson/testPoints.geojson'
        self.assertIsNotNone(self.fileActions.readMultiPointJson(dir))

    def test_givenAGeoJson_then_attributeDataMustExist(self):
        dir = self.dir + '/digiroad/test/data/geojson/testPoints.geojson'
        multiPoints = self.fileActions.readMultiPointJson(dir)
        self.assertIsNotNone(multiPoints["features"])

    def test_givenAGeoJsonWithAttributeData_then_attributeFeaturesMustExist(
            self):
        dir = self.dir + '/digiroad/test/data/geojson/testPoints.geojson'
        multiPoints = self.fileActions.readMultiPointJson(dir)
        self.assertIsNotNone(multiPoints["features"])

    def test_givenAGeoJsonWithPointData_then_FeaturesPointMustExist(self):
        dir = self.dir + '/digiroad/test/data/geojson/reititinTestPoints.geojson'
        multiPoints = self.fileActions.readPointJson(dir)
        self.assertIsNotNone(multiPoints["features"])

    def test_givenAnEmptyGeoJson_then_allowed(self):
        dir = self.dir + '/digiroad/test/data/geojson/testEmpty.geojson'
        multiPoints = self.fileActions.readMultiPointJson(dir)
        self.assertEquals(0, len(multiPoints["features"]))

    def test_eachFeatureMustBeMultiPointType_IfNot_then_throwNotMultiPointGeometryError(
            self):
        dir = self.dir + '/digiroad/test/data/geojson/testNotMultiPointGeometry.geojson'
        self.assertRaises(IncorrectGeometryTypeException,
                          self.fileActions.readMultiPointJson, dir)

    def test_givenAPairOfPoints_retrieveSomething(self):
        # point_coordinates = {
        #     "lat": 60.1836272547957,
        #     "lng": 24.929379456878265
        # }
        coordinates = Point(latitute=60.1836272547957,
                            longitude=24.929379456878265,
                            epsgCode="EPSG:4326")

        self.assertIsNotNone(
            self.wfsServiceProvider.getNearestRoutableVertexFromAPoint(
                coordinates))

    def test_givenAPoint_retrieveNearestCarRoutingVertexGeojson(self):
        # point_coordinates = {  # EPSG:3857
        #     "lat": 8443095.452975733,
        #     "lng": 2770620.87667954
        # }

        # coordinates = Point(latitute=8443095.452975733,
        #                     longitude=2770620.87667954,
        #                     epsgCode="EPSG:3857")

        coordinates = Point(latitute=6672380.0,
                            longitude=385875.0,
                            epsgCode="EPSG:3047")

        nearestVertexExpectedGeojson = self.readGeojsonExpectedResponse(
            '/digiroad/test/data/geojson/nearestCarRoutingVertexResponse.geojson'
        )

        coordinates = self.operations.transformPoint(
            coordinates, self.wfsServiceProvider.getEPSGCode())

        geoJson = self.wfsServiceProvider.getNearestRoutableVertexFromAPoint(
            coordinates)

        for feature in nearestVertexExpectedGeojson["features"]:
            if "id" in feature:
                del feature["id"]

        if "totalFeatures" in geoJson:
            del geoJson["totalFeatures"]

        for feature in geoJson["features"]:
            if "id" in feature:
                del feature["id"]
            if "geometry_name" in feature:
                del feature["geometry_name"]

        self.assertEqual(nearestVertexExpectedGeojson, geoJson)

    def test_givenAPoint_retrieveNearestVertexGeojson(self):
        # point_coordinates = {  # EPSG:3857
        #     "lat": 8443095.452975733,
        #     "lng": 2770620.87667954
        # }

        coordinates = Point(latitute=8443095.452975733,
                            longitude=2770620.87667954,
                            epsgCode="EPSG:3857")

        nearestVertexExpectedGeojson = self.readGeojsonExpectedResponse(
            '/digiroad/test/data/geojson/nearestVertextResponse.geojson')

        self.assertEqual(
            nearestVertexExpectedGeojson,
            self.wfsServiceProvider.getNearestVertexFromAPoint(coordinates))

    def test_givenAPairOfPoints_then_retrieveTheShortestPath(self):
        self.maxDiff = None

        shortestPathGeojson = self.readShortestPathGeojsonExpectedResponse()
        for feature in shortestPathGeojson["features"]:
            if "id" in feature:
                del feature["id"]
            if "geometry_name" in feature:
                del feature["geometry_name"]

        shortestPathResult = self.wfsServiceProvider.getShortestPath(
            startVertexId=106290,
            endVertexId=96275,
            cost=CostAttributes.DISTANCE)
        for feature in shortestPathResult["features"]:
            if "id" in feature:
                del feature["id"]
            if "geometry_name" in feature:
                del feature["geometry_name"]

        self.assertDictEqual(shortestPathGeojson, shortestPathResult)

    def readGeojsonExpectedResponse(self, geojsonPath):

        fileDir = self.dir + geojsonPath
        nearestVertexGeojson = self.fileActions.readJson(fileDir)
        return nearestVertexGeojson

    def readShortestPathGeojsonExpectedResponse(self):
        fileDir = self.dir + '/digiroad/test/data/geojson/shortestPathResponse.geojson'
        shortestPathGeojson = self.fileActions.readJson(fileDir)
        return shortestPathGeojson