【问题标题】:Invalid Geojson Object Angularjs &Leafletjs无效的 Geojson 对象 Angularjs &Leafletjs
【发布时间】:2015-02-12 14:36:17
【问题描述】:

在我的项目中,我尝试将过滤器与显示在表格和地图上的 geojson 同步。为了实现这一点,我使用了 angular 和以前的 angular-leaflet-directive,但是出于我的目的,性能会变慢,所以我决定为 leaflet.js 制作自己的指令。

在我的情况下,我可以将数据从控制器传递到我的指令,但它使地图成为静态,当我尝试在过滤后传递数据以使我的地图动态时,地图没有显示任何标记并且我从传单中得到错误, 无效的 Geojson 对象。

Fiddler 以我为例:http://jsfiddle.net/ior88/5ea8yxwo/4/

 $scope.FilteredGeojson = function () {

    var result;

    result = $filter('filter')($scope.data, $scope.search);

    $scope.geojson = result;
    return result;
};

如果你在那里查看控制台,你会看到错误。

我不明白,因为当我在 {{}} 中显示 geojson 或 geojson_watch 时,它看起来与数据中的 geojson 相同,所以假设这里的问题是过滤?我会非常感谢有人会告诉我哪里出错了

【问题讨论】:

    标签: angularjs leaflet geojson angularjs-filter


    【解决方案1】:

    首先,您展示的不是 GeoJSON 对象。 Leaflet 的L.GeoJSON 只接受一组特征,不会使其成为有效的 GeoJSON 对象,因此您不应将其称为 GeoJSON 对象。它是一组 GeoJSON 特征对象。在一个有效的 GeoJSON 特征集合对象中,特征数组的包含如下:

    {
        "type": "FeatureCollection",
        "features": [
            // The features
        ]
    }
    

    接下来,您尝试以一种不起作用的方式过滤一些复杂的对象。以下是$filter('filter') 的工作原理:

    var simpleArray = [{
      'name': 'Foo'
    }, {
      'name': 'Bar'
    }];
    
    $filter('filter')(simpleArray, {'name': 'Foo'}); // Returns array with Foo object
    $filter('filter')(simpleArray, {'name': 'Bar'}); // Returns array with Bar object
    $filter('filter')(simpleArray, {'name': 'Foobar'}); // Returns empty array
    

    Plunker 示例:http://plnkr.co/edit/I7OGfoJLwaCz0XibcTDB?p=preview

    你想用$filter('filter')做什么:

    var complexArray = [{
      'properties': {
        'name': 'Foo'
      }
    }, {
      'properties': { 
         'name': 'Bar'
      }
    }];
    
    $filter('filter')(complexArray, {'name': 'Foo'}); // Returns empty array
    $filter('filter')(complexArray, {'name': 'Bar'}); // Returns empty array
    $filter('filter')(complexArray, {'name': 'Foobar'}); //Returns empty array
    

    Plunker 示例:http://plnkr.co/edit/rUtseKWCeyLiewDxnDDn?p=preview

    为什么?因为数组中的对象没有名为name 的属性。它们只有一个名为properties 的属性,它包含一个对象并且确实有一个name 属性。您不能指望过滤器递归地搜索您的对象,直到它找到一个名称属性。它没有。只有当你明确告诉它这样做时它才会这样做:

    $filter('filter')(complexArray, {'properties': {'name': 'Foo'}}); // Returns with Foo
    $filter('filter')(complexArray, {'properties': {'name': 'Bar'}}); // Returns with Bar
    $filter('filter')(complexArray, {'properties': {'name': 'Foobar'}}); // Returns empty
    

    Plunker 示例:http://plnkr.co/edit/LpOvr7Zxw5C5A3Tt5umQ?p=preview

    所以你需要设置你的逻辑有点不同,假设你想搜索两个属性,idname 在你的范围内你会拥有:

    $scope.search = {
      'properties': {}
    };
    
    $scope.$watch('search', function (newVal, oldVal) {
      if (newVal !== oldVal) {
        $scope.data = $filter('filter')($scope.source, $scope.search);
      }
    }, true);
    

    在你的模板中:

    <input ng-model="search.properties.id" placeholder="ID" />
    <input ng-model="search.properties.name" placeholder="Name" />
    

    现在,每次您使用其中一个输入时,搜索属性上的监视都会触发,它会过滤源并更新数据。为了在指令中也反映这种变化,您还必须在指令的 link 方法中监视数据对象。在那里,您可以使用新数据更新图层:

    scope.$watch('data', function (newVal, oldVal) {
        if (newVal !== oldVal) {
            geojsonLayer.clearLayers();
            geojsonLayer.addData(scope.data);
        }
    }, true);
    

    Plunker 上一个工作示例中的完整代码:http://plnkr.co/edit/CmfBdmt7BYKPmE22HLvl?p=preview

    【讨论】:

      【解决方案2】:

      此错误来自 Leaflet 代码中的 here,表示 GeoJSON 包含一个没有有效 type 属性的 Geometry 对象。您需要调查您的代码生成此类对象的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-09
        • 1970-01-01
        相关资源
        最近更新 更多