view src/djol/WFSSource.js @ 33:8af8e840dd49

added return fn
author nickolay
date Wed, 05 Jun 2019 17:44:17 +0300
parents f750c89976d3
children
line wrap: on
line source

define([
    "ol",
    "dojo/request",
    "dojo/_base/array",
    "implab/safe",
    "implab/log/trace!"
], function (ol,
    request,
    array,
    safe,
    trace
) {
    return function (wfs, featurePrefix, featureType, featureNS, queryArgs) {
        if (arguments.length == 1) {
            featurePrefix = wfs.featurePrefix;
            featureType = wfs.featureType;
            featureNS = wfs.featureNS;
            wfs = wfs.wfsURL;
            queryArgs = wfs.queryArgs;
        }

        safe.argumentNotNull(wfs, "wfsURL");
        safe.argumentNotEmptyString(featurePrefix, "featurePrefix");
        safe.argumentNotEmptyString(featureNS, "featureNS");
        safe.argumentNotEmptyString(featureType, "featureType");

        var format = new ol.format.WFS({
            featureNS: featureNS,
            featureType: featureType
        });

        var layerName = featurePrefix + ":" + featureType;

        function loader(extent, resolution, projection) {
            var query = {
                service: 'WFS',
                version: '1.1.0',
                request: 'GetFeature',
                typename: layerName,
                srsname: projection.getCode()
            };
            safe.mixin(query, queryArgs);

            if (extent && isFinite(extent[0]))
                query.bbox = extent.join(',') + "," + projection.getCode();

            return request(wfs, {
                query: query,
                handleAs: 'xml'
            }).then(function (data) {
                // в загрузчике нельзя вызывать метод source.clear() поскольку
                // это приводит к рекурсии
                var features = format.readFeatures(data);

                var map = {},
                    del = [],
                    add = [];

                array.forEach(features, function (x) {
                    // HACK исправляем идентификаторы, чтобы они совпадали с
                    // реальными

                    var id = x.get("id");
                    if (id)
                        x.setId(id);
                    else
                        id = x.getId();

                    map[id] = x;

                    // нужно проверить, была ли фича на карте
                    var prev = source.getFeatureById(id);
                    if (prev) {
                        // если да, то обновить ее.
                        var data = x.getProperties();
                        prev.setProperties(data);
                    } else {
                        // иначе добавить
                        add.push(x);
                    }
                });

                source.forEachFeatureInExtent(extent, function (x) {
                    if (!(x.getId() in map))
                        del.push(x);
                });

                source.addFeatures(add);

                array.forEach(del, function (x) {
                    source.removeFeature(x);
                });

                //revision = revision + 1;

                source.set("revision", ++revision);

            });
        }

        var cls = ol.source.ServerVector || ol.source.Vector;
        var revision = 0;
        var source = new cls({
            loader: loader,
            //revision: revision
            wrapX: false
            // ,
            // strategy : options.strategy || ol.loadingstrategy.all,
            // projection : options.projection
        });
        source.set("revision", revision);
        source.reload = function (extent, resolution, projection, q) {
            if (arguments.length >= 4)
                queryArgs = q;
            if (!extent)
                extent = [-Infinity, -Infinity, Infinity, Infinity];
            return loader(extent, resolution, projection);
        };

        trace.log("{0} -> {1}", layerName, wfs);
        return source;
    };
});