Changeset 22101 in osm for applications


Ignore:
Timestamp:
2010-06-29T19:21:09+02:00 (14 years ago)
Author:
pieren
Message:

going forward with implementation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/Address.java

    r22042 r22101  
    66import java.awt.GridBagLayout;
    77import java.awt.Point;
     8import java.awt.Toolkit;
    89import java.awt.event.ActionEvent;
    910import java.awt.event.ActionListener;
     
    1314import java.awt.event.MouseMotionListener;
    1415import java.util.ArrayList;
     16import java.util.Collection;
     17import java.util.Collections;
     18import java.util.HashMap;
     19import java.util.HashSet;
     20import java.util.Iterator;
     21import java.util.LinkedList;
    1522import java.util.List;
     23import java.util.Map;
     24import java.util.Set;
    1625
    1726import javax.swing.ButtonGroup;
     
    2534
    2635import org.openstreetmap.josm.Main;
     36import org.openstreetmap.josm.command.AddCommand;
     37import org.openstreetmap.josm.command.ChangeCommand;
     38import org.openstreetmap.josm.command.Command;
     39import org.openstreetmap.josm.command.SequenceCommand;
    2740import org.openstreetmap.josm.actions.mapmode.MapMode;
     41import org.openstreetmap.josm.data.coor.EastNorth;
    2842import org.openstreetmap.josm.data.osm.Node;
    2943import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    3650import org.openstreetmap.josm.tools.GBC;
    3751import org.openstreetmap.josm.tools.ImageProvider;
     52import org.openstreetmap.josm.tools.Pair;
    3853import org.openstreetmap.josm.tools.Shortcut;
    3954
     
    5873    final JTextField inputNumber = new JTextField();
    5974    final JTextField inputStreet = new JTextField();
    60 
     75   
     76    MapFrame mapFrame;
     77   
    6178    public Address(MapFrame mapFrame) {
    6279        super(tr("Add address"), "buildings",
     
    6481                Shortcut.registerShortcut("mapmode:buildings", tr("Mode: {0}", tr("Buildings")), KeyEvent.VK_E, Shortcut.GROUP_EDIT),
    6582                mapFrame, getCursor());
     83        this.mapFrame = mapFrame;
    6684    }
    6785
     
    166184            } else if (mouseOnExistingWays.size() == 0) {
    167185                // clicked a non highway and not a node => add the new address
    168                 Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
    169                 if (n != null)
    170                     if (!n.hasKey(tagHouseNumber))
    171                         addAddrToNode(n);
    172                 else
    173                     createNewNode(mousePos);
     186                if (inputStreet.getText().equals("") || inputNumber.getText().equals("")) {
     187                    Toolkit.getDefaultToolkit().beep();
     188                } else {
     189                    Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
     190                    if (n == null)
     191                        n = createNewNode(e);
     192                    addAddrToNode(n);
     193                }
    174194            }
    175195        }
     
    178198   
    179199    private void addAddrToNode(Node n) {
    180         // node exists : just add the tag addr:housenumber and member in relation
    181     }
    182    
    183     private void createNewNode(Point mousePos) {
    184        
     200        // add the tag addr:housenumber in node and member in relation
     201    }
     202   
     203    private Node createNewNode(MouseEvent e) {
     204        // DrawAction.mouseReleased() but without key modifiers
     205        Node n = new Node(Main.map.mapView.getLatLon(e.getX(), e.getY()));
     206        Collection<Command> cmds = new LinkedList<Command>();
     207        cmds.add(new AddCommand(n));
     208        List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint(), OsmPrimitive.isSelectablePredicate);
     209        Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
     210        for (WaySegment ws : wss) {
     211            List<Integer> is;
     212            if (insertPoints.containsKey(ws.way)) {
     213                is = insertPoints.get(ws.way);
     214            } else {
     215                is = new ArrayList<Integer>();
     216                insertPoints.put(ws.way, is);
     217            }
     218
     219            is.add(ws.lowerIndex);
     220        }
     221        Set<Pair<Node,Node>> segSet = new HashSet<Pair<Node,Node>>();
     222        ArrayList<Way> replacedWays = new ArrayList<Way>();
     223        ArrayList<Way> reuseWays = new ArrayList<Way>();
     224        for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
     225            Way w = insertPoint.getKey();
     226            List<Integer> is = insertPoint.getValue();
     227            Way wnew = new Way(w);
     228            pruneSuccsAndReverse(is);
     229            for (int i : is) {
     230                segSet.add(Pair.sort(new Pair<Node,Node>(w.getNode(i), w.getNode(i+1))));
     231            }
     232            for (int i : is) {
     233                wnew.addNode(i + 1, n);
     234            }
     235            cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
     236            replacedWays.add(insertPoint.getKey());
     237            reuseWays.add(wnew);
     238        }
     239        adjustNode(segSet, n);
     240
     241        Command c = new SequenceCommand("Add node address", cmds);
     242        Main.main.undoRedo.add(c);
     243        return n;
     244    }
     245   
     246    private static void adjustNode(Collection<Pair<Node,Node>> segs, Node n) {
     247
     248        switch (segs.size()) {
     249        case 0:
     250            return;
     251        case 2:
     252            // This computes the intersection between
     253            // the two segments and adjusts the node position.
     254            Iterator<Pair<Node,Node>> i = segs.iterator();
     255            Pair<Node,Node> seg = i.next();
     256            EastNorth A = seg.a.getEastNorth();
     257            EastNorth B = seg.b.getEastNorth();
     258            seg = i.next();
     259            EastNorth C = seg.a.getEastNorth();
     260            EastNorth D = seg.b.getEastNorth();
     261
     262            double u=det(B.east() - A.east(), B.north() - A.north(), C.east() - D.east(), C.north() - D.north());
     263
     264            // Check for parallel segments and do nothing if they are
     265            // In practice this will probably only happen when a way has been duplicated
     266
     267            if (u == 0) return;
     268
     269            // q is a number between 0 and 1
     270            // It is the point in the segment where the intersection occurs
     271            // if the segment is scaled to lenght 1
     272
     273            double q = det(B.north() - C.north(), B.east() - C.east(), D.north() - C.north(), D.east() - C.east()) / u;
     274            EastNorth intersection = new EastNorth(
     275                    B.east() + q * (A.east() - B.east()),
     276                    B.north() + q * (A.north() - B.north()));
     277
     278            int snapToIntersectionThreshold
     279            = Main.pref.getInteger("edit.snap-intersection-threshold",10);
     280
     281            // only adjust to intersection if within snapToIntersectionThreshold pixel of mouse click; otherwise
     282            // fall through to default action.
     283            // (for semi-parallel lines, intersection might be miles away!)
     284            if (Main.map.mapView.getPoint(n).distance(Main.map.mapView.getPoint(intersection)) < snapToIntersectionThreshold) {
     285                n.setEastNorth(intersection);
     286                return;
     287            }
     288
     289        default:
     290            EastNorth P = n.getEastNorth();
     291            seg = segs.iterator().next();
     292            A = seg.a.getEastNorth();
     293            B = seg.b.getEastNorth();
     294            double a = P.distanceSq(B);
     295            double b = P.distanceSq(A);
     296            double c = A.distanceSq(B);
     297            q = (a - b + c) / (2*c);
     298            n.setEastNorth(new EastNorth(B.east() + q * (A.east() - B.east()), B.north() + q * (A.north() - B.north())));
     299        }
     300    }
     301   
     302    static double det(double a, double b, double c, double d) {
     303        return a * d - b * c;
     304    }
     305
     306    private static void pruneSuccsAndReverse(List<Integer> is) {
     307        //if (is.size() < 2) return;
     308
     309        HashSet<Integer> is2 = new HashSet<Integer>();
     310        for (int i : is) {
     311            if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
     312                is2.add(i);
     313            }
     314        }
     315        is.clear();
     316        is.addAll(is2);
     317        Collections.sort(is);
     318        Collections.reverse(is);
    185319    }
    186320
Note: See TracChangeset for help on using the changeset viewer.