void
RODFDetector::writeSingleSpeedTrigger(const std::string& file,
                                      const RODFDetectorFlows& flows,
                                      SUMOTime startTime, SUMOTime endTime,
                                      SUMOTime stepOffset, SUMOReal defaultSpeed) {
    OutputDevice& out = OutputDevice::getDevice(file);
    out.writeXMLHeader("vss");
    const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
    unsigned int index = 0;
    for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
        assert(index < mflows.size());
        const FlowDef& srcFD = mflows[index];
        SUMOReal speed = MAX2(srcFD.vLKW, srcFD.vPKW);
        if (speed <= 0 || speed > 250) {
            speed = defaultSpeed;
        } else {
            speed = (SUMOReal)(speed / 3.6);
        }
        out.openTag(SUMO_TAG_STEP).writeAttr(SUMO_ATTR_TIME, time2string(t)).writeAttr(SUMO_ATTR_SPEED, speed).closeTag();
    }
    out.close();
}
Beispiel #2
0
void
RODFDetector::writeSingleSpeedTrigger(const std::string& file,
                                      const RODFDetectorFlows& flows,
                                      SUMOTime startTime, SUMOTime endTime,
                                      SUMOTime stepOffset, SUMOReal defaultSpeed) {
    OutputDevice& out = OutputDevice::getDevice(file);
    out.writeXMLHeader("vss");
    const std::vector<FlowDef> &mflows = flows.getFlowDefs(myID);
    int index = 0;
    for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
        assert(index < mflows.size());
        const FlowDef& srcFD = mflows[index];
        SUMOReal speed = MAX2(srcFD.vLKW, srcFD.vPKW);
        if (speed <= 0 || speed > 250) {
            speed = defaultSpeed;
        } else {
            speed = (SUMOReal)(speed / 3.6);
        }
        out << "   <step time=\"" << t << "\" speed=\"" << speed << "\"/>\n";
    }
    out.close();
}
Beispiel #3
0
void
RODFNet::buildEdgeFlowMap(const RODFDetectorFlows& flows,
                          const RODFDetectorCon& detectors,
                          SUMOTime startTime, SUMOTime endTime,
                          SUMOTime stepOffset) {
    std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
    for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
        ROEdge* into = (*i).first;
        const std::vector<std::string>& dets = (*i).second;
        std::map<SUMOReal, std::vector<std::string> > cliques;
        std::vector<std::string>* maxClique = 0;
        for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
            if (!flows.knows(*j)) {
                continue;
            }
            const RODFDetector& det = detectors.getDetector(*j);
            bool found = false;
            for (std::map<SUMOReal, std::vector<std::string> >::iterator k = cliques.begin(); !found && k != cliques.end(); ++k) {
                if (fabs((*k).first - det.getPos()) < 1) {
                    (*k).second.push_back(*j);
                    if ((*k).second.size() > maxClique->size()) {
                        maxClique = &(*k).second;
                    }
                    found = true;
                }
            }
            if (!found) {
                cliques[det.getPos()].push_back(*j);
                maxClique = &cliques[det.getPos()];
            }
        }
        if (maxClique == 0) {
            continue;
        }
        std::vector<FlowDef> mflows; // !!! reserve
        for (SUMOTime t = startTime; t < endTime; t += stepOffset) {
            FlowDef fd;
            fd.qPKW = 0;
            fd.qLKW = 0;
            fd.vLKW = 0;
            fd.vPKW = 0;
            fd.fLKW = 0;
            fd.isLKW = 0;
            mflows.push_back(fd);
        }
        for (std::vector<std::string>::iterator l = maxClique->begin(); l != maxClique->end(); ++l) {
            bool didWarn = false;
            const std::vector<FlowDef>& dflows = flows.getFlowDefs(*l);
            int index = 0;
            for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
                const FlowDef& srcFD = dflows[index];
                FlowDef& fd = mflows[index];
                fd.qPKW += srcFD.qPKW;
                fd.qLKW += srcFD.qLKW;
                fd.vLKW += (srcFD.vLKW / (SUMOReal) maxClique->size());
                fd.vPKW += (srcFD.vPKW / (SUMOReal) maxClique->size());
                fd.fLKW += (srcFD.fLKW / (SUMOReal) maxClique->size());
                fd.isLKW += (srcFD.isLKW / (SUMOReal) maxClique->size());
                if (!didWarn && srcFD.vPKW > 0 && srcFD.vPKW < 255 && srcFD.vPKW / 3.6 > into->getSpeed()) {
                    WRITE_MESSAGE("Detected PKW speed higher than allowed speed at '" + (*l) + "' on '" + into->getID() + "'.");
                    didWarn = true;
                }
                if (!didWarn && srcFD.vLKW > 0 && srcFD.vLKW < 255 && srcFD.vLKW / 3.6 > into->getSpeed()) {
                    WRITE_MESSAGE("Detected LKW speed higher than allowed speed at '" + (*l) + "' on '" + into->getID() + "'.");
                    didWarn = true;
                }
            }
        }
        static_cast<RODFEdge*>(into)->setFlows(mflows);
    }
}
Beispiel #4
0
void
RODFNet::revalidateFlows(const RODFDetector* detector,
                         RODFDetectorFlows& flows,
                         SUMOTime startTime, SUMOTime endTime,
                         SUMOTime stepOffset) {
    {
        if (flows.knows(detector->getID())) {
            const std::vector<FlowDef>& detFlows = flows.getFlowDefs(detector->getID());
            for (std::vector<FlowDef>::const_iterator j = detFlows.begin(); j != detFlows.end(); ++j) {
                if ((*j).qPKW > 0 || (*j).qLKW > 0) {
                    return;
                }
            }
        }
    }
    // ok, there is no information for the whole time;
    //  lets find preceding detectors and rebuild the flows if possible
    WRITE_WARNING("Detector '" + detector->getID() + "' has no flows.\n Trying to rebuild.");
    // go back and collect flows
    std::vector<ROEdge*> previous;
    {
        std::vector<IterationEdge> missing;
        IterationEdge ie;
        ie.depth = 0;
        ie.edge = getDetectorEdge(*detector);
        missing.push_back(ie);
        bool maxDepthReached = false;
        while (!missing.empty() && !maxDepthReached) {
            IterationEdge last = missing.back();
            missing.pop_back();
            std::vector<ROEdge*> approaching = myApproachingEdges[last.edge];
            for (std::vector<ROEdge*>::const_iterator j = approaching.begin(); j != approaching.end(); ++j) {
                if (hasDetector(*j)) {
                    previous.push_back(*j);
                } else {
                    ie.depth = last.depth + 1;
                    ie.edge = *j;
                    missing.push_back(ie);
                    if (ie.depth > 5) {
                        maxDepthReached = true;
                    }
                }
            }
        }
        if (maxDepthReached) {
            WRITE_WARNING(" Could not build list of previous flows.");
        }
    }
    // Edges with previous detectors are now in "previous";
    //  compute following
    std::vector<ROEdge*> latter;
    {
        std::vector<IterationEdge> missing;
        for (std::vector<ROEdge*>::const_iterator k = previous.begin(); k != previous.end(); ++k) {
            IterationEdge ie;
            ie.depth = 0;
            ie.edge = *k;
            missing.push_back(ie);
        }
        bool maxDepthReached = false;
        while (!missing.empty() && !maxDepthReached) {
            IterationEdge last = missing.back();
            missing.pop_back();
            std::vector<ROEdge*> approached = myApproachedEdges[last.edge];
            for (std::vector<ROEdge*>::const_iterator j = approached.begin(); j != approached.end(); ++j) {
                if (*j == getDetectorEdge(*detector)) {
                    continue;
                }
                if (hasDetector(*j)) {
                    latter.push_back(*j);
                } else {
                    IterationEdge ie;
                    ie.depth = last.depth + 1;
                    ie.edge = *j;
                    missing.push_back(ie);
                    if (ie.depth > 5) {
                        maxDepthReached = true;
                    }
                }
            }
        }
        if (maxDepthReached) {
            WRITE_WARNING(" Could not build list of latter flows.");
            return;
        }
    }
    // Edges with latter detectors are now in "latter";

    // lets not validate them by now - surely this should be done
    // for each time step: collect incoming flows; collect outgoing;
    std::vector<FlowDef> mflows;
    int index = 0;
    for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
        FlowDef inFlow;
        inFlow.qLKW = 0;
        inFlow.qPKW = 0;
        inFlow.vLKW = 0;
        inFlow.vPKW = 0;
        // collect incoming
        {
            // !! time difference is missing
            for (std::vector<ROEdge*>::iterator i = previous.begin(); i != previous.end(); ++i) {
                const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(*i)->getFlows();
                if (flows.size() != 0) {
                    const FlowDef& srcFD = flows[index];
                    inFlow.qLKW += srcFD.qLKW;
                    inFlow.qPKW += srcFD.qPKW;
                    inFlow.vLKW += srcFD.vLKW;
                    inFlow.vPKW += srcFD.vPKW;
                }
            }
        }
        inFlow.vLKW /= (SUMOReal) previous.size();
        inFlow.vPKW /= (SUMOReal) previous.size();
        // collect outgoing
        FlowDef outFlow;
        outFlow.qLKW = 0;
        outFlow.qPKW = 0;
        outFlow.vLKW = 0;
        outFlow.vPKW = 0;
        {
            // !! time difference is missing
            for (std::vector<ROEdge*>::iterator i = latter.begin(); i != latter.end(); ++i) {
                const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(*i)->getFlows();
                if (flows.size() != 0) {
                    const FlowDef& srcFD = flows[index];
                    outFlow.qLKW += srcFD.qLKW;
                    outFlow.qPKW += srcFD.qPKW;
                    outFlow.vLKW += srcFD.vLKW;
                    outFlow.vPKW += srcFD.vPKW;
                }
            }
        }
        outFlow.vLKW /= (SUMOReal) latter.size();
        outFlow.vPKW /= (SUMOReal) latter.size();
        //
        FlowDef mFlow;
        mFlow.qLKW = inFlow.qLKW - outFlow.qLKW;
        mFlow.qPKW = inFlow.qPKW - outFlow.qPKW;
        mFlow.vLKW = (inFlow.vLKW + outFlow.vLKW) / (SUMOReal) 2.;
        mFlow.vPKW = (inFlow.vPKW + outFlow.vPKW) / (SUMOReal) 2.;
        mflows.push_back(mFlow);
    }
    static_cast<RODFEdge*>(getDetectorEdge(*detector))->setFlows(mflows);
    flows.setFlows(detector->getID(), mflows);
}
bool
RODFDetector::writeEmitterDefinition(const std::string& file,
                                     const std::map<size_t, RandomDistributor<size_t>* >& dists,
                                     const RODFDetectorFlows& flows,
                                     SUMOTime startTime, SUMOTime endTime,
                                     SUMOTime stepOffset,
                                     bool includeUnusedRoutes,
                                     SUMOReal scale,
                                     bool insertionsOnly,
                                     SUMOReal defaultSpeed) const {
    OutputDevice& out = OutputDevice::getDevice(file);
    if (getType() != SOURCE_DETECTOR) {
        out.writeXMLHeader("calibrator");
    }
    // routes
    if (myRoutes != 0 && myRoutes->get().size() != 0) {
        const std::vector<RODFRouteDesc>& routes = myRoutes->get();
        out.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, myID);
        bool isEmptyDist = true;
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0) {
                isEmptyDist = false;
            }
        }
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0 || includeUnusedRoutes) {
                out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, (*i).overallProb).closeTag();
            }
            if (isEmptyDist) {
                out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, SUMOReal(1)).closeTag();
            }
        }
        out.closeTag(); // routeDistribution
    } else {
        WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
        return false;
    }
    // insertions
    if (insertionsOnly || flows.knows(myID)) {
        // get the flows for this detector
        const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
        // go through the simulation seconds
        unsigned int index = 0;
        for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
            // get own (departure flow)
            assert(index < mflows.size());
            const FlowDef& srcFD = mflows[index];  // !!! check stepOffset
            // get flows at end
            RandomDistributor<size_t>* destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
            // go through the cars
            size_t carNo = (size_t)((srcFD.qPKW + srcFD.qLKW) * scale);
            for (size_t car = 0; car < carNo; ++car) {
                // get the vehicle parameter
                SUMOReal v = -1;
                int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
                if (srcFD.isLKW >= 1) {
                    srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
                    v = srcFD.vLKW;
                } else {
                    v = srcFD.vPKW;
                }
                // compute insertion speed
                if (v <= 0 || v > 250) {
                    v = defaultSpeed;
                } else {
                    v = (SUMOReal)(v / 3.6);
                }
                // compute the departure time
                SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));

                // write
                out.openTag(SUMO_TAG_VEHICLE);
                if (getType() == SOURCE_DETECTOR) {
                    out.writeAttr(SUMO_ATTR_ID, "emitter_" + myID + "_" + toString(ctime));
                } else {
                    out.writeAttr(SUMO_ATTR_ID, "calibrator_" + myID + "_" + toString(ctime));
                }
                out.writeAttr(SUMO_ATTR_DEPART, time2string(ctime));
                if (v > defaultSpeed) {
                    out.writeAttr(SUMO_ATTR_DEPARTSPEED, "max");
                } else {
                    out.writeAttr(SUMO_ATTR_DEPARTSPEED, v);
                }
                out.writeAttr(SUMO_ATTR_DEPARTPOS, myPosition).writeAttr(SUMO_ATTR_DEPARTLANE, TplConvert::_2int(myLaneID.substr(myLaneID.rfind("_") + 1).c_str()));
                if (destIndex >= 0) {
                    out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
                } else {
                    out.writeAttr(SUMO_ATTR_ROUTE, myID);
                }
                out.closeTag();
                srcFD.isLKW += srcFD.fLKW;
            }
        }
    }
    if (getType() != SOURCE_DETECTOR) {
        out.close();
    }
    return true;
}
Beispiel #6
0
bool
RODFDetector::writeEmitterDefinition(const std::string& file,
                                     const std::map<size_t, RandomDistributor<size_t>* > &dists,
                                     const RODFDetectorFlows& flows,
                                     SUMOTime startTime, SUMOTime endTime,
                                     SUMOTime stepOffset,
                                     bool includeUnusedRoutes,
                                     SUMOReal scale,
                                     bool insertionsOnly,
                                     SUMOReal defaultSpeed) const {
    OutputDevice& out = OutputDevice::getDevice(file);
    if (getType() != SOURCE_DETECTOR) {
        out.writeXMLHeader("calibrator");
    }
    // routes
    if (myRoutes != 0 && myRoutes->get().size() != 0) {
        const std::vector<RODFRouteDesc> &routes = myRoutes->get();
        out.openTag("routeDistribution") <<  " id=\"" << myID << "\">\n";
        bool isEmptyDist = true;
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0) {
                isEmptyDist = false;
            }
        }
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0 || includeUnusedRoutes) {
                out.openTag("route") << " refId=\"" << (*i).routename << "\" probability=\"" << (*i).overallProb << "\"";
                out.closeTag(true);
            }
            if (isEmptyDist) {
                out.openTag("route") << " refId=\"" << (*i).routename << "\" probability=\"1\"";
                out.closeTag(true);
            }
        }
        out.closeTag();
    } else {
        WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
        return false;
    }
    // emissions
    if (insertionsOnly || flows.knows(myID)) {
        // get the flows for this detector

        const std::vector<FlowDef> &mflows = flows.getFlowDefs(myID);
        // go through the simulation seconds
        int index = 0;
        for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
            // get own (departure flow)
            assert(index < mflows.size());
            const FlowDef& srcFD = mflows[index];  // !!! check stepOffset
            // get flows at end
            RandomDistributor<size_t> *destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
            // go through the cars
            size_t carNo = (size_t)((srcFD.qPKW + srcFD.qLKW) * scale);
            for (size_t car = 0; car < carNo; ++car) {
                // get the vehicle parameter
                std::string type = "test";
                SUMOReal v = -1;
                int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
                if (srcFD.isLKW >= 1) {
                    srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
//!!!		        	type = lkwTypes[vehSpeedDist.get()];
                    v = srcFD.vLKW;
                } else {
//!!!	    			type = pkwTypes[vehSpeedDist.get()];
                    v = srcFD.vPKW;
                }
                // compute emission speed
                if (v < 0 || v > 250) {
                    v = defaultSpeed;
                } else {
                    v = (SUMOReal)(v / 3.6);
                }
                // compute the departure time
                SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));

                // write
                out.openTag("vehicle") << " id=\"";
                if (getType() == SOURCE_DETECTOR) {
                    out << "emitter_" << myID;
                } else {
                    out << "calibrator_" << myID;
                }
                out << "_" << ctime  << "\"" // !!! running
                    << " depart=\"" << time2string(ctime) << "\""
                    << " departSpeed=\"";
                if (v > defaultSpeed) {
                    out << "max";
                } else {
                    out << v;
                }
                out << "\" departPos=\"" << myPosition << "\""
                    << " departLane=\"" << myLaneID.substr(myLaneID.rfind("_") + 1) << "\" route=\"";
                if (destIndex >= 0) {
                    out << myRoutes->get()[destIndex].routename << "\"";
                } else {
                    out << myID << "\"";
                }
                out.closeTag(true);
                srcFD.isLKW += srcFD.fLKW;
            }
        }
    }
    if (getType() != SOURCE_DETECTOR) {
        out.close();
    }
    return true;
}
Beispiel #7
0
bool
RODFDetector::writeEmitterDefinition(const std::string& file,
                                     const std::map<SUMOTime, RandomDistributor<int>* >& dists,
                                     const RODFDetectorFlows& flows,
                                     SUMOTime startTime, SUMOTime endTime,
                                     SUMOTime stepOffset,
                                     bool includeUnusedRoutes,
                                     SUMOReal scale,
                                     bool insertionsOnly,
                                     SUMOReal defaultSpeed) const {
    OutputDevice& out = OutputDevice::getDevice(file);
    OptionsCont& oc = OptionsCont::getOptions();
    if (getType() != SOURCE_DETECTOR) {
        out.writeXMLHeader("additional", "additional_file.xsd");
    }
    // routes
    if (myRoutes != 0 && myRoutes->get().size() != 0) {
        const std::vector<RODFRouteDesc>& routes = myRoutes->get();
        out.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, myID);
        bool isEmptyDist = true;
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0) {
                isEmptyDist = false;
            }
        }
        for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
            if ((*i).overallProb > 0 || includeUnusedRoutes) {
                out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, (*i).overallProb).closeTag();
            }
            if (isEmptyDist) {
                out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, SUMOReal(1)).closeTag();
            }
        }
        out.closeTag(); // routeDistribution
    } else {
        WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
        return false;
    }
    // insertions
    if (insertionsOnly || flows.knows(myID)) {
        // get the flows for this detector
        const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
        // go through the simulation seconds
        int index = 0;
        for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
            // get own (departure flow)
            assert(index < (int)mflows.size());
            const FlowDef& srcFD = mflows[index];  // !!! check stepOffset
            // get flows at end
            RandomDistributor<int>* destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
            // go through the cars
            int carNo = (int)((srcFD.qPKW + srcFD.qLKW) * scale);
            for (int car = 0; car < carNo; ++car) {
                // get the vehicle parameter
                SUMOReal v = -1;
                std::string vtype;
                int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
                if (srcFD.isLKW >= 1) {
                    srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
                    v = srcFD.vLKW;
                    vtype = "LKW";
                } else {
                    v = srcFD.vPKW;
                    vtype = "PKW";
                }
                // compute insertion speed
                if (v <= 0 || v > 250) {
                    v = defaultSpeed;
                } else {
                    v = (SUMOReal)(v / 3.6);
                }
                // compute the departure time
                SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));

                // write
                out.openTag(SUMO_TAG_VEHICLE);
                if (getType() == SOURCE_DETECTOR) {
                    out.writeAttr(SUMO_ATTR_ID, "emitter_" + myID + "_" + toString(ctime));
                } else {
                    out.writeAttr(SUMO_ATTR_ID, "calibrator_" + myID + "_" + toString(ctime));
                }
                if (oc.getBool("vtype")) {
                    out.writeAttr(SUMO_ATTR_TYPE, vtype);
                }
                out.writeAttr(SUMO_ATTR_DEPART, time2string(ctime));
                if (oc.isSet("departlane")) {
                    out.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
                } else {
                    out.writeAttr(SUMO_ATTR_DEPARTLANE, TplConvert::_2int(myLaneID.substr(myLaneID.rfind("_") + 1).c_str()));
                }
                if (oc.isSet("departpos")) {
                    std::string posDesc = oc.getString("departpos");
                    if (posDesc.substr(0, 8) == "detector") {
                        SUMOReal position = myPosition;
                        if (posDesc.length() > 8) {
                            if (posDesc[8] == '+') {
                                position += TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
                            } else if (posDesc[8] == '-') {
                                position -= TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
                            } else {
                                throw NumberFormatException();
                            }
                        }
                        out.writeAttr(SUMO_ATTR_DEPARTPOS, position);
                    } else {
                        out.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, posDesc);
                    }
                } else {
                    out.writeAttr(SUMO_ATTR_DEPARTPOS, myPosition);
                }
                if (oc.isSet("departspeed")) {
                    out.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
                } else {
                    out.writeAttr(SUMO_ATTR_DEPARTSPEED, v);
                }
                if (oc.isSet("arrivallane")) {
                    out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
                }
                if (oc.isSet("arrivalpos")) {
                    out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
                }
                if (oc.isSet("arrivalspeed")) {
                    out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
                }
                if (destIndex >= 0) {
                    out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
                } else {
                    out.writeAttr(SUMO_ATTR_ROUTE, myID);
                }
                out.closeTag();
                srcFD.isLKW += srcFD.fLKW;
            }
        }
    }
    if (getType() != SOURCE_DETECTOR) {
        out.close();
    }
    return true;
}