Найти, если точка находится внутри многоугольника - JAVA jts / awt / geotools - PullRequest
0 голосов
/ 17 января 2019

У меня есть случайное число координат для многоугольника, взятого из шейп-файла.

-119.00072399999999 35.36158, -118.99903 35.361576, -118.999026 35.362579, -118.999023 35.363482, -118.999019 35.36432, -118.999408 35.364847999999995, -118.999406 35.365564, -118.999402 35.366516, -118.999398 35.367467999999995, -118.999394 35.368438, -118.999256 35.368438, -118.998232 35.368441

Теперь я должен проверить, находится ли точка (33.63705, -112.17563) внутри этого многоугольника.

Меня беспокоит то, что мои координаты не вписываются в тип данных int.

Вот что я пробовал:

import java.awt.Polygon;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

public class ReadShapeFile {

    public static void main(String[] args) {

        File file = new File("D:\\shapefile201806\\tl_2018_06_bg.shp");

        try {
            Map<String, String> connect = new HashMap<String, String>();
            connect.put("url", file.toURI().toString());

            DataStore dataStore = DataStoreFinder.getDataStore(connect);
            String[] typeNames = dataStore.getTypeNames();
            String typeName = typeNames[0];

            System.out.println("Reading content : " + typeName);

            SimpleFeatureSource featureSource = dataStore.getFeatureSource(typeName);
            SimpleFeatureCollection collection = featureSource.getFeatures();
            SimpleFeatureIterator iterator = collection.features();

            try {
                while (iterator.hasNext()) {

                    SimpleFeature feature = iterator.next();
                    String featureString = feature.toString();

                    List<String> polygonList = new ArrayList<String>();

                    String polygonCoordinates = StringUtils.substringBetween(featureString, "(((", ")))");
                    System.out.println(polygonCoordinates);
                    polygonList = Arrays.asList(polygonCoordinates.split(","));

                    SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

                    b.setName("MyFeatureType");
                    b.setCRS(DefaultGeographicCRS.WGS84);
                    b.add("location", Point.class);
                    final SimpleFeatureType TYPE = b.buildFeatureType();

                    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
                    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
                    SimpleFeature pointFeature = featureBuilder.buildFeature(null);
                    DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
                    featureCollection.add(pointFeature);

                    try {
                        Polygon polygon = new Polygon();
                        for (int i = 0; i < polygonList.size(); i++) {
                            String[] splitAxis = (polygonList.get(i).split("\\s+"));
                            polygon.addPoint(Integer.valueOf(splitAxis[0]), Integer.valueOf(splitAxis[1]));
                        }

                        boolean isInside = polygon.contains(33.63705,  -112.17563);
                        System.out.println(isInside);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            } finally {
                iterator.close();
            }

        } catch (Throwable e) {
        }

    }

}

Я знал, что преобразование двойного в строковое и обратно в целое не будет работать в любом случае.

Как мне решить, находится ли точка в многоугольнике для отрицательных прореженных значений? Пожалуйста, помогите.

1 Ответ

0 голосов
/ 17 января 2019

Используя SimpleFeature, вы можете вызвать getDefaultGeometry и получить объект Geometry. После того, как вы приведете к Geometry, должен быть метод contains, который будет принимать класс Point.

Кроме того, вы не хотите использовать класс java.awt.Polygon. Вместо этого вы будете использовать классы геометрии org.locationtech.jts.

...