OpenLayers WFS отображение нескольких featureType

Mapserver, GeoServer, MapGuide, Google и другое ПО для веб-картографии
Ответить
im4LF
Новоприбывший
Сообщения: 6
Зарегистрирован: 19 окт 2011, 01:11
Репутация: 0

OpenLayers WFS отображение нескольких featureType

Сообщение im4LF »

Доброго времени суток.

Исходные данные - сервер ArcGis, отдает WFS с несколькими слоями, OpenLayers (2.11) отображает.
Необоходимо отобразить через OpenLayers.Layer.Vector несколько слоев.
Пример подключения:

Код: Выделить всё

var layer3 = new OpenLayers.Layer.Vector('test', {
	styleMap: style,
	strategies: [new OpenLayers.Strategy.BBOX()],
	projection: new OpenLayers.Projection('EPSG:4326'),
	protocol: new OpenLayers.Protocol.WFS({
		version: '1.1.0',
		srsName: 'EPSG:4326',
		url: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer?request=GetFeature&typeName=mypref:type_a,mypref:type_b',
		featureType: ['type_a', 'type_b'],
		singleFeatureType: false,
		featurePrefix: 'mypref',
		geometryName: 'Shape',
		readFormat: new OpenLayers.Format.GML.v3({ xy: false })
	})
});	
В документации и исходниках featureType может быть как строкой так и массивом.
Но в результате отображаются только type_a. При отладке выяснилось что при инициализации OpenLayers.Format.GML получает featureType как массив, но при чтении и разборе ответа от сервера featureType уже является строкой "type_a".

Фикс в виде жесткого прописывания внутри парсера

Код: Выделить всё

// lib/OpenLayers/Format/GML/Base.js:380
        "*": function(node, obj) {
                
                var name;
                var local = node.localName || node.nodeName.split(":").pop();
               
                this.featureType = ['type_a', 'type_b'];  // <<<
                
                if (obj.features) {
                    if (!this.singleFeatureType &&
                        (OpenLayers.Util.indexOf(this.featureType, local) !== -1)) {
                        name = "_typeName";
                    } else if(local === this.featureType) {
                        name = "_typeName";
                    }
                } else {
                    // Assume attribute elements have one child node and that the child
                    // is a text node.  Otherwise assume it is a geometry node.
                    if(node.childNodes.length == 0 ||
                       (node.childNodes.length == 1 && node.firstChild.nodeType == 3)) {
                        if(this.extractAttributes) {
                            name = "_attribute";
                        }
                    } else {
                        name = "_geometry";
                    }
                }
                if(name) {
                    this.readers.feature[name].apply(this, [node, obj]);
                }
            }, 
решает проблему...

Но возможно кто-то сталкивался с подобной задачей и странным поведением OpenLayers?
Или это некорректной настройка с моей стороны?
Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: OpenLayers WFS отображение нескольких featureType

Сообщение Denis Rykov »

Замените в свойствах протокола url c:

Код: Выделить всё

url: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer?request=GetFeature&typeName=mypref:type_a,mypref:type_b'
на

Код: Выделить всё

url: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer'
Если не поможет, будем дальше смотреть. Но в любом случае дублировать имена слоёв ни к чему.
Spatial is now, more than ever, just another column- The Geometry Column.
im4LF
Новоприбывший
Сообщения: 6
Зарегистрирован: 19 окт 2011, 01:11
Репутация: 0

Re: OpenLayers WFS отображение нескольких featureType

Сообщение im4LF »

Если в url'e не указывать request или typeName, то сервис выдает ошибку

Код: Выделить всё

<ows:ExceptionReport version='1.1.0' language='en' xmlns:ows='http://www.opengis.net/ows'><ows:Exception exceptionCode='NoApplicableCode'><ows:ExceptionText>Unknown operation name.</ows:ExceptionText></ows:Exception></ows:ExceptionReport>
или

Код: Выделить всё

<ows:ExceptionReport version='1.1.0' language='en' xmlns:ows='http://www.opengis.net/ows'><ows:Exception exceptionCode='NoApplicableCode'><ows:ExceptionText>TypeName is mandatory if featureID isn't present in GET requests.</ows:ExceptionText></ows:Exception></ows:ExceptionReport>
Но проблему решил путем ковыряния исходников и отслеживания логики парсера. Без указания featureNS парсер пытался сам определить featureNS:

Код: Выделить всё

// lib/OpenLayers/Format/GML/Base.js:213
readNode: function(node, obj, first) {
        if (first === true && this.autoConfig === true) {
            this.featureType = null;
            delete this.namespaceAlias[this.featureNS];
            delete this.namespaces["feature"];
            this.featureNS = null;
        }
        if (!this.featureNS && (!(node.prefix in this.namespaces) &&
                node.parentNode.namespaceURI == this.namespaces["gml"] &&
                this.regExes.featureMember.test(node.parentNode.nodeName))) {

            // node.nodeName = mypref:type_a
            this.featureType = node.nodeName.split(":").pop(); // <<< что и приводит к замене ['type_a', 'type_b'] на 'type_a'
            this.setNamespace("feature", node.namespaceURI);
            this.featureNS = node.namespaceURI;
            this.autoConfig = true;
        }
        return OpenLayers.Format.XML.prototype.readNode.apply(this, [node, obj]);
    }
В итоге рабочий код:

Код: Выделить всё

var layer3 = new OpenLayers.Layer.Vector('test', {
   styleMap: style,
   strategies: [new OpenLayers.Strategy.BBOX()],
   projection: new OpenLayers.Projection('EPSG:4326'),
   protocol: new OpenLayers.Protocol.WFS({
      version: '1.1.0',
      srsName: 'EPSG:4326',
      url: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer?request=GetFeature&typeName=mypref:type_a,mypref:type_b',
      featureType: ['type_a', 'type_b'],
      featureNS: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer',
      singleFeatureType: false,
      featurePrefix: 'mypref',
      geometryName: 'Shape',
      readFormat: new OpenLayers.Format.GML.v3({ xy: false, featureNS: 'http://XX.XX.XX.XX/ArcGIS/services/TestService/MapServer/WFSServer' })
   })
});
Ответить

Вернуться в «Веб-картография»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость