Random geographic coordinates (on land, avoid the ocean)

Any smart ideas on how to create random coordinates (latitude / longitude) of places on Earth? Latitude Longitude. Accuracy up to 5 points and avoid ponds.

double minLat = -90.00; double maxLat = 90.00; double latitude = minLat + (double)(Math.random() * ((maxLat - minLat) + 1)); double minLon = 0.00; double maxLon = 180.00; double longitude = minLon + (double)(Math.random() * ((maxLon - minLon) + 1)); DecimalFormat df = new DecimalFormat("#.#####"); log.info("latitude:longitude --> " + df.format(latitude) + "," + df.format(longitude)); 

Maybe I live in a dream world, and the theme of water is inevitable ... but I hope there will be a cleaner, cleaner and more effective way to do this?

EDIT

Some fantastic answers / ideas - however, on a scale of, say, I need to create 25,000 coordinates. Switching to an external service provider may not be the best option due to latency, cost, and several other factors.

+24
java geocoding gis
Feb 01 '12 at 23:21
source share
15 answers

To solve the water problem, the problem will be mainly a data problem, for example. you just want to skip the oceans or you also need to skip small streams. Either you need to use the service with the quality of the data you need, or you need to get the data yourself and run it locally. From your edit, it sounds like you want to go through a local data route, so I will focus on how to do this.

One way is to get a shape file for land or water areas. Then you can create a random point and determine if it crosses a piece of land (or, conversely, does not cross the water area).

To get started, you can get low resolution data here , and then get higher resolution data here when you want the best answers on coastlines or lakes / rivers, etc. You mentioned that you want the accuracy of your points to be 5 decimal places, which is slightly more than 1 m. Keep in mind that if you get data to match this accuracy, you will have one gigantic data set. And if you want really good data, be prepared to pay for it.

When you have form data, you will need some tools to help you determine the intersection of your random points. Geotools is a great place to start and will probably work for your needs. You will also come across opengis code (docs under the geotools site - not sure if they consumed them or what) and JTS to process the geometry. Using this, you can quickly open the shapefile and start executing some intersection requests.

  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 ); 

Brief Explanations:

  • It is assumed that the resulting shapefile is polygonal data. Crossing lines or dots will not give you what you want.
  • The first section opens the shapefile - nothing interesting
  • you need to get the name of the geometry property for this file
  • coordinate system - you indicated lat / long in your message, but GIS can be a little more complicated. In general, the data that I pointed to you is geographic, wgs84 , and that is what I installed here. However, if this is not the case for you, you must be sure that you are dealing with your data in the correct coordinate system. If all this sounds like gibberish, google around the GIS tutorial / coordinate systems / datum / ellipsoid.
  • the generation of coordinate geometries and filters is pretty straightforward. The resulting feature set will either be empty, which means that the coordinate is in the water if your data is cover art or not empty, which means the opposite.

Note: if you do this with a truly random set of points, you will often hit the water, and it may take you some time to get to 25 thousand points. You might want to try to cover your generation of points better than truly random ones (for example, remove large chunks of the Atlantic / Pacific / Indian Oceans).

In addition, you may find that your crossing requests are too slow. If so, you might want to create a quadtree index (qix) using a tool such as GDAL . I don’t remember what types of indexes are supported by geotags.

+12
Feb 17 '12 at 19:58
source share
  • Download a truck of KML files containing only local locations.
  • Extract from them all the coordinates this may help here .
  • Select them randomly.
+4
Feb 13 2018-12-12T00:
source share

There is another way to get closer with Google Earth Api. I know this is javascript, but I thought it was a new way to solve the problem.

In any case, I have put together a complete working solution - note that it works for rivers too: http://www.msa.mmu.ac.uk/~fraser/ge/coord/

The main idea I used was to implement the hiTest method of a GEView object in Google Earth Api .

Take a look at the following Hitest example from Google. http://earth-api-samples.googlecode.com/svn/trunk/examples/hittest.html

The hitTest method is supplied with a random point on the screen (pixel coordinates), for which it returns a GEHitTestResult object that contains information about the geographical location corresponding to the point. If you use the GEPlugin.HIT_TEST_TERRAIN mode using the method, you can limit the results to only landing (terrain) while we look at the results at points with a height> 1 m

This is the function I use to implement hitTest:

 var hitTestTerrain = function() { var x = getRandomInt(0, 200); // same pixel size as the map3d div height var y = getRandomInt(0, 200); // ditto for width var result = ge.getView().hitTest(x, ge.UNITS_PIXELS, y, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN); var success = result && (result.getAltitude() > 1); return { success: success, result: result }; }; 

Obviously, you also want to have random results from anywhere on the globe (and not just random points visible from one point of view). To do this, I move the land view after each successful hitTestTerrain call. This is achieved with a small helper function.

 var flyTo = function(lat, lng, rng) { lookAt.setLatitude(lat); lookAt.setLongitude(lng); lookAt.setRange(rng); ge.getView().setAbstractView(lookAt); }; 

Finally, this is a stripped-down version of the main block of code that calls these two methods.

 var getRandomLandCoordinates = function() { var test = hitTestTerrain(); if (test.success) { coords[coords.length] = { lat: test.result.getLatitude(), lng: test.result.getLongitude() }; } if (coords.length <= number) { getRandomLandCoordinates(); } else { displayResults(); } }; 

So, the earth moves randomly to postulate

Other functions have only helpers for generating random x, y and random numbers lat, lng for outputting results, as well as for switching controls, etc.

I tested the code a bit, and the results were not 100% perfect, improving the altitude to a level higher, for example 50 m, but obviously it reduces the area of ​​possible selected coordinates.

Obviously, you could adapt the idea to suit your needs. Perhaps run the code several times to populate the database or something else.

+4
Mar 21 '12 at 7:35
source share

To get a good uniform distribution of latitudes and longitudes, you should do something like this to get the right angles:

 double longitude = Math.random() * Math.PI * 2; double latitude = Math.acos(Math.random() * 2 - 1); 

How to avoid bodies of water, do you have data on where the water already exists? Well, just redo it until you get a hit! If you do not have this data, then it seems that some other people have some better suggestions than I would like for this ...

Hope this helps, welcome.

+3
Feb 13 2018-12-12T00:
source share

It has been asked a long time ago, and now I have a similar need. There are two possibilities that I am exploring:

1. Define surface ranges for a random generator.

It is important to determine the level of accuracy in which you are going to move. The easiest way is to have a very relaxed and rough approach. In this case, you can divide the world map into "boxes":

enter image description here

Each box has its own lat lon range. Then you first make it to the manufacturer to get a random cell, then you produce a random lat and a random long one within the borders of this window.

Accuracy, of course, is not the best here ... Although it depends: if you do your homework well and define a lot of boxes covering the most complex surface shapes, you can be fine with accuracy.

2. List item

Some APIs return the name of the continent from the coordinates OR address OR country OR region = what is not in WATER. The Google Maps API can help here. I did not investigate this problem more deeply, but I think it is possible, although you will have to run a check for each generated coordinate pair and repeat it if it is wrong. Therefore, you may be a little stuck if a random generator continues to throw you into the ocean.

In addition, some waters belong to countries, regions ... so yes, not very accurately.

For my needs - I gather with “boxes”, because I also want to control the exact areas from which random coordinates are taken, and do not mind if they land on a lake or river, just do not open the ocean :)

+3
Dec 16 '15 at 15:02
source share

You should definitely have a map as a resource. You can take it here: http://www.naturalearthdata.com/

Then I prepared a 1 bit black and white raster resource with a 1s mark and a 0x water mark.

The size of the bitmap depends on your required accuracy. If you need 5 degrees, then your bitmap will be 360/5 x 180/5 = 72x36 pixels = 2592 bits.

Then I would load this bitmap into Java, generate a random integer with a range higher, a read bit, and regenerate if it was zero.

PS You can also dig here http://geotools.org/ for some ready-made solutions.

+2
Feb 13 '12 at 17:58
source share

Like Plan B, perhaps you can select a random country, and then select a random coordinate within that country. To be fair when choosing a country, you can use its area as weight.

+2
Feb 06 '15 at 12:54
source share
+1
Feb 18 2018-12-18T00:
source share

I think you could use a world map, define a few points on it to distinguish most water bodies, as you say, and use the polygon.contains method to check the coordinates.

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

0
Feb 01 '12 at 23:40
source share

You can also do a blue-green thing, and then save all the green dots for later retrieval. This has the advantage of being rescheduled "step by step". When you figure out the best way to create your list of points, you can simply point your random robbery into a more and more clear group of points.

Your service provider may already have an answer to your question: for example. https://www.google.com/enterprise/marketplace/viewListing?productListingId=3030+17310026046429031496&pli=1

Api height? http://code.google.com/apis/maps/documentation/elevation/ above sea level or lower? (no Dutch glasses for you!)

0
Feb 02 2018-12-12T00:
source share

There is a library here , and you can use its .random () method to get a random coordinate. You can then use GeoNames WebServices to determine if it is on land or not. They have a list of web services, and you just need to use the right one. GeoNames is free and reliable.

0
Feb 14 2018-12-14T00:
source share

Creation is easy, the problem is that they should not be on the water. I would import "Open Streetmap", for example, here http://ftp.ecki-netz.de/osm/ and import it into the database (verry easy data Structure). I would suggest PostgreSQL, it comes with some geo-functions http://www.postgresql.org/docs/8.2/static/functions-geometry.html . To do this, you need to save the points in the "polygon" -column, then you can check with "& &" if it is in the water polygon. For OpenStreetmap Way-Entry attributes, you should take a look at http://wiki.openstreetmap.org/wiki/Category:En:Keys

0
Feb 17 '12 at 18:43
source share

Do I need to evenly distribute random points throughout the world? If you can agree on a seemingly uniform distribution, you can do this:

Open your favorite mapping service, draw a rectangle inside the USA, Russia, China, Western Europe and, of course, the northern part of Africa - make sure that there are no large lakes or Caspian seas in the rectangles. Take the angular coordinates of each rectangle, and then randomly select the coordinates inside these rectangles.

You are guaranteed that these glasses will not be on any sea or lakes. You can find a rare river, but I'm not sure how many geo services will be accurate enough for this.

0
Feb 18 '12 at 7:24
source share

This is an extremely interesting question, both from a theoretical and a practical point of view. The most suitable solution will largely depend on your exact requirements. Do you need to consider every body of water, or just the main seas and oceans? How important accuracy and correctness are; Will the definition of the sea as land or vice versa be a catastrophic failure?

I think that machine learning methods would be a great solution to this problem if you do not mind (hopefully small) the likelihood that a point of water is incorrectly classified as land. If this is not a problem, then this approach should have several advantages over other methods.

Using a bitmap is a nice solution, simple and elegant. It can be done with a certain accuracy, and the classification is guaranteed to be correct (or at least as correct as you made a bitmap). But its practicality depends on how accurate your solution should be. You note that you need a coordinate accuracy of up to 5 decimal places (which is equivalent to displaying the entire surface of the planet about the nearest meter). Using 1 bit per element, the bitmap will weigh about ~ 73.6 terabytes!

We do not need to store all this data; We only need to know where the coastlines are. Just knowing where the point refers to the coast, we can determine if it is on land or at sea. According to rough estimates, the CIA World Newsletter reports that there are 22,498 km of coastline on Earth. If we store the coordinates for each meter of the coastline using a 32-bit word for each latitude and longitude, it will take less than 1.35 GB to store. This is still a lot if it is for a trivial application, but several orders of magnitude less than using a bitmap. If it is not necessary to have such a high degree of accuracy, these numbers will decrease significantly. Reducing the display only by the nearest kilometer would make a bitmap of only ~ 75 GB, and the coordinates for the world coastline could fit on a floppy disk.

I suggest using a clustering algorithm to decide if a point is on land or not. First, we would need a fairly large number of coordinates that we already know, both on land and at sea. Existing GIS databases are suitable for this. Then we can analyze the points to determine the land and sea clusters. The boundary of the solution between the clusters should fall on the coastlines, and all points that do not define the boundary of the solution can be removed. This process can be repeated to obtain a more accurate boundary.

It is only necessary to save the points defining the solution boundary / coastline, and using a simple distance metric, we can quickly and easily decide whether the coordinate set is on land or at sea. Learning a system will require a large amount of resources, but after the classifier is completed, very little space or time will be required.

0
Feb 18 2018-12-18T00:
source share

Assuming Atlantis is not in the database, you can randomly select cities. It also provides a more realistic distribution of points if you intend to simulate human activity: https://simplemaps.com/data/world-cities

Only 7,300 cities are available in the free version.

0
Nov 12 '17 at 17:14
source share



All Articles