无效的 Geojson 对象 Angularjs &Leafletjs
Invalid Geojson Object Angularjs &Leafletjs
在我的项目中,我尝试将过滤器与显示在 table 和地图上的 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 相同,所以假设这里的问题是过滤?我将非常感谢能告诉我哪里出错的人
此错误来自 Leaflet 代码中的 here,表明 GeoJSON 包含一个没有有效 type
属性 的 Geometry 对象。您需要调查您的代码生成此类对象的原因。
首先,您显示的不是 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
所以你需要设置你的逻辑有点不同,假设你想搜索两个属性,id
和 name
在你的范围内你将有:
$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
在我的项目中,我尝试将过滤器与显示在 table 和地图上的 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 相同,所以假设这里的问题是过滤?我将非常感谢能告诉我哪里出错的人
此错误来自 Leaflet 代码中的 here,表明 GeoJSON 包含一个没有有效 type
属性 的 Geometry 对象。您需要调查您的代码生成此类对象的原因。
首先,您显示的不是 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
所以你需要设置你的逻辑有点不同,假设你想搜索两个属性,id
和 name
在你的范围内你将有:
$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