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)
示例#2
0
    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 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
    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_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.RUSH_HOUR_DELAY
        # 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=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_givenAPointGeojson_then_returnGeojsonFeatures(self):
        inputCoordinatesURL = self.dir + '%digiroad%test%data%geojson%onePoint.geojson'.replace(
            "%", os.sep)
        input2CoordinatesURL = self.dir + '%digiroad%test%data%geojson%anotherPoint.geojson'.replace(
            "%", os.sep)
        outputFolderFeaturesURL = self.dir + '%digiroad%test%data%outputFolderBicycle%'.replace(
            "%", os.sep)
        expectedResultPath = self.dir + '%digiroad%test%data%geojson%shortpathBetweenTwoPoints.geojson'.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 = os.path.basename(
            inputCoordinatesURL) + "_" + os.path.basename(
                input2CoordinatesURL) + "_log."

        Logger.configureLogger(outputFolderFeaturesURL, prefix)

        self.metroAccessDigiroad.calculateTotalTimeTravel(
            startCoordinatesGeojsonFilename=inputCoordinatesURL,
            endCoordinatesGeojsonFilename=input2CoordinatesURL,
            outputFolderPath=outputFolderFeaturesURL,
            costAttribute=distanceCostAttribute)

        inputCoordinatesGeojson = self.fileActions.readJson(
            inputCoordinatesURL)
        expectedResult = self.fileActions.readJson(expectedResultPath)

        if not outputFolderFeaturesURL.endswith(os.sep):
            geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + \
                                           "geoms" + os.sep + \
                                           getEnglishMeaning(CostAttributes.BICYCLE_FAST_TIME) + os.sep
        else:
            geomsOutputFolderFeaturesURL = outputFolderFeaturesURL + "geoms" + os.sep + getEnglishMeaning(
                CostAttributes.BICYCLE_FAST_TIME) + os.sep

        outputFileList = self.readOutputFolderFiles(
            geomsOutputFolderFeaturesURL)

        outputFilename = outputFileList[0]
        outputFilePath = outputFolderFeaturesURL + os.sep + "geoms" + os.sep + getEnglishMeaning(
            CostAttributes.BICYCLE_FAST_TIME) + os.sep + outputFilename

        outputResult = self.fileActions.readJson(outputFilePath)

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

        maxSeq = 0
        for feature in outputResult["features"]:
            maxSeq = max(feature["properties"]["seq"], maxSeq)
            if "id" in feature:
                del feature["id"]

        self.assertEqual(expectedResult, outputResult)
    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")
    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)
示例#10
0
    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)
示例#11
0
def createShortestPathFileWithAdditionalProperties(self,
                                                   costAttribute,
                                                   startPointFeature,
                                                   endPointFeature,
                                                   outputFolderPath,
                                                   summaryFolderPath,
                                                   csv_filename,
                                                   epsgCode,
                                                   endEpsgCode):
    # startTime = time.time()
    # functionName = "createShortestPathFileWithAdditionalProperties"
    # Logger.getInstance().info("%s Start Time: %s" % (functionName, getFormattedDatetime(timemilis=startTime)))

    ####################################
    startVertexId, newStartPointFeature = extractFeatureInformation(
        self=self,
        epsgCode=epsgCode,
        feature=startPointFeature,
        geojsonServiceProvider=self.transportMode,
        operations=self.operations
    )

    startCoordinates = newStartPointFeature["properties"]["selectedPointCoordinates"]
    startPoint = Point(latitute=startCoordinates[1],
                       longitude=startCoordinates[0],
                       epsgCode=self.transportMode.getEPSGCode())

    nearestStartCoordinates = newStartPointFeature["properties"]["nearestVertexCoordinates"]
    nearestStartPoint = Point(latitute=nearestStartCoordinates[1],
                              longitude=nearestStartCoordinates[0],
                              epsgCode=self.transportMode.getEPSGCode())
    ####################################
    endVertexId, newEndPointFeature = extractFeatureInformation(
        self=self,
        epsgCode=endEpsgCode,
        feature=endPointFeature,
        geojsonServiceProvider=self.transportMode,
        operations=self.operations
    )

    endCoordinates = newEndPointFeature["properties"]["selectedPointCoordinates"]
    endPoint = Point(latitute=endCoordinates[1],
                     longitude=endCoordinates[0],
                     epsgCode=self.transportMode.getEPSGCode())

    nearestEndCoordinates = newEndPointFeature["properties"]["nearestVertexCoordinates"]
    nearestEndPoint = Point(latitute=nearestEndCoordinates[1],
                            longitude=nearestEndCoordinates[0],
                            epsgCode=self.transportMode.getEPSGCode())
    ####################################

    if startPoint.equals(endPoint):
        return None, None, None, None

    # shortestPathId = str(startVertexId) + "_" + str(endVertexId)
    # existShortestPath = shortestPathId in self.shortestPathCache
    # if existShortestPath:
    #     shortestPath = self.shortestPathCache[shortestPathId]
    #     Logger.getInstance().info("Shortest path is cached %s " + shortestPathId)
    # else:
    #     shortestPath = self.transportMode.getShortestPath(startVertexId=startVertexId,
    #                                                       endVertexId=endVertexId,
    #                                                       cost=costAttribute)
    #     self.shortestPathCache[shortestPathId] = shortestPath

    # shortestPath = copy.deepcopy(shortestPath)
    ### The above cache procedure is too large that exceed the shared memory.

    shortestPath = self.transportMode.getShortestPath(startVertexId=startVertexId,
                                                      endVertexId=endVertexId,
                                                      cost=costAttribute)

    shortestPath["overallProperties"] = self.insertAdditionalProperties(
        newStartPointFeature,
        newEndPointFeature
    )

    shortestPath["overallProperties"]["selectedStartCoordinates"] = [startPoint.getLongitude(),
                                                                     startPoint.getLatitude()]
    shortestPath["overallProperties"]["selectedEndCoordinates"] = [endPoint.getLongitude(),
                                                                   endPoint.getLatitude()]
    shortestPath["overallProperties"]["nearestStartCoordinates"] = [nearestStartPoint.getLongitude(),
                                                                    nearestStartPoint.getLatitude()]
    shortestPath["overallProperties"]["nearestEndCoordinates"] = [nearestEndPoint.getLongitude(),
                                                                  nearestEndPoint.getLatitude()]

    shortestPath["overallProperties"]["startVertexId"] = startVertexId
    shortestPath["overallProperties"]["endVertexId"] = endVertexId

    if "totalFeatures" not in shortestPath:
        shortestPath["totalFeatures"] = len(shortestPath["features"])

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

    startPointIdentifier = newStartPointFeature["properties"][pointIdentifierKey]
    endPointIdentifier = newEndPointFeature["properties"][pointIdentifierKey]

    filename = "shortestPath"
    extension = "geojson"
    completeFilename = "%s-%s-%s-%s.%s" % (
        filename, getEnglishMeaning(costAttribute), startPointIdentifier, endPointIdentifier, extension)

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

    valueList = [startPointId, endPointId, totalDistance, totalTravelTime]
    self.fileActions.writeInCSV(summaryFolderPath, csv_filename, valueList)

    if "True".__eq__(getConfigurationProperties(section="WFS_CONFIG")["storeShortPathFile"]):
        self.fileActions.writeFile(folderPath=outputFolderPath, filename=completeFilename,
                                   data=shortestPath)

    # endTime = time.time()
    # Logger.getInstance().info("%s End Time: %s" % (functionName, getFormattedDatetime(timemilis=endTime)))
    #
    # totalTime = timeDifference(startTime, endTime)
    # Logger.getInstance().info("%s Total Time: %s m" % (functionName, totalTime))

    return outputFolderPath, completeFilename, summaryFolderPath, csv_filename