Random geographic coordinates (on land, avoid ocean)

前端 未结 16 1101
死守一世寂寞
死守一世寂寞 2020-12-08 10:03

Any clever ideas on how to generate random coordinates (latitude / longitude) of places on Earth? Latitude / Longitude. Precision to 5 points and avoid bodies of water. <

相关标签:
16条回答
  • 2020-12-08 10:40
    1. Go there http://wiki.openstreetmap.org/
    2. Try to use API: http://wiki.openstreetmap.org/wiki/Databases_and_data_access_APIs
    0 讨论(0)
  • 2020-12-08 10:41

    I guess you could use a world map, define a few points on it to delimit most of water bodies as you say and use a polygon.contains method to validate the coordinates.

    A faster algorithm would be to use this map, take some random point and check the color beneath, if it's blue, then water... when you have the coordinates, you convert them to lat/long.

    0 讨论(0)
  • 2020-12-08 10:45

    To deal with the body of water problem is going to be largely a data issue, e.g. do you just want to miss the oceans or do you need to also miss small streams. Either you need to use a service with the quality of data that you need, or, you need to obtain the data yourself and run it locally. From your edit, it sounds like you want to go the local data route, so I'll focus on a way to do that.

    One method is to obtain a shapefile for either land areas or water areas. You can then generate a random point and determine if it intersects a land area (or alternatively, does not intersect a water area).

    To get started, you might get some low resolution data here and then get higher resolution data here for when you want to get better answers on coast lines or with lakes/rivers/etc. You mentioned that you want precision in your points to 5 decimal places, which is a little over 1m. Do be aware that if you get data to match that precision, you will have one giant data set. And, if you want really good data, be prepared to pay for it.

    Once you have your shape data, you need some tools to help you determine the intersection of your random points. Geotools is a great place to start and probably will work for your needs. You will also end up looking at opengis code (docs under geotools site - not sure if they consumed them or what) and JTS for the geometry handling. Using this you can quickly open the shapefile and start doing some intersection queries.

        File f = new File ( "world.shp" );
        ShapefileDataStore dataStore = new ShapefileDataStore ( f.toURI ().toURL () );
        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = 
            dataStore.getFeatureSource ();
        String geomAttrName = featureSource.getSchema ()
            .getGeometryDescriptor ().getLocalName ();
    
        ResourceInfo resourceInfo = featureSource.getInfo ();
        CoordinateReferenceSystem crs = resourceInfo.getCRS ();
        Hints hints = GeoTools.getDefaultHints ();
        hints.put ( Hints.JTS_SRID, 4326 );
        hints.put ( Hints.CRS, crs );
    
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2 ( hints );
        GeometryFactory gf = JTSFactoryFinder.getGeometryFactory ( hints );
    
        Coordinate land = new Coordinate ( -122.0087, 47.54650 );
        Point pointLand = gf.createPoint ( land );
        Coordinate water = new Coordinate ( 0, 0 );
        Point pointWater = gf.createPoint ( water );
    
        Intersects filter = ff.intersects ( ff.property ( geomAttrName ), 
            ff.literal ( pointLand ) );
        FeatureCollection<SimpleFeatureType, SimpleFeature> features = featureSource
                .getFeatures ( filter );
    
        filter = ff.intersects ( ff.property ( geomAttrName ), 
            ff.literal ( pointWater ) );
        features = featureSource.getFeatures ( filter );
    

    Quick explanations:

    1. This assumes the shapefile you got is polygon data. Intersection on lines or points isn't going to give you what you want.
    2. First section opens the shapefile - nothing interesting
    3. you have to fetch the geometry property name for the given file
    4. coordinate system stuff - you specified lat/long in your post but GIS can be quite a bit more complicated. In general, the data I pointed you at is geographic, wgs84, and, that is what I setup here. However, if this is not the case for you then you need to be sure you are dealing with your data in the correct coordinate system. If that all sounds like gibberish, google around for a tutorial on GIS/coordinate systems/datum/ellipsoid.
    5. generating the coordinate geometries and the filters are pretty self-explanatory. The resulting set of features will either be empty, meaning the coordinate is in the water if your data is land cover, or not empty, meaning the opposite.

    Note: if you do this with a really random set of points, you are going to hit water pretty often and it could take you a while to get to 25k points. You may want to try to scope your point generation better than truly random (like remove big chunks of the Atlantic/Pacific/Indian oceans).

    Also, you may find that your intersection queries are too slow. If so, you may want to look into creating a quadtree index (qix) with a tool like GDAL. I don't recall which index types are supported by geotools, though.

    0 讨论(0)
  • 2020-12-08 10:47

    Do the random points have to be uniformly distributed all over the world? If you could settle for a seemingly uniform distribution, you can do this:

    Open your favorite map service, draw a rectangle inside the United States, Russia, China, Western Europe and definitely the northern part of Africa - making sure there are no big lakes or Caspian seas inside the rectangles. Take the corner coordinates of each rectangle, and then select coordinates at random inside those rectangles.

    You are guaranteed non of these points will be on any sea or lake. You might find an occasional river, but I'm not sure how many geoservices are going to be accurate enough for that anyway.

    0 讨论(0)
提交回复
热议问题