如何确定一个点是否在kml或形状内

时间:2012-04-09 16:24:45

标签: google-maps kml point google-fusion-tables

我有一些形状数据(融合表和/或数据库列中的一系列kml文件),我想将它与另一个包含纬度经度点的表合并。基本上我想要一些方法来确定给定的lat lon点是否包含在kml形状的on中,如果是,则保存对该行的引用。      我可能在融合表中有一种方法可以做到这一点,但如果没有,也许有一种方法可以循环每个kml并测试lat lon点是否包含在其中。我理解这一点并不是非常有效。      任何帮助,算法,服务等都会​​很棒。

2 个答案:

答案 0 :(得分:3)

Fusion Tables SQL API具有ST_INTERSECTS运算符,但只能在CIRCLE或RECTANGLE中找到点。 GMap V3有一个几何库,它有一个poly.containsLocation()方法,我认为它适用于任意多边形。请参阅:GoogleMap geometry/poly library

P.S。我意识到这对KML文件不起作用,但它们确实包含可以转换为GMAP多边形的多边形点

答案 1 :(得分:0)

这可能早已解决,但由于我遇到了类似的问题,我认为我会发布我的解决方案。

我有两张Fusion桌子i)地址&数据和ii)多边形和数据。我希望能够轻松查询以查找一个或多个多边形内的所有地址。我可以通过我的映射网页实时完成这项工作,但决定提前一次查找相关多边形然后使用此数据进行我的映射查询(更快更容易在Web界面中指定多个多边形)。

所以,我将表格i)导出到google工作表的地址,并创建了一个简短的简单脚本,用于检查地址所在的多边形并将其写回google工作表。然后我更新了我的融合表i)。

我有一个近3000个地址和2000个多边形的数据集,所以它超时几次并且有一些地址错误,但这很容易修复,我只是将脚本设置为从第一行运行没有更新。请注意,如果多边形相互重叠,这不会起作用,但我的并不是因为它们是地理边界; - )

我使用的代码在下面,也在gist here上。你显然需要更新表格ID,并且可能需要对OAuth做一些事情(我没有完全理解,但遵循谷歌的指示并完成了它。)



// 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)');
  }
};
&#13;
&#13;
&#13;