/** * Compute weight and add edge to the graph * * @param way * @param from * @param to */ private void addEdge(Way way, Node from, Node to) { LatLon fromLL = from.getCoor(); LatLon toLL = from.getCoor(); if (fromLL == null || toLL == null) { return; } double length = fromLL.greatCircleDistance(toLL); OsmEdge edge = new OsmEdge(way, from, to); edge.setSpeed(12.1); graph.addEdge(from, to, edge); // weight = getWeight(way); double weight = getWeight(way, length); setWeight(edge, length); logger.debug( "edge for way " + way.getId() + "(from node " + from.getId() + " to node " + to.getId() + ") has weight: " + weight); ((DirectedWeightedMultigraph<Node, OsmEdge>) graph).setEdgeWeight(edge, weight); }
private boolean areCoordinatesValid( double minlat, double minlon, double maxlat, double maxlon) { return LatLon.isValidLat(minlat) && LatLon.isValidLat(maxlat) && LatLon.isValidLon(minlon) && LatLon.isValidLon(maxlon); }
private void testProj(Projection p) { double maxErrLat = 0, maxErrLon = 0; Bounds b = p.getWorldBoundsLatLon(); text += String.format("*** %s %s\n", p.toString(), p.toCode()); for (int num = 0; num < 1000; ++num) { double lat = rand.nextDouble() * (b.getMax().lat() - b.getMin().lat()) + b.getMin().lat(); double lon = rand.nextDouble() * (b.getMax().lon() - b.getMin().lon()) + b.getMin().lon(); LatLon ll = new LatLon(lat, lon); for (int i = 0; i < 10; ++i) { EastNorth en = p.latlon2eastNorth(ll); ll = p.eastNorth2latlon(en); } maxErrLat = Math.max(maxErrLat, Math.abs(lat - ll.lat())); maxErrLon = Math.max(maxErrLon, Math.abs(lon - ll.lon())); } String mark = ""; if (maxErrLat + maxErrLon > 1e-5) { mark = "--FAILED-- "; error = true; } text += String.format("%s errorLat: %s errorLon: %s\n", mark, maxErrLat, maxErrLon); }
/** * Formats a name for a history node * * @param node the node * @return the name */ @Override public String format(HistoryNode node) { StringBuilder sb = new StringBuilder(); String name; if (Main.pref.getBoolean("osm-primitives.localize-name", true)) { name = node.getLocalName(); } else { name = node.getName(); } if (name == null) { sb.append(node.getId()); } else { sb.append(name); } LatLon coord = node.getCoords(); if (coord != null) { sb.append(" (") .append(coord.latToString(CoordinateFormat.getDefaultFormat())) .append(", ") .append(coord.lonToString(CoordinateFormat.getDefaultFormat())) .append(")"); } decorateNameWithId(sb, node); return sb.toString(); }
/** output a point */ private void wayPoint(WayPoint pnt, int mode) { String type; switch (mode) { case WAY_POINT: type = "wpt"; break; case ROUTE_POINT: type = "rtept"; break; case TRACK_POINT: type = "trkpt"; break; default: throw new RuntimeException(tr("Unknown mode {0}.", mode)); } if (pnt != null) { LatLon c = pnt.getCoor(); String coordAttr = "lat=\"" + c.lat() + "\" lon=\"" + c.lon() + '\"'; if (pnt.attr.isEmpty()) { inline(type, coordAttr); } else { openAtt(type, coordAttr); writeAttr(pnt, WPT_KEYS); closeln(type); } } }
public static String getURL(LatLon pos, int zoom) { // Truncate lat and lon to something more sensible int decimals = (int) Math.pow(10, (zoom / 3)); double lat = (Math.round(pos.lat() * decimals)); lat /= decimals; double lon = (Math.round(pos.lon() * decimals)); lon /= decimals; return "http://www.openstreetmap.org/?lat=" + lat + "&lon=" + lon + "&zoom=" + zoom; }
@Override public void actionPerformed(GpsActionEvent event) { LatLon coordinates = event.getCoordinates(); System.out.println( getClass().getSimpleName() + " KOORD: " + coordinates.lat() + ", " + coordinates.lon() + " params: " + getParameters()); }
/** * Replies the download area. * * @return The download area */ public Bounds getDownloadArea() { double[] values = new double[4]; for (int i = 0; i < 4; i++) { try { values[i] = Double.parseDouble(latlon[i].getText()); } catch (NumberFormatException x) { return null; } } if (!LatLon.isValidLat(values[0]) || !LatLon.isValidLon(values[1])) return null; if (!LatLon.isValidLat(values[2]) || !LatLon.isValidLon(values[3])) return null; return new Bounds(values); }
/** * Single point Bounds defined by point [lat,lon]. Coordinates will be rounded to osm precision if * {@code roundToOsmPrecision} is true. * * @param lat latitude of given point. * @param lon longitude of given point. * @param roundToOsmPrecision defines if lat/lon will be rounded. * @since 6203 */ public Bounds(double lat, double lon, boolean roundToOsmPrecision) { // Do not call this(b, b) to avoid GPX performance issue (see #7028) until roundToOsmPrecision() // is improved if (roundToOsmPrecision) { this.minLat = LatLon.roundToOsmPrecision(lat); this.minLon = LatLon.roundToOsmPrecision(lon); } else { this.minLat = lat; this.minLon = lon; } this.maxLat = this.minLat; this.maxLon = this.minLon; }
/** * @param zoom level of the tile * @return how many pixels of the screen occupies one pixel of the tile */ private double getTileToScreenRatio(int zoom) { MapView mv = Main.map.mapView; LatLon topLeft = mv.getLatLon(0, 0); LatLon botLeft = mv.getLatLon(0, tileSource.getTileSize()); TileXY topLeftTile = tileSource.latLonToTileXY(topLeft.toCoordinate(), zoom); ICoordinate north = tileSource.tileXYToLatLon(topLeftTile.getXIndex(), topLeftTile.getYIndex(), zoom); ICoordinate south = tileSource.tileXYToLatLon(topLeftTile.getXIndex(), topLeftTile.getYIndex() + 1, zoom); return Math.abs((north.getLat() - south.getLat()) / (topLeft.lat() - botLeft.lat())); }
public Bounds( double minlat, double minlon, double maxlat, double maxlon, boolean roundToOsmPrecision) { if (roundToOsmPrecision) { this.minLat = LatLon.roundToOsmPrecision(minlat); this.minLon = LatLon.roundToOsmPrecision(minlon); this.maxLat = LatLon.roundToOsmPrecision(maxlat); this.maxLon = LatLon.roundToOsmPrecision(maxlon); } else { this.minLat = minlat; this.minLon = minlon; this.maxLat = maxlat; this.maxLon = maxlon; } }
/** * Returns the heading, in radians, that you have to use to get from this lat/lon to another. * * @param other the "destination" position * @return heading */ public double heading(LatLon other) { double rv; if (other.lat() == lat()) { rv = (other.lon() > lon() ? Math.PI / 2 : Math.PI * 3 / 2); } else { rv = Math.atan((other.lon() - lon()) / (other.lat() - lat())); if (rv < 0) { rv += Math.PI; } if (other.lon() < lon()) { rv += Math.PI; } } return rv; }
/** * Replies the length of the way, in metres, as computed by {@link LatLon#greatCircleDistance}. * * @return The length of the way, in metres * @since 4138 */ public double getLength() { double length = 0; Node lastN = null; for (Node n : nodes) { if (lastN != null) { LatLon lastNcoor = lastN.getCoor(); LatLon coor = n.getCoor(); if (lastNcoor != null && coor != null) { length += coor.greatCircleDistance(lastNcoor); } } lastN = n; } return length; }
/** * Angle between line AB and CD * * @param a Point A. * @param b Point B. * @param c Point C. * @param d Point D. * @return Angle in degrees. */ public static double angleOfLines(LatLon a, LatLon b, LatLon c, LatLon d) { return (Math.abs( Math.atan2(a.lat() - b.lat(), a.lon() - b.lon()) - Math.atan2(c.lat() - d.lat(), c.lon() - d.lon())) / Math.PI * 180) % 360; }
double getLength() { List<LatLon> pts = getPoints(); Iterator<LatLon> it1, it2; LatLon pp1, pp2; if (pts.size() < 2) return 0; it1 = pts.listIterator(0); it2 = pts.listIterator(1); double len = 0; for (int i = 0; i < pts.size() - 1; i++) { pp1 = it1.next(); pp2 = it2.next(); len += pp1.greatCircleDistance(pp2); } return len; }
public Bounds(double[] coords, boolean roundToOsmPrecision) { CheckParameterUtil.ensureParameterNotNull(coords, "coords"); if (coords.length != 4) throw new IllegalArgumentException( MessageFormat.format("Expected array of length 4, got {0}", coords.length)); if (roundToOsmPrecision) { this.minLat = LatLon.roundToOsmPrecision(coords[0]); this.minLon = LatLon.roundToOsmPrecision(coords[1]); this.maxLat = LatLon.roundToOsmPrecision(coords[2]); this.maxLon = LatLon.roundToOsmPrecision(coords[3]); } else { this.minLat = coords[0]; this.minLon = coords[1]; this.maxLat = coords[2]; this.maxLon = coords[3]; } }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((eastNorth == null) ? 0 : eastNorth.hashCode()); result = prime * result + ((latlon == null) ? 0 : latlon.hashCode()); result = prime * result + (modified ? 1231 : 1237); return result; }
protected Bounds build() { double minlon, minlat, maxlon, maxlat; try { minlat = Double.parseDouble(latlon[0].getText().trim()); minlon = Double.parseDouble(latlon[1].getText().trim()); maxlat = Double.parseDouble(latlon[2].getText().trim()); maxlon = Double.parseDouble(latlon[3].getText().trim()); } catch (NumberFormatException e) { return null; } if (!LatLon.isValidLon(minlon) || !LatLon.isValidLon(maxlon) || !LatLon.isValidLat(minlat) || !LatLon.isValidLat(maxlat)) return null; if (minlon > maxlon) return null; if (minlat > maxlat) return null; return new Bounds(minlat, minlon, maxlat, maxlon); }
@Override public void run() { if (!active) return; LatLon min = bbox.getMin(); LatLon max = bbox.getMax(); // Extend the area to download beond the view double t = Main.pref.getDouble("plugin.continuos_download.extra_download", 0.1); double dLat = Math.abs(max.lat() - min.lat()) * t; double dLon = Math.abs(max.lon() - min.lon()) * t; Bounds newBbox = new Bounds(min.lat() - dLat, min.lon() - dLon, max.lat() + dLat, max.lon() + dLon); // Do not try to download an area if the user have zoomed far out if (newBbox.getArea() < Main.pref.getDouble("plugin.continuos_download.max_area", 0.25)) getStrat().fetch(newBbox); }
private void infoSync(LatLon pos, ProgressMonitor progressMonitor) { progressMonitor.beginTask(null, 3); try { mRuian.prepareData(pos); htmlText = mRuian.getHtml(); coordinatesText = PointInfoUtils.formatCoordinates(pos.lat(), pos.lon()); } finally { progressMonitor.finishTask(); } progressMonitor.invalidate(); if (htmlText.length() == 0) { GuiHelper.runInEDTAndWait( () -> PointInfoUtils.showNotification( tr("Data not available.") + "\n(" + pos.toDisplayString() + ")", "warning")); return; } }
public void update(Camera camera, Perspective3D perspective3d) { Point3d cameraPoint = camera.getPoint(); Vector3d cameraRotation = camera.getAngle(); Perspective3D perspective = perspective3d; EastNorth eastNorth = perspective.toEastNorth(cameraPoint.x, -cameraPoint.z); Projection proj = Main.getProjection(); LatLon latLon = proj.eastNorth2latlon(eastNorth); // XXX update cache this.photo.setLat(latLon.lat()); this.photo.setLon(latLon.lon()); this.photo.setHeight(cameraPoint.y); this.photo.setRotate(cameraRotation.x, cameraRotation.y, cameraRotation.z); }
@Override protected void realRun() throws IOException, OsmTransferException { LatLon center = Main.getProjection().eastNorth2latlon(Main.map.mapView.getCenter()); scale = Settings.getScaleNumerator() / Settings.getScaleDivisor() / Math.cos(Math.toRadians(center.lat())); this.center = projection.latlon2eastNorth(center); try { SVGUniverse universe = new SVGUniverse(); universe.setVerbose(Main.pref.getBoolean("importvec.verbose", false)); for (File f : files) { if (f.isDirectory()) continue; if (canceled) { return; } SVGDiagram diagram = universe.getDiagram(f.toURI()); ShapeElement root = diagram.getRoot(); if (root == null) { throw new IOException("Can't find root SVG element"); } Rectangle2D bbox = root.getBoundingBox(); this.center = this.center.add(-bbox.getCenterX() * scale, bbox.getCenterY() * scale); processElement(root, null); } } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException(e); } LinkedList<Command> cmds = new LinkedList<>(); for (Node n : nodes) { cmds.add(new AddCommand(n)); } for (Way w : ways) { cmds.add(new AddCommand(w)); } Main.main.undoRedo.add(new SequenceCommand("Import primitives", cmds)); }
/** * Returns maximum number of simplified line points divided by line segment length max((k-1) / * (L(i,i+1)+L(i+1,i+2)+...+L(i+k-1,i+k))) [ i=1..n-k ] * * @param k - window size (number of points to average points per km */ public double getNodesPerKm(int k) { List<LatLon> pts = simplePoints; if (!wasSimplified()) pts = points; int n = pts.size(); if (n < 2) return 0; if (k < 2) k = 2; if (k > n) k = n; LatLon pp1, pp2 = null; Iterator<LatLon> it1, it2; it1 = pts.listIterator(0); it2 = pts.listIterator(1); double lens[] = new double[n]; for (int i = 0; i < n - 1; i++) { pp1 = it1.next(); // p1 = getPoint(pp1); pp2 = it2.next(); // p2 =sa getPoint(pp2); lens[i] = pp1.greatCircleDistance(pp2); } double pkm = 0, maxpkm = 0; double len = 0; int seg = 0; // averaged segments counts for (int i = 1; i < n; i++) { len += lens[i - 1]; // add next next point // remove old segment if (i > k) { seg = k; len -= lens[i - k - 1]; } else seg = i; if (i >= k || i == n - 1) { // len is length of points[i-windowSize] .. points[i] if (len > 0) pkm = seg / len * 1000; // System.out.println("i="+i+" pkm="+len+" pkm="+pkm); if (pkm > maxpkm) maxpkm = pkm; } } return Math.round(maxpkm); }
/** * Computes the distance between this lat/lon and another point on the earth. Uses Haversine * formular. * * @param other the other point. * @return distance in metres. */ public double greatCircleDistance(LatLon other) { double R = 6378135; double sinHalfLat = sin(toRadians(other.lat() - this.lat()) / 2); double sinHalfLon = sin(toRadians(other.lon() - this.lon()) / 2); double d = 2 * R * asin( sqrt( sinHalfLat * sinHalfLat + cos(toRadians(this.lat())) * cos(toRadians(other.lat())) * sinHalfLon * sinHalfLon)); // For points opposite to each other on the sphere, // rounding errors could make the argument of asin greater than 1 // (This should almost never happen.) if (java.lang.Double.isNaN(d)) { System.err.println("Error: NaN in greatCircleDistance"); d = PI * R; } return d; }
/** * Determines if the given point {@code ll} is within these bounds. * * @param ll The lat/lon to check * @return {@code true} if {@code ll} is within these bounds, {@code false} otherwise */ public boolean contains(LatLon ll) { if (ll.lat() < minLat || ll.lat() > maxLat) return false; if (crosses180thMeridian()) { if (ll.lon() > maxLon && ll.lon() < minLon) return false; } else { if (ll.lon() < minLon || ll.lon() > maxLon) return false; } return true; }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; OldNodeState other = (OldNodeState) obj; if (eastNorth == null) { if (other.eastNorth != null) return false; } else if (!eastNorth.equals(other.eastNorth)) return false; if (latlon == null) { if (other.latlon != null) return false; } else if (!latlon.equals(other.latlon)) return false; if (modified != other.modified) return false; return true; }
protected void check() { double value = 0; try { value = Double.parseDouble(tfLatValue.getText()); } catch (NumberFormatException ex) { setErrorMessage( tfLatValue, tr("The string ''{0}'' is not a valid double value.", tfLatValue.getText())); return; } if (!LatLon.isValidLat(value)) { setErrorMessage( tfLatValue, tr("Value for latitude in range [-90,90] required.", tfLatValue.getText())); return; } resetErrorMessage(tfLatValue); }
public void selectFeatures(int x, int y) { int pixelDelta = 2; LatLon clickUL = Main.map.mapView.getLatLon(x - pixelDelta, y - pixelDelta); LatLon clickLR = Main.map.mapView.getLatLon(x + pixelDelta, y + pixelDelta); Envelope envelope = new Envelope( Math.min(clickUL.lon(), clickLR.lon()), Math.max(clickUL.lon(), clickLR.lon()), Math.min(clickUL.lat(), clickLR.lat()), Math.max(clickUL.lat(), clickLR.lat())); ReferencedEnvelope mapArea = new ReferencedEnvelope(envelope, crsOSMI); Intersects filter = ff.intersects(ff.property("msGeometry"), ff.literal(mapArea)); // // Select features in all layers // content.layers().clear(); // Iterate through features and build a list that intersects the above // envelope for (int idx = 0; idx < arrFeatures.size(); ++idx) { OSMIFeatureTracker tracker = arrFeatures.get(idx); FeatureCollection<SimpleFeatureType, SimpleFeature> features = tracker.getFeatures(); SimpleFeatureSource tempfs = DataUtilities.source(features); FeatureCollection<SimpleFeatureType, SimpleFeature> selectedFeatures; try { selectedFeatures = tempfs.getFeatures(filter); Set<FeatureId> IDs = new HashSet<>(); try (FeatureIterator<SimpleFeature> iter = selectedFeatures.features()) { Main.info("Selected features " + selectedFeatures.size()); while (iter.hasNext()) { SimpleFeature feature = iter.next(); IDs.add(feature.getIdentifier()); } } geometryType = selectGeomType.get(idx + layerOffset); Style style = createDefaultStyle(idx + layerOffset, IDs); content.addLayer(new FeatureLayer(features, style)); } catch (IOException e) { Main.error(e); } } bIsChanged = true; }
/** * Determines whether a way is oriented clockwise. * * <p>Internals: Assuming a closed non-looping way, compute twice the area of the polygon using * the formula {@code 2 * area = sum (X[n] * Y[n+1] - X[n+1] * Y[n])}. If the area is negative the * way is ordered in a clockwise direction. * * <p>See http://paulbourke.net/geometry/polyarea/ * * @param w the way to be checked. * @return true if and only if way is oriented clockwise. * @throws IllegalArgumentException if way is not closed (see {@link Way#isClosed}). */ public static boolean isClockwise(Way w) { if (!w.isClosed()) { throw new IllegalArgumentException("Way must be closed to check orientation."); } double area2 = 0.; int nodesCount = w.getNodesCount(); for (int node = 1; node <= /*sic! consider last-first as well*/ nodesCount; node++) { LatLon coorPrev = w.getNode(node - 1).getCoor(); LatLon coorCurr = w.getNode(node % nodesCount).getCoor(); area2 += coorPrev.lon() * coorCurr.lat(); area2 -= coorCurr.lon() * coorPrev.lat(); } return area2 < 0; }
@Override public void paint(Graphics2D g, MapView mv, Bounds box) { LatLon min = box.getMin(); LatLon max = box.getMax(); Envelope envelope2 = new Envelope( Math.min(min.lat(), max.lat()), Math.max(min.lat(), max.lat()), Math.min(min.lon(), max.lon()), Math.max(min.lon(), max.lon())); ReferencedEnvelope mapArea = new ReferencedEnvelope(envelope2, crsOSMI); renderer.setInteractive(false); renderer.paint(g, mv.getBounds(), mapArea); bIsChanged = false; }