我正在构建一个Java Swing应用程序,尝试在地图上绘制多条线来表示路点。这些路点通常以这样的形式相交:一个路点的终点是另一个路点的起点。我的问题是,只有第一条绘制的线条会像预期的那样出现,而其他的线条将会“漂浮”在似乎是另一个图层的地方(见下图)。我不太确定为什么会这样,因为代码不应该在同一个Graphics2D对象上划线吗?我在一些相关的问题中看到,隐式JPanel创建的问题导致了一些类似的问题,但我认为这里不应该是这样的?任何帮助都将不胜感激。
private void drawRoute( final Graphics2D g, final JXMapViewer map, List<List<? extends GeoPosition>> tracks)
{
for (List<? extends GeoPosition> track : tracks) {
int lastX = 0;
int lastY = 0;
boolean first = true;
for (GeoPosition gp : track)
{
// convert geo-coordinate to world bitmap pixel
Point2D pt = map.getTileFactory().geoToPixel(gp, map.getZoom());
if (first)
{
first = false;
}
else
{
double curX = pt.getX();
double curY = pt.getY();
Line2D.Double testLine = new Line2D.Double(lastX, lastY, curX, curY);
//g.drawLine(lastX, lastY, (int) curX, (int) curY);
g.draw(testLine);
}
lastX = (int) pt.getX();
lastY = (int) pt.getY();
}
}
}
private void paintLeg( final Leg start, final Leg end, final Graphics2D graphics,
final JXMapViewer map , Optional<Color> color)
{
Point2D pointStart = map.getTileFactory().geoToPixel(positionToGeo(start.terminatorPosition()),
map.getZoom());
Point2D pointEnd = map.getTileFactory().geoToPixel(positionToGeo(end.terminatorPosition()),
map.getZoom());
Line2D.Double line = new Line2D.Double(pointStart, pointEnd);
Rectangle clipBounds = map.getViewportBounds();
if (clipBounds.contains(pointStart) || clipBounds.contains(pointEnd) || clipBounds.intersectsLine(line))
{
List<GeoPosition> track = new ArrayList<>();
double[] curCoords = new double[2]; // hold the waypoint coords
curCoords[0] = start.terminatorPosition().latitudeDegrees();
curCoords[1] = start.terminatorPosition().longitudeDegrees();
GeoPosition startPosition = new GeoPosition(curCoords);
track.add(startPosition);
curCoords[0] = end.terminatorPosition().latitudeDegrees();
curCoords[1] = end.terminatorPosition().longitudeDegrees();
GeoPosition endPosition = new GeoPosition(curCoords);
track.add(endPosition);
// convert from viewport to world bitmap
Rectangle rect = map.getViewportBounds();
graphics.translate(-rect.x, -rect.y);
tracks.add(track);
// do the drawing
if (color.isPresent()) {
graphics.setColor(color.get());
}
else {
graphics.setColor(Color.BLACK);
}
graphics.setStroke(new BasicStroke(4));
drawRoute(graphics, map, tracks);
}
}
@Override
protected void doPaint( final Graphics2D graphics, final JXMapViewer map,
final int width, final int height )
{
// API doesn't provide any guarantee on nullability of these arguments. To be
// safe, check this and do nothing if so.
if ((graphics != null) && (map != null))
{
Optional<Color> color = Optional.empty();
Optional<Integer> startAndEnd = Optional.empty();
paintLegs(flightPlanLegs, graphics, map, color, startAndEnd, startAndEnd);
}
}
private final JXMapKit map = new JXMapKit();
private final FixPainter fixPainter = new FixPainter();
private final RoutePainter routePainter = new RoutePainter();
private final DataCreditPainter dataCreditPainter = new DataCreditPainter();
private Iterable<? extends Fix> databaseFixes = ImmutableList.of();
private Iterable<? extends Fix> selectedFixes = ImmutableList.of();
private Iterable<? extends Leg> flightPlanLegs = ImmutableList.of();
private List<List<? extends GeoPosition>> tracks = ArrayList<>();
private void initializeMap()
{
map().setDefaultProvider(DefaultProviders.OpenStreetMaps);
map().setDataProviderCreditShown(true);
// Create a compound painter for all of the painters
CompoundPainter<JXMapViewer> painter =
new CompoundPainter<>(ImmutableList.of(fixPainter, dataCreditPainter,
routePainter));
painter.setCacheable(false);
map().getMainMap().setOverlayPainter(painter);
map().setTileFactory(MapBoxTileFactoryInfo.newTileFactory());
zoom(DEFAULT_ZOOM);
replaceFlightPlan(null);
}
void replaceFlightPlan( final Iterable<? extends Leg> legs )
{
Leg fpl1 = new Leg()
{
@Override
public Position terminatorPosition()
{
return Position.of(47, -122);
}
@Override
public String identifier()
{
return "fpl1";
}
};
Leg fpl2 = new Leg()
{
@Override
public Position terminatorPosition()
{
return Position.of(48, -111);
}
@Override
public String identifier()
{
return "fpl2";
}
};
Leg fpl3 = new Leg()
{
@Override
public Position terminatorPosition()
{
return Position.of(32, -111);
}
@Override
public String identifier()
{
return "fpl3";
}
};
ArrayList<Leg> ok = new ArrayList<>();
ok.add(fpl1);
ok.add(fpl2);
ok.add(fpl3);
flightPlanLegs = ImmutableList.copyOf(ok);
Iterator<List<? extends GeoPosition>> tracksItr = tracks.iterator();
while (tracksItr.hasNext()) {
tracksItr.remove();
}
}

英国的线应该从美国的线结束的地方开始。
https://stackoverflow.com/questions/47518192
复制相似问题