2012-04-09 11 views
3

Ich habe einige Formdaten (eine Reihe von kml-Dateien in der Spalte einer Fusionstabelle und/oder Datenbank) und möchte sie mit einer anderen Tabelle mit Längengrad zusammenführen Punkte. Grundsätzlich möchte ich einen Weg finden, zu bestimmen, ob ein bestimmter Breitengradpunkt in den kml-Formen enthalten ist, und wenn ja, speichern Sie einen Bezug auf diese Reihe. Ich hatte vielleicht einen Weg, dies innerhalb der Fusionstabellen zu tun, aber wenn nicht, gibt es vielleicht eine Möglichkeit, jeden Kilometer zu durchlaufen und zu testen, ob der Breitengrad in ihm enthalten ist. Ich verstehe das nicht besonders effizient. Jede Hilfe, Algorithmus, Service usw. wäre großartig.So ermitteln Sie, ob ein Punkt innerhalb eines kml oder einer Form liegt

Antwort

3

Die Fusion Tables SQL-API hat einen ST_INTERSECTS-Operator, findet jedoch nur Punkte innerhalb eines CIRCLE oder eines RECTANGLE. GMap V3 hat eine Geometriebibliothek mit einer poly.containsLocation() -Methode, die für beliebige Polygone funktionieren wird. Siehe: GoogleMap geometry/poly library

P.S. Ich weiß, das funktioniert nicht für KML-Dateien, aber sie enthalten die Polygonpunkte, die in GMAP-Polygone verwandelt werden könnten.

+0

Splendid, das ist ein guter Start – user379468

0

Dies ist wahrscheinlich seit langem gelöst, aber da ich ein ähnliches Problem hatte, dachte ich, dass ich meine Lösung posten würde .

Ich hatte zwei Fusion Tabellen i) Adresse & Daten und ii) Polygone & Daten. Ich wollte in der Lage sein, alle Adressen innerhalb eines oder mehrerer der Polygone leicht abzufragen. Ich hätte dies in Echtzeit über meine Mapping-Webseite tun können, entschied aber, dass es besser war, das relevante Polygon einmal im Voraus zu suchen und dann diese Daten für meine Mapping-Abfragen zu verwenden (schneller und einfacher mehrere Polygone in der Weboberfläche zu spezifizieren).

Also exportierte ich meine Tabelle i) mit den Adressen in Google Sheets, und erstellte ein kurzes einfaches Skript, das überprüfte, in welchem ​​Polygon die Adresse war und schrieb es zurück auf das Google-Blatt. Dann habe ich meine Fusionstabelle aktualisiert i).

Ich hatte einen Datensatz von fast 3000 Adressen und 2000 Polygonen, so dass es ein paar Mal ausging und hatte ein paar Adressfehler, aber das war einfach zu beheben und ich habe nur das Skript aus der ersten Zeile ausgeführt das war nicht aktualisiert worden. Beachten Sie, dass dies nicht funktioniert, wenn die Polygone sich gegenseitig überlappen, aber meiner nicht, da sie geografische Grenzen waren ;-)

Der Code, den ich benutzte, ist unten und auch auf dem Punkt here. Sie müssen natürlich die Tabellen-ID aktualisieren und müssen wahrscheinlich etwas mit OAuth machen (was ich nicht ganz verstanden habe, aber den Anweisungen von Google gefolgt ist).

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