Недопустимый объект Geojson Angularjs и Leafletjs

В моем проекте я пытаюсь синхронизировать фильтры с geojson, отображаемыми в таблице и на карте. Для этого я использовал angular и ранее angular-leaflet-directive, но производительность для моих целей была низкой, поэтому я решил создать свою собственную директиву для leaflet.js.

В моем случае я могу передавать данные из контроллера в свою директиву, но это делает карту статической, когда я пытаюсь передать данные после фильтрации, чтобы сделать мою карту динамической, на карте не отображаются маркеры, и я получаю сообщение об ошибке из листовки Invalid 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 в данных. Итак, предположим, проблема здесь в фильтрации? Буду очень благодарен тому, кто подскажет, где я делаю ошибки.


person IOR88    schedule 12.02.2015    source источник


Ответы (2)


Во-первых, то, что вы показываете, не является объектом GeoJSON. Этот L.GeoJSON в Leaflet принимает только набор функций, не делает его допустимым объектом 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

person iH8    schedule 12.02.2015

Эта ошибка возникает из здесь в коде листовки. и указывает, что GeoJSON содержит объект Geometry без допустимого свойства type. Вам нужно выяснить, почему ваш код генерирует такой объект.

person John    schedule 12.02.2015