Alter map layer symbology dynamically (ArcGIS Server) - esri

What is the preferred method of altering a layer's symbology dynamically? My web app consumes a map service via the REST API, but I don't mind using the SOAP API or ArcObjects (.NET).

As of version 2.0, feature layers existed in the ESRI JS API.
ESRI API samples show the use of renderers being used to change the default symbology for dynamic map services via feature layers through assigned unique value & class breaks renderers. As feature layers are derived from the graphics layer object, they render differently (client side vs. services' on the fly img/tile export). Nevertheless, they do allow the alteration of a layers appearance based on developer defined fields/values.
Note the use of a unique value render on a dynamic map service in this:
example (code) http://help.arcgis.com/en/webapi/javascript/arcgis/jssamples/renderer_unique_value.html
live sample
http://developers.arcgis.com/en/javascript/samples/renderer_unique_value/
var defaultSymbol = new esri.symbol.SimpleFillSymbol().setStyle(
esri.symbol.SimpleFillSymbol.STYLE_NULL);
defaultSymbol.outline.setStyle(esri.symbol.SimpleLineSymbol.STYLE_NULL);
//create renderer
var renderer = new esri.renderer.UniqueValueRenderer(defaultSymbol, "SUB_REGION");
//add symbol for each possible value
renderer.addValue("Pacific", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 0, 0, 0.5])));
renderer.addValue("Mtn", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([0, 255, 0, 0.5])));
renderer.addValue("N Eng", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([0, 0, 255, 0.5])));
renderer.addValue("S Atl", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 0, 255, 0.5])));
renderer.addValue("Mid Atl", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 255, 255, 0.75])));
renderer.addValue("E N Cen", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([0, 255, 255, 0.5])));
renderer.addValue("W N Cen", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255, 255, 0, 0.5])));
renderer.addValue("E S Cen", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([127, 127, 127, 0.5])));
renderer.addValue("W S Cen", new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([0, 0, 0, 0.5])));
var featureLayer = new esri.layers.FeatureLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1", {
mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
outFields: ["SUB_REGION"]
});
featureLayer.setRenderer(renderer);
map.addLayer(featureLayer);

The REST API is stateless, so you can't change the symbology via a connection to a RESTful service (although you could use a graphics layer to dynamically extract the features you want to display differently).
You'll have better luck using the SOAP API (via the Web ADF or simply connecting to the service via SOAP manually) and altering the symbology there. More information about this is available here: http://forums.esri.com/Thread.asp?c=158&f=2421&t=266974

If you want to change the appearance of the symbol in the map service its self then you need to either use the WebADF or create your own service that uses the SOAP API. The actual bit to change the symbol and then produce an image is quite easy, the hard part will be to then get open layers to consume it. I would either not bother or do as Michael suggests and bring back graphics to the client and draw them as you wish using OpenLayers, maybe have the layer set to invisible in the map service, so that they don't show up under the graphics.

Related

Can not we initialize a Font for second time in VB.NET?

I am making a 2D game in VB.NET. I use only one font object to draw strings on the form. This font is only needed in Game Menu. Therefore I dispose the font when it is not necessary and initialize it again when needed.
font_1 = New Font("Autobus Bold", 15.0)
When I use this font (font_1) to draw a string on the form, I get this error.
An unhandled exception of type 'System.ArgumentException' occurred in
System.Drawing.dll
Additional information: Parameter is not valid.
When I view the the font, it shows,
{Name = Reference to a non-shared member requires an object reference.
Size=15.0}
This error doesn't happen when the game menu is loaded for the first time (when font_1 is initialized for the first time). When the user plays the game, font is disposed. When user enters to Game Menu again, font is initialized again before it is used for drawing. When font is used for drawing a string on the window, this error happens.
It looks like error is only within the Font Family. I saw this question in few forums, but no one had given a solution. (This is my first question in a forum)
Edited : I removed the Font(font_1). But still I get the same error. Here is the code that draws the string.
Private Sub mcFramesHandler_TIMER_Tick(sender As Object, e As EventArgs) Handles mcFramesHandler_TIMER.Tick
gB.Clear(Color.Black)
gB.DrawImage(Background_IMG, 0, 0, 640, 480)
Select Case currentMode
Case GameMode.OnGame
If mcShoot_TIMER.Enabled Then gB.DrawImage(Bullet_IMG, Bullet_X, Bullet_Y, 20, 50)
If mcEneShoot_TIMER.Enabled Then gB.DrawImage(EneBullet_IMG, EneBullet_X, EneBullet_Y, 20, 50)
If Shooter_Lives Then gB.DrawImage(Shooter_IMG, Shooter_X, Bullet_Y_Def, 100, 105)
If mcMoveEnemy_TIMER.Enabled Then gB.DrawImage(Enemy_IMG, Enemy_X, 10, 100, 80)
If mcExplode_TMER.Enabled Then gB.DrawImage(Explotion_IMG, Explotion_X, Explotion_Y, 100, 80)
Case GameMode.Begining
gB.DrawString("Start", New Font("Autobus Bold", 15.0), textBrush(0), 110, 98) 'Error is generated in this line
gB.DrawString("Credits", New Font("Autobus Bold", 15.0), textBrush(1), 102, 158)
gB.DrawString("Exit", New Font("Autobus Bold", 15.0), textBrush(2), 114, 218)
End Select
Me.CreateGraphics.DrawImage(backbuffer, 0, 0, 640, 480)
End Sub
Here textBrudh(0) is a brush. gB is the Graphic object. gB successfully draws the background image before it draws the string. This happens only when Game Menu is displayed
Your support is really appreciated.
After you have finished to draw your things you need to dispose all objects around Graphics, not only the font but all (better with closure techniques like code below)
If you need a new instace of Graphics you can create this at the moment this is needed without using a Global object (when you work with Graphics).
Using gB As Graphics = Me.CreateGraphics
Using textBrush As Brush = Brushes.Black
Using font_1 As Font = New Font("Courier New", 15)
gB.DrawString("Start", font_1, textBrush, 400, 98)
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
End Using
End Using
End Using
Problem was with the brush (textBrush : an array of brush). When I dsipose each item in the array and re initialize, looks like something has happened to them (like they are not brushes anymore. See the error again. It says "Parameter is not valid"). So I just redim the array to 0.
Redim textBrush (0)
This clears previous items. Then I redim the array again initilizes each of them when needed.
Redim textBrush (2)
textBrush (0) = Brushes.Yellow
textBrush (1) = Brushes.Red
textBrush (2) = Brushes.Red
This array is used to change text color when up and down key is pressed.
I saw lot of people had mentioned this error in forums
{Name = Reference to a non-shared member requires an object reference. Size=15.0}
I don't what this name is, but it doesn't effect the programme. It is always like that in any Font.

Create js clone a Shape with dynamically drawn graphics

I have a Image on a stage and I'm drawing over it and erasing it. Using the following method
http://jsfiddle.net/lannymcnie/ZNYPD/
Now i want to take a clone of the user drawings but its not working. I tried
var drawingAreaClone = drawingArea.clone(true);
but its not working .
Is there a way to clone it. kindly Help
The demo you posted doesn't clear the stage, but instead clears the graphics each frame. If you clone the shape, it will have no instructions.
#Catalin's answer is right if you just need a visual -- but another option is to use the Graphics store() method instead of clearing the graphics: http://createjs.com/docs/easeljs/classes/Graphics.html#method_store
Essentially this method just sets an internal pointer to where the graphics draw from. By storing after each draw, only future draw calls are made. This will have the same application as the demo you posted, only you can call unstore() later to reset the Graphics to draw from the beginning. If you clone it this way, it should work.
var erase = document.getElementById("toggle").checked;
wrapper.updateCache(erase?"destination-out":"source-over");
//drawing.graphics.clear();
drawing.graphics.store(); // Don't draw anything before this point
// Later
var newGraphics = drawing.graphics.clone();
newGraphics.unstore(); // Might be redundant
var shape = new Shape(newGraphics);
Note that cloning Graphics doesn't recreate the entire graphics tree, and simply clones the array that stores the instructions. Modifying the individual instructions after the fact would impact any clones of that Graphics object.
Hope that helps.
If the drawn line shape is a child of the drawingAreaClone then the clone should work properly.
However, if for some reason you can't make it work with that, you can take a snapshot of the canvas and save it as an img type varaible like this:
var snapshot = new Image();
snapshot.src = canvas.toDataURL();
Also, if you don't want to snapshot the whole canvas, after you saved the initial image, you can limit the drawing area to a rectangle with these extra instructions:
var ctx = canvas.getContext('2d');
canvas.width = snapshot.width;
canvas.height = snapshot.height;
ctx.drawImage(snapshot, rectangle.x, rectangle.y, rectangle.width, rectangle.height, 0, 0, rectangle.width, rectangle.height);
snapshot.src = canvas.toDataURL();

How to format the axis label using MVC Chart Helper and razor?

As a training exercise I'm converting a weather data application I wrote from webforms to MVC5. I was able to convert my entire application to MVC with the exception of the graph page. My old application used ZedGraph. For the new application I'm trying to use the Chart helper, but I can't seem to figure out how to format the axis label. The data is coming from a list of WeatherData objects that have a Date property which I'd like to display as a time.
Is there any way to format the label?
I figure worst case I can add a new property to WeatherData to format the date, but that goes against the separation of display logic from business logic.
#{
var myChart = new Chart(width: 700, height: 400)
.AddTitle(ViewBag.Station)
.AddSeries("Maximum wind speed", chartType: "line",
xValue: Model.data, xField: "Date",
yValues: Model.data, yFields: "MaximumWindspeed")
.AddSeries("Average wind speed", chartType: "line",
xValue: Model.data, xField: "Date",
yValues: Model.data, yFields: "AverageWindspeed")
.Write();
}
Example Graph

Soundcloud custom widget : change container background color w/o waveform.js?

Is there any way to change the sc-waveform container background from #efefef without having to load the waveform.js library? I have enough libraries loading already and the conainer bg conflicts with our site background color
I am experiencing the same issue and have had this problem before ( Overlay visible areas of transparent black silhouette PNG with pattern using CSS3 or JS ).
Here is an example with your waveform: http://jsfiddle.net/eLmmA/3/
$(function() {
var canvas = document.createElement('canvas');
canvas.width = 1800; // must match
canvas.height = 280; // must match
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = 'WAVEFORM_IMAGE.EXT';
}
img.src = 'OVERLAY_IMAGE.EXT';
document.body.appendChild(canvas);
});
I think I understand what you mean. You want to change the color of the waveform background, the gray stuff around the waveform:
The problem here is that waveforms you get from SoundCloud API are represented as partly transparent PNG images, where waveform itself is transparent and the chrome around it is gray (#efefef) color.
So, unless the library you want to use for waveform customisation is using HTML5 canvas, you won't be able to use change the color of that chrome (so no, not possible with either HTML5 Widget API or Custom Player API). And you have to use waveform.js or the likes (or modify the waveform image on canvas yourself).
You could try to experiment with newest CSS filters (webkit only for now) and SVG filters, and possibly some MS IE filters for older IE versions, but I am not sure you'd manage to just change the color.

vb.net code to make a image transparent

I wish to make a bitmap image (.bmp) transparent using VB.NET code. Kindly help me.
I found the key was using the imageAttributes class. Basically set the color key to the color you are using to represent the transparent area, and use one of the drawImage calls that accepts an imageAttribute parameter...
Imports System.Drawing.Imaging
' and in a sub somewhere:
Private mImageAttributes As New ImageAttributes
mImageAttributes.SetColorKey(Color.FromArgb(0, 220, 20, 255),
Color.FromArgb(0, 220, 20, 255))
Dim imageRectangle As New Rectangle(pX, pY, pBitmap.Width, pBitmap.Height)
e.Graphics.DrawImage(pBitmap, imageRectangle, 0, 0, pBitmap.Width, pBitmap.Height,
GraphicsUnit.Pixel, mImageAttributes)
VS 2012
Dim watermark_bm2 As Bitmap = 'someimage(from file or global resource)
watermark_bm2.MakeTransparent()
This msdn article gives full details on how to do this
Here is another article, but code sample is in c#