1

Does anybody know of an existing script or a workaround that will convert WFS returned data into something that the ArcGIS JS API can digest and display? Essentially, it would be some sort of script that either returns data that looks like it came from the REST service, or tricks the API into thinking it's an ArcGIS feature layer? I'd prefer not to reinvent the wheel if I don't have to.

Thanks

1

I created my own workaround for it. Basicly, I created a dojo module that included the Polyline (But this could be Polygon, Point, or other layer type) and SpacialReference modules from ArcGIS Javascript API. Then the script queries the WFS service, parses the returned XML into a javascript object (JSON), declares a new Polyline for each returned feature and uses the array of paths/points as a parameter.

define(function() {

    var Polyline, SpatialReference;
    require(["esri/geometry/Polyline", "esri/SpatialReference"], function(PL, SR) {
        //console.log("hello world");
        Polyline = PL;
        SpatialReference = SR;
    });



    var privateValue = 0;
    wfsRoad = {
        queryWFS: function(queryObject) {
            var result;

            queryObject.searchStringArray = this.makeStringArray(queryObject.rawSearchString);

            try {
                // this.compileXML(queryObject);
            } catch (e) {
                console.log(e);
            }

            $.ajax({
                url: 'the URL for your WFS service',
                async: false,
                type: "POST",
                data: this.compileXML(queryObject),
                contentType: "text/xml"
            }).done(function(res) {
                console.log(res);
                result = $.xml2json(res);
            });



            return this.convertToFeature(result, queryObject.originalWkid);
        },

        convertToFeature: function(rawJSON, wkid) {
            var superThis = this;
            console.log(rawJSON);
            var newFeatureArray = [];
            var newFeature = {};

            $.each(rawJSON.featureMember, function(index, value) {
                console.log("hello world");
                newFeature = {};
                try {
                    //add attributes
                    newFeature.attributes = superThis.fixRoadAttributes(rawJSON.featureMember[index].Roads);



                    //declare geometry
                    newFeature.geometry = new Polyline(superThis.getPaths(rawJSON.featureMember[index].Roads.Shape.MultiCurve.curveMember.LineString.posList));
                    newFeature.geometry.setSpatialReference(new SpatialReference(wkid));


                    newFeatureArray.push(newFeature);
                } catch (e) {
                    console.log(e);
                }
            });
            console.log(newFeatureArray);

            //return [newFeature, newFeature];
            return newFeatureArray;
        },

        fixRoadAttributes: function(rawJSON) {

            var attributes = {};
            attributes.ALTNAME1 = rawJSON.Alternate_Name1;
            attributes.CITY = rawJSON.City_Name;
            attributes.OBJECTID = rawJSON.OBJECTID;
            attributes.RD_LABEL = rawJSON.Road_Label;
            return attributes;
        },

        getPaths: function(pathList) {
            // console.log(pathList);

            var pathStringArray = pathList.split(" ");
            // console.log(pathStringArray);

            var pathNumberArray = [];
            var loopTracker = 1;
            var arrayCount = 0;
            for (var i = 0; i < pathStringArray.length - 1;) {
                pathNumberArray[arrayCount] = [];
                if (loopTracker == 1) {

                    pathNumberArray[arrayCount].push(parseFloat(pathStringArray[i]));
                    i++;
                }
                if (loopTracker == 1) {

                    pathNumberArray[arrayCount].push(parseFloat(pathStringArray[i]));
                    i++;
                    arrayCount++;
                    loopTracker = 1;
                }

            }
            // console.log( pathNumberArray);
            return pathNumberArray;
        },
        makeStringArray: function(rawSearchString) {

            var q = "";
            console.log(rawSearchString);

            var temp;

            rawSearchString = rawSearchString.match(/\S+\s*/g);
            console.log(rawSearchString);

            for (i = 0; i <= rawSearchString.length; i++) {
                if (i + 1 != rawSearchString.length) {
                    try {
                        rawSearchString[i] = rawSearchString[i].replace(/\s/g, '');
                    } catch (e) {}

                } else {
                    try {
                        rawSearchString[i] = rawSearchString[i].replace(/\s/g, '');
                    } catch (e) {}

                    console.log(rawSearchString);

                }
            }

            return rawSearchString;
        },


        compileXML: function(queryObject) {


            console.log(queryObject);

            var data = '<?xml version="1.0"?>\n' + '<wfs:GetFeature service="WFS" version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"  xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">\n' + '<wfs:Query typeName="' + queryObject.serviceName + ':' + queryObject.serviceLayerName + '">\n' + '<wfs:PropertyName>' + queryObject.serviceName + ':' + queryObject.serviceLayerName + '</wfs:PropertyName>\n';

            try {
                $.each(queryObject.returnFields, function(index, value) {
                    data += '<wfs:PropertyName>' + queryObject.serviceName + ':' + value + '</wfs:PropertyName>\n';
                });
            } catch (e) {
                console.log(e);
            }

            data += '<ogc:Filter>\n' + '<ogc:And>\n';
            try {
                $.each(queryObject.searchStringArray, function(index, value) {
                    data += '<ogc:PropertyIsLike escape="\\" singleChar="_" wildCard="%">\n' + '<ogc:PropertyName>' + queryObject.fieldToQuery + '</ogc:PropertyName>\n' + '<ogc:Literal>%' + value + '%</ogc:Literal>\n' + '</ogc:PropertyIsLike>\n';
                });
            } catch (e) {
                console.log(e);
            }
            data += '</ogc:And>\n' + '</ogc:Filter>\n' + '</wfs:Query>\n' + '</wfs:GetFeature>';

            console.log(data);
            return data;



        }

    };
    return wfsRoad;
});

To call the script, I use an object as the parameter:

 var queryObject = {
     serviceURL: "WFS service URL",
     proxyService: "url to proxy script if you have one",
     serviceName: "pueblo_county_roads_wms_only",
     serviceLayerName: "Roads",
     fieldToQuery: "Road_Label",
     returnFields: {
         0: "Alternate_Name1",
         1: "City_Name",
         2: "Shape",
         3: "Road_Label"
     },
     originalWkid: 2233,
     rawSearchString: dom.byId("address").value
 };

 selection = wfsRoad.queryWFS(queryObject);

"wfsRoad" is just the variable I chose to name it in the require declaration.

0

Koop might be an option here. It has the ability to create custom providers. Not sure if WFS is an out of the box provider but the dev team is very active and might help build one if asked. https://github.com/Esri/koop

  • I just spoke with the maintainer of the repo. Unfortunately, it does not. – JavaScript_Guru Aug 21 '14 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.