简体   繁体   中英

Custom ArcGIS GraphicsLayer (JavaScript)

I am working on an application that will retrieve data from various sources and construct ESRI GraphicsLayer objects from the data and display it on a map. I have created custom FeatureLayers before but this project requires the use of GraphicsLayers because I need to be able to toggle the visibility of layers. The code below fetches the data from the host and puts it into a GraphicsLayer.

define(["dojo/_base/declare", "dojo/_base/array", "dojo/request", "esri/graphic", "esri/geometry/Geometry", "esri/InfoTemplate"],
  function(declare, array, request, Graphic, Geometry, InfoTemplate) {
    return declare(null, {
      getAllCurrentReadings: function() {
        var rtn = [];
        var stations = ["S", "SN", "AN", "UP", "GR", "PL", "SR", "J", "N", "FL"];
        array.forEach(stations, function(item, i) {
          request.post("includes/buoybay_proxy.php", {
            data: {
              "method": "RetrieveCurrentReadings",
              "params": "CBIBS," + item + ",113f8b...f27e0a0bb" // NOTE: id: 1 is necessary as well but is added manually by jsonRPCClient
            },
            sync: true,
            handleAs: "json"
          }).then(
            function(response) {
              var gfx, attr, t;
              //console.log(response);
              // Now build the Graphic Object and push it into rtn
              gfx = new Graphic();
              gfx.spatialReference = {
                wkid: 102100
              };

              // Define attribute object
              attr = {};
              attr["station"] = response.station;
              attr["title"] = translateStationID(response.station);
              for (var j = 0; j < response.measurement.length; j++) {
                attr[String(response.measurement[j])] = response.value[j];
              }
              gfx.attributes = attr;

              // Define geometry object
              gfx.geometry = new Geometry(gfx.spatialReference, "point");
              gfx.geometry.spatialReference = {
                wkid: 102100
              };
              gfx.geometry.type = "point";
              t = esri.geometry.geographicToWebMercator(new esri.geometry.Point(attr["longitude"], attr["latitude"], gfx.spatialReference));
              gfx.geometry.x = t.x;
              gfx.geometry.y = t.y;

              // Define infoTemplate object
              gfx.infoTemplate = new esri.InfoTemplate();
              gfx.infoTemplate.setTitle(attr["title"]);
              gfx.infoTemplate.setContent("${*}");

              // Define symbol
              gfx.symbol = new esri.symbol.PictureMarkerSymbol("../images/marker.png", 15, 15);

              //console.log(gfx);
              rtn.push(gfx);
            },
            function(error) {
              console.log("Error: " + error + "\n");
            }
          )
        });
        //console.log(rtn);
        return rtn;
      }
    })
  })

This code seems to construct the GraphicsLayers properly but when I add them to the map object no points are displayed on the map. The code I use to add them to the map object is below.

require(["dojo/parser", "dojo/_base/array", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/ready", "esri/map", "esri/layers/ArcGISTiledMapServiceLayer", "js/cbibsGfxModule", "dojo/domReady!"],
  function(parser, array, BorderContainer, ContentPane, ready, map, ArcGISTiledMapServiceLayer, cbibsGfxModule) {
    var Map, cbibs, gfxLayer, t = [];

    function init() {
      Map = new map("mapDiv", {
        basemap: "oceans",
        center: [-77.0357, 38.7877],
        zoom: 7
      });
      dojo.connect(Map, "onLoad", displayData); // Map didn't load until 3rd arg was a function name; why?

      function displayData() {
        cbibs = new cbibsGfxModule();
        t = cbibs.getAllCurrentReadings();
        gfxLayer = new esri.layers.GraphicsLayer();
        array.forEach(t, function(item) {
          gfxLayer.add(item);
          Map.graphics.add(item);
        });
        gfxLayer.spatialReference = {
          wkid: 102100
        };
        //Map.addLayer(gfxLayer); // Add GraphicsLayer to Map object
        console.log(Map); // Custom GraphicLayers are under _layers
      };
    };
    dojo.ready(init);
  }
);

I realize that gfxLayer.add(item) and Map.graphics.add(item) are somewhat redundant but even with the data in two locations in the Map object the points are still not displayed on the map.

I've been working on this for some time now and I really am fresh out of ideas. Any help anyone could offer would be greatly appreciated. Thank you.

Your issue (or at least one issue) is in the line where you are attempting to project your Geographic coordinates to Web Mercator:

    t = esri.geometry.geographicToWebMercator(
new esri.geometry.Point(attr["longitude"], attr["latitude"], gfx.spatialReference));

In the Point constructor you are correctly passing in your longitude and latitude value, but then are specifying the spatial reference via gfx.spatialReference, which is set to 102100. 102100 is the WKID for Web Mercator. But your input data is geographic decimal degrees, so you need a spatial reference with WKID = 4326 to represent GCS WGS84. So your line should read:

t = esri.geometry.geographicToWebMercator(
  new esri.geometry.Point(attr["longitude"], attr["latitude"], 
    new esri.SpatialReference(4326));

That's your main issue.

Also, the line:

gfx.spatialReference = { wkid: 102100 };

has no effect. There is no spatialReference property on the Graphics object - only on the Graphics.geometry - where you are setting it correctly.

Just one last comment - you say you are using a Geometry layer here instead of a Feature Layer because you need to be able to toggle the visibility, but you can toggle the visibility of any layer including Feature layers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM