Changeset 11858 in josm for trunk/src/org/openstreetmap/josm/gui
- Timestamp:
- 2017-04-09T11:08:10+02:00 (7 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
r11840 r11858 638 638 mvs = mvs.movedTo(mvs.getCenter(), newCenter); 639 639 Point2D enOrigin = mvs.getPointFor(new EastNorth(0, 0)).getInView(); 640 Point2D enOriginAligned = new Point2D.Double(Math.round(enOrigin.getX()), Math.round(enOrigin.getY())); 640 // as a result of the alignment, it is common to round "half integer" values 641 // like 1.49999, which is numerically unstable; add small epsilon to resolve this 642 double EPSILON = 1e-3; 643 Point2D enOriginAligned = new Point2D.Double( 644 Math.round(enOrigin.getX()) + EPSILON, 645 Math.round(enOrigin.getY()) + EPSILON); 641 646 EastNorth enShift = mvs.getForView(enOriginAligned.getX(), enOriginAligned.getY()).getEastNorth(); 642 647 newCenter = newCenter.subtract(enShift); -
trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
r11846 r11858 49 49 import javax.swing.AbstractAction; 50 50 import javax.swing.Action; 51 import javax.swing.BorderFactory;52 51 import javax.swing.JCheckBoxMenuItem; 53 52 import javax.swing.JLabel; … … 57 56 import javax.swing.JPopupMenu; 58 57 import javax.swing.JSeparator; 59 import javax.swing.JTextField;60 58 import javax.swing.Timer; 61 59 … … 88 86 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 89 87 import org.openstreetmap.josm.data.preferences.IntegerProperty; 88 import org.openstreetmap.josm.data.projection.Projection; 89 import org.openstreetmap.josm.data.projection.Projections; 90 90 import org.openstreetmap.josm.gui.ExtendedDialog; 91 91 import org.openstreetmap.josm.gui.MapFrame; … … 96 96 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; 97 97 import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings.FilterChangeListener; 98 import org.openstreetmap.josm.gui.layer.imagery.ReprojectionTile; 98 99 import org.openstreetmap.josm.gui.layer.imagery.TileAnchor; 99 100 import org.openstreetmap.josm.gui.layer.imagery.TileCoordinateConverter; … … 109 110 import org.openstreetmap.josm.tools.MemoryManager.MemoryHandle; 110 111 import org.openstreetmap.josm.tools.MemoryManager.NotEnoughMemoryException; 112 import org.openstreetmap.josm.tools.Utils; 111 113 112 114 /** … … 185 187 private final ImageryAdjustAction adjustAction = new ImageryAdjustAction(this); 186 188 // prepared to be moved to the painter 187 pr ivateTileCoordinateConverter coordinateConverter;189 protected TileCoordinateConverter coordinateConverter; 188 190 189 191 /** … … 346 348 public Object getInfoComponent() { 347 349 JPanel panel = (JPanel) super.getInfoComponent(); 350 List<List<String>> content = new ArrayList<>(); 348 351 EastNorth offset = getDisplaySettings().getDisplacement(); 349 352 if (offset.distanceSq(0, 0) > 1e-10) { 350 panel.add(new JLabel(tr("Offset: ") + offset.east() + ';' + offset.north()), GBC.eol().insets(0, 5, 10, 0)); 353 content.add(Arrays.asList(tr("Offset"), offset.east() + ";" + offset.north())); 354 } 355 if (coordinateConverter.requiresReprojection()) { 356 content.add(Arrays.asList(tr("Tile download projection"), tileSource.getServerCRS())); 357 content.add(Arrays.asList(tr("Tile display projection"), Main.getProjection().toCode())); 358 } 359 content.add(Arrays.asList(tr("Current zoom"), Integer.toString(currentZoomLevel))); 360 for (List<String> entry: content) { 361 panel.add(new JLabel(entry.get(0) + ':'), GBC.std()); 362 panel.add(GBC.glue(5, 0), GBC.std()); 363 panel.add(createTextField(entry.get(1)), GBC.eol().fill(GBC.HORIZONTAL)); 351 364 } 352 365 return panel; … … 363 376 * @return average number of screen pixels per tile pixel 364 377 */ 365 pr ivatedouble getScaleFactor(int zoom) {378 protected double getScaleFactor(int zoom) { 366 379 if (coordinateConverter != null) { 367 380 return coordinateConverter.getScaleFactor(zoom); … … 384 397 */ 385 398 int intResult = (int) Math.round(result + 1 + ZOOM_OFFSET.get() / 1.9); 386 387 intResult = Math.min(intResult, getMaxZoomLvl()); 388 intResult = Math.max(intResult, getMinZoomLvl()); 399 intResult = Utils.clamp(intResult, getMinZoomLvl(), getMaxZoomLvl()); 389 400 return intResult; 390 401 } … … 398 409 private ShowTileInfoAction() { 399 410 super(tr("Show tile info")); 411 setEnabled(clickedTileHolder.getTile() != null); 400 412 } 401 413 402 414 private String getSizeString(int size) { 403 415 return new StringBuilder().append(size).append('x').append(size).toString(); 404 }405 406 private JTextField createTextField(String text) {407 JTextField ret = new JTextField(text);408 ret.setEditable(false);409 ret.setBorder(BorderFactory.createEmptyBorder());410 return ret;411 416 } 412 417 … … 426 431 } 427 432 428 String[][] content = { 429 {"Tile name", clickedTile.getKey()}, 430 {"Tile url", url}, 431 {"Tile size", getSizeString(clickedTile.getTileSource().getTileSize()) }, 432 {"Tile display size", new StringBuilder().append(displaySize.getWidth()) 433 .append('x') 434 .append(displaySize.getHeight()).toString()}, 435 }; 436 437 for (String[] entry: content) { 438 panel.add(new JLabel(tr(entry[0]) + ':'), GBC.std()); 433 List<List<String>> content = new ArrayList<>(); 434 content.add(Arrays.asList(tr("Tile name"), clickedTile.getKey())); 435 content.add(Arrays.asList(tr("Tile URL"), url)); 436 content.add(Arrays.asList(tr("Tile size"), 437 getSizeString(clickedTile.getTileSource().getTileSize()))); 438 content.add(Arrays.asList(tr("Tile display size"), 439 new StringBuilder().append(displaySize.getWidth()) 440 .append('x') 441 .append(displaySize.getHeight()).toString())); 442 if (coordinateConverter.requiresReprojection()) { 443 content.add(Arrays.asList(tr("Reprojection"), 444 clickedTile.getTileSource().getServerCRS() + 445 " -> " + Main.getProjection().toCode())); 446 BufferedImage img = clickedTile.getImage(); 447 if (img != null) { 448 content.add(Arrays.asList(tr("Reprojected tile size"), 449 img.getWidth() + "x" + img.getHeight())); 450 451 } 452 } 453 for (List<String> entry: content) { 454 panel.add(new JLabel(entry.get(0) + ':'), GBC.std()); 439 455 panel.add(GBC.glue(5, 0), GBC.std()); 440 panel.add(createTextField(entry [1]), GBC.eol().fill(GBC.HORIZONTAL));456 panel.add(createTextField(entry.get(1)), GBC.eol().fill(GBC.HORIZONTAL)); 441 457 } 442 458 … … 462 478 private LoadTileAction() { 463 479 super(tr("Load tile")); 480 setEnabled(clickedTileHolder.getTile() != null); 464 481 } 465 482 … … 946 963 Tile tile = getTile(x, y, zoom); 947 964 if (tile == null) { 948 tile = new Tile(tileSource, x, y, zoom); 965 if (coordinateConverter.requiresReprojection()) { 966 tile = new ReprojectionTile(tileSource, x, y, zoom); 967 } else { 968 tile = new Tile(tileSource, x, y, zoom); 969 } 949 970 tileCache.addTile(tile); 950 971 } … … 1021 1042 1022 1043 /** 1023 * Invalidate the layer at a time in the future so t aht the user still sees the interface responsive.1044 * Invalidate the layer at a time in the future so that the user still sees the interface responsive. 1024 1045 */ 1025 1046 private void invalidateLater() { … … 1055 1076 } 1056 1077 1057 /**1078 /** 1058 1079 * Draw a tile image on screen. 1059 1080 * @param g the Graphics2D … … 1066 1087 AffineTransform imageToScreen = anchorImage.convert(anchorScreen); 1067 1088 Point2D screen0 = imageToScreen.transform(new Point.Double(0, 0), null); 1068 Point2D screen1 = imageToScreen.transform(new Point.Double(toDrawImg.getWidth(), toDrawImg.getHeight()), null); 1089 Point2D screen1 = imageToScreen.transform(new Point.Double( 1090 toDrawImg.getWidth(), toDrawImg.getHeight()), null); 1091 1069 1092 Shape oldClip = null; 1070 1093 if (clip != null) { … … 1085 1108 boolean miss = false; 1086 1109 BufferedImage img = null; 1110 TileAnchor anchorImage = null; 1087 1111 if (!tile.isLoaded() || tile.hasError()) { 1088 1112 miss = true; 1089 1113 } else { 1090 img = getLoadedTileImage(tile); 1091 if (img == null) { 1114 synchronized (tile) { 1115 img = getLoadedTileImage(tile); 1116 anchorImage = getAnchor(tile, img); 1117 } 1118 if (img == null || anchorImage == null) { 1092 1119 miss = true; 1093 1120 } … … 1097 1124 return; 1098 1125 } 1099 TileAnchor anchorImage = new TileAnchor( 1100 new Point.Double(0, 0), 1101 new Point.Double(img.getWidth(), img.getHeight())); 1102 img = applyImageProcessors((BufferedImage) img); 1126 1127 img = applyImageProcessors(img); 1128 1103 1129 TileAnchor anchorScreen = coordinateConverter.getScreenAnchorForTile(tile); 1104 1130 synchronized (paintMutex) { … … 1106 1132 drawImageInside(g, img, anchorImage, anchorScreen, null); 1107 1133 } 1134 if (tile instanceof ReprojectionTile) { 1135 // This means we have a reprojected tile in memory cache, but not at 1136 // current scale. Generally, the positioning of the tile will still 1137 // be correct, but for best image quality, the tile should be 1138 // reprojected to the target scale. The original tile image should 1139 // still be in disk cache, so this is fairly cheap. 1140 if (((ReprojectionTile) tile).needsUpdate(Main.map.mapView.getScale())) { 1141 loadTile(tile, true); 1142 } 1143 } 1144 1108 1145 }, missed::add); 1109 1146 … … 1128 1165 boolean miss = false; 1129 1166 BufferedImage img = null; 1167 TileAnchor anchorImage = null; 1130 1168 if (!tile.isLoaded() || tile.hasError()) { 1131 1169 miss = true; 1132 1170 } else { 1133 img = getLoadedTileImage(tile); 1134 if (img == null) { 1171 synchronized (tile) { 1172 img = getLoadedTileImage(tile); 1173 anchorImage = getAnchor(tile, img); 1174 } 1175 1176 if (img == null || anchorImage == null) { 1135 1177 miss = true; 1136 1178 } … … 1140 1182 continue; 1141 1183 } 1142 TileAnchor anchorImage = new TileAnchor(1143 new Point.Double(0, 0),1144 new Point.Double(img.getWidth(), img.getHeight()));1145 1184 1146 1185 // applying all filters to this layer … … 1159 1198 } 1160 1199 return missedTiles; 1200 } 1201 1202 private TileAnchor getAnchor(Tile tile, BufferedImage image) { 1203 if (tile instanceof ReprojectionTile) { 1204 return ((ReprojectionTile) tile).getAnchor(); 1205 } else { 1206 return new TileAnchor(new Point.Double(0, 0), new Point.Double(image.getWidth(), image.getHeight())); 1207 } 1161 1208 } 1162 1209 … … 1188 1235 } 1189 1236 1190 private void paintTileText(Tile tile, Graphics g, MapView mv) {1237 private void paintTileText(Tile tile, Graphics2D g) { 1191 1238 if (tile == null) { 1192 1239 return; … … 1218 1265 } 1219 1266 1220 int xCursor = -1;1221 int yCursor = -1;1222 1267 if (Main.isDebugEnabled()) { 1223 if (yCursor < tile.getYtile()) { 1224 if (Math.abs(tile.getYtile() % 32) == 31) { 1225 g.fillRect(0, y - 1, mv.getWidth(), 3); 1226 } else { 1227 g.drawLine(0, y, mv.getWidth(), y); 1228 } 1229 //yCursor = t.getYtile(); 1230 } 1231 // This draws the vertical lines for the entire column. Only draw them for the top tile in the column. 1232 if (xCursor < tile.getXtile()) { 1233 if (tile.getXtile() % 32 == 0) { 1234 // level 7 tile boundary 1235 g.fillRect(x - 1, 0, 3, mv.getHeight()); 1236 } else { 1237 g.drawLine(x, 0, x, mv.getHeight()); 1238 } 1239 //xCursor = t.getXtile(); 1240 } 1268 // draw tile outline in semi-transparent red 1269 g.setColor(new Color(255, 0, 0, 50)); 1270 g.draw(coordinateConverter.getScreenQuadrilateralForTile(tile)); 1241 1271 } 1242 1272 } … … 1397 1427 */ 1398 1428 protected TileSet getTileSet(ProjectionBounds bounds, int zoom) { 1399 IProjected topLeftUnshifted = coordinateConverter.shiftDisplayToServer(bounds.getMin()); 1400 IProjected botRightUnshifted = coordinateConverter.shiftDisplayToServer(bounds.getMax()); 1401 TileXY t1 = tileSource.projectedToTileXY(topLeftUnshifted, zoom); 1402 TileXY t2 = tileSource.projectedToTileXY(botRightUnshifted, zoom); 1429 if (zoom == 0) 1430 return new TileSet(); 1431 TileXY t1, t2; 1432 if (coordinateConverter.requiresReprojection()) { 1433 Projection projCurrent = Main.getProjection(); 1434 Projection projServer = Projections.getProjectionByCode(tileSource.getServerCRS()); 1435 bounds = new ProjectionBounds( 1436 new EastNorth(coordinateConverter.shiftDisplayToServer(bounds.getMin())), 1437 new EastNorth(coordinateConverter.shiftDisplayToServer(bounds.getMax()))); 1438 bounds = projServer.getEastNorthBoundsBox(bounds, projCurrent); 1439 t1 = tileSource.projectedToTileXY(bounds.getMin().toProjected(), zoom); 1440 t2 = tileSource.projectedToTileXY(bounds.getMax().toProjected(), zoom); 1441 } else { 1442 IProjected topLeftUnshifted = coordinateConverter.shiftDisplayToServer(bounds.getMin()); 1443 IProjected botRightUnshifted = coordinateConverter.shiftDisplayToServer(bounds.getMax()); 1444 t1 = tileSource.projectedToTileXY(topLeftUnshifted, zoom); 1445 t2 = tileSource.projectedToTileXY(botRightUnshifted, zoom); 1446 } 1403 1447 return new TileSet(t1, t2, zoom); 1404 1448 } … … 1593 1637 // The current zoom tileset should have all of its tiles due to the loadAllTiles(), unless it to tooLarge() 1594 1638 for (Tile t : ts.allExistingTiles()) { 1595 this.paintTileText(t, g , mv);1639 this.paintTileText(t, g); 1596 1640 } 1597 1641 … … 1640 1684 Main.debug("getTileForPixelpos("+px+", "+py+')'); 1641 1685 } 1642 Point clicked = new Point(px, py); 1643 TileSet ts = getVisibleTileSet(); 1644 1645 if (!ts.tooLarge()) { 1646 ts.loadAllTiles(false); // make sure there are tile objects for all tiles 1647 } 1648 Stream<Tile> clickedTiles = ts.allExistingTiles().stream() 1649 .filter(t -> coordinateConverter.getRectangleForTile(t).contains(clicked)); 1650 if (Main.isTraceEnabled()) { 1651 clickedTiles = clickedTiles.peek(t -> Main.trace("Clicked on tile: " + t.getXtile() + ' ' + t.getYtile() + 1652 " currentZoomLevel: " + currentZoomLevel)); 1653 } 1654 return clickedTiles.findAny().orElse(null); 1686 TileXY xy = coordinateConverter.getTileforPixel(px, py, currentZoomLevel); 1687 return getTile(xy.getXIndex(), xy.getYIndex(), currentZoomLevel); 1655 1688 } 1656 1689 -
trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java
r11785 r11858 2 2 package org.openstreetmap.josm.gui.layer; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr;5 4 import static org.openstreetmap.josm.tools.I18n.trc; 6 5 … … 11 10 import java.awt.image.BufferedImageOp; 12 11 import java.util.ArrayList; 12 import java.util.Arrays; 13 import java.util.Collection; 13 14 import java.util.List; 14 15 15 16 import javax.swing.AbstractAction; 16 17 import javax.swing.Action; 18 import javax.swing.BorderFactory; 17 19 import javax.swing.Icon; 18 20 import javax.swing.JCheckBoxMenuItem; … … 24 26 import javax.swing.JPopupMenu; 25 27 import javax.swing.JSeparator; 28 import javax.swing.JTextField; 26 29 27 30 import org.openstreetmap.josm.Main; … … 33 36 import org.openstreetmap.josm.gui.layer.imagery.ImageryFilterSettings; 34 37 import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings; 35 import org.openstreetmap.josm.gui.widgets.UrlLabel;36 38 import org.openstreetmap.josm.tools.GBC; 39 import static org.openstreetmap.josm.tools.I18n.tr; 37 40 import org.openstreetmap.josm.tools.ImageProvider; 38 41 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; … … 146 149 public void mergeFrom(Layer from) { 147 150 } 151 152 public abstract Collection<String> getNativeProjections(); 148 153 149 154 @Override … … 152 157 panel.add(new JLabel(getToolTipText()), GBC.eol()); 153 158 if (info != null) { 154 String url = info.getUrl(); 155 if (url != null) { 156 panel.add(new JLabel(tr("URL: ")), GBC.std().insets(0, 5, 2, 0)); 157 panel.add(new UrlLabel(url), GBC.eol().insets(2, 5, 10, 0)); 159 List<List<String>> content = new ArrayList<>(); 160 content.add(Arrays.asList(tr("Name"), info.getName())); 161 content.add(Arrays.asList(tr("Type"), info.getImageryType().getTypeString().toUpperCase())); 162 content.add(Arrays.asList(tr("URL"), info.getUrl())); 163 content.add(Arrays.asList(tr("Id"), info.getId() == null ? "-" : info.getId())); 164 if (info.getMinZoom() != 0) { 165 content.add(Arrays.asList(tr("Min. zoom"), Integer.toString(info.getMinZoom()))); 166 } 167 if (info.getMaxZoom() != 0) { 168 content.add(Arrays.asList(tr("Max. zoom"), Integer.toString(info.getMaxZoom()))); 169 } 170 if (info.getDescription() != null) { 171 content.add(Arrays.asList(tr("Description"), info.getDescription())); 172 } 173 content.add(Arrays.asList(tr("Native projections"), Utils.join(", ", getNativeProjections()))); 174 for (List<String> entry: content) { 175 panel.add(new JLabel(entry.get(0) + ':'), GBC.std()); 176 panel.add(GBC.glue(5, 0), GBC.std()); 177 panel.add(createTextField(entry.get(1)), GBC.eol().fill(GBC.HORIZONTAL)); 158 178 } 159 179 } 160 180 return panel; 181 } 182 183 protected JTextField createTextField(String text) { 184 JTextField ret = new JTextField(text); 185 ret.setEditable(false); 186 ret.setBorder(BorderFactory.createEmptyBorder()); 187 return ret; 161 188 } 162 189 -
trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
r11167 r11858 6 6 import java.util.ArrayList; 7 7 import java.util.Collection; 8 import java.util.Collections; 9 import java.util.List; 8 10 9 11 import org.apache.commons.jcs.access.CacheAccess; … … 79 81 80 82 @Override 81 public final boolean isProjectionSupported(Projection proj) { 82 return "EPSG:3857".equals(proj.toCode()) || "EPSG:4326".equals(proj.toCode()); 83 } 84 85 @Override 86 public final String nameSupportedProjections() { 87 return tr("EPSG:4326 and Mercator projection are supported"); 83 public Collection<String> getNativeProjections() { 84 return Collections.singletonList("EPSG:3857"); 88 85 } 89 86 … … 161 158 return new ScaleList(scales); 162 159 } 163 160 } -
trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
r11848 r11858 7 7 import java.util.ArrayList; 8 8 import java.util.Arrays; 9 import java.util.Collection; 9 10 import java.util.List; 10 import java.util.Set; 11 import java.util.TreeSet; 11 import java.util.Objects; 12 12 13 13 import javax.swing.AbstractAction; … … 28 28 import org.openstreetmap.josm.data.preferences.IntegerProperty; 29 29 import org.openstreetmap.josm.data.projection.Projection; 30 import org.openstreetmap.josm.data.projection.Projections; 30 31 import org.openstreetmap.josm.gui.ExtendedDialog; 31 32 import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings; … … 55 56 private static final String CACHE_REGION_NAME = "WMS"; 56 57 57 private final Set<String> supportedProjections;58 private final List<String> serverProjections; 58 59 59 60 /** … … 66 67 CheckParameterUtil.ensureParameterNotNull(info.getUrl(), "info.url"); 67 68 TemplatedWMSTileSource.checkUrl(info.getUrl()); 68 this.s upportedProjections = new TreeSet<>(info.getServerProjections());69 this.serverProjections = new ArrayList<>(info.getServerProjections()); 69 70 } 70 71 … … 87 88 @Override 88 89 protected AbstractWMSTileSource getTileSource() { 89 AbstractWMSTileSource tileSource = new TemplatedWMSTileSource(info); 90 AbstractWMSTileSource tileSource = new TemplatedWMSTileSource( 91 info, chooseProjection(Main.getProjection())); 90 92 info.setAttribution(tileSource); 91 93 return tileSource; … … 112 114 113 115 @Override 114 public boolean isProjectionSupported(Projection proj) { 115 return supportedProjections == null || supportedProjections.isEmpty() || supportedProjections.contains(proj.toCode()) || 116 (info.isEpsg4326To3857Supported() && supportedProjections.contains("EPSG:4326") 117 && "EPSG:3857".equals(Main.getProjection().toCode())); 118 } 119 120 @Override 121 public String nameSupportedProjections() { 122 StringBuilder ret = new StringBuilder(); 123 for (String e: supportedProjections) { 124 ret.append(e).append(", "); 125 } 126 String appendix = ""; 127 128 if (isReprojectionPossible()) { 129 appendix = ". <p>" + tr("JOSM will use EPSG:4326 to query the server, but results may vary " 130 + "depending on the WMS server") + "</p>"; 131 } 132 return ret.substring(0, ret.length()-2) + appendix; 116 public Collection<String> getNativeProjections() { 117 return serverProjections; 133 118 } 134 119 135 120 @Override 136 121 public void projectionChanged(Projection oldValue, Projection newValue) { 137 // do not call super - we need custom warning dialog 122 Projection tileProjection = chooseProjection(newValue); 123 if (!Objects.equals(tileSource.getTileProjection(), tileProjection)) { 124 tileSource.setTileProjection(tileProjection); 125 } 126 } 138 127 139 if (!isProjectionSupported(newValue)) { 140 String message = 141 "<html><body><p>" + tr("The layer {0} does not support the new projection {1}.", 142 Utils.escapeReservedCharactersHTML(getName()), newValue.toCode()) + 143 "<p style='width: 450px; position: absolute; margin: 0px;'>" + 144 tr("Supported projections are: {0}", nameSupportedProjections()) + "</p>" + 145 "<p>" + tr("Change the projection again or remove the layer."); 146 147 ExtendedDialog warningDialog = new ExtendedDialog(Main.parent, tr("Warning"), new String[]{tr("OK")}). 148 setContent(message). 149 setIcon(JOptionPane.WARNING_MESSAGE); 150 151 if (isReprojectionPossible()) { 152 warningDialog.toggleEnable("imagery.wms.projectionSupportWarnings." + tileSource.getBaseUrl()); 128 private Projection chooseProjection(Projection requested) { 129 if (serverProjections.contains(requested.toCode())) { 130 return requested; 131 } else { 132 for (String code : serverProjections) { 133 Projection proj = Projections.getProjectionByCode(code); 134 if (proj != null) { 135 Main.info(tr("Reprojecting layer {0} from {1} to {2}. For best image quality and performance," 136 + " switch to one of the supported projections: {3}", 137 getName(), proj.toCode(), Main.getProjection().toCode(), Utils.join(", ", getNativeProjections()))); 138 return proj; 139 } 153 140 } 154 warningDialog.showDialog(); 155 } 156 157 if (!newValue.equals(oldValue)) { 158 tileSource.initProjection(newValue); 141 Main.warn(tr("Unable to find supported projection for layer {0}. Using {1}.", getName(), requested.toCode())); 142 return requested; 159 143 } 160 144 } … … 176 160 return AbstractCachedTileSourceLayer.getCache(CACHE_REGION_NAME); 177 161 } 178 179 private boolean isReprojectionPossible() {180 return supportedProjections.contains("EPSG:4326") && "EPSG:3857".equals(Main.getProjection().toCode());181 }182 162 } -
trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java
r11789 r11858 3 3 4 4 import java.io.IOException; 5 import java.util. Set;5 import java.util.Collection; 6 6 7 7 import org.apache.commons.jcs.access.CacheAccess; … … 15 15 import org.openstreetmap.josm.data.projection.Projection; 16 16 import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings; 17 import org.openstreetmap.josm.tools.Utils; 17 18 18 19 /** … … 75 76 return getMaxZoomLvl(); 76 77 } 77 double displayScale = Main.map.mapView.getScale() * Main.getProjection().getMetersPerUnit(); // meter per pixel 78 double displayScale = Main.map.mapView.getScale(); 79 if (coordinateConverter.requiresReprojection()) { 80 displayScale *= Main.getProjection().getMetersPerUnit(); 81 } 78 82 Scale snap = scaleList.getSnapScale(displayScale, false); 79 return Math.max( 80 getMinZoomLvl(), 81 Math.min( 82 snap != null ? snap.getIndex() : getMaxZoomLvl(), 83 getMaxZoomLvl() 84 ) 85 ); 83 return Utils.clamp(snap != null ? snap.getIndex() : getMaxZoomLvl(), 84 getMinZoomLvl(), getMaxZoomLvl()); 86 85 } 87 86 … … 92 91 93 92 @Override 94 public boolean isProjectionSupported(Projection proj) { 95 Set<String> supportedProjections = tileSource.getSupportedProjections(); 96 return supportedProjections.contains(proj.toCode()); 97 } 98 99 @Override 100 public String nameSupportedProjections() { 101 StringBuilder ret = new StringBuilder(); 102 for (String e: tileSource.getSupportedProjections()) { 103 ret.append(e).append(", "); 104 } 105 return ret.length() > 2 ? ret.substring(0, ret.length()-2) : ret.toString(); 93 public Collection<String> getNativeProjections() { 94 return tileSource.getSupportedProjections(); 106 95 } 107 96 -
trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileCoordinateConverter.java
r11846 r11858 12 12 import org.openstreetmap.gui.jmapviewer.interfaces.IProjected; 13 13 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 14 import org.openstreetmap.josm.Main; 14 15 import org.openstreetmap.josm.data.coor.EastNorth; 15 16 import org.openstreetmap.josm.data.coor.LatLon; … … 85 86 */ 86 87 public Point2D getPixelForTile(Tile tile) { 87 return this.getPixelForTile(tile.getXtile(), tile.getYtile(), tile.getZoom()); 88 return getPixelForTile(tile.getXtile(), tile.getYtile(), tile.getZoom()); 89 } 90 91 /** 92 * Convert screen pixel coordinate to tile position at certain zoom level. 93 * @param sx x coordinate (screen pixel) 94 * @param sy y coordinate (screen pixel) 95 * @param zoom zoom level 96 * @return the tile 97 */ 98 public TileXY getTileforPixel(int sx, int sy, int zoom) { 99 if (requiresReprojection()) { 100 LatLon ll = getProjecting().eastNorth2latlonClamped(mapView.getEastNorth(sx, sy)); 101 return tileSource.latLonToTileXY(ll.toCoordinate(), zoom); 102 } else { 103 IProjected p = shiftDisplayToServer(mapView.getEastNorth(sx, sy)); 104 return tileSource.projectedToTileXY(p, zoom); 105 } 88 106 } 89 107 … … 91 109 * Gets the position of the tile inside the map view. 92 110 * @param tile The tile 93 * @return The positon .111 * @return The positon as a rectangle in screen coordinates 94 112 */ 95 113 public Rectangle2D getRectangleForTile(Tile tile) { … … 130 148 */ 131 149 public double getScaleFactor(int zoom) { 132 LatLon topLeft = mapView.getLatLon(0, 0); 133 LatLon botRight = mapView.getLatLon(mapView.getWidth(), mapView.getHeight()); 134 TileXY t1 = tileSource.latLonToTileXY(topLeft.toCoordinate(), zoom); 135 TileXY t2 = tileSource.latLonToTileXY(botRight.toCoordinate(), zoom); 136 150 TileXY t1, t2; 151 if (requiresReprojection()) { 152 LatLon topLeft = mapView.getLatLon(0, 0); 153 LatLon botRight = mapView.getLatLon(mapView.getWidth(), mapView.getHeight()); 154 t1 = tileSource.latLonToTileXY(topLeft.toCoordinate(), zoom); 155 t2 = tileSource.latLonToTileXY(botRight.toCoordinate(), zoom); 156 } else { 157 EastNorth topLeftEN = mapView.getEastNorth(0, 0); 158 EastNorth botRightEN = mapView.getEastNorth(mapView.getWidth(), mapView.getHeight()); 159 t1 = tileSource.projectedToTileXY(topLeftEN.toProjected(), zoom); 160 t2 = tileSource.projectedToTileXY(botRightEN.toProjected(), zoom); 161 } 137 162 int screenPixels = mapView.getWidth()*mapView.getHeight(); 138 163 double tilePixels = Math.abs((t2.getY()-t1.getY())*(t2.getX()-t1.getX())*tileSource.getTileSize()*tileSource.getTileSize()); … … 147 172 */ 148 173 public TileAnchor getScreenAnchorForTile(Tile tile) { 149 IProjected p1 = tileSource.tileXYtoProjected(tile.getXtile(), tile.getYtile(), tile.getZoom()); 150 IProjected p2 = tileSource.tileXYtoProjected(tile.getXtile() + 1, tile.getYtile() + 1, tile.getZoom()); 151 return new TileAnchor(pos(p1).getInView(), pos(p2).getInView()); 174 if (requiresReprojection()) { 175 ICoordinate c1 = tile.getTileSource().tileXYToLatLon(tile); 176 ICoordinate c2 = tile.getTileSource().tileXYToLatLon(tile.getXtile() + 1, tile.getYtile() + 1, tile.getZoom()); 177 return new TileAnchor(pos(c1).getInView(), pos(c2).getInView()); 178 } else { 179 IProjected p1 = tileSource.tileXYtoProjected(tile.getXtile(), tile.getYtile(), tile.getZoom()); 180 IProjected p2 = tileSource.tileXYtoProjected(tile.getXtile() + 1, tile.getYtile() + 1, tile.getZoom()); 181 return new TileAnchor(pos(p1).getInView(), pos(p2).getInView()); 182 } 183 } 184 185 /** 186 * Return true if tiles need to be reprojected from server projection to display projection. 187 * @return true if tiles need to be reprojected from server projection to display projection 188 */ 189 public boolean requiresReprojection() { 190 return !tileSource.getServerCRS().equals(Main.getProjection().toCode()); 152 191 } 153 192 }
Note:
See TracChangeset
for help on using the changeset viewer.