我正在开发一个应用程序,它将从各种源检索数据并从数据构造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)
有点多余,但即使地图对象中的两个位置的数据,这些点仍未显示在地图上。
我一直在研究这个问题已经有一段时间了,我真的很想完。任何人都可以提供的任何帮助将不胜感激。谢谢。
答案 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上 - 您正确设置它。
最后一条评论 - 您说您在这里使用的是几何图层而不是要素图层,因为您需要能够切换可见性,但您可以切换包括要素图层在内的任何图层的可见性。