使用 KML 几何列的 Fusiontableslayer 获得正确的缩放级别和中心地图

Fusiontableslayer using KML Geometry column get correct zoom level and center map

我有一个大型 KML 文件,我已将其转换为 Fusion Table。使用下面的代码,我可以将多边形绘制到地图上。我现在想做的是获得正确的缩放级别,以便多边形可以填充地图 canvas 并使地图居中,以便多边形很好地适合屏幕。

var FT_TableID = '1wZ5CUvoqmpYOjtcnUkMvFu1hWbPeKdaMT0NkTw_5'; 
 map = new google.maps.Map(document.getElementById('map_canvas'), {
            center: new google.maps.LatLng(50.7200, -1.8800),
            zoom: 5,
            mapTypeId: 'roadmap'
        });

 // GET DATA    
        layer = new google.maps.FusionTablesLayer({
            query: {
                select: 'Geometry',
                from: FT_TableID
            },
            options: {
                styleId: 2,
                templateId: 2
            }
        });
        //SET MAP    
        layer.setMap(map);

Fusion 中的几何列 Table 是每个多边形的 KML 图,因此看起来有点像:

<Polygon><outerBoundaryIs><LinearRing><coordinates>-2.817673,50.719771,0.0 -2.816075,50.719314,0.0 -2.813323,50.718085,....

一种选择是使用geoxml3 to parse the KML retrieved from the FusionTable using the visualization library查询。

proof of concept

代码片段:

google.load('visualization', '1', {
    'packages': ['corechart', 'table', 'geomap']
  });
  var map;
  var layer;
  var FT_TableID = '1wZ5CUvoqmpYOjtcnUkMvFu1hWbPeKdaMT0NkTw_5';

  function initialize() {
    map = new google.maps.Map(document.getElementById('map_canvas'), {
      center: new google.maps.LatLng(50.7200, -1.8800),
      zoom: 8,
      mapTyp8Id: 'roadmap'
    });

    // GET DATA    
    layer = new google.maps.FusionTablesLayer({
      query: {
        select: 'geometry',
        from: FT_TableID
      },
      options: {
        styleId: 2,
        templateId: 2
      }
    });
    //SET MAP    
    layer.setMap(map);
  }

  function changeMap(option) {
    var searchString = document.getElementById('searchString').value.replace("'", "\'");
    var searchString = geoXML3.nodeValue(option.selectedOptions[0]);
    if (searchString == "--ALL--") {
      layer.setOptions({
        query: {
          select: 'geometry',
          from: tableid
        }
      });
      map.setZoom(8);
      map.setCenter(new google.maps.LatLng(50.7200, -1.8800));
      return;
    }
    var query = "SELECT 'geometry' FROM " + FT_TableID + " WHERE 'name' = '" + searchString + "'";
    layer.setOptions({
      query: {
        from: FT_TableID,
        select: 'geometry',
        where: "'name' = '" + searchString + "'"
      }
    });
    zoom2query(query);
  }

  function zoom2query(query) {
    // zoom and center map on query results
    //set the query using the parameter
    var queryText = encodeURIComponent(query);
    var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
    //set the callback function
    query.send(zoomTo);
  }

  function zoomTo(response) {
    if (!response) {
      alert('no response');
      return;
    }
    if (response.isError()) {
      alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
      return;
    }
    FTresponse = response;
    //for more information on the response object, see the documentation
    //http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
    numRows = response.getDataTable().getNumberOfRows();
    numCols = response.getDataTable().getNumberOfColumns();
    // handle multiple matches
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < numRows; i++) {
      var kml = FTresponse.getDataTable().getValue(i, 0);
      // create a geoXml3 parser for the click handlers
      var geoXml = new geoXML3.parser({
        map: map,
        zoom: false
      });

      geoXml.parseKmlString("<Placemark>" + kml + "</Placemark>");
      // handle all possible kml placmarks
      if (geoXml.docs[0].gpolylines.length > 0) {
        geoXml.docs[0].gpolylines[0].setMap(null);
        if (i == 0) var bounds = geoXml.docs[0].gpolylines[0].bounds;
        else bounds.union(geoXml.docs[0].gpolylines[0].bounds);
      } else if (geoXml.docs[0].markers.length > 0) {
        geoXml.docs[0].markers[0].setMap(null);
        if (i == 0) bounds.extend(geoXml.docs[0].markers[0].getPosition());
        else bounds.extend(geoXml.docs[0].markers[0].getPosition());
      } else if (geoXml.docs[0].gpolygons.length > 0) {
        geoXml.docs[0].gpolygons[0].setMap(null);
        if (i == 0) var bounds = geoXml.docs[0].gpolygons[0].bounds;
        else bounds.union(geoXml.docs[0].gpolygons[0].bounds);
      }
    }
    map.fitBounds(bounds);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
html,
  body {
    width: 100%;
    height: 100%;
  }
  #map_canvas {
    width: 100%;
    height: 98%;
  }
<script src="http://geoxml3.googlecode.com/svn/branches/polys/geoxml3.js"></script>
<script src="http://www.google.com/jsapi"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div style="margin-top: 10px;">
  <label>NPT</label>
  <select id="searchString" onchange="changeMap(this);">
    <option value="">--ALL--</option>
    <option value="1">Beaminster NPT</option>
    <option value="2">Bearwood NPT</option>
    <option value="3">Blandford Rural NPT</option>
    <option value="4">Blandford Town</option>
    <option value="5">Bournemouth Central NPT</option>
    <option value="6">Bridport Town NPT</option>
    <option value="7">Broadstone &amp; Merley NPT</option>
    <option value="8">Canford Heath NPT</option>
    <option value="9">Central Christchurch NPT</option>
    <option value="10">Charminster &amp; Queens Park NPT</option>
    <option value="11">Chickerell NPT</option>
    <option value="12">Christchurch Town Center NPT</option>
    <option value="13">Corfe Mullen &amp; Stour NPT</option>
    <option value="14">Creekmoor NPT</option>
    <option value="15">Dorchester East Rural NPT</option>
    <option value="16">Dorchester South NPT</option>
    <option value="17">Dorchester West Rural NPT</option>
    <option value="18">East Cliff, Springborne &amp; Boscombe NPT</option>
    <option value="19">East Dorset Rural NPT</option>
    <option value="20">Ferndown Central NPT</option>
    <option value="21">Gillingham Rural NPT</option>
    <option value="22">Gillingham Town NPT</option>
    <option value="23">Hamworthy NPT</option>
    <option value="24">Heatherlands &amp; Ferndown Links NPT</option>
    <option value="25">Kinson North NPT</option>
    <option value="26">Littlemoor NPT</option>
    <option value="27">Lyme Regis NPT</option>
    <option value="28">Melcombe Regis NPT</option>
    <option value="29">Meyrick &amp; Talbot NPT</option>
    <option value="30">Moordown NPT</option>
    <option value="31">Mudeford &amp; Highcliffe NPT</option>
    <option value="32">Newtown &amp; Branksome NPT</option>
    <option value="33">Northbourne &amp; Wallisdown NPT</option>
    <option value="34">Nothe &amp; Chapelhay NPT</option>
    <option value="35">Parkstone, Penn Hill &amp; Canford Cliffs NPT</option>
    <option value="36">Poole Town &amp; Oakdale NPT</option>
    <option value="37">Portland NPT</option>
    <option value="38">Potterne &amp; Three Legged Cross NPT</option>
    <option value="39">Rossmore &amp; Alderney NPT</option>
    <option value="40">Shaftesbury Rural NPT</option>
    <option value="41">Shaftesbury Town NPT</option>
    <option value="42">Sherborne Rural NPT</option>
    <option value="43">Sherborne Town NPT</option>
    <option value="44">Southbourne, Pokesdown &amp; Littledown NPT</option>
    <option value="45">Stour Valley NPT</option>
    <option value="46">Strouden Park NPT</option>
    <option value="47">Sturminster Newton NPT</option>
    <option value="48">Swanage NPT</option>
    <option value="49">The Grange NPT</option>
    <option value="50">Throop &amp; Muscliff NPT</option>
    <option value="51">Townsend NPT</option>
    <option value="52">Verwood Town NPT</option>
    <option value="53">Wareham North NPT</option>
    <option value="54">Wareham West Rural NPT</option>
    <option value="55">West Christchurch NPT</option>
    <option value="56">West Howe NPT</option>
    <option value="57">West Moors, St Leonards &amp; St Ives NPT</option>
    <option value="58">Westbourne &amp; West Cliff NPT</option>
    <option value="59">Westham NPT</option>
    <option value="60">Weymouth Valey, Radipole &amp; Preston NPT</option>
    <option value="61">Wimborne &amp; Colehill NPT</option>
    <option value="62">Winton NPT</option>
    <option value="63">Wyke Regis NPT</option>
  </select>
</div>
<div id="map_canvas"></div>