【问题标题】:Google Maps API v3: data layer IDs undefinedGoogle Maps API v3:数据层 ID 未定义
【发布时间】:2016-09-01 06:46:49
【问题描述】:

长期潜伏者,第一次在这里发帖,所以要温柔......

我正在构建一个地图,该地图使用通过 PHP 从 MYSQL 数据库解析的数据来设置由 geoJson 文件定义的多边形的颜色(它使用 Google 开发网站上的 this 示例作为模板)。我遇到的问题是页面加载时数据层不会自动初始化。

完整的 javascript/HTML 发布在下面,但我在下面的示例中用于初始化数据层的代码部分是:

  google.maps.event.addListenerOnce(map.data, 'addfeature', function() {
  google.maps.event.trigger(document.getElementById('price_select'),
        'change');
  });

这给了我错误“Uncaught TypeError: Cannot read property 'setProperty' of undefined”。如果我注释掉侦听器,数据层将正常加载,但只有在我从下拉列表中手动选择新输入 (id='price_select') 之后。

我正在加载的 geoJson 文件相对较大(~14mb),所以我认为正在发生的事情是侦听器在整个文件加载之前触发('addfeature' 只等待添加第一个功能,但是我有 >2000),因此 PHP 解析的地区还没有相应的功能 ID,它由 loadGeoJson 调用中的idPropertyName: 'Name' 参数设置。我不知道如何将侦听器设置为仅在整个 GeoJson 文件加载后才触发。或者,我可能完全错误地认为这是错误的原因。

无论如何,下面的完整代码 - 我知道它有一些怪癖(例如,我向 loadData 函数传递了一个参数,但不使用它),但这些主要是因为我计划稍后添加更多功能。感谢您对我的包容!

    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
        <script>

        var map;

        var priceMin = 1000000;
        var priceMax = 0;

        google.maps.event.addDomListener(window, 'load', function(){

            map = new google.maps.Map(document.getElementById('map-canvas'), {
            center: new google.maps.LatLng(53.587425,-1.663539),
             zoom: 7,
            }); 

        // add styles
        map.data.setStyle(styleFeature);
        map.data.addListener('mouseover', mouseInToRegion);
        map.data.addListener('mouseout', mouseOutOfRegion);


      // initiate drop down functionality
      var selectBox = document.getElementById('price_select');
      google.maps.event.addDomListener(selectBox, 'change', function() {
        clearData();
        loadData(selectBox.options[selectBox.selectedIndex].value);
      });


      // load polygons
      loadMapShapes();

    });     

    function loadMapShapes(){

     map.data.loadGeoJson('http://localhost/OS_raw.json',
        { idPropertyName: 'Name' }); 

  //This is the listener that is supposed to initiate the data layer

      google.maps.event.addListenerOnce(map.data, 'addfeature', function() {
      google.maps.event.trigger(document.getElementById('price_select'),
            'change');
      });

 // End listener   


    }

    function loadData(variable){

        var phpdistricts = (<?php echo $phpdistricts; ?>);
        var phpprices = (<?php echo $phpprices; ?>);



        for(var i=0; i<phpdistricts.length; i++){

            var district = phpdistricts[i];
            var price = parseInt(phpprices[i]);

            // keep track of min and max values
            if (price < priceMin) {
            priceMin = price;
            }
            if (price > priceMax) {
            priceMax = price;
            }


            console.log(map.data.getFeatureById(district));

   //This is where the error triggers - feature is undefined according to console log above
            map.data
            .getFeatureById(district)
            .setProperty('price', price);}

   //end of problematic section        

            // update and display the legend
            document.getElementById('census-min').textContent =
                priceMin.toLocaleString();
            document.getElementById('census-max').textContent =
                priceMax.toLocaleString();    

    }

    function clearData() {
      priceMin = 1000000;
      priceMax = 0;
      map.data.forEach(function(row) {
        row.setProperty('price', undefined);
      });
      document.getElementById('data-box').style.display = 'none';
      document.getElementById('data-caret').style.display = 'none';
    }

    function styleFeature(feature) {
      var low =  [151, 83, 34]; // color of smallest datum
      var high = [5, 69, 54];   // color of largest datum

      // delta represents where the value sits between the min and max
      var delta = (feature.getProperty('price') - priceMin) /
          (priceMax - priceMin);

      var color = [];
      for (var i = 0; i < 3; i++) {
        // calculate an integer color based on the delta
        color[i] = (high[i] - low[i]) * delta + low[i];
      }

      // filters out areas without data
      var showRow = true;
      if (feature.getProperty('price') == null ||
          isNaN(feature.getProperty('price'))) {
        showRow = false;
      }

      var outlineWeight = 0.5, zIndex = 1;
      if (feature.getProperty('state') === 'hover') {
        outlineWeight = zIndex = 2;
      }

      return {
        strokeWeight: outlineWeight,
        strokeColor: '#fff',
        zIndex: zIndex,
        fillColor: 'hsl(' + color[0] + ',' + color[1] + '%,' + color[2] + '%)',
        fillOpacity: 0.75,
        visible: showRow
      };
    }

    function mouseInToRegion(e) {
      // set the hover state so the setStyle function can change the border
      e.feature.setProperty('state', 'hover');

      var percent = (e.feature.getProperty('price') - priceMin) /
          (priceMax - priceMin) * 100;

      // update the label
      document.getElementById('data-label').textContent =
          e.feature.getProperty('Name');
      document.getElementById('data-value').textContent =
          e.feature.getProperty('price');
      document.getElementById('data-box').style.display = 'block';
      document.getElementById('data-caret').style.display = 'block';
      document.getElementById('data-caret').style.paddingLeft = percent + '%';
    }

    function mouseOutOfRegion(e) {
      // reset the hover state, returning the border to normal
      e.feature.setProperty('state', 'normal');
    }


        </script>
      </head>
      <body>
        <div id="controls" class="nicebox">
            <div>
            <select id="price_select">
                <option value="price">Jun '14</option>
                <option value="price">Jun '14</option>
            </select>
            </div>

            <div id="legend">
            <div id="census-min">min</div>
            <div class="color-key">
                <span id="data-caret">◆</span>              
            </div>
            <div id="census-max">max</div>          
            </div>
            </div>
        <div id="data-box" class="nicebox">
            <label id="data-label" for="data-value">Area: </label>
            <span id="data-value"></span>
        </div>
        <div id="map-canvas"></div>
      </body>
    </html>   

【问题讨论】:

标签: javascript json google-maps google-maps-api-3 geojson


【解决方案1】:

我不完全明白你在这里问什么,但你是否尝试过使用数据层事件而不是地图来设置样式?

map.data.setStyle(
 function(feature){
   // Build your styles here based on feature properties.

    return style_i_want_for_this_feature;
 }
);

这将为您的 GeoJSON 数据中的每个特征调用,您可以适当地处理它。我以这种方式加载和设置具有数千个特征的特征集合。

【讨论】:

    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2014-10-05
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多