Пользовательский ArcGIS GraphicsLayer (JavaScript)

Я работаю над приложением, которое будет извлекать данные из различных источников и создавать объекты 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) несколько избыточны, но даже если данные в двух местах объекта Map, точки все равно не отображаются на карте.

Я работаю над этим в течение некоторого времени, и я действительно свежа из идей. Любая помощь, которую кто-либо может предложить, будет принята с благодарностью. Спасибо.

1 ответ

Ваша проблема (или хотя бы одна проблема) находится в той строке, в которой вы пытаетесь проецировать свои географические координаты в Web Mercator:

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

В конструкторе Point вы правильно передаете свои значения долготы и широты, но затем указываете пространственную привязку через gfx.spatialReference, для которого установлено значение 102100. 102100 - это WKID для Web Mercator. Но ваши входные данные имеют географические десятичные градусы, поэтому вам нужна пространственная привязка с 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 нет свойства пространственной привязки - только в Graphics.geometry, где вы устанавливаете его правильно.

Только один последний комментарий - вы говорите, что здесь вы используете слой Geometry вместо векторного слоя, потому что вам нужно иметь возможность переключать видимость, но вы можете переключать видимость любого слоя, включая слои объектов.

Другие вопросы по тегам