src/main/java/de/blau/android/osm/StorageDelegator.java
/**
     * Split way at node with relation support
     * 
     * @param way way to split
     * @param node node to split at
     * @return the new Way in the first Result
     */
Split way at node with relation support

@param way way to split
@param node node to split at
@return the new Way in the first Result
Split way at node with relation support @param way way to split @param node node to split at @return the new Way in the first Result
@NonNull
    public List<Result> splitAtNode(@NonNull final Way way, @NonNull final Node node) {
        Log.d(DEBUG_TAG, "splitAtNode way " + way.getOsmId() + " node " + node.getOsmId());
        Result result = new Result();
        dirty = true;
        undo.save(way);
        List<Node> nodes = way.getNodes();
        int occurances = Collections.frequency(way.getNodes(), node);
        if (nodes.size() < 3 || (way.isEndNode(node) && (way.isClosed() ? occurances == 2 : occurances == 1))) {
            String msg = "splitAtNode can't split " + nodes.size() + " node long way at this node";
            Log.d(DEBUG_TAG, msg);
            throw new OsmIllegalOperationException(msg);
        }
        validateRelationMemberCount(way.getParentRelations(), 1);
        List<String> metricKeys = new ArrayList<>();
        for (String key : way.getTags().keySet()) {
            if (Tags.isWayMetric(key)) {
                metricKeys.add(key);
            }
        }
        double originalLength = 1D;
        if (!metricKeys.isEmpty()) {
            originalLength = way.length();
        }
        List<Node> nodesForNewWay = new LinkedList<>();
        boolean found = false;
        boolean first = true; 
        for (Iterator<Node> it = way.getRemovableNodes(); it.hasNext();) {
            Node wayNode = it.next();
            if (!found && wayNode.getOsmId() == node.getOsmId() && !first) {
                found = true;
                nodesForNewWay.add(wayNode);
            } else if (found) {
                nodesForNewWay.add(wayNode);
                it.remove();
            }
            first = false;
        }
        if (nodesForNewWay.size() <= 1) {
            String msg = "splitAtNode can't split, new way would have " + nodesForNewWay.size() + " node(s)";
            Log.d(DEBUG_TAG, msg);
            throw new OsmIllegalOperationException(msg);
        }
        List<OsmElement> changedElements = new ArrayList<>();
        try {
            way.updateState(OsmElement.STATE_MODIFIED);
            apiStorage.insertElementSafe(way);
            changedElements.add(way);
            Way newWay = factory.createWayWithNewId();
            newWay.addNodes(nodesForNewWay, false);
            newWay.addTags(way.getTags());
            insertElementUnsafe(newWay);
            if (!metricKeys.isEmpty() && originalLength != 0) {
                result.addIssue(SplitIssue.SPLIT_METRIC);
                for (String key : metricKeys) {
                    distributeMetric(key, originalLength, way);
                    distributeMetric(key, originalLength, newWay);
                }
            }
            List<Result> relationResults = addSplitWayToRelations(way, false, newWay, changedElements);
            onElementChanged(null, changedElements);
            result.setElement(newWay);
            List<Result> resultList = Util.wrapInList(result);
            resultList.addAll(relationResults);
            return resultList;
        } catch (StorageException e) {
            Log.e(DEBUG_TAG, "splitAtNode got " + e.getMessage());
            throw e;
        }
    }
@ NonNull public List < Result > splitAtNode ( @ NonNull final Way way , @ NonNull final Node node ) { Log . d ( DEBUG_TAG , "splitAtNode way " + way . getOsmId ( ) + " node " + node . getOsmId ( ) ) ; Result result = new Result ( ) ; dirty = true ; undo . save ( way ) ; List < Node > nodes = way . getNodes ( ) ; int occurances = Collections . frequency ( way . getNodes ( ) , node ) ; if ( nodes . size ( ) < 3 || ( way . isEndNode ( node ) && ( way . isClosed ( ) ? occurances == 2 : occurances == 1 ) ) ) { String msg = "splitAtNode can't split " + nodes . size ( ) + " node long way at this node" ; Log . d ( DEBUG_TAG , msg ) ; throw new OsmIllegalOperationException ( msg ) ; } validateRelationMemberCount ( way . getParentRelations ( ) , 1 ) ; List < String > metricKeys = new ArrayList < > ( ) ; for ( String key : way . getTags ( ) . keySet ( ) ) { if ( Tags . isWayMetric ( key ) ) { metricKeys . add ( key ) ; } } double originalLength = 1D ; if ( ! metricKeys . isEmpty ( ) ) { originalLength = way . length ( ) ; } List < Node > nodesForNewWay = new LinkedList < > ( ) ; boolean found = false ; boolean first = true ; for ( Iterator < Node > it = way . getRemovableNodes ( ) ; it . hasNext ( ) ; ) { Node wayNode = it . next ( ) ; if ( ! found && wayNode . getOsmId ( ) == node . getOsmId ( ) && ! first ) { found = true ; nodesForNewWay . add ( wayNode ) ; } else if ( found ) { nodesForNewWay . add ( wayNode ) ; it . remove ( ) ; } first = false ; } if ( nodesForNewWay . size ( ) <= 1 ) { String msg = "splitAtNode can't split, new way would have " + nodesForNewWay . size ( ) + " node(s)" ; Log . d ( DEBUG_TAG , msg ) ; throw new OsmIllegalOperationException ( msg ) ; } List < OsmElement > changedElements = new ArrayList < > ( ) ; try { way . updateState ( OsmElement . STATE_MODIFIED ) ; apiStorage . insertElementSafe ( way ) ; changedElements . add ( way ) ; Way newWay = factory . createWayWithNewId ( ) ; newWay . addNodes ( nodesForNewWay , false ) ; newWay . addTags ( way . getTags ( ) ) ; insertElementUnsafe ( newWay ) ; if ( ! metricKeys . isEmpty ( ) && originalLength != 0 ) { result . addIssue ( SplitIssue . SPLIT_METRIC ) ; for ( String key : metricKeys ) { distributeMetric ( key , originalLength , way ) ; distributeMetric ( key , originalLength , newWay ) ; } } List < Result > relationResults = addSplitWayToRelations ( way , false , newWay , changedElements ) ; onElementChanged ( null , changedElements ) ; result . setElement ( newWay ) ; List < Result > resultList = Util . wrapInList ( result ) ; resultList . addAll ( relationResults ) ; return resultList ; } catch ( StorageException e ) { Log . e ( DEBUG_TAG , "splitAtNode got " + e . getMessage ( ) ) ; throw e ; } }
Split way at node with relation support
Split way at node with relation support
// undo - old way is saved here, new way is saved at insert // the following condition is fairly obscure and should likely be replaced by checking for position of the node // in the way // protect against producing single node ways // check tags for problematic keys // determine the length before we remove nodes // we assume this node is only contained in the way once. // else the user needs to split the remaining way again. // node to split at can't be the first one // update original way // create the new way