我有一些形状数据(融合表和/或数据库列中的一系列 kml 文件),我想将它与另一个包含纬度经度点的表合并。基本上我想要某种方法来确定给定的纬度点是否包含在 kml 形状中,如果是,则保存对该行的引用。我虽然也许有一种方法可以从融合表中做到这一点,但如果没有,也许有一种方法可以遍历每个 kml 并测试 lat lon 点是否包含在其中。我理解这不是非常有效。任何帮助、算法、服务等都会很棒。
2 回答
Fusion Tables SQL API 有一个 ST_INTERSECTS 运算符,但只能在 CIRCLE 或 RECTANGLE 中查找点。GMap V3 有一个几何库,它有一个 poly.containsLocation() 方法,我认为它适用于任意多边形。请参阅:GoogleMap 几何/多边形库
PS我意识到这不适用于KML文件,但它们确实包含可以变成GMAP多边形的多边形点
这可能早就解决了,但是由于我遇到了类似的问题,我想我会发布我的解决方案。
我有两个 Fusion 表 i)地址和数据以及 ii)多边形和数据。我希望能够轻松查询以查找一个或多个多边形内的所有地址。我可以通过我的地图网页实时完成这项工作,但我决定最好提前查找一次相关的多边形,然后使用这些数据进行地图查询(在 Web 界面中更快、更容易地指定多个多边形)。
因此,我将带有地址的表格 i) 导出到了 google 表格,并创建了一个简短的简单脚本,用于检查地址所在的多边形并将其写回 google 表格。然后我更新了我的融合表 i)。
我有一个包含近 3000 个地址和 2000 个多边形的数据集,所以它超时了几次,并且有几个地址错误,但这很容易修复,我只是将脚本设置为从没有的第一行运行已更新。请注意,如果多边形相互重叠,这将不起作用,但我的没有,因为它们是地理边界;-)
我使用的代码在下面,也是在这里的要点。您显然需要更新表 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)');
}
};