Check if the point is Earth or Water on Google Maps.

.. and then google maps "share water from water"

Well, not in the biblical sense, but ..

I would like to know what options I have to check if the point [Lat, Lawn] is land or water.

Google Maps obviously has this data (the bodies of the water are blue) - but is there anything in the API that I can use for this? And if not, don't they serve him because they never thought about it? Or because it is too complicated?

I did not find any information on this issue - except for some similar questions here (for example, find the type of terrain or altitude - but this is not quite what I need).

Is there a dedicated layer for this? Option? Team? Or do I need to do this manually?

The only way I can think of how to approach this (should I do it manually) is to check each served snippet for the exact point - and then check the RGB value for this shade of the Google map. This is only in theory - because in practice - I have no idea how to do this, the first obstacle is that I do not know how I can convert the location of a pixel on a tile to a point [LatLon], for example

The turnkey solution will be much simpler.

Notice that I don’t need ALL the water in the world (for example, I don’t care about streams, small ponds, most rivers or your neighboring pool. I need points where a person can risk without a floating car)

Edit i

After reading the comments: The rise method is not reliable, there are too many places BELOW the sea level (you can see the list of the “deepest” 10 here http://geology.com/below-sea-level/ ) and too many landlocked BODIES ABOVE sea level (lake). The reverse geolocation method is not reliable because it will return a geopolitical entity, such as a city or state, or ZERO many times. I already examined these pseudo-solutions before asking a question, but none of them answered the question - these methods are poorly suited at best.

+97
javascript google-maps google-maps-api-3
Mar 10 2018-12-12T00:
source share
18 answers

These are two different ways you can try:

  • You can use Google Reverse Geocoding . In the result set, you can determine if it is water by checking types . In the case of water, the type is natural_feature . See more at this link http://code.google.com/apis/maps/documentation/geocoding/#Types .

    You also need to check the function names if they contain Sea, Lake, Ocean and some other words related to water for more accuracy. For example, deserts also have natural_feature s.

    Prons . All discovery processes will run on the client machine. No need to create your own server service.

    Cons - Very inaccurate, and the chances that you get no in the waters are very high.

  • You can determine the water / land by pixels using Google Static Maps . But for this you need to create an http service.

    These are the steps that your service should perform:

    • Get latitude , longitude and current zoom from the client.
    • Send a http://maps.googleapis.com/maps/api/staticmap?center={ latitude , longitude }&zoom={ current zoom`} & size = 1x1 & maptype = roadmap & sensor = false request to the Google Static Map service.
    • Define the pixel color of a static image 1x1.
    • Respond to discovery information.

    You cannot determine the color of the pixel on the client side. Yes, you can upload a static image to the client machine and draw the image on the canvas element. But you cannot use the canvas context getImageData to get the color of the pixel. This is limited to cross-domain policies.

    Prons - Precision Detection

    Cons - using your own server resources for discovery

+54
Mar 10 2018-12-12T00:
source share

This is not possible in any current Google service.

But there are other services, such as Order vector JSON service ! You just request the data in the url and you get a JSON / XML response .

Example request: http://api.koordinates.com/api/vectorQuery.json?key=YOUR_GEODATA_KEY&layer=1298&x=-159.9609375&y=13.239945499286312&max_results=3&radius=10000&geometry=true&with_field_names=true

You need to register and indicate your number and the number of the selected layer. You can find all available repositories of available layers . Most layers are only regional, but you can also find global ones, for example, World Coastline :

enter image description here

When you select a layer, you click on the “Services” tab, you get the URL of the sample request. I believe you just need to register and what it is!

And now the best:

You can upload your layer!

It is not immediately available, it needs to be processed somehow, but it should work! The level repository actually looks like people downloaded them as needed.

+18
Jun 28 '13 at 16:04 on
source share

This is what I use and it doesn't work so bad ... you can improve the test if you have more CPU to spend time adding pixels.

 function isItWatter($lat,$lng) { $GMAPStaticUrl = "https://maps.googleapis.com/maps/api/staticmap?center=".$lat.",".$lng."&size=40x40&maptype=roadmap&sensor=false&zoom=12&key=YOURAPIKEY"; //echo $GMAPStaticUrl; $chuid = curl_init(); curl_setopt($chuid, CURLOPT_URL, $GMAPStaticUrl); curl_setopt($chuid, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($chuid, CURLOPT_SSL_VERIFYPEER, FALSE); $data = trim(curl_exec($chuid)); curl_close($chuid); $image = imagecreatefromstring($data); // this is for debug to print the image ob_start(); imagepng($image); $contents = ob_get_contents(); ob_end_clean(); echo "<img src='data:image/png;base64,".base64_encode($contents)."' />"; // here is the test : I only test 3 pixels ( enough to avoid rivers ... ) $hexaColor = imagecolorat($image,0,0); $color_tran = imagecolorsforindex($image, $hexaColor); $hexaColor2 = imagecolorat($image,0,1); $color_tran2 = imagecolorsforindex($image, $hexaColor2); $hexaColor3 = imagecolorat($image,0,2); $color_tran3 = imagecolorsforindex($image, $hexaColor3); $red = $color_tran['red'] + $color_tran2['red'] + $color_tran3['red']; $green = $color_tran['green'] + $color_tran2['green'] + $color_tran3['green']; $blue = $color_tran['blue'] + $color_tran2['blue'] + $color_tran3['blue']; imagedestroy($image); var_dump($red,$green,$blue); //int(492) int(570) int(660) if($red == 492 && $green == 570 && $blue == 660) return 1; else return 0; } 
+8
Jan 22 '13 at 13:50
source share

Check out this article. It accurately determines whether something is on the water without requiring a server. This is a hack that depends on the user style in Google Maps.

http://tech.bellycard.com/blog/where-d-the-water-go-google-maps-water-pixel-detection-with-canvas/

+7
Sep 17 '13 at 23:15
source share

I thought it would be more interesting to do this request locally, so I can be more confident: let me say that I want to generate 25,000 random earth coordinates at once, I would prefer to avoid calls to expensive external APIs. Here is my snapshot on this in python using the python example mentioned by TomSchober. Basically, he looks at the coordinates on a 350 MB pre-made file containing all the coordinates of the earth, and if the coordinates exist there, he prints them.

 import ogr from IPython import embed import sys drv = ogr.GetDriverByName('ESRI Shapefile') #We will load a shape file ds_in = drv.Open("land_polygons.shp") #Get the contents of the shape file lyr_in = ds_in.GetLayer(0) #Get the shape file first layer #Put the title of the field you are interested in here idx_reg = lyr_in.GetLayerDefn().GetFieldIndex("P_Loc_Nm") #If the latitude/longitude we're going to use is not in the projection #of the shapefile, then we will get erroneous results. #The following assumes that the latitude longitude is in WGS84 #This is identified by the number "4236", as in "EPSG:4326" #We will create a transformation between this and the shapefile's #project, whatever it may be geo_ref = lyr_in.GetSpatialRef() point_ref=ogr.osr.SpatialReference() point_ref.ImportFromEPSG(4326) ctran=ogr.osr.CoordinateTransformation(point_ref,geo_ref) def check(lon, lat): #Transform incoming longitude/latitude to the shapefile projection [lon,lat,z]=ctran.TransformPoint(lon,lat) #Create a point pt = ogr.Geometry(ogr.wkbPoint) pt.SetPoint_2D(0, lon, lat) #Set up a spatial filter such that the only features we see when we #loop through "lyr_in" are those which overlap the point defined above lyr_in.SetSpatialFilter(pt) #Loop through the overlapped features and display the field of interest for feat_in in lyr_in: # success! print lon, lat check(-95,47) 

I tried a dozen coordinates, it works great. The file land_polygons.shp can be downloaded here , OpenStreetMaps compliments. (I myself used the first link to download WGS84, maybe the second one works as well)

+7
Dec 19 '14 at 11:00
source share

There is a free web API that solves exactly this problem and is called onwater.io . This is not something built into Google Maps, but given latitude and longitude, it will definitely return true or false through a request for receipt.

Water example: https://api.onwater.io/api/v1/results/23.92323,-66.3

 { lat: 23.92323, lon: -66.3, water: true } 

Land example: https://api.onwater.io/api/v1/results/42.35,-71.1

 { lat: 42.35, lon: -71.1, water: false } 

Full disclosure I work for Dockwa.com , an onwater development company. We built on the water to solve this problem ourselves and help the community. It is free to use (pay for a large amount) and we would like to share :)

+6
Jul 18 '17 at 3:26
source share

In addition to reverse geocoding - as Dr. Mollet pointed out that he can return ZERO_RESULTS - you can use the Elevation service. If you get zero reverse geocoding results, get the height of the location. As a rule, the sea receives a negative number, since the bottom of the sea is below sea level. There is a fully processed example of the elevation service at http://www.daftlogic.com/sandbox-google-maps-find-altitude.htm .

Keep in mind that since Google does not make this information available, any other method is just a guess, and guesswork is inherently inaccurate. However, using type returned by reverse geocoding, or raising if type not available, will cover most cases.

+5
Mar 10 2018-12-12T00:
source share

This method is completely unreliable. In fact, the data returned will depend entirely on what part of the world you work in. For example, I work in France. If I click on the sea on the coast of France, Google will return the nearest section where it can “guess”. When I requested information from Google on the same issue, they replied that they could not accurately return that the requested point was on the water mass.

Not a very satisfactory answer, I know. This is quite difficult, especially for those of us who provide the user with the ability to click on the map to determine the position of the marker.

+3
Mar 10 2018-12-12T00:
source share

If all else fails, you can always try to check the height at a point and for a distance - not many things, except water, are usually completely flat.

+3
Jul 04 '13 at 14:04 on
source share

Unfortunately, this answer is not part of the Google Maps API, and the reference resource is not free, but there is a DynamicGeometry web service that provides a GetWaterOrLand operation that accepts a latitude / longitude pair ( you can see the demo here ).

My understanding of how this is implemented is the use of water form files. How exactly these form files are used with the Google Maps API, but you might get some idea of ​​the related demo.

Hope this helps in some way.

+2
Aug 17 2018-12-12T00:
source share

I would recommend you quit your game here. You can use tools like GDAL to request the content below the dot in the shapefile. You can get shapefiles for US geography from many sources, including the US Census Bureau .

This can be done using GDAL binaries, a C source, or using swig in Java, Python, etc.

Census maps

GDAL Information

Python point request example

+2
Jul 02 '13 at
source share

Here is another example in pure JavaScript: http://jsfiddle.net/eUwMf/

As you can see, the idea is basically the same as rebe100x, getting the image from the Google static map API and reading the first pixel:

 $("#xGps, #yGps").change(function() { var img = document.getElementById('mapImg'); // Bypass the security issue : drawing a canvas from an external URL. img.crossOrigin='anonymous'; var xGps = $("#xGps").val(); var yGps = $("#yGps").val(); var mapUrl = "http://maps.googleapis.com/maps/api/staticmap?center=" + xGps + "," + yGps + "&zoom=14&size=20x20&maptype=roadmap&sensor=false"; // mapUrl += "&key=" + key; $(img).attr("src", mapUrl); var canvas = $('<canvas/>')[0]; canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); var pixelData = canvas.getContext('2d').getImageData(1, 1, 1, 1).data; if (pixelData[0] == 164 && pixelData[1] == 190 && pixelData[2] == 220) { $("#result").html("Water"); } else { $("#result").html("Not water"); } }); 
+2
Jul 02 '13 at 17:25
source share

See the answer I gave a similar question - it uses the "HIT_TEST_TERRAIN" from Earth Api to achieve this function.

There is a working example of an idea that I put together here: http://www.msa.mmu.ac.uk/~fraser/ge/coord/

+2
Jul 02 '13 at 17:33
source share

I managed to get closer using the Google Elevation API. Here's a picture of the results:

screenshot of results

You see that the hexagons largely remain on land, although a rectangular perimeter is defined that extends partially above the water. In this case, I did a quick check with Google Maps and the minimum height on land was about 8-9 m, so that was my threshold. The code is mainly copied / pasted from Google documentation and, here is the full text:

https://gist.github.com/dvas0004/fd541a0502528ebfb825

+2
Mar 01 '16 at 16:31
source share

Here is a simple solution

Since Google does not give reliable results regarding coordinates that lie on ocean or inland waters, you need to use another backup service, such as Yandex, to help provide this important information when it is missing. Most likely, you will not want to use Yandex as the main geocoder, since Google far surpasses the reliability and completeness of world data, however Yandex can be very useful for retrieving data when it is associated with coordinates over bodies of water, so use both.




Yandex Documentation: https://api.yandex.com.tr/maps/doc/geocoder/desc/concepts/input_params.xml




Steps for extracting the name of the ocean:

1.) First use Google to change the geocode coordinate.

2.) If Google returns zero results, the probability that the coordinate lies above the ocean is 99%. Now make a secondary reverse geocoding request with the same coordinates as for Yandex. Yandex will return a JSON response with exact coordinates, inside this answer there will be two "key": values ​​"value" of importance

 ["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] and ["GeoObject"]["name"] 

Check the view key, if it is == "hydro", you know that you are above the body of the water, and since Google returned zero results, it is probably 99.99%, this body of water is the ocean. The name of the ocean will be designated as "name".

Here is an example of how I use this strategy written in Ruby

 if result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] == "hydro" ocean = result.data["GeoObject"]["name"] end 



Steps to extract the name of the inner body of water:

In this example, suppose our coordinate lies somewhere in the lake:

1.) First use Google to change geocoding coordinates.

2.) Google is likely to return a result that is an outstanding default address on land. As a result, it supplies the coordinates of the returned address, this coordinate will not match the one you specified. Measure the distance between the coordinate you submitted and the one returned with the result, if it differs significantly (for example, 100 yards), then query the secondary backup using Yandex and check to see the “view” value, if it is “hydro”, then you know that coordinate lies on the water. Since Google returned the result, unlike the above example, this is 99.99%, it is probably the internal water flow of water, so now you can get the name. If the “view” is not “hydro,” use a Google geocoded object.

 ["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] and ["GeoObject"]["name"] 

Here is the same code written in Ruby to get inland_body_of_water

 if result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] == "hydro" inland_body_of_water = result.data["GeoObject"]["name"] end 



Licensing note: as far as I know, Google does not allow its data to be displayed on any maps other than those offered by Google. However, Yandex has very flexible licensing, and you can use their data to display on Google maps.

In addition, Yandex has a limit on the maximum speed of 50,000 requests / day for free and without an API key.

+1
May 18 '15 at 20:01
source share

If the address of the List<Address> returns 0, you can guess this location as an ocean or natural resources. Just add the code below in your answer. Google Places API Response Method.

Initialize the list below

List<Address> addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);

if (addresses.size()==0) { Toast.MakeText(getApplicationContext,"Ocean or Natural Resources selected",Toast.LENGTH_SHORT).show(); }else{ }

+1
May 27 '17 at 11:04
source share

As a complete newbie in Python, I could not get the SylvainB solution to work with a python script that checks if the coordinates are on the ground. However, I managed to figure this out by downloading OSGeo4W ( https://trac.osgeo.org/osgeo4w/ ), and then installed everything I needed, pip, Ipython and verified that all the specified imports were there. I saved the following code as a .py file.

Code to check if the coordinates on the ground

 ###make sure you check these are there and working separately before using the .py file import ogr from IPython import embed from osgeo import osr import osgeo import random #####generate a 1000 random coordinates ran1= [random.uniform(-180,180) for x in range(1,1001)] ran2= [random.uniform(-180,180) for x in range(1,1001)] drv = ogr.GetDriverByName('ESRI Shapefile') #We will load a shape file ds_in = drv.Open("D:\Downloads\land-polygons-complete-4326\land-polygons-complete-4326\land_polygons.shp") #Get the contents of the shape file lyr_in = ds_in.GetLayer(0) #Get the shape file first layer #Put the title of the field you are interested in here idx_reg = lyr_in.GetLayerDefn().GetFieldIndex("P_Loc_Nm") #If the latitude/longitude we're going to use is not in the projection #of the shapefile, then we will get erroneous results. #The following assumes that the latitude longitude is in WGS84 #This is identified by the number "4236", as in "EPSG:4326" #We will create a transformation between this and the shapefile's #project, whatever it may be geo_ref = lyr_in.GetSpatialRef() point_ref=osgeo.osr.SpatialReference() point_ref.ImportFromEPSG(4326) ctran=osgeo.osr.CoordinateTransformation(point_ref,geo_ref) ###check if the random coordinates are on land def check(runs): lon=ran1[runs] lat=ran2[runs] #Transform incoming longitude/latitude to the shapefile projection [lon,lat,z]=ctran.TransformPoint(lon,lat) #Create a point pt = ogr.Geometry(ogr.wkbPoint) pt.SetPoint_2D(0, lon, lat) #Set up a spatial filter such that the only features we see when we #loop through "lyr_in" are those which overlap the point defined above lyr_in.SetSpatialFilter(pt) #Loop through the overlapped features and display the field of interest for feat_in in lyr_in: return(lon, lat) ###give it a try result = [check(x) for x in range(1,11)] ###checks first 10 coordinates 

I tried to get it to work in R, but I had a nightmare trying to get all the packages that need to be installed, so it got stuck in python.

0
Jan 29 '19 at 11:05
source share

I have a different solution here. In the current implementation of the Google map, it does not calculate the direction / distance from the location of the water to the placement and vice versa. Why do not we use this logic to determine if a point is earth or water.

For example, let's look at this example.

if we want to determine if point x is land or water, then

check the direction between the point x and the known point y , which is the ground. If it determines the direction / distance, then the point x is ground or is it water.

-2
Jul 04 '13 at 12:01
source share



All Articles