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_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)
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 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