Using streamlayer with data coming from a PubNub websocket

1070
3
Jump to solution
04-29-2017 10:19 AM
MarcusSilva
New Contributor

Hi, I'm trying to use streamlayer accessing ESRI JSON point objects sent as messages to a PubNub channel. I initialized the websocket using:

<!-- Use WebSocket Constructor for a New Socket Connection -->
WebSocket = PUBNUB.ws;
var socket = new WebSocket('wss://pubsub.pubnub.com/my-publish-key/my-subscribe-key/my-channel');

And used the piece of code bellow but the point is not displaying. I can see that the point object is getting in, the map extent is being updated based on its coordinates, but the symbol is not showing.

Can anybody tell me what I'm doing wrong? Any help will be much appreciated.

Thanks,

Marcus

PS. Sorry about the code bellow. Could not paste it keeping the formatting I have in my notepad ++.

================================================================================

var symbol = new SimpleMarkerSymbol({
  "color": [255,255,255,64],
  "size": 12,
  "angle": -30,
  "xoffset": 0,
  "yoffset": 0,
  "type": "esriSMS",
  "style": "esriSMSCircle",
  "outline": {
    "color": [0,0,0,255],
    "width": 1,
    "type": "esriSLS",
    "style": "esriSLSSolid"
  }
});

var svcUrl = "wss://pubsub.pubnub.com/my-publish-key/my-subscribe-key/my-channel"

var streamLayer = new StreamLayer(featureCollection, {
  socketUrl: svcUrl,
  purgeOptions: { displayCount: 1000, age:20 },
  trackIdField: featureCollection.layerDefinition.timeInfo.trackIdField,
  infoTemplate: new InfoTemplate("${*}" )
});

//Register listeners for layer events
streamLayer.on("connect", function() {
  console.log("Stream on connect data received.");
  console.log(message.data[0]);
 map.setExtent(map.extent.centerAt(webMercatorUtils.geographicToWebMercator(jsonUtils.fromJson(message.data[0].geometry))));
  var gra = new Graphic(message.data[0], symbol);//[0].geometry, );
  streamLayer.add(gra);
});

//add layer to the map
map.addLayer(streamLayer);

============================================================================

The data being sent to the websocket is:

[{"geometry":{"type":"point","x":-77.506431000,"y":39.466250000,"z":87.3,"spatialReference":{"wkid":102100}},"attributes":{"trackId":1,"time":"2011-09-25T18:08:35Z"}}]

0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

I'm fairly sure you can't create a symbol like that.  There's a distinction between the JSON representation of a symbol (or any class in the API) and the constructor parameters.

Try something like this to create the symbol:

var symbol = new SimpleMarkerSymbol({
  "color": [255,255,255,64],
  "size": 12,
  "angle": -30,
  "xoffset": 0,
  "yoffset": 0,
  "style": "circle",
  "outline": {
    "color": [0,0,0,255],
    "width": 1,
    "style": "solid"
  }
});

You can also use esri/symbols/jsonUtils | API Reference | ArcGIS API for JavaScript 3.20  to convert from symbol JSON to an instance of a symbol.

I suspect you're making a similar error when constructing a graphic.  I would try using jsonUtils.fromJSON to parse the geometry JSON and pass that into the graphic constructor.    It looks like Graphic does support JSON as a parameter, but I think it expects the symbol to be passed in as part of the JSON (optionally you could pass the symbol JSON as part of your web socket messages if you want, and then pass that whole JSON into the graphic constructor).  But I would try something like this:

var geometry = webMercatorUtils.geographicToWebMercator(jsonUtils.fromJson(message.data[0].geometry));

map.setExtent(map.extent.centerAt(geometry));

var graphic = new Graphic(geometry, symbol); 
streamLayer.add(graphic);

I also think you could get rid of the webMercatorUtils.geographicToWebMercator if you tag your geometry JSON with wkid: 4326.

View solution in original post

0 Kudos
3 Replies
ThomasSolow
Occasional Contributor III

I'm fairly sure you can't create a symbol like that.  There's a distinction between the JSON representation of a symbol (or any class in the API) and the constructor parameters.

Try something like this to create the symbol:

var symbol = new SimpleMarkerSymbol({
  "color": [255,255,255,64],
  "size": 12,
  "angle": -30,
  "xoffset": 0,
  "yoffset": 0,
  "style": "circle",
  "outline": {
    "color": [0,0,0,255],
    "width": 1,
    "style": "solid"
  }
});

You can also use esri/symbols/jsonUtils | API Reference | ArcGIS API for JavaScript 3.20  to convert from symbol JSON to an instance of a symbol.

I suspect you're making a similar error when constructing a graphic.  I would try using jsonUtils.fromJSON to parse the geometry JSON and pass that into the graphic constructor.    It looks like Graphic does support JSON as a parameter, but I think it expects the symbol to be passed in as part of the JSON (optionally you could pass the symbol JSON as part of your web socket messages if you want, and then pass that whole JSON into the graphic constructor).  But I would try something like this:

var geometry = webMercatorUtils.geographicToWebMercator(jsonUtils.fromJson(message.data[0].geometry));

map.setExtent(map.extent.centerAt(geometry));

var graphic = new Graphic(geometry, symbol); 
streamLayer.add(graphic);

I also think you could get rid of the webMercatorUtils.geographicToWebMercator if you tag your geometry JSON with wkid: 4326.

0 Kudos
MarcusSilva
New Contributor

Hi Thomas, I've made my second post and did not see yours. But thank you. The main problem was the, as you mentioned, the spatial reference. I'm also going to take care of the other points you made.

Thank you very much!!! 

0 Kudos
MarcusSilva
New Contributor

Hi all, just found out what was wrong. It was a basic spatial reference error. I'm new to javascript and esri api but I'm also a long time cartographer :(. So I should have seem it at the very begining. Sorry to take your time for reading this post.

Regards,

Marcus

0 Kudos