自定义ArcGIS GraphicsLayer(JavaScript)

时间:2013-10-12 17:24:31

标签: javascript esri arcgis-server

我正在开发一个应用程序,它将从各种源检索数据并从数据构造ESRI GraphicsLayer对象并将其显示在地图上。我之前创建过自定义FeatureLayers,但是这个项目需要使用GraphicsLayers,因为我需要能够切换图层的可见性。下面的代码从主机获取数据并将其放入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;
      }
    })
  })

此代码似乎正确构造了GraphicsLayers,但是当我将它们添加到地图对象时,地图上不会显示任何点。我用来将它们添加到地图对象的代码如下。

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);
  }
);

我意识到gfxLayer.add(item)Map.graphics.add(item)有点多余,但即使地图对象中的两个位置的数据,这些点仍未显示在地图上。

我一直在研究这个问题已经有一段时间了,我真的很想完。任何人都可以提供的任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:6)

您的问题(或至少一个问题)位于您尝试将地理坐标投影到Web Mercator的行中:

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

在Point构造函数中,您正确传递经度和纬度值,但随后通过gfx.spatialReference指定空间参考,该参考设置为102100. 102100是Web Mercator的WKID。但是您的输入数据是地理十进制度,因此您需要一个WKID = 4326的空间参考来表示GCS WGS84。所以你的行应该是:

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

这是你的主要问题。

另外,该行:

gfx.spatialReference = { wkid: 102100 };

无效。 Graphics对象上没有spatialReference属性 - 仅在Graphics.geometry上 - 您正确设置它。

最后一条评论 - 您说您在这里使用的是几何图层而不是要素图层,因为您需要能够切换可见性,但您可以切换包括要素图层在内的任何图层的可见性。