2012-04-09 1 views
3

융합 테이블 및/또는 데이터베이스의 열에 일련의 kml 파일이 있음) 위도 위도가 포함 된 다른 테이블과 병합하려고합니다. 전철기. 기본적으로 주어진 위도 lon point가 kml 도형 내에 포함되어 있는지 확인하고, 그렇다면 해당 행에 대한 참조를 저장하는 몇 가지 방법이 필요합니다. 융합 테이블에서이 작업을 수행하는 방법이 있었지만 그렇지 않은 경우 각 kml을 반복하고 lat lon point가 포함되어 있는지 테스트하는 방법이있을 수 있습니다. 나는 이것을 대단히 효율적이지 않다는 것을 안다. 도움, 알고리즘, 서비스 등 모든 도움이 될 것입니다.포인트가 kml 또는 모양에 속하는지 확인하는 방법

답변

3

Fusion Tables SQL API에는 ST_INTERSECTS 연산자가 있지만 CIRCLE 또는 RECTANGLE 내에서만 점을 찾습니다. GMap V3에는 poly.containsLocation() 메소드가있는 기하 도형 라이브러리가 있습니다. 이것은 임의의 다각형에서 작동 할 것입니다. 참조 : GoogleMap geometry/poly library

P. KML 파일에는 작동하지 않지만 GMAP 폴리곤으로 바뀔 수있는 다각형 점이 포함되어 있습니다.

+0

화려한, 그 위대한 시작입니다 – user379468

0

이것은 아마도 오래전부터 해결되었지만 비슷한 문제가 있었기 때문에 내 솔루션을 게시 할 것으로 생각했습니다. .

나는 두 개의 퓨전 테이블 i) 주소 & 데이터와 ii) 폴리곤 & 데이터를 가지고있다. 하나 이상의 폴리곤 내의 모든 주소를 쉽게 찾을 수 있기를 원했습니다. 내 매핑 웹 페이지를 통해 실시간으로이 작업을 수행 할 수 있었지만 사전에 관련 다각형을 한 번 조회 한 다음이 데이터를 사용하여 매핑 쿼리를 수행하는 것이 더 빠르고 웹 인터페이스에서 여러 다각형을 더 쉽게 지정할 수 있다고 판단했습니다.

주소를 Google 시트로 내 보낸 다음 주소가있는 폴리곤을 확인하고 Google 시트에 다시 작성하는 간단한 간단한 스크립트를 만들었습니다. 그런 다음 융합 표를 업데이트했습니다.

나는 거의 3000 개의 주소와 2000 개의 다각형을 가진 데이터 세트를 가지고 있으므로 몇 번 타임 아웃되고 두 개의 주소 오류가 발생하지만 수정하기 쉽고 첫 번째 행에서 실행되도록 스크립트를 설정했다. 업데이트되지 않았습니다. 폴리곤이 서로 겹치지 만 내 경계가 경계선이 아니기 때문에이 점은 작동하지 않습니다.

사용하는 코드는 아래와 같으며 요점은 here입니다. 분명히 테이블 ID를 업데이트 할 필요가있을 것입니다. OAuth로 뭔가를해야 할 필요가 있습니다 (Google의 지침에 따라 잘 이해하지 못했지만 완료되었습니다.).

// replace with your fusion table's id (from File > About this table) 
 
var TABLE_ID = 'xxxxxxxxxx'; 
 

 
// first row that has data, as opposed to header information 
 
var FIRST_DATA_ROW = 2; 
 
var FIRST_DATA_COLUMN = 11; 
 
var LAT_COLUMN = 1; 
 
var LNG_COLUMN = 2; 
 
var SA2_COLUMN = 6; 
 
var SA3_COLUMN = 7; 
 

 
/** 
 
* Uses a lat and lng data in google sheets to check if an address is within a kml polygon 
 
* in a list of KML polygons in fusion (in this case ABS/ASGC SA2 and SA3 regions, but could be any polygon) 
 
* the function then stores the ID/name of the relevant polygon in google sheets 
 
* I could check this data in realtime as I render maps, but as it doesn't changed, figure its better to just record 
 
* which polygon each address pertains to so its quicker and easier to search (in particular it mades it easier to write a query 
 
* which identifies all the address within multiple polygons) 
 
* in this case I had 3000 rows so it exceeded maximum execution times, so I just updated the first data row a couple of times 
 
* when the execution time exceeded. 
 
*/ 
 
function updateSA2ID() { 
 
    var tasks = FusionTables.Task.list(TABLE_ID); 
 
    var sqlResponse = ''; 
 
    
 
    // Only run if there are no outstanding deletions or schema changes. 
 
    if (tasks.totalItems === 0) { 
 
    var sheet = SpreadsheetApp.getActiveSheet(); 
 
    var latLngData = sheet.getRange(FIRST_DATA_ROW, FIRST_DATA_COLUMN, sheet.getLastRow(), sheet.getLastColumn()); 
 
    
 
     i = 1; 
 
    // Loop through the current current sheet 
 
    for (i = 1; i <= latLngData.getNumRows(); i++) {  
 
     
 
     // cross reference to Fusion table 
 
     lat = latLngData.getCell(i,LAT_COLUMN).getValue(); 
 
     lng = latLngData.getCell(i,LNG_COLUMN).getValue(); 
 
      
 
     sqlString = "SELECT 'SA2 Code', 'SA3 Code' FROM " + TABLE_ID + " WHERE ST_INTERSECTS(geometry, CIRCLE(LATLNG(" + lat + ", " + lng + "),1)) ";  
 
     //Browser.msgBox('Lat ' + lat + ' Lng ' + lng + '; ' + sqlString, Browser.Buttons.OK); 
 
     sqlResponse = FusionTables.Query.sql(sqlString); 
 
     //Browser.msgBox('SQL Response ' + sqlResponse, Browser.Buttons.OK); 
 

 
     latLngData.getCell(i,SA2_COLUMN).setValue(sqlResponse.rows[0][0]); // set SA2 
 
     latLngData.getCell(i,SA3_COLUMN).setValue(sqlResponse.rows[0][1]); // set SA3  
 

 
    } 
 
     
 
    } 
 
    else { 
 
    Logger.log('Skipping row replacement because of ' + tasks.totalItems + ' active background task(s)'); 
 
    } 
 
};