У меня есть некоторые данные формы (ряд файлов kml в столбце сводной таблицы и/или базы данных), и я хочу объединить их с другой таблицей, содержащей точки широты и долготы. По сути, мне нужен какой-то способ определить, содержится ли данная точка широты и долготы в одной из форм kml, и если да, то сохранить ссылку на эту строку. Я думал, что, возможно, есть способ сделать это из таблиц слияния, но если нет, возможно, есть способ перебрать каждый kml и проверить, содержится ли в нем точка lat lon. Я понимаю, что это не очень эффективно. Любая помощь, алгоритм, сервис и т. д. были бы замечательными.
Как определить, находится ли точка в пределах kml или формы
Ответы (2)
API Fusion Tables SQL имеет оператор ST_INTERSECTS, но находит точки только внутри CIRCLE или RECTANGLE. GMap V3 имеет библиотеку геометрии, в которой есть метод poly.containsLocation(), который, я думаю, будет работать для произвольных полигонов. См.: геометрия/полибиблиотека GoogleMap.
P.S. Я понимаю, что это не работает для файлов KML, но они содержат точки полигонов, которые можно превратить в полигоны GMAP.
Вероятно, это давно решено, но, поскольку у меня была аналогичная проблема, я решил опубликовать свое решение.
У меня было две таблицы Fusion: i) адрес и данные и ii) полигоны и данные. Я хотел иметь возможность легко запрашивать все адреса в пределах одного или нескольких полигонов. Я мог бы сделать это в реальном времени через свою веб-страницу картографирования, но решил, что лучше один раз заранее найти соответствующий полигон, а затем использовать эти данные для выполнения моих запросов картографирования (быстрее и проще указать несколько полигонов в веб-интерфейсе).
Итак, я экспортировал свою таблицу i) с адресами в листы Google и создал короткий простой скрипт, который проверял, в каком полигоне находится адрес, и записывал его обратно в лист Google. Затем я обновил свою таблицу слияния i).
У меня был набор данных почти из 3000 адресов и 2000 полигонов, так что время ожидания несколько раз истекло, и было несколько адресных ошибок, но это было легко исправить, и я просто настроил скрипт на запуск с первой строки, которая не был обновлен. Обратите внимание, что это не сработает, если полигоны накладываются друг на друга, но у меня этого не произошло, поскольку они были географическими границами ;-)
Код, который я использовал, приведен ниже, а также в здесь. Очевидно, вам нужно обновить идентификатор таблицы и, вероятно, нужно что-то сделать с 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)');
}
};