[javascript] 지점이 Google지도에서 육지 또는 물인지 확인

.. 그리고 구글지도 “물에서 물을 나눕니다”

글쎄요, 성경적인 의미는 아니지만 ..

[Lat, Lon] 지점이 육지인지 물인지 확인하기 위해 어떤 옵션이 있는지 알고 싶습니다.

Google지도에는 분명히이 데이터가 있습니다 (수역은 파란색 임). API에이를 위해 사용할 수있는 것이 있습니까? 그리고 그렇지 않다면-그들은 그것을 생각하지 않았기 때문에 그것을 제공하지 않습니까? 아니면 너무 복잡해서?

이 문제에 대한 정보를 찾지 못했습니다. 여기에서 비슷한 질문 (지형 또는 고도 찾기 등)을 제외하고는 정확히 필요한 것은 아닙니다.

그것을 위해 분리 된 층이 있습니까? 옵션? 명령? 아니면 수동으로해야합니까?

이 방법에 접근하는 방법을 생각할 수있는 유일한 방법 (수동으로 수행해야하는 경우)은 제공된 모든 타일에서 정확한 지점을 확인한 다음 해당 Google지도 색조에 대한 RGB 값을 확인하는 것입니다. 이것은 이론에 불과합니다. 왜냐하면 실제로는 어떻게해야할지 모르겠습니다. 첫 번째 장애물은 예를 들어 타일의 픽셀 위치를 [LatLon] 지점으로 변환 할 수있는 방법을 모릅니다.

준비된 솔루션이 훨씬 쉬울 것입니다.

전 세계의 모든 물이 필요하지는 않습니다 (예 : 시내, 작은 연못, 대부분의 강 또는 이웃의 수영장에 관심이 없습니다. 사람이 떠 다니는 차량의 도움없이 모험 할 수있는 지점이 필요합니다. )

편집 I

댓글을 읽은 후 : 고도 방법은 신뢰할 수 없습니다. 해수면 아래에 너무 많은 장소가 있습니다 ( http://geology.com/below-sea-level/ 여기에서 “가장 깊은”10 개의 목록을 볼 수 있음). 해수면 (호수) 위에 너무 많은 내륙 수역이 있습니다. 역 지리적 위치 방법은 도시, 주 또는 ZERO와 같은 지정 학적 엔티티를 여러 번 반환하므로 신뢰할 수 없습니다. 나는 질문을하기 전에 이미 그 의사 해결책들을 조사해 보았지만, 그들 중 어느 누구도 실제로 질문에 답하지 않았습니다. 이러한 방법은 기껏해야 “추측”이 나쁩니다.



답변

다음 두 가지 방법을 시도해 볼 수 있습니다.

  • Google Maps Reverse Geocoding을 사용할 수 있습니다 . 결과 집합에서을 확인하여 물인지 여부를 확인할 수 있습니다 types. 물의 경우 유형은 natural_feature. http://code.google.com/apis/maps/documentation/geocoding/#Types 링크에서 자세히 알아보세요 .

    또한 지형지 Sea, Lake, Ocean물에 포함 된 경우 지형지 물의 이름과 더 정확한 물과 관련된 다른 단어 를 확인해야합니다 . 예를 들어 사막도 natural_features입니다.

    장점 -모든 감지 프로세스는 클라이언트의 컴퓨터에서 수행됩니다. 자체 서버 측 서비스를 만들 필요가 없습니다.

    단점 -매우 부정확하며 물에서 “없음”을 얻을 가능성이 매우 높습니다.

  • Google 정적지도 를 사용하여 물 / 토지를 픽셀 단위로 감지 할 수 있습니다 . 그러나이를 위해서는 http 서비스를 만들어야합니다.

    서비스에서 수행해야하는 단계는 다음과 같습니다.

    1. 수신 latitude, longitudecurrent zoom클라이언트에서.
    2. http://maps.googleapis.com/maps/api/staticmap?center={위도 ,경도 }&zoom={현재 확대 / 축소`} & size = 1×1 & maptype = roadmap & sensor = false 요청을 Google 정적지도 서비스에 보냅니다 .
    3. 1×1 정적 이미지의 픽셀 색상을 감지합니다.
    4. 탐지에 대한 정보에 응답합니다.

    클라이언트 측에서 픽셀의 색상을 감지 할 수 없습니다. 예, 클라이언트의 컴퓨터에 정적 이미지를로드하고 canvas요소에 이미지를 그릴 수 있습니다. 그러나 getImageData픽셀의 색상을 얻기 위해 캔버스의 컨텍스트를 사용할 수 없습니다 . 이것은 교차 도메인 정책에 의해 제한됩니다.

    Prons- 매우 정확한 감지

    단점 -탐지를위한 자체 서버 리소스 사용


답변

현재 Google 서비스로는 불가능한 것 같습니다.

그러나 Koordinates Vector JSON Query 서비스 와 같은 다른 서비스가 있습니다 ! URL의 데이터를 쿼리하기 만하면 JSON / XML 응답이 반환 됩니다.

요청 예시 : 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

키와 선택한 레이어 번호를 등록하고 제공해야합니다. 사용 가능한 레이어의 모든 저장소를 검색 할 수 있습니다 . 대부분의 레이어는 지역에만 해당되지만 World Coastline 과 같이 전역 레이어도 찾을 수 있습니다 .

여기에 이미지 설명 입력

계층을 선택하고 “서비스”탭을 클릭하면 예제 요청 URL이 표시됩니다. 등록 만하면된다고 믿습니다.

그리고 이제 최고 :

레이어를 업로드 할 수 있습니다!

바로 사용할 수 없습니다. 어떻게 든 처리해야하지만 작동해야합니다! 레이어 저장소는 실제로 사람들이 필요에 따라 업로드 한 것처럼 보입니다.


답변

이것은 내가 사용하고 너무 나쁘지 않습니다 … 픽셀을 추가하여 낭비 할 CPU가 더 많으면 테스트를 향상시킬 수 있습니다.

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


답변

onwater.io 라는이 문제를 정확히 해결하는 무료 웹 API가 있습니다. Google지도에 내장 된 것은 아니지만 위도와 경도가 주어지면 get 요청을 통해 정확하게 true 또는 false를 반환합니다.

물의 예 :
https://api.onwater.io/api/v1/results/23.92323,-66.3

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

육지의 예 :
https://api.onwater.io/api/v1/results/42.35,-71.1

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

전체 공개 저는 onwater 회사 인 Dockwa.com에서 일합니다. 우리는이 문제를 스스로 해결하고 지역 사회를 돕기 위해 물 위에 건설했습니다. 무료로 사용할 수 있으며 (대량 유료) 공유하고 싶었습니다. 🙂


답변

이 쿼리를 로컬에서 수행하는 것이 더 흥미 롭다고 생각했기 때문에 좀 더 자립 할 수 있습니다. 한 번에 25000 개의 임의의 토지 좌표를 생성하고 비용이 많이 드는 외부 API에 대한 호출을 피하고 싶습니다. 다음은 TomSchober가 언급 한 파이썬 예제를 사용하여 파이썬 으로 찍은 사진입니다. 기본적으로 모든 육지 좌표를 포함 하는 미리 만들어진 350MB 파일 에서 좌표를 조회 하고 좌표가 거기에 있으면 인쇄합니다.

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's 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's 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)

나는 12 개의 코디네이터를 시도했는데 훌륭하게 작동합니다. “land_polygons.shp”파일은 여기 에서 다운로드 할 수 있으며 OpenStreetMaps를 보완합니다. (첫 번째 WGS84 다운로드 링크를 직접 사용했으며 두 번째도 작동 할 수 있습니다)


답변

기사를 확인하십시오 . 서버없이 물에 무언가가 있는지 정확하게 감지합니다. Google지도의 맞춤 스타일링 기능에 의존하는 해킹입니다.


답변

Molle 박사 가 지적했듯이 역 지오 코딩 외에도 ZERO_RESULTS를 반환 할 수 있습니다. 고도 서비스를 사용할 수 있습니다. 역 지오 코딩으로 결과가 0 인 경우 위치의 고도를 가져옵니다. 일반적으로 해저가 해수면보다 낮기 때문에 바다는 음수를 얻습니다. 완전히 작동 된 예가 있습니다.고도 서비스의 있습니다.

Google은이 정보를 제공하지 않으므로 다른 방법은 추측 일 뿐이며 추측은 본질적으로 정확하지 않습니다. 그러나 type역 지오 코딩으로 반환 된 값을 사용 하거나 type사용할 수없는 경우 고도를 사용하면 대부분의 상황을 해결할 수 있습니다.