class WFSServiceProviderTest(unittest.TestCase): def setUp(self): self.wfsServiceProvider = WFSServiceProvider( wfs_url="http://localhost:9000/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 + '/src/test/data/geojson/testPoints.geojson' self.assertIsNotNone(self.fileActions.readMultiPointJson(dir)) def test_givenAGeoJson_then_attributeDataMustExist(self): dir = self.dir + '/src/test/data/geojson/testPoints.geojson' multiPoints = self.fileActions.readMultiPointJson(dir) self.assertIsNotNone(multiPoints["features"]) def test_givenAGeoJsonWithAttributeData_then_attributeFeaturesMustExist( self): dir = self.dir + '/src/test/data/geojson/testPoints.geojson' multiPoints = self.fileActions.readMultiPointJson(dir) self.assertIsNotNone(multiPoints["features"]) def test_givenAGeoJsonWithPointData_then_FeaturesPointMustExist(self): dir = self.dir + '/src/test/data/geojson/reititinTestPoints.geojson' multiPoints = self.fileActions.readPointJson(dir) self.assertIsNotNone(multiPoints["features"]) def test_givenAnEmptyGeoJson_then_allowed(self): dir = self.dir + '/src/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 + '/src/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( '/src/test/data/geojson/nearestCarRoutingVertexResponseGeoServer.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( '/src/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 + '/src/test/data/geojson/shortestPathResponse.geojson' shortestPathGeojson = self.fileActions.readJson(fileDir) return shortestPathGeojson
class DORARouterAnalyst: 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) enDEpsgCode = self.operations.extractCRSWithGeopandas( endCoordinatesGeojsonFilename) # 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, enDEpsgCode)) 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, enDEpsgCode)) ################################################################################################################ 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
class DORARouterAnalystPrivateCar_WFSServiceTest(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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%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.doraRouterAnalyst.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 + '%src%test%data%geojson%metroAccessDigiroadSummaryResult.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace("%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%onePoint.geojson'.replace("%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%anotherPoint.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace("%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%onePoint.geojson'.replace("%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace("%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToManyCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%onePoint.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace("%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace("%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToManyCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%sampleYKRGridPoints-5.geojson'.replace("%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%sampleYKRGridPoints-13000.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderYKR-5-13000%'.replace("%", os.sep) # expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) # expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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
class DORARouterAnalystBicycle_PostGISServiceTest(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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) inputEndCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) # inputStartCoordinatesURL = self.dir + '%src%test%data%geojson%not-fast-points.geojson'.replace("%", os.sep) # inputEndCoordinatesURL = self.dir + '%src%test%data%geojson%not-fast-points2.geojson'.replace("%", os.sep) # outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderNotFast3%'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%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.doraRouterAnalyst.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 + '%src%test%data%geojson%metroAccessDigiroadSummaryResult-Bicycle.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%shortestPath-fast_time-bicycle.geojson'.replace( "%", os.sep) shortestPath = self.fileActions.readJson(shortestPathFile) startPointId, endPointId, totalDistance, totalTravelTime = self.doraRouterAnalyst.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 + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%anotherPoint.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToManyCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToOneCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%pointsInTheForest.geojson'.replace("%", os.sep) # endInputCoordinatesURL = self.dir + '%src%test%data%geojson%rautatientoriPoint.geojson'.replace("%", os.sep) # startInputCoordinatesURL = self.dir + '%src%test%data%geojson%empty_FROM_points.geojson'.replace("%", os.sep) # endInputCoordinatesURL = self.dir + '%src%test%data%geojson%empty_TO_points.geojson'.replace("%", os.sep) startInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderForest%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToManyCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%destPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%bike_missing_values_coordinates.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderBikeMissingValues%'.replace( "%", os.sep) # startInputCoordinatesURL = self.dir + '%src%test%data%geojson%sampleYKRGridPoints-100.geojson'.replace("%", # os.sep) # endInputCoordinatesURL = self.dir + '%src%test%data%geojson%sampleYKRGridPoints-100.geojson'.replace("%", # os.sep) # outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderYKR-100%'.replace("%", os.sep) # expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) # expectedResult = self.fileActions.readJson(expectedJsonURL) outputFileName = "bikeMissingValues" self.doraRouterAnalyst.createGeneralSummary( startCoordinatesGeojsonFilename=startInputCoordinatesURL, endCoordinatesGeojsonFilename=endInputCoordinatesURL, costAttribute=CostAttributes.DISTANCE, outputFolderPath=outputFolderFeaturesURL, outputFilename=outputFileName) summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep summaryResult = self.fileActions.readJson( summaryOutputFolderFeaturesURL + getEnglishMeaning(CostAttributes.DISTANCE) + "_%s.geojson" % outputFileName) # 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])
class OperationsTest(unittest.TestCase): def setUp(self): self.wfsServiceProvider = WFSServiceProvider(wfs_url="http://localhost:9000/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 + '%src%test%data%geojson%withinPoints.geojson'.replace("%", os.sep) testPointsURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) testPolygonsURL = self.dir + '%src%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 + '%src%test%data%geojson%mergedLayerGeoServer.geojson'.replace("%", os.sep) testPointsURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%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"][0][1], longitude=nearestVertex["features"][0]["geometry"]["coordinates"][0][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"][0][1], longitude=nearestVertex["features"][0]["geometry"]["coordinates"][0][0], epsgCode=epsgCode) self.assertEqual(euclideanDistanceExpected, self.operations.calculateEuclideanDistance(startPoint, endPoint)) def test_transformPoint_to_newCoordinateSystem(self): url = self.dir + '%src%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 + '%src%test%data%outputFolder'.replace("%", os.sep) Logger.configureLogger(outputFolder=outputFolder, prefix="prefix") Logger.getInstance().info("MY LOG")
class DORARouterAnalystPrivateCar_PostGISServiceTest(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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) inputEndCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) # inputStartCoordinatesURL = self.dir + '%src%test%data%geojson%not-fast-points.geojson'.replace("%", os.sep) # inputEndCoordinatesURL = self.dir + '%src%test%data%geojson%not-fast-points2.geojson'.replace("%", os.sep) # outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderNotFast3%'.replace("%", os.sep) outputFolderFeaturesURL = self.dir + '%src%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.doraRouterAnalyst.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 + '%src%test%data%geojson%metroAccessDigiroadSummaryResult.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.createDetailedSummary( outputFolderFeaturesURL, CostAttributes.RUSH_HOUR_DELAY, "metroAccessDigiroadSummary.geojson") summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep summaryResult = self.fileActions.readJson( summaryOutputFolderFeaturesURL + getEnglishMeaning(CostAttributes.RUSH_HOUR_DELAY) + "_metroAccessDigiroadSummary.geojson") self.assertEqual(expectedResult, summaryResult) def test_givenOneStartPointGeojsonAndOneEndPointGeojson_then_createMultiPointSummary( self): startInputCoordinatesURL = self.dir + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%anotherPoint.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%oneToManyCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%onePoint.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolder%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToOneCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%pointsInTheForest.geojson'.replace("%", os.sep) # endInputCoordinatesURL = self.dir + '%src%test%data%geojson%rautatientoriPoint.geojson'.replace("%", os.sep) startInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%reititinTestPoints.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderForest%'.replace( "%", os.sep) expectedJsonURL = self.dir + '%src%test%data%geojson%manyToManyCostSummaryAdditionalInfo.geojson'.replace( "%", os.sep) expectedResult = self.fileActions.readJson(expectedJsonURL) self.doraRouterAnalyst.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 + '%src%test%data%geojson%destPoints.geojson'.replace( "%", os.sep) endInputCoordinatesURL = self.dir + '%src%test%data%geojson%Subsets%subset3%172_Origs_WGS84.geojson'.replace( "%", os.sep) outputFolderFeaturesURL = self.dir + '%src%test%data%outputFolderInstance6%'.replace( "%", os.sep) # expectedJsonURL = self.dir + '%src%test%data%geojson%oneToOneCostSummaryAdditionalInfo.geojson'.replace("%", os.sep) # expectedResult = self.fileActions.readJson(expectedJsonURL) self.generalLogger.getLogger().info( "Start test_givenYKRGridCellPoints_then_createMultiPointSummary") prefix = os.path.basename( startInputCoordinatesURL) + "_" + os.path.basename( endInputCoordinatesURL) Logger.configureLogger(outputFolder=outputFolderFeaturesURL, prefix=prefix) self.doraRouterAnalyst.createGeneralSummary( startCoordinatesGeojsonFilename=startInputCoordinatesURL, endCoordinatesGeojsonFilename=endInputCoordinatesURL, costAttribute=CostAttributes.RUSH_HOUR_DELAY, outputFolderPath=outputFolderFeaturesURL, outputFilename="pt_points_2") summaryOutputFolderFeaturesURL = outputFolderFeaturesURL + os.sep + "summary" + os.sep summaryResult = self.fileActions.readJson( summaryOutputFolderFeaturesURL + getEnglishMeaning(CostAttributes.RUSH_HOUR_DELAY) + "_YKRCostSummary-13000-5.geojson") # self.assertEqual(expectedResult, summaryResult) self.generalLogger.getLogger().info( "End test_givenYKRGridCellPoints_then_createMultiPointSummary") 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])
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 + '/src/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 + '%src%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 + '%src%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 + '%src%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 + '%src%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