Print FeatureLayer labels in Esri JavaScript API 3.5 and earlier - javascript

I have a need to implement labels on features in a FeatureLayer in version 3.5 if Esri's Javascript API. The labels are from a field returned by a REST feature service. I can't move to 3.7 for various reasons at this time. I have tried using a TextSymbol but my map features just turn to the color of the TextSymbol and no text appears. I may be approaching this in he wrong manner, though. Below is the code I'm attempting to use for labeling with the featureLayer object being my instance of the FeatureLayer I'm adding to the map. Is there a different or proper way to accomplish this task?
featureLayer.on("graphic-add", function (evt) {
var labelColor = new Color([255, 0, 0, 0.25]);
var myLabel = new TextSymbol(evt.graphic.attributes["My Field Name"]);
myLabel.setColor(labelColor);
myLabel.font.setSize("14pt");
evt.graphic.setSymbol(myLabel);
//console.log(evt);
});
Thanks for any help that can be provided!

I was able to solve this with the code below. This seems to work great.
var labelList = new Array();
featureLayer.on("update-end", function (evt) {
for (var i = 0; i < evt.target.graphics.length; i++) {
var gfx = evt.target.graphics[i];
//if label hasn't been added go ahead and generate it and add to array
if (labelList.indexOf(gfx.attributes[idField]) == -1) {
labelList.push(gfx.attributes[idField]);
addLabelToGeometry(gfx.attributes[labelField], gfx.geometry);
}
}
});
function addLabelToGeometry(text, geometry) {
var point = geometry.getExtent().getCenter();
//top level label of text
var TextSymbolJson = {
"type": "esriTS",
"color": [0, 0, 0, 255],
"verticalAlignment": "middle",
"horizontalAlignment": "center",
"font": {
"family": "Helvetica",
"size": 12,
"style": "normal",
"weight": "bold",
"decoration": "none"
}
};
var labelTextSymbol = new esri.symbol.TextSymbol(TextSymbolJson);
labelTextSymbol.setText(text);
var labelGraphic = new esri.Graphic(point, labelTextSymbol);
map.graphics.add(labelGraphic);
}

Related

amcharts4 dynamic location marker

https://www.amcharts.com/demos/custom-html-elements-map-markers/
I need to add a location marker when I click a button. I tried imageSeries.data.push, addData, init and other methods but when I move the chart (mappositionchanged) is triggered location updates.
I need to make it work automatically without moving or zooming the chart.
I am using amcharts version 4.
function test() {
imageSeries.addData({
"zoomLevel": 5,
"scale": 0.5,
"title": "Pretoria",
"latitude": -25.7463,
"longitude": 28.1876
});
alert(imageSeries.data);
}
<button onClick="test();">click</button>
I'm unable to replicate this behavior where adding data dynamically to a MapImageSeries via its addData method requires refreshing the chart (for what it's worth, user posted the same issue to our GitHub and solved it there.). imageSeries.addData(...) should work just fine.
Setup code:
// Create map instance
var chart = am4core.create("chartdiv", am4maps.MapChart);
// Set map definition
chart.geodata = am4geodata_worldLow;
// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
// Make map load polygon (like country names) data from GeoJSON
polygonSeries.useGeodata = true;
// Create image series
var imageSeries = chart.series.push(new am4maps.MapImageSeries());
// Create a circle image in image series template so it gets replicated to all new images
var imageSeriesTemplate = imageSeries.mapImages.template;
var circle = imageSeriesTemplate.createChild(am4core.Circle);
circle.radius = 4;
circle.fill = am4core.color("#B27799");
circle.stroke = am4core.color("#FFFFFF");
circle.strokeWidth = 2;
circle.nonScaling = true;
circle.tooltipText = "{title}";
// Set property fields
imageSeriesTemplate.propertyFields.latitude = "latitude";
imageSeriesTemplate.propertyFields.longitude = "longitude";
Test code (addPlace method):
// Add data for the three cities
var data = [{
"latitude": 48.856614,
"longitude": 2.352222,
"title": "Paris",
zoomLevel: 1
}, {
"latitude": 40.712775,
"longitude": -74.005973,
"title": "New York",
zoomLevel: 2
}, {
"latitude": 49.282729,
"longitude": -123.120738,
"title": "Vancouver",
zoomLevel: 4
}];
const dataIterator = data[Symbol.iterator]();
function addPlace() {
var item = dataIterator.next();
if ( !item.done) {
imageSeries.addData(item.value);
}
}
Here's a quick demo:
https://codepen.io/team/amcharts/pen/c5a5803d81b9517a8fd37d4e2c6541ed
The "Add Marker" button adds a marker each time (up to 3 times since there's only 3 items in the array) without having to refresh the chart (via invalidate or whatever).

Polyline geometry to graphic - SimpleLineSymbol is the only type not displaying on the map

I have modified the ESRI ArcGIS js API Measurement widget to keep a session based history of the measurements the user has made. When a user clicks on a history item, it should display the geometry associated with that history item as a GraphicsLayer on the map. I am using knockout to manage the history items and to retrieve measurement metadata when a history item is clicked.
At this point, both my Polygons (for area) and Points (for location) work just fine with the SimpleFillSymbol() and the SimpleMarkerSymbol(), respectively. However, the Polyline geometry returned from a distance measurement is not displaying on the map with the SimpleLineSymbol().
Here's the code:
var graphicLayerId = "measurementHistoryGraphicsLayer";
function addGraphicsLayerToMap(graphicsLayer) {
var lay = getGraphicsLayerFromMap();
if (lay !== undefined) {
lay.clear();
lay.add(graphicsLayer);
map.removeLayer(lay);
}
map.addLayer(graphicsLayer);
}
function createGraphicFromGeometry(viewModel) {
//Determine the symbol type
var symbol;
switch (viewModel.activeTool) {
case "area":
symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID,
new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new esri.Color([255, 0, 0]), 2),
new esri.Color([255, 0, 0, 0.25]));
break;
case "distance":
symbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new esri.Color([255, 0, 0]), 3);
break;
case "location":
symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 10,
new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new esri.Color([255, 0, 0]), 3),
new esri.Color([0, 255, 0, 0.25]));
break;
}
var graphic = new esri.Graphic(viewModel.geometry, symbol, { "extent": viewModel.extent, "unitName": viewModel.unitName });
return graphic;
}
function createGraphicsLayerFromGraphic(graphic) {
var graphicLayer = new esri.layers.GraphicsLayer({ id: graphicLayerId });
graphicLayer.add(graphic);
graphicLayer.setRenderer(new esri.renderer.SimpleRenderer(graphic.symbol));
return graphicLayer;
}
function getGraphicsLayerFromMap() {
return map.getLayer(graphicLayerId);
}
$(document).on('click', '#emv_measurement_history .list-group-item', function () {
$('#emv_measurement_history .list-group-item.list-group-item-info').removeClass('list-group-item-info');
$(this).addClass('list-group-item-info');
var measurementData = ko.mapping.toJS(ko.dataFor($(this)[0]));
var graphic = createGraphicFromGeometry(measurementData);
var graphicsLayer = createGraphicsLayerFromGraphic(graphic);
addGraphicsLayerToMap(graphicsLayer);
map.setExtent(measurementData.extent);
});
Like I said, this works fine for both area and location, but distance does not seem to work. I've even tried adding a hard-coded polyline value in there are creating a SimpleLineSymbol from that without success.
For additional information, here is the Polyline info:
[
[
[
2591769.2297164765,
5236836.417134136
],
[
2573584.2281166334,
4620357.96034264
],
[
2557384.1428811993,
4038303.8136230526
],
[
3124973.8484519687,
4260007.60486125
],
[
3714518.451309448,
4454862.77067183
],
[
4324318.833989203,
4618552.510359674
],
[
4666465.839330839,
4693607.843734423
],
[
5013294.285789721,
4757423.375729576
]
]
]
And the spatial reference is set to 102100.
I finally figured it out.
I have the geometry from the original measurement stored in a knockout variable. When I was reading from it, it would build out the graphic, symbol, and graphic layer just fine without any errors throwing.
I discovered that for some reason, the data and the spatial reference were mismatched, so I extracted the path from the stored geometry, assigned it to a new polyline variable, re-set the spatial reference to 102100 like I needed, and re-assigned the geometry to the graphic, which worked.
var g = new esri.Graphic(viewModel.geometry, symbol, { "extent": viewModel.extent, "unitName": viewModel.unitName });
if (viewModel.activeTool === "distance") {
var polyline = new esri.geometry.Polyline(viewModel.geometry.paths);
polyline.setSpatialReference(new esri.SpatialReference(102100));
g.setGeometry(polyline);
}

How to create a sprite with EaselJS?

So I've been looking for the best way for me to create a game in Javascript, and decided that EaselJS would probably work best (If there is a better library, please do tell).
I've just hardly started, but I can't seem to get loading a sprite to work... I'm not quite sure what the problem is, as it's connecting with the canvas, it's loading the library...
Here is the javascript console error:
Uncaught TypeError: Cannot read property 'length' of null easeljs-0.7.1.min.j
s:12
b._calculateFrames easeljs-0.7.1.min.js:12
b.initialize easeljs-0.7.1.min.js:12
a easeljs-0.7.1.min.js:12
init index.html:3
onload
So yeah... If you could help me out that'd be great... here is the src code:
function init() {
var stage = new createjs.Stage(document.getElementById("demoCanvas"));
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2],
"images": ["http://imgur.com/bLfR7TO.png"]
}
});
var jaza = new createjs.Sprite(jazaSheet);
jaza.x = 0;
jaza.y = 0;
jaza.goToAndPlay("walkDown");
stage.addChild(jaza);
Ticker.setFPS(60);
Ticker.addListener(stage);
stage.update();
}
EDIT:
Ok so I've changed it as said, but I still can't seem to get it to show up on the canvas...
function init() {
var stage = new createjs.Stage(document.getElementById("demoCanvas"));
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2]
},
"images": ["http://imgur.com/bLfR7TO.png"]
});
var jaza = new createjs.Sprite(jazaSheet);
jaza.x = 100;
jaza.y = 100;
jaza.gotoAndPlay("walkDown");
stage.addChild(jaza);
createjs.Ticker.setFPS(60);
stage.update();
}
I took a look at it, you can see the source of the class here.
Basically, you have a typo in your parameter object.
Take the images object out of the animations
var jazaSheet = new createjs.SpriteSheet ({
"frames": {
"width": 15,
"height": 16,
"numFrames": 8,
"regX": 0,
"regY": 0
},
"animations":{
"walkDown": [0, 1, "walkDown", 2]
},
"images": {
["http://imgur.com/bLfR7TO"]
}
});
Explanation:
_calculateFrames() function uses the private variable images. Row 464 creates a loop with the array.length as one parameter. Since the array is null (typo in parameter), TypeError exception is thrown.

Changing color of YUI pie chart after creation

I want to change the array of colors available to a pie-chart after I have created it. I think I need to use the setSeriesStyles method but I cannot find any examples of it and the documentation is not clear.
So far I have tried
pieChart.setSeriesStyles([{colors: ['#D4D4D4']}]);
and
pieChart.setSeriesStyles([{ style: { colors: ['#D4D4D4']}}]);
Because I have a live datasource that I am polling, I can listen for an event when the data changes and then update the chart before sending the data onto it.
datasource.doBeforeCallback = function(oRequest, oFullResponse, oParsedResponse, oCallback) {
if (!oParsedResponse.results || oParsedResponse.results.length < 1) {
oParsedResponse.results = [{ "name": "No Activity", "count": "0" }];
mychart._seriesDefs.style.colors = [{style: { colors: ['#000000']}}];
} else {
mychart._seriesDefs = null; // sets color array back to default
}
return oParsedResponse;
};

Openlayers - LayerRedraw() / Feature rotation / Linestring coords

TLDR: I have an Openlayers map with a layer called 'track' I want to remove track and add track back in. Or figure out how to plot a triangle based off one set of coords & a heading(see below).
I have an image 'imageFeature' on a layer that rotates on load to the direction being set. I want it to update this rotation that is set in 'styleMap' on a layer called 'tracking'.
I set the var 'stylemap' to apply the external image & rotation.
The 'imageFeature' is added to the layer at the coords specified.
'imageFeature' is removed.
'imageFeature' is added again in its new location. Rotation is not applied..
As the 'styleMap' applies to the layer I think that I have to remove the layer and add it again rather than just the 'imageFeature'
Layer:
var tracking = new OpenLayers.Layer.GML("Tracking", "coordinates.json", {
format: OpenLayers.Format.GeoJSON,
styleMap: styleMap
});
styleMap:
var styleMap = new OpenLayers.StyleMap({
fillOpacity: 1,
pointRadius: 10,
rotation: heading,
});
Now wrapped in a timed function the imageFeature:
map.layers[3].addFeatures(new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(longitude, latitude), {
rotation: heading,
type: parseInt(Math.random() * 3)
}
));
Type refers to a lookup of 1 of 3 images.:
styleMap.addUniqueValueRules("default", "type", lookup);
var lookup = {
0: {
externalGraphic: "Image1.png",
rotation: heading
},
1: {
externalGraphic: "Image2.png",
rotation: heading
},
2: {
externalGraphic: "Image3.png",
rotation: heading
}
}
I have tried the 'redraw()' function: but it returns "tracking is undefined" or "map.layers[2]" is undefined.
tracking.redraw(true);
map.layers[2].redraw(true);
Heading is a variable: from a JSON feed.
var heading = 13.542;
But so far can't get anything to work it will only rotate the image onload. The image will move in coordinates as it should though.
So what am I doing wrong with the redraw function or how can I get this image to rotate live?
Thanks in advance
-Ozaki
Add: I managed to get
map.layers[2].redraw(true);
to sucessfully redraw layer 2. But it still does not update the rotation. I am thinking because the stylemap is updating. But it runs through the style map every n sec, but no updates to rotation and the variable for heading is updating correctly if i put a watch on it in firebug.
If I were to draw a triangle with an array of points & linestring.
How would I go about facing the triangle towards the heading.
I have the Lon/lat of one point and the heading.
var points = new Array(
new OpenLayers.Geometry.Point(lon1, lat1),
new OpenLayers.Geometry.Point(lon2, lat2),
new OpenLayers.Geometry.Point(lon3, lat3)
);
var line = new OpenLayers.Geometry.LineString(points);
Looking for any way to solve this problem Image or Line anyone know how to do either added a 100rep bounty I am really stuck with this.
//From getJSON request//
var heading = data.RawHeading;
Adding and removing the imageFeature
Solved the problem as follows:
var styleMap = new OpenLayers.StyleMap({
fillOpacity: 1,
pointRadius: 10,
rotation: "${angle}",
});
var lookup = {
0: { externalGraphic: "Image1.png", rotation: "${angle}" },
1: { externalGraphic: "Image2.png", rotation: "${angle}" },
2: { externalGraphic: "Image3.png", rotation: "${angle}" }
}
styleMap.addUniqueValueRules("default", "type", lookup);
map.layers[3].addFeatures(new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(lon, lat), {"angle": dir, type: parseInt(Math.random() * 3)}
), {"angle": dir});
then the request:
var dir = (function () {
$.ajax({
'async': false,
'global': true,
'url': urldefault,
'dataType': "json",
'success': function (data) {
dir = data.Heading
}
});
return dir;
})();
Problem solved. Works perfectly.
You can also try to put heading on the object as an attribute:
{"mapFeatures": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "1579001",
"x": 51.0,
"y": 1.2,
"geometry": {
"type": "Point",
"coordinates": [
51.0,
1.2
],
"crs": {
"type": "OGC",
"properties": {
"urn": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
}
},
"properties": {
"heading": 45,
"label": "some_label_goes_here"
}
}
]
}
}
Then you would have to rewrite your lookup function like this:
var lookup = {
0: {externalGraphic: "Image1.png", rotation: ${heading}},
1: {externalGraphic: "Image2.png", rotation: ${heading}},
2: {externalGraphic: "Image3.png", rotation: ${heading}}
}
Could you try that and see if it works? If you don' t know if the attributes are set correctly, you can always debug with firebug, that is what I always do. There is one tricky thing; when parsing geojson; "properties" are translated to "attributes" on the final javascript object.
First guess:
I assume your layer has a single point object that moves and rotates as when following a car with GPS?
It might be better if you would simply destroy all features on the layer (assuming it is only one feature) and redraw the feature with the new heading set.
Second guess:
Perhaps you need to use a function instead of a variable to maintain the live connection to the rotation.
Please check the documentation here: http://trac.openlayers.org/wiki/Styles on styles.
Hope this helps a bit.

Categories