geotools указывает на полигон графически - PullRequest
0 голосов
/ 27 сентября 2018

Я хочу рисовать многоугольники на карте из вставленных точек

Я добавляю несколько точек с помощью перетаскивания мышью, пока нажата клавиша control

enter image description here

Теперь я хочу преобразовать (или заменить) эти точки, чтобы графически закрыть полигон, когда я отпущу клавишу 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);
    }
}

Спасибо

1 Ответ

0 голосов
/ 28 сентября 2018

Когда у вас есть список координат, первое, что нужно сделать, это закрыть цикл так, чтобы начальная и конечная точки были одинаковыми.Тогда это простой вызов createPolygon в GeometryFactory, так как вам не о чем беспокоиться.

GeometryFactory factory = new GeometryFactory();
ArrayList<Coordinate> coordList = new ArrayList<>();
//...track mouse clicks to fill arrayList
// close loop
coordList.add(coordList.get(0));
//create polygon
Polygon poly=factory.createPolygon(coordList.toArray(new Coordinate[] {}));
...