Select to view content in your preferred language

Accessing Geoserver WMS with popup using ArcGIS Javascript API 4.7

3389
6
05-22-2018 09:33 PM
GrahamHumphries1
New Contributor II

I have been building a map interface that loads road networks from ArcGIS Server. One of the requirements is to display current road works.

We have an existing application that records locations and extent of road works. This road works app uses Geoserver as the layer repository.

I have added the roadworks to my ArcGIS Javascript using the WMSLayer. I was having some issues getting the popup to work. This error was showing in thedeveloper window:

dojo.js:249 [esri.widgets.FeatureViewModel] error loading template SyntaxError: Unexpected number in JSON at position 1
at JSON.parse (<anonymous>)
at b (dojo.js:258)
at Object.<anonymous> (dojo.js:263)
at dojo.js:42
at String.replace (<anonymous>)
at Object.replace (dojo.js:44)
at Object.substitute (dojo.js:263)
at Object.c._compileText (FeatureViewModel.js:12)
at Object.c._compileContent (FeatureViewModel.js:8)
at FeatureViewModel.js:22

I finally tracked it down to a style element within the html of the popup created in Geoserver. This was defined in the content.ftl of the layer as follows:

<style>
.even{
   background-color: rgba(178, 125, 32, 1);
}
</style>

Changing the style to this:

.even{
   background-color: #e1ffed;
}

Resolves the issue.

Tracing through the code dojo is attempting to parse the value rgba(178, 125, 32, 1); as JSON. A regular expression within the code was stripping the rgba text and parentheses leaving 178 as the first key/value pair which is subsequently rejected as invalid.

This brings me to the reason for posting this. I spent several days trying to find information about this problem with no success. so hopefully it might be usefull for someone else trying to add non ArcGIS WMS layers.

0 Kudos
6 Replies
LakshmiKanth
New Contributor

Hi,

I developed Web MapViewer using ArcGIS JavaScript API 3.25 which displays esri Map Services with popup. I am adding layers individually and not using WebMap. It is working fine so far. When I try to add a new layer from GeoServer WMS Layer over esri MapServices, I get different errors in JavaScript "Cannot read property 'query' of null".

My end goal is to show info popup window over both WMS and esri Map Services. Do I need to upgrade my codebase to API 4.7+ to get this worked? I didn't find any working sample or example. Appreciate if you could share a sample page or example code.

Thanks in advance.

0 Kudos
GrahamHumphries1
New Contributor II

Hi Lakshmi,

This will work fine in ArcGIS Javascript 3.25. 

I first created a request to get the info from Geoserver (roadWorks is my geoserver layer) :

function roadWorksIdentify(map, eventMapPoint, tolerance) {
    var screenPoint=null, coords=[], coords2=[], width=0, height=0;
    require(["esri/geometry/screenUtils"], function (screenUtils) {
        screenPoint = screenUtils.toScreenGeometry(map.extent, map.width, map.height, eventMapPoint);
        coords = proj4("EPSG:3857", "EPSG:28355", [map.extent.xmin, map.extent.ymin]);
        coords2 = proj4("EPSG:3857", "EPSG:28355", [map.extent.xmax, map.extent.ymax]);
        width = Math.round((map.width / tolerance)).toString();
        height = Math.round((map.height / tolerance)).toString()
    });

    return {
        REQUEST: 'GetFeatureInfo',
        SERVICE: 'WMS',
        VERSION: '1.1.1',
        LAYERS: "GEO_ROAD_WORKS,GEO_RD_EVTS", 
        STYLES: '',
        FORMAT: "image/png", BGCOLOR: '0xFFFFFF',
        TRANSPARENT: 'TRUE',
        SRS: 'EPSG:4326',
        BBOX: coords.join(",") + "," + coords2.join(","),
        WIDTH: width,
        HEIGHT: height,
        QUERY_LAYERS: "GEO_ROAD_WORKS,GEO_RD_EVTS", 
        INFO_FORMAT: "text/html",
        X: Math.round((screenPoint.x / tolerance)).toString(),
        Y: Math.round((screenPoint.y / tolerance)).toString()
 };
}

I then Used an ajax call to GeoServer to make a getFeatureInfo  request that will return a Promise:

function ajax(type, data1) {
    return Promise.resolve($.ajax({
        type: type,
        url: mapParams.roadWorksWms.wms.url,
        data: data1
    }));
}

I then used the Promise object to show the returned html in a popup
LakshmiKanth
New Contributor

Thanks Humphries for your quick response and sharing the code snippet. I will try to implement this popup code.

Right now, I am struggling to resolve the errors in displaying both WMSLayer and ArcGISDynamicMapServerLayer together on map. Do you think, it works with the current version of JavaScript API 3.25 or 4.x? Your inputs or suggestion on this would be very helpful. I will start debugging the map display issues and update here with my findings.

0 Kudos
GrahamHumphries1
New Contributor II

Hi Lakshmi,

Click the link below to see the Geoserver wms working inArcGIS javascript v3.23:

Geoserver WMS in ArcGIS javascript 3.23 map

Here is the code I use to add my roadworks layers an ArcGIS javascript v3.23:

function addRoadworks() {
    require(["esri/InfoTemplate",
            "esri/layers/WMSLayer",
            "esri/layers/WMSLayerInfo",
            "esri/InfoTemplate"],
        function (InfoTemplate, WMSLayer, WMSLayerInfo) {
            var infoStr = "<b>Name:</b>${ROAD_NAME}<br/>Event Type: ${EVENT_TYPE}<br/>Type of Works: ${TYPE_OF_WORKS}<br/>Location: ${LOCATION_DESC}<br/>Start: ${START_TIME}<br/>End: ${END_TIME}<br/>Working Hours: ${WORKING_HOURS}<br/Traffic Mgmt:${TRAFFIC_MANAGEMENT}<br/>Links: ${WEB}";
            infoTemplate = new InfoTemplate("State Growth Road Works", infoStr);
            roadWorksLayer = new WMSLayer(mapParams.roadWorksWms.url, {
                format: mapParams.roadWorksWms.wms.format,
                resourceInfo: {
                    copyright: "My Copyright title",
                    description: "Roadworks",
                    extent: initialExtent,
                    featureInfoFormat: "text/html",
                    infoTemplate: infoTemplate,
                    tolerance: 10,
                    getFeatureInfoURL: myBaseUrl + "geoserver/ssg/ows/?service=WMS&version=1.3.0&info_format=application/json&xsl_template=infoTemplate.xsl",                    getMapURL: mapParams.roadWorksWms.url,
                    layerInfos: [
                        new WMSLayerInfo({
                            name: "GEO_ROAD_WORKS",
                            title: "Roadworks",
                            queryable: true,
                            showPopup: false
                        })
                    ],
                    spatialReferences: [3857, 28355],
                    version: mapParams.roadWorksWms.wms.version
                },
                visibleLayers: [
                    "GEO_ROAD_WORKS"
                ]
            });
            roadWorksPointLayer = new WMSLayer(mapParams.roadWorksWms.url, {
                format: mapParams.roadWorksWms.wms.format,
                resourceInfo: {
                    copyright: "My Copyright title",
                    description: "Roadworks",
                    extent: initialExtent,
                    featureInfoFormat: "text/html",
                    infoTemplate: infoTemplate,
                    tolerance: 10,
                    getFeatureInfoURL: myBaseUrl + "geoserver/ssg/ows/?service=WMS&version=1.3.0&info_format=application/json&xsl_template=infoTemplate.xsl",                    getMapURL: mapParams.roadWorksWms.url,
                    layerInfos: [
                        new WMSLayerInfo({
                            name: "GEO_RD_EVTS",
                            title: "Roadworks",
                            queryable: true,
                            showPopup: false
                        })
                    ],
spatialReferences: [3857, 28355],
version: mapParams.roadWorksWms.wms.version
},
visibleLayers: [
"GEO_RD_EVTS" ]
});
map.addLayers([roadWorksLayer, roadWorksPointLayer]);
roadWorksLayer.setVisibility(false);
roadWorksPointLayer.setVisibility(false);
dojo.connect(roadWorksLayer, "onClick", function () {
map.infoWindow.setTitle("State Growth Road Wrks");
map.infoWindow.resize(370, 360);
});
});

if (typeof roadWorksLayer !=="undefined") {
roadWorksIdentifyTask = new esri.tasks.IdentifyTask(roadWorksLayer.getFeatureInfoURL);
roadWorksIdentifyParams.geometry = eventMapPoint;
roadWorksIdentifyParams.mapExtent = map.extent;
roadWorksIdentifyParams.layerIds = [0];
}
}
RochelleWolfe
New Contributor II

Hello, my need is very similar, I have managed to display a geoserver wms layer in my arcgis js project, but beginning to display information from that layer is overwheming, I am pretty new to development. Could you please share a working example with codepen or fiddlerjs or similar? Some of the variables referenced in these code snippets are not defined within them, leaving me questioning what value I will need to replace them with.

0 Kudos
GrahamHumphries2
New Contributor

Hi Rochelle,

Go to this site: https://data.stategrowth.tas.gov.au/Networks/?mapName=hml

Click the Show State Growth Roadworks button, bottom right corner.

Click OK on the dialog 

The orange and black lines and the workman icons are coming from Geoserver

As you can see from the code above I created an identify task to display the information when you click on a road works element.