Openlayers多线段对象调用.getGeometry undefined 多级下拉地图缩放报错
问题根因
- 索引使用错误:下拉框
option的value是要素的objectid属性值,但代码直接将该值作为要素数组的下标取元素,仅当objectid刚好和数组下标完全一致时可正常运行,一旦数据变化、objectid不连续或非数字,就会取到undefined,调用.getGeometry()自然报错。 - 资源未清空、事件重复绑定:
- 每次行政区(mahalle)切换时,没有清空道路图层(yollar)的已有要素,也没有清空道路下拉框的旧选项,直接追加新内容,导致要素数组长度、下拉框选项持续累加,索引完全混乱
- 每次行政区切换的ajax请求成功后,都会给道路下拉框绑定一次
change事件,多次切换后同一个选择动作会触发多次事件回调,进一步加剧报错概率
- 潜在问题:行政区选中后的缩放逻辑也存在同样的索引误用问题,随时可能报错。
修复方案
直接替换原有代码为以下版本即可:
var url = 'http://localhost:8080/geoserver/kbs/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=kbs:mahalle&outputFormat=application/json&SRS=EPSG:3857'; $.getJSON( url, function (data) { loadFeatures(data); } ); function loadFeatures(data) { // 加载行政区要素 mahalle.getSource().addFeatures(new ol.format.GeoJSON().readFeatures(data)); const featuresmah = mahalle.getSource().getFeatures(); // 填充行政区下拉框 $.each(featuresmah, function (key, value) { $('#mahalleId').append('<option value=' + value.get('objectid') + '>' + value.get('yazi') + '</option>'); }); // 行政区切换事件 $('#mahalleId').on('change', function () { var selected = $('#mahalleId').val(); // 修复:按objectid匹配行政区要素,不直接用索引 const targetMahalle = mahalle.getSource().getFeatures().find(f => f.get('objectid') == selected); if (targetMahalle) { const extentmah = targetMahalle.getGeometry().getExtent(); map.getView().fit(extentmah, map.getSize()); } // 每次切换行政区先清空旧的道路数据、下拉选项、旧事件 yollar.getSource().clear(); $('#yolId').empty().append('<option value="">请选择道路</option>'); $('#yolId').off('change'); $.ajax({ method: 'GET', url: 'http://localhost:8080/geoserver/kbs/wfs', data: { service: 'WFS', request: 'GetFeature', typename: 'kbs:yollar', outputFormat: 'application/json', cql_filter: "mahalle_id='" + mahalleId.value + "'", srsname: 'EPSG:3857' }, success: function (response) { yollar.getSource().addFeatures(new ol.format.GeoJSON().readFeatures(response)); map.getView().fit(yollar.getSource().getExtent()); const featuresyol = yollar.getSource().getFeatures(); // 填充道路下拉框 $.each(featuresyol, function (key, value) { $('#yolId').append('<option value=' + value.get('objectid') + '>' + value.get('sokak_adi') + '</option>'); }); // 道路切换事件 $('#yolId').on('change', function (e) { const selectyol = $('#yolId').val(); if (!selectyol) return; // 修复:按objectid匹配道路要素,不直接用索引 const targetYol = yollar.getSource().getFeatures().find(f => f.get('objectid') == selectyol); if (targetYol) { const extentyol = targetYol.getGeometry().getExtent(); map.getView().fit(extentyol, map.getSize()); } console.log(selectyol); }); }, fail: function (jqXHR, textStatus) { console.log("Request failed: " + textStatus); } }); }) }
内容的提问来源于stack exchange,提问作者Veysel Alceylan
相关产品推荐
相关产品推荐

