Package org.openstreetmap.josm.data.coor

Examples of org.openstreetmap.josm.data.coor.EastNorth


        if (segmentOnly && offset <= 0)
            return p1;
        else if (segmentOnly && offset >= 1)
            return p2;
        else
            return new EastNorth(p1.getX() + ldx * offset, p1.getY() + ldy * offset);
    }
View Full Code Here


    public static Area getArea(List<Node> polygon) {
        Path2D path = new Path2D.Double();

        boolean begin = true;
        for (Node n : polygon) {
            EastNorth en = n.getEastNorth();
            if (en != null) {
                if (begin) {
                    path.moveTo(en.getX(), en.getY());
                    begin = false;
                } else {
                    path.lineTo(en.getX(), en.getY());
                }
            }
        }
        if (!begin) {
            path.closePath();
View Full Code Here

        BigDecimal north = BigDecimal.ZERO;
        BigDecimal east = BigDecimal.ZERO;

        // See https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon for the equation used here
        for (int i = 0; i < nodes.size(); i++) {
            EastNorth n0 = nodes.get(i).getEastNorth();
            EastNorth n1 = nodes.get((i+1) % nodes.size()).getEastNorth();

            if (n0 != null && n1 != null && n0.isValid() && n1.isValid()) {
                BigDecimal x0 = new BigDecimal(n0.east());
                BigDecimal y0 = new BigDecimal(n0.north());
                BigDecimal x1 = new BigDecimal(n1.east());
                BigDecimal y1 = new BigDecimal(n1.north());

                BigDecimal k = x0.multiply(y1, MathContext.DECIMAL128).subtract(y0.multiply(x1, MathContext.DECIMAL128));

                area = area.add(k, MathContext.DECIMAL128);
                east = east.add(k.multiply(x0.add(x1, MathContext.DECIMAL128), MathContext.DECIMAL128));
                north = north.add(k.multiply(y0.add(y1, MathContext.DECIMAL128), MathContext.DECIMAL128));
            }
        }

        BigDecimal d = new BigDecimal(3, MathContext.DECIMAL128); // 1/2 * 6 = 3
        area  = area.multiply(d, MathContext.DECIMAL128);
        if (area.compareTo(BigDecimal.ZERO) != 0) {
            north = north.divide(area, MathContext.DECIMAL128);
            east = east.divide(area, MathContext.DECIMAL128);
        }

        return new EastNorth(east.doubleValue(), north.doubleValue());
    }
View Full Code Here

        double[] a = new double[nc];
        double[] b = new double[nc];
        double[] c = new double[nc];
        // Compute equation of bisector
        for(int i = 0; i < nc; i++) {
            EastNorth pt1 = nodes.get(i).getEastNorth();
            EastNorth pt2 = nodes.get((i+1) % nc).getEastNorth();
            a[i] = pt1.east() - pt2.east();
            b[i] = pt1.north() - pt2.north();
            double d = Math.sqrt(a[i]*a[i] + b[i]*b[i]);
            if(d == 0) return null;
            a[i] /= d;
            b[i] /= d;
            double xC = (pt1.east() + pt2.east()) / 2;
            double yC = (pt1.north() + pt2.north()) / 2;
            c[i] = -(a[i]*xC + b[i]*yC);
        }
        // At.A = [aij]
        double a11 = 0, a12 = 0, a22 = 0;
        // At.Y = [bi]
        double b1 = 0, b2 = 0;
        for(int i = 0; i < nc; i++) {
            a11 += a[i]*a[i];
            a12 += a[i]*b[i];
            a22 += b[i]*b[i];
            b1 -= a[i]*c[i];
            b2 -= b[i]*c[i];
        }
        // (At.A)^-1 = [invij]
        double det = a11*a22 - a12*a12;
        if(Math.abs(det) < 1e-5) return null;
        double inv11 = a22/det;
        double inv12 = -a12/det;
        double inv22 = a11/det;
        // center (xC, yC) = (At.A)^-1.At.y
        double xC = inv11*b1 + inv12*b2;
        double yC = inv12*b1 + inv22*b2;
        return new EastNorth(xC, yC);
    }
View Full Code Here

        Double segmentLenght = sp1.distance(sp2);
        Double altitudeAngle = getSegmentAngle(sp1, sp2) + Math.PI / 2;

        // Taking a random point on the altitude line (angle is known).
        EastNorth ap2 = new EastNorth(ap.east() + 1000
                * Math.cos(altitudeAngle), ap.north() + 1000
                * Math.sin(altitudeAngle));

        // Finding the intersection of two lines
        EastNorth resultCandidate = Geometry.getLineLineIntersection(sp1, sp2,
                ap, ap2);

        // Filtering result
        if (resultCandidate != null
                && resultCandidate.distance(sp1) * .999 < segmentLenght
                && resultCandidate.distance(sp2) * .999 < segmentLenght) {
            return resultCandidate;
        } else {
            return null;
        }
    }
View Full Code Here

                    w.calcDirections(Direction.RIGHT);
                    int directionOffset = angleToDirectionChange(w.heading - refHeading, TOLERANCE2);
                    w.calcDirections(Direction.RIGHT.changeBy(directionOffset));
                    if (angleToDirectionChange(refHeading - w.heading, TOLERANCE2) != 0) throw new RuntimeException();
                }
                EastNorth totSum = new EastNorth(0., 0.);
                for (WayData w : wayDataList) {
                    totSum = EN.sum(totSum, w.segSum);
                }
                headingAll = EN.polar(new EastNorth(0., 0.), totSum);
            }
            else {
                headingAll = EN.polar(headingNodes.get(0).getEastNorth(), headingNodes.get(1).getEastNorth());
                for (WayData w : wayDataList) {
                    w.calcDirections(Direction.RIGHT);
                    int directionOffset = angleToDirectionChange(w.heading - headingAll, TOLERANCE2);
                    w.calcDirections(Direction.RIGHT.changeBy(directionOffset));
                }
            }
        } catch (RejectedAngleException ex) {
            throw new InvalidUserInputException(
                    tr("<html>Please make sure all selected ways head in a similar direction<br>"+
                    "or orthogonalize them one by one.</html>"), ex);
        }

        // put the nodes of all ways in a set
        final HashSet<Node> allNodes = new HashSet<>();
        for (WayData w : wayDataList) {
            for (Node n : w.way.getNodes()) {
                allNodes.add(n);
            }
        }

        // the new x and y value for each node
        final HashMap<Node, Double> nX = new HashMap<>();
        final HashMap<Node, Double> nY = new HashMap<>();

        // calculate the centroid of all nodes
        // it is used as rotation center
        EastNorth pivot = new EastNorth(0., 0.);
        for (Node n : allNodes) {
            pivot = EN.sum(pivot, n.getEastNorth());
        }
        pivot = new EastNorth(pivot.east() / allNodes.size(), pivot.north() / allNodes.size());

        // rotate
        for (Node n: allNodes) {
            EastNorth tmp = EN.rotate_cc(pivot, n.getEastNorth(), - headingAll);
            nX.put(n, tmp.east());
            nY.put(n, tmp.north());
        }

        // orthogonalize
        final Direction[] HORIZONTAL = {Direction.RIGHT, Direction.LEFT};
        final Direction[] VERTICAL = {Direction.UP, Direction.DOWN};
        final Direction[][] ORIENTATIONS = {HORIZONTAL, VERTICAL};
        for (Direction[] orientation : ORIENTATIONS){
            final HashSet<Node> s = new HashSet<>(allNodes);
            int s_size = s.size();
            for (int dummy = 0; dummy < s_size; ++dummy) {
                if (s.isEmpty()) {
                    break;
                }
                final Node dummy_n = s.iterator().next();     // pick arbitrary element of s

                final HashSet<Node> cs = new HashSet<>(); // will contain each node that can be reached from dummy_n
                cs.add(dummy_n);                              // walking only on horizontal / vertical segments

                boolean somethingHappened = true;
                while (somethingHappened) {
                    somethingHappened = false;
                    for (WayData w : wayDataList) {
                        for (int i=0; i < w.nSeg; ++i) {
                            Node n1 = w.way.getNodes().get(i);
                            Node n2 = w.way.getNodes().get(i+1);
                            if (Arrays.asList(orientation).contains(w.segDirections[i])) {
                                if (cs.contains(n1) && ! cs.contains(n2)) {
                                    cs.add(n2);
                                    somethingHappened = true;
                                }
                                if (cs.contains(n2) && ! cs.contains(n1)) {
                                    cs.add(n1);
                                    somethingHappened = true;
                                }
                            }
                        }
                    }
                }
                for (Node n : cs) {
                    s.remove(n);
                }

                final HashMap<Node, Double> nC = (orientation == HORIZONTAL) ? nY : nX;

                double average = 0;
                for (Node n : cs) {
                    average += nC.get(n).doubleValue();
                }
                average = average / cs.size();

                // if one of the nodes is a heading node, forget about the average and use its value
                for (Node fn : headingNodes) {
                    if (cs.contains(fn)) {
                        average = nC.get(fn);
                    }
                }

                // At this point, the two heading nodes (if any) are horizontally aligned, i.e. they
                // have the same y coordinate. So in general we shouldn't find them in a vertical string
                // of segments. This can still happen in some pathological cases (see #7889). To avoid
                // both heading nodes collapsing to one point, we simply skip this segment string and
                // don't touch the node coordinates.
                if (orientation == VERTICAL && headingNodes.size() == 2 && cs.containsAll(headingNodes)) {
                    continue;
                }

                for (Node n : cs) {
                    nC.put(n, average);
                }
            }
            if (!s.isEmpty()) throw new RuntimeException();
        }

        // rotate back and log the change
        final Collection<Command> commands = new LinkedList<>();
        for (Node n: allNodes) {
            EastNorth tmp = new EastNorth(nX.get(n), nY.get(n));
            tmp = EN.rotate_cc(pivot, tmp, headingAll);
            final double dx = tmp.east()  - n.getEastNorth().east();
            final double dy = tmp.north() - n.getEastNorth().north();
            if (headingNodes.contains(n)) { // The heading nodes should not have changed
                final double EPSILON = 1E-6;
                if (Math.abs(dx) > Math.abs(EPSILON * tmp.east()) ||
                        Math.abs(dy) > Math.abs(EPSILON * tmp.east()))
                    throw new AssertionError();
            }
            else {
                OrthogonalizeAction.rememberMovements.put(n, new EastNorth(dx, dy));
                commands.add(new MoveCommand(n, dx, dy));
            }
        }
        return commands;
    }
View Full Code Here

            try {
                for (OsmPrimitive p : sel) {
                    if (! (p instanceof Node)) throw new InvalidUserInputException();
                    Node n = (Node) p;
                    if (rememberMovements.containsKey(n)) {
                        EastNorth tmp = rememberMovements.get(n);
                        commands.add(new MoveCommand(n, - tmp.east(), - tmp.north()));
                        rememberMovements.remove(n);
                    }
                }
                if (!commands.isEmpty()) {
                    Main.main.undoRedo.add(new SequenceCommand(tr("Orthogonalize / Undo"), commands));
View Full Code Here

         * @throws InvalidUserInputException
         */
        public void calcDirections(Direction pInitialDirection) throws InvalidUserInputException {
            final EastNorth[] en = new EastNorth[nNode]; // alias: way.getNodes().get(i).getEastNorth() ---> en[i]
            for (int i=0; i < nNode; i++) {
                en[i] = new EastNorth(way.getNodes().get(i).getEastNorth().east(), way.getNodes().get(i).getEastNorth().north());
            }
            segDirections = new Direction[nSeg];
            Direction direction = pInitialDirection;
            segDirections[0] = direction;
            for (int i=0; i < nSeg - 1; i++) {
                double h1 = EN.polar(en[i],en[i+1]);
                double h2 = EN.polar(en[i+1],en[i+2]);
                try {
                    direction = direction.changeBy(angleToDirectionChange(h2 - h1, TOLERANCE1));
                } catch (RejectedAngleException ex) {
                    throw new InvalidUserInputException(tr("Please select ways with angles of approximately 90 or 180 degrees."), ex);
                }
                segDirections[i+1] = direction;
            }

            // sum up segments
            EastNorth h = new EastNorth(0.,0.);
            EastNorth v = new EastNorth(0.,0.);
            for (int i = 0; i < nSeg; ++i) {
                EastNorth segment = EN.diff(en[i+1], en[i]);
                if      (segDirections[i] == Direction.RIGHT) {
                    h = EN.sum(h,segment);
                } else if (segDirections[i] == Direction.UP) {
                    v = EN.sum(v,segment);
                } else if (segDirections[i] == Direction.LEFT) {
                    h = EN.diff(h,segment);
                } else if (segDirections[i] == Direction.DOWN) {
                    v = EN.diff(v,segment);
                } else throw new IllegalStateException();
                /**
                 * When summing up the length of the sum vector should increase.
                 * However, it is possible to construct ways, such that this assertion fails.
                 * So only uncomment this for testing
                 **/
                //                if (segDirections[i].ordinal() % 2 == 0) {
                //                    if (EN.abs(h) < lh) throw new AssertionError();
                //                    lh = EN.abs(h);
                //                } else {
                //                    if (EN.abs(v) < lv) throw new AssertionError();
                //                    lv = EN.abs(v);
                //                }
            }
            // rotate the vertical vector by 90 degrees (clockwise) and add it to the horizontal vector
            segSum = EN.sum(h, new EastNorth(v.north(), - v.east()));
            //            if (EN.abs(segSum) < lh) throw new AssertionError();
            this.heading = EN.polar(new EastNorth(0.,0.), segSum);
        }
View Full Code Here

            double sinPhi = Math.sin(angle);
            double x = en.east() - pivot.east();
            double y = en.north() - pivot.north();
            double nx =  cosPhi * x - sinPhi * y + pivot.east();
            double ny =  sinPhi * x + cosPhi * y + pivot.north();
            return new EastNorth(nx, ny);
        }
View Full Code Here

            double nx =  cosPhi * x - sinPhi * y + pivot.east();
            double ny =  sinPhi * x + cosPhi * y + pivot.north();
            return new EastNorth(nx, ny);
        }
        public static EastNorth sum(EastNorth en1, EastNorth en2) {
            return new EastNorth(en1.east() + en2.east(), en1.north() + en2.north());
        }
View Full Code Here

TOP

Related Classes of org.openstreetmap.josm.data.coor.EastNorth

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.