Пример #1
0
def qVerify_line(sK_code, ccTremb):
    """
    Method checks the database for the existance of the K-code header. It then
    returns the route name details.
    """
    # Access database
    cLine = db.lines(ccTremb)

    # Verify that the database exists:
    cLine = db.lines(ccTremb)
    xParam = {"my_id": sK_code, "tag": "meta"}
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)

    # Extract the data
    dMeta = ""
    for query in dQuery:
        dMeta = query  # Save data for further processing

    if dMeta == "":
        print("\n\aLine {0} couldn't be found".format(sK_code))
        return None

    sTxt = "Route [{0}], Named '{1}'"
    sTxt = sTxt.format(dMeta["dVal"]["route_no"], dMeta["dVal"]["sRoute_name"])
    return sTxt
Пример #2
0
def pretty_print_all(ccTremb):
    """ Writes to a file the full line, ordered by km"""

    import datetime

    sTxt = "\nEnter the line identifier ('K00-001') to be printed"
    print(sTxt)
    sK_code = input().upper()

    # Verify the existance of the route
    sRte_det = qVerify_line(sK_code, ccTremb)
    if sRte_det == None: return None  # Error condition

    # Extract the full data
    cLine = db.lines(ccTremb)
    xParam = {"my_id": sK_code, "tag": "val"}
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)
    dQuery.sort("dVal.km")

    # Extract the data
    dData = []
    for query in dQuery:
        dData.append(query)  # Save data for further processing

    sFile_path = "Logs/{0}_full.txt".format(sK_code)
    eSingle_data = open(sFile_path, "w", encoding="utf-8")

    sAll = ""  # All data in a single string.
    # Write the title:
    xNow = datetime.datetime.now()

    sTxt = "Pretty print information for was generated on {0}\n".format(xNow)
    sAll += sTxt
    sAll += sRte_det + "\n"  # Populated by the route verification function

    for dItem in dData:
        sTxt = "{0:7.2f}km ".format(dItem["dVal"]["km"])
        sTxt += "[id:{0:>4}] ".format(dItem["dVal"]["id"])
        sTxt += "{0}: ".format(dItem["dVal"]["item"]).upper()
        sTxt += "{0} ".format(dItem["dVal"]["type"])
        sTxt += " --> {0}".format(dItem["dVal"]["xVal"])

        sAll += sTxt + "\n"

# Write the data to the file
    eSingle_data.write("{0}\n".format(sAll))
    eSingle_data.close()
Пример #3
0
def pretty_print_meta(ccTremb):
    """ Writes elements of the meta-data entry to a file """

    import datetime

    sTxt = "\nEnter the line identifier ('K00-001') to be printed"
    print(sTxt)
    sK_code = input().upper()

    # Access database
    cLine = db.lines(ccTremb)
    xParam = {"my_id": sK_code, "tag": "meta"}
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)

    # Extract the data
    dData = ""
    for query in dQuery:
        dData = query  # Save data for further processing

    if dData == "":
        print("\n\aNo information available")
        return None

    sFile_path = "Logs/{0}_meta.txt".format(sK_code)
    eSingle_data = open(sFile_path, "w", encoding="utf-8")

    sAll = ""  # All data in a single string.
    # Write the title:
    xNow = datetime.datetime.now()

    sTxt = "Pretty print information was generated on {0}\n".format(xNow)
    sAll += sTxt

    sAll += "METADATA:\n"
    dVal = dData["dVal"]
    sAll += ">   Host Geo-code: '{0}'\n".format(dVal["host_geo_code"])
    sAll += ">   Route number:  '{0}'\n".format(dVal["route_no"])
    sAll += ">   Route name:    '{0}'\n".format(dVal["sRoute_name"])
    sAll += ">   Type of line:  '{0}'\n".format(dVal["type"])
    sAll += ">   Starting point:'{0}'\n".format(dVal["start"])
    sAll += ">   Ending point:  '{0}'\n".format(dVal["end"])
    print(dData)

    # Write the data to the file
    eSingle_data.write("{0}\n".format(sAll))
    eSingle_data.close()
Пример #4
0
def remove_sub_comp(ccTremb):
    """ Method prompts the user for data and returns distance on the map for the
        approach to the structure.
    """
    # Request the line identifier
    sTxt = ("You are about to remove a component from a line.\nPlease enter " +
            "the K-code ('K00-001' for example) of the line\n")
    print(sTxt)
    sK_code = input().upper()

    # Verify the line number
    sRte_det = qVerify_line(sK_code, ccTremb)
    if sRte_det == None: return None

    # Ask for the identifier mark
    sTxt = ("Please enter the item identifier (id: 39 for example) as an " +
            "integer")
    iId_req = misc.get_int(sTxt)
    if iId_req == None: return None

    # Pull up the data you are about to delete:
    xParam = {"my_id": sK_code, "dVal.id": iId_req}
    xRestr = {"_id": 0, "dVal": 1}
    cDatabase = db.lines(ccTremb)
    dQuery = cDatabase.find(xParam, xRestr)

    dElement = []
    for query in dQuery:
        dElement.append(query)

    print("\n-----------------------------")
    sTxt = ("You are about to remove\n\n{0}\n\nfrom {1}\n\n" +
            "Do you want to procceed?")
    sTxt = sTxt.format(dElement[0], sRte_det)
    yn_remove = misc.get_binary(sTxt)
    if yn_remove == None: return None
    if yn_remove == "N":
        print("\n\aAborting removal")
        return None

    # Remove the item
    xParam = {"my_id": sK_code, "dVal.id": iId_req}
    xRestr = {}
    dQuery = cDatabase.delete_one(xParam, xRestr)
    print("Specified element deleted")
Пример #5
0
def calc_timetable(ccTremb):
    """ This method calculates the approximate time for the train to travel
    between the two specified points.
    """
# Open the 'lines' database.
    cLines = db.lines(ccTremb)
    cDest = db.destinations(ccTremb)
    sLine = "K00-001"

# Obtain the travel durations.
    dSta_jct = calc_pax(cLines, sLine)
    if dSta_jct == None: return None
    if len(dSta_jct) < 1: return None

# Process the array
    aKeys = dSta_jct[0].keys()
    sAll = ""
    sSep = ";"
    sAll += "km{0}type{0}code{0}name{0}s away{0}s home\n".format(sSep)

    for item in dSta_jct:
        fKm = item["km"]
        sType = item["type"]
        code = item["code"]
        sLat = " "
        if sType == "sta" and code != None:
            aNames = misc.verify_geo_code(code, cDest, bDont_warn=True)
            if aNames != None:
                sLat = aNames["lat"]

        away = item["away"]
        home = item["home"]

        sTxt = "{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}\n"
        sTxt = sTxt.format(sSep, fKm, sType, code, sLat, away, home)
        sAll += sTxt

# Write this data to a .csv file (to be used with excel)
    sFile_path = "Logs/travel_{0}.csv".format(sLine)
    eTravel = open(sFile_path, "w", encoding="utf-8")
    eTravel.write(sAll)
    eTravel.close()
    print("Please see {0}".format(sFile_path))
    return True
Пример #6
0
def sub_menu():
    """ Provides lines """

    ccTremb = db.connect()
    cLine = db.lines(ccTremb)
    sSub_menu = """
LINES SUB-MENU (K):
.: Exit
1: Open New line (Record its meta-data)
3: Pretty print one line (ordered by distance)
4: Pretty print meta data to a file
5: Add to line (Sub-component as a new entry)
6: Do a gradient (elevation change) report
C: Calculate distance on map for gradient
_: Remove a sub-component from the line
    """
    # Go through the menu system.
    bExit = False
    while bExit == False:  # loop until the user exits
        print(sSub_menu)
        sInput = input().upper()

        # Analise the user choice
        if sInput == ".":  # Exit
            bExit = True
        elif sInput == "1":  # Open new line
            add_line(ccTremb)
        elif sInput == "3":  # Prints the line ordered by km.
            pretty_print_all(ccTremb)
        elif sInput == "4":  # Meta-data view
            pretty_print_meta(ccTremb)
        elif sInput == "5":  # New component of a line
            add_sub_comp(ccTremb)
        elif sInput == "6":
            pretty_gradient(ccTremb)
        elif sInput == "C":
            design_gradient(ccTremb)
        elif sInput == "_":
            remove_sub_comp(ccTremb)
Пример #7
0
def mm_star():
    """ Tests a concept (This is a scratch pad, or a place to fix mistakes) """
    import modules.x_database as db
    # Delete a single entry
    if False:
        xParam = {"dVal.id": 115}
        xRestr = {}
        ccTremb = db.connect()
        cDatabase = db.lines(ccTremb)
        dQuery = cDatabase.delete_one(xParam, xRestr)
        print("Specified element deleted")

    # Delete an entire collection
    if False:
        ccTremb = db.connect()
        cRnd_man = db.rnd_suffix_surname(ccTremb)
        dQuery = cRnd_man.delete_many({})
        print(dQuery.deleted_count, " deleted items!")

    # Update an array
    if False:
        xParam = {"geo_code": "TJV"}  # Vaenesston district
        xNew_data = {
            "$set": {
                "aChildren": [
                    "D00-09I",
                    "D00-09J",
                    "D00-0CM",
                    "D00-0CN",
                    "D00-0CO",
                ]
            }
        }  # Prepare the update

        ccTremb = db.connect()
        cDest = db.destinations(ccTremb)
        dParent_query = cDest.update_one(xParam, xNew_data)

    # Update a bad complex value
    if False:
        dNew_data = {
            'resource': 'chicken',
            'annual_output': 15356,
            'units': 't/yr'
        }

        xParam = {"my_id": "D00-017"}
        xNew_data = {"$set": {"aWarehouse.chicken farm 0": dNew_data}}

        ccTremb = db.connect()
        cDb = db.destinations(ccTremb)
        dQuery = cDb.update_one(xParam, xNew_data)

    # Delete all the geo-codes
    if False:
        parent_my_id = "D00-0AL"  # Edit me.

        # Data base connection and selection
        ccTremb = db.connect()
        cDb = db.destinations(ccTremb)

        # Get the parent so we can access the children
        xParam = {"my_id": parent_my_id}
        xRestr = {"_id": 0, "aChildren": 1}
        dQuery = cDb.find(xParam, xRestr)

        # Analyse the query
        aChildren = []
        for query in dQuery:
            aChildren = query["aChildren"]  # copy out

        # Erase each child's geo-code
        for child in aChildren:
            xParam = {"my_id": child}
            xNew_data = {"$set": {"geo_code": None}}
            dQuery = cDb.update_one(xParam, xNew_data)

    # Global change to the structure
    if False:
        dNew_data = {
            "total": {
                "rm": 0,
                "rf": 0,
                "hm": 0,
                "hf": 0,
                "mm": 0,
                "mf": 0,
                "lm": 0,
                "lf": 0,
                "pm": 0,
                "pf": 0
            },
            "aItemised": [],
        }

        xParam = {}
        xNew_data = {"$set": {"aSupply_workforce": dNew_data}}

        ccTremb = db.connect()
        cDb = db.destinations(ccTremb)
        dQuery = cDb.update_many(xParam, xNew_data)

    # Update a bad simple value
    if False:
        dNew_data = "Fusþton"

        xParam = {'sRegion': 'Loggers Crossing'}
        #        xNew_data = {"$set": {"aVehicles.aItemised.Blàhim" : dNew_data}}
        xNew_data = {"$set": {'sRegion': dNew_data}}

        ccTremb = db.connect()
        cDb = db.maps_db(ccTremb)
        dQuery = cDb.update_one(xParam, xNew_data)
    #    dQuery = cDb.update_many(xParam, xNew_data)

    # delete an element
    if False:
        xParam = {"geo_code": "GYG"}
        xNew_data = {"$unset": {"aDemogfx_item": 0, "aWhs_item": 0}}

        ccTremb = db.connect()
        cDb = db.destinations(ccTremb)
        dQuery = cDb.update_one(xParam, xNew_data)

    # Oblitorate everything except the name, children, area data.
    # Basically, erase balancing when it was not required.
    if False:
        xParam = {"geo_code": "VXA-J"}  # Vaenesston district
        xNew_data = {
            "$set": {
                #            'aMap': {
                #                'sRegion': 'Vænesston',
                #                'iYear': '2019',
                #                'fScale': 2000000.0,
                #                'x': None,'y': None,'a': None},
                "aDemand_workforce": {
                    "total": {
                        "rm": 0,
                        "rf": 0,
                        "hm": 0,
                        "hf": 0,
                        "mm": 0,
                        "mf": 0,
                        "lm": 0,
                        "lf": 0,
                        "pm": 0,
                        "pf": 0
                    },
                    "aItemised": []
                },
                "aSupply_workforce": {
                    "total": {
                        "rm": 0,
                        "rf": 0,
                        "hm": 0,
                        "hf": 0,
                        "mm": 0,
                        "mf": 0,
                        "lm": 0,
                        "lf": 0,
                        "pm": 0,
                        "pf": 0
                    },
                    "aItemised": []
                },
                "aDemand_hholds": {
                    "total": {
                        "r": 0,
                        "h": 0,
                        "m": 0,
                        "l": 0,
                        "p": 0
                    },
                    "aItemised": []
                },
                "aSupply_hholds": {
                    "total": {
                        "r": 0,
                        "h": 0,
                        "m": 0,
                        "l": 0,
                        "p": 0
                    },
                    "aItemised": []
                },
                "aDemographics": {},
                "aVehicles": {},
                "aFootprint": {},
                "aWarehouse": {}
            }
        }  # Prepare the update

        ccTremb = db.connect()
        cDest = db.destinations(ccTremb)
        dParent_query = cDest.update_one(xParam, xNew_data)
Пример #8
0
def qLine_gradient(sK_code, ccTremb):
    """ Method takes in the 'K-code' (K00-001) for Vænesston - Fusþton Line.
    It then extracts the elevation information and computes the grade of the
    track.
    """
    # Access database
    cLine = db.lines(ccTremb)

    # K-CODE EXISTS?:
    cLine = db.lines(ccTremb)
    xParam = {"my_id": sK_code, "tag": "meta"}
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)

    # Extract the data
    dMeta = ""
    for query in dQuery:
        dMeta = query  # Save data for further processing

    if dMeta == "":
        print("\n\aLine does not exist")
        return None

# EXTRACT THE DATA
    xParam = {
        "my_id": sK_code,  # Only this line
        "tag": "val",  # Only true data
        "dVal.item": "elev_ft"  # Only elevation data.
    }
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)
    dQuery.sort("dVal.km")

    # Extract the data
    dRaw = []
    for query in dQuery:
        dRaw.append(query)  # Save data for further processing

    # my_id and tag have been assured by the database query. extract the
    # 'interesting' stuff.
    dData = []
    for item in dRaw:
        dItem = {
            "km": item["dVal"]["km"],
            "type": item["dVal"]["type"],
            "elev_ft": item["dVal"]["xVal"]
        }
        dData.append(dItem)

    # misc.write_debug_txt(dData)         # See what we found

    # Prepare for calculation:
    dGradient = []
    iNo_of_items = len(dData)  # Working in pairs of values.

    # TERRAIN:
    for iCnt in range(1, iNo_of_items):
        # Process the spot elevation first.
        if dData[iCnt]["type"] != "spot":  # spot elevation, not trapezoidal
            continue  # Loop to the next iteration.

    # LOOK FOR THE PREVIOUS 'SPOT' HEIGHT.
    # We are a spot. Lets look back to find the previous spot.
        iPrev_spot_idx = None  # Either next or 5 back... read on

        # There could be a bridge or tunnel behind us. Also, there could be
        # an error in its entry. At this stage, we don't care. We just want
        # to find the last spot height.
        for iIdx in range(iCnt - 1, -1, -1):  # Go backwards
            if dData[iIdx]["type"] == "spot":
                iPrev_spot_idx = iIdx
                break

        if iPrev_spot_idx == None:
            print("\n\aERROR: Unable to find previous spot height")
            return None

    # DO THE CALCULATION
        fKm_now = dData[iCnt]["km"]
        fKm_bef = dData[iPrev_spot_idx]["km"]
        fFt_now = dData[iCnt]["elev_ft"]
        fFt_bef = dData[iPrev_spot_idx]["elev_ft"]

        # Calculation is common to 'terrain' and 'structure' items.
        dItem = q_grad_calc(fKm_now, fKm_bef, fFt_now, fFt_bef)
        dItem["type"] = "Terrain"
        dGradient.append(dItem)
    # End of the elevation loop loop

# BRIDGES AND TUNNELS:
# Run the bridges and tunnels as a second pass.
    for iCnt in range(iNo_of_items):
        if dData[iCnt]["type"] != "trapezoid":
            continue  # Loop to the next iteration.

        iExam = iCnt + 0
        if dData[iExam]["elev_ft"] == 0:  # Beginning or End of a structure
            # Test for beginning: look at the previous item
            iExam = iCnt - 1

            # Does the previous item exist?
            if iExam < 0:
                sError = ("\n\aERROR: Structure needs a preceeding " +
                          "'spot elevation' for correct operation\n")
                print(sError)
                return None

            bBegin = False
            # Test if this is the first structure after a spot height
            if dData[iExam]["type"] == "spot":
                bBegin = True

            # Test if the previous structure was terminated
            if (dData[iExam]["type"] == "trapezoid"
                    and dData[iExam]["elev_ft"] == 0):
                bBegin = bBegin or True

            # We have a beginning of a structure.
            if bBegin:
                # VERIFY ELEMENTS IN SUB-STRUCTURE (0, [+20, +20, 0])
                for iOffset in range(1, 4):
                    # There are
                    iExam = iCnt + iOffset  # Look forwards at the data
                    if iExam >= iNo_of_items:
                        sError = ("\n\aERROR: Structure has suddenly ended " +
                                  "(listing error)\n")
                        print(sError)
                        return None

                    if (dData[iExam]["type"] != "trapezoid"):
                        # Wrong type
                        sError = (
                            "\n\aERROR: Structure has suddenly ended " +
                            "(non-structural item found as a next element)\n")
                        print(sError)
                        return None

                    if iOffset in [1, 2] and dData[iExam]["elev_ft"] == 0:
                        sError = (
                            "\n\aERROR: Structure's central 'span' is " +
                            "not elevated or depressed. Expected non-zero number"
                        )
                        print(sError)
                        return None

                    if iOffset == 3 and dData[iExam]["elev_ft"] != 0:
                        sError = ("\n\aERROR: Structure has no termination")
                        print(sError)
                        return None
                # End going through the next 3 following points of the structure

            # CALCULATE THE ACTUAL ELEVATIONS AT ALL THE 4 SPOTS:
            # Lets use the previous calculations which generated a list
            # of dictionaries named 'dGradient'. Lets look through it and
            # try to find the piece of terrain we are working on.
                iIdx = None  # Entry pointer w/ error detect
                km_tgt = dData[iCnt]["km"]  # Our target milepost
                for dItem in dGradient:
                    if (dItem["km_bef"] < km_tgt < dItem["km_now"]
                            and dItem["type"] == "Terrain"):
                        iIdx = dGradient.index(dItem)
                        break

                if iIdx == None:
                    sTxt = ("\n\aERROR: Unable to find host terrain section.")
                    return None

                # Calculate ft/km gradient. This gives us both units.
                dTerrain = dGradient[iIdx]  # Extract the entry
                fFt_per_km = dTerrain["ft_del"] / dTerrain["km_del"]

                # distance from beginning of terrain setion to the structure
                # Initialisation of the loop:
                afFt = [0, 0, 0, 0]
                fKm_bef = dTerrain["km_bef"]

                # Calculate the equivalent 'spot' elevations
                for iOffset in range(4):
                    # Build up the km
                    iNow = iCnt + iOffset
                    fKm_str = dData[iNow]["km"]  # Structure element
                    fLoc_km = round(fKm_str - fKm_bef, 2)  # Local km

                    # how much has the terrain changed upto our structure:
                    fFt_del = fLoc_km * fFt_per_km  # ft = km * ft/km

                    # What is the absolue elevation at the foot of the bridge?
                    # 1.) Use ratio and proportion to get the base of element.
                    fFt_terrain = dTerrain["ft_bef"] + fFt_del

                    # 2.) Add the relative change of the structure
                    fFt_struct = fFt_terrain + dData[iNow]["elev_ft"]

                    # 3.) Round off and save.
                    afFt[iOffset] = round(fFt_struct, 1)

                # Calculate the actual gradients of the structure
                for iCalc in range(1, 4):
                    # DO THE CALCULATION
                    iNow = iCnt + iCalc - 0

                    fKm_now = dData[iNow - 0]["km"]
                    fKm_bef = dData[iNow - 1]["km"]
                    fFt_now = afFt[iCalc - 0]
                    fFt_bef = afFt[iCalc - 1]

                    # Calculation is common to 'terrain' and 'structure' items.
                    dItem = q_grad_calc(fKm_now, fKm_bef, fFt_now, fFt_bef)
                    dItem["type"] = "Structure"
                    dGradient.append(dItem)

            # End of finding the beginning of the structure
        # End of delta elevation is zero

    # All the bridges and tunnels have been sorted out. Lets sort the list
    dSorted = sorted(dGradient, key=lambda i: i["km_bef"])

    # Debug: to see what the track data actually looks like.
    return dSorted  # Return the array of tracks.
Пример #9
0
def add_line(ccTremb):
    """ Creates a new railway line meta-data header in the database.
    Use the 'append' function to add the details to it. However, those details
    will be dataase entries themselves. This is the classic debate, few large
    documents vs lots of small documents."""
    # Obtain the highest "my_id" code already registered.
    # Get a list of all the registered base-36 codes
    xParam = {}
    xRestr = {"_id": 0, "my_id": 1}
    cLine = db.lines(ccTremb)
    dId_query = cLine.find(xParam, xRestr)
    iHighest, aEvery_id = misc.find_highest_id(dId_query)

    if (True):  # Debugging
        sTxt = "\n\nHighest number is {0}(10) < < < < < < < <"
        print(sTxt.format(iHighest))

    # We do have the highest identifier (expressed as a decimal number). Hence,
    # we can incerement the sequence and use it.
    iNext_id = iHighest + 1
    if iNext_id > 36**5:
        print("\n\aMaximum count has been exceeded")
        return None

    # Convert to base36
    sBase36 = misc.base_conv(iNext_id)
    sBase36_5 = sBase36.rjust(5, "0")
    # "0002W" -> "D00-02W"
    sNew_id = "K{0}-{1}".format(sBase36_5[:2], sBase36_5[2:])

    # Display the number
    print("\nCode assigned will be: '{0}'".format(sNew_id))

    # PREPARE THE TEMPLATE
    # Open a blank dictionary. I need to arrange the elements in order
    dNew_line = {
        "my_id": sNew_id,  # K00-001
        "tag": "meta",  # Describes that this is the description
        "dVal": {
            "host_geo_code": None,  # VA
            "route_no": None,  # RFU for road B96
            "sRoute_name": "",  # "Vænesston-Kændis Beach (VA-FS)"
            "type": None,  # RFU
            "start": None,  # Where is the zero km count
            "end": None,  # Where is the maximum point
        }  # Closes "dVal" for the meta data
    }

    # GET THE HOST:
    sTxt = (
        "\n\nPlease note that an unregistered host may be entered. Fill " +
        "out the known part\nof the geocode. Enter '?' as the final " +
        "character. Geocode will not be verified.\nIt will be entered as " +
        "'Unnamed'" + "\n\nPlease enter the geo-code of the Host:")
    print(sTxt)
    sGeo_code = input().upper()

    # Confirm host exists
    if sGeo_code[-1] != "?":
        cDest = db.destinations(ccTremb)
        aHost_name = misc.verify_geo_code(sGeo_code, cDest)
        if aHost_name == None:
            print("\n\aUnrecognised host name. Exiting")
            return
        sTxt = "\nHosted by {0} / {1}"
        print(sTxt.format(aHost_name["lat"], aHost_name["cyr"]))

    # Save the geocode
    dNew_line["dVal"]["host_geo_code"] = sGeo_code

    # ROUTE NUMBER
    sTxt = "Is the route number (Б96 for example) known?"
    yn_route = misc.get_binary(sTxt)
    if yn_route == "Y":
        sTxt = "\nPlease enter the route number:"
        dNew_line["dVal"]["route_no"] = input().upper()
    else:
        dNew_line["dVal"]["route_no"] = None

# NAME OF THE STRETCH
    sTxt = ("\nPlease enter the name of this stretch. For example:\n" +
            "Vænesston-Kændis Beach (VA-FS)")
    print(sTxt)
    dNew_line["dVal"]["sRoute_name"] = input()

    # TODO: TYPE OF LINE

    # STARTING POINT
    sTxt = "\nIs the STARTING point known?"
    yn_start = misc.get_binary(sTxt)
    if yn_start == "Y":
        sTxt = ("\nWhere is the starting point? (Ex: 'VAA-00', " +
                "'[email protected]')")
        print(sTxt)
        dNew_line["dVal"]["start"] = input()
    else:
        print("TODO 'AXUZI'")
        return None

# FINISHING POINT
    sTxt = "\nIs the ENDING point known?"
    yn_end = misc.get_binary(sTxt)
    if yn_end == "Y":
        sTxt = ("\nWhere is the ending point? (Ex: 'FS0', '[email protected]')")
        print(sTxt)
        dNew_line["dVal"]["start"] = input()
    else:
        print("TODO 'BZHAK'")
        return None

# Meta data captured:
    cLine.insert_one(dNew_line)
    print(">>>\nNew line OPENED")
Пример #10
0
def add_sub_comp(ccTremb):
    """ This method adds to the railway line opened. Items line track switches,
    level crossings, diverges, merges, stations, ect can be added.
    """
    # Get the line input.
    # To avoid annoying the user of having to enter the line segment, lets
    # assume that the user is working on the 'latest' line. So, lets provide
    # the preselected item.
    xParam = {}
    xRestr = {"_id": 0}
    cLine = db.lines(ccTremb)
    dId_query = cLine.find(xParam, xRestr).sort("_id", -1)
    dId_query.sort("_id", -1)  # From latest to earliest

    # Pull the text for the user to know if he is working on the correct object
    sCode = dId_query[0]["my_id"]

    sTxt = ("The last worked on line was '{0}'. Would you like to work on" +
            " it more?").format(sCode)
    yn_prev_code = misc.get_binary(sTxt)
    if yn_prev_code == "N":
        print("Please enter the line code (K00-001) you would like to work on")
        sLast_code = input().upper()

# Verify the existance of the code and return a string verifying identity
    sRte_det = qVerify_line(sCode, ccTremb)
    if sRte_det == None: return None  # Error condition

    # Full confirmation message:
    sTxt = ("Are you are working on {0}".format(sRte_det))
    yn_confirm = misc.get_binary(sTxt)
    if yn_confirm == 'N': return

    # Confirmation completed. Lets get the reference point
    # Run a query on all milestones.
    xParam = {"my_id": sCode, "tag": "val"}
    xRestr = {"_id": 0}
    dQuery = cLine.find(xParam, xRestr)

    dData = []
    for query in dQuery:
        dData.append(query)  # Save data for further processing

    # Pull out the distances already entered
    s1st_line = "Enter the relative distance from the last known point"
    sMenu = "{0}:\n".format(s1st_line)
    sMenu += "0  : -.--km (beginning of the line)\n"
    iNo_of_entries = len(dData)
    iIndex = 0

    # pull out the reference numbers
    iHighest = 0

    # Offer the distances in a menu
    for idx in range(iNo_of_entries):
        iIndex += 1  # This will show up in the menu.
        sLast_item = ""
        dItem = dData[idx]["dVal"]
        sLast_item += "{:.2f}km ".format(dItem["km"])
        sLast_item += "({0}-".format(dItem["item"])
        sLast_item += "{0}-".format(dItem["type"])
        sLast_item += "{0})".format(dItem["xVal"])
        iLoc_high = dItem["id"]
        if iLoc_high > iHighest:
            iHighest = iLoc_high

        sMenu += ("{0:<3}: {1}".format(iIndex, sLast_item))[:78] + "\n"
        # Keep the string less than 78 characters (avoid collumn breaks)

    # Get the user to choose.
    iDist_choice = misc.get_int(sMenu, iIndex)
    if iDist_choice == None:
        return

    # Default option, when there is no other options.
    fDist = 0.00
    if iDist_choice != 0:
        sTxt = "Is the absolute distance known (from 0.00km)?"
        yn_abs_dist = misc.get_binary(sTxt)
        if yn_abs_dist == "Y":
            sTxt = "Please enter the absolute distance in km"
            fAbs_dist = misc.get_float(sTxt)  # Allow negative dist.
            if fAbs_dist == None: return
            fDist = round(fAbs_dist, 2)
        # We want to enter a relative distance
        else:
            sTxt = "Is the relative distance read from the map?"
            yn_rel_map = misc.get_binary(sTxt)
            if yn_rel_map == "N":
                # Relative distance is known in km.
                sTxt = "Please enter the relative distance in km"
                fRel_dist = misc.get_float(sTxt, bNeg=True)
                if fRel_dist == None: return
                fRel_dist = round(fRel_dist, 2)
            # We are reading off the map.
            else:
                # Select a map to work on
                dMap = misc.get_the_map(ccTremb)
                if dMap == None:
                    print("\n\aInvalid map selected. Exiting")
                    return None
                fScale = dMap["fScale"]

                # Ask user to input the distance on the map.
                sTxt = "Please enter the relative distance in mm from the map"
                fRel_mm = misc.get_float(sTxt, bNeg=True)
                if fRel_mm == None: return

                fRel_dist = fRel_mm * (fScale / 1e6)  # Convert map mm to km
                fRel_dist = round(fRel_dist, 2)
                print("km distance: {0}".format(fRel_dist))
            # Relative distane known. Now calculate the absolute distance
            iEntry = iDist_choice - 1  # 1-count to 0-count
            fOld_dist = dData[iEntry]["dVal"]["km"]
            fDist = fOld_dist + fRel_dist
            fDist = round(fDist, 2)
        # Absolute distance is now known.
    # Non-initial condition is being closed here.

    sMenu = "\nPlease select 'event' category:\n"
    sMenu += "1.  Build Track\n"
    sMenu += "2.  Build Junction\n"
    sMenu += "3.  Station\n"
    sMenu += "4.  Non-rail crossing\n"
    sMenu += "5.  [RFU] --- Structure\n"
    sMenu += "6.  Elevation\n"
    sMenu += "7.  [RFU] --- Signal\n"
    sMenu += "8.  Sign (speed / warning / direction)"
    print(sMenu)
    sInput = input().upper()

    dPack = {
        "tremb": ccTremb,  # For full DB access.
        "db": cLine,
        "dEntry": {
            "km": fDist,
            "id": iHighest + 1,  # Unique reference number
            "item": None,
            "type": None,
            "xVal": None
        },
    }

    if sInput == "1":
        dEntry = qEvent_track(dPack)
    elif sInput == "2":
        dEntry = qEvent_junction(dPack)
    elif sInput == "3":
        dEntry = qEvent_station(dPack)
    elif sInput == "4":
        dEntry = qEvent_crossing(dPack)
    elif sInput == "6":
        dEntry = qEvent_elevation(dPack)
    elif sInput == "8":
        dEntry = qEvent_signage(dPack)
    else:
        print("\n\aInvalid selection. Exiting")
        return

    if dEntry == None: return  # We got an error somewhere.

    # Add the item to the database
    dAdd_line = {
        "my_id": sCode,  # K00-001
        "tag": "val",  # Describes that this is the description
        "dVal": dEntry,  # The data generated
    }

    sTxt = "Is this entry OK?: \n{0}\n".format(dAdd_line)
    yn_final = misc.get_binary(sTxt)
    if yn_final == "N":
        print("User confirmation declined. Exiting")
        return

    # Add to the data base.
    cLine.insert_one(dAdd_line)
    print(">>>\nNew item added")