我想从插入点在地图上绘制多边形
我在按下control
键的同时用鼠标拖动来添加一些点
现在,我想在释放control
键时转换(或替换)这些点以图形方式关闭多边形。有任何代码可以做到这一点吗?对不起,我的英语。
该类包含地图
public class MapCanvas {
private Canvas canvas;
private MapContent map;
private GraphicsContext gc;
private double x;
private double y;
public MapCanvas(int width, int height) {
canvas = new Canvas(width, height);
gc = canvas.getGraphicsContext2D();
initMap();
drawMap(gc);
initEvent();
initPaintThread();
MenuItem item1 = new MenuItem("Insert");
item1.setOnAction(e -> convertAndInsert(x, y));
MenuItem item2 = new MenuItem("Delete");
item2.setOnAction(e -> {
//deletePolygonLayer(x, y);
});
ContextMenu contextMenu = new ContextMenu(item1, item2);
canvas.setOnContextMenuRequested(e -> {
x = e.getX();
y = e.getY();
contextMenu.show(canvas, e.getScreenX(), e.getScreenY());
});
}
/*private void deletePolygonLayer(double x, double y) {
Point2D.Double transfor = transformScrToWrl(x, y);
//find a code to delete selected polygon with intersect() (except the map layer)
}*/
private void convertAndInsert(double x, double y) {
Point2D.Double pointD = transformScrToWrl(x, y);
addGeometry(pointD.getX(), pointD.getY());
}
private Point2D.Double transformScrToWrl(double x, double y) {
Point2D.Double pointS = new Point2D.Double(x, y);
Point2D.Double pointD = new Point2D.Double();
map.getViewport().getScreenToWorld().transform(pointS, pointD);
return pointD;
}
private void addGeometry(double x, double y) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Location");
builder.setCRS(DefaultGeographicCRS.WGS84);
builder.add("the_geom", Geometry.class);
GeometryFactory factory = JTSFactoryFinder.getGeometryFactory();
Geometry geom = factory.createPoint(new Coordinate(x, y));
SimpleFeatureType type = builder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
featureBuilder.add(geom);
SimpleFeature feature = featureBuilder.buildFeature(null);
DefaultFeatureCollection simpleFeatures = new DefaultFeatureCollection();
simpleFeatures.add(feature);
Style style = null;
if (geom != null) {
style = SLD.createPointStyle("Circle", Color.RED, Color.RED, 0.5f, 10);
}
Layer layer = new FeatureLayer(simpleFeatures, style);
map.addLayer(layer);
//code to refresh the map
ReferencedEnvelope env = new ReferencedEnvelope(map.getViewport().getBounds());
doSetDisplayArea(env);
}
public Node getCanvas() {
return canvas;
}
private void initMap() {
try {
FileDataStore store = FileDataStoreFinder
.getDataStore(getClass().getResource("resource/CUB_adm0.shp"));
SimpleFeatureSource featureSource = store.getFeatureSource();
map = new MapContent();
Style style = SLD.createSimpleStyle(featureSource.getSchema());
FeatureLayer layer = new FeatureLayer(featureSource, style);
map.addLayer(layer);
map.getViewport().setScreenArea(new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight()));
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean repaint = true;
private void drawMap(GraphicsContext gc) {
if (!repaint) {
return;
}
repaint = false;
StreamingRenderer draw = new StreamingRenderer();
draw.setMapContent(map);
FXGraphics2D graphics = new FXGraphics2D(gc);
graphics.setBackground(Color.WHITE);
graphics.clearRect(0, 0, (int) canvas.getWidth(), (int) canvas.getHeight());
Rectangle rectangle = new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight());
draw.paint(graphics, rectangle, map.getViewport().getBounds());
}
private double baseDrageX;
private double baseDrageY;
/*
*initial for mouse event
*/
private void initEvent() {
/*
* setting the original coordinate
*/
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {
baseDrageX = e.getSceneX();
baseDrageY = e.getSceneY();
e.consume();
});
/*
* translate according to the mouse drag
*/
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> {
if (!e.isControlDown()) {
double difX = e.getSceneX() - baseDrageX;
double difY = e.getSceneY() - baseDrageY;
baseDrageX = e.getSceneX();
baseDrageY = e.getSceneY();
DirectPosition2D newPos = new DirectPosition2D(difX, difY);
DirectPosition2D result = new DirectPosition2D();
map.getViewport().getScreenToWorld().transform(newPos, result);
ReferencedEnvelope env = new ReferencedEnvelope(map.getViewport().getBounds());
env.translate(env.getMinimum(0) - result.x, env.getMaximum(1) - result.y);
doSetDisplayArea(env);
} else {
//here insert points to map
convertAndInsert(e.getX(), e.getY());
}
e.consume();
});
/*
* double clicks to restore to original map
*/
canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, t -> {
if (t.getClickCount() > 1) {
doSetDisplayArea(map.getMaxBounds());
}
t.consume();
});
/*
* scroll for zoom in and out
*/
canvas.addEventHandler(ScrollEvent.SCROLL, e -> {
ReferencedEnvelope envelope = map.getViewport().getBounds();
double percent = e.getDeltaY() / canvas.getWidth();
double width = envelope.getWidth();
double height = envelope.getHeight();
double deltaW = width * percent;
double deltaH = height * percent;
envelope.expandBy(deltaW, deltaH);
doSetDisplayArea(envelope);
e.consume();
});
}
private static final double PAINT_HZ = 60.0;
private void initPaintThread() {
ScheduledService<Boolean> svc = new ScheduledService<Boolean>() {
protected Task<Boolean> createTask() {
return new Task<Boolean>() {
protected Boolean call() {
Platform.runLater(() -> drawMap(gc));
return true;
}
};
}
};
svc.setPeriod(Duration.millis(1000.0 / PAINT_HZ));
svc.start();
}
private void doSetDisplayArea(ReferencedEnvelope envelope) {
map.getViewport().setBounds(envelope);
repaint = true;
}
}
还有Main
类
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
MapCanvas canvas = new MapCanvas(1000, 500);
Pane pane = new Pane(canvas.getCanvas());
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.setTitle("Map Tutorial 2");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
谢谢
答案 0 :(得分:0)
有了坐标列表后,首先要做的是闭合循环,以使起点和终点相同。然后,这是对long
中的createPolygon
的简单调用,因为您无需担心。
GeometryFactory