Fusion Tables 层中超过最大 URL 长度的请求

Requests exceeding maximum URL length in Fusion Tables layer

我在 Google 地图上使用 Fusion Tables 图层。如果我添加一个大的 where 条件(在 1000 多个项目中),该层不会加载。

<!DOCTYPE html>
<html>
<head>
  <meta content="initial-scale=1.0, user-scalable=no" name="viewport">
  <meta charset="utf-8">
  <title>GEO View</title>
  <style>
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    #map {
      height: 100%;
      zoom: 0.7;
      -moz-transform: scale(0.8);
      -moz-transform-origin: 0 0;
    }
  </style>
</head>
<body>
  <div id="map"></div>
  <script>
    var arr = ['37159'];
    var draw_str = ['06037', '06043', '06057', '06065', '06079', '06097', '08011', '08037', '08051', '08069', '08099', '08119', '12041', '12075', '12113', '12123', '13015', '13029', '13095', '13151', '13161', '13169', '13197', '13209', '13213', '13235', '13263', '13267', '13273', '13275', '13293', '13305', '13319', '13990', '16017', '16023', '16047', '16049', '17015', '17043', '17053', '17077', '17079', '17081', '17129', '17141', '17197', '18019', '18043', '18067', '18105', '18115', '18119', '18127', '18147', '19013', '19031', '19067', '19079', '19087', '19111', '19113', '19127', '19153', '19161', '19169', '19175', '19187', '20009', '20019', '20037', '20039', '20051', '20059', '20067', '20087', '01017', '01035', '01053', '01073', '01081', '01127', '02282', '05007', '05031', '05039', '05053', '05067', '05087', '05089', '05119', '05123', '37025', '37037', '37057', '37077', '37123', '37153', '37157', '37159', '37193', '38017', '38045', '38051', '38065', '38101', '39007', '39019', '39021', '39049', '39057', '39059', '39063', '39069', '39081', '39089', '39091', '39097', '39101', '39139', '39153', '39167', '40003', '40019', '40087', '40129', '40153', '41011', '41027', '41049', '42013', '42021', '42035', '42037', '42041', '42055', '42063', '42073', '42077', '42085', '42091', '42109', '42115', '42131', '72027', '72051', '72055', '72057', '72065', '72073', '72087', '72129', '45033', '45035', '45059', '45071', '20095', '20099', '20101', '20107', '20109', '20117', '20133', '20139', '20177', '20195', '20209', '21029', '21031', '21037', '21059', '21061', '21083', '21113', '21127', '21157', '21173', '21211', '21217', '21229', '21239', '22013', '22035', '22049', '22055', '22065', '22079', '22103', '23005', '23025', '4001', '4003', '4005', '4007', '4009', '4011', '4012', '4013', '4015', '4017', '4019', '4021', '4023', '4025', '4027', '5001', '5003', '5005', '5007', '5009', '5011', '5013', '5015', '5017', '5019', '5021', '5023', '5025', '5027', '5029', '5031', '5033', '5035', '5037', '5039', '5041', '5043', '5045', '5047', '5049', '5051', '5053', '5055', '5057', '5059', '5061', '5063', '5065', '5067', '5069', '5071', '5073', '5075', '5077', '5079', '5081', '5083', '5085', '5087', '5089', '5091', '5093', '5095', '5097', '5099', '5101', '5103', '5105', '5107', '5109', '5111', '5113', '5115', '5117', '5119', '5121', '5123', '5125', '5127', '5129', '5131', '5133', '5135', '5137', '5139', '5141', '5143', '5145', '5147', '5149', '6001', '6003', '6005', '6007', '6009', '6011', '6013', '6015', '6017', '6019', '6021', '6023', '6025', '6027', '6029', '6031', '6033', '6035', '6037', '6039', '6041', '6043', '6045', '6047', '6049', '6051', '6053', '6055', '6057', '6059', '6061', '6063', '6065', '6067', '6069', '6071', '6073', '6075', '6077', '6079', '6081', '6083', '6085', '6087', '6089', '6091', '6093', '6095', '6097', '6099', '6101', '6103', '6105', '6107', '6109', '6111', '6113', '6115', '8001', '8003', '8005', '8007', '8009', '8011', '8013', '8014', '8015', '8017', '8019', '8021', '8023', '8025', '8027', '8029', '8031', '8033', '8035', '8037', '8041', '8039', '8043', '8045', '8047', '8049', '8051', '8053', '8055', '8057', '8059', '8061', '8063', '8065', '8067', '8069', '8071', '8073', '8075', '8077', '8079', '8081', '8083', '8085', '8087', '8089', '8091', '8093', '8095', '8097', '8099', '8101', '8103', '8105', '8107', '8109', '8111', '8113', '8115', '8117', '8119', '8121', '8123', '8125', '9001', '9003', '9005', '9007', '9009', '9011', '9013', '9015', '10001', '10003', '10005', '11001', '12001', '12003', '12005', '12007', '12009', '12011', '12013', '12015', '12017', '12019', '12021', '12023', '12027', '12029', '12031', '12033', '12035', '12037', '12039', '12041', '12043', '12045', '12047', '12049', '12051', '12053', '12055', '12057', '12059', '12061', '12063', '12065', '12067', '12069', '12071', '12073', '12075', '12077', '12079', '12081', '12083', '12085', '12086', '12087', '12089', '12091', '12093', '12095', '12097', '12099', '12101', '12103', '12105', '12107', '12109', '12111', '12113', '12115', '12117', '12119', '12121', '12123', '12125', '12127', '12129', '12131', '12133', '13001', '13003', '13005', '13007', '13009', '13011', '13013', '13015', '13017', '13019', '13021', '13023', '13025', '13027', '13029', '13031', '13033', '13035', '13037', '13039', '13043', '13045', '13047', '13049', '13051', '13053', '13055', '13057', '13059', '13061', '13063', '13065', '13067', '13069', '13071', '13073', '13075', '13077', '13079', '13081', '13083', '13085', '13089', '13087', '13091', '13093', '13095', '13097', '13099', '13101', '13103', '13105', '13107', '13109', '13111', '13113', '13115', '13117', '13119', '13121', '13123', '13125', '13127', '13129', '13131', '13133', '13135', '13137', '13139', '13141', '13143', '13145', '13147', '13149', '13151', '13153', '13155', '13157', '13159', '13161', '13163', '13165', '13167', '13169', '13171', '13173', '13175', '13177', '13179', '13181', '13183', '13185', '13187', '13189', '13191', '13193', '13195', '13197', '13199', '13201', '13205', '13207', '13209', '13211', '13213', '13215', '13217', '13219', '13221', '13223', '13225', '13227', '13229', '13231', '13233', '13235', '13237', '13239', '13241', '13243', '13245', '13247', '13249', '13251', '13253', '13255', '13257', '13259', '13261', '13263', '13265', '13267', '13269', '13271', '13273', '13275', '13277', '13279', '13281', '13283', '13285', '13287', '13289', '13291', '13293', '13295', '13297', '13299', '13301', '13303', '13305', '13307', '13309', '13311', '13313', '13315', '13317', '13319', '13321', '15001', '15003', '15005', '15007', '15009', '16001', '16003', '16005', '16007', '16009', '16011', '16013', '16015', '16017', '16019', '16021', '16023', '16025', '16027', '16029', '16031', '16033', '16035', '16037', '16039', '16041', '16043', '16045', '16047', '16049', '16051', '16053', '16055', '16057', '16059', '16061', '16063', '16065', '16067', '16069', '16071', '16073', '16075', '16077', '16079', '16081', '16083', '16085', '16087', '17001', '17003', '17005', '17007', '17009', '17011', '17013', '17015', '17017', '17019', '17021', '17023', '17025', '17027', '17029', '17031', '17033', '17035', '17037', '17039', '17041', '17043', '17045', '17047', '17049', '17051', '17053', '17055', '17057', '17059', '17061', '17063', '17065', '17067', '17069', '17071', '17073', '17075', '17077', '17079', '17081', '17083', '17085', '17087', '17089', '17091', '17093', '17095', '17097', '17099', '17101', '17103', '17105', '17107', '17109', '17111', '17113', '17115', '17117', '17119', '17121', '17123', '17125', '17127', '17129', '17131', '17133', '17135', '17137', '17139', '17141', '17143', '17145', '17147', '17149', '17151', '17153', '17155', '17157', '17159', '17161', '17163', '17165', '17167', '17169', '17171', '17173', '17175', '17177', '17179', '17181', '17183', '17185', '17187', '17189', '17191', '17193', '17195', '17197', '17199', '17201', '17203', '18001', '18003', '18005', '18007', '18009', '18011', '18013', '18015', '18017', '18019', '18021', '18023', '18025', '18027', '18029', '18031', '18033', '18035', '18037', '18039', '18041', '18043', '18045', '18047', '18049', '18051', '18053', '18055', '18057', '18059', '18061', '18063', '18065', '18067', '18069', '18071', '18073', '18075', '18077', '18079', '18081', '18083', '18085', '18087', '18089', '18091', '18093', '18095', '18097', '18099', '18101', '18103', '18105', '18107', '18109', '18111', '18113', '18115', '18117', '18119', '18121', '18123', '18125', '18127', '18129', '18131', '18133', '18135', '18137', '18139', '18141', '18143', '18145', '18147', '18149', '18151', '18153', '18155', '18157', '18159', '18161', '18163', '18165', '18167', '18169', '18171', '18173', '18175', '18177', '18179', '18181', '18183', '19001', '19003', '19005', '19007', '19009', '19011', '19013', '19015', '19017', '19019', '19021', '19023', '19025', '19027', '19029', '19031', '19033', '19035', '19037', '19039', '19041', '19043', '19045', '19047', '19049', '19051', '19053', '19055', '19057', '19059', '19061', '19063', '19065', '19067', '19069', '19071', '19073', '19075', '19077', '19079', '19081', '19083', '19085', '19087', '19089', '19091', '19093', '19095', '19097', '19099', '19101', '19103', '19105', '19107', '19109', '19111', '19113', '19115', '19117', '19119', '19121', '19123', '19125', '19127', '19129', '19131', '19133', '19135', '19137', '19139', '19141', '19143', '19145', '19147', '19149', '19151', '19153', '19155', '19157', '19159', '19161', '19163', '19165', '19167', '19169', '19171', '19173', '19175', '19177', '19179', '19181', '19183', '19185', '19187', '19189', '19191', '19193', '19195', '19197', '20001', '20003', '20005', '20007', '20009', '20011', '20013', '20015', '20017', '20019', '20021', '20023', '20025', '20027', '20029', '20031', '20033', '20035', '20037', '20039', '20041', '20043', '20045', '20047', '20049', '20051', '20053', '20055', '20057', '20059', '20061', '20063', '20065', '20067', '20069', '20071', '20073', '20075', '20077', '20079', '20081', '20083', '20085', '20087', '20089', '20091', '20093', '20095', '20097', '20099'];

    function initMap() {
      var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 5,
        disableDefaultUI: true,
        center: {
          lat: 38.755724,
          lng: -96.492369
        }
      });
      mark();
      //Draw layer Function
      function mark() {
        layer = new google.maps.FusionTablesLayer({
          query: {
            select: 'geometry',
            from: '1xdysxZ94uUFIit9eXmnw1fYc6VcQiXhceFd_CVKa'
          },
          styles: [{
            polygonOptions: {
              fillColor: '#000000',
              fillOpacity: 0.001
            }
          }, {
            where: "'GEO_ID2' IN (" + draw_str.toString() + ")",

            polygonOptions: {
              fillOpacity: 0.3
            }
          }]
        });

        layer.setMap(map);
      }
    }
  </script>
  <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBMtoh9P3UkoxbXndKu_HOP7KsVwTRvxGU&callback=initMap"></script>
</body>
</html>

我认为这是 GET 请求长度问题。有没有办法克服这个问题?使用 POST 代替 GET 或其他替代方法的某种方式。

请注意上面的 where 子句只是一个例子,它应该适用于更多 GEO_ID2。

问题是请求的长度URL。 javascript 控制台中的错误:

Failed to load resource: the server responded with a status of 400 ()
https://maps.googleapis.com/maps/vt?pb=!1m4!1m3!1i5!2i6!3i11!1m4!1m3!1i5!2i…Q!5i1!3m3!2sen-US!3sUS!5e18!4e3!12m1!5b1&callback=_xdc_._1mbvg&token=38465 

您需要减少查询字符串的长度。一种选择(对于这种特定情况,可能无法解决所有可能的问题)是删除查询中的前导 0:

var draw_str = ['6037', '6043', '6057', '6065', '6079', '6097', '8011', '8037', '8051', '8069', '8099', '8119', '12041', '12075', '12113', '12123', '13015', '13029', '13095', '13151', '13161', '13169', '13197', '13209', '13213', '13235', '13263', '13267', '13273', '13275', '13293', '13305', '13319', '13990', '16017', '16023', '16047', '16049', '17015', '17043', '17053', '17077', '17079', '17081', '17129', '17141', '17197', '18019', '18043', '18067', '18105', '18115', '18119', '18127', '18147', '19013', '19031', '19067', '19079', '19087', '19111', '19113', '19127', '19153', '19161', '19169', '19175', '19187', '20009', '20019', '20037', '20039', '20051', '20059', '20067', '20087', '1017', '1035', '1053', '1073', '1081', '1127', '2282', '5007', '5031', '5039', '5053', '5067', '5087', '5089', '5119', '5123', '37025', '37037', '37057', '37077', '37123', '37153', '37157', '37159', '37193', '38017', '38045', '38051', '38065', '38101', '39007', '39019', '39021', '39049', '39057', '39059', '39063', '39069', '39081', '39089', '39091', '39097', '39101', '39139', '39153', '39167', '40003', '40019', '40087', '40129', '40153', '41011', '41027', '41049', '42013', '42021', '42035', '42037', '42041', '42055', '42063', '42073', '42077', '42085', '42091', '42109', '42115', '42131', '72027', '72051', '72055', '72057', '72065', '72073', '72087', '72129', '45033', '45035', '45059', '45071', '20095', '20099', '20101', '20107', '20109', '20117', '20133', '20139', '20177', '20195', '20209', '21029', '21031', '21037', '21059', '21061', '21083', '21113', '21127', '21157', '21173', '21211', '21217', '21229', '21239', '22013', '22035', '22049', '22055', '22065', '22079', '22103', '23005',  '23025'];

proof of concept fiddle

代码片段:

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map {
  height: 100%;
  zoom: 0.7;
  -moz-transform: scale(0.8);
  -moz-transform-origin: 0 0;
}
<div id="map"></div>
<script>
  var arr = ['37159'];
  var draw_str = ['6037', '6043', '6057', '6065', '6079', '6097', '8011', '8037', '8051', '8069', '8099', '8119', '12041', '12075', '12113', '12123', '13015', '13029', '13095', '13151', '13161', '13169', '13197', '13209', '13213', '13235', '13263', '13267', '13273', '13275', '13293', '13305', '13319', '13990', '16017', '16023', '16047', '16049', '17015', '17043', '17053', '17077', '17079', '17081', '17129', '17141', '17197', '18019', '18043', '18067', '18105', '18115', '18119', '18127', '18147', '19013', '19031', '19067', '19079', '19087', '19111', '19113', '19127', '19153', '19161', '19169', '19175', '19187', '20009', '20019', '20037', '20039', '20051', '20059', '20067', '20087', '1017', '1035', '1053', '1073', '1081', '1127', '2282', '5007', '5031', '5039', '5053', '5067', '5087', '5089', '5119', '5123', '37025', '37037', '37057', '37077', '37123', '37153', '37157', '37159', '37193', '38017', '38045', '38051', '38065', '38101', '39007', '39019', '39021', '39049', '39057', '39059', '39063', '39069', '39081', '39089', '39091', '39097', '39101', '39139', '39153', '39167', '40003', '40019', '40087', '40129', '40153', '41011', '41027', '41049', '42013', '42021', '42035', '42037', '42041', '42055', '42063', '42073', '42077', '42085', '42091', '42109', '42115', '42131', '72027', '72051', '72055', '72057', '72065', '72073', '72087', '72129', '45033', '45035', '45059', '45071', '20095', '20099', '20101', '20107', '20109', '20117', '20133', '20139', '20177', '20195', '20209', '21029', '21031', '21037', '21059', '21061', '21083', '21113', '21127', '21157', '21173', '21211', '21217', '21229', '21239', '22013', '22035', '22049', '22055', '22065', '22079', '22103', '23005', '23025'];

  function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 5,
      disableDefaultUI: true,
      center: {
        lat: 38.755724,
        lng: -96.492369
      }
    });
    mark();
    //Draw layer Function
    function mark() {
      layer = new google.maps.FusionTablesLayer({
        query: {
          select: 'geometry',
          from: '1xdysxZ94uUFIit9eXmnw1fYc6VcQiXhceFd_CVKa'
        },
        styles: [{
          polygonOptions: {
            fillColor: '#000000',
            fillOpacity: 0.001
          }
        }, {
          //
          where: "'GEO_ID2' IN (" + draw_str.toString() + ")",

          polygonOptions: {
            fillOpacity: 0.3
          }
        }]
      });
      layer.setMap(map);
    }
  }
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>

如果使用Fusion Tables layer, your map tile requests will end up with long query strings 。没有层设置可以使用 POST 而不是 GET 请求,所以我们必须通过在客户端过滤地图结果来避免这个问题。

的启发,我们可以:

  1. 使用Fusion Tables API,一次请求所有地图数据。结果会很大,但是GET请求很小:

    https://www.googleapis.com/fusiontables/v2/query?sql=select GEO_ID2, geometry from 1xdysxZ94uUFIit9eXmnw1fYc6VcQiXhceFd_CVKa&key=<YOUR_API_KEY>
    
  2. 整理数据。 "geometry" 列是 in GeoJSON. There are a few issues with the returned format: the outermost wrapping object is inconsistent, and the coordinate lists of the polygons don't have the same start and end points.

  3. 使用 Data layer 在地图上绘制 GeoJSON 要素。为这些功能添加样式和交互性是有据可查的。

对于此演示,仅使用了一小部分 ID,并且使用数组 indexOf() 查找 ID。如果 ID 较多,请考虑使用 a faster lookup table.

html,
body,
#map {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3"></script>
<script>
  var ids = ['17015', '17043', '17053', '17077', '17079', '17081', '17129', '17141', '17197', '18019', '18043', '18067'];

  var map;

  function initialize() {
    var mapOptions = {
      zoom: 7,
      disableDefaultUI: true,
      center: {
        lat: 41.8781,
        lng: -87.6298
      }
    };

    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    map.data.setStyle({
      strokeWeight: 0,
      fillOpacity: 0.3,
    });

    // Basic interactivity
    map.data.addListener('mouseover', function(event) {
      map.data.revertStyle();
      map.data.overrideStyle(event.feature, {
        fillColor: '#FF0000',
        fillOpacity: 0.5,
      });
    });

    map.data.addListener('mouseout', function(event) {
      map.data.revertStyle();
    });

    // Send Fusion Tables JSONP request
    var url = ['https://www.googleapis.com/fusiontables/v2/query'];
    url.push('?sql=' + encodeURIComponent('SELECT GEO_ID2, geometry FROM 1xdysxZ94uUFIit9eXmnw1fYc6VcQiXhceFd_CVKa'));
    url.push('&callback=drawMap');
    url.push('&key=AIzaSyBMtoh9P3UkoxbXndKu_HOP7KsVwTRvxGU');
    var script = document.createElement('script');
    script.src = url.join('');
    document.getElementsByTagName('body')[0].appendChild(script);
  }

  function drawMap(data) {
    var rows = data['rows'];

    for (var i = 0, rc = rows.length; i < rc; i++) {
      if (ids.indexOf(rows[i][0]) !== -1) {
        var geojson = {
          type: 'Feature',
          properties: {
            name: rows[i][0], // GEO_ID2
          }
        }

        // Second column: geometry (GeoJSON)
        var geometries = rows[i][1]['geometries'];
        if (geometries) {
          geojson['geometry'] = rows[i][1];
          for (var g = 0, len = geometries.length; g < len; g++) {
            validateLinearRings(geometries[g]['coordinates']);
          }
        } else {
          geojson['geometry'] = rows[i][1]['geometry'];
          validateLinearRings(geojson['geometry']['coordinates']);
        }

        map.data.addGeoJson(geojson);
      }
    }
  }

  function validateLinearRings(coordinates) {
    var len = coordinates.length;
    for (var i = 0; i < len; i++) {
      // Add the first point as the last, closing the loop
      // http://geojson.org/geojson-spec.html#linestring
      coordinates[i].push(coordinates[i][0]);
    }
  }

  google.maps.event.addDomListener(window, 'load', initialize);
</script>